From 2c10c242323438c8283cb7766495dea234bd3175 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Tue, 19 Mar 2024 10:38:36 +0800 Subject: [PATCH] refactor: update invitation apis --- .changeset/witty-moose-kick.md | 5 +++++ packages/core/src/utils/zod.ts | 7 +++++++ .../toolkit/connector-kit/src/index.test.ts | 16 +++++++++++++--- packages/toolkit/connector-kit/src/index.ts | 3 +-- .../connector-kit/src/types/passwordless.ts | 18 +++++++++--------- 5 files changed, 35 insertions(+), 14 deletions(-) create mode 100644 .changeset/witty-moose-kick.md diff --git a/.changeset/witty-moose-kick.md b/.changeset/witty-moose-kick.md new file mode 100644 index 000000000..029c30b7c --- /dev/null +++ b/.changeset/witty-moose-kick.md @@ -0,0 +1,5 @@ +--- +"@logto/connector-kit": patch +--- + +allow unknown properties in send message payload diff --git a/packages/core/src/utils/zod.ts b/packages/core/src/utils/zod.ts index 901550715..d8331a037 100644 --- a/packages/core/src/utils/zod.ts +++ b/packages/core/src/utils/zod.ts @@ -21,6 +21,7 @@ import { ZodUnion, ZodUnknown, ZodDefault, + ZodIntersection, } from 'zod'; import RequestError from '#src/errors/RequestError/index.js'; @@ -279,5 +280,11 @@ export const zodTypeToSwagger = ( }; } + if (config instanceof ZodIntersection) { + return { + allOf: [zodTypeToSwagger(config._def.left), zodTypeToSwagger(config._def.right)], + }; + } + throw new RequestError('swagger.invalid_zod_type', config); }; diff --git a/packages/toolkit/connector-kit/src/index.test.ts b/packages/toolkit/connector-kit/src/index.test.ts index 5016b4007..6cece2333 100644 --- a/packages/toolkit/connector-kit/src/index.test.ts +++ b/packages/toolkit/connector-kit/src/index.test.ts @@ -59,15 +59,25 @@ describe('replaceSendMessageHandlebars', () => { ); }); - it('should replace handlebars with empty string if payload does not contain the key', () => { + it('should not replace handlebars if payload does not contain the key', () => { const template = 'Your verification code is {{code}}'; const payload = {}; - expect(replaceSendMessageHandlebars(template, payload)).toEqual('Your verification code is '); + expect(replaceSendMessageHandlebars(template, payload)).toEqual( + 'Your verification code is {{code}}' + ); }); - it('should ignore handlebars that are not in the predefined list for both template and payload', () => { + it('should replace all handlebars even they are not in the predefined list for payload', () => { const template = 'Your verification code is {{code}} and {{foo}}'; const payload = { code: '123456', foo: 'bar' }; + expect(replaceSendMessageHandlebars(template, payload)).toEqual( + 'Your verification code is 123456 and bar' + ); + }); + + it('should ignore handlebars that are not in the payload', () => { + const template = 'Your verification code is {{code}} and {{foo}}'; + const payload = { code: '123456' }; expect(replaceSendMessageHandlebars(template, payload)).toEqual( 'Your verification code is 123456 and {{foo}}' ); diff --git a/packages/toolkit/connector-kit/src/index.ts b/packages/toolkit/connector-kit/src/index.ts index 6dc55f59d..68b33e00e 100644 --- a/packages/toolkit/connector-kit/src/index.ts +++ b/packages/toolkit/connector-kit/src/index.ts @@ -3,7 +3,6 @@ import type { ZodType, ZodTypeDef } from 'zod'; import { ConnectorError, ConnectorErrorCodes, - sendMessagePayloadKeys, type SendMessagePayload, ConnectorType, } from './types/index.js'; @@ -96,7 +95,7 @@ export const replaceSendMessageHandlebars = ( template: string, payload: SendMessagePayload ): string => { - return sendMessagePayloadKeys.reduce( + return Object.keys(payload).reduce( (accumulator, key) => accumulator.replaceAll(new RegExp(`{{\\s*${key}\\s*}}`, 'g'), payload[key] ?? ''), template diff --git a/packages/toolkit/connector-kit/src/types/passwordless.ts b/packages/toolkit/connector-kit/src/types/passwordless.ts index 688a60a03..5decfc0ad 100644 --- a/packages/toolkit/connector-kit/src/types/passwordless.ts +++ b/packages/toolkit/connector-kit/src/types/passwordless.ts @@ -32,6 +32,7 @@ export enum TemplateType { export const templateTypeGuard = z.nativeEnum(TemplateType); +/** The payload for sending email or sms. */ export type SendMessagePayload = { /** * The dynamic verification code to send. It will replace the `{{code}}` handlebars in the @@ -44,16 +45,15 @@ export type SendMessagePayload = { * @example 'https://example.com' */ link?: string; -}; +} & Record; -export const sendMessagePayloadKeys = ['code', 'link'] as const satisfies Array< - keyof SendMessagePayload ->; - -export const sendMessagePayloadGuard = z.object({ - code: z.string().optional(), - link: z.string().optional(), -}) satisfies z.ZodType; +/** The guard for {@link SendMessagePayload}. */ +export const sendMessagePayloadGuard = z + .object({ + code: z.string().optional(), + link: z.string().optional(), + }) + .and(z.record(z.string())) satisfies z.ZodType; export const urlRegEx = /(https?:\/\/)?(?:www\.)?[\w#%+.:=@~-]{1,256}\.[\d()A-Za-z]{1,6}\b[\w#%&()+./:=?@~-]*/;