@wildo-ai/zod-decorators 1.1.8 → 1.1.10

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.
Files changed (71) hide show
  1. package/dist/esm/commons.d.ts.map +1 -1
  2. package/dist/esm/commons.js.map +1 -1
  3. package/dist/esm/currencies.shared.schemas.d.ts.map +1 -1
  4. package/dist/esm/currencies.shared.schemas.js.map +1 -1
  5. package/dist/esm/files/agent-file-formats.d.ts.map +1 -1
  6. package/dist/esm/files/agent-file-formats.js.map +1 -1
  7. package/dist/esm/files/extension-nature-map.d.ts.map +1 -1
  8. package/dist/esm/files/extension-nature-map.js.map +1 -1
  9. package/dist/esm/files/file-extensions.enum.d.ts.map +1 -1
  10. package/dist/esm/files/file-extensions.enum.js.map +1 -1
  11. package/dist/esm/files/mime-registry.d.ts.map +1 -1
  12. package/dist/esm/files/mime-registry.js.map +1 -1
  13. package/dist/esm/files/unified-registry.d.ts.map +1 -1
  14. package/dist/esm/files/unified-registry.js.map +1 -1
  15. package/dist/esm/index.d.ts +1 -0
  16. package/dist/esm/index.d.ts.map +1 -1
  17. package/dist/esm/index.js +1 -0
  18. package/dist/esm/index.js.map +1 -1
  19. package/dist/esm/install-bigint-json-encoding.d.ts.map +1 -1
  20. package/dist/esm/install-bigint-json-encoding.js.map +1 -1
  21. package/dist/esm/testing/decorated-test-schemas.d.ts.map +1 -1
  22. package/dist/esm/testing/decorated-test-schemas.js.map +1 -1
  23. package/dist/esm/testing.d.ts.map +1 -1
  24. package/dist/esm/testing.js.map +1 -1
  25. package/dist/esm/zod-address.d.ts.map +1 -1
  26. package/dist/esm/zod-address.js.map +1 -1
  27. package/dist/esm/zod-bigdecimal.d.ts +1 -0
  28. package/dist/esm/zod-bigdecimal.d.ts.map +1 -1
  29. package/dist/esm/zod-bigdecimal.js.map +1 -1
  30. package/dist/esm/zod-code.d.ts +1 -0
  31. package/dist/esm/zod-code.d.ts.map +1 -1
  32. package/dist/esm/zod-code.js.map +1 -1
  33. package/dist/esm/zod-color.d.ts.map +1 -1
  34. package/dist/esm/zod-color.js.map +1 -1
  35. package/dist/esm/zod-decorators.types.d.ts +9 -0
  36. package/dist/esm/zod-decorators.types.d.ts.map +1 -1
  37. package/dist/esm/zod-decorators.types.js +5 -0
  38. package/dist/esm/zod-decorators.types.js.map +1 -1
  39. package/dist/esm/zod-document-sequence.d.ts +119 -0
  40. package/dist/esm/zod-document-sequence.d.ts.map +1 -0
  41. package/dist/esm/zod-document-sequence.js +212 -0
  42. package/dist/esm/zod-document-sequence.js.map +1 -0
  43. package/dist/esm/zod-duration.d.ts +1 -0
  44. package/dist/esm/zod-duration.d.ts.map +1 -1
  45. package/dist/esm/zod-duration.js.map +1 -1
  46. package/dist/esm/zod-file.d.ts.map +1 -1
  47. package/dist/esm/zod-file.js.map +1 -1
  48. package/dist/esm/zod-money.d.ts +1 -0
  49. package/dist/esm/zod-money.d.ts.map +1 -1
  50. package/dist/esm/zod-money.js.map +1 -1
  51. package/dist/esm/zod-phone.d.ts.map +1 -1
  52. package/dist/esm/zod-phone.js.map +1 -1
  53. package/dist/esm/zod-range.d.ts.map +1 -1
  54. package/dist/esm/zod-range.js.map +1 -1
  55. package/dist/esm/zod-utils.shared.d.ts +6 -0
  56. package/dist/esm/zod-utils.shared.d.ts.map +1 -1
  57. package/dist/esm/zod-utils.shared.js +8 -0
  58. package/dist/esm/zod-utils.shared.js.map +1 -1
  59. package/dist/esm/zod-versioned.d.ts.map +1 -1
  60. package/dist/esm/zod-versioned.js.map +1 -1
  61. package/dist/esm/zod.module-override.d.ts +5 -0
  62. package/dist/esm/zod.module-override.d.ts.map +1 -1
  63. package/dist/esm/zod.module-override.js +46 -1
  64. package/dist/esm/zod.module-override.js.map +1 -1
  65. package/dist/tsconfig.build.tsbuildinfo +1 -1
  66. package/package.json +1 -1
  67. package/dist/esm/.native.tsbuildinfo +0 -1
  68. package/dist/esm/__mocks__/mime.d.ts +0 -12
  69. package/dist/esm/__mocks__/mime.d.ts.map +0 -1
  70. package/dist/esm/__mocks__/mime.js +0 -75
  71. package/dist/esm/__mocks__/mime.js.map +0 -1
@@ -0,0 +1,119 @@
1
+ /**
2
+ * @wildo_source:part:start zod.decorators.document-sequence facet:layer:shared facet:family:decorator facet:audience:app-developer
3
+ *
4
+ * A DOCUMENT NUMBER the server allocates: an invoice, quote or job number such as `INV-2026-00042`.
5
+ *
6
+ * Declared on a string field with `.documentSequence({ format, scope })`. The server assigns the next number of the
7
+ * field's sequence when the row is created (or, with `allocation: EXPLICIT`, when the application's own operation asks
8
+ * for it, such as an "issue" transition), inside the same transaction as the write. So two documents created at the same
9
+ * instant in one organization get consecutive numbers, and a failed write consumes none: the sequence has no gaps.
10
+ * EU VAT invoicing requires exactly that, a sequential number that identifies each invoice once.
11
+ *
12
+ * The field is never written by a client: the decorator implies `excludeFromCreate`, `excludeFromUpdate`, and a unique
13
+ * index in the sequence's scope.
14
+ *
15
+ * Import from `@wildo-ai/zod-decorators` (the decorator is installed on every string schema).
16
+ *
17
+ * @example
18
+ * invoiceNumber: z.string().documentSequence({ format: 'INV-{YYYY}-{n:5}', scope: DocumentSequenceScope.ORGANIZATION }),
19
+ * // first invoice of 2026 in an organization: INV-2026-00001; the count restarts at 1 in 2027
20
+ */
21
+ export declare enum DocumentSequenceScope {
22
+ /** One sequence per organization: two organizations each have their own INV-2026-00001. */
23
+ ORGANIZATION = "organization",
24
+ /** One sequence across the whole application. */
25
+ APPLICATION = "application"
26
+ }
27
+ /** WHEN the number is allocated. */
28
+ export declare enum DocumentSequenceAllocation {
29
+ /** When the row is created. The default. */
30
+ CREATE = "create",
31
+ /**
32
+ * When the application's own operation allocates it, through the backend's document-sequence allocator: an invoice
33
+ * drafted without a number and numbered when it is issued. The field stays empty until then, so declare it optional.
34
+ */
35
+ EXPLICIT = "explicit"
36
+ }
37
+ /**
38
+ * The parameters of `.documentSequence(...)`.
39
+ *
40
+ * `format` is literal text with these tokens:
41
+ * - `{n}` or `{n:5}`: the sequence number, zero-padded to the width given (exactly one, required);
42
+ * - `{YYYY}` or `{YY}`: the year, which also RESTARTS the count every year;
43
+ * - `{MM}`: the month (with a year token), which restarts the count every month.
44
+ *
45
+ * The year and month are those of the moment the number is allocated, in the organization's timezone for an
46
+ * ORGANIZATION sequence (its profile's `timezone`) and in UTC for an APPLICATION sequence.
47
+ */
48
+ export interface DocumentSequenceParams {
49
+ format: string;
50
+ scope: DocumentSequenceScope;
51
+ /** Defaults to {@link DocumentSequenceAllocation.CREATE}. */
52
+ allocation?: DocumentSequenceAllocation;
53
+ }
54
+ /** @wildo_source:part:end zod.decorators.document-sequence */
55
+ /** How often a sequence's count restarts, derived from its format: the period is never configured separately. */
56
+ export declare enum DocumentSequencePeriod {
57
+ NEVER = "never",
58
+ YEARLY = "yearly",
59
+ MONTHLY = "monthly"
60
+ }
61
+ /** What one part of a parsed format renders. */
62
+ export declare enum DocumentSequenceFormatPartKind {
63
+ /** Text written as it is. */
64
+ LITERAL = "literal",
65
+ /** `{YYYY}` or `{YY}`. */
66
+ YEAR = "year",
67
+ /** `{MM}`. */
68
+ MONTH = "month",
69
+ /** `{n}` / `{n:<width>}`. */
70
+ NUMBER = "number"
71
+ }
72
+ export type DocumentSequenceFormatPart = {
73
+ readonly kind: DocumentSequenceFormatPartKind.LITERAL;
74
+ readonly text: string;
75
+ } | {
76
+ readonly kind: DocumentSequenceFormatPartKind.YEAR;
77
+ readonly fourDigits: boolean;
78
+ } | {
79
+ readonly kind: DocumentSequenceFormatPartKind.MONTH;
80
+ } | {
81
+ readonly kind: DocumentSequenceFormatPartKind.NUMBER;
82
+ readonly width: number;
83
+ };
84
+ /** A format split into its literal text and tokens. */
85
+ export interface ParsedDocumentSequenceFormat {
86
+ readonly parts: readonly DocumentSequenceFormatPart[];
87
+ readonly period: DocumentSequencePeriod;
88
+ }
89
+ /**
90
+ * Parse a format, or throw naming what is wrong. Called when the decorator is applied, so a bad format fails when the
91
+ * schema loads rather than when the first document is created.
92
+ */
93
+ export declare function parseDocumentSequenceFormat(format: string): ParsedDocumentSequenceFormat;
94
+ /**
95
+ * The key of the counting period `at` falls in: `''` for a sequence that never restarts, `'2026'` yearly, `'2026-10'`
96
+ * monthly. Two allocations share a counter exactly when they share this key.
97
+ */
98
+ export declare function documentSequencePeriodKey(parsed: ParsedDocumentSequenceFormat, at: Date, timeZone?: string): string;
99
+ /** The document number for count `value`, allocated at `at`. */
100
+ export declare function formatDocumentSequenceValue(parsed: ParsedDocumentSequenceFormat, value: number, at: Date, timeZone?: string): string;
101
+ /** What a document number says about the count it carries: the count, and the key of the period it was counted in. */
102
+ export interface ReadDocumentSequenceValue {
103
+ readonly value: number;
104
+ /** As {@link documentSequencePeriodKey} would compute it: `''`, `'2026'` or `'2026-10'`. */
105
+ readonly periodKey: string;
106
+ }
107
+ /**
108
+ * Read a document number back: the count it carries and its period, or `undefined` when `text` is not EXACTLY
109
+ * what {@link formatDocumentSequenceValue} renders for some count under this format.
110
+ *
111
+ * Exact on purpose. The question this answers is "could the counter one day hand out this number?", which is what
112
+ * makes an existing value collide with a new one on the unique index. `INV-2026-042` under `INV-{YYYY}-{n:5}` is not a
113
+ * number the counter can produce (it pads to 5), so it can never collide, and it is not read. Nor is free text.
114
+ *
115
+ * A two-digit year (`{YY}`) is read as 20YY: the format keeps no century, and a document numbered by this system was
116
+ * numbered in this century.
117
+ */
118
+ export declare function readDocumentSequenceValue(parsed: ParsedDocumentSequenceFormat, text: string): ReadDocumentSequenceValue | undefined;
119
+ //# sourceMappingURL=zod-document-sequence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-document-sequence.d.ts","sourceRoot":"","sources":["../../src/zod-document-sequence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,oBAAY,qBAAqB;IAC/B,2FAA2F;IAC3F,YAAY,iBAAiB;IAC7B,iDAAiD;IACjD,WAAW,gBAAgB;CAC5B;AAED,oCAAoC;AACpC,oBAAY,0BAA0B;IACpC,4CAA4C;IAC5C,MAAM,WAAW;IACjB;;;OAGG;IACH,QAAQ,aAAa;CACtB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,qBAAqB,CAAC;IAC7B,6DAA6D;IAC7D,UAAU,CAAC,EAAE,0BAA0B,CAAC;CACzC;AACD,8DAA8D;AAE9D,iHAAiH;AACjH,oBAAY,sBAAsB;IAChC,KAAK,UAAU;IACf,MAAM,WAAW;IACjB,OAAO,YAAY;CACpB;AAED,gDAAgD;AAChD,oBAAY,8BAA8B;IACxC,6BAA6B;IAC7B,OAAO,YAAY;IACnB,0BAA0B;IAC1B,IAAI,SAAS;IACb,cAAc;IACd,KAAK,UAAU;IACf,6BAA6B;IAC7B,MAAM,WAAW;CAClB;AAED,MAAM,MAAM,0BAA0B,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,8BAA8B,CAAC,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChF;IAAE,QAAQ,CAAC,IAAI,EAAE,8BAA8B,CAAC,IAAI,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;CAAE,GACpF;IAAE,QAAQ,CAAC,IAAI,EAAE,8BAA8B,CAAC,KAAK,CAAA;CAAE,GACvD;IAAE,QAAQ,CAAC,IAAI,EAAE,8BAA8B,CAAC,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAErF,uDAAuD;AACvD,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,KAAK,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACtD,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;CACzC;AAKD;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,4BAA4B,CAoCxF;AAeD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,4BAA4B,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAInH;AAED,gEAAgE;AAChE,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,4BAA4B,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAUpI;AAED,sHAAsH;AACtH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAOD;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,4BAA4B,EAAE,IAAI,EAAE,MAAM,GAAG,yBAAyB,GAAG,SAAS,CAwCnI"}
@@ -0,0 +1,212 @@
1
+ /**
2
+ * @wildo_source:part:start zod.decorators.document-sequence facet:layer:shared facet:family:decorator facet:audience:app-developer
3
+ *
4
+ * A DOCUMENT NUMBER the server allocates: an invoice, quote or job number such as `INV-2026-00042`.
5
+ *
6
+ * Declared on a string field with `.documentSequence({ format, scope })`. The server assigns the next number of the
7
+ * field's sequence when the row is created (or, with `allocation: EXPLICIT`, when the application's own operation asks
8
+ * for it, such as an "issue" transition), inside the same transaction as the write. So two documents created at the same
9
+ * instant in one organization get consecutive numbers, and a failed write consumes none: the sequence has no gaps.
10
+ * EU VAT invoicing requires exactly that, a sequential number that identifies each invoice once.
11
+ *
12
+ * The field is never written by a client: the decorator implies `excludeFromCreate`, `excludeFromUpdate`, and a unique
13
+ * index in the sequence's scope.
14
+ *
15
+ * Import from `@wildo-ai/zod-decorators` (the decorator is installed on every string schema).
16
+ *
17
+ * @example
18
+ * invoiceNumber: z.string().documentSequence({ format: 'INV-{YYYY}-{n:5}', scope: DocumentSequenceScope.ORGANIZATION }),
19
+ * // first invoice of 2026 in an organization: INV-2026-00001; the count restarts at 1 in 2027
20
+ */
21
+ export var DocumentSequenceScope;
22
+ (function (DocumentSequenceScope) {
23
+ /** One sequence per organization: two organizations each have their own INV-2026-00001. */
24
+ DocumentSequenceScope["ORGANIZATION"] = "organization";
25
+ /** One sequence across the whole application. */
26
+ DocumentSequenceScope["APPLICATION"] = "application";
27
+ })(DocumentSequenceScope || (DocumentSequenceScope = {}));
28
+ /** WHEN the number is allocated. */
29
+ export var DocumentSequenceAllocation;
30
+ (function (DocumentSequenceAllocation) {
31
+ /** When the row is created. The default. */
32
+ DocumentSequenceAllocation["CREATE"] = "create";
33
+ /**
34
+ * When the application's own operation allocates it, through the backend's document-sequence allocator: an invoice
35
+ * drafted without a number and numbered when it is issued. The field stays empty until then, so declare it optional.
36
+ */
37
+ DocumentSequenceAllocation["EXPLICIT"] = "explicit";
38
+ })(DocumentSequenceAllocation || (DocumentSequenceAllocation = {}));
39
+ /** @wildo_source:part:end zod.decorators.document-sequence */
40
+ /** How often a sequence's count restarts, derived from its format: the period is never configured separately. */
41
+ export var DocumentSequencePeriod;
42
+ (function (DocumentSequencePeriod) {
43
+ DocumentSequencePeriod["NEVER"] = "never";
44
+ DocumentSequencePeriod["YEARLY"] = "yearly";
45
+ DocumentSequencePeriod["MONTHLY"] = "monthly";
46
+ })(DocumentSequencePeriod || (DocumentSequencePeriod = {}));
47
+ /** What one part of a parsed format renders. */
48
+ export var DocumentSequenceFormatPartKind;
49
+ (function (DocumentSequenceFormatPartKind) {
50
+ /** Text written as it is. */
51
+ DocumentSequenceFormatPartKind["LITERAL"] = "literal";
52
+ /** `{YYYY}` or `{YY}`. */
53
+ DocumentSequenceFormatPartKind["YEAR"] = "year";
54
+ /** `{MM}`. */
55
+ DocumentSequenceFormatPartKind["MONTH"] = "month";
56
+ /** `{n}` / `{n:<width>}`. */
57
+ DocumentSequenceFormatPartKind["NUMBER"] = "number";
58
+ })(DocumentSequenceFormatPartKind || (DocumentSequenceFormatPartKind = {}));
59
+ /** The widest zero padding a format may ask for: wider is a typo, not a document number. */
60
+ const MAX_NUMBER_WIDTH = 12;
61
+ /**
62
+ * Parse a format, or throw naming what is wrong. Called when the decorator is applied, so a bad format fails when the
63
+ * schema loads rather than when the first document is created.
64
+ */
65
+ export function parseDocumentSequenceFormat(format) {
66
+ if (typeof format !== 'string' || format.length === 0)
67
+ throw new Error('documentSequence: format must be a non-empty string such as "INV-{YYYY}-{n:5}".');
68
+ const parts = [];
69
+ const tokenPattern = /\{([^{}]*)\}/gu;
70
+ let cursor = 0;
71
+ let numbers = 0;
72
+ let year = false;
73
+ let month = false;
74
+ for (const match of format.matchAll(tokenPattern)) {
75
+ const literal = format.slice(cursor, match.index);
76
+ if (/[{}]/u.test(literal))
77
+ throw new Error(`documentSequence: format "${format}" has an unbalanced brace.`);
78
+ if (literal.length > 0)
79
+ parts.push({ kind: DocumentSequenceFormatPartKind.LITERAL, text: literal });
80
+ const token = match[1];
81
+ const numberToken = /^n(?::(\d+))?$/u.exec(token);
82
+ if (numberToken !== null) {
83
+ const width = numberToken[1] === undefined ? 1 : Number(numberToken[1]);
84
+ if (width < 1 || width > MAX_NUMBER_WIDTH)
85
+ throw new Error(`documentSequence: format "${format}" pads the number to ${width}; use 1 to ${MAX_NUMBER_WIDTH}.`);
86
+ parts.push({ kind: DocumentSequenceFormatPartKind.NUMBER, width });
87
+ numbers += 1;
88
+ }
89
+ else if (token === 'YYYY' || token === 'YY') {
90
+ parts.push({ kind: DocumentSequenceFormatPartKind.YEAR, fourDigits: token === 'YYYY' });
91
+ year = true;
92
+ }
93
+ else if (token === 'MM') {
94
+ parts.push({ kind: DocumentSequenceFormatPartKind.MONTH });
95
+ month = true;
96
+ }
97
+ else {
98
+ throw new Error(`documentSequence: format "${format}" has an unknown token "{${token}}"; the tokens are {n}, {n:<width>}, {YYYY}, {YY} and {MM}.`);
99
+ }
100
+ cursor = match.index + match[0].length;
101
+ }
102
+ const tail = format.slice(cursor);
103
+ if (/[{}]/u.test(tail))
104
+ throw new Error(`documentSequence: format "${format}" has an unbalanced brace.`);
105
+ if (tail.length > 0)
106
+ parts.push({ kind: DocumentSequenceFormatPartKind.LITERAL, text: tail });
107
+ if (numbers !== 1)
108
+ throw new Error(`documentSequence: format "${format}" must contain exactly one {n} token; it has ${numbers}.`);
109
+ if (month && !year)
110
+ throw new Error(`documentSequence: format "${format}" has {MM} without a year, so January would repeat every year's numbers.`);
111
+ return { parts, period: month ? DocumentSequencePeriod.MONTHLY : year ? DocumentSequencePeriod.YEARLY : DocumentSequencePeriod.NEVER };
112
+ }
113
+ /** The calendar year and month of `at` in `timeZone` (an IANA zone; UTC when absent or unknown). */
114
+ function calendarOf(at, timeZone) {
115
+ try {
116
+ const parts = new Intl.DateTimeFormat('en-US', { timeZone: timeZone ?? 'UTC', year: 'numeric', month: 'numeric' }).formatToParts(at);
117
+ const year = Number(parts.find((part) => part.type === 'year')?.value);
118
+ const month = Number(parts.find((part) => part.type === 'month')?.value);
119
+ if (Number.isFinite(year) && Number.isFinite(month))
120
+ return { year, month };
121
+ }
122
+ catch {
123
+ // An unknown zone falls back to UTC below: a document number must still be allocated.
124
+ }
125
+ return { year: at.getUTCFullYear(), month: at.getUTCMonth() + 1 };
126
+ }
127
+ /**
128
+ * The key of the counting period `at` falls in: `''` for a sequence that never restarts, `'2026'` yearly, `'2026-10'`
129
+ * monthly. Two allocations share a counter exactly when they share this key.
130
+ */
131
+ export function documentSequencePeriodKey(parsed, at, timeZone) {
132
+ if (parsed.period === DocumentSequencePeriod.NEVER)
133
+ return '';
134
+ const { year, month } = calendarOf(at, timeZone);
135
+ return parsed.period === DocumentSequencePeriod.YEARLY ? String(year) : `${year}-${String(month).padStart(2, '0')}`;
136
+ }
137
+ /** The document number for count `value`, allocated at `at`. */
138
+ export function formatDocumentSequenceValue(parsed, value, at, timeZone) {
139
+ const { year, month } = calendarOf(at, timeZone);
140
+ return parsed.parts.map((part) => {
141
+ switch (part.kind) {
142
+ case DocumentSequenceFormatPartKind.LITERAL: return part.text;
143
+ case DocumentSequenceFormatPartKind.YEAR: return part.fourDigits ? String(year) : String(year % 100).padStart(2, '0');
144
+ case DocumentSequenceFormatPartKind.MONTH: return String(month).padStart(2, '0');
145
+ case DocumentSequenceFormatPartKind.NUMBER: return String(value).padStart(part.width, '0');
146
+ }
147
+ }).join('');
148
+ }
149
+ /** Escape text for use inside a regular expression. */
150
+ function escapeForPattern(text) {
151
+ return text.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
152
+ }
153
+ /**
154
+ * Read a document number back: the count it carries and its period, or `undefined` when `text` is not EXACTLY
155
+ * what {@link formatDocumentSequenceValue} renders for some count under this format.
156
+ *
157
+ * Exact on purpose. The question this answers is "could the counter one day hand out this number?", which is what
158
+ * makes an existing value collide with a new one on the unique index. `INV-2026-042` under `INV-{YYYY}-{n:5}` is not a
159
+ * number the counter can produce (it pads to 5), so it can never collide, and it is not read. Nor is free text.
160
+ *
161
+ * A two-digit year (`{YY}`) is read as 20YY: the format keeps no century, and a document numbered by this system was
162
+ * numbered in this century.
163
+ */
164
+ export function readDocumentSequenceValue(parsed, text) {
165
+ const pattern = parsed.parts.map((part) => {
166
+ switch (part.kind) {
167
+ case DocumentSequenceFormatPartKind.LITERAL: return escapeForPattern(part.text);
168
+ case DocumentSequenceFormatPartKind.YEAR: return part.fourDigits ? '(\\d{4})' : '(\\d{2})';
169
+ case DocumentSequenceFormatPartKind.MONTH: return '(\\d{2})';
170
+ case DocumentSequenceFormatPartKind.NUMBER: return `(\\d{${part.width},})`;
171
+ }
172
+ }).join('');
173
+ const match = new RegExp(`^${pattern}$`, 'u').exec(text);
174
+ if (match === null)
175
+ return undefined;
176
+ let year;
177
+ let month;
178
+ let value;
179
+ let group = 1;
180
+ for (const part of parsed.parts) {
181
+ if (part.kind === DocumentSequenceFormatPartKind.LITERAL)
182
+ continue;
183
+ const captured = match[group];
184
+ group += 1;
185
+ if (part.kind === DocumentSequenceFormatPartKind.YEAR) {
186
+ // A format may repeat a token (`{YYYY}-{YY}`); text whose repeats disagree is text the formatter never renders.
187
+ const read = part.fourDigits ? Number(captured) : 2000 + Number(captured);
188
+ if (year !== undefined && year !== read)
189
+ return undefined;
190
+ year = read;
191
+ }
192
+ else if (part.kind === DocumentSequenceFormatPartKind.MONTH) {
193
+ const read = Number(captured);
194
+ if (month !== undefined && month !== read)
195
+ return undefined;
196
+ month = read;
197
+ }
198
+ else {
199
+ // Only the canonical rendering: no leading zero beyond the padding, and a count the counter can reach.
200
+ value = Number(captured);
201
+ if (!Number.isSafeInteger(value) || value < 1 || String(value).padStart(part.width, '0') !== captured)
202
+ return undefined;
203
+ }
204
+ }
205
+ if (month !== undefined && (month < 1 || month > 12))
206
+ return undefined;
207
+ const periodKey = parsed.period === DocumentSequencePeriod.NEVER
208
+ ? ''
209
+ : parsed.period === DocumentSequencePeriod.YEARLY ? String(year) : `${year}-${String(month).padStart(2, '0')}`;
210
+ return { value: value, periodKey };
211
+ }
212
+ //# sourceMappingURL=zod-document-sequence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-document-sequence.js","sourceRoot":"","sources":["../../src/zod-document-sequence.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @wildo_source:part:start zod.decorators.document-sequence facet:layer:shared facet:family:decorator facet:audience:app-developer\n *\n * A DOCUMENT NUMBER the server allocates: an invoice, quote or job number such as `INV-2026-00042`.\n *\n * Declared on a string field with `.documentSequence({ format, scope })`. The server assigns the next number of the\n * field's sequence when the row is created (or, with `allocation: EXPLICIT`, when the application's own operation asks\n * for it, such as an \"issue\" transition), inside the same transaction as the write. So two documents created at the same\n * instant in one organization get consecutive numbers, and a failed write consumes none: the sequence has no gaps.\n * EU VAT invoicing requires exactly that, a sequential number that identifies each invoice once.\n *\n * The field is never written by a client: the decorator implies `excludeFromCreate`, `excludeFromUpdate`, and a unique\n * index in the sequence's scope.\n *\n * Import from `@wildo-ai/zod-decorators` (the decorator is installed on every string schema).\n *\n * @example\n * invoiceNumber: z.string().documentSequence({ format: 'INV-{YYYY}-{n:5}', scope: DocumentSequenceScope.ORGANIZATION }),\n * // first invoice of 2026 in an organization: INV-2026-00001; the count restarts at 1 in 2027\n */\nexport enum DocumentSequenceScope {\n /** One sequence per organization: two organizations each have their own INV-2026-00001. */\n ORGANIZATION = 'organization',\n /** One sequence across the whole application. */\n APPLICATION = 'application',\n}\n\n/** WHEN the number is allocated. */\nexport enum DocumentSequenceAllocation {\n /** When the row is created. The default. */\n CREATE = 'create',\n /**\n * When the application's own operation allocates it, through the backend's document-sequence allocator: an invoice\n * drafted without a number and numbered when it is issued. The field stays empty until then, so declare it optional.\n */\n EXPLICIT = 'explicit',\n}\n\n/**\n * The parameters of `.documentSequence(...)`.\n *\n * `format` is literal text with these tokens:\n * - `{n}` or `{n:5}`: the sequence number, zero-padded to the width given (exactly one, required);\n * - `{YYYY}` or `{YY}`: the year, which also RESTARTS the count every year;\n * - `{MM}`: the month (with a year token), which restarts the count every month.\n *\n * The year and month are those of the moment the number is allocated, in the organization's timezone for an\n * ORGANIZATION sequence (its profile's `timezone`) and in UTC for an APPLICATION sequence.\n */\nexport interface DocumentSequenceParams {\n format: string;\n scope: DocumentSequenceScope;\n /** Defaults to {@link DocumentSequenceAllocation.CREATE}. */\n allocation?: DocumentSequenceAllocation;\n}\n/** @wildo_source:part:end zod.decorators.document-sequence */\n\n/** How often a sequence's count restarts, derived from its format: the period is never configured separately. */\nexport enum DocumentSequencePeriod {\n NEVER = 'never',\n YEARLY = 'yearly',\n MONTHLY = 'monthly',\n}\n\n/** What one part of a parsed format renders. */\nexport enum DocumentSequenceFormatPartKind {\n /** Text written as it is. */\n LITERAL = 'literal',\n /** `{YYYY}` or `{YY}`. */\n YEAR = 'year',\n /** `{MM}`. */\n MONTH = 'month',\n /** `{n}` / `{n:<width>}`. */\n NUMBER = 'number',\n}\n\nexport type DocumentSequenceFormatPart =\n | { readonly kind: DocumentSequenceFormatPartKind.LITERAL; readonly text: string }\n | { readonly kind: DocumentSequenceFormatPartKind.YEAR; readonly fourDigits: boolean }\n | { readonly kind: DocumentSequenceFormatPartKind.MONTH }\n | { readonly kind: DocumentSequenceFormatPartKind.NUMBER; readonly width: number };\n\n/** A format split into its literal text and tokens. */\nexport interface ParsedDocumentSequenceFormat {\n readonly parts: readonly DocumentSequenceFormatPart[];\n readonly period: DocumentSequencePeriod;\n}\n\n/** The widest zero padding a format may ask for: wider is a typo, not a document number. */\nconst MAX_NUMBER_WIDTH = 12;\n\n/**\n * Parse a format, or throw naming what is wrong. Called when the decorator is applied, so a bad format fails when the\n * schema loads rather than when the first document is created.\n */\nexport function parseDocumentSequenceFormat(format: string): ParsedDocumentSequenceFormat {\n if (typeof format !== 'string' || format.length === 0) throw new Error('documentSequence: format must be a non-empty string such as \"INV-{YYYY}-{n:5}\".');\n const parts: DocumentSequenceFormatPart[] = [];\n const tokenPattern = /\\{([^{}]*)\\}/gu;\n let cursor = 0;\n let numbers = 0;\n let year = false;\n let month = false;\n for (const match of format.matchAll(tokenPattern)) {\n const literal = format.slice(cursor, match.index);\n if (/[{}]/u.test(literal)) throw new Error(`documentSequence: format \"${format}\" has an unbalanced brace.`);\n if (literal.length > 0) parts.push({ kind: DocumentSequenceFormatPartKind.LITERAL, text: literal });\n const token = match[1]!;\n const numberToken = /^n(?::(\\d+))?$/u.exec(token);\n if (numberToken !== null) {\n const width = numberToken[1] === undefined ? 1 : Number(numberToken[1]);\n if (width < 1 || width > MAX_NUMBER_WIDTH) throw new Error(`documentSequence: format \"${format}\" pads the number to ${width}; use 1 to ${MAX_NUMBER_WIDTH}.`);\n parts.push({ kind: DocumentSequenceFormatPartKind.NUMBER, width });\n numbers += 1;\n } else if (token === 'YYYY' || token === 'YY') {\n parts.push({ kind: DocumentSequenceFormatPartKind.YEAR, fourDigits: token === 'YYYY' });\n year = true;\n } else if (token === 'MM') {\n parts.push({ kind: DocumentSequenceFormatPartKind.MONTH });\n month = true;\n } else {\n throw new Error(`documentSequence: format \"${format}\" has an unknown token \"{${token}}\"; the tokens are {n}, {n:<width>}, {YYYY}, {YY} and {MM}.`);\n }\n cursor = match.index + match[0].length;\n }\n const tail = format.slice(cursor);\n if (/[{}]/u.test(tail)) throw new Error(`documentSequence: format \"${format}\" has an unbalanced brace.`);\n if (tail.length > 0) parts.push({ kind: DocumentSequenceFormatPartKind.LITERAL, text: tail });\n if (numbers !== 1) throw new Error(`documentSequence: format \"${format}\" must contain exactly one {n} token; it has ${numbers}.`);\n if (month && !year) throw new Error(`documentSequence: format \"${format}\" has {MM} without a year, so January would repeat every year's numbers.`);\n return { parts, period: month ? DocumentSequencePeriod.MONTHLY : year ? DocumentSequencePeriod.YEARLY : DocumentSequencePeriod.NEVER };\n}\n\n/** The calendar year and month of `at` in `timeZone` (an IANA zone; UTC when absent or unknown). */\nfunction calendarOf(at: Date, timeZone: string | undefined): { year: number; month: number } {\n try {\n const parts = new Intl.DateTimeFormat('en-US', { timeZone: timeZone ?? 'UTC', year: 'numeric', month: 'numeric' }).formatToParts(at);\n const year = Number(parts.find((part) => part.type === 'year')?.value);\n const month = Number(parts.find((part) => part.type === 'month')?.value);\n if (Number.isFinite(year) && Number.isFinite(month)) return { year, month };\n } catch {\n // An unknown zone falls back to UTC below: a document number must still be allocated.\n }\n return { year: at.getUTCFullYear(), month: at.getUTCMonth() + 1 };\n}\n\n/**\n * The key of the counting period `at` falls in: `''` for a sequence that never restarts, `'2026'` yearly, `'2026-10'`\n * monthly. Two allocations share a counter exactly when they share this key.\n */\nexport function documentSequencePeriodKey(parsed: ParsedDocumentSequenceFormat, at: Date, timeZone?: string): string {\n if (parsed.period === DocumentSequencePeriod.NEVER) return '';\n const { year, month } = calendarOf(at, timeZone);\n return parsed.period === DocumentSequencePeriod.YEARLY ? String(year) : `${year}-${String(month).padStart(2, '0')}`;\n}\n\n/** The document number for count `value`, allocated at `at`. */\nexport function formatDocumentSequenceValue(parsed: ParsedDocumentSequenceFormat, value: number, at: Date, timeZone?: string): string {\n const { year, month } = calendarOf(at, timeZone);\n return parsed.parts.map((part) => {\n switch (part.kind) {\n case DocumentSequenceFormatPartKind.LITERAL: return part.text;\n case DocumentSequenceFormatPartKind.YEAR: return part.fourDigits ? String(year) : String(year % 100).padStart(2, '0');\n case DocumentSequenceFormatPartKind.MONTH: return String(month).padStart(2, '0');\n case DocumentSequenceFormatPartKind.NUMBER: return String(value).padStart(part.width, '0');\n }\n }).join('');\n}\n\n/** What a document number says about the count it carries: the count, and the key of the period it was counted in. */\nexport interface ReadDocumentSequenceValue {\n readonly value: number;\n /** As {@link documentSequencePeriodKey} would compute it: `''`, `'2026'` or `'2026-10'`. */\n readonly periodKey: string;\n}\n\n/** Escape text for use inside a regular expression. */\nfunction escapeForPattern(text: string): string {\n return text.replace(/[.*+?^${}()|[\\]\\\\]/gu, '\\\\$&');\n}\n\n/**\n * Read a document number back: the count it carries and its period, or `undefined` when `text` is not EXACTLY\n * what {@link formatDocumentSequenceValue} renders for some count under this format.\n *\n * Exact on purpose. The question this answers is \"could the counter one day hand out this number?\", which is what\n * makes an existing value collide with a new one on the unique index. `INV-2026-042` under `INV-{YYYY}-{n:5}` is not a\n * number the counter can produce (it pads to 5), so it can never collide, and it is not read. Nor is free text.\n *\n * A two-digit year (`{YY}`) is read as 20YY: the format keeps no century, and a document numbered by this system was\n * numbered in this century.\n */\nexport function readDocumentSequenceValue(parsed: ParsedDocumentSequenceFormat, text: string): ReadDocumentSequenceValue | undefined {\n const pattern = parsed.parts.map((part) => {\n switch (part.kind) {\n case DocumentSequenceFormatPartKind.LITERAL: return escapeForPattern(part.text);\n case DocumentSequenceFormatPartKind.YEAR: return part.fourDigits ? '(\\\\d{4})' : '(\\\\d{2})';\n case DocumentSequenceFormatPartKind.MONTH: return '(\\\\d{2})';\n case DocumentSequenceFormatPartKind.NUMBER: return `(\\\\d{${part.width},})`;\n }\n }).join('');\n const match = new RegExp(`^${pattern}$`, 'u').exec(text);\n if (match === null) return undefined;\n let year: number | undefined;\n let month: number | undefined;\n let value: number | undefined;\n let group = 1;\n for (const part of parsed.parts) {\n if (part.kind === DocumentSequenceFormatPartKind.LITERAL) continue;\n const captured = match[group]!;\n group += 1;\n if (part.kind === DocumentSequenceFormatPartKind.YEAR) {\n // A format may repeat a token (`{YYYY}-{YY}`); text whose repeats disagree is text the formatter never renders.\n const read = part.fourDigits ? Number(captured) : 2000 + Number(captured);\n if (year !== undefined && year !== read) return undefined;\n year = read;\n } else if (part.kind === DocumentSequenceFormatPartKind.MONTH) {\n const read = Number(captured);\n if (month !== undefined && month !== read) return undefined;\n month = read;\n }\n else {\n // Only the canonical rendering: no leading zero beyond the padding, and a count the counter can reach.\n value = Number(captured);\n if (!Number.isSafeInteger(value) || value < 1 || String(value).padStart(part.width, '0') !== captured) return undefined;\n }\n }\n if (month !== undefined && (month < 1 || month > 12)) return undefined;\n const periodKey = parsed.period === DocumentSequencePeriod.NEVER\n ? ''\n : parsed.period === DocumentSequencePeriod.YEARLY ? String(year) : `${year}-${String(month).padStart(2, '0')}`;\n return { value: value!, periodKey };\n}\n"]}
@@ -100,6 +100,7 @@ export type DecoratedDurationSchema = z.ZodObject<{
100
100
  [ZodDecorator.IS_DB_INDEXED](): DecoratedDurationSchema;
101
101
  /** Installed at runtime with the other chainable methods; declared here so an authored `.durationUI(…)` typechecks. */
102
102
  [ZodDecorator.DURATION_UI](params?: ZodDecorator_ParamsType[ZodDecorator.DURATION_UI]): DecoratedDurationSchema;
103
+ [ZodDecorator.DURATION_SPEC](params?: ZodDecorator_ParamsType[ZodDecorator.DURATION_SPEC]): DecoratedDurationSchema;
103
104
  [ZodDecorator.IS_HIDDEN](params?: ZodDecorator_ParamsType[ZodDecorator.IS_HIDDEN]): DecoratedDurationSchema;
104
105
  [ZodDecorator.IS_NOT_EDITABLE](params?: ZodDecorator_ParamsType[ZodDecorator.IS_NOT_EDITABLE]): DecoratedDurationSchema;
105
106
  [ZodDecorator.IS_SUMMARY_FIELD](params?: SummaryFieldParams): DecoratedDurationSchema;
@@ -1 +1 @@
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
+ {"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,aAAa,CAAC,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC,YAAY,CAAC,aAAa,CAAC,GAAG,uBAAuB,CAAC;IACpH,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":"AACA,+EAA+E;AAC/E,yBAAyB;AACzB,+EAA+E;AAE/E,OAAO,EAEL,eAAe,EAGf,YAAY,EAEZ,YAAY,GAEb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAkC5D,gDAAgD;AAChD,MAAM,oBAAoB,GAAiC;IACzD,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,KAAK;IAClC,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;IACzB,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,EAAE;IAC1B,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,IAAI;IAC1B,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK;IAC1B,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM;IAC5B,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,KAAK;IACjC,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK;IACpC,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,GAAG,GAAG,MAAM,GAAG,KAAK;CAC/C,CAAC;AAEF,6FAA6F;AAC7F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AAElF;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sCAAsC,CAAC;IAC/E,IAAI,EAAE,kBAAkB,CAAC,QAAQ,CAAC,iCAAiC,CAAC;CACrE,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,CAAgB;IAChD,OAAO,CAAC,CAAC,KAAK,GAAG,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAAoB;IACpD,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC;IAClD,CAAC;IACD,MAAM,KAAK,GAAmB;QAC5B,YAAY,CAAC,SAAS;QACtB,YAAY,CAAC,KAAK;QAClB,YAAY,CAAC,MAAM;QACnB,YAAY,CAAC,KAAK;QAClB,YAAY,CAAC,IAAI;QACjB,YAAY,CAAC,KAAK;QAClB,YAAY,CAAC,OAAO;QACpB,YAAY,CAAC,OAAO;QACpB,YAAY,CAAC,YAAY;KAC1B,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,YAAY,GAAG,CAAC,KAAK,CAAC,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YAChD,OAAO,EAAE,KAAK,EAAE,YAAY,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC;QAC3C,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC;AAC7D,CAAC;AAED,6DAA6D;AAC7D,MAAM,sBAAsB,GAAiC;IAC3D,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,aAAa;IAC1C,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,QAAQ;IAChC,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,QAAQ;IAChC,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM;IAC5B,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK;IAC1B,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM;IAC5B,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO;IAC9B,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM;IAC5B,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,SAAS;CACpC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,CAAgB,EAChB,UAAmC,EAAE;IAErC,MAAM,EAAE,SAAS,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACrC,MAAM,KAAK,GACT,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC;QACxB,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI;QAC1C,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACb,OAAO,GAAG,CAAC,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,UAAiC,EAAE;IAEnC,MAAM,EACJ,YAAY,EACZ,QAAQ,EACR,QAAQ,GACT,GAAG,OAAO,CAAC;IAEZ,IAAI,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IACD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,UAAU,GACd,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC;QACrC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAA0B,CAAC;QAC9E,CAAC,CAAC,kBAAkB,CAAC;IAEzB,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;QAC9B,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,sCAAsC,CAAC;QACnE,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,iCAAiC,CAAC;KAC7D,CAAC,CAAC;IAEH,MAAM,gBAAgB,GAA2B;QAC/C,UAAU,EAAE,IAAI;QAChB,GAAG,CAAC,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;QAChE,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC3C,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,CAAC;KAC5C,CAAC;IAEF,MAAM,gBAAgB,GAAyB,cAAsB,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;IAC5F,cAAsB,CAAC,eAAe,CAAC,GAAG;QACzC,GAAG,gBAAgB;QACnB,cAAc,EAAE,gBAAgB;KACjC,CAAC;IAEF,mBAAmB,CAAC,cAAc,CAAC,CAAC;IAEpC,OAAO,cAAoD,CAAC;AAC9D,CAAC;AAsBD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,UAAU,CAAC,OAA+B;IACxD,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC;AACD,oDAAoD;AAEpD;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAU,CAAC;IAChD,QAAQ,EAAE,CAAC;IACX,YAAY,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC;CAC5E,CAAC,CAAC","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).describe(\"How many `unit`s the duration lasts.\"),\n unit: DurationUnitSchema.describe(\"The unit `value` is counted in.\"),\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.describe(\"How many `unit`s the duration lasts.\"),\n unit: unitSchema.describe(\"The unit `value` is counted in.\"),\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"]}
1
+ {"version":3,"file":"zod-duration.js","sourceRoot":"","sources":["../../src/zod-duration.ts"],"names":[],"mappings":"AACA,+EAA+E;AAC/E,yBAAyB;AACzB,+EAA+E;AAE/E,OAAO,EAEL,eAAe,EAGf,YAAY,EAEZ,YAAY,GAEb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAkC5D,gDAAgD;AAChD,MAAM,oBAAoB,GAAiC;IACzD,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,KAAK;IAClC,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;IACzB,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,EAAE;IAC1B,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,IAAI;IAC1B,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK;IAC1B,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM;IAC5B,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,KAAK;IACjC,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK;IACpC,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,GAAG,GAAG,MAAM,GAAG,KAAK;CAC/C,CAAC;AAEF,6FAA6F;AAC7F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AAElF;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sCAAsC,CAAC;IAC/E,IAAI,EAAE,kBAAkB,CAAC,QAAQ,CAAC,iCAAiC,CAAC;CACrE,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,CAAgB;IAChD,OAAO,CAAC,CAAC,KAAK,GAAG,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAAoB;IACpD,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC;IAClD,CAAC;IACD,MAAM,KAAK,GAAmB;QAC5B,YAAY,CAAC,SAAS;QACtB,YAAY,CAAC,KAAK;QAClB,YAAY,CAAC,MAAM;QACnB,YAAY,CAAC,KAAK;QAClB,YAAY,CAAC,IAAI;QACjB,YAAY,CAAC,KAAK;QAClB,YAAY,CAAC,OAAO;QACpB,YAAY,CAAC,OAAO;QACpB,YAAY,CAAC,YAAY;KAC1B,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,YAAY,GAAG,CAAC,KAAK,CAAC,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YAChD,OAAO,EAAE,KAAK,EAAE,YAAY,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC;QAC3C,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC;AAC7D,CAAC;AAED,6DAA6D;AAC7D,MAAM,sBAAsB,GAAiC;IAC3D,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,aAAa;IAC1C,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,QAAQ;IAChC,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,QAAQ;IAChC,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM;IAC5B,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK;IAC1B,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM;IAC5B,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO;IAC9B,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM;IAC5B,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,SAAS;CACpC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,CAAgB,EAChB,UAAmC,EAAE;IAErC,MAAM,EAAE,SAAS,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACrC,MAAM,KAAK,GACT,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC;QACxB,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI;QAC1C,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACb,OAAO,GAAG,CAAC,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,UAAiC,EAAE;IAEnC,MAAM,EACJ,YAAY,EACZ,QAAQ,EACR,QAAQ,GACT,GAAG,OAAO,CAAC;IAEZ,IAAI,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC1C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IACD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,UAAU,GACd,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC;QACrC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAA0B,CAAC;QAC9E,CAAC,CAAC,kBAAkB,CAAC;IAEzB,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;QAC9B,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,sCAAsC,CAAC;QACnE,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,iCAAiC,CAAC;KAC7D,CAAC,CAAC;IAEH,MAAM,gBAAgB,GAA2B;QAC/C,UAAU,EAAE,IAAI;QAChB,GAAG,CAAC,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC;QAChE,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,CAAC;QAC3C,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,CAAC;KAC5C,CAAC;IAEF,MAAM,gBAAgB,GAAyB,cAAsB,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;IAC5F,cAAsB,CAAC,eAAe,CAAC,GAAG;QACzC,GAAG,gBAAgB;QACnB,cAAc,EAAE,gBAAgB;KACjC,CAAC;IAEF,mBAAmB,CAAC,cAAc,CAAC,CAAC;IAEpC,OAAO,cAAoD,CAAC;AAC9D,CAAC;AAuBD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,UAAU,CAAC,OAA+B;IACxD,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC;AACD,oDAAoD;AAEpD;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAU,CAAC;IAChD,QAAQ,EAAE,CAAC;IACX,YAAY,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC;CAC5E,CAAC,CAAC","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).describe(\"How many `unit`s the duration lasts.\"),\n unit: DurationUnitSchema.describe(\"The unit `value` is counted in.\"),\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.describe(\"How many `unit`s the duration lasts.\"),\n unit: unitSchema.describe(\"The unit `value` is counted in.\"),\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.DURATION_SPEC](params?: ZodDecorator_ParamsType[ZodDecorator.DURATION_SPEC]): 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 +1 @@
1
- {"version":3,"file":"zod-file.d.ts","sourceRoot":"","sources":["../../../src/zod-file.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"zod-file.d.ts","sourceRoot":"","sources":["../../src/zod-file.ts"],"names":[],"mappings":"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"}