"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.smtpShape = exports.smtpInputSpec = exports.systemSmtpSpec = exports.smtpProviderVariants = exports.customSmtp = void 0; exports.smtpPrefill = smtpPrefill; const util_1 = require("../../util"); const inputSpec_1 = require("./builder/inputSpec"); const value_1 = require("./builder/value"); const variants_1 = require("./builder/variants"); const zod_1 = require("zod"); const securityVariants = variants_1.Variants.of({ tls: { name: 'TLS', spec: inputSpec_1.InputSpec.of({ port: value_1.Value.dynamicText(async () => ({ name: 'Port', required: true, default: '465', disabled: 'Fixed for TLS', })), }), }, starttls: { name: 'STARTTLS', spec: inputSpec_1.InputSpec.of({ port: value_1.Value.select({ name: 'Port', default: '587', values: { '25': '25', '587': '587', '2525': '2525' }, }), }), }, }); /** * Creates an SMTP field spec with provider-specific defaults pre-filled. */ function smtpFields(defaults = {}) { const hostSpec = value_1.Value.text({ name: 'Host', required: true, default: defaults.host ?? null, placeholder: 'smtp.example.com', }); return inputSpec_1.InputSpec.of({ host: defaults.hostDisabled ? hostSpec.withDisabled('Fixed for this provider') : hostSpec, security: value_1.Value.union({ name: 'Connection Security', default: defaults.security ?? 'tls', variants: securityVariants, }), from: value_1.Value.text({ name: 'From Address', required: true, default: null, placeholder: 'Example Name ', patterns: [util_1.Patterns.emailWithName], }), username: value_1.Value.text({ name: 'Username', required: true, default: null, }), password: value_1.Value.text({ name: 'Password', required: false, default: null, masked: true, }), }); } /** * Base SMTP settings with no provider-specific defaults. */ exports.customSmtp = smtpFields(); /** * Provider presets for SMTP configuration. * Each variant has SMTP fields pre-filled with the provider's recommended settings. */ exports.smtpProviderVariants = variants_1.Variants.of({ gmail: { name: 'Gmail', spec: smtpFields({ host: 'smtp.gmail.com', security: 'tls', hostDisabled: true, }), }, ses: { name: 'Amazon SES', spec: smtpFields({ host: 'email-smtp.us-east-1.amazonaws.com', security: 'tls', }), }, sendgrid: { name: 'SendGrid', spec: smtpFields({ host: 'smtp.sendgrid.net', security: 'tls', hostDisabled: true, }), }, mailgun: { name: 'Mailgun', spec: smtpFields({ host: 'smtp.mailgun.org', security: 'tls', hostDisabled: true, }), }, protonmail: { name: 'Proton Mail', spec: smtpFields({ host: 'smtp.protonmail.ch', security: 'tls', hostDisabled: true, }), }, other: { name: 'Other', spec: exports.customSmtp, }, }); /** * System SMTP settings with provider presets. * Wraps smtpProviderVariants in a union for use by the system email settings page. */ exports.systemSmtpSpec = inputSpec_1.InputSpec.of({ provider: value_1.Value.union({ name: 'Provider', default: 'gmail', variants: exports.smtpProviderVariants, }), }); const smtpVariants = variants_1.Variants.of({ disabled: { name: 'Disabled', spec: inputSpec_1.InputSpec.of({}) }, system: { name: 'System Credentials', spec: inputSpec_1.InputSpec.of({ customFrom: value_1.Value.text({ name: 'Custom From Address', description: 'A custom from address for this service. If not provided, the system from address will be used.', required: false, default: null, placeholder: 'Name ', patterns: [util_1.Patterns.emailWithName], }), }), }, custom: { name: 'Custom Credentials', spec: inputSpec_1.InputSpec.of({ provider: value_1.Value.union({ name: 'Provider', default: null, variants: exports.smtpProviderVariants, }), }), }, }); /** * For service inputSpec. Gives users 3 options for SMTP: (1) disabled, (2) use system SMTP settings, (3) use custom SMTP settings with provider presets */ exports.smtpInputSpec = value_1.Value.dynamicUnion(async ({ effects }) => { const smtp = await new util_1.GetSystemSmtp(effects).once(); const disabled = smtp ? [] : ['system']; return { name: 'SMTP', description: 'Optionally provide an SMTP server for sending emails', default: 'disabled', disabled, variants: smtpVariants, }; }, smtpVariants.validator); const securityShape = zod_1.z .object({ selection: zod_1.z.enum(['tls', 'starttls']).catch('tls'), value: zod_1.z.object({ port: zod_1.z.string().catch('465') }).catch({ port: '465' }), }) .catch({ selection: 'tls', value: { port: '465' } }); const providerShape = zod_1.z .object({ selection: zod_1.z.string().catch('other'), value: zod_1.z .object({ host: zod_1.z.string().catch(''), from: zod_1.z.string().catch(''), username: zod_1.z.string().catch(''), password: zod_1.z.string().nullable().optional().catch(null), security: securityShape, }) .catch({ host: '', from: '', username: '', password: null, security: securityShape.parse(undefined), }), }) .catch({ selection: 'other', value: { host: '', from: '', username: '', password: null, security: securityShape.parse(undefined), }, }); /** * Zod schema for persisting SMTP selection in a store file model. * Use this instead of `smtpInputSpec.validator` to avoid cross-zod-instance issues. */ exports.smtpShape = zod_1.z .discriminatedUnion('selection', [ zod_1.z.object({ selection: zod_1.z.literal('disabled'), value: zod_1.z.object({}).catch({}), }), zod_1.z.object({ selection: zod_1.z.literal('system'), value: zod_1.z .object({ customFrom: zod_1.z.string().nullable().optional().catch(null) }) .catch({ customFrom: null }), }), zod_1.z.object({ selection: zod_1.z.literal('custom'), value: zod_1.z .object({ provider: providerShape }) .catch({ provider: providerShape.parse(undefined) }), }), ]) .catch({ selection: 'disabled', value: {} }); /** * Convert a stored SmtpSelection to a value suitable for prefilling smtpInputSpec. * * The stored type (SmtpSelection from smtpShape) uses flat unions for provider/security * selection, while the input spec (smtpInputSpec) uses distributed discriminated unions * (UnionRes). These are structurally incompatible in TypeScript's type system, even * though the runtime values are identical. This function bridges the two types so that * service code doesn't need `as any`. */ function smtpPrefill(smtp) { return smtp || undefined; } //# sourceMappingURL=inputSpecConstants.js.map