Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

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