0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

Merge pull request #5521 from logto-io/gao-allow-unknown-keys-in-message-payload

refactor: allow unknown keys in send message payload
This commit is contained in:
Gao Sun 2024-03-19 10:49:52 +08:00 committed by GitHub
commit 23bc5cdc8e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 35 additions and 14 deletions

View file

@ -0,0 +1,5 @@
---
"@logto/connector-kit": patch
---
allow unknown properties in send message payload

View file

@ -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);
};

View file

@ -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}}'
);

View file

@ -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

View file

@ -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<string, string>;
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<SendMessagePayload>;
/** 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<SendMessagePayload>;
export const urlRegEx =
/(https?:\/\/)?(?:www\.)?[\w#%+.:=@~-]{1,256}\.[\d()A-Za-z]{1,6}\b[\w#%&()+./:=?@~-]*/;