diff --git a/src/common.ts b/src/common.ts index b6ce817..4baaffa 100644 --- a/src/common.ts +++ b/src/common.ts @@ -91,3 +91,6 @@ export enum CryptoType { export const cryptoTypeSchema = z.nativeEnum(CryptoType, { description: 'cryptoTypeSchema', }) +export const EMAIL_REGEX = + /* eslint-disable-next-line no-useless-escape */ // For some reason, eslint thinks the escaped \[ and /] are useless. they are indeed useful. + /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ // credit to http://emailregex.com/ diff --git a/src/fiat-account.ts b/src/fiat-account.ts index df1cfe3..44aa974 100644 --- a/src/fiat-account.ts +++ b/src/fiat-account.ts @@ -1,4 +1,5 @@ import { z } from 'zod' +import { EMAIL_REGEX } from './common' /* * FiatConnect dynamic type definitions. @@ -47,9 +48,6 @@ const requiredFiatAccountSchemaFieldsSchema = z.object({ fiatAccountType: fiatAccountTypeSchema, }) -export const PIX_EMAIL_KEY_REGEX = - /* eslint-disable-next-line no-useless-escape */ // For some reason, eslint thinks the escaped \[ and /] are useless. they are indeed useful. - /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ // credit to http://emailregex.com/ export const PIX_CPF_KEY_REGEX = /^([0-9]{3}\.){2}[0-9]{3}[-]([0-9]{2})$/ // example: 000.000.000-00, see https://en.wikipedia.org/wiki/CPF_number export const PIX_PHONE_KEY_REGEX = /^[0-9]{11}$/ export const PIX_RANDOM_KEY_REGEX = /^[a-zA-Z0-9-]{32}$/ @@ -67,7 +65,7 @@ export const pixAccountSchema = requiredFiatAccountSchemaFieldsSchema z .object({ keyType: z.literal(PIXKeyTypeEnum.EMAIL), - key: z.string().regex(PIX_EMAIL_KEY_REGEX), + key: z.string().regex(EMAIL_REGEX), }) .or( z.object({ diff --git a/src/kyc.ts b/src/kyc.ts index 89b22ca..7e6a31a 100644 --- a/src/kyc.ts +++ b/src/kyc.ts @@ -1,4 +1,5 @@ import { z } from 'zod' +import { EMAIL_REGEX } from './common' export enum KycStatus { KycNotCreated = 'KycNotCreated', @@ -7,6 +8,7 @@ export enum KycStatus { KycDenied = 'KycDenied', KycExpired = 'KycExpired', } + export const kycStatusSchema = z.nativeEnum(KycStatus, { description: 'kycStatusSchema', }) @@ -23,11 +25,44 @@ export const kycStatusSchema = z.nativeEnum(KycStatus, { // When adding new schemas be sure to also update kycSchemasSchema export enum KycSchema { PersonalDataAndDocuments = 'PersonalDataAndDocuments', + PersonalDataAndDocumentsDetailed = 'PersonalDataAndDocumentsDetailed', } + export const kycSchemaSchema = z.nativeEnum(KycSchema, { description: 'kycSchemaSchema', }) +export enum IdentificationDocumentType { + IDC = 'IDC', + PAS = 'PAS', + DL = 'DL', +} + +// need nonempty array types to get zod enums to compile +const documentsWithBack: [ + IdentificationDocumentType, + ...IdentificationDocumentType[], +] = [IdentificationDocumentType.IDC, IdentificationDocumentType.DL] +const documentsWithoutBack: [ + IdentificationDocumentType, + ...IdentificationDocumentType[], +] = ( + Object.keys(IdentificationDocumentType) as [ + IdentificationDocumentType, + ...IdentificationDocumentType[], + ] +).filter((idType) => !documentsWithBack.includes(idType)) as [ + IdentificationDocumentType, + ...IdentificationDocumentType[], +] + +const identificationDocumentTypeWithBackSchema = z.enum(documentsWithBack) +const identificationDocumentTypeWithoutBackSchema = z.enum(documentsWithoutBack) +export const identificationDocumentTypeSchema = + identificationDocumentTypeWithBackSchema.or( + identificationDocumentTypeWithoutBackSchema, + ) + export const personalDataAndDocumentsKycSchema = z.object( { firstName: z.string(), @@ -56,10 +91,39 @@ export type PersonalDataAndDocumentsKyc = z.infer< typeof personalDataAndDocumentsKycSchema > +export const personalDataAndDocumentsDetailedKycSchema = + personalDataAndDocumentsKycSchema + .omit({ identificationDocument: true }) + .and( + z.object({ + email: z.string().regex(EMAIL_REGEX), + identificationDocumentFront: z.string(), + }), + ) + .and( + z + .object({ + identificationDocumentType: identificationDocumentTypeWithBackSchema, + identificationDocumentBack: z.string(), + }) + .or( + z.object({ + identificationDocumentType: + identificationDocumentTypeWithoutBackSchema, + }), + ), + ) + +export type PersonalDataAndDocumentsDetailedKyc = z.infer< + typeof personalDataAndDocumentsDetailedKycSchema +> + export const kycSchemasSchema = z.object( { [kycSchemaSchema.enum.PersonalDataAndDocuments]: personalDataAndDocumentsKycSchema, + [kycSchemaSchema.enum.PersonalDataAndDocumentsDetailed]: + personalDataAndDocumentsDetailedKycSchema, }, { description: 'kycSchemasSchema' }, )