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:
commit
23bc5cdc8e
5 changed files with 35 additions and 14 deletions
5
.changeset/witty-moose-kick.md
Normal file
5
.changeset/witty-moose-kick.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"@logto/connector-kit": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
allow unknown properties in send message payload
|
|
@ -21,6 +21,7 @@ import {
|
||||||
ZodUnion,
|
ZodUnion,
|
||||||
ZodUnknown,
|
ZodUnknown,
|
||||||
ZodDefault,
|
ZodDefault,
|
||||||
|
ZodIntersection,
|
||||||
} from 'zod';
|
} from 'zod';
|
||||||
|
|
||||||
import RequestError from '#src/errors/RequestError/index.js';
|
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);
|
throw new RequestError('swagger.invalid_zod_type', config);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 template = 'Your verification code is {{code}}';
|
||||||
const payload = {};
|
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 template = 'Your verification code is {{code}} and {{foo}}';
|
||||||
const payload = { code: '123456', foo: 'bar' };
|
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(
|
expect(replaceSendMessageHandlebars(template, payload)).toEqual(
|
||||||
'Your verification code is 123456 and {{foo}}'
|
'Your verification code is 123456 and {{foo}}'
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,7 +3,6 @@ import type { ZodType, ZodTypeDef } from 'zod';
|
||||||
import {
|
import {
|
||||||
ConnectorError,
|
ConnectorError,
|
||||||
ConnectorErrorCodes,
|
ConnectorErrorCodes,
|
||||||
sendMessagePayloadKeys,
|
|
||||||
type SendMessagePayload,
|
type SendMessagePayload,
|
||||||
ConnectorType,
|
ConnectorType,
|
||||||
} from './types/index.js';
|
} from './types/index.js';
|
||||||
|
@ -96,7 +95,7 @@ export const replaceSendMessageHandlebars = (
|
||||||
template: string,
|
template: string,
|
||||||
payload: SendMessagePayload
|
payload: SendMessagePayload
|
||||||
): string => {
|
): string => {
|
||||||
return sendMessagePayloadKeys.reduce(
|
return Object.keys(payload).reduce(
|
||||||
(accumulator, key) =>
|
(accumulator, key) =>
|
||||||
accumulator.replaceAll(new RegExp(`{{\\s*${key}\\s*}}`, 'g'), payload[key] ?? ''),
|
accumulator.replaceAll(new RegExp(`{{\\s*${key}\\s*}}`, 'g'), payload[key] ?? ''),
|
||||||
template
|
template
|
||||||
|
|
|
@ -32,6 +32,7 @@ export enum TemplateType {
|
||||||
|
|
||||||
export const templateTypeGuard = z.nativeEnum(TemplateType);
|
export const templateTypeGuard = z.nativeEnum(TemplateType);
|
||||||
|
|
||||||
|
/** The payload for sending email or sms. */
|
||||||
export type SendMessagePayload = {
|
export type SendMessagePayload = {
|
||||||
/**
|
/**
|
||||||
* The dynamic verification code to send. It will replace the `{{code}}` handlebars in the
|
* 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'
|
* @example 'https://example.com'
|
||||||
*/
|
*/
|
||||||
link?: string;
|
link?: string;
|
||||||
};
|
} & Record<string, string>;
|
||||||
|
|
||||||
export const sendMessagePayloadKeys = ['code', 'link'] as const satisfies Array<
|
/** The guard for {@link SendMessagePayload}. */
|
||||||
keyof SendMessagePayload
|
export const sendMessagePayloadGuard = z
|
||||||
>;
|
.object({
|
||||||
|
|
||||||
export const sendMessagePayloadGuard = z.object({
|
|
||||||
code: z.string().optional(),
|
code: z.string().optional(),
|
||||||
link: z.string().optional(),
|
link: z.string().optional(),
|
||||||
}) satisfies z.ZodType<SendMessagePayload>;
|
})
|
||||||
|
.and(z.record(z.string())) satisfies z.ZodType<SendMessagePayload>;
|
||||||
|
|
||||||
export const urlRegEx =
|
export const urlRegEx =
|
||||||
/(https?:\/\/)?(?:www\.)?[\w#%+.:=@~-]{1,256}\.[\d()A-Za-z]{1,6}\b[\w#%&()+./:=?@~-]*/;
|
/(https?:\/\/)?(?:www\.)?[\w#%+.:=@~-]{1,256}\.[\d()A-Za-z]{1,6}\b[\w#%&()+./:=?@~-]*/;
|
||||||
|
|
Loading…
Reference in a new issue