@wildo-ai/zod-decorators 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/files/agent-file-formats.d.ts +51 -37
- package/dist/esm/files/agent-file-formats.d.ts.map +1 -1
- package/dist/esm/files/agent-file-formats.js +54 -47
- package/dist/esm/files/agent-file-formats.js.map +1 -1
- package/dist/esm/files/unified-registry.d.ts +2 -2
- package/dist/esm/files/unified-registry.js +1 -1
- package/dist/esm/files/unified-registry.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/testing.d.ts +11 -0
- package/dist/esm/testing.d.ts.map +1 -1
- package/dist/esm/testing.js +11 -0
- package/dist/esm/testing.js.map +1 -1
- package/dist/esm/zod-address.d.ts +146 -0
- package/dist/esm/zod-address.d.ts.map +1 -0
- package/dist/esm/zod-address.js +176 -0
- package/dist/esm/zod-address.js.map +1 -0
- package/dist/esm/zod-code.d.ts +2 -0
- package/dist/esm/zod-code.d.ts.map +1 -1
- package/dist/esm/zod-code.js.map +1 -1
- package/dist/esm/zod-decorators.types.d.ts +275 -23
- package/dist/esm/zod-decorators.types.d.ts.map +1 -1
- package/dist/esm/zod-decorators.types.js +152 -4
- package/dist/esm/zod-decorators.types.js.map +1 -1
- package/dist/esm/zod-duration.d.ts +2 -0
- package/dist/esm/zod-duration.d.ts.map +1 -1
- package/dist/esm/zod-duration.js.map +1 -1
- package/dist/esm/zod-file.d.ts +70 -4
- package/dist/esm/zod-file.d.ts.map +1 -1
- package/dist/esm/zod-file.js +85 -64
- package/dist/esm/zod-file.js.map +1 -1
- package/dist/esm/zod-money.d.ts +2 -0
- package/dist/esm/zod-money.d.ts.map +1 -1
- package/dist/esm/zod-money.js.map +1 -1
- package/dist/esm/zod-phone.d.ts +8 -0
- package/dist/esm/zod-phone.d.ts.map +1 -1
- package/dist/esm/zod-phone.js +6 -1
- package/dist/esm/zod-phone.js.map +1 -1
- package/dist/esm/zod-utils.shared.d.ts +311 -9
- package/dist/esm/zod-utils.shared.d.ts.map +1 -1
- package/dist/esm/zod-utils.shared.js +898 -86
- package/dist/esm/zod-utils.shared.js.map +1 -1
- package/dist/esm/zod-versioned.d.ts.map +1 -1
- package/dist/esm/zod-versioned.js.map +1 -1
- package/dist/esm/zod.module-override.d.ts +27 -1
- package/dist/esm/zod.module-override.d.ts.map +1 -1
- package/dist/esm/zod.module-override.js +52 -7
- package/dist/esm/zod.module-override.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -7
- package/dist/esm/.native.tsbuildinfo +0 -1
- package/dist/esm/companion-exports.d.ts +0 -8
- package/dist/esm/companion-exports.d.ts.map +0 -1
- package/dist/esm/companion-exports.js +0 -8
- package/dist/esm/companion-exports.js.map +0 -1
package/dist/esm/zod-file.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod-file.js","sourceRoot":"","sources":["../../../src/zod-file.ts"],"names":[],"mappings":"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","sourcesContent":["\n// ============================================================================\n// FILE SCHEMA HELPER\n// ============================================================================\n\n\nimport {\n DecoratorInput,\n SCHEMA_METADATA,\n CustomFieldMetadata,\n FileSchemaMetadata,\n FileSchemaOptions,\n FileMimeTypeGroups,\n FileMimeTypeGroup,\n FileNature,\n FileDisplayNature,\n FileDisplayPresentation,\n FileActivationPolicy,\n type FileActivationConfig,\n type FileUIDisplayParams,\n FileStorageAccepted,\n FileNatureConstraints_Image,\n FileNatureConstraints_Video,\n FileNatureConstraints_Audio,\n FileNatureConstraints_Document,\n FileGenerationConfig,\n FileGenerationSource,\n RagSourceConfiguration,\n ZodDecorator,\n ZodDecorator_ParamsType\n} from \"./zod-decorators.types\";\nimport { z } from \"zod\";\nimport { addChainableMethods, addDecorators } from \"./zod.module-override\";\nimport { UnifiedFileFormatRegistry } from \"./files/unified-registry\";\n\n// Minimal console declaration — avoids pulling in 'dom' or '@types/node' into this shared lib\ndeclare const console: { warn(...args: unknown[]): void };\n\n/**\n * Deduplicated warning tracker for unsupported storage providers.\n * Prevents console spam when the same schema is created multiple times (e.g., in tests or HMR).\n */\nconst _warnedStorageProviders = new Set<string>();\nconst _supportedProviders = new Set([FileStorageAccepted.WILDO_MANAGED, FileStorageAccepted.LOCAL_DIRECTORY]);\nconst GENERATED_PDF_MIME_TYPES = ['application/pdf'] as const;\nconst GENERATION_METADATA_KEYS = new Set(['source', 'templateId']);\n\n/**\n * Single file value type - represents a single file reference stored in the database.\n * The actual file is stored in a file storage system, this object references it.\n */\nexport interface SingleFileValue {\n /** File ID (foreign key to file storage) */\n fileId: string;\n /** Last update timestamp */\n updatedAt: Date;\n\n}\n\n/**\n * Multiple files value type - represents multiple file references stored in the database.\n */\nexport interface MultipleFileValue {\n /** File IDs (foreign keys to file storage) */\n fileIds: string[];\n /** Last update timestamp */\n updatedAt: Date;\n}\n\n/**\n * File value type - can be single or multiple depending on schema configuration.\n */\nexport type FileValue = SingleFileValue | MultipleFileValue;\n\n/**\n * Zod schema for SingleFileValue.\n */\nexport const SingleFileValueSchema: z.ZodObject<{ fileId: z.ZodString; updatedAt: z.ZodDate }> = z.object({\n fileId: z.string().min(1),\n updatedAt: z.date(),\n});\n\n/**\n * Zod schema for MultipleFileValue.\n */\nexport const MultipleFileValueSchema: z.ZodObject<{ fileIds: z.ZodArray<z.ZodString>; updatedAt: z.ZodDate }> = z.object({\n fileIds: z.array(z.string().min(1)),\n updatedAt: z.date(),\n});\n\n\n/**\n * Resolve MIME type groups to actual MIME types.\n * Handles both single group names and arrays of groups/MIME types.\n */\nexport function resolveMimeTypes(\n allowedMimeTypes: string[] | FileMimeTypeGroup | FileMimeTypeGroup[] | undefined\n): string[] | undefined {\n if (!allowedMimeTypes) return undefined;\n\n // If it's a single group name\n if (typeof allowedMimeTypes === 'string') {\n if (allowedMimeTypes in FileMimeTypeGroups) {\n return [...FileMimeTypeGroups[allowedMimeTypes as FileMimeTypeGroup]];\n }\n // Single MIME type\n return [allowedMimeTypes];\n }\n\n // If it's an array\n if (Array.isArray(allowedMimeTypes)) {\n const resolved: string[] = [];\n for (const item of allowedMimeTypes) {\n if (item in FileMimeTypeGroups) {\n // It's a group name\n resolved.push(...FileMimeTypeGroups[item as FileMimeTypeGroup]);\n } else {\n // It's a MIME type\n resolved.push(item);\n }\n }\n // Remove duplicates\n return [...new Set(resolved)];\n }\n\n return undefined;\n}\n\nfunction assertValidFileGenerationConfig(generation: FileGenerationConfig): void {\n const rawGeneration = generation as unknown as Record<string, unknown> | undefined;\n if (!rawGeneration || typeof rawGeneration !== 'object' || Array.isArray(rawGeneration)) {\n throw new Error('[z_file] generation must be an object.');\n }\n\n const extraKeys = Object.keys(rawGeneration).filter((key) => !GENERATION_METADATA_KEYS.has(key));\n if (extraKeys.length > 0) {\n throw new Error(\n `[z_file] generation contains unsupported key(s): ${extraKeys.join(', ')}. ` +\n 'Use only { source: FileGenerationSource.PDF_TEMPLATE, templateId }.'\n );\n }\n\n if (rawGeneration.source !== FileGenerationSource.PDF_TEMPLATE) {\n throw new Error('[z_file] generation.source must be FileGenerationSource.PDF_TEMPLATE.');\n }\n\n if (typeof rawGeneration.templateId !== 'string' || rawGeneration.templateId.trim().length === 0) {\n throw new Error('[z_file] generation.templateId must be a non-empty string.');\n }\n}\n\nfunction assertGeneratedPdfFileOptions(params: {\n generation?: FileGenerationConfig;\n multiple: boolean;\n resolvedMimeTypes?: string[];\n overridable: boolean;\n ragSource?: RagSourceConfiguration;\n scanPolicy?: unknown;\n}): void {\n if (!params.generation) return;\n\n assertValidFileGenerationConfig(params.generation);\n\n if (params.multiple) {\n throw new Error('[z_file] PDF template generation supports single-file fields only.');\n }\n\n if (params.overridable === false) {\n throw new Error('[z_file] PDF template generation requires overridable to remain true so framework REGENERATE can replace the generated file.');\n }\n\n // Re-expression of the pre-Phase-0 `rag` refusal against the shared decorator: a PDF-template\n // output is framework-RENDERED presentation of resource data the corpus can already reach at the\n // source fields — chunking the rendering would index the same facts twice, keyed to a file the\n // next REGENERATE silently replaces.\n if (params.ragSource) {\n throw new Error('[z_file] PDF template generation cannot be combined with RAG ingestion options.');\n }\n\n if (params.scanPolicy) {\n throw new Error('[z_file] PDF template generation cannot be combined with upload scanPolicy options.');\n }\n\n if (\n params.resolvedMimeTypes !== undefined &&\n (params.resolvedMimeTypes.length !== 1 || params.resolvedMimeTypes[0] !== GENERATED_PDF_MIME_TYPES[0])\n ) {\n throw new Error('[z_file] PDF template generation requires allowedMimeTypes to resolve exactly to application/pdf.');\n }\n}\n\n/**\n * z_file() - Creates file schemas for file uploads.\n *\n * File values are stored as: { fileId: string, updatedAt: Date }\n * - fileId: Reference to the file in storage (foreign key, indexed)\n * - updatedAt: When the file was last updated\n *\n * @example\n * ```typescript\n * import { z_file } from '@wildo-ai/zod-decorators';\n *\n * const avatar = z_file();\n * const document = z_file({ allowedMimeTypes: 'Documents' });\n * const images = z_file({\n * allowedMimeTypes: 'Images',\n * maxSize: 5 * 1024 * 1024, // 5MB\n * overridable: true\n * });\n *\n * // With decorators (chainable)\n * z_file().fileUI({ edit: { editMode: FileEditMode.DROPZONE } })\n * z_file({ allowedMimeTypes: ['Images', 'PDF'] }).isHidden({ edit: true })\n * ```\n */\n\n/**\n * @wildo_source:part:start zod.decorators.file-schema\n *\n * Creates a file schema with metadata for detection and form component rendering.\n *\n * ## Where a file field may be declared\n *\n * **The resource's primary scope must be application, organization or user.** A resource scoped to\n * an ANONYMOUS visitor cannot carry a file field — a file's own scope is one of those three, so\n * there is nothing to attribute the bytes to, and the upload refuses that scope by name rather than\n * pretending to support it.\n *\n * **Within the schema, a file field may nest inside objects, arrays and DISCRIMINATED unions.** It\n * may NOT sit inside a record, a map, a set, a tuple, or a plain (non-discriminated) union — the\n * walker that finds file fields refuses those shapes. Where variants are needed, use a discriminated\n * union.\n *\n * **A field carried on several branches of a discriminated union must declare IDENTICAL options on\n * every branch.** Differing options at one path are a conflict the framework refuses rather than\n * choosing between, so a branch that quietly widens `maxSize` or changes `allowedMimeTypes` fails\n * the schema instead of silently winning.\n *\n * ## Uploading is not attaching\n *\n * The generated upload route creates a FILE ROW. Attaching it to a business record is that record's\n * own write, with its own authority. So an uploaded-but-never-submitted file is a real state a\n * caller can produce; the cleanup sweep is what handles it.\n *\n * ## Declaring `imageConstraints.aspectRatio` turns the cropper on\n *\n * That option is the switch for the browser-side crop step — nothing else is wired. It applies to\n * single-file fields only: a `multiple` field keeps the plain upload path. Vector images and\n * formats the browser cannot decode bypass the cropper and upload the original, so the server-side\n * constraint stays the authority.\n *\n * @param options - Configuration options for file field\n * @returns A Zod object schema with metadata for file detection\n */\nexport function createFileSchema(\n options: FileSchemaOptions = {}\n): DecoratedFileSchema | DecoratedMultipleFileSchema {\n const {\n overridable = true,\n allowedMimeTypes,\n maxSize,\n minSize,\n multiple = false,\n maxFiles,\n nature,\n storageAccepted,\n filePathBinding,\n generation,\n imageConstraints,\n videoConstraints,\n audioConstraints,\n documentConstraints,\n ragSource,\n textExtraction,\n scanPolicy,\n onParentDelete = 'cascade',\n sharable,\n sharableDefaults,\n } = options;\n\n // Warn at schema creation if non-WILDO_MANAGED storage providers are configured (not yet supported)\n // Uses deduplication to avoid console spam during tests or HMR\n if (storageAccepted && storageAccepted.some(s => !_supportedProviders.has(s))) {\n const unsupported = storageAccepted.filter(s => !_supportedProviders.has(s));\n const warnKey = unsupported.sort().join(',');\n if (!_warnedStorageProviders.has(warnKey)) {\n _warnedStorageProviders.add(warnKey);\n console.warn(\n `[z_file] storageAccepted contains unsupported providers: ${unsupported.join(', ')}. ` +\n `Only '${FileStorageAccepted.WILDO_MANAGED}' and '${FileStorageAccepted.LOCAL_DIRECTORY}' are currently implemented. ` +\n `External storage providers (OneDrive, Google Drive, Dropbox) will be ignored until their integrations are available.`\n );\n }\n }\n\n if (filePathBinding) {\n if (filePathBinding.multipleFilePolicy && !multiple) {\n console.warn(\n '[z_file] filePathBinding.multipleFilePolicy is set but multiple is false — multipleFilePolicy will be ignored. ' +\n 'Either set multiple: true or remove multipleFilePolicy.'\n );\n }\n if (filePathBinding.fileName && multiple) {\n console.warn(\n '[z_file] filePathBinding.fileName is set on a multiple file field — fileName is ignored for multiple uploads. ' +\n 'Use filePathBinding.multipleFilePolicy.fileNameTemplate instead.'\n );\n }\n // Warned for EVERY provider, not only WILDO_MANAGED. The condition used to exempt a field that\n // named LOCAL_DIRECTORY, because that provider defaulted to `false` anyway and the warning would\n // have fired on its own default. Both providers now default to `true` and both honour `false`\n // identically, so `false` is an explicit opt-out of the tenant-scoped key shape wherever it is\n // authored — and that is the thing worth saying out loud.\n if (filePathBinding.includeApplicationId === false) {\n console.warn(\n '[z_file] filePathBinding.includeApplicationId is false. Storage keys for this field will carry ' +\n 'NO applications/<appId>/files/<resource>/<scope>/<scopeId>/ prefix, so per-tenant listing, ' +\n 'erasure sweeps and prefix-confined credentials cannot address them — ensure that is intended.'\n );\n }\n }\n\n // Resolve MIME type groups to actual MIME types\n const resolvedMimeTypes = resolveMimeTypes(allowedMimeTypes);\n assertGeneratedPdfFileOptions({ generation, multiple, resolvedMimeTypes, overridable, ragSource, scanPolicy });\n const effectiveMimeTypes = generation ? [...GENERATED_PDF_MIME_TYPES] : resolvedMimeTypes;\n\n // Create the file object schema based on single/multiple\n const fileSchema = multiple\n ? z.object({\n fileIds: z.array(z.string().min(1)),\n updatedAt: z.date(),\n })\n : z.object({\n fileId: z.string().min(1),\n updatedAt: z.date(),\n });\n\n // No longer stored in metadata — consumers derive accept from allowedMimeTypes via buildAcceptAttribute()\n\n // Store file metadata in SCHEMA_METADATA.fileConfig\n const fileMetadata: FileSchemaMetadata = {\n isFile: true,\n overridable,\n ...(effectiveMimeTypes !== undefined && { allowedMimeTypes: effectiveMimeTypes }),\n ...(maxSize !== undefined && { maxSize }),\n ...(minSize !== undefined && { minSize }),\n multiple,\n ...(maxFiles !== undefined && { maxFiles }),\n ...(nature !== undefined && { nature }),\n ...(storageAccepted !== undefined && { storageAccepted }),\n ...(filePathBinding !== undefined && { filePathBinding }),\n ...(generation !== undefined && { generation }),\n ...(imageConstraints !== undefined && { imageConstraints }),\n ...(videoConstraints !== undefined && { videoConstraints }),\n ...(audioConstraints !== undefined && { audioConstraints }),\n ...(documentConstraints !== undefined && { documentConstraints }),\n // Text-provider config only — the RAG declaration itself is NOT stored here (single source of\n // truth is the RAG_SOURCE decorator registered below; read it with `getRagSourceConfig`).\n ...(textExtraction !== undefined && { textExtraction }),\n ...(scanPolicy !== undefined && { scanPolicy }),\n onParentDelete,\n ...(sharable !== undefined && { sharable }),\n ...(sharableDefaults !== undefined && { sharableDefaults }),\n };\n\n // Initialize or extend SCHEMA_METADATA with file config\n const existingMetadata: CustomFieldMetadata = (fileSchema as any)[SCHEMA_METADATA] || {};\n (fileSchema as any)[SCHEMA_METADATA] = {\n ...existingMetadata,\n fileConfig: fileMetadata,\n };\n\n // Add chainable decorator methods to the file schema instance\n addChainableMethods(fileSchema);\n\n // Map the file-side `ragSource` option onto the SHARED RAG_SOURCE decorator — the same one\n // `z.string().ragSource()` registers — so `RagSourceFieldDetection` sees one uniform declaration\n // regardless of text provider. Registered through `addDecorators` (the escape-hatch door) because\n // the fluent `.ragSource()` is deliberately not installed on ZodObject; the shared chokepoint\n // still validates the config and enforces the refused companions identically.\n if (ragSource !== undefined) {\n addDecorators(fileSchema, [{ ref: ZodDecorator.RAG_SOURCE, params: ragSource }]);\n }\n\n if (multiple) {\n return fileSchema as unknown as DecoratedMultipleFileSchema;\n }\n return fileSchema as unknown as DecoratedFileSchema;\n}\n\n/**\n * File schemas declare NO decorator surface of their own.\n *\n * They used to, via a `FileSchemaDecoratorMethods<TSelf>` mixin that re-declared `isDBIndexed`,\n * `isHidden`, `isNotEditable` and `showWhen` with the return narrowed to the file schema — necessary\n * only because the `ZodObject` module augmentation did not carry them. It now does (2026-08-12), and\n * re-declaring them made both interfaces below fail TS2320: an interface may not extend two types\n * whose same-named member differs, and `TSelf` is not `DecoratedPrimitiveZodType<this>`.\n *\n * Removing the mixin costs nothing, because `DecoratedPrimitiveZodType<T>` is `T & { … }` — an\n * INTERSECTION. `z_file().isHidden()` still returns something assignable to `DecoratedFileSchema`,\n * and the full decorator surface is now available rather than the four this mixin listed.\n */\n\n/**\n * Return type for single file schemas - includes decorator methods.\n * IS_DB_INDEXED will index the fileId field for query optimization.\n *\n * Uses `interface` instead of `type` to allow self-referencing without circular alias errors.\n */\nexport interface DecoratedFileSchema extends z.ZodObject<{\n fileId: z.ZodString;\n updatedAt: z.ZodDate;\n}> {}\n\n/**\n * Return type for multiple file schemas - includes decorator methods.\n * IS_DB_INDEXED will index the fileIds array for query optimization.\n *\n * Uses `interface` instead of `type` to allow self-referencing without circular alias errors.\n */\nexport interface DecoratedMultipleFileSchema extends z.ZodObject<{\n fileIds: z.ZodArray<z.ZodString>;\n updatedAt: z.ZodDate;\n}> {}\n\n/**\n * Creates a file schema for file uploads with reference storage.\n * Named z_file to indicate it's a Zod helper function exported standalone.\n *\n * Single file values are stored as: { fileId: string, updatedAt: Date }\n * Multiple file values are stored as: { fileIds: string[], updatedAt: Date }\n *\n * @example\n * ```typescript\n * import { z_file } from '@wildo-ai/zod-decorators';\n *\n * // Simple usage - single file, any type\n * z_file()\n *\n * // With MIME type groups (shortcuts)\n * z_file({ allowedMimeTypes: 'Images' })\n * z_file({ allowedMimeTypes: 'PDF' })\n * z_file({ allowedMimeTypes: ['Images', 'Video'] })\n * z_file({ allowedMimeTypes: 'Documents' }) // PDF + Office\n *\n * // With specific MIME types\n * z_file({ allowedMimeTypes: ['image/png', 'image/jpeg'] })\n *\n * // With size constraints\n * z_file({ maxSize: 10 * 1024 * 1024 }) // 10MB max\n *\n * // Multiple files (uses fileIds instead of fileId)\n * z_file({ multiple: true, maxFiles: 5 })\n *\n * // Non-overridable (append-only)\n * z_file({ overridable: false })\n *\n * // RAG corpus source — registers the shared RAG_SOURCE decorator on the returned schema\n * // (chunking config), with the file-side text-provider knobs beside it (OCR opt-in).\n * z_file({ allowedMimeTypes: 'Documents', ragSource: {}, textExtraction: { ocr: true } })\n *\n * // With decorators\n * z_file().fileUI({ edit: { editMode: FileEditMode.DROPZONE } })\n * z_file().isHidden({ display: true })\n * ```\n */\nexport function z_file(options?: FileSchemaOptions): DecoratedFileSchema | DecoratedMultipleFileSchema {\n return createFileSchema(options);\n}\n/** @wildo_source:part:end zod.decorators.file-schema */\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Format file size for display.\n */\nexport function formatFileSize(bytes: number): string {\n if (!Number.isFinite(bytes)) return '—';\n if (bytes === 0) return '0 B';\n if (bytes < 0) return '-' + formatFileSize(Math.abs(bytes));\n\n const units = ['B', 'KB', 'MB', 'GB', 'TB'];\n const k = 1024;\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${units[i]}`;\n}\n\n/**\n * Build enhanced accept attribute string from MIME types.\n * Includes both MIME types and extensions for better browser compatibility.\n * Format: \"image/*,.jpg,.jpeg,.png\" or \"application/pdf,.pdf\"\n *\n * @param mimeTypes - Array of MIME type strings\n * @returns Accept attribute string with MIME types and extensions\n */\nexport function buildAcceptAttribute(mimeTypes: string[]): string {\n if (!mimeTypes || mimeTypes.length === 0) return '';\n\n const parts = new Set<string>();\n const extensions = new Set<string>();\n\n for (const mimeType of mimeTypes) {\n // Add MIME type\n parts.add(mimeType);\n\n // Get extensions for this MIME type\n const mimeExtensions = UnifiedFileFormatRegistry.getExtensions(mimeType);\n for (const ext of mimeExtensions) {\n if (ext) {\n extensions.add(`.${ext}`);\n }\n }\n\n // Also check if it's a wildcard MIME type (e.g., image/*)\n // In that case, get all extensions for that nature\n if (mimeType.endsWith('/*')) {\n const formatType = UnifiedFileFormatRegistry.getFormatTypeFromMimeType(mimeType);\n\n if (formatType && formatType.type === 'nature') {\n const natureExtensions = UnifiedFileFormatRegistry.getExtensionsForNature(formatType.nature);\n for (const ext of natureExtensions) {\n if (ext) {\n extensions.add(`.${ext}`);\n }\n }\n }\n }\n }\n\n // Combine MIME types and extensions\n const allParts = [...parts, ...extensions];\n return allParts.join(',');\n}\n\n/**\n * Get file extension from filename.\n * Uses UnifiedFileFormatRegistry for consistency.\n */\nexport function getFileExtension(filename: string): string {\n return UnifiedFileFormatRegistry.getFileExtension(filename);\n}\n\n/**\n * Check if a MIME type is allowed based on allowed types.\n */\nexport function isMimeTypeAllowed(mimeType: string, allowedMimeTypes?: string[]): boolean {\n if (!allowedMimeTypes || allowedMimeTypes.length === 0) return true;\n\n // Check exact match\n if (allowedMimeTypes.includes(mimeType)) return true;\n\n // Check wildcard match (e.g., \"image/*\")\n const [type] = mimeType.split('/');\n if (allowedMimeTypes.includes(`${type}/*`)) return true;\n\n return false;\n}\n\n/**\n * Get a human-readable description of allowed file types.\n * Uses UnifiedFileFormatRegistry for better format detection.\n */\nexport function getAcceptDescription(allowedMimeTypes?: string[]): string {\n if (!allowedMimeTypes || allowedMimeTypes.length === 0) return 'All files';\n\n const types = new Set<string>();\n\n for (const mime of allowedMimeTypes) {\n // Use registry to detect format type\n const formatType = UnifiedFileFormatRegistry.getFormatTypeFromMimeType(mime);\n\n if (formatType) {\n if (formatType.type === 'nature') {\n // Map FileNature to human-readable names\n const natureNames: Record<string, string> = {\n [FileNature.IMAGE]: 'Images',\n [FileNature.VIDEO]: 'Videos',\n [FileNature.AUDIO]: 'Audio files',\n [FileNature.PDF]: 'PDF',\n [FileNature.OFFICE]: 'Office documents',\n [FileNature.ARCHIVE]: 'Archives',\n };\n const name = natureNames[formatType.nature];\n if (name) {\n types.add(name);\n continue;\n }\n } else if (formatType.type === 'agent') {\n // Map agent formats to human-readable names\n const agentNames: Record<string, string> = {\n 'text': 'Text files',\n 'markdown': 'Markdown',\n 'json': 'JSON',\n 'typescript': 'TypeScript',\n 'typescript_react': 'TypeScript React',\n 'yaml': 'YAML',\n };\n const name = agentNames[formatType.format] || formatType.format.replace(/_/g, ' ').replace(/\\b\\w/g, l => l.toUpperCase());\n types.add(name);\n continue;\n }\n }\n\n // Fallback: use MIME type patterns\n if (mime === 'application/pdf') {\n types.add('PDF');\n } else if (mime.startsWith('image/')) {\n types.add('Images');\n } else if (mime.startsWith('video/')) {\n types.add('Videos');\n } else if (mime.startsWith('audio/')) {\n types.add('Audio');\n } else if (mime.includes('document') || mime.includes('word') || mime.includes('excel') || mime.includes('powerpoint')) {\n types.add('Office documents');\n } else {\n // Get extension-like description\n const ext = mime.split('/').pop()?.toUpperCase();\n if (ext) types.add(ext);\n }\n }\n\n return Array.from(types).join(', ') || 'Selected file types';\n}\n\n/**\n * Get file nature from schema metadata.\n * @param schema - Zod schema (must be a file schema)\n * @returns FileNature or undefined if not set\n */\nexport function getFileNature(schema: z.ZodTypeAny): FileNature | undefined {\n const metadata = (schema as any)[SCHEMA_METADATA] as CustomFieldMetadata | undefined;\n return metadata?.fileConfig?.nature;\n}\n\n/**\n * Get storage accepted from schema metadata.\n * @param schema - Zod schema (must be a file schema)\n * @returns Array of FileStorageAccepted or undefined if not set\n */\nexport function getStorageAccepted(schema: z.ZodTypeAny): FileStorageAccepted[] | undefined {\n const metadata = (schema as any)[SCHEMA_METADATA] as CustomFieldMetadata | undefined;\n return metadata?.fileConfig?.storageAccepted;\n}\n\n/**\n * Get file constraints from schema metadata.\n * @param schema - Zod schema (must be a file schema)\n * @returns Object with all constraint properties or undefined if not set\n */\nexport function getFileConstraints(schema: z.ZodTypeAny): {\n imageConstraints?: FileNatureConstraints_Image;\n videoConstraints?: FileNatureConstraints_Video;\n audioConstraints?: FileNatureConstraints_Audio;\n documentConstraints?: FileNatureConstraints_Document;\n} | undefined {\n const metadata = (schema as any)[SCHEMA_METADATA] as CustomFieldMetadata | undefined;\n const fileConfig = metadata?.fileConfig;\n if (!fileConfig) return undefined;\n\n const hasConstraints =\n fileConfig.imageConstraints ||\n fileConfig.videoConstraints ||\n fileConfig.audioConstraints ||\n fileConfig.documentConstraints;\n\n if (!hasConstraints) return undefined;\n\n return {\n ...(fileConfig.imageConstraints && { imageConstraints: fileConfig.imageConstraints }),\n ...(fileConfig.videoConstraints && { videoConstraints: fileConfig.videoConstraints }),\n ...(fileConfig.audioConstraints && { audioConstraints: fileConfig.audioConstraints }),\n ...(fileConfig.documentConstraints && { documentConstraints: fileConfig.documentConstraints }),\n };\n}\n\n// ============================================================================\n// DISPLAY NATURE RESOLUTION\n// ============================================================================\n\n/**\n * Mapping from schema-level `FileNature` to rendering-level `FileDisplayNature`.\n *\n * PDF and OFFICE both render as DOCUMENT.\n * ARCHIVE and ALL are GENERIC (no specialized renderer).\n */\nconst FILE_NATURE_TO_DISPLAY_NATURE: Record<FileNature, FileDisplayNature> = {\n [FileNature.IMAGE]: FileDisplayNature.IMAGE,\n [FileNature.VIDEO]: FileDisplayNature.VIDEO,\n [FileNature.AUDIO]: FileDisplayNature.AUDIO,\n [FileNature.PDF]: FileDisplayNature.DOCUMENT,\n [FileNature.OFFICE]: FileDisplayNature.DOCUMENT,\n [FileNature.ARCHIVE]: FileDisplayNature.GENERIC,\n [FileNature.ALL]: FileDisplayNature.GENERIC,\n};\n\n/**\n * Detect `FileDisplayNature` from a MIME type string.\n *\n * Used as a fallback when no `FileNature` is declared in schema metadata.\n */\nfunction detectDisplayNatureFromMimeType(mimeType: string): FileDisplayNature {\n if (mimeType.startsWith('image/')) return FileDisplayNature.IMAGE;\n if (mimeType.startsWith('video/')) return FileDisplayNature.VIDEO;\n if (mimeType.startsWith('audio/')) return FileDisplayNature.AUDIO;\n if (\n mimeType === 'application/pdf' ||\n mimeType.includes('document') || mimeType.includes('word') ||\n mimeType.includes('spreadsheet') || mimeType.includes('excel') ||\n mimeType.includes('presentation') || mimeType.includes('powerpoint')\n ) return FileDisplayNature.DOCUMENT;\n return FileDisplayNature.GENERIC;\n}\n\n/**\n * Resolve the rendering-level display nature for a file.\n *\n * Resolution priority:\n * 1. `schemaNature` (from `z_file({ nature: ... })` metadata) → mapped via `FILE_NATURE_TO_DISPLAY_NATURE`\n * 2. `mimeType` (from file metadata or browser File object) → detected via MIME prefix matching\n * 3. `FileDisplayNature.GENERIC` (fallback)\n *\n * @param schemaNature - The `FileNature` declared in schema metadata (from `getFileMetadata(schema)?.nature`)\n * @param mimeType - The MIME type of the actual file\n * @returns The `FileDisplayNature` to use for rendering\n *\n * @example\n * ```typescript\n * const displayNature = resolveFileDisplayNature(fileSchemaMetadata?.nature, metadata.mimeType)\n * // FileDisplayNature.IMAGE | .VIDEO | .AUDIO | .DOCUMENT | .GENERIC\n * ```\n */\nexport function resolveFileDisplayNature(\n schemaNature?: FileNature,\n mimeType?: string,\n): FileDisplayNature {\n // Priority 1: Schema-declared nature\n if (schemaNature) {\n return FILE_NATURE_TO_DISPLAY_NATURE[schemaNature] ?? FileDisplayNature.GENERIC;\n }\n // Priority 2: MIME type detection\n if (mimeType) {\n return detectDisplayNatureFromMimeType(mimeType);\n }\n // Priority 3: Fallback\n return FileDisplayNature.GENERIC;\n}\n\n// ============================================================================\n// DISPLAY POLICY RESOLUTION (presentation × activation, + the availability guard)\n// ============================================================================\n\n/**\n * Whether the engine can RENDER a file of this nature/MIME (i.e. whether\n * `THUMBNAIL` / `FULL` presentation and `OVERLAY` activation are satisfiable).\n *\n * Nature alone is not always enough: `DOCUMENT` covers PDF *and* Office, and only\n * PDF has a viewer — so the MIME decides when it is known. Extend this (and only\n * this) when a new displayer ships; every guard tier reads it, so availability can\n * never drift between the static and runtime answers.\n */\nexport function fileNatureHasDisplayer(\n displayNature: FileDisplayNature,\n mimeType?: string,\n): boolean {\n switch (displayNature) {\n case FileDisplayNature.IMAGE:\n case FileDisplayNature.VIDEO:\n case FileDisplayNature.AUDIO:\n return true;\n case FileDisplayNature.DOCUMENT:\n // PDF renders (PDF.js); Office documents have no viewer yet. With no MIME\n // known (the static tier on a declared PDF nature) the answer is yes,\n // because `FileNature.PDF` maps here only for PDFs.\n return mimeType === undefined || mimeType === 'application/pdf';\n case FileDisplayNature.GENERIC:\n return false;\n }\n}\n\n/**\n * Whether a DECLARED schema nature can satisfy a display-requiring policy, decided\n * WITHOUT a MIME type. This is the static (registry-build) tier of the guard.\n *\n * Returns `undefined` for `FileNature.ALL` — genuinely undecidable before the file\n * exists, so the static tier must admit it and the runtime tier decides. Any other\n * nature yields a definite answer, which is what lets a misauthored\n * `ARCHIVE` + `FULL` fail at build instead of rendering nothing at runtime.\n */\nexport function declaredFileNatureCanDisplay(schemaNature: FileNature): boolean | undefined {\n if (schemaNature === FileNature.ALL) return undefined;\n return fileNatureHasDisplayer(FILE_NATURE_TO_DISPLAY_NATURE[schemaNature] ?? FileDisplayNature.GENERIC);\n}\n\n/** Outcome of {@link resolveFileDisplayPolicy}. */\nexport interface ResolvedFileDisplayPolicy {\n /** Effective resting presentation after the availability guard. */\n presentation: FileDisplayPresentation;\n /** Effective activation after the availability guard. */\n activation: FileActivationConfig;\n /** The nature the effective policy was resolved against. */\n displayNature: FileDisplayNature;\n /** True when the authored policy could not be satisfied and was degraded. */\n degraded: boolean;\n /** Human-readable cause, for the dev-only warning. Set iff `degraded`. */\n degradationReason?: string;\n}\n\n/**\n * Resolve the effective file display policy — the RUNTIME tier of the guard.\n *\n * Defaults, when nothing is authored: `CARD` presentation, and an activation derived\n * from the nature (`OVERLAY` when a displayer exists, `DOWNLOAD` otherwise) — so a\n * file is always useful without any authoring, and a document does not mount a\n * viewer just by being on the page.\n *\n * Degradation is deterministic, never a crash and never a dead control:\n * `FULL`/`THUMBNAIL` → `CARD`, `OVERLAY` → `DOWNLOAD`. It only fires when the file's\n * actual nature has no displayer — which is only reachable when the schema declared\n * an open nature (`FileNature.ALL`), because a narrow declared nature that cannot\n * display was already refused at registry build.\n *\n * `CUSTOM` is never degraded: it targets an operation, not a displayer, so displayer\n * availability is irrelevant to it.\n */\nexport function resolveFileDisplayPolicy(params: {\n schemaNature?: FileNature;\n mimeType?: string;\n authored?: FileUIDisplayParams;\n}): ResolvedFileDisplayPolicy {\n const { schemaNature, mimeType, authored } = params;\n const displayNature = resolveFileDisplayNature(schemaNature, mimeType);\n const hasDisplayer = fileNatureHasDisplayer(displayNature, mimeType);\n\n const requestedPresentation = authored?.presentation ?? FileDisplayPresentation.CARD;\n const requestedActivation: FileActivationConfig = authored?.activation ?? {\n policy: hasDisplayer ? FileActivationPolicy.OVERLAY : FileActivationPolicy.DOWNLOAD,\n };\n\n const presentationNeedsDisplayer = requestedPresentation !== FileDisplayPresentation.CARD;\n const activationNeedsDisplayer = requestedActivation.policy === FileActivationPolicy.OVERLAY;\n\n if (hasDisplayer || (!presentationNeedsDisplayer && !activationNeedsDisplayer)) {\n return { presentation: requestedPresentation, activation: requestedActivation, displayNature, degraded: false };\n }\n\n return {\n presentation: presentationNeedsDisplayer ? FileDisplayPresentation.CARD : requestedPresentation,\n activation: activationNeedsDisplayer ? { policy: FileActivationPolicy.DOWNLOAD } : requestedActivation,\n displayNature,\n degraded: true,\n degradationReason:\n `no displayer for ${displayNature}${mimeType ? ` (${mimeType})` : ''}: `\n + `${presentationNeedsDisplayer ? `presentation ${requestedPresentation} → card` : ''}`\n + `${presentationNeedsDisplayer && activationNeedsDisplayer ? ', ' : ''}`\n + `${activationNeedsDisplayer ? 'activation overlay → download' : ''}`,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"zod-file.js","sourceRoot":"","sources":["../../../src/zod-file.ts"],"names":[],"mappings":"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","sourcesContent":["\n// ============================================================================\n// FILE SCHEMA HELPER\n// ============================================================================\n\n\nimport {\n DecoratorInput,\n SCHEMA_METADATA,\n CustomFieldMetadata,\n FileSchemaMetadata,\n FileSchemaOptions,\n FileMimeTypeGroups,\n FileMimeTypeGroup,\n FileNature,\n FileDisplayNature,\n FileDisplayPresentation,\n FileActivationPolicy,\n type FileActivationConfig,\n type FileUIDisplayParams,\n FileStorageAccepted,\n FileNatureConstraints_Image,\n FileNatureConstraints_Video,\n FileNatureConstraints_Audio,\n FileNatureConstraints_Document,\n FileGenerationConfig,\n FileGenerationSource,\n RagSourceConfiguration,\n ZodDecorator,\n ZodDecorator_ParamsType\n} from \"./zod-decorators.types\";\nimport { z } from \"zod\";\nimport { addChainableMethods, addDecorators } from \"./zod.module-override\";\nimport { UnifiedFileFormatRegistry } from \"./files/unified-registry\";\nimport { AgentFileFormat } from \"./files/agent-file-formats\";\n\n// Minimal console declaration — avoids pulling in 'dom' or '@types/node' into this shared lib\ndeclare const console: { warn(...args: unknown[]): void };\n\n/**\n * Deduplicated warning tracker for unsupported storage providers.\n * Prevents console spam when the same schema is created multiple times (e.g., in tests or HMR).\n */\nconst _warnedStorageProviders = new Set<string>();\n/**\n * The storages an `IFileStorageProvider` exists for. `GOOGLE_DRIVE` joined on\n * 2026-09-09 (#394 P5): its bytes stay in Drive, read and written through the\n * connected account of the person who linked or uploaded them. `ONEDRIVE` and\n * `DROPBOX` remain declared-but-unserved until each gets a provider.\n */\nconst _supportedProviders = new Set([FileStorageAccepted.WILDO_MANAGED, FileStorageAccepted.LOCAL_DIRECTORY, FileStorageAccepted.GOOGLE_DRIVE]);\nconst GENERATED_PDF_MIME_TYPES = ['application/pdf'] as const;\nconst GENERATION_METADATA_KEYS = new Set(['source', 'templateId']);\n\n/**\n * Single file value type - represents a single file reference stored in the database.\n * The actual file is stored in a file storage system, this object references it.\n */\nexport interface SingleFileValue {\n /** File ID (foreign key to file storage) */\n fileId: string;\n /** Last update timestamp */\n updatedAt: Date;\n\n}\n\n/**\n * Multiple files value type - represents multiple file references stored in the database.\n */\nexport interface MultipleFileValue {\n /** File IDs (foreign keys to file storage) */\n fileIds: string[];\n /** Last update timestamp */\n updatedAt: Date;\n}\n\n/**\n * File value type - can be single or multiple depending on schema configuration.\n */\nexport type FileValue = SingleFileValue | MultipleFileValue;\n\n/**\n * Zod schema for SingleFileValue.\n */\nexport const SingleFileValueSchema: z.ZodObject<{ fileId: z.ZodString; updatedAt: z.ZodDate }> = z.object({\n fileId: z.string().min(1),\n updatedAt: z.date(),\n});\n\n/**\n * Zod schema for MultipleFileValue.\n */\nexport const MultipleFileValueSchema: z.ZodObject<{ fileIds: z.ZodArray<z.ZodString>; updatedAt: z.ZodDate }> = z.object({\n fileIds: z.array(z.string().min(1)),\n updatedAt: z.date(),\n});\n\n\n/**\n * Resolve MIME type groups to actual MIME types.\n * Handles both single group names and arrays of groups/MIME types.\n */\nexport function resolveMimeTypes(\n allowedMimeTypes: string[] | FileMimeTypeGroup | FileMimeTypeGroup[] | undefined\n): string[] | undefined {\n if (!allowedMimeTypes) return undefined;\n\n // If it's a single group name\n if (typeof allowedMimeTypes === 'string') {\n if (allowedMimeTypes in FileMimeTypeGroups) {\n return [...FileMimeTypeGroups[allowedMimeTypes as FileMimeTypeGroup]];\n }\n // Single MIME type\n return [allowedMimeTypes];\n }\n\n // If it's an array\n if (Array.isArray(allowedMimeTypes)) {\n const resolved: string[] = [];\n for (const item of allowedMimeTypes) {\n if (item in FileMimeTypeGroups) {\n // It's a group name\n resolved.push(...FileMimeTypeGroups[item as FileMimeTypeGroup]);\n } else {\n // It's a MIME type\n resolved.push(item);\n }\n }\n // Remove duplicates\n return [...new Set(resolved)];\n }\n\n return undefined;\n}\n\nfunction assertValidFileGenerationConfig(generation: FileGenerationConfig): void {\n const rawGeneration = generation as unknown as Record<string, unknown> | undefined;\n if (!rawGeneration || typeof rawGeneration !== 'object' || Array.isArray(rawGeneration)) {\n throw new Error('[z_file] generation must be an object.');\n }\n\n const extraKeys = Object.keys(rawGeneration).filter((key) => !GENERATION_METADATA_KEYS.has(key));\n if (extraKeys.length > 0) {\n throw new Error(\n `[z_file] generation contains unsupported key(s): ${extraKeys.join(', ')}. ` +\n 'Use only { source: FileGenerationSource.PDF_TEMPLATE, templateId }.'\n );\n }\n\n if (rawGeneration.source !== FileGenerationSource.PDF_TEMPLATE) {\n throw new Error('[z_file] generation.source must be FileGenerationSource.PDF_TEMPLATE.');\n }\n\n if (typeof rawGeneration.templateId !== 'string' || rawGeneration.templateId.trim().length === 0) {\n throw new Error('[z_file] generation.templateId must be a non-empty string.');\n }\n}\n\nfunction assertGeneratedPdfFileOptions(params: {\n generation?: FileGenerationConfig;\n multiple: boolean;\n resolvedMimeTypes?: string[];\n overridable: boolean;\n ragSource?: RagSourceConfiguration;\n scanPolicy?: unknown;\n}): void {\n if (!params.generation) return;\n\n assertValidFileGenerationConfig(params.generation);\n\n if (params.multiple) {\n throw new Error('[z_file] PDF template generation supports single-file fields only.');\n }\n\n if (params.overridable === false) {\n throw new Error('[z_file] PDF template generation requires overridable to remain true so framework REGENERATE can replace the generated file.');\n }\n\n // Re-expression of the pre-Phase-0 `rag` refusal against the shared decorator: a PDF-template\n // output is framework-RENDERED presentation of resource data the corpus can already reach at the\n // source fields — chunking the rendering would index the same facts twice, keyed to a file the\n // next REGENERATE silently replaces.\n if (params.ragSource) {\n throw new Error('[z_file] PDF template generation cannot be combined with RAG ingestion options.');\n }\n\n if (params.scanPolicy) {\n throw new Error('[z_file] PDF template generation cannot be combined with upload scanPolicy options.');\n }\n\n if (\n params.resolvedMimeTypes !== undefined &&\n (params.resolvedMimeTypes.length !== 1 || params.resolvedMimeTypes[0] !== GENERATED_PDF_MIME_TYPES[0])\n ) {\n throw new Error('[z_file] PDF template generation requires allowedMimeTypes to resolve exactly to application/pdf.');\n }\n}\n\n/**\n * z_file() - Creates file schemas for file uploads.\n *\n * File values are stored as: { fileId: string, updatedAt: Date }\n * - fileId: Reference to the file in storage (foreign key, indexed)\n * - updatedAt: When the file was last updated\n *\n * @example\n * ```typescript\n * import { z_file } from '@wildo-ai/zod-decorators';\n *\n * const avatar = z_file();\n * const document = z_file({ allowedMimeTypes: 'Documents' });\n * const images = z_file({\n * allowedMimeTypes: 'Images',\n * maxSize: 5 * 1024 * 1024, // 5MB\n * overridable: true\n * });\n *\n * // With decorators (chainable)\n * z_file().fileUI({ edit: { editMode: FileEditMode.DROPZONE } })\n * z_file({ allowedMimeTypes: ['Images', 'PDF'] }).isHidden({ edit: true })\n * ```\n */\n\n/**\n * @wildo_source:part:start zod.decorators.file-schema\n *\n * Creates a file schema with metadata for detection and form component rendering.\n *\n * ## Where a file field may be declared\n *\n * **The resource's primary scope must be application, organization or user.** A resource scoped to\n * an ANONYMOUS visitor cannot carry a file field — a file's own scope is one of those three, so\n * there is nothing to attribute the bytes to, and the upload refuses that scope by name rather than\n * pretending to support it.\n *\n * **Within the schema, a file field may nest inside objects, arrays and DISCRIMINATED unions.** It\n * may NOT sit inside a record, a map, a set, a tuple, or a plain (non-discriminated) union — the\n * walker that finds file fields refuses those shapes. Where variants are needed, use a discriminated\n * union.\n *\n * **A field carried on several branches of a discriminated union must declare IDENTICAL options on\n * every branch.** Differing options at one path are a conflict the framework refuses rather than\n * choosing between, so a branch that quietly widens `maxSize` or changes `allowedMimeTypes` fails\n * the schema instead of silently winning.\n *\n * ## Uploading is not attaching\n *\n * The generated upload route creates a FILE ROW. Attaching it to a business record is that record's\n * own write, with its own authority. So an uploaded-but-never-submitted file is a real state a\n * caller can produce; the cleanup sweep is what handles it.\n *\n * ## Declaring `imageConstraints.aspectRatio` turns the cropper on\n *\n * That option is the switch for the browser-side crop step — nothing else is wired. It applies to\n * single-file fields only: a `multiple` field keeps the plain upload path. Vector images and\n * formats the browser cannot decode bypass the cropper and upload the original, so the server-side\n * constraint stays the authority.\n *\n * @param options - Configuration options for file field\n * @returns A Zod object schema with metadata for file detection\n */\nexport function createFileSchema(\n options: FileSchemaOptions = {}\n): DecoratedFileSchema | DecoratedMultipleFileSchema {\n const {\n overridable = true,\n allowedMimeTypes,\n maxSize,\n minSize,\n multiple = false,\n maxFiles,\n nature,\n storageAccepted,\n filePathBinding,\n generation,\n imageConstraints,\n videoConstraints,\n audioConstraints,\n documentConstraints,\n ragSource,\n textExtraction,\n scanPolicy,\n onParentDelete = 'cascade',\n sharable,\n sharableDefaults,\n } = options;\n\n // Warn at schema creation for a storage no provider serves yet — a declared vocabulary member with no implementation\n // Uses deduplication to avoid console spam during tests or HMR\n if (storageAccepted && storageAccepted.some(s => !_supportedProviders.has(s))) {\n const unsupported = storageAccepted.filter(s => !_supportedProviders.has(s));\n const warnKey = unsupported.sort().join(',');\n if (!_warnedStorageProviders.has(warnKey)) {\n _warnedStorageProviders.add(warnKey);\n // The two cases are NOT the same outcome, and saying only \"skipped\" understates the second\n // badly enough to be misleading: alongside an implemented storage the declaration really is\n // ignored, but as the ONLY declared storage it stops the application booting. That is the\n // split #460 records, stated here at the moment an author writes the declaration — earlier\n // than the startup validator and the storage router, which draw the same distinction.\n console.warn(\n `[z_file] storageAccepted names storage(s) no provider serves yet: ${unsupported.join(', ')}. ` +\n `Implemented: ${[..._supportedProviders].map((s) => `'${s}'`).join(', ')}. ` +\n `Declared ALONGSIDE an implemented storage it is skipped by the storage router; declared as the ONLY ` +\n `storage the application refuses to boot and every upload to this field is refused. There is no ` +\n `environment variable that would enable it — a storage with no provider cannot be configured into existence.`\n );\n }\n }\n\n if (filePathBinding) {\n if (filePathBinding.multipleFilePolicy && !multiple) {\n console.warn(\n '[z_file] filePathBinding.multipleFilePolicy is set but multiple is false — multipleFilePolicy will be ignored. ' +\n 'Either set multiple: true or remove multipleFilePolicy.'\n );\n }\n if (filePathBinding.fileName && multiple) {\n console.warn(\n '[z_file] filePathBinding.fileName is set on a multiple file field — fileName is ignored for multiple uploads. ' +\n 'Use filePathBinding.multipleFilePolicy.fileNameTemplate instead.'\n );\n }\n // Warned for EVERY provider, not only WILDO_MANAGED. The condition used to exempt a field that\n // named LOCAL_DIRECTORY, because that provider defaulted to `false` anyway and the warning would\n // have fired on its own default. Both providers now default to `true` and both honour `false`\n // identically, so `false` is an explicit opt-out of the tenant-scoped key shape wherever it is\n // authored — and that is the thing worth saying out loud.\n if (filePathBinding.includeApplicationId === false) {\n console.warn(\n '[z_file] filePathBinding.includeApplicationId is false. Storage keys for this field will carry ' +\n 'NO applications/<appId>/files/<resource>/<scope>/<scopeId>/ prefix, so per-tenant listing, ' +\n 'erasure sweeps and prefix-confined credentials cannot address them — ensure that is intended.'\n );\n }\n }\n\n // Resolve MIME type groups to actual MIME types\n const resolvedMimeTypes = resolveMimeTypes(allowedMimeTypes);\n assertGeneratedPdfFileOptions({ generation, multiple, resolvedMimeTypes, overridable, ragSource, scanPolicy });\n const effectiveMimeTypes = generation ? [...GENERATED_PDF_MIME_TYPES] : resolvedMimeTypes;\n\n // Create the file object schema based on single/multiple\n const fileSchema = multiple\n ? z.object({\n fileIds: z.array(z.string().min(1)),\n updatedAt: z.date(),\n })\n : z.object({\n fileId: z.string().min(1),\n updatedAt: z.date(),\n });\n\n // No longer stored in metadata — consumers derive accept from allowedMimeTypes via buildAcceptAttribute()\n\n // Store file metadata in SCHEMA_METADATA.fileConfig\n const fileMetadata: FileSchemaMetadata = {\n isFile: true,\n overridable,\n ...(effectiveMimeTypes !== undefined && { allowedMimeTypes: effectiveMimeTypes }),\n ...(maxSize !== undefined && { maxSize }),\n ...(minSize !== undefined && { minSize }),\n multiple,\n ...(maxFiles !== undefined && { maxFiles }),\n ...(nature !== undefined && { nature }),\n ...(storageAccepted !== undefined && { storageAccepted }),\n ...(filePathBinding !== undefined && { filePathBinding }),\n ...(generation !== undefined && { generation }),\n ...(imageConstraints !== undefined && { imageConstraints }),\n ...(videoConstraints !== undefined && { videoConstraints }),\n ...(audioConstraints !== undefined && { audioConstraints }),\n ...(documentConstraints !== undefined && { documentConstraints }),\n // Text-provider config only — the RAG declaration itself is NOT stored here (single source of\n // truth is the RAG_SOURCE decorator registered below; read it with `getRagSourceConfig`).\n ...(textExtraction !== undefined && { textExtraction }),\n ...(scanPolicy !== undefined && { scanPolicy }),\n onParentDelete,\n ...(sharable !== undefined && { sharable }),\n ...(sharableDefaults !== undefined && { sharableDefaults }),\n };\n\n // Initialize or extend SCHEMA_METADATA with file config\n const existingMetadata: CustomFieldMetadata = (fileSchema as any)[SCHEMA_METADATA] || {};\n (fileSchema as any)[SCHEMA_METADATA] = {\n ...existingMetadata,\n fileConfig: fileMetadata,\n };\n\n // Add chainable decorator methods to the file schema instance\n addChainableMethods(fileSchema);\n\n // Map the file-side `ragSource` option onto the SHARED RAG_SOURCE decorator — the same one\n // `z.string().ragSource()` registers — so `RagSourceFieldDetection` sees one uniform declaration\n // regardless of text provider. Registered through `addDecorators` (the escape-hatch door) because\n // the fluent `.ragSource()` is deliberately not installed on ZodObject; the shared chokepoint\n // still validates the config and enforces the refused companions identically.\n if (ragSource !== undefined) {\n addDecorators(fileSchema, [{ ref: ZodDecorator.RAG_SOURCE, params: ragSource }]);\n }\n\n if (multiple) {\n return fileSchema as unknown as DecoratedMultipleFileSchema;\n }\n return fileSchema as unknown as DecoratedFileSchema;\n}\n\n/**\n * File schemas declare NO decorator surface of their own.\n *\n * They used to, via a `FileSchemaDecoratorMethods<TSelf>` mixin that re-declared `isDBIndexed`,\n * `isHidden`, `isNotEditable` and `showWhen` with the return narrowed to the file schema — necessary\n * only because the `ZodObject` module augmentation did not carry them. It now does (2026-08-12), and\n * re-declaring them made both interfaces below fail TS2320: an interface may not extend two types\n * whose same-named member differs, and `TSelf` is not `DecoratedPrimitiveZodType<this>`.\n *\n * Removing the mixin costs nothing, because `DecoratedPrimitiveZodType<T>` is `T & { … }` — an\n * INTERSECTION. `z_file().isHidden()` still returns something assignable to `DecoratedFileSchema`,\n * and the full decorator surface is now available rather than the four this mixin listed.\n */\n\n/**\n * Return type for single file schemas - includes decorator methods.\n * IS_DB_INDEXED will index the fileId field for query optimization.\n *\n * Uses `interface` instead of `type` to allow self-referencing without circular alias errors.\n */\nexport interface DecoratedFileSchema extends z.ZodObject<{\n fileId: z.ZodString;\n updatedAt: z.ZodDate;\n}> {\n /**\n * Declared here, as the sibling factories declare theirs (`DecoratedMoneySchema.moneyUI`,\n * `DecoratedPhoneSchema.phoneUI`, …), because a file's display and edit policy is authored on\n * the factory's output and nowhere else. The applyable-type map admits `fileUI` on `ZodObject`,\n * but a bare `z.object({...})` is not a file, so the base prototype deliberately does not carry\n * it — the per-instance install `createFileSchema` performs is what makes it reachable.\n *\n * Not a RE-declaration: `fileUI` is absent from the `ZodObject` module augmentation, so this adds\n * a member rather than conflicting with one. That distinction is what the TS2320 note above is\n * about — re-declaring a member the augmentation already carries is what broke here before.\n */\n [ZodDecorator.FILE_UI](params?: ZodDecorator_ParamsType[ZodDecorator.FILE_UI]): DecoratedFileSchema;\n [ZodDecorator.FILE_SPEC](params?: ZodDecorator_ParamsType[ZodDecorator.FILE_SPEC]): DecoratedFileSchema;\n}\n\n/**\n * Return type for multiple file schemas - includes decorator methods.\n * IS_DB_INDEXED will index the fileIds array for query optimization.\n *\n * Uses `interface` instead of `type` to allow self-referencing without circular alias errors.\n */\nexport interface DecoratedMultipleFileSchema extends z.ZodObject<{\n fileIds: z.ZodArray<z.ZodString>;\n updatedAt: z.ZodDate;\n}> {\n /**\n * Declared here, as the sibling factories declare theirs (`DecoratedMoneySchema.moneyUI`,\n * `DecoratedPhoneSchema.phoneUI`, …), because a file's display and edit policy is authored on\n * the factory's output and nowhere else. The applyable-type map admits `fileUI` on `ZodObject`,\n * but a bare `z.object({...})` is not a file, so the base prototype deliberately does not carry\n * it — the per-instance install `createFileSchema` performs is what makes it reachable. Mirrors the single-file interface above.\n *\n * Not a RE-declaration: `fileUI` is absent from the `ZodObject` module augmentation, so this adds\n * a member rather than conflicting with one. That distinction is what the TS2320 note above is\n * about — re-declaring a member the augmentation already carries is what broke here before.\n */\n [ZodDecorator.FILE_UI](params?: ZodDecorator_ParamsType[ZodDecorator.FILE_UI]): DecoratedMultipleFileSchema;\n [ZodDecorator.FILE_SPEC](params?: ZodDecorator_ParamsType[ZodDecorator.FILE_SPEC]): DecoratedMultipleFileSchema;\n}\n\n/**\n * Creates a file schema for file uploads with reference storage.\n * Named z_file to indicate it's a Zod helper function exported standalone.\n *\n * Single file values are stored as: { fileId: string, updatedAt: Date }\n * Multiple file values are stored as: { fileIds: string[], updatedAt: Date }\n *\n * @example\n * ```typescript\n * import { z_file } from '@wildo-ai/zod-decorators';\n *\n * // Simple usage - single file, any type\n * z_file()\n *\n * // With MIME type groups (shortcuts)\n * z_file({ allowedMimeTypes: 'Images' })\n * z_file({ allowedMimeTypes: 'PDF' })\n * z_file({ allowedMimeTypes: ['Images', 'Video'] })\n * z_file({ allowedMimeTypes: 'Documents' }) // PDF + Office\n *\n * // With specific MIME types\n * z_file({ allowedMimeTypes: ['image/png', 'image/jpeg'] })\n *\n * // With size constraints\n * z_file({ maxSize: 10 * 1024 * 1024 }) // 10MB max\n *\n * // Multiple files (uses fileIds instead of fileId)\n * z_file({ multiple: true, maxFiles: 5 })\n *\n * // Non-overridable (append-only)\n * z_file({ overridable: false })\n *\n * // RAG corpus source — registers the shared RAG_SOURCE decorator on the returned schema\n * // (chunking config), with the file-side text-provider knobs beside it (OCR opt-in).\n * z_file({ allowedMimeTypes: 'Documents', ragSource: {}, textExtraction: { ocr: true } })\n *\n * // With decorators\n * z_file().fileUI({ edit: { editMode: FileEditMode.DROPZONE } })\n * z_file().isHidden({ display: true })\n * ```\n */\nexport function z_file(options?: FileSchemaOptions): DecoratedFileSchema | DecoratedMultipleFileSchema {\n return createFileSchema(options);\n}\n/** @wildo_source:part:end zod.decorators.file-schema */\n\n// ============================================================================\n// UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Format file size for display.\n */\nexport function formatFileSize(bytes: number): string {\n if (!Number.isFinite(bytes)) return '—';\n if (bytes === 0) return '0 B';\n if (bytes < 0) return '-' + formatFileSize(Math.abs(bytes));\n\n const units = ['B', 'KB', 'MB', 'GB', 'TB'];\n const k = 1024;\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${units[i]}`;\n}\n\n/**\n * Build enhanced accept attribute string from MIME types.\n * Includes both MIME types and extensions for better browser compatibility.\n * Format: \"image/*,.jpg,.jpeg,.png\" or \"application/pdf,.pdf\"\n *\n * @param mimeTypes - Array of MIME type strings\n * @returns Accept attribute string with MIME types and extensions\n */\nexport function buildAcceptAttribute(mimeTypes: string[]): string {\n if (!mimeTypes || mimeTypes.length === 0) return '';\n\n const parts = new Set<string>();\n const extensions = new Set<string>();\n\n for (const mimeType of mimeTypes) {\n // Add MIME type\n parts.add(mimeType);\n\n // Get extensions for this MIME type\n const mimeExtensions = UnifiedFileFormatRegistry.getExtensions(mimeType);\n for (const ext of mimeExtensions) {\n if (ext) {\n extensions.add(`.${ext}`);\n }\n }\n\n // Also check if it's a wildcard MIME type (e.g., image/*)\n // In that case, get all extensions for that nature\n if (mimeType.endsWith('/*')) {\n const formatType = UnifiedFileFormatRegistry.getFormatTypeFromMimeType(mimeType);\n\n if (formatType && formatType.type === 'nature') {\n const natureExtensions = UnifiedFileFormatRegistry.getExtensionsForNature(formatType.nature);\n for (const ext of natureExtensions) {\n if (ext) {\n extensions.add(`.${ext}`);\n }\n }\n }\n }\n }\n\n // Combine MIME types and extensions\n const allParts = [...parts, ...extensions];\n return allParts.join(',');\n}\n\n/**\n * Get file extension from filename.\n * Uses UnifiedFileFormatRegistry for consistency.\n */\nexport function getFileExtension(filename: string): string {\n return UnifiedFileFormatRegistry.getFileExtension(filename);\n}\n\n/**\n * Check if a MIME type is allowed based on allowed types.\n */\nexport function isMimeTypeAllowed(mimeType: string, allowedMimeTypes?: string[]): boolean {\n if (!allowedMimeTypes || allowedMimeTypes.length === 0) return true;\n\n // Check exact match\n if (allowedMimeTypes.includes(mimeType)) return true;\n\n // Check wildcard match (e.g., \"image/*\")\n const [type] = mimeType.split('/');\n if (allowedMimeTypes.includes(`${type}/*`)) return true;\n\n return false;\n}\n\n/**\n * How an accepted file type is identified — the discriminator of {@link AcceptedFileKind}.\n */\nexport enum AcceptedFileKindCategory {\n /** A broad nature (images, PDF, office documents, …) — one {@link FileNature} member. */\n NATURE = 'nature',\n /** A text format an agent can produce — one {@link AgentFileFormat} member. */\n AGENT_FORMAT = 'agent_format',\n /** Neither: the MIME subtype itself (`csv` for `text/csv`), shown as the value it is. */\n MIME_SUBTYPE = 'mime_subtype',\n}\n\n/** One kind of file a field accepts, as a FACT a renderer names — never as words. */\nexport type AcceptedFileKind =\n | { category: AcceptedFileKindCategory.NATURE; nature: FileNature }\n | { category: AcceptedFileKindCategory.AGENT_FORMAT; format: AgentFileFormat }\n | { category: AcceptedFileKindCategory.MIME_SUBTYPE; subtype: string };\n\nconst AGENT_FILE_FORMAT_VALUES: ReadonlySet<string> = new Set(Object.values(AgentFileFormat));\n\n/**\n * The kinds of file a field's `allowedMimeTypes` admit, deduplicated, in first-seen order. An empty\n * result means every file is accepted.\n *\n * This answers FACTS and the renderer names them from its label tree. It used to answer an English\n * sentence (\"Images, PDF, Text files\") from two hand-kept maps plus a humanizing fallback — words\n * produced by code in a package with no i18n at all, which no locale could translate (#1283,\n * `.claude/rules/display-text-comes-from-i18n.md`).\n *\n * Resolution per MIME type: the unified format registry first (a nature, or an agent format), then\n * the broad MIME families the registry does not classify, then the subtype as a value.\n */\nexport function getAcceptedFileKinds(allowedMimeTypes?: string[]): AcceptedFileKind[] {\n if (!allowedMimeTypes || allowedMimeTypes.length === 0) return [];\n\n const kinds: AcceptedFileKind[] = [];\n const seen = new Set<string>();\n const add = (kind: AcceptedFileKind, identity: string): void => {\n if (seen.has(identity)) return;\n seen.add(identity);\n kinds.push(kind);\n };\n const addNature = (nature: FileNature): void => add({ category: AcceptedFileKindCategory.NATURE, nature }, `nature:${nature}`);\n\n for (const mime of allowedMimeTypes) {\n const formatType = UnifiedFileFormatRegistry.getFormatTypeFromMimeType(mime);\n if (formatType?.type === 'nature') {\n addNature(formatType.nature);\n continue;\n }\n if (formatType?.type === 'agent' && AGENT_FILE_FORMAT_VALUES.has(formatType.format)) {\n const format = formatType.format as AgentFileFormat;\n add({ category: AcceptedFileKindCategory.AGENT_FORMAT, format }, `agent:${format}`);\n continue;\n }\n\n if (mime === 'application/pdf') addNature(FileNature.PDF);\n else if (mime.startsWith('image/')) addNature(FileNature.IMAGE);\n else if (mime.startsWith('video/')) addNature(FileNature.VIDEO);\n else if (mime.startsWith('audio/')) addNature(FileNature.AUDIO);\n else if (mime.includes('document') || mime.includes('word') || mime.includes('excel') || mime.includes('powerpoint')) addNature(FileNature.OFFICE);\n else {\n const subtype = mime.split('/').pop();\n if (subtype) add({ category: AcceptedFileKindCategory.MIME_SUBTYPE, subtype }, `subtype:${subtype}`);\n }\n }\n return kinds;\n}\n\n/**\n * Get file nature from schema metadata.\n * @param schema - Zod schema (must be a file schema)\n * @returns FileNature or undefined if not set\n */\nexport function getFileNature(schema: z.ZodTypeAny): FileNature | undefined {\n const metadata = (schema as any)[SCHEMA_METADATA] as CustomFieldMetadata | undefined;\n return metadata?.fileConfig?.nature;\n}\n\n/**\n * Get storage accepted from schema metadata.\n * @param schema - Zod schema (must be a file schema)\n * @returns Array of FileStorageAccepted or undefined if not set\n */\nexport function getStorageAccepted(schema: z.ZodTypeAny): FileStorageAccepted[] | undefined {\n const metadata = (schema as any)[SCHEMA_METADATA] as CustomFieldMetadata | undefined;\n return metadata?.fileConfig?.storageAccepted;\n}\n\n/**\n * Get file constraints from schema metadata.\n * @param schema - Zod schema (must be a file schema)\n * @returns Object with all constraint properties or undefined if not set\n */\nexport function getFileConstraints(schema: z.ZodTypeAny): {\n imageConstraints?: FileNatureConstraints_Image;\n videoConstraints?: FileNatureConstraints_Video;\n audioConstraints?: FileNatureConstraints_Audio;\n documentConstraints?: FileNatureConstraints_Document;\n} | undefined {\n const metadata = (schema as any)[SCHEMA_METADATA] as CustomFieldMetadata | undefined;\n const fileConfig = metadata?.fileConfig;\n if (!fileConfig) return undefined;\n\n const hasConstraints =\n fileConfig.imageConstraints ||\n fileConfig.videoConstraints ||\n fileConfig.audioConstraints ||\n fileConfig.documentConstraints;\n\n if (!hasConstraints) return undefined;\n\n return {\n ...(fileConfig.imageConstraints && { imageConstraints: fileConfig.imageConstraints }),\n ...(fileConfig.videoConstraints && { videoConstraints: fileConfig.videoConstraints }),\n ...(fileConfig.audioConstraints && { audioConstraints: fileConfig.audioConstraints }),\n ...(fileConfig.documentConstraints && { documentConstraints: fileConfig.documentConstraints }),\n };\n}\n\n// ============================================================================\n// DISPLAY NATURE RESOLUTION\n// ============================================================================\n\n/**\n * Mapping from schema-level `FileNature` to rendering-level `FileDisplayNature`.\n *\n * PDF and OFFICE both render as DOCUMENT.\n * ARCHIVE and ALL are GENERIC (no specialized renderer).\n */\nconst FILE_NATURE_TO_DISPLAY_NATURE: Record<FileNature, FileDisplayNature> = {\n [FileNature.IMAGE]: FileDisplayNature.IMAGE,\n [FileNature.VIDEO]: FileDisplayNature.VIDEO,\n [FileNature.AUDIO]: FileDisplayNature.AUDIO,\n [FileNature.PDF]: FileDisplayNature.DOCUMENT,\n [FileNature.OFFICE]: FileDisplayNature.DOCUMENT,\n [FileNature.ARCHIVE]: FileDisplayNature.GENERIC,\n [FileNature.ALL]: FileDisplayNature.GENERIC,\n};\n\n/**\n * Detect `FileDisplayNature` from a MIME type string.\n *\n * Used as a fallback when no `FileNature` is declared in schema metadata.\n */\nfunction detectDisplayNatureFromMimeType(mimeType: string): FileDisplayNature {\n if (mimeType.startsWith('image/')) return FileDisplayNature.IMAGE;\n if (mimeType.startsWith('video/')) return FileDisplayNature.VIDEO;\n if (mimeType.startsWith('audio/')) return FileDisplayNature.AUDIO;\n if (\n mimeType === 'application/pdf' ||\n mimeType.includes('document') || mimeType.includes('word') ||\n mimeType.includes('spreadsheet') || mimeType.includes('excel') ||\n mimeType.includes('presentation') || mimeType.includes('powerpoint')\n ) return FileDisplayNature.DOCUMENT;\n return FileDisplayNature.GENERIC;\n}\n\n/**\n * Resolve the rendering-level display nature for a file.\n *\n * Resolution priority:\n * 1. `schemaNature` (from `z_file({ nature: ... })` metadata) → mapped via `FILE_NATURE_TO_DISPLAY_NATURE`\n * 2. `mimeType` (from file metadata or browser File object) → detected via MIME prefix matching\n * 3. `FileDisplayNature.GENERIC` (fallback)\n *\n * `FileNature.ALL` is not a nature, it is the ABSENCE of a declaration: a field that accepts anything\n * says nothing about the file in front of it. So it does not decide at step 1 — the file's own MIME\n * type does, exactly as for a field with no declared nature. Until 2026-09-24 it mapped to GENERIC and\n * won, so every file in an open field, a PNG and a PDF included, resolved to GENERIC: no preview, and\n * an authored `OVERLAY` activation always degraded to a download. `resolveFileDisplayPolicy` already\n * describes the intended behaviour (\"the file's ACTUAL nature has no displayer — which is only\n * reachable when the schema declared an open nature\"); this is what makes that sentence true.\n * `FileNature.ARCHIVE` stays GENERIC at step 1, because that IS a declaration.\n *\n * @param schemaNature - The `FileNature` declared in schema metadata (from `getFileMetadata(schema)?.nature`)\n * @param mimeType - The MIME type of the actual file\n * @returns The `FileDisplayNature` to use for rendering\n *\n * @example\n * ```typescript\n * const displayNature = resolveFileDisplayNature(fileSchemaMetadata?.nature, metadata.mimeType)\n * // FileDisplayNature.IMAGE | .VIDEO | .AUDIO | .DOCUMENT | .GENERIC\n * ```\n */\nexport function resolveFileDisplayNature(\n schemaNature?: FileNature,\n mimeType?: string,\n): FileDisplayNature {\n // Priority 1: Schema-declared nature — `ALL` declares nothing, so it falls through to the file itself.\n if (schemaNature && schemaNature !== FileNature.ALL) {\n return FILE_NATURE_TO_DISPLAY_NATURE[schemaNature] ?? FileDisplayNature.GENERIC;\n }\n // Priority 2: MIME type detection\n if (mimeType) {\n return detectDisplayNatureFromMimeType(mimeType);\n }\n // Priority 3: Fallback\n return FileDisplayNature.GENERIC;\n}\n\n// ============================================================================\n// DISPLAY POLICY RESOLUTION (presentation × activation, + the availability guard)\n// ============================================================================\n\n/**\n * Whether the engine can RENDER a file of this nature/MIME (i.e. whether\n * `THUMBNAIL` / `FULL` presentation and `OVERLAY` activation are satisfiable).\n *\n * Nature alone is not always enough: `DOCUMENT` covers PDF *and* Office, and only\n * PDF has a viewer — so the MIME decides when it is known. Extend this (and only\n * this) when a new displayer ships; every guard tier reads it, so availability can\n * never drift between the static and runtime answers.\n */\nexport function fileNatureHasDisplayer(\n displayNature: FileDisplayNature,\n mimeType?: string,\n): boolean {\n switch (displayNature) {\n case FileDisplayNature.IMAGE:\n case FileDisplayNature.VIDEO:\n case FileDisplayNature.AUDIO:\n return true;\n case FileDisplayNature.DOCUMENT:\n // PDF renders (PDF.js); Office documents have no viewer yet. With no MIME\n // known (the static tier on a declared PDF nature) the answer is yes,\n // because `FileNature.PDF` maps here only for PDFs.\n return mimeType === undefined || mimeType === 'application/pdf';\n case FileDisplayNature.GENERIC:\n return false;\n }\n}\n\n/**\n * Whether a DECLARED schema nature can satisfy a display-requiring policy, decided\n * WITHOUT a MIME type. This is the static (registry-build) tier of the guard.\n *\n * Returns `undefined` for `FileNature.ALL` — genuinely undecidable before the file\n * exists, so the static tier must admit it and the runtime tier decides. Any other\n * nature yields a definite answer, which is what lets a misauthored\n * `ARCHIVE` + `FULL` fail at build instead of rendering nothing at runtime.\n */\nexport function declaredFileNatureCanDisplay(schemaNature: FileNature): boolean | undefined {\n if (schemaNature === FileNature.ALL) return undefined;\n return fileNatureHasDisplayer(FILE_NATURE_TO_DISPLAY_NATURE[schemaNature] ?? FileDisplayNature.GENERIC);\n}\n\n/** Outcome of {@link resolveFileDisplayPolicy}. */\nexport interface ResolvedFileDisplayPolicy {\n /** Effective resting presentation after the availability guard. */\n presentation: FileDisplayPresentation;\n /** Effective activation after the availability guard. */\n activation: FileActivationConfig;\n /** The nature the effective policy was resolved against. */\n displayNature: FileDisplayNature;\n /** True when the authored policy could not be satisfied and was degraded. */\n degraded: boolean;\n /** Human-readable cause, for the dev-only warning. Set iff `degraded`. */\n degradationReason?: string;\n}\n\n/**\n * Resolve the effective file display policy — the RUNTIME tier of the guard.\n *\n * Defaults, when nothing is authored: `CARD` presentation, and an activation derived\n * from the nature (`OVERLAY` when a displayer exists, `DOWNLOAD` otherwise) — so a\n * file is always useful without any authoring, and a document does not mount a\n * viewer just by being on the page.\n *\n * Degradation is deterministic, never a crash and never a dead control:\n * `FULL`/`THUMBNAIL` → `CARD`, `OVERLAY` → `DOWNLOAD`. It only fires when the file's\n * actual nature has no displayer — which is only reachable when the schema declared\n * an open nature (`FileNature.ALL`), because a narrow declared nature that cannot\n * display was already refused at registry build.\n *\n * `CUSTOM` is never degraded: it targets an operation, not a displayer, so displayer\n * availability is irrelevant to it.\n */\nexport function resolveFileDisplayPolicy(params: {\n schemaNature?: FileNature;\n mimeType?: string;\n authored?: FileUIDisplayParams;\n}): ResolvedFileDisplayPolicy {\n const { schemaNature, mimeType, authored } = params;\n const displayNature = resolveFileDisplayNature(schemaNature, mimeType);\n const hasDisplayer = fileNatureHasDisplayer(displayNature, mimeType);\n\n const requestedPresentation = authored?.presentation ?? FileDisplayPresentation.CARD;\n const requestedActivation: FileActivationConfig = authored?.activation ?? {\n policy: hasDisplayer ? FileActivationPolicy.OVERLAY : FileActivationPolicy.DOWNLOAD,\n };\n\n const presentationNeedsDisplayer = requestedPresentation !== FileDisplayPresentation.CARD;\n const activationNeedsDisplayer = requestedActivation.policy === FileActivationPolicy.OVERLAY;\n\n if (hasDisplayer || (!presentationNeedsDisplayer && !activationNeedsDisplayer)) {\n return { presentation: requestedPresentation, activation: requestedActivation, displayNature, degraded: false };\n }\n\n return {\n presentation: presentationNeedsDisplayer ? FileDisplayPresentation.CARD : requestedPresentation,\n activation: activationNeedsDisplayer ? { policy: FileActivationPolicy.DOWNLOAD } : requestedActivation,\n displayNature,\n degraded: true,\n degradationReason:\n `no displayer for ${displayNature}${mimeType ? ` (${mimeType})` : ''}: `\n + `${presentationNeedsDisplayer ? `presentation ${requestedPresentation} → card` : ''}`\n + `${presentationNeedsDisplayer && activationNeedsDisplayer ? ', ' : ''}`\n + `${activationNeedsDisplayer ? 'activation overlay → download' : ''}`,\n };\n}\n"]}
|
package/dist/esm/zod-money.d.ts
CHANGED
|
@@ -97,6 +97,8 @@ export type DecoratedMoneySchema = z.ZodObject<{
|
|
|
97
97
|
decimals: z.ZodNumber;
|
|
98
98
|
}> & {
|
|
99
99
|
[ZodDecorator.IS_DB_INDEXED](): DecoratedMoneySchema;
|
|
100
|
+
/** Installed at runtime with the other chainable methods; declared here so an authored `.moneyUI(…)` typechecks. */
|
|
101
|
+
[ZodDecorator.MONEY_UI](params?: ZodDecorator_ParamsType[ZodDecorator.MONEY_UI]): DecoratedMoneySchema;
|
|
100
102
|
[ZodDecorator.IS_HIDDEN](params?: ZodDecorator_ParamsType[ZodDecorator.IS_HIDDEN]): DecoratedMoneySchema;
|
|
101
103
|
[ZodDecorator.IS_NOT_EDITABLE](params?: ZodDecorator_ParamsType[ZodDecorator.IS_NOT_EDITABLE]): DecoratedMoneySchema;
|
|
102
104
|
[ZodDecorator.IS_SUMMARY_FIELD](params?: SummaryFieldParams): DecoratedMoneySchema;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod-money.d.ts","sourceRoot":"","sources":["../../../src/zod-money.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"zod-money.d.ts","sourceRoot":"","sources":["../../../src/zod-money.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod-money.js","sourceRoot":"","sources":["../../../src/zod-money.ts"],"names":[],"mappings":"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","sourcesContent":["\n// ============================================================================\n// MONEY SCHEMA HELPER\n// ============================================================================\n\nimport { DecoratorInput, SCHEMA_METADATA, CustomFieldMetadata, MoneySchemaMetadata, MoneySchemaOptions, SummaryFieldParams, ZodDecorator, ZodDecorator_ParamsType } from \"./zod-decorators.types\";\nimport { z } from \"zod\";\nimport { addChainableMethods } from \"./zod.module-override\";\nimport { CurrencySchema, currencyMinorUnitDecimals } from \"./currencies.shared.schemas\";\n\n/**\n * Money value type - represents a monetary amount with bigint storage.\n *\n * The amount is stored as a bigint in the smallest unit (e.g., cents for USD).\n * Using bigint ensures no precision loss for arbitrarily large amounts.\n * The decimals field indicates how to convert to the display value:\n * - displayValue = Number(amount) / (10 ** decimals)\n *\n * Example: { amount: 1999n, currency: 'USD', decimals: 2 } = $19.99\n */\nexport interface MoneyValue {\n /**\n * Amount in smallest unit (e.g., cents). BigInt to avoid precision issues with\n * large amounts.\n *\n * WIRE CONTRACT: a `bigint` has no JSON form, so on the wire (and at rest in\n * Mongo) this amount is a decimal STRING (e.g. `\"1999\"`). Outbound it is encoded\n * by `BigInt.prototype.toJSON` (`installBigIntJsonEncoding`, same package);\n * inbound it is coerced back to `bigint` by `applyNetworkBoundaryCoercion`\n * (`@wildo-ai/saas-models`) on the shared request/response DTO — so both the\n * frontend and backend hold a real `bigint` at runtime. Full mechanism map:\n * `install-bigint-json-encoding.ts`.\n */\n amount: bigint;\n /** ISO 4217 currency code (e.g., 'USD', 'EUR', 'BTC') */\n currency: string;\n /** Number of decimal places for display (e.g., 2 for USD, 8 for BTC) */\n decimals: number;\n}\n\n/**\n * Zod schema for MoneyValue.\n */\nexport const MoneyValueSchema: z.ZodObject<{ amount: z.ZodBigInt; currency: typeof CurrencySchema; decimals: z.ZodNumber }> = z.object({\n amount: z.bigint(),\n currency: CurrencySchema,\n decimals: z.number().int().min(0).max(18),\n});\n\n/**\n * @wildo_source:part:start zod.factories.money facet:layer:shared facet:family:schema-factory\n *\n * z_money() - Creates money schemas for financial amounts.\n *\n * Money values are stored as integers to avoid floating-point precision issues.\n * The schema creates an object with: { amount, currency, decimals }\n *\n * @example\n * ```typescript\n * import { z_money } from '@wildo-ai/zod-decorators';\n *\n * const price = z_money();\n * const fiatPrice = z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] });\n * const usdPrice = z_money({ allowCurrencyChange: false }).moneyUI({ edit: { defaultCurrency: 'USD' } });\n *\n * // With decorators (chainable)\n * z_money().moneyUI({ edit: { defaultCurrency: 'EUR' } })\n * z_money({ currenciesAllowed: [CurrencyAllowed.FIAT_MAJOR] }).isHidden({ edit: true })\n * ```\n */\n\n/**\n * Creates a money schema with metadata for detection and form component rendering.\n *\n * @param options - Configuration options for money field\n * @returns A Zod object schema with metadata for money detection\n *\n * @example\n * ```typescript\n * // Simple money (all currencies)\n * const price = z_money();\n * // Infers: { amount: bigint, currency: string, decimals: number }\n *\n * // Fiat only (no crypto)\n * const fiatPrice = z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] });\n *\n * // Fixed currency with amount constraints\n * const usdPrice = z_money({\n * allowCurrencyChange: false,\n * minAmount: 0n,\n * maxAmount: 100000000n // $1,000,000.00 in cents\n * }).moneyUI({ edit: { defaultCurrency: 'USD' } });\n * ```\n */\nexport function createMoneySchema(\n options: MoneySchemaOptions = {}\n): DecoratedMoneySchema {\n const {\n currenciesAllowed,\n appEnabledOnly = true,\n allowCurrencyChange = true,\n minAmount,\n maxAmount,\n } = options;\n\n // Create the amount schema with optional min/max constraints\n // Using bigint for amount to avoid precision issues with large financial amounts\n let amountSchema = z.bigint();\n if (minAmount !== undefined) {\n amountSchema = amountSchema.min(minAmount);\n }\n if (maxAmount !== undefined) {\n amountSchema = amountSchema.max(maxAmount);\n }\n\n // Create the money object schema\n const moneySchema = z.object({\n amount: amountSchema,\n currency: CurrencySchema,\n decimals: z.number().int().min(0).max(18),\n });\n\n const moneyMetadata: MoneySchemaMetadata = {\n isMoney: true,\n ...(currenciesAllowed && currenciesAllowed.length > 0 && { currenciesAllowed }),\n appEnabledOnly,\n allowCurrencyChange,\n ...(minAmount !== undefined && { minAmount }),\n ...(maxAmount !== undefined && { maxAmount }),\n };\n\n // Initialize or extend SCHEMA_METADATA with money config\n const existingMetadata: CustomFieldMetadata = (moneySchema as any)[SCHEMA_METADATA] || {};\n (moneySchema as any)[SCHEMA_METADATA] = {\n ...existingMetadata,\n moneyConfig: moneyMetadata,\n };\n\n // Add chainable decorator methods to the money schema instance\n // This allows: z_money().moneyUI({ edit: { defaultCurrency: 'EUR' } }).isHidden()\n addChainableMethods(moneySchema);\n\n return moneySchema as DecoratedMoneySchema;\n}\n\n/**\n * Return type for money schemas - includes decorator methods.\n * Note: IS_FOREIGN_KEY is not applicable to money objects.\n * IS_DB_INDEXED will index internal fields (amount, currency) for query optimization.\n *\n * This type must list all decorators applicable to ZodObject (per ApplyableTypeAllTypes).\n * Missing entries here cause TS errors when chaining decorators on z_money() fields.\n */\nexport type DecoratedMoneySchema = z.ZodObject<{\n amount: z.ZodBigInt;\n currency: typeof CurrencySchema;\n decimals: z.ZodNumber;\n}> & {\n [ZodDecorator.IS_DB_INDEXED](): DecoratedMoneySchema;\n [ZodDecorator.IS_HIDDEN](params?: ZodDecorator_ParamsType[ZodDecorator.IS_HIDDEN]): DecoratedMoneySchema;\n [ZodDecorator.IS_NOT_EDITABLE](params?: ZodDecorator_ParamsType[ZodDecorator.IS_NOT_EDITABLE]): DecoratedMoneySchema;\n // Resource-level decorators (applicable to all types including ZodObject)\n [ZodDecorator.IS_SUMMARY_FIELD](params?: SummaryFieldParams): DecoratedMoneySchema;\n [ZodDecorator.IS_BACKEND_ONLY](params?: ZodDecorator_ParamsType[ZodDecorator.IS_BACKEND_ONLY]): DecoratedMoneySchema;\n [ZodDecorator.IS_WRITE_ONLY_SECRET](params?: ZodDecorator_ParamsType[ZodDecorator.IS_WRITE_ONLY_SECRET]): DecoratedMoneySchema;\n [ZodDecorator.EXCLUDE_FROM_CREATE](): DecoratedMoneySchema;\n [ZodDecorator.EXCLUDE_FROM_UPDATE](): DecoratedMoneySchema;\n addDecorators(decorators: DecoratorInput[]): DecoratedMoneySchema;\n};\n\n/**\n * Creates a money schema for financial amounts with integer storage.\n * Named z_money to indicate it's a Zod helper function exported standalone.\n *\n * Money values are stored as: { amount: int, currency: string, decimals: int }\n * - amount: Value in smallest unit (e.g., cents for USD, satoshis for BTC)\n * - currency: ISO 4217 code (e.g., 'USD', 'EUR', 'BTC')\n * - decimals: Decimal places for display conversion (e.g., 2 for USD, 8 for BTC)\n *\n * @example\n * ```typescript\n * import { z_money } from '@wildo-ai/zod-decorators';\n *\n * // Simple usage\n * z_money() // All currencies\n *\n * // With options\n * z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] })\n * z_money({ allowCurrencyChange: false }).moneyUI({ edit: { defaultCurrency: 'USD' } })\n * z_money({ currenciesAllowed: [CurrencyAllowed.FIAT_MAJOR], minAmount: 0n })\n *\n * // With decorators (chainable)\n * z_money().moneyUI({ edit: { defaultCurrency: 'USD' } })\n * z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] }).isHidden({ edit: true })\n *\n * // Usage example\n * const price: MoneyValue = { amount: 1999n, currency: 'USD', decimals: 2 };\n * // Represents $19.99\n * ```\n */\nexport function z_money(\n options?: MoneySchemaOptions\n): DecoratedMoneySchema {\n return createMoneySchema(options) as DecoratedMoneySchema;\n}\n/** @wildo_source:part:end zod.factories.money */\n\n// ============================================================================\n// MONEY UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Why an amount could not be expressed in its currency's smallest unit.\n *\n * A named vocabulary rather than three bare strings, because each member has a DIFFERENT remedy and\n * an operator reading a sync log needs to know which one they are looking at: an unknown minor unit\n * is a catalogue problem, a precision loss is an authoring problem, and an unsafe magnitude is a\n * limit of the provider's own number type.\n */\nexport enum MoneyMinorUnitConversionFailure {\n /** The currency has no minor unit (`XDR`, `XXX`) or is not one this vocabulary knows. */\n UNKNOWN_MINOR_UNIT = 'unknown_minor_unit',\n /** Converting down would discard a fraction of the provider's smallest unit. */\n PRECISION_LOSS = 'precision_loss',\n /** The converted amount cannot be represented exactly as a JavaScript number. */\n UNSAFE_MAGNITUDE = 'unsafe_magnitude',\n}\n\n/** Thrown by {@link toCurrencyMinorUnitAmountOrThrow}; carries the reason so a caller can branch. */\nexport class MoneyMinorUnitConversionError extends Error {\n constructor(\n public readonly reason: MoneyMinorUnitConversionFailure,\n message: string,\n ) {\n super(message);\n this.name = 'MoneyMinorUnitConversionError';\n }\n}\n\n/**\n * Convert a {@link MoneyValue} to the amount a payment provider expects: an integer in the CURRENCY's\n * smallest unit.\n *\n * Wildo stores money at an AUTHORED scale (`decimals` on the value); a provider reads it at the\n * currency's own scale. Those are two different numbers whenever they disagree, and until 2026-09-08\n * the billing boundary sent the stored amount straight through — so a price authored at any scale\n * other than the currency's was charged at the wrong magnitude, by a factor of 10 per decimal place\n * of disagreement.\n *\n * **All arithmetic is `bigint`.** The stored amount already is one, and the whole reason it is a\n * bigint rather than a number is that money must not round; converting through a float to save a cast\n * would give that back at exactly the boundary where it costs money.\n *\n * **Scaling UP is always exact. Scaling DOWN refuses on a remainder rather than rounding** — a price\n * of 1.005 in a currency whose smallest unit is a cent is not 1.00 and not 1.01, it is a price the\n * provider cannot express, and silently picking one is how a catalogue and an invoice come to\n * disagree by a cent per unit forever.\n *\n * **Throws rather than returning a result union**, and the reason is the compiler rather than taste:\n * this repository compiles with `strict: false` (`engine/tsconfig.common.json`), which disables the\n * discriminant narrowing a `{ ok: true } | { ok: false }` result depends on — so every caller would\n * need a cast to read the failure, at every boundary. A typed error narrows by `instanceof`, which\n * works regardless. Callers that must not throw resolve the scale directly with\n * `currencyMinorUnitDecimals` and decide for themselves.\n *\n * @param subject what the message names (\"price p_1 tier 2 flat amount\"), so an operator reading a\n * sync log knows which amount could not be expressed without opening the catalogue.\n */\nexport function toCurrencyMinorUnitAmountOrThrow(value: MoneyValue, subject: string): number {\n const target = currencyMinorUnitDecimals(value.currency);\n if (target === undefined) {\n throw new MoneyMinorUnitConversionError(\n MoneyMinorUnitConversionFailure.UNKNOWN_MINOR_UNIT,\n `Cannot express ${subject} for a payment provider: currency '${value.currency}' has no minor unit this framework can resolve. Cryptocurrencies are in this position deliberately — their decimals are protocol conventions, not a fiat provider's minor unit.`,\n );\n }\n\n let converted: bigint;\n if (value.decimals === target) {\n converted = value.amount;\n } else if (value.decimals < target) {\n converted = value.amount * 10n ** BigInt(target - value.decimals);\n } else {\n const divisor = 10n ** BigInt(value.decimals - target);\n if (value.amount % divisor !== 0n) {\n throw new MoneyMinorUnitConversionError(\n MoneyMinorUnitConversionFailure.PRECISION_LOSS,\n `Cannot express ${subject} for a payment provider: amount ${value.amount} at scale ${value.decimals} cannot be written in ${value.currency}'s smallest unit (scale ${target}) without discarding a fraction of it. Author the amount at scale ${target}, or at a scale whose extra digits are zero.`,\n );\n }\n converted = value.amount / divisor;\n }\n\n const asNumber = Number(converted);\n if (!Number.isSafeInteger(asNumber)) {\n throw new MoneyMinorUnitConversionError(\n MoneyMinorUnitConversionFailure.UNSAFE_MAGNITUDE,\n `Cannot express ${subject} for a payment provider: amount ${converted} in ${value.currency}'s smallest unit exceeds the range a JavaScript number represents exactly, so handing it over would silently change its value.`,\n );\n }\n\n return asNumber;\n}\n\n/**\n * Convert a decimal amount to bigint representation.\n *\n * **Precision caveat:** This uses floating-point arithmetic internally\n * (`Math.round(decimalAmount * 10^decimals)`), which can produce rounding\n * errors for certain values. Prefer `parseDecimalStringToAmount` when working\n * with user input strings to avoid float precision issues entirely.\n *\n * @param decimalAmount - The decimal amount (e.g., 19.99)\n * @param decimals - Number of decimal places (e.g., 2)\n * @returns BigInt amount (e.g., 1999n)\n */\nexport function toMoneyAmount(decimalAmount: number, decimals: number): bigint {\n return BigInt(Math.round(decimalAmount * Math.pow(10, decimals)));\n}\n\n/**\n * Convert a bigint amount to decimal representation.\n * @param amount - The bigint amount (e.g., 1999n)\n * @param decimals - Number of decimal places (e.g., 2)\n * @returns Decimal amount (e.g., 19.99)\n */\nexport function fromMoneyAmount(amount: bigint, decimals: number): number {\n return Number(amount) / Math.pow(10, decimals);\n}\n\n/**\n * Convert a string or number to bigint safely.\n * Useful for parsing user input or JSON values.\n * @param value - String, number, or bigint to convert\n * @returns BigInt amount\n */\nexport function toBigIntAmount(value: string | number | bigint): bigint {\n if (typeof value === 'bigint') return value;\n if (typeof value === 'number') return BigInt(Math.round(value));\n return BigInt(value);\n}\n\n/**\n * Parse a decimal string directly to a bigint amount, avoiding floating-point\n * precision issues entirely.\n *\n * This is the preferred way to convert user input (e.g., from an HTML input\n * element) to a money amount. It works by splitting the string at the decimal\n * point and manipulating integer/fractional parts as strings, so no float\n * arithmetic is ever involved.\n *\n * - Extra fractional digits beyond `decimals` are **truncated** (not rounded).\n * - Missing fractional digits are **zero-padded**.\n *\n * @param input - A decimal string (e.g., \"19.99\", \"5\", \".50\", \"-12.345\")\n * @param decimals - Number of decimal places for the target currency\n * @returns BigInt amount, or `null` if the input is not a valid decimal string\n *\n * **Note:** Scientific notation strings (e.g., `\"1e+10\"`) are rejected (returns\n * `null`) since they are not valid monetary input. This is correct behavior when\n * reading from `<input type=\"number\">`, which may produce such strings for very\n * large values — those inputs should be constrained via `min`/`max` attributes.\n *\n * @example\n * ```typescript\n * parseDecimalStringToAmount(\"19.99\", 2) // → 1999n\n * parseDecimalStringToAmount(\"19.999\", 2) // → 1999n (truncates, not rounds)\n * parseDecimalStringToAmount(\"19.9\", 2) // → 1990n (pads missing decimals)\n * parseDecimalStringToAmount(\"5\", 2) // → 500n\n * parseDecimalStringToAmount(\".50\", 2) // → 50n\n * parseDecimalStringToAmount(\"-12.34\", 2) // → -1234n\n * parseDecimalStringToAmount(\"abc\", 2) // → null\n * parseDecimalStringToAmount(\"1e+10\", 2) // → null (scientific notation rejected)\n * ```\n */\nexport function parseDecimalStringToAmount(input: string, decimals: number): bigint | null {\n const trimmed = input.trim();\n if (trimmed === '' || trimmed === '.' || trimmed === '-' || trimmed === '-.') return null;\n\n // Handle sign\n const isNegative = trimmed.startsWith('-');\n const unsigned = isNegative ? trimmed.slice(1) : trimmed;\n\n // Validate: only digits and at most one decimal point\n if (!/^\\d*\\.?\\d*$/.test(unsigned)) return null;\n\n const dotIndex = unsigned.indexOf('.');\n const integerPart = dotIndex === -1 ? unsigned : (unsigned.slice(0, dotIndex) || '0');\n const fractionalRaw = dotIndex === -1 ? '' : unsigned.slice(dotIndex + 1);\n\n // Pad or truncate fractional part to exactly `decimals` digits\n const fractionalPart = decimals === 0\n ? ''\n : fractionalRaw.padEnd(decimals, '0').slice(0, decimals);\n\n // Build the combined string and convert to bigint\n const combined = integerPart + fractionalPart;\n // Guard against empty combined (shouldn't happen after validation, but be safe)\n if (combined === '') return 0n;\n\n try {\n const result = BigInt(combined);\n return isNegative ? -result : result;\n } catch {\n return null;\n }\n}\n\n/**\n * Convert a money amount from one decimal precision to another using pure\n * bigint arithmetic (no floating-point involved).\n *\n * Use this when changing a currency (which may have different decimal places)\n * instead of the float roundtrip `fromMoneyAmount` → `toMoneyAmount`.\n *\n * - When increasing decimals (e.g., 2 → 8): multiplies by 10^(diff)\n * - When decreasing decimals (e.g., 8 → 2): divides with half-away-from-zero rounding\n *\n * @param amount - The bigint amount in the source precision\n * @param fromDecimals - Source decimal places\n * @param toDecimals - Target decimal places\n * @returns BigInt amount in the target precision\n *\n * @example\n * ```typescript\n * convertMoneyDecimals(1999n, 2, 2) // → 1999n (same decimals, no-op)\n * convertMoneyDecimals(1999n, 2, 4) // → 199900n (scale up)\n * convertMoneyDecimals(199900n, 4, 2) // → 1999n (scale down)\n * convertMoneyDecimals(12345678n, 8, 2) // → 12n (BTC satoshis to 2-decimal)\n * ```\n */\nexport function convertMoneyDecimals(amount: bigint, fromDecimals: number, toDecimals: number): bigint {\n if (fromDecimals === toDecimals) return amount;\n\n const diff = toDecimals - fromDecimals;\n\n if (diff > 0) {\n // Scale up: multiply\n return amount * (10n ** BigInt(diff));\n }\n\n // Scale down: divide with rounding (half-away-from-zero)\n const divisor = 10n ** BigInt(-diff);\n const isNegative = amount < 0n;\n const absAmount = isNegative ? -amount : amount;\n const rounded = (absAmount + divisor / 2n) / divisor;\n return isNegative ? -rounded : rounded;\n}\n\n/**\n * Format a money value for display.\n * @param money - The money value\n * @param options - Formatting options\n * @returns Formatted string (e.g., \"$19.99\" or \"19.99 USD\")\n */\nexport function formatMoney(\n money: MoneyValue,\n options: {\n showSymbol?: boolean;\n symbolPosition?: 'before' | 'after';\n thousandsSeparator?: string;\n decimalSeparator?: string;\n } = {}\n): string {\n const {\n showSymbol = true,\n symbolPosition = 'before',\n thousandsSeparator = ',',\n decimalSeparator = '.',\n } = options;\n\n const decimalValue = fromMoneyAmount(money.amount, money.decimals);\n\n // Format with proper decimal places\n const [integerPart, decimalPart] = decimalValue.toFixed(money.decimals).split('.');\n\n // Add thousands separator\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, thousandsSeparator);\n\n const formattedNumber = decimalPart\n ? `${formattedInteger}${decimalSeparator}${decimalPart}`\n : formattedInteger;\n\n if (!showSymbol) {\n return formattedNumber;\n }\n\n // For now, use currency code as symbol (can be enhanced with CURRENCY_INFO_MAP)\n const symbol = money.currency;\n\n return symbolPosition === 'before'\n ? `${symbol} ${formattedNumber}`\n : `${formattedNumber} ${symbol}`;\n}\n\n"]}
|
|
1
|
+
{"version":3,"file":"zod-money.js","sourceRoot":"","sources":["../../../src/zod-money.ts"],"names":[],"mappings":"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","sourcesContent":["\n// ============================================================================\n// MONEY SCHEMA HELPER\n// ============================================================================\n\nimport { DecoratorInput, SCHEMA_METADATA, CustomFieldMetadata, MoneySchemaMetadata, MoneySchemaOptions, SummaryFieldParams, ZodDecorator, ZodDecorator_ParamsType } from \"./zod-decorators.types\";\nimport { z } from \"zod\";\nimport { addChainableMethods } from \"./zod.module-override\";\nimport { CurrencySchema, currencyMinorUnitDecimals } from \"./currencies.shared.schemas\";\n\n/**\n * Money value type - represents a monetary amount with bigint storage.\n *\n * The amount is stored as a bigint in the smallest unit (e.g., cents for USD).\n * Using bigint ensures no precision loss for arbitrarily large amounts.\n * The decimals field indicates how to convert to the display value:\n * - displayValue = Number(amount) / (10 ** decimals)\n *\n * Example: { amount: 1999n, currency: 'USD', decimals: 2 } = $19.99\n */\nexport interface MoneyValue {\n /**\n * Amount in smallest unit (e.g., cents). BigInt to avoid precision issues with\n * large amounts.\n *\n * WIRE CONTRACT: a `bigint` has no JSON form, so on the wire (and at rest in\n * Mongo) this amount is a decimal STRING (e.g. `\"1999\"`). Outbound it is encoded\n * by `BigInt.prototype.toJSON` (`installBigIntJsonEncoding`, same package);\n * inbound it is coerced back to `bigint` by `applyNetworkBoundaryCoercion`\n * (`@wildo-ai/saas-models`) on the shared request/response DTO — so both the\n * frontend and backend hold a real `bigint` at runtime. Full mechanism map:\n * `install-bigint-json-encoding.ts`.\n */\n amount: bigint;\n /** ISO 4217 currency code (e.g., 'USD', 'EUR', 'BTC') */\n currency: string;\n /** Number of decimal places for display (e.g., 2 for USD, 8 for BTC) */\n decimals: number;\n}\n\n/**\n * Zod schema for MoneyValue.\n */\nexport const MoneyValueSchema: z.ZodObject<{ amount: z.ZodBigInt; currency: typeof CurrencySchema; decimals: z.ZodNumber }> = z.object({\n amount: z.bigint(),\n currency: CurrencySchema,\n decimals: z.number().int().min(0).max(18),\n});\n\n/**\n * @wildo_source:part:start zod.factories.money facet:layer:shared facet:family:schema-factory\n *\n * z_money() - Creates money schemas for financial amounts.\n *\n * Money values are stored as integers to avoid floating-point precision issues.\n * The schema creates an object with: { amount, currency, decimals }\n *\n * @example\n * ```typescript\n * import { z_money } from '@wildo-ai/zod-decorators';\n *\n * const price = z_money();\n * const fiatPrice = z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] });\n * const usdPrice = z_money({ allowCurrencyChange: false }).moneyUI({ edit: { defaultCurrency: 'USD' } });\n *\n * // With decorators (chainable)\n * z_money().moneyUI({ edit: { defaultCurrency: 'EUR' } })\n * z_money({ currenciesAllowed: [CurrencyAllowed.FIAT_MAJOR] }).isHidden({ edit: true })\n * ```\n */\n\n/**\n * Creates a money schema with metadata for detection and form component rendering.\n *\n * @param options - Configuration options for money field\n * @returns A Zod object schema with metadata for money detection\n *\n * @example\n * ```typescript\n * // Simple money (all currencies)\n * const price = z_money();\n * // Infers: { amount: bigint, currency: string, decimals: number }\n *\n * // Fiat only (no crypto)\n * const fiatPrice = z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] });\n *\n * // Fixed currency with amount constraints\n * const usdPrice = z_money({\n * allowCurrencyChange: false,\n * minAmount: 0n,\n * maxAmount: 100000000n // $1,000,000.00 in cents\n * }).moneyUI({ edit: { defaultCurrency: 'USD' } });\n * ```\n */\nexport function createMoneySchema(\n options: MoneySchemaOptions = {}\n): DecoratedMoneySchema {\n const {\n currenciesAllowed,\n appEnabledOnly = true,\n allowCurrencyChange = true,\n minAmount,\n maxAmount,\n } = options;\n\n // Create the amount schema with optional min/max constraints\n // Using bigint for amount to avoid precision issues with large financial amounts\n let amountSchema = z.bigint();\n if (minAmount !== undefined) {\n amountSchema = amountSchema.min(minAmount);\n }\n if (maxAmount !== undefined) {\n amountSchema = amountSchema.max(maxAmount);\n }\n\n // Create the money object schema\n const moneySchema = z.object({\n amount: amountSchema,\n currency: CurrencySchema,\n decimals: z.number().int().min(0).max(18),\n });\n\n const moneyMetadata: MoneySchemaMetadata = {\n isMoney: true,\n ...(currenciesAllowed && currenciesAllowed.length > 0 && { currenciesAllowed }),\n appEnabledOnly,\n allowCurrencyChange,\n ...(minAmount !== undefined && { minAmount }),\n ...(maxAmount !== undefined && { maxAmount }),\n };\n\n // Initialize or extend SCHEMA_METADATA with money config\n const existingMetadata: CustomFieldMetadata = (moneySchema as any)[SCHEMA_METADATA] || {};\n (moneySchema as any)[SCHEMA_METADATA] = {\n ...existingMetadata,\n moneyConfig: moneyMetadata,\n };\n\n // Add chainable decorator methods to the money schema instance\n // This allows: z_money().moneyUI({ edit: { defaultCurrency: 'EUR' } }).isHidden()\n addChainableMethods(moneySchema);\n\n return moneySchema as DecoratedMoneySchema;\n}\n\n/**\n * Return type for money schemas - includes decorator methods.\n * Note: IS_FOREIGN_KEY is not applicable to money objects.\n * IS_DB_INDEXED will index internal fields (amount, currency) for query optimization.\n *\n * This type must list all decorators applicable to ZodObject (per ApplyableTypeAllTypes).\n * Missing entries here cause TS errors when chaining decorators on z_money() fields.\n */\nexport type DecoratedMoneySchema = z.ZodObject<{\n amount: z.ZodBigInt;\n currency: typeof CurrencySchema;\n decimals: z.ZodNumber;\n}> & {\n [ZodDecorator.IS_DB_INDEXED](): DecoratedMoneySchema;\n /** Installed at runtime with the other chainable methods; declared here so an authored `.moneyUI(…)` typechecks. */\n [ZodDecorator.MONEY_UI](params?: ZodDecorator_ParamsType[ZodDecorator.MONEY_UI]): DecoratedMoneySchema;\n [ZodDecorator.IS_HIDDEN](params?: ZodDecorator_ParamsType[ZodDecorator.IS_HIDDEN]): DecoratedMoneySchema;\n [ZodDecorator.IS_NOT_EDITABLE](params?: ZodDecorator_ParamsType[ZodDecorator.IS_NOT_EDITABLE]): DecoratedMoneySchema;\n // Resource-level decorators (applicable to all types including ZodObject)\n [ZodDecorator.IS_SUMMARY_FIELD](params?: SummaryFieldParams): DecoratedMoneySchema;\n [ZodDecorator.IS_BACKEND_ONLY](params?: ZodDecorator_ParamsType[ZodDecorator.IS_BACKEND_ONLY]): DecoratedMoneySchema;\n [ZodDecorator.IS_WRITE_ONLY_SECRET](params?: ZodDecorator_ParamsType[ZodDecorator.IS_WRITE_ONLY_SECRET]): DecoratedMoneySchema;\n [ZodDecorator.EXCLUDE_FROM_CREATE](): DecoratedMoneySchema;\n [ZodDecorator.EXCLUDE_FROM_UPDATE](): DecoratedMoneySchema;\n addDecorators(decorators: DecoratorInput[]): DecoratedMoneySchema;\n};\n\n/**\n * Creates a money schema for financial amounts with integer storage.\n * Named z_money to indicate it's a Zod helper function exported standalone.\n *\n * Money values are stored as: { amount: int, currency: string, decimals: int }\n * - amount: Value in smallest unit (e.g., cents for USD, satoshis for BTC)\n * - currency: ISO 4217 code (e.g., 'USD', 'EUR', 'BTC')\n * - decimals: Decimal places for display conversion (e.g., 2 for USD, 8 for BTC)\n *\n * @example\n * ```typescript\n * import { z_money } from '@wildo-ai/zod-decorators';\n *\n * // Simple usage\n * z_money() // All currencies\n *\n * // With options\n * z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] })\n * z_money({ allowCurrencyChange: false }).moneyUI({ edit: { defaultCurrency: 'USD' } })\n * z_money({ currenciesAllowed: [CurrencyAllowed.FIAT_MAJOR], minAmount: 0n })\n *\n * // With decorators (chainable)\n * z_money().moneyUI({ edit: { defaultCurrency: 'USD' } })\n * z_money({ currenciesAllowed: [CurrencyAllowed.FIAT] }).isHidden({ edit: true })\n *\n * // Usage example\n * const price: MoneyValue = { amount: 1999n, currency: 'USD', decimals: 2 };\n * // Represents $19.99\n * ```\n */\nexport function z_money(\n options?: MoneySchemaOptions\n): DecoratedMoneySchema {\n return createMoneySchema(options) as DecoratedMoneySchema;\n}\n/** @wildo_source:part:end zod.factories.money */\n\n// ============================================================================\n// MONEY UTILITY FUNCTIONS\n// ============================================================================\n\n/**\n * Why an amount could not be expressed in its currency's smallest unit.\n *\n * A named vocabulary rather than three bare strings, because each member has a DIFFERENT remedy and\n * an operator reading a sync log needs to know which one they are looking at: an unknown minor unit\n * is a catalogue problem, a precision loss is an authoring problem, and an unsafe magnitude is a\n * limit of the provider's own number type.\n */\nexport enum MoneyMinorUnitConversionFailure {\n /** The currency has no minor unit (`XDR`, `XXX`) or is not one this vocabulary knows. */\n UNKNOWN_MINOR_UNIT = 'unknown_minor_unit',\n /** Converting down would discard a fraction of the provider's smallest unit. */\n PRECISION_LOSS = 'precision_loss',\n /** The converted amount cannot be represented exactly as a JavaScript number. */\n UNSAFE_MAGNITUDE = 'unsafe_magnitude',\n}\n\n/** Thrown by {@link toCurrencyMinorUnitAmountOrThrow}; carries the reason so a caller can branch. */\nexport class MoneyMinorUnitConversionError extends Error {\n constructor(\n public readonly reason: MoneyMinorUnitConversionFailure,\n message: string,\n ) {\n super(message);\n this.name = 'MoneyMinorUnitConversionError';\n }\n}\n\n/**\n * Convert a {@link MoneyValue} to the amount a payment provider expects: an integer in the CURRENCY's\n * smallest unit.\n *\n * Wildo stores money at an AUTHORED scale (`decimals` on the value); a provider reads it at the\n * currency's own scale. Those are two different numbers whenever they disagree, and until 2026-09-08\n * the billing boundary sent the stored amount straight through — so a price authored at any scale\n * other than the currency's was charged at the wrong magnitude, by a factor of 10 per decimal place\n * of disagreement.\n *\n * **All arithmetic is `bigint`.** The stored amount already is one, and the whole reason it is a\n * bigint rather than a number is that money must not round; converting through a float to save a cast\n * would give that back at exactly the boundary where it costs money.\n *\n * **Scaling UP is always exact. Scaling DOWN refuses on a remainder rather than rounding** — a price\n * of 1.005 in a currency whose smallest unit is a cent is not 1.00 and not 1.01, it is a price the\n * provider cannot express, and silently picking one is how a catalogue and an invoice come to\n * disagree by a cent per unit forever.\n *\n * **Throws rather than returning a result union**, and the reason is the compiler rather than taste:\n * this repository compiles with `strict: false` (`engine/tsconfig.common.json`), which disables the\n * discriminant narrowing a `{ ok: true } | { ok: false }` result depends on — so every caller would\n * need a cast to read the failure, at every boundary. A typed error narrows by `instanceof`, which\n * works regardless. Callers that must not throw resolve the scale directly with\n * `currencyMinorUnitDecimals` and decide for themselves.\n *\n * @param subject what the message names (\"price p_1 tier 2 flat amount\"), so an operator reading a\n * sync log knows which amount could not be expressed without opening the catalogue.\n */\nexport function toCurrencyMinorUnitAmountOrThrow(value: MoneyValue, subject: string): number {\n const target = currencyMinorUnitDecimals(value.currency);\n if (target === undefined) {\n throw new MoneyMinorUnitConversionError(\n MoneyMinorUnitConversionFailure.UNKNOWN_MINOR_UNIT,\n `Cannot express ${subject} for a payment provider: currency '${value.currency}' has no minor unit this framework can resolve. Cryptocurrencies are in this position deliberately — their decimals are protocol conventions, not a fiat provider's minor unit.`,\n );\n }\n\n let converted: bigint;\n if (value.decimals === target) {\n converted = value.amount;\n } else if (value.decimals < target) {\n converted = value.amount * 10n ** BigInt(target - value.decimals);\n } else {\n const divisor = 10n ** BigInt(value.decimals - target);\n if (value.amount % divisor !== 0n) {\n throw new MoneyMinorUnitConversionError(\n MoneyMinorUnitConversionFailure.PRECISION_LOSS,\n `Cannot express ${subject} for a payment provider: amount ${value.amount} at scale ${value.decimals} cannot be written in ${value.currency}'s smallest unit (scale ${target}) without discarding a fraction of it. Author the amount at scale ${target}, or at a scale whose extra digits are zero.`,\n );\n }\n converted = value.amount / divisor;\n }\n\n const asNumber = Number(converted);\n if (!Number.isSafeInteger(asNumber)) {\n throw new MoneyMinorUnitConversionError(\n MoneyMinorUnitConversionFailure.UNSAFE_MAGNITUDE,\n `Cannot express ${subject} for a payment provider: amount ${converted} in ${value.currency}'s smallest unit exceeds the range a JavaScript number represents exactly, so handing it over would silently change its value.`,\n );\n }\n\n return asNumber;\n}\n\n/**\n * Convert a decimal amount to bigint representation.\n *\n * **Precision caveat:** This uses floating-point arithmetic internally\n * (`Math.round(decimalAmount * 10^decimals)`), which can produce rounding\n * errors for certain values. Prefer `parseDecimalStringToAmount` when working\n * with user input strings to avoid float precision issues entirely.\n *\n * @param decimalAmount - The decimal amount (e.g., 19.99)\n * @param decimals - Number of decimal places (e.g., 2)\n * @returns BigInt amount (e.g., 1999n)\n */\nexport function toMoneyAmount(decimalAmount: number, decimals: number): bigint {\n return BigInt(Math.round(decimalAmount * Math.pow(10, decimals)));\n}\n\n/**\n * Convert a bigint amount to decimal representation.\n * @param amount - The bigint amount (e.g., 1999n)\n * @param decimals - Number of decimal places (e.g., 2)\n * @returns Decimal amount (e.g., 19.99)\n */\nexport function fromMoneyAmount(amount: bigint, decimals: number): number {\n return Number(amount) / Math.pow(10, decimals);\n}\n\n/**\n * Convert a string or number to bigint safely.\n * Useful for parsing user input or JSON values.\n * @param value - String, number, or bigint to convert\n * @returns BigInt amount\n */\nexport function toBigIntAmount(value: string | number | bigint): bigint {\n if (typeof value === 'bigint') return value;\n if (typeof value === 'number') return BigInt(Math.round(value));\n return BigInt(value);\n}\n\n/**\n * Parse a decimal string directly to a bigint amount, avoiding floating-point\n * precision issues entirely.\n *\n * This is the preferred way to convert user input (e.g., from an HTML input\n * element) to a money amount. It works by splitting the string at the decimal\n * point and manipulating integer/fractional parts as strings, so no float\n * arithmetic is ever involved.\n *\n * - Extra fractional digits beyond `decimals` are **truncated** (not rounded).\n * - Missing fractional digits are **zero-padded**.\n *\n * @param input - A decimal string (e.g., \"19.99\", \"5\", \".50\", \"-12.345\")\n * @param decimals - Number of decimal places for the target currency\n * @returns BigInt amount, or `null` if the input is not a valid decimal string\n *\n * **Note:** Scientific notation strings (e.g., `\"1e+10\"`) are rejected (returns\n * `null`) since they are not valid monetary input. This is correct behavior when\n * reading from `<input type=\"number\">`, which may produce such strings for very\n * large values — those inputs should be constrained via `min`/`max` attributes.\n *\n * @example\n * ```typescript\n * parseDecimalStringToAmount(\"19.99\", 2) // → 1999n\n * parseDecimalStringToAmount(\"19.999\", 2) // → 1999n (truncates, not rounds)\n * parseDecimalStringToAmount(\"19.9\", 2) // → 1990n (pads missing decimals)\n * parseDecimalStringToAmount(\"5\", 2) // → 500n\n * parseDecimalStringToAmount(\".50\", 2) // → 50n\n * parseDecimalStringToAmount(\"-12.34\", 2) // → -1234n\n * parseDecimalStringToAmount(\"abc\", 2) // → null\n * parseDecimalStringToAmount(\"1e+10\", 2) // → null (scientific notation rejected)\n * ```\n */\nexport function parseDecimalStringToAmount(input: string, decimals: number): bigint | null {\n const trimmed = input.trim();\n if (trimmed === '' || trimmed === '.' || trimmed === '-' || trimmed === '-.') return null;\n\n // Handle sign\n const isNegative = trimmed.startsWith('-');\n const unsigned = isNegative ? trimmed.slice(1) : trimmed;\n\n // Validate: only digits and at most one decimal point\n if (!/^\\d*\\.?\\d*$/.test(unsigned)) return null;\n\n const dotIndex = unsigned.indexOf('.');\n const integerPart = dotIndex === -1 ? unsigned : (unsigned.slice(0, dotIndex) || '0');\n const fractionalRaw = dotIndex === -1 ? '' : unsigned.slice(dotIndex + 1);\n\n // Pad or truncate fractional part to exactly `decimals` digits\n const fractionalPart = decimals === 0\n ? ''\n : fractionalRaw.padEnd(decimals, '0').slice(0, decimals);\n\n // Build the combined string and convert to bigint\n const combined = integerPart + fractionalPart;\n // Guard against empty combined (shouldn't happen after validation, but be safe)\n if (combined === '') return 0n;\n\n try {\n const result = BigInt(combined);\n return isNegative ? -result : result;\n } catch {\n return null;\n }\n}\n\n/**\n * Convert a money amount from one decimal precision to another using pure\n * bigint arithmetic (no floating-point involved).\n *\n * Use this when changing a currency (which may have different decimal places)\n * instead of the float roundtrip `fromMoneyAmount` → `toMoneyAmount`.\n *\n * - When increasing decimals (e.g., 2 → 8): multiplies by 10^(diff)\n * - When decreasing decimals (e.g., 8 → 2): divides with half-away-from-zero rounding\n *\n * @param amount - The bigint amount in the source precision\n * @param fromDecimals - Source decimal places\n * @param toDecimals - Target decimal places\n * @returns BigInt amount in the target precision\n *\n * @example\n * ```typescript\n * convertMoneyDecimals(1999n, 2, 2) // → 1999n (same decimals, no-op)\n * convertMoneyDecimals(1999n, 2, 4) // → 199900n (scale up)\n * convertMoneyDecimals(199900n, 4, 2) // → 1999n (scale down)\n * convertMoneyDecimals(12345678n, 8, 2) // → 12n (BTC satoshis to 2-decimal)\n * ```\n */\nexport function convertMoneyDecimals(amount: bigint, fromDecimals: number, toDecimals: number): bigint {\n if (fromDecimals === toDecimals) return amount;\n\n const diff = toDecimals - fromDecimals;\n\n if (diff > 0) {\n // Scale up: multiply\n return amount * (10n ** BigInt(diff));\n }\n\n // Scale down: divide with rounding (half-away-from-zero)\n const divisor = 10n ** BigInt(-diff);\n const isNegative = amount < 0n;\n const absAmount = isNegative ? -amount : amount;\n const rounded = (absAmount + divisor / 2n) / divisor;\n return isNegative ? -rounded : rounded;\n}\n\n/**\n * Format a money value for display.\n * @param money - The money value\n * @param options - Formatting options\n * @returns Formatted string (e.g., \"$19.99\" or \"19.99 USD\")\n */\nexport function formatMoney(\n money: MoneyValue,\n options: {\n showSymbol?: boolean;\n symbolPosition?: 'before' | 'after';\n thousandsSeparator?: string;\n decimalSeparator?: string;\n } = {}\n): string {\n const {\n showSymbol = true,\n symbolPosition = 'before',\n thousandsSeparator = ',',\n decimalSeparator = '.',\n } = options;\n\n const decimalValue = fromMoneyAmount(money.amount, money.decimals);\n\n // Format with proper decimal places\n const [integerPart, decimalPart] = decimalValue.toFixed(money.decimals).split('.');\n\n // Add thousands separator\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, thousandsSeparator);\n\n const formattedNumber = decimalPart\n ? `${formattedInteger}${decimalSeparator}${decimalPart}`\n : formattedInteger;\n\n if (!showSymbol) {\n return formattedNumber;\n }\n\n // For now, use currency code as symbol (can be enhanced with CURRENCY_INFO_MAP)\n const symbol = money.currency;\n\n return symbolPosition === 'before'\n ? `${symbol} ${formattedNumber}`\n : `${formattedNumber} ${symbol}`;\n}\n\n"]}
|
package/dist/esm/zod-phone.d.ts
CHANGED
|
@@ -93,6 +93,14 @@ export type DecoratedPhoneSchema = z.ZodString & {
|
|
|
93
93
|
[ZodDecorator.IS_WRITE_ONLY_SECRET](params?: ZodDecorator_ParamsType[ZodDecorator.IS_WRITE_ONLY_SECRET]): DecoratedPhoneSchema;
|
|
94
94
|
[ZodDecorator.EXCLUDE_FROM_CREATE](): DecoratedPhoneSchema;
|
|
95
95
|
[ZodDecorator.EXCLUDE_FROM_UPDATE](): DecoratedPhoneSchema;
|
|
96
|
+
/**
|
|
97
|
+
* Declared here, as the sibling factories declare theirs (`DecoratedMoneySchema.moneyUI`,
|
|
98
|
+
* `DecoratedCodeSchema.codeUI`, …), because a phone's display and edit policy is authored on the
|
|
99
|
+
* factory's output and nowhere else. The applyable-type map admits `phoneUI` on `ZodString`, but
|
|
100
|
+
* a bare `z.string()` is not a phone, so the base prototype deliberately does not carry it.
|
|
101
|
+
*/
|
|
102
|
+
[ZodDecorator.PHONE_UI](params?: ZodDecorator_ParamsType[ZodDecorator.PHONE_UI]): DecoratedPhoneSchema;
|
|
103
|
+
[ZodDecorator.PHONE_SPEC](params?: ZodDecorator_ParamsType[ZodDecorator.PHONE_SPEC]): DecoratedPhoneSchema;
|
|
96
104
|
addDecorators(decorators: DecoratorInput[]): DecoratedPhoneSchema;
|
|
97
105
|
};
|
|
98
106
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod-phone.d.ts","sourceRoot":"","sources":["../../../src/zod-phone.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EAGd,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,uBAAuB,EACxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,0BAA0B,EAQ3B,MAAM,mBAAmB,CAAC;AAM3B,mEAAmE;AACnE,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAEvC;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAKhC;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAMhH;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAM5E;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,cAAc,CAAC,EAAE,MAAM,EACvB,MAAM,GAAE,eAAe,GAAG,UAA4B,GACrD,MAAM,CAIR;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAIhF;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGzE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKpE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,oBAAoB,
|
|
1
|
+
{"version":3,"file":"zod-phone.d.ts","sourceRoot":"","sources":["../../../src/zod-phone.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/zod-phone.js
CHANGED
|
@@ -156,7 +156,12 @@ export function createPhoneSchema(options = {}) {
|
|
|
156
156
|
...existingMetadata,
|
|
157
157
|
phoneConfig: phoneMetadata,
|
|
158
158
|
};
|
|
159
|
-
|
|
159
|
+
// 'ZodString' rather than the instance's own constructor, which is `ZodPipe` because of the
|
|
160
|
+
// `.pipe(z.string())` above. A phone IS a string for every decorator purpose — the pipe exists to
|
|
161
|
+
// normalize to E.164, not to change what the field is — and without this the applyable-type
|
|
162
|
+
// lookup matches nothing and the schema carries NO decorators at all, including the eight
|
|
163
|
+
// `DecoratedPhoneSchema` declares.
|
|
164
|
+
addChainableMethods(phoneSchema, 'ZodString');
|
|
160
165
|
return phoneSchema;
|
|
161
166
|
}
|
|
162
167
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod-phone.js","sourceRoot":"","sources":["../../../src/zod-phone.ts"],"names":[],"mappings":"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","sourcesContent":["// ============================================================================\n// PHONE SCHEMA HELPER\n// ============================================================================\n\nimport type {\n DecoratorInput,\n CustomFieldMetadata,\n PhoneSchemaMetadata,\n PhoneSchemaOptions,\n SummaryFieldParams,\n ZodDecorator,\n ZodDecorator_ParamsType,\n} from './zod-decorators.types';\nimport { SCHEMA_METADATA } from './zod-decorators.types';\nimport { z } from 'zod';\nimport { addChainableMethods } from './zod.module-override';\nimport {\n parsePhoneNumberFromString,\n isValidPhoneNumber,\n getCountries as getCountriesFromLib,\n type CountryCode,\n getCountryCallingCode,\n formatIncompletePhoneNumber,\n getExampleNumber,\n AsYouType,\n} from 'libphonenumber-js';\n// JS-module subpath (NOT the .json subpath): importable under native ESM\n// without JSON import attributes, so the same source compiles for Node and\n// browser consumers alike. Example numbers back per-country placeholders.\nimport phoneExamples from 'libphonenumber-js/mobile/examples';\n\n/** Returns country codes (e.g. \"US\", \"FR\") for form components. */\nexport function getCountries(): string[] {\n return getCountriesFromLib() as string[];\n}\n\n/**\n * Phone value type — E.164 string (e.g., \"+33123456789\").\n * Use formatPhoneNumber() for display, parsePhoneNumber() for parsing.\n */\nexport type PhoneValue = string;\n\n/** Default country when parsing numbers without country code */\nconst DEFAULT_COUNTRY: CountryCode = 'US';\n\n/**\n * Parse a phone string to PhoneNumber or undefined.\n *\n * @param value - Raw input (E.164, national, or partial)\n * @param defaultCountry - Country code (e.g. \"US\", \"FR\") for numbers without +prefix\n * @returns PhoneNumber or undefined if invalid\n */\nexport function parsePhone(value: string, defaultCountry?: string): ReturnType<typeof parsePhoneNumberFromString> {\n if (!value || typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n const country = defaultCountry ?? DEFAULT_COUNTRY;\n return parsePhoneNumberFromString(trimmed, { defaultCountry: country as CountryCode });\n}\n\n/**\n * Validate a phone number string.\n *\n * @param value - Phone string to validate\n * @param defaultCountry - Country code (e.g. \"US\", \"FR\") for numbers without +prefix\n * @returns true if valid\n */\nexport function isValidPhone(value: string, defaultCountry?: string): boolean {\n if (!value || typeof value !== 'string') return false;\n const trimmed = value.trim();\n if (!trimmed) return false;\n const country = defaultCountry ?? DEFAULT_COUNTRY;\n return isValidPhoneNumber(trimmed, { defaultCountry: country as CountryCode });\n}\n\n/**\n * Format a phone number for display.\n *\n * @param value - E.164 or parseable phone string\n * @param defaultCountry - Country code (e.g. \"US\", \"FR\") for numbers without +prefix\n * @param format - 'international' | 'national' (default: international)\n * @returns Formatted string or original if unparseable\n */\nexport function formatPhoneNumber(\n value: string,\n defaultCountry?: string,\n format: 'international' | 'national' = 'international'\n): string {\n const parsed = parsePhone(value, defaultCountry);\n if (!parsed) return value;\n return format === 'national' ? parsed.formatNational() : parsed.formatInternational();\n}\n\n/**\n * Get country calling code (e.g., \"1\" for US).\n *\n * @param country - Country code (e.g. \"US\", \"FR\")\n */\nexport function getPhoneCountryCode(country: string): string {\n return getCountryCallingCode(country as CountryCode);\n}\n\n/**\n * Format a PARTIAL (as-you-type) national phone input for a country.\n *\n * Wraps libphonenumber's incomplete-number formatter so form controls can\n * format while the user is still typing (\"0612\" → \"06 12\" for FR) without\n * importing libphonenumber-js directly — the phone surface stays owned here.\n *\n * @param value - Partial national input (digits, may carry punctuation)\n * @param country - Country code (e.g. \"US\", \"FR\") providing the format plan\n * @returns The formatted partial, or the input unchanged when no plan applies\n */\nexport function formatPartialPhoneNumber(value: string, country?: string): string {\n if (!value) return value;\n const cc = (country ?? DEFAULT_COUNTRY) as CountryCode;\n return formatIncompletePhoneNumber(value, cc);\n}\n\n/**\n * Example national number for a country, for use as an input placeholder\n * (e.g. FR → \"06 12 34 56 78\"). Backed by libphonenumber's curated mobile\n * example set; returns undefined for countries without an example.\n *\n * @param country - Country code (e.g. \"US\", \"FR\")\n */\nexport function getExamplePhoneNumber(country: string): string | undefined {\n const example = getExampleNumber(country as CountryCode, phoneExamples);\n return example?.formatNational();\n}\n\n/**\n * Detect the country of a phone input that starts with an international\n * prefix (\"+...\"), even while the number is still incomplete.\n *\n * Powers the best-practice behavior where pasting/typing \"+49 30 ...\" into\n * the national input automatically switches the country selector to DE.\n * Returns undefined when the input is not international or the country is\n * not yet determinable (e.g. \"+1\" is ambiguous across NANP countries).\n *\n * @param value - Raw input, expected to start with \"+\"\n */\nexport function detectPhoneCountry(value: string): string | undefined {\n if (!value?.trim().startsWith('+')) return undefined;\n const formatter = new AsYouType();\n formatter.input(value.trim());\n return formatter.getCountry();\n}\n\n/**\n * @wildo_source:part:start zod.factories.phone facet:layer:shared facet:family:schema-factory\n *\n * Creates a phone schema with metadata for detection and form component rendering.\n * Values are stored as E.164 strings. Empty string passes validation.\n *\n * @param options - Configuration options for phone field\n * @returns A Zod string schema with metadata for phone detection\n */\nexport function createPhoneSchema(options: PhoneSchemaOptions = {}): DecoratedPhoneSchema {\n const { defaultCountry = DEFAULT_COUNTRY } = options;\n\n const phoneMetadata: PhoneSchemaMetadata = {\n isPhone: true,\n defaultCountry,\n };\n\n // PhoneCountryCode is libphonenumber's CountryCode union, so no cast needed.\n const country: CountryCode = defaultCountry;\n const phoneSchema = z\n .string()\n .trim()\n .refine((val) => val === '' || isValidPhone(val, country), {\n message: 'Invalid phone number',\n })\n // E.164 normalization is string -> string, so model it as a Zod 4\n // overwrite rather than a transform. The runtime result is identical, but\n // the schema remains truthfully introspectable as a string by JSON Schema /\n // OpenAPI generators instead of degrading to an unrepresentable transform.\n .overwrite((val) => {\n if (val === '') return '';\n const parsed = parsePhone(val, country);\n return parsed?.format('E.164') ?? val;\n })\n // Preserve the established ZodPipe surface used by decorator metadata and\n // boundary walkers; the terminal string adds no value conversion.\n .pipe(z.string()) as unknown as z.ZodString;\n\n const existingMetadata: CustomFieldMetadata = (phoneSchema as any)[SCHEMA_METADATA] || {};\n (phoneSchema as any)[SCHEMA_METADATA] = {\n ...existingMetadata,\n phoneConfig: phoneMetadata,\n };\n\n addChainableMethods(phoneSchema);\n\n return phoneSchema as unknown as DecoratedPhoneSchema;\n}\n\n/**\n * Return type for phone schemas - includes decorator methods.\n */\nexport type DecoratedPhoneSchema = z.ZodString & {\n [ZodDecorator.IS_DB_INDEXED](): DecoratedPhoneSchema;\n [ZodDecorator.IS_HIDDEN](params?: ZodDecorator_ParamsType[ZodDecorator.IS_HIDDEN]): DecoratedPhoneSchema;\n [ZodDecorator.IS_NOT_EDITABLE](params?: ZodDecorator_ParamsType[ZodDecorator.IS_NOT_EDITABLE]): DecoratedPhoneSchema;\n [ZodDecorator.IS_SUMMARY_FIELD](params?: SummaryFieldParams): DecoratedPhoneSchema;\n [ZodDecorator.IS_BACKEND_ONLY](params?: ZodDecorator_ParamsType[ZodDecorator.IS_BACKEND_ONLY]): DecoratedPhoneSchema;\n [ZodDecorator.IS_WRITE_ONLY_SECRET](params?: ZodDecorator_ParamsType[ZodDecorator.IS_WRITE_ONLY_SECRET]): DecoratedPhoneSchema;\n [ZodDecorator.EXCLUDE_FROM_CREATE](): DecoratedPhoneSchema;\n [ZodDecorator.EXCLUDE_FROM_UPDATE](): DecoratedPhoneSchema;\n addDecorators(decorators: DecoratorInput[]): DecoratedPhoneSchema;\n};\n\n/**\n * Creates a phone schema for E.164 phone numbers.\n *\n * @example\n * ```typescript\n * import { z_phone } from '@wildo-ai/zod-decorators';\n *\n * z_phone()\n * z_phone({ defaultCountry: 'FR' })\n * ```\n */\nexport function z_phone(options?: PhoneSchemaOptions): DecoratedPhoneSchema {\n return createPhoneSchema(options);\n}\n/** @wildo_source:part:end zod.factories.phone */\n"]}
|
|
1
|
+
{"version":3,"file":"zod-phone.js","sourceRoot":"","sources":["../../../src/zod-phone.ts"],"names":[],"mappings":"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","sourcesContent":["// ============================================================================\n// PHONE SCHEMA HELPER\n// ============================================================================\n\nimport type {\n DecoratorInput,\n CustomFieldMetadata,\n PhoneSchemaMetadata,\n PhoneSchemaOptions,\n SummaryFieldParams,\n ZodDecorator,\n ZodDecorator_ParamsType,\n} from './zod-decorators.types';\nimport { SCHEMA_METADATA } from './zod-decorators.types';\nimport { z } from 'zod';\nimport { addChainableMethods } from './zod.module-override';\nimport {\n parsePhoneNumberFromString,\n isValidPhoneNumber,\n getCountries as getCountriesFromLib,\n type CountryCode,\n getCountryCallingCode,\n formatIncompletePhoneNumber,\n getExampleNumber,\n AsYouType,\n} from 'libphonenumber-js';\n// JS-module subpath (NOT the .json subpath): importable under native ESM\n// without JSON import attributes, so the same source compiles for Node and\n// browser consumers alike. Example numbers back per-country placeholders.\nimport phoneExamples from 'libphonenumber-js/mobile/examples';\n\n/** Returns country codes (e.g. \"US\", \"FR\") for form components. */\nexport function getCountries(): string[] {\n return getCountriesFromLib() as string[];\n}\n\n/**\n * Phone value type — E.164 string (e.g., \"+33123456789\").\n * Use formatPhoneNumber() for display, parsePhoneNumber() for parsing.\n */\nexport type PhoneValue = string;\n\n/** Default country when parsing numbers without country code */\nconst DEFAULT_COUNTRY: CountryCode = 'US';\n\n/**\n * Parse a phone string to PhoneNumber or undefined.\n *\n * @param value - Raw input (E.164, national, or partial)\n * @param defaultCountry - Country code (e.g. \"US\", \"FR\") for numbers without +prefix\n * @returns PhoneNumber or undefined if invalid\n */\nexport function parsePhone(value: string, defaultCountry?: string): ReturnType<typeof parsePhoneNumberFromString> {\n if (!value || typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n const country = defaultCountry ?? DEFAULT_COUNTRY;\n return parsePhoneNumberFromString(trimmed, { defaultCountry: country as CountryCode });\n}\n\n/**\n * Validate a phone number string.\n *\n * @param value - Phone string to validate\n * @param defaultCountry - Country code (e.g. \"US\", \"FR\") for numbers without +prefix\n * @returns true if valid\n */\nexport function isValidPhone(value: string, defaultCountry?: string): boolean {\n if (!value || typeof value !== 'string') return false;\n const trimmed = value.trim();\n if (!trimmed) return false;\n const country = defaultCountry ?? DEFAULT_COUNTRY;\n return isValidPhoneNumber(trimmed, { defaultCountry: country as CountryCode });\n}\n\n/**\n * Format a phone number for display.\n *\n * @param value - E.164 or parseable phone string\n * @param defaultCountry - Country code (e.g. \"US\", \"FR\") for numbers without +prefix\n * @param format - 'international' | 'national' (default: international)\n * @returns Formatted string or original if unparseable\n */\nexport function formatPhoneNumber(\n value: string,\n defaultCountry?: string,\n format: 'international' | 'national' = 'international'\n): string {\n const parsed = parsePhone(value, defaultCountry);\n if (!parsed) return value;\n return format === 'national' ? parsed.formatNational() : parsed.formatInternational();\n}\n\n/**\n * Get country calling code (e.g., \"1\" for US).\n *\n * @param country - Country code (e.g. \"US\", \"FR\")\n */\nexport function getPhoneCountryCode(country: string): string {\n return getCountryCallingCode(country as CountryCode);\n}\n\n/**\n * Format a PARTIAL (as-you-type) national phone input for a country.\n *\n * Wraps libphonenumber's incomplete-number formatter so form controls can\n * format while the user is still typing (\"0612\" → \"06 12\" for FR) without\n * importing libphonenumber-js directly — the phone surface stays owned here.\n *\n * @param value - Partial national input (digits, may carry punctuation)\n * @param country - Country code (e.g. \"US\", \"FR\") providing the format plan\n * @returns The formatted partial, or the input unchanged when no plan applies\n */\nexport function formatPartialPhoneNumber(value: string, country?: string): string {\n if (!value) return value;\n const cc = (country ?? DEFAULT_COUNTRY) as CountryCode;\n return formatIncompletePhoneNumber(value, cc);\n}\n\n/**\n * Example national number for a country, for use as an input placeholder\n * (e.g. FR → \"06 12 34 56 78\"). Backed by libphonenumber's curated mobile\n * example set; returns undefined for countries without an example.\n *\n * @param country - Country code (e.g. \"US\", \"FR\")\n */\nexport function getExamplePhoneNumber(country: string): string | undefined {\n const example = getExampleNumber(country as CountryCode, phoneExamples);\n return example?.formatNational();\n}\n\n/**\n * Detect the country of a phone input that starts with an international\n * prefix (\"+...\"), even while the number is still incomplete.\n *\n * Powers the best-practice behavior where pasting/typing \"+49 30 ...\" into\n * the national input automatically switches the country selector to DE.\n * Returns undefined when the input is not international or the country is\n * not yet determinable (e.g. \"+1\" is ambiguous across NANP countries).\n *\n * @param value - Raw input, expected to start with \"+\"\n */\nexport function detectPhoneCountry(value: string): string | undefined {\n if (!value?.trim().startsWith('+')) return undefined;\n const formatter = new AsYouType();\n formatter.input(value.trim());\n return formatter.getCountry();\n}\n\n/**\n * @wildo_source:part:start zod.factories.phone facet:layer:shared facet:family:schema-factory\n *\n * Creates a phone schema with metadata for detection and form component rendering.\n * Values are stored as E.164 strings. Empty string passes validation.\n *\n * @param options - Configuration options for phone field\n * @returns A Zod string schema with metadata for phone detection\n */\nexport function createPhoneSchema(options: PhoneSchemaOptions = {}): DecoratedPhoneSchema {\n const { defaultCountry = DEFAULT_COUNTRY } = options;\n\n const phoneMetadata: PhoneSchemaMetadata = {\n isPhone: true,\n defaultCountry,\n };\n\n // PhoneCountryCode is libphonenumber's CountryCode union, so no cast needed.\n const country: CountryCode = defaultCountry;\n const phoneSchema = z\n .string()\n .trim()\n .refine((val) => val === '' || isValidPhone(val, country), {\n message: 'Invalid phone number',\n })\n // E.164 normalization is string -> string, so model it as a Zod 4\n // overwrite rather than a transform. The runtime result is identical, but\n // the schema remains truthfully introspectable as a string by JSON Schema /\n // OpenAPI generators instead of degrading to an unrepresentable transform.\n .overwrite((val) => {\n if (val === '') return '';\n const parsed = parsePhone(val, country);\n return parsed?.format('E.164') ?? val;\n })\n // Preserve the established ZodPipe surface used by decorator metadata and\n // boundary walkers; the terminal string adds no value conversion.\n .pipe(z.string()) as unknown as z.ZodString;\n\n const existingMetadata: CustomFieldMetadata = (phoneSchema as any)[SCHEMA_METADATA] || {};\n (phoneSchema as any)[SCHEMA_METADATA] = {\n ...existingMetadata,\n phoneConfig: phoneMetadata,\n };\n\n // 'ZodString' rather than the instance's own constructor, which is `ZodPipe` because of the\n // `.pipe(z.string())` above. A phone IS a string for every decorator purpose — the pipe exists to\n // normalize to E.164, not to change what the field is — and without this the applyable-type\n // lookup matches nothing and the schema carries NO decorators at all, including the eight\n // `DecoratedPhoneSchema` declares.\n addChainableMethods(phoneSchema, 'ZodString');\n\n return phoneSchema as unknown as DecoratedPhoneSchema;\n}\n\n/**\n * Return type for phone schemas - includes decorator methods.\n */\nexport type DecoratedPhoneSchema = z.ZodString & {\n [ZodDecorator.IS_DB_INDEXED](): DecoratedPhoneSchema;\n [ZodDecorator.IS_HIDDEN](params?: ZodDecorator_ParamsType[ZodDecorator.IS_HIDDEN]): DecoratedPhoneSchema;\n [ZodDecorator.IS_NOT_EDITABLE](params?: ZodDecorator_ParamsType[ZodDecorator.IS_NOT_EDITABLE]): DecoratedPhoneSchema;\n [ZodDecorator.IS_SUMMARY_FIELD](params?: SummaryFieldParams): DecoratedPhoneSchema;\n [ZodDecorator.IS_BACKEND_ONLY](params?: ZodDecorator_ParamsType[ZodDecorator.IS_BACKEND_ONLY]): DecoratedPhoneSchema;\n [ZodDecorator.IS_WRITE_ONLY_SECRET](params?: ZodDecorator_ParamsType[ZodDecorator.IS_WRITE_ONLY_SECRET]): DecoratedPhoneSchema;\n [ZodDecorator.EXCLUDE_FROM_CREATE](): DecoratedPhoneSchema;\n [ZodDecorator.EXCLUDE_FROM_UPDATE](): DecoratedPhoneSchema;\n /**\n * Declared here, as the sibling factories declare theirs (`DecoratedMoneySchema.moneyUI`,\n * `DecoratedCodeSchema.codeUI`, …), because a phone's display and edit policy is authored on the\n * factory's output and nowhere else. The applyable-type map admits `phoneUI` on `ZodString`, but\n * a bare `z.string()` is not a phone, so the base prototype deliberately does not carry it.\n */\n [ZodDecorator.PHONE_UI](params?: ZodDecorator_ParamsType[ZodDecorator.PHONE_UI]): DecoratedPhoneSchema;\n [ZodDecorator.PHONE_SPEC](params?: ZodDecorator_ParamsType[ZodDecorator.PHONE_SPEC]): DecoratedPhoneSchema;\n addDecorators(decorators: DecoratorInput[]): DecoratedPhoneSchema;\n};\n\n/**\n * Creates a phone schema for E.164 phone numbers.\n *\n * @example\n * ```typescript\n * import { z_phone } from '@wildo-ai/zod-decorators';\n *\n * z_phone()\n * z_phone({ defaultCountry: 'FR' })\n * ```\n */\nexport function z_phone(options?: PhoneSchemaOptions): DecoratedPhoneSchema {\n return createPhoneSchema(options);\n}\n/** @wildo_source:part:end zod.factories.phone */\n"]}
|