From 407824ab2889476c1535b431f996a7e0d5650673 Mon Sep 17 00:00:00 2001 From: Charlie Andrews Date: Wed, 1 Feb 2023 16:07:05 -0800 Subject: [PATCH 1/6] feat: personalDataAndDocumentsDetailedKycSchema --- src/common.ts | 3 +++ src/fiat-account.ts | 6 ++--- src/kyc.ts | 57 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 4 deletions(-) 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..047c9fd 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,36 @@ 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', +} + +const documentsWithBack = [ + IdentificationDocumentType.IDC, + IdentificationDocumentType.DL, +] +const documentsWithoutBack = Object.keys(IdentificationDocumentType).filter( + (idType: IdentificationDocumentType) => !documentsWithBack.includes(idType), +) + +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 +83,40 @@ 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(), + identificationDocumentType: identificationDocumentTypeSchema, + }), + ) + .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' }, ) From aeeac174a45ebad495740bca5c8d5d8d048ce328 Mon Sep 17 00:00:00 2001 From: Charlie Andrews Date: Wed, 1 Feb 2023 16:08:48 -0800 Subject: [PATCH 2/6] type safety --- src/kyc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kyc.ts b/src/kyc.ts index 047c9fd..426ad9f 100644 --- a/src/kyc.ts +++ b/src/kyc.ts @@ -38,7 +38,7 @@ export enum IdentificationDocumentType { DL = 'DL', } -const documentsWithBack = [ +const documentsWithBack: IdentificationDocumentType[] = [ IdentificationDocumentType.IDC, IdentificationDocumentType.DL, ] From fbb47dd4733a136aefea073c6edb4e707425b87f Mon Sep 17 00:00:00 2001 From: Charlie Andrews Date: Wed, 1 Feb 2023 16:27:56 -0800 Subject: [PATCH 3/6] cosmetics --- src/kyc.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/kyc.ts b/src/kyc.ts index 426ad9f..d915314 100644 --- a/src/kyc.ts +++ b/src/kyc.ts @@ -46,10 +46,8 @@ const documentsWithoutBack = Object.keys(IdentificationDocumentType).filter( (idType: IdentificationDocumentType) => !documentsWithBack.includes(idType), ) -const identificationDocumentTypeWithBackSchema = - z.enum(documentsWithBack) -const identificationDocumentTypeWithoutBackSchema = - z.enum(documentsWithoutBack) +const identificationDocumentTypeWithBackSchema = z.enum(documentsWithBack) +const identificationDocumentTypeWithoutBackSchema = z.enum(documentsWithoutBack) export const identificationDocumentTypeSchema = identificationDocumentTypeWithBackSchema.or( identificationDocumentTypeWithoutBackSchema, From 352af691d372037d60e12283d954f49707cfe1d5 Mon Sep 17 00:00:00 2001 From: Charlie Andrews Date: Wed, 1 Feb 2023 16:40:08 -0800 Subject: [PATCH 4/6] fix types --- src/kyc.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/kyc.ts b/src/kyc.ts index d915314..f43ae3f 100644 --- a/src/kyc.ts +++ b/src/kyc.ts @@ -38,13 +38,17 @@ export enum IdentificationDocumentType { DL = 'DL', } -const documentsWithBack: IdentificationDocumentType[] = [ +// need [string, ...string[]] types to get zod enums to compile +const documentsWithBack: [string, ...string[]] = [ IdentificationDocumentType.IDC, IdentificationDocumentType.DL, ] -const documentsWithoutBack = Object.keys(IdentificationDocumentType).filter( - (idType: IdentificationDocumentType) => !documentsWithBack.includes(idType), -) +const documentsWithoutBack: [string, ...string[]] = Object.keys( + IdentificationDocumentType, +).filter((idType) => !documentsWithBack.includes(idType)) as [ + string, + ...string[], +] const identificationDocumentTypeWithBackSchema = z.enum(documentsWithBack) const identificationDocumentTypeWithoutBackSchema = z.enum(documentsWithoutBack) From fcfff4d66e4bd8647016de5ca5d607740851a5a0 Mon Sep 17 00:00:00 2001 From: Charlie Andrews Date: Thu, 2 Feb 2023 12:03:45 -0800 Subject: [PATCH 5/6] use IdentificationDocumentType instead of string --- src/kyc.ts | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/kyc.ts b/src/kyc.ts index f43ae3f..fe5834f 100644 --- a/src/kyc.ts +++ b/src/kyc.ts @@ -38,16 +38,22 @@ export enum IdentificationDocumentType { DL = 'DL', } -// need [string, ...string[]] types to get zod enums to compile -const documentsWithBack: [string, ...string[]] = [ - IdentificationDocumentType.IDC, - IdentificationDocumentType.DL, -] -const documentsWithoutBack: [string, ...string[]] = Object.keys( +// 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 [ - string, - ...string[], + IdentificationDocumentType, + ...IdentificationDocumentType[], ] const identificationDocumentTypeWithBackSchema = z.enum(documentsWithBack) From 73bd9f91351aecd2b04a6b8235ab0b671fb60b1c Mon Sep 17 00:00:00 2001 From: Charlie Andrews Date: Thu, 2 Feb 2023 16:03:17 -0800 Subject: [PATCH 6/6] remove unnecessary field from zod schema --- src/kyc.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/kyc.ts b/src/kyc.ts index fe5834f..7e6a31a 100644 --- a/src/kyc.ts +++ b/src/kyc.ts @@ -98,7 +98,6 @@ export const personalDataAndDocumentsDetailedKycSchema = z.object({ email: z.string().regex(EMAIL_REGEX), identificationDocumentFront: z.string(), - identificationDocumentType: identificationDocumentTypeSchema, }), ) .and(