@wildo-ai/zod-decorators 1.1.4 → 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/currencies.shared.schemas.d.ts.map +1 -1
- package/dist/esm/currencies.shared.schemas.js.map +1 -1
- 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/extension-nature-map.d.ts.map +1 -1
- package/dist/esm/files/mime-registry.d.ts.map +1 -1
- package/dist/esm/files/unified-registry.d.ts +2 -2
- package/dist/esm/files/unified-registry.d.ts.map +1 -1
- 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/decorated-test-schemas.d.ts.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-bigdecimal.d.ts.map +1 -1
- 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-color.d.ts.map +1 -1
- package/dist/esm/zod-decorators.types.d.ts +265 -19
- package/dist/esm/zod-decorators.types.d.ts.map +1 -1
- package/dist/esm/zod-decorators.types.js +142 -0
- 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 +76 -61
- 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-range.d.ts.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
|
@@ -98,6 +98,8 @@ export type DecoratedDurationSchema = z.ZodObject<{
|
|
|
98
98
|
unit: z.ZodTypeAny;
|
|
99
99
|
}> & {
|
|
100
100
|
[ZodDecorator.IS_DB_INDEXED](): DecoratedDurationSchema;
|
|
101
|
+
/** Installed at runtime with the other chainable methods; declared here so an authored `.durationUI(…)` typechecks. */
|
|
102
|
+
[ZodDecorator.DURATION_UI](params?: ZodDecorator_ParamsType[ZodDecorator.DURATION_UI]): DecoratedDurationSchema;
|
|
101
103
|
[ZodDecorator.IS_HIDDEN](params?: ZodDecorator_ParamsType[ZodDecorator.IS_HIDDEN]): DecoratedDurationSchema;
|
|
102
104
|
[ZodDecorator.IS_NOT_EDITABLE](params?: ZodDecorator_ParamsType[ZodDecorator.IS_NOT_EDITABLE]): DecoratedDurationSchema;
|
|
103
105
|
[ZodDecorator.IS_SUMMARY_FIELD](params?: SummaryFieldParams): DecoratedDurationSchema;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod-duration.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"zod-duration.d.ts","sourceRoot":"","sources":["../../../src/zod-duration.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,cAAc,EAId,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACZ,uBAAuB,EACxB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB;IACnB,IAAI,EAAE,YAAY,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,YAAY,CAAC,EAAE,YAAY,EAAE,CAAC;IAC9B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAeD,6FAA6F;AAC7F,eAAO,MAAM,kBAAkB,2FAAkD,CAAC;AAElF;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;iBAG9B,CAAC;AAEH;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAE1D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,CAsBrE;AAeD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,CAAC,EAAE,aAAa,EAChB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACpC,MAAM,CAOR;AAED;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,GAAE,qBAA0B,GAClC,uBAAuB,CAyCzB;AAED;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,SAAS,CAAC;IAChD,KAAK,EAAE,CAAC,CAAC,SAAS,CAAC;IACnB,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC;CACpB,CAAC,GAAG;IACH,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,uBAAuB,CAAC;IACxD,uHAAuH;IACvH,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,uBAAuB,CAAC;IAChH,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,uBAAuB,CAAC;IAC5G,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC,YAAY,CAAC,eAAe,CAAC,GAAG,uBAAuB,CAAC;IACxH,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,uBAAuB,CAAC;IACtF,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC,YAAY,CAAC,eAAe,CAAC,GAAG,uBAAuB,CAAC;IACxH,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC,YAAY,CAAC,oBAAoB,CAAC,GAAG,uBAAuB,CAAC;IAClI,CAAC,YAAY,CAAC,mBAAmB,CAAC,IAAI,uBAAuB,CAAC;IAC9D,CAAC,YAAY,CAAC,mBAAmB,CAAC,IAAI,uBAAuB,CAAC;IAC9D,aAAa,CAAC,UAAU,EAAE,cAAc,EAAE,GAAG,uBAAuB,CAAC;CACtE,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,uBAAuB,CAEnF;AACD,oDAAoD;AAEpD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,yBAGlC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod-duration.js","sourceRoot":"","sources":["../../../src/zod-duration.ts"],"names":[],"mappings":"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","sourcesContent":["\n// ============================================================================\n// DURATION SCHEMA HELPER\n// ============================================================================\n\nimport {\n DecoratorInput,\n SCHEMA_METADATA,\n CustomFieldMetadata,\n DurationSchemaMetadata,\n DurationUnit,\n SummaryFieldParams,\n ZodDecorator,\n ZodDecorator_ParamsType,\n} from './zod-decorators.types';\nimport { z } from 'zod';\nimport { addChainableMethods } from './zod.module-override';\n\n/**\n * @wildo_source:part:start zod.factories.duration facet:layer:shared facet:family:schema-factory\n *\n * Duration value type — represents a time span with value and unit.\n *\n * Stored as { value: number, unit: DurationUnit } for clarity and flexibility.\n * Use durationToSeconds() for canonical conversion when needed (e.g., TTL, expiry).\n *\n * @example\n * { value: 5, unit: DurationUnit.MINUTES } // 5 minutes\n * { value: 1, unit: DurationUnit.HOURS } // 1 hour\n */\nexport interface DurationValue {\n /** Numeric quantity (must be non-negative for typical use) */\n value: number;\n /** Unit of time */\n unit: DurationUnit;\n}\n\n/**\n * Options for creating a duration schema via z_duration().\n * Uses the DurationUnit enum for type-safe configuration.\n */\nexport interface DurationSchemaOptions {\n /** Allowed units (if empty/undefined, all units are allowed) */\n allowedUnits?: DurationUnit[];\n /** Minimum value (for the numeric part) */\n minValue?: number;\n /** Maximum value (for the numeric part) */\n maxValue?: number;\n}\n\n/** Seconds multiplier for each duration unit */\nconst DURATION_MULTIPLIERS: Record<DurationUnit, number> = {\n [DurationUnit.MILLISECONDS]: 0.001,\n [DurationUnit.SECONDS]: 1,\n [DurationUnit.MINUTES]: 60,\n [DurationUnit.HOURS]: 3600,\n [DurationUnit.DAYS]: 86400,\n [DurationUnit.WEEKS]: 604800,\n [DurationUnit.MONTHS]: 30 * 86400,\n [DurationUnit.YEARS]: 365.25 * 86400,\n [DurationUnit.CENTURIES]: 100 * 365.25 * 86400,\n};\n\n/** Canonical Zod schema for DurationUnit. Clone via `z_clone()` for independent metadata. */\nexport const DurationUnitSchema = z.enum(DurationUnit).systemEnum('DurationUnit');\n\n/**\n * Zod schema for DurationValue.\n */\nexport const DurationValueSchema = z.object({\n value: z.number().int().min(0),\n unit: DurationUnitSchema,\n});\n\n/**\n * Convert a duration to total seconds for canonical storage/comparison.\n * Use when setting TTL, expiry, or comparing durations.\n *\n * @param d - Duration value\n * @returns Total seconds\n */\nexport function durationToSeconds(d: DurationValue): number {\n return d.value * DURATION_MULTIPLIERS[d.unit];\n}\n\n/**\n * Create a duration from total seconds, using the most appropriate unit.\n * Prefers larger units when the value divides evenly.\n *\n * @param totalSeconds - Total seconds\n * @returns DurationValue\n */\nexport function secondsToDuration(totalSeconds: number): DurationValue {\n if (totalSeconds <= 0) {\n return { value: 0, unit: DurationUnit.SECONDS };\n }\n const units: DurationUnit[] = [\n DurationUnit.CENTURIES,\n DurationUnit.YEARS,\n DurationUnit.MONTHS,\n DurationUnit.WEEKS,\n DurationUnit.DAYS,\n DurationUnit.HOURS,\n DurationUnit.MINUTES,\n DurationUnit.SECONDS,\n DurationUnit.MILLISECONDS,\n ];\n for (const unit of units) {\n const m = DURATION_MULTIPLIERS[unit];\n if (totalSeconds % m === 0 && totalSeconds >= m) {\n return { value: totalSeconds / m, unit };\n }\n }\n return { value: totalSeconds, unit: DurationUnit.SECONDS };\n}\n\n/** Singular form for each duration unit (when value is 1) */\nconst DURATION_UNIT_SINGULAR: Record<DurationUnit, string> = {\n [DurationUnit.MILLISECONDS]: 'millisecond',\n [DurationUnit.SECONDS]: 'second',\n [DurationUnit.MINUTES]: 'minute',\n [DurationUnit.HOURS]: 'hour',\n [DurationUnit.DAYS]: 'day',\n [DurationUnit.WEEKS]: 'week',\n [DurationUnit.MONTHS]: 'month',\n [DurationUnit.YEARS]: 'year',\n [DurationUnit.CENTURIES]: 'century',\n};\n\n/**\n * Format a duration for display.\n *\n * @param d - Duration value\n * @param options - Format options\n * @returns Formatted string (e.g., \"5 minutes\", \"1 hour\")\n */\nexport function formatDuration(\n d: DurationValue,\n options: { pluralize?: boolean } = {}\n): string {\n const { pluralize = true } = options;\n const label =\n pluralize && d.value === 1\n ? DURATION_UNIT_SINGULAR[d.unit] ?? d.unit\n : d.unit;\n return `${d.value} ${label}`;\n}\n\n/**\n * z_duration() - Creates duration schemas for time spans.\n *\n * Duration values are stored as { value, unit }.\n * Use durationToSeconds() when you need canonical seconds (e.g., TTL).\n *\n * @example\n * ```typescript\n * import { z_duration, DurationUnit } from '@wildo-ai/zod-decorators';\n *\n * const sessionTtl = z_duration();\n * const allowedUnits = z_duration({ allowedUnits: [DurationUnit.MINUTES, DurationUnit.HOURS] });\n *\n * // UI props via .durationUI()\n * z_duration().durationUI({ edit: { defaultUnit: DurationUnit.MINUTES } })\n * z_duration({ allowedUnits: [DurationUnit.HOURS, DurationUnit.DAYS] }).durationUI({ edit: { defaultUnit: DurationUnit.HOURS } })\n * ```\n */\n\n/**\n * Creates a duration schema with metadata for detection and form component rendering.\n *\n * @param options - Configuration options for duration field\n * @returns A Zod object schema with metadata for duration detection\n */\nexport function createDurationSchema(\n options: DurationSchemaOptions = {}\n): DecoratedDurationSchema {\n const {\n allowedUnits,\n minValue,\n maxValue,\n } = options;\n\n let valueSchema = z.number().int().min(0);\n if (minValue !== undefined) {\n valueSchema = valueSchema.min(minValue);\n }\n if (maxValue !== undefined) {\n valueSchema = valueSchema.max(maxValue);\n }\n\n const unitSchema =\n allowedUnits && allowedUnits.length > 0\n ? z.enum([allowedUnits[0], ...allowedUnits.slice(1)] as [string, ...string[]])\n : DurationUnitSchema;\n\n const durationSchema = z.object({\n value: valueSchema,\n unit: unitSchema,\n });\n\n const durationMetadata: DurationSchemaMetadata = {\n isDuration: true,\n ...(allowedUnits && allowedUnits.length > 0 && { allowedUnits }),\n ...(minValue !== undefined && { minValue }),\n ...(maxValue !== undefined && { maxValue }),\n };\n\n const existingMetadata: CustomFieldMetadata = (durationSchema as any)[SCHEMA_METADATA] || {};\n (durationSchema as any)[SCHEMA_METADATA] = {\n ...existingMetadata,\n durationConfig: durationMetadata,\n };\n\n addChainableMethods(durationSchema);\n\n return durationSchema as unknown as DecoratedDurationSchema;\n}\n\n/**\n * Return type for duration schemas - includes decorator methods.\n */\nexport type DecoratedDurationSchema = z.ZodObject<{\n value: z.ZodNumber;\n unit: z.ZodTypeAny;\n}> & {\n [ZodDecorator.IS_DB_INDEXED](): DecoratedDurationSchema;\n [ZodDecorator.IS_HIDDEN](params?: ZodDecorator_ParamsType[ZodDecorator.IS_HIDDEN]): DecoratedDurationSchema;\n [ZodDecorator.IS_NOT_EDITABLE](params?: ZodDecorator_ParamsType[ZodDecorator.IS_NOT_EDITABLE]): DecoratedDurationSchema;\n [ZodDecorator.IS_SUMMARY_FIELD](params?: SummaryFieldParams): DecoratedDurationSchema;\n [ZodDecorator.IS_BACKEND_ONLY](params?: ZodDecorator_ParamsType[ZodDecorator.IS_BACKEND_ONLY]): DecoratedDurationSchema;\n [ZodDecorator.IS_WRITE_ONLY_SECRET](params?: ZodDecorator_ParamsType[ZodDecorator.IS_WRITE_ONLY_SECRET]): DecoratedDurationSchema;\n [ZodDecorator.EXCLUDE_FROM_CREATE](): DecoratedDurationSchema;\n [ZodDecorator.EXCLUDE_FROM_UPDATE](): DecoratedDurationSchema;\n addDecorators(decorators: DecoratorInput[]): DecoratedDurationSchema;\n};\n\n/**\n * Creates a duration schema for time spans.\n *\n * @example\n * ```typescript\n * import { z_duration, DurationUnit } from '@wildo-ai/zod-decorators';\n *\n * z_duration()\n * z_duration({ allowedUnits: [DurationUnit.MINUTES, DurationUnit.HOURS, DurationUnit.DAYS] })\n * z_duration({ minValue: 1, maxValue: 1440 }) // 1–1440 minutes\n *\n * // UI props via .durationUI()\n * z_duration().durationUI({ edit: { defaultUnit: DurationUnit.HOURS } })\n * ```\n */\nexport function z_duration(options?: DurationSchemaOptions): DecoratedDurationSchema {\n return createDurationSchema(options);\n}\n/** @wildo_source:part:end zod.factories.duration */\n\n/**\n * Schema for token expiry duration — minutes, hours, or days only, value ≥ 1.\n * Use for expiresIn in consumable tokens, sharableDefaults, and share API.\n */\nexport const ExpiresInDurationSchema = z_duration({\n minValue: 1,\n allowedUnits: [DurationUnit.MINUTES, DurationUnit.HOURS, DurationUnit.DAYS],\n});\n"]}
|
|
1
|
+
{"version":3,"file":"zod-duration.js","sourceRoot":"","sources":["../../../src/zod-duration.ts"],"names":[],"mappings":"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","sourcesContent":["\n// ============================================================================\n// DURATION SCHEMA HELPER\n// ============================================================================\n\nimport {\n DecoratorInput,\n SCHEMA_METADATA,\n CustomFieldMetadata,\n DurationSchemaMetadata,\n DurationUnit,\n SummaryFieldParams,\n ZodDecorator,\n ZodDecorator_ParamsType,\n} from './zod-decorators.types';\nimport { z } from 'zod';\nimport { addChainableMethods } from './zod.module-override';\n\n/**\n * @wildo_source:part:start zod.factories.duration facet:layer:shared facet:family:schema-factory\n *\n * Duration value type — represents a time span with value and unit.\n *\n * Stored as { value: number, unit: DurationUnit } for clarity and flexibility.\n * Use durationToSeconds() for canonical conversion when needed (e.g., TTL, expiry).\n *\n * @example\n * { value: 5, unit: DurationUnit.MINUTES } // 5 minutes\n * { value: 1, unit: DurationUnit.HOURS } // 1 hour\n */\nexport interface DurationValue {\n /** Numeric quantity (must be non-negative for typical use) */\n value: number;\n /** Unit of time */\n unit: DurationUnit;\n}\n\n/**\n * Options for creating a duration schema via z_duration().\n * Uses the DurationUnit enum for type-safe configuration.\n */\nexport interface DurationSchemaOptions {\n /** Allowed units (if empty/undefined, all units are allowed) */\n allowedUnits?: DurationUnit[];\n /** Minimum value (for the numeric part) */\n minValue?: number;\n /** Maximum value (for the numeric part) */\n maxValue?: number;\n}\n\n/** Seconds multiplier for each duration unit */\nconst DURATION_MULTIPLIERS: Record<DurationUnit, number> = {\n [DurationUnit.MILLISECONDS]: 0.001,\n [DurationUnit.SECONDS]: 1,\n [DurationUnit.MINUTES]: 60,\n [DurationUnit.HOURS]: 3600,\n [DurationUnit.DAYS]: 86400,\n [DurationUnit.WEEKS]: 604800,\n [DurationUnit.MONTHS]: 30 * 86400,\n [DurationUnit.YEARS]: 365.25 * 86400,\n [DurationUnit.CENTURIES]: 100 * 365.25 * 86400,\n};\n\n/** Canonical Zod schema for DurationUnit. Clone via `z_clone()` for independent metadata. */\nexport const DurationUnitSchema = z.enum(DurationUnit).systemEnum('DurationUnit');\n\n/**\n * Zod schema for DurationValue.\n */\nexport const DurationValueSchema = z.object({\n value: z.number().int().min(0),\n unit: DurationUnitSchema,\n});\n\n/**\n * Convert a duration to total seconds for canonical storage/comparison.\n * Use when setting TTL, expiry, or comparing durations.\n *\n * @param d - Duration value\n * @returns Total seconds\n */\nexport function durationToSeconds(d: DurationValue): number {\n return d.value * DURATION_MULTIPLIERS[d.unit];\n}\n\n/**\n * Create a duration from total seconds, using the most appropriate unit.\n * Prefers larger units when the value divides evenly.\n *\n * @param totalSeconds - Total seconds\n * @returns DurationValue\n */\nexport function secondsToDuration(totalSeconds: number): DurationValue {\n if (totalSeconds <= 0) {\n return { value: 0, unit: DurationUnit.SECONDS };\n }\n const units: DurationUnit[] = [\n DurationUnit.CENTURIES,\n DurationUnit.YEARS,\n DurationUnit.MONTHS,\n DurationUnit.WEEKS,\n DurationUnit.DAYS,\n DurationUnit.HOURS,\n DurationUnit.MINUTES,\n DurationUnit.SECONDS,\n DurationUnit.MILLISECONDS,\n ];\n for (const unit of units) {\n const m = DURATION_MULTIPLIERS[unit];\n if (totalSeconds % m === 0 && totalSeconds >= m) {\n return { value: totalSeconds / m, unit };\n }\n }\n return { value: totalSeconds, unit: DurationUnit.SECONDS };\n}\n\n/** Singular form for each duration unit (when value is 1) */\nconst DURATION_UNIT_SINGULAR: Record<DurationUnit, string> = {\n [DurationUnit.MILLISECONDS]: 'millisecond',\n [DurationUnit.SECONDS]: 'second',\n [DurationUnit.MINUTES]: 'minute',\n [DurationUnit.HOURS]: 'hour',\n [DurationUnit.DAYS]: 'day',\n [DurationUnit.WEEKS]: 'week',\n [DurationUnit.MONTHS]: 'month',\n [DurationUnit.YEARS]: 'year',\n [DurationUnit.CENTURIES]: 'century',\n};\n\n/**\n * Format a duration for display.\n *\n * @param d - Duration value\n * @param options - Format options\n * @returns Formatted string (e.g., \"5 minutes\", \"1 hour\")\n */\nexport function formatDuration(\n d: DurationValue,\n options: { pluralize?: boolean } = {}\n): string {\n const { pluralize = true } = options;\n const label =\n pluralize && d.value === 1\n ? DURATION_UNIT_SINGULAR[d.unit] ?? d.unit\n : d.unit;\n return `${d.value} ${label}`;\n}\n\n/**\n * z_duration() - Creates duration schemas for time spans.\n *\n * Duration values are stored as { value, unit }.\n * Use durationToSeconds() when you need canonical seconds (e.g., TTL).\n *\n * @example\n * ```typescript\n * import { z_duration, DurationUnit } from '@wildo-ai/zod-decorators';\n *\n * const sessionTtl = z_duration();\n * const allowedUnits = z_duration({ allowedUnits: [DurationUnit.MINUTES, DurationUnit.HOURS] });\n *\n * // UI props via .durationUI()\n * z_duration().durationUI({ edit: { defaultUnit: DurationUnit.MINUTES } })\n * z_duration({ allowedUnits: [DurationUnit.HOURS, DurationUnit.DAYS] }).durationUI({ edit: { defaultUnit: DurationUnit.HOURS } })\n * ```\n */\n\n/**\n * Creates a duration schema with metadata for detection and form component rendering.\n *\n * @param options - Configuration options for duration field\n * @returns A Zod object schema with metadata for duration detection\n */\nexport function createDurationSchema(\n options: DurationSchemaOptions = {}\n): DecoratedDurationSchema {\n const {\n allowedUnits,\n minValue,\n maxValue,\n } = options;\n\n let valueSchema = z.number().int().min(0);\n if (minValue !== undefined) {\n valueSchema = valueSchema.min(minValue);\n }\n if (maxValue !== undefined) {\n valueSchema = valueSchema.max(maxValue);\n }\n\n const unitSchema =\n allowedUnits && allowedUnits.length > 0\n ? z.enum([allowedUnits[0], ...allowedUnits.slice(1)] as [string, ...string[]])\n : DurationUnitSchema;\n\n const durationSchema = z.object({\n value: valueSchema,\n unit: unitSchema,\n });\n\n const durationMetadata: DurationSchemaMetadata = {\n isDuration: true,\n ...(allowedUnits && allowedUnits.length > 0 && { allowedUnits }),\n ...(minValue !== undefined && { minValue }),\n ...(maxValue !== undefined && { maxValue }),\n };\n\n const existingMetadata: CustomFieldMetadata = (durationSchema as any)[SCHEMA_METADATA] || {};\n (durationSchema as any)[SCHEMA_METADATA] = {\n ...existingMetadata,\n durationConfig: durationMetadata,\n };\n\n addChainableMethods(durationSchema);\n\n return durationSchema as unknown as DecoratedDurationSchema;\n}\n\n/**\n * Return type for duration schemas - includes decorator methods.\n */\nexport type DecoratedDurationSchema = z.ZodObject<{\n value: z.ZodNumber;\n unit: z.ZodTypeAny;\n}> & {\n [ZodDecorator.IS_DB_INDEXED](): DecoratedDurationSchema;\n /** Installed at runtime with the other chainable methods; declared here so an authored `.durationUI(…)` typechecks. */\n [ZodDecorator.DURATION_UI](params?: ZodDecorator_ParamsType[ZodDecorator.DURATION_UI]): DecoratedDurationSchema;\n [ZodDecorator.IS_HIDDEN](params?: ZodDecorator_ParamsType[ZodDecorator.IS_HIDDEN]): DecoratedDurationSchema;\n [ZodDecorator.IS_NOT_EDITABLE](params?: ZodDecorator_ParamsType[ZodDecorator.IS_NOT_EDITABLE]): DecoratedDurationSchema;\n [ZodDecorator.IS_SUMMARY_FIELD](params?: SummaryFieldParams): DecoratedDurationSchema;\n [ZodDecorator.IS_BACKEND_ONLY](params?: ZodDecorator_ParamsType[ZodDecorator.IS_BACKEND_ONLY]): DecoratedDurationSchema;\n [ZodDecorator.IS_WRITE_ONLY_SECRET](params?: ZodDecorator_ParamsType[ZodDecorator.IS_WRITE_ONLY_SECRET]): DecoratedDurationSchema;\n [ZodDecorator.EXCLUDE_FROM_CREATE](): DecoratedDurationSchema;\n [ZodDecorator.EXCLUDE_FROM_UPDATE](): DecoratedDurationSchema;\n addDecorators(decorators: DecoratorInput[]): DecoratedDurationSchema;\n};\n\n/**\n * Creates a duration schema for time spans.\n *\n * @example\n * ```typescript\n * import { z_duration, DurationUnit } from '@wildo-ai/zod-decorators';\n *\n * z_duration()\n * z_duration({ allowedUnits: [DurationUnit.MINUTES, DurationUnit.HOURS, DurationUnit.DAYS] })\n * z_duration({ minValue: 1, maxValue: 1440 }) // 1–1440 minutes\n *\n * // UI props via .durationUI()\n * z_duration().durationUI({ edit: { defaultUnit: DurationUnit.HOURS } })\n * ```\n */\nexport function z_duration(options?: DurationSchemaOptions): DecoratedDurationSchema {\n return createDurationSchema(options);\n}\n/** @wildo_source:part:end zod.factories.duration */\n\n/**\n * Schema for token expiry duration — minutes, hours, or days only, value ≥ 1.\n * Use for expiresIn in consumable tokens, sharableDefaults, and share API.\n */\nexport const ExpiresInDurationSchema = z_duration({\n minValue: 1,\n allowedUnits: [DurationUnit.MINUTES, DurationUnit.HOURS, DurationUnit.DAYS],\n});\n"]}
|
package/dist/esm/zod-file.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { FileSchemaOptions, FileMimeTypeGroup, FileNature, FileDisplayNature, FileDisplayPresentation, type FileActivationConfig, type FileUIDisplayParams, FileStorageAccepted, FileNatureConstraints_Image, FileNatureConstraints_Video, FileNatureConstraints_Audio, FileNatureConstraints_Document } from "./zod-decorators.types";
|
|
1
|
+
import { FileSchemaOptions, FileMimeTypeGroup, FileNature, FileDisplayNature, FileDisplayPresentation, type FileActivationConfig, type FileUIDisplayParams, FileStorageAccepted, FileNatureConstraints_Image, FileNatureConstraints_Video, FileNatureConstraints_Audio, FileNatureConstraints_Document, ZodDecorator, ZodDecorator_ParamsType } from "./zod-decorators.types";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import { AgentFileFormat } from "./files/agent-file-formats";
|
|
3
4
|
/**
|
|
4
5
|
* Single file value type - represents a single file reference stored in the database.
|
|
5
6
|
* The actual file is stored in a file storage system, this object references it.
|
|
@@ -128,6 +129,19 @@ export interface DecoratedFileSchema extends z.ZodObject<{
|
|
|
128
129
|
fileId: z.ZodString;
|
|
129
130
|
updatedAt: z.ZodDate;
|
|
130
131
|
}> {
|
|
132
|
+
/**
|
|
133
|
+
* Declared here, as the sibling factories declare theirs (`DecoratedMoneySchema.moneyUI`,
|
|
134
|
+
* `DecoratedPhoneSchema.phoneUI`, …), because a file's display and edit policy is authored on
|
|
135
|
+
* the factory's output and nowhere else. The applyable-type map admits `fileUI` on `ZodObject`,
|
|
136
|
+
* but a bare `z.object({...})` is not a file, so the base prototype deliberately does not carry
|
|
137
|
+
* it — the per-instance install `createFileSchema` performs is what makes it reachable.
|
|
138
|
+
*
|
|
139
|
+
* Not a RE-declaration: `fileUI` is absent from the `ZodObject` module augmentation, so this adds
|
|
140
|
+
* a member rather than conflicting with one. That distinction is what the TS2320 note above is
|
|
141
|
+
* about — re-declaring a member the augmentation already carries is what broke here before.
|
|
142
|
+
*/
|
|
143
|
+
[ZodDecorator.FILE_UI](params?: ZodDecorator_ParamsType[ZodDecorator.FILE_UI]): DecoratedFileSchema;
|
|
144
|
+
[ZodDecorator.FILE_SPEC](params?: ZodDecorator_ParamsType[ZodDecorator.FILE_SPEC]): DecoratedFileSchema;
|
|
131
145
|
}
|
|
132
146
|
/**
|
|
133
147
|
* Return type for multiple file schemas - includes decorator methods.
|
|
@@ -139,6 +153,19 @@ export interface DecoratedMultipleFileSchema extends z.ZodObject<{
|
|
|
139
153
|
fileIds: z.ZodArray<z.ZodString>;
|
|
140
154
|
updatedAt: z.ZodDate;
|
|
141
155
|
}> {
|
|
156
|
+
/**
|
|
157
|
+
* Declared here, as the sibling factories declare theirs (`DecoratedMoneySchema.moneyUI`,
|
|
158
|
+
* `DecoratedPhoneSchema.phoneUI`, …), because a file's display and edit policy is authored on
|
|
159
|
+
* the factory's output and nowhere else. The applyable-type map admits `fileUI` on `ZodObject`,
|
|
160
|
+
* but a bare `z.object({...})` is not a file, so the base prototype deliberately does not carry
|
|
161
|
+
* it — the per-instance install `createFileSchema` performs is what makes it reachable. Mirrors the single-file interface above.
|
|
162
|
+
*
|
|
163
|
+
* Not a RE-declaration: `fileUI` is absent from the `ZodObject` module augmentation, so this adds
|
|
164
|
+
* a member rather than conflicting with one. That distinction is what the TS2320 note above is
|
|
165
|
+
* about — re-declaring a member the augmentation already carries is what broke here before.
|
|
166
|
+
*/
|
|
167
|
+
[ZodDecorator.FILE_UI](params?: ZodDecorator_ParamsType[ZodDecorator.FILE_UI]): DecoratedMultipleFileSchema;
|
|
168
|
+
[ZodDecorator.FILE_SPEC](params?: ZodDecorator_ParamsType[ZodDecorator.FILE_SPEC]): DecoratedMultipleFileSchema;
|
|
142
169
|
}
|
|
143
170
|
/**
|
|
144
171
|
* Creates a file schema for file uploads with reference storage.
|
|
@@ -206,10 +233,40 @@ export declare function getFileExtension(filename: string): string;
|
|
|
206
233
|
*/
|
|
207
234
|
export declare function isMimeTypeAllowed(mimeType: string, allowedMimeTypes?: string[]): boolean;
|
|
208
235
|
/**
|
|
209
|
-
*
|
|
210
|
-
* Uses UnifiedFileFormatRegistry for better format detection.
|
|
236
|
+
* How an accepted file type is identified — the discriminator of {@link AcceptedFileKind}.
|
|
211
237
|
*/
|
|
212
|
-
export declare
|
|
238
|
+
export declare enum AcceptedFileKindCategory {
|
|
239
|
+
/** A broad nature (images, PDF, office documents, …) — one {@link FileNature} member. */
|
|
240
|
+
NATURE = "nature",
|
|
241
|
+
/** A text format an agent can produce — one {@link AgentFileFormat} member. */
|
|
242
|
+
AGENT_FORMAT = "agent_format",
|
|
243
|
+
/** Neither: the MIME subtype itself (`csv` for `text/csv`), shown as the value it is. */
|
|
244
|
+
MIME_SUBTYPE = "mime_subtype"
|
|
245
|
+
}
|
|
246
|
+
/** One kind of file a field accepts, as a FACT a renderer names — never as words. */
|
|
247
|
+
export type AcceptedFileKind = {
|
|
248
|
+
category: AcceptedFileKindCategory.NATURE;
|
|
249
|
+
nature: FileNature;
|
|
250
|
+
} | {
|
|
251
|
+
category: AcceptedFileKindCategory.AGENT_FORMAT;
|
|
252
|
+
format: AgentFileFormat;
|
|
253
|
+
} | {
|
|
254
|
+
category: AcceptedFileKindCategory.MIME_SUBTYPE;
|
|
255
|
+
subtype: string;
|
|
256
|
+
};
|
|
257
|
+
/**
|
|
258
|
+
* The kinds of file a field's `allowedMimeTypes` admit, deduplicated, in first-seen order. An empty
|
|
259
|
+
* result means every file is accepted.
|
|
260
|
+
*
|
|
261
|
+
* This answers FACTS and the renderer names them from its label tree. It used to answer an English
|
|
262
|
+
* sentence ("Images, PDF, Text files") from two hand-kept maps plus a humanizing fallback — words
|
|
263
|
+
* produced by code in a package with no i18n at all, which no locale could translate (#1283,
|
|
264
|
+
* `.claude/rules/display-text-comes-from-i18n.md`).
|
|
265
|
+
*
|
|
266
|
+
* Resolution per MIME type: the unified format registry first (a nature, or an agent format), then
|
|
267
|
+
* the broad MIME families the registry does not classify, then the subtype as a value.
|
|
268
|
+
*/
|
|
269
|
+
export declare function getAcceptedFileKinds(allowedMimeTypes?: string[]): AcceptedFileKind[];
|
|
213
270
|
/**
|
|
214
271
|
* Get file nature from schema metadata.
|
|
215
272
|
* @param schema - Zod schema (must be a file schema)
|
|
@@ -241,6 +298,15 @@ export declare function getFileConstraints(schema: z.ZodTypeAny): {
|
|
|
241
298
|
* 2. `mimeType` (from file metadata or browser File object) → detected via MIME prefix matching
|
|
242
299
|
* 3. `FileDisplayNature.GENERIC` (fallback)
|
|
243
300
|
*
|
|
301
|
+
* `FileNature.ALL` is not a nature, it is the ABSENCE of a declaration: a field that accepts anything
|
|
302
|
+
* says nothing about the file in front of it. So it does not decide at step 1 — the file's own MIME
|
|
303
|
+
* type does, exactly as for a field with no declared nature. Until 2026-09-24 it mapped to GENERIC and
|
|
304
|
+
* won, so every file in an open field, a PNG and a PDF included, resolved to GENERIC: no preview, and
|
|
305
|
+
* an authored `OVERLAY` activation always degraded to a download. `resolveFileDisplayPolicy` already
|
|
306
|
+
* describes the intended behaviour ("the file's ACTUAL nature has no displayer — which is only
|
|
307
|
+
* reachable when the schema declared an open nature"); this is what makes that sentence true.
|
|
308
|
+
* `FileNature.ARCHIVE` stays GENERIC at step 1, because that IS a declaration.
|
|
309
|
+
*
|
|
244
310
|
* @param schemaNature - The `FileNature` declared in schema metadata (from `getFileMetadata(schema)?.nature`)
|
|
245
311
|
* @param mimeType - The MIME type of the actual file
|
|
246
312
|
* @returns The `FileDisplayNature` to use for rendering
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod-file.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"zod-file.d.ts","sourceRoot":"","sources":["../../../src/zod-file.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/zod-file.js
CHANGED
|
@@ -5,6 +5,7 @@ import { SCHEMA_METADATA, FileMimeTypeGroups, FileNature, FileDisplayNature, Fil
|
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { addChainableMethods, addDecorators } from "./zod.module-override.js";
|
|
7
7
|
import { UnifiedFileFormatRegistry } from "./files/unified-registry.js";
|
|
8
|
+
import { AgentFileFormat } from "./files/agent-file-formats.js";
|
|
8
9
|
/**
|
|
9
10
|
* Deduplicated warning tracker for unsupported storage providers.
|
|
10
11
|
* Prevents console spam when the same schema is created multiple times (e.g., in tests or HMR).
|
|
@@ -179,9 +180,16 @@ export function createFileSchema(options = {}) {
|
|
|
179
180
|
const warnKey = unsupported.sort().join(',');
|
|
180
181
|
if (!_warnedStorageProviders.has(warnKey)) {
|
|
181
182
|
_warnedStorageProviders.add(warnKey);
|
|
182
|
-
|
|
183
|
+
// The two cases are NOT the same outcome, and saying only "skipped" understates the second
|
|
184
|
+
// badly enough to be misleading: alongside an implemented storage the declaration really is
|
|
185
|
+
// ignored, but as the ONLY declared storage it stops the application booting. That is the
|
|
186
|
+
// split #460 records, stated here at the moment an author writes the declaration — earlier
|
|
187
|
+
// than the startup validator and the storage router, which draw the same distinction.
|
|
188
|
+
console.warn(`[z_file] storageAccepted names storage(s) no provider serves yet: ${unsupported.join(', ')}. ` +
|
|
183
189
|
`Implemented: ${[..._supportedProviders].map((s) => `'${s}'`).join(', ')}. ` +
|
|
184
|
-
`
|
|
190
|
+
`Declared ALONGSIDE an implemented storage it is skipped by the storage router; declared as the ONLY ` +
|
|
191
|
+
`storage the application refuses to boot and every upload to this field is refused. There is no ` +
|
|
192
|
+
`environment variable that would enable it — a storage with no provider cannot be configured into existence.`);
|
|
185
193
|
}
|
|
186
194
|
}
|
|
187
195
|
if (filePathBinding) {
|
|
@@ -392,72 +400,70 @@ export function isMimeTypeAllowed(mimeType, allowedMimeTypes) {
|
|
|
392
400
|
return false;
|
|
393
401
|
}
|
|
394
402
|
/**
|
|
395
|
-
*
|
|
396
|
-
* Uses UnifiedFileFormatRegistry for better format detection.
|
|
403
|
+
* How an accepted file type is identified — the discriminator of {@link AcceptedFileKind}.
|
|
397
404
|
*/
|
|
398
|
-
export
|
|
405
|
+
export var AcceptedFileKindCategory;
|
|
406
|
+
(function (AcceptedFileKindCategory) {
|
|
407
|
+
/** A broad nature (images, PDF, office documents, …) — one {@link FileNature} member. */
|
|
408
|
+
AcceptedFileKindCategory["NATURE"] = "nature";
|
|
409
|
+
/** A text format an agent can produce — one {@link AgentFileFormat} member. */
|
|
410
|
+
AcceptedFileKindCategory["AGENT_FORMAT"] = "agent_format";
|
|
411
|
+
/** Neither: the MIME subtype itself (`csv` for `text/csv`), shown as the value it is. */
|
|
412
|
+
AcceptedFileKindCategory["MIME_SUBTYPE"] = "mime_subtype";
|
|
413
|
+
})(AcceptedFileKindCategory || (AcceptedFileKindCategory = {}));
|
|
414
|
+
const AGENT_FILE_FORMAT_VALUES = new Set(Object.values(AgentFileFormat));
|
|
415
|
+
/**
|
|
416
|
+
* The kinds of file a field's `allowedMimeTypes` admit, deduplicated, in first-seen order. An empty
|
|
417
|
+
* result means every file is accepted.
|
|
418
|
+
*
|
|
419
|
+
* This answers FACTS and the renderer names them from its label tree. It used to answer an English
|
|
420
|
+
* sentence ("Images, PDF, Text files") from two hand-kept maps plus a humanizing fallback — words
|
|
421
|
+
* produced by code in a package with no i18n at all, which no locale could translate (#1283,
|
|
422
|
+
* `.claude/rules/display-text-comes-from-i18n.md`).
|
|
423
|
+
*
|
|
424
|
+
* Resolution per MIME type: the unified format registry first (a nature, or an agent format), then
|
|
425
|
+
* the broad MIME families the registry does not classify, then the subtype as a value.
|
|
426
|
+
*/
|
|
427
|
+
export function getAcceptedFileKinds(allowedMimeTypes) {
|
|
399
428
|
if (!allowedMimeTypes || allowedMimeTypes.length === 0)
|
|
400
|
-
return
|
|
401
|
-
const
|
|
429
|
+
return [];
|
|
430
|
+
const kinds = [];
|
|
431
|
+
const seen = new Set();
|
|
432
|
+
const add = (kind, identity) => {
|
|
433
|
+
if (seen.has(identity))
|
|
434
|
+
return;
|
|
435
|
+
seen.add(identity);
|
|
436
|
+
kinds.push(kind);
|
|
437
|
+
};
|
|
438
|
+
const addNature = (nature) => add({ category: AcceptedFileKindCategory.NATURE, nature }, `nature:${nature}`);
|
|
402
439
|
for (const mime of allowedMimeTypes) {
|
|
403
|
-
// Use registry to detect format type
|
|
404
440
|
const formatType = UnifiedFileFormatRegistry.getFormatTypeFromMimeType(mime);
|
|
405
|
-
if (formatType) {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
const natureNames = {
|
|
409
|
-
[FileNature.IMAGE]: 'Images',
|
|
410
|
-
[FileNature.VIDEO]: 'Videos',
|
|
411
|
-
[FileNature.AUDIO]: 'Audio files',
|
|
412
|
-
[FileNature.PDF]: 'PDF',
|
|
413
|
-
[FileNature.OFFICE]: 'Office documents',
|
|
414
|
-
[FileNature.ARCHIVE]: 'Archives',
|
|
415
|
-
};
|
|
416
|
-
const name = natureNames[formatType.nature];
|
|
417
|
-
if (name) {
|
|
418
|
-
types.add(name);
|
|
419
|
-
continue;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
else if (formatType.type === 'agent') {
|
|
423
|
-
// Map agent formats to human-readable names
|
|
424
|
-
const agentNames = {
|
|
425
|
-
'text': 'Text files',
|
|
426
|
-
'markdown': 'Markdown',
|
|
427
|
-
'json': 'JSON',
|
|
428
|
-
'typescript': 'TypeScript',
|
|
429
|
-
'typescript_react': 'TypeScript React',
|
|
430
|
-
'yaml': 'YAML',
|
|
431
|
-
};
|
|
432
|
-
const name = agentNames[formatType.format] || formatType.format.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
433
|
-
types.add(name);
|
|
434
|
-
continue;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
// Fallback: use MIME type patterns
|
|
438
|
-
if (mime === 'application/pdf') {
|
|
439
|
-
types.add('PDF');
|
|
440
|
-
}
|
|
441
|
-
else if (mime.startsWith('image/')) {
|
|
442
|
-
types.add('Images');
|
|
441
|
+
if (formatType?.type === 'nature') {
|
|
442
|
+
addNature(formatType.nature);
|
|
443
|
+
continue;
|
|
443
444
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
types.add('Audio');
|
|
449
|
-
}
|
|
450
|
-
else if (mime.includes('document') || mime.includes('word') || mime.includes('excel') || mime.includes('powerpoint')) {
|
|
451
|
-
types.add('Office documents');
|
|
445
|
+
if (formatType?.type === 'agent' && AGENT_FILE_FORMAT_VALUES.has(formatType.format)) {
|
|
446
|
+
const format = formatType.format;
|
|
447
|
+
add({ category: AcceptedFileKindCategory.AGENT_FORMAT, format }, `agent:${format}`);
|
|
448
|
+
continue;
|
|
452
449
|
}
|
|
450
|
+
if (mime === 'application/pdf')
|
|
451
|
+
addNature(FileNature.PDF);
|
|
452
|
+
else if (mime.startsWith('image/'))
|
|
453
|
+
addNature(FileNature.IMAGE);
|
|
454
|
+
else if (mime.startsWith('video/'))
|
|
455
|
+
addNature(FileNature.VIDEO);
|
|
456
|
+
else if (mime.startsWith('audio/'))
|
|
457
|
+
addNature(FileNature.AUDIO);
|
|
458
|
+
else if (mime.includes('document') || mime.includes('word') || mime.includes('excel') || mime.includes('powerpoint'))
|
|
459
|
+
addNature(FileNature.OFFICE);
|
|
453
460
|
else {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
types.add(ext);
|
|
461
|
+
const subtype = mime.split('/').pop();
|
|
462
|
+
if (subtype)
|
|
463
|
+
add({ category: AcceptedFileKindCategory.MIME_SUBTYPE, subtype }, `subtype:${subtype}`);
|
|
458
464
|
}
|
|
459
465
|
}
|
|
460
|
-
return
|
|
466
|
+
return kinds;
|
|
461
467
|
}
|
|
462
468
|
/**
|
|
463
469
|
* Get file nature from schema metadata.
|
|
@@ -545,6 +551,15 @@ function detectDisplayNatureFromMimeType(mimeType) {
|
|
|
545
551
|
* 2. `mimeType` (from file metadata or browser File object) → detected via MIME prefix matching
|
|
546
552
|
* 3. `FileDisplayNature.GENERIC` (fallback)
|
|
547
553
|
*
|
|
554
|
+
* `FileNature.ALL` is not a nature, it is the ABSENCE of a declaration: a field that accepts anything
|
|
555
|
+
* says nothing about the file in front of it. So it does not decide at step 1 — the file's own MIME
|
|
556
|
+
* type does, exactly as for a field with no declared nature. Until 2026-09-24 it mapped to GENERIC and
|
|
557
|
+
* won, so every file in an open field, a PNG and a PDF included, resolved to GENERIC: no preview, and
|
|
558
|
+
* an authored `OVERLAY` activation always degraded to a download. `resolveFileDisplayPolicy` already
|
|
559
|
+
* describes the intended behaviour ("the file's ACTUAL nature has no displayer — which is only
|
|
560
|
+
* reachable when the schema declared an open nature"); this is what makes that sentence true.
|
|
561
|
+
* `FileNature.ARCHIVE` stays GENERIC at step 1, because that IS a declaration.
|
|
562
|
+
*
|
|
548
563
|
* @param schemaNature - The `FileNature` declared in schema metadata (from `getFileMetadata(schema)?.nature`)
|
|
549
564
|
* @param mimeType - The MIME type of the actual file
|
|
550
565
|
* @returns The `FileDisplayNature` to use for rendering
|
|
@@ -556,8 +571,8 @@ function detectDisplayNatureFromMimeType(mimeType) {
|
|
|
556
571
|
* ```
|
|
557
572
|
*/
|
|
558
573
|
export function resolveFileDisplayNature(schemaNature, mimeType) {
|
|
559
|
-
// Priority 1: Schema-declared nature
|
|
560
|
-
if (schemaNature) {
|
|
574
|
+
// Priority 1: Schema-declared nature — `ALL` declares nothing, so it falls through to the file itself.
|
|
575
|
+
if (schemaNature && schemaNature !== FileNature.ALL) {
|
|
561
576
|
return FILE_NATURE_TO_DISPLAY_NATURE[schemaNature] ?? FileDisplayNature.GENERIC;
|
|
562
577
|
}
|
|
563
578
|
// Priority 2: MIME type detection
|