Initial Commit
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import z from "zod";
|
||||
|
||||
/** Channel literals from `@suaveplan/notification-channel`, mirrored here so Zod can validate. */
|
||||
const DispatcherChannelEnum = z.enum([
|
||||
"email",
|
||||
"sms",
|
||||
"push",
|
||||
"in_app",
|
||||
"webhook",
|
||||
"apn",
|
||||
]);
|
||||
|
||||
/**
|
||||
* APN configuration accepted at plugin-construction time. Mirrors the
|
||||
* upstream `APNConfig` surface but is owned by the plugin's Zod
|
||||
* boundary so the values arrive at the transport already validated.
|
||||
*/
|
||||
export const ApnConfigSchema = z.object({
|
||||
cert: z.string().optional(),
|
||||
key: z.string().optional(),
|
||||
pfx: z.string().optional(),
|
||||
passphrase: z.string().optional(),
|
||||
token: z
|
||||
.object({
|
||||
key: z.string().min(1),
|
||||
keyId: z.string().min(1),
|
||||
teamId: z.string().min(1),
|
||||
})
|
||||
.optional(),
|
||||
production: z.boolean().default(false),
|
||||
defaultTopic: z.string().optional(),
|
||||
address: z.string().optional(),
|
||||
port: z.number().int().positive().optional(),
|
||||
connectionRetryLimit: z.number().int().min(0).optional(),
|
||||
requestTimeout: z.number().int().positive().optional(),
|
||||
rejectUnauthorized: z.boolean().optional(),
|
||||
});
|
||||
export type ApnConfig = z.infer<typeof ApnConfigSchema>;
|
||||
|
||||
/**
|
||||
* Plugin options accepted by `createNotificationsPlugin`.
|
||||
*
|
||||
* Every field has a default so a no-arg call
|
||||
* (`createNotificationsPlugin()`) produces a fully-resolved
|
||||
* `NotificationsPluginConfig`.
|
||||
*/
|
||||
export const NotificationsPluginOptionsSchema = z.object({
|
||||
/** Mount prefix for the `/notifications` route group. */
|
||||
basePath: z.string().min(1).default("/notifications"),
|
||||
/** Mount prefix for the `/push` route group. */
|
||||
pushBasePath: z.string().min(1).default("/push"),
|
||||
/** Enable APN push delivery (registers the APN service). */
|
||||
enablePush: z.boolean().default(false),
|
||||
/** APN-specific config; required only when `enablePush === true`. */
|
||||
apn: ApnConfigSchema.optional(),
|
||||
/** Auto-clean read notifications older than N days (0 disables). */
|
||||
autoCleanOldDays: z.number().int().min(0).default(30),
|
||||
/** Maximum recipients accepted by `POST /push/send-bulk`. */
|
||||
maxBulkRecipients: z.number().int().min(1).max(10000).default(1000),
|
||||
/**
|
||||
* Opt in to constructing a `NotificationDispatcher` that fans
|
||||
* notifications across `notification-channel`-style delivery
|
||||
* channels. Off by default — existing routes still call
|
||||
* `apnService` directly.
|
||||
*/
|
||||
enableDispatcher: z.boolean().default(false),
|
||||
/**
|
||||
* Default delivery channel used by the dispatcher when an input
|
||||
* does not specify one. Only consulted when `enableDispatcher` is
|
||||
* on.
|
||||
*/
|
||||
defaultChannel: DispatcherChannelEnum.default("apn"),
|
||||
/**
|
||||
* Tenant id stamped on every `DeliveryEvent` emitted by the
|
||||
* dispatcher. Required to make the events queryable per-tenant.
|
||||
*/
|
||||
deliveryTenantId: z.string().min(1).default("default"),
|
||||
});
|
||||
|
||||
/** Resolved config used by the plugin runtime. */
|
||||
export type NotificationsPluginConfig = z.infer<
|
||||
typeof NotificationsPluginOptionsSchema
|
||||
>;
|
||||
|
||||
/** Caller-facing config — every field optional. */
|
||||
export type NotificationsPluginConfigInput = z.input<
|
||||
typeof NotificationsPluginOptionsSchema
|
||||
>;
|
||||
Reference in New Issue
Block a user