@stndrds/schema 1.0.0-alpha.293 → 1.0.0-alpha.68

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 (161) hide show
  1. package/dist/chunk-36UBIXJN.js +82 -0
  2. package/dist/chunk-3RG5ZIWI.js +10 -0
  3. package/dist/chunk-IXHWBBIY.mjs +721 -0
  4. package/dist/chunk-KG75T7MA.mjs +18664 -0
  5. package/dist/chunk-NEVERCM3.js +41 -0
  6. package/dist/chunk-V2RPPE2Y.mjs +41 -0
  7. package/dist/chunk-V32FQLWX.js +721 -0
  8. package/dist/chunk-V5QXU2OK.mjs +82 -0
  9. package/dist/chunk-XGFBT4K2.js +18664 -0
  10. package/dist/chunk-Y6FXYEAI.mjs +10 -0
  11. package/dist/default-roles-42X3TJI5.mjs +21 -0
  12. package/dist/default-roles-C3FYDYMN.js +21 -0
  13. package/dist/index.d.mts +3392 -10860
  14. package/dist/index.d.ts +3392 -10860
  15. package/dist/index.js +1705 -10255
  16. package/dist/index.mjs +1735 -9398
  17. package/dist/runtime-B0G6eBXO.d.ts +12810 -0
  18. package/dist/runtime-fj4EKCWH.d.mts +12810 -0
  19. package/dist/runtime.d.mts +6 -0
  20. package/dist/runtime.d.ts +6 -0
  21. package/dist/runtime.js +323 -0
  22. package/dist/runtime.mjs +323 -0
  23. package/dist/utils.d.mts +55 -35
  24. package/dist/utils.d.ts +55 -35
  25. package/dist/utils.js +19 -31
  26. package/dist/utils.mjs +19 -2
  27. package/dist/validation/validators.d.mts +4 -0
  28. package/dist/validation/validators.d.ts +4 -0
  29. package/dist/validation/validators.js +121 -0
  30. package/dist/validation/validators.mjs +121 -0
  31. package/dist/validators-B6L_hVBw.d.ts +1564 -0
  32. package/dist/validators-CgiGGhyH.d.mts +1564 -0
  33. package/package.json +16 -106
  34. package/dist/all-CDJSpI46.d.ts +0 -978
  35. package/dist/all-Cru_CaSY.d.mts +0 -978
  36. package/dist/attributes-CNYwg_Nr.d.ts +0 -584
  37. package/dist/attributes-CWPLbp7c.d.mts +0 -584
  38. package/dist/capabilities.d.mts +0 -146
  39. package/dist/capabilities.d.ts +0 -146
  40. package/dist/capabilities.js +0 -77
  41. package/dist/capabilities.mjs +0 -70
  42. package/dist/chunk-5N7OSHVX.js +0 -657
  43. package/dist/chunk-5WATIVCA.js +0 -10
  44. package/dist/chunk-ACKMC6FL.js +0 -17
  45. package/dist/chunk-APRL56F4.mjs +0 -226
  46. package/dist/chunk-AYVHMVKQ.mjs +0 -15
  47. package/dist/chunk-C32UUQ6D.js +0 -241
  48. package/dist/chunk-E6JUYGJX.js +0 -22
  49. package/dist/chunk-EEH4XQ7W.js +0 -61
  50. package/dist/chunk-EW5XR2X3.js +0 -12
  51. package/dist/chunk-GO6LQADH.mjs +0 -57
  52. package/dist/chunk-GRUSTQK3.mjs +0 -641
  53. package/dist/chunk-HRQEZUAA.mjs +0 -29
  54. package/dist/chunk-HTSTPTNZ.js +0 -10
  55. package/dist/chunk-KNGWHQLR.js +0 -16
  56. package/dist/chunk-LV3FEUKU.mjs +0 -14
  57. package/dist/chunk-NS63SPNN.mjs +0 -8
  58. package/dist/chunk-O73ROMWQ.mjs +0 -85
  59. package/dist/chunk-OASIPLEB.js +0 -1504
  60. package/dist/chunk-OSSGN43B.mjs +0 -8
  61. package/dist/chunk-P4VCAPJT.js +0 -81
  62. package/dist/chunk-Q44QKLN4.mjs +0 -43
  63. package/dist/chunk-Q4SZAMJT.js +0 -72
  64. package/dist/chunk-QVLQPW3O.mjs +0 -10
  65. package/dist/chunk-QWKLQRBX.js +0 -35
  66. package/dist/chunk-R5LAJCBU.mjs +0 -67
  67. package/dist/chunk-SI34M4IC.js +0 -45
  68. package/dist/chunk-UANQJ2GH.mjs +0 -25
  69. package/dist/chunk-ULM2BA5A.mjs +0 -1432
  70. package/dist/chunk-UXAHLSWC.mjs +0 -8
  71. package/dist/chunk-V2UA2D4E.js +0 -10
  72. package/dist/chunk-VGGGLTYJ.mjs +0 -74
  73. package/dist/chunk-Y3UPKP2B.js +0 -605
  74. package/dist/chunk-YIP5FJ5H.js +0 -27
  75. package/dist/chunk-YKWSHBT5.js +0 -32
  76. package/dist/chunk-YUFTHPOE.mjs +0 -20
  77. package/dist/chunk-Z5OPSBMQ.mjs +0 -566
  78. package/dist/chunk-ZDQ5AP26.mjs +0 -31
  79. package/dist/chunk-ZPFOKBIN.js +0 -89
  80. package/dist/exceptions.d.mts +0 -507
  81. package/dist/exceptions.d.ts +0 -507
  82. package/dist/exceptions.js +0 -158
  83. package/dist/exceptions.mjs +0 -1
  84. package/dist/helpers-CXkVwpsl.d.ts +0 -76
  85. package/dist/helpers-Dul_r9rJ.d.mts +0 -76
  86. package/dist/index-BdVnHL3F.d.mts +0 -853
  87. package/dist/index-CFhPHQaI.d.ts +0 -853
  88. package/dist/migrations-DaFneOfx.d.ts +0 -39
  89. package/dist/migrations-fRvadl6i.d.mts +0 -39
  90. package/dist/objects-CDwMSnqv.d.mts +0 -250
  91. package/dist/objects-DJv6WrDE.d.ts +0 -250
  92. package/dist/types-CVYiFc69.d.mts +0 -38
  93. package/dist/types-NGEww_ln.d.ts +0 -38
  94. package/dist/validation/all.d.mts +0 -11
  95. package/dist/validation/all.d.ts +0 -11
  96. package/dist/validation/all.js +0 -131
  97. package/dist/validation/all.mjs +0 -18
  98. package/dist/validation/complex/currency.d.mts +0 -15
  99. package/dist/validation/complex/currency.d.ts +0 -15
  100. package/dist/validation/complex/currency.js +0 -11
  101. package/dist/validation/complex/currency.mjs +0 -2
  102. package/dist/validation/complex/location.d.mts +0 -22
  103. package/dist/validation/complex/location.d.ts +0 -22
  104. package/dist/validation/complex/location.js +0 -11
  105. package/dist/validation/complex/location.mjs +0 -2
  106. package/dist/validation/complex/phone.d.mts +0 -22
  107. package/dist/validation/complex/phone.d.ts +0 -22
  108. package/dist/validation/complex/phone.js +0 -11
  109. package/dist/validation/complex/phone.mjs +0 -2
  110. package/dist/validation/complex/relation.d.mts +0 -25
  111. package/dist/validation/complex/relation.d.ts +0 -25
  112. package/dist/validation/complex/relation.js +0 -19
  113. package/dist/validation/complex/relation.mjs +0 -2
  114. package/dist/validation/complex/richtext.d.mts +0 -13
  115. package/dist/validation/complex/richtext.d.ts +0 -13
  116. package/dist/validation/complex/richtext.js +0 -11
  117. package/dist/validation/complex/richtext.mjs +0 -2
  118. package/dist/validation/complex/select.d.mts +0 -20
  119. package/dist/validation/complex/select.d.ts +0 -20
  120. package/dist/validation/complex/select.js +0 -19
  121. package/dist/validation/complex/select.mjs +0 -2
  122. package/dist/validation/complex/user.d.mts +0 -13
  123. package/dist/validation/complex/user.d.ts +0 -13
  124. package/dist/validation/complex/user.js +0 -11
  125. package/dist/validation/complex/user.mjs +0 -2
  126. package/dist/validation/computed/formula.d.mts +0 -14
  127. package/dist/validation/computed/formula.d.ts +0 -14
  128. package/dist/validation/computed/formula.js +0 -11
  129. package/dist/validation/computed/formula.mjs +0 -2
  130. package/dist/validation/computed/rollup.d.mts +0 -14
  131. package/dist/validation/computed/rollup.d.ts +0 -14
  132. package/dist/validation/computed/rollup.js +0 -11
  133. package/dist/validation/computed/rollup.mjs +0 -2
  134. package/dist/validation/config/index.d.mts +0 -7
  135. package/dist/validation/config/index.d.ts +0 -7
  136. package/dist/validation/config/index.js +0 -52
  137. package/dist/validation/config/index.mjs +0 -7
  138. package/dist/validation/core/index.d.mts +0 -19
  139. package/dist/validation/core/index.d.ts +0 -19
  140. package/dist/validation/core/index.js +0 -14
  141. package/dist/validation/core/index.mjs +0 -1
  142. package/dist/validation/object/index.d.mts +0 -32
  143. package/dist/validation/object/index.d.ts +0 -32
  144. package/dist/validation/object/index.js +0 -69
  145. package/dist/validation/object/index.mjs +0 -16
  146. package/dist/validation/primitives/checkbox.d.mts +0 -12
  147. package/dist/validation/primitives/checkbox.d.ts +0 -12
  148. package/dist/validation/primitives/checkbox.js +0 -11
  149. package/dist/validation/primitives/checkbox.mjs +0 -2
  150. package/dist/validation/primitives/date.d.mts +0 -25
  151. package/dist/validation/primitives/date.d.ts +0 -25
  152. package/dist/validation/primitives/date.js +0 -11
  153. package/dist/validation/primitives/date.mjs +0 -2
  154. package/dist/validation/primitives/number.d.mts +0 -12
  155. package/dist/validation/primitives/number.d.ts +0 -12
  156. package/dist/validation/primitives/number.js +0 -11
  157. package/dist/validation/primitives/number.mjs +0 -2
  158. package/dist/validation/primitives/text.d.mts +0 -12
  159. package/dist/validation/primitives/text.d.ts +0 -12
  160. package/dist/validation/primitives/text.js +0 -11
  161. package/dist/validation/primitives/text.mjs +0 -2
@@ -0,0 +1,721 @@
1
+ // src/validation/validators.ts
2
+ import { isValidIso3 } from "@stndrds/constants";
3
+ import { z } from "zod";
4
+
5
+ // src/phone-utils.ts
6
+ import { getCountryByIso3, stripTrunkPrefix } from "@stndrds/constants";
7
+ import { parsePhoneNumberFromString } from "libphonenumber-js";
8
+ function digitsOnly(input) {
9
+ return input.replace(/\D/g, "");
10
+ }
11
+ function getIso2(iso3) {
12
+ const country = getCountryByIso3(iso3);
13
+ return country?.iso2;
14
+ }
15
+ function normalizePhoneNumber(phoneNumber, countryIso3) {
16
+ if (!phoneNumber) return "";
17
+ const iso2 = getIso2(countryIso3);
18
+ if (!iso2) {
19
+ return digitsOnly(phoneNumber);
20
+ }
21
+ const parsed = parsePhoneNumberFromString(phoneNumber, iso2);
22
+ if (parsed) {
23
+ return parsed.nationalNumber;
24
+ }
25
+ const country = getCountryByIso3(countryIso3);
26
+ const digits = digitsOnly(phoneNumber);
27
+ if (country) {
28
+ const callingCode = country.phoneCode.replace("+", "");
29
+ const withoutCC = digits.startsWith(callingCode) ? digits.slice(callingCode.length) : digits;
30
+ return stripTrunkPrefix(withoutCC, country.phoneTrunkPrefix ?? "");
31
+ }
32
+ return digits;
33
+ }
34
+ function validatePhoneNumber(phoneNumber, countryIso3) {
35
+ if (!phoneNumber) return false;
36
+ const iso2 = getIso2(countryIso3);
37
+ if (!iso2) return false;
38
+ const country = getCountryByIso3(countryIso3);
39
+ if (!country) return false;
40
+ const trunkPrefix = country.phoneTrunkPrefix ?? "";
41
+ const digits = digitsOnly(phoneNumber);
42
+ const withTrunk = trunkPrefix + digits;
43
+ const parsed = parsePhoneNumberFromString(withTrunk, iso2);
44
+ if (parsed?.isValid()) return true;
45
+ const parsedDirect = parsePhoneNumberFromString(phoneNumber, iso2);
46
+ if (parsedDirect?.isValid()) return true;
47
+ const maxDigits = country.phoneMaxDigits ?? 15;
48
+ const expectedWithoutTrunk = maxDigits - trunkPrefix.length;
49
+ return digits.length === expectedWithoutTrunk || digits.length === maxDigits;
50
+ }
51
+ function formatPhoneForDisplay(phone) {
52
+ if (!phone.phoneNumber) return "";
53
+ const iso2 = getIso2(phone.countryCode);
54
+ const country = getCountryByIso3(phone.countryCode);
55
+ const dial = country?.phoneCode ?? "";
56
+ if (!iso2) {
57
+ return `${dial} ${phone.phoneNumber}`.trim();
58
+ }
59
+ const e164 = `${dial}${digitsOnly(phone.phoneNumber)}`;
60
+ const parsed = parsePhoneNumberFromString(e164);
61
+ if (parsed) {
62
+ return parsed.formatInternational();
63
+ }
64
+ return `${dial} ${phone.phoneNumber}`.trim();
65
+ }
66
+ function parseRawPhoneInput(rawInput, countryIso3) {
67
+ if (!rawInput || rawInput.trim() === "") {
68
+ return { success: false, error: "Phone number is empty" };
69
+ }
70
+ const normalized = normalizePhoneNumber(rawInput, countryIso3);
71
+ if (!normalized) {
72
+ return { success: false, error: "Could not extract digits from input" };
73
+ }
74
+ if (!validatePhoneNumber(normalized, countryIso3)) {
75
+ return { success: false, error: "Invalid phone number for country" };
76
+ }
77
+ return {
78
+ success: true,
79
+ phone: { countryCode: countryIso3, phoneNumber: normalized }
80
+ };
81
+ }
82
+
83
+ // src/validation/validators.ts
84
+ var regexPatternCache = /* @__PURE__ */ new Map();
85
+ function getCachedRegex(pattern) {
86
+ let cached = regexPatternCache.get(pattern);
87
+ if (!cached) {
88
+ cached = new RegExp(pattern);
89
+ regexPatternCache.set(pattern, cached);
90
+ }
91
+ return cached;
92
+ }
93
+ function formatZodErrors(error) {
94
+ return error.issues.map((err) => ({
95
+ path: err.path.map(String),
96
+ message: err.message
97
+ }));
98
+ }
99
+ var DEFAULT_VALIDATION_MESSAGES = {
100
+ required: (attr) => `${attr.label} is required`,
101
+ invalidType: (attr, expected) => `${attr.label} must be a ${expected}`,
102
+ minLength: (attr, min) => `${attr.label} must be at least ${min} characters`,
103
+ maxLength: (attr, max) => `${attr.label} must be at most ${max} characters`,
104
+ invalidPattern: (attr) => `${attr.label} format is invalid`,
105
+ minValue: (attr, min) => `${attr.label} must be at least ${min}`,
106
+ maxValue: (attr, max) => `${attr.label} must be at most ${max}`,
107
+ mustBeInteger: (attr) => `${attr.label} must be an integer`,
108
+ invalidDate: (attr) => `${attr.label} must be a valid date`,
109
+ invalidOption: (attr, options) => `${attr.label} must be one of: ${options.join(", ")}`,
110
+ invalidId: (attr) => `${attr.label} must be a valid ID`,
111
+ minItems: (attr, min) => `${attr.label} must have at least ${min} item${min > 1 ? "s" : ""}`,
112
+ maxItems: (attr, max) => `${attr.label} must have at most ${max} item${max > 1 ? "s" : ""}`,
113
+ invalidRichtext: (attr) => `${attr.label} must be valid rich text content`,
114
+ invalidPhone: (attr) => `${attr.label} must be a valid phone number`,
115
+ invalidCurrency: (attr) => `${attr.label} must be a valid currency value`,
116
+ invalidLocation: (attr) => `${attr.label} must be a valid location`
117
+ };
118
+ var baseConfigSchema = z.object({
119
+ disabled: z.boolean().optional(),
120
+ placeholder: z.string().optional(),
121
+ description: z.string().optional(),
122
+ defaultValue: z.unknown().optional(),
123
+ icon: z.string().optional(),
124
+ order: z.number().int().optional(),
125
+ hidden: z.boolean().optional(),
126
+ archived: z.boolean().optional(),
127
+ deprecated: z.boolean().optional(),
128
+ metadata: z.record(z.string(), z.unknown()).optional()
129
+ });
130
+ var optionSchema = z.object({
131
+ id: z.string().min(1),
132
+ label: z.string().min(1),
133
+ value: z.string().min(1),
134
+ color: z.string().optional(),
135
+ icon: z.string().optional(),
136
+ description: z.string().optional(),
137
+ group: z.enum(["idle", "in_progress", "finished"]).optional()
138
+ });
139
+ var optionsArraySchema = z.array(optionSchema).min(1).refine(
140
+ (options) => {
141
+ const values = options.map((o) => o.value);
142
+ return new Set(values).size === values.length;
143
+ },
144
+ { message: "Duplicate option values are not allowed" }
145
+ );
146
+ var relationTargetSchema = z.object({
147
+ object: z.string().min(1),
148
+ displayTemplate: z.string().optional(),
149
+ filter: z.record(z.string(), z.unknown()).optional()
150
+ });
151
+ var textConfigSchema = baseConfigSchema.extend({
152
+ minLength: z.number().int().min(0).optional(),
153
+ maxLength: z.number().int().min(1).optional(),
154
+ pattern: z.string().optional()
155
+ });
156
+ var textareaConfigSchema = baseConfigSchema;
157
+ var richtextConfigSchema = baseConfigSchema.extend({
158
+ features: z.array(
159
+ z.enum(["headings", "bold", "italic", "lists", "links", "images", "codeBlocks", "tables"])
160
+ ).optional()
161
+ });
162
+ var numberConfigSchema = baseConfigSchema.extend({
163
+ min: z.number().optional(),
164
+ max: z.number().optional(),
165
+ unit: z.enum(["integer", "decimal", "percentage"]).optional(),
166
+ decimals: z.number().int().min(0).optional()
167
+ });
168
+ var checkboxConfigSchema = baseConfigSchema;
169
+ var dateConfigSchema = baseConfigSchema.extend({
170
+ dateFormat: z.enum(["short", "long", "full", "relative"]).optional(),
171
+ minDate: z.string().optional(),
172
+ maxDate: z.string().optional()
173
+ });
174
+ var phoneConfigSchema = baseConfigSchema.extend({
175
+ defaultCountryCode: z.string().length(3).optional()
176
+ });
177
+ var currencyConfigSchema = baseConfigSchema.extend({
178
+ defaultCurrency: z.string().length(3).optional(),
179
+ allowedCurrencies: z.array(z.string().length(3)).optional()
180
+ });
181
+ var statusConfigSchema = baseConfigSchema.extend({
182
+ options: optionsArraySchema
183
+ });
184
+ var locationConfigSchema = baseConfigSchema.extend({
185
+ granularity: z.enum(["full", "address", "city", "state", "country", "coordinates"]),
186
+ enableAutocomplete: z.boolean().optional(),
187
+ enableMap: z.boolean().optional(),
188
+ defaultCountry: z.string().length(3).optional(),
189
+ allowedCountries: z.array(z.string().length(3)).optional(),
190
+ displayFormat: z.enum(["single_line", "multi_line", "compact"]).optional()
191
+ });
192
+ var selectConfigSchema = baseConfigSchema.extend({
193
+ options: optionsArraySchema
194
+ });
195
+ var multiselectConfigSchema = baseConfigSchema.extend({
196
+ options: optionsArraySchema
197
+ });
198
+ var fileConfigSchema = baseConfigSchema.extend({
199
+ maxFiles: z.number().int().min(1).optional(),
200
+ maxSize: z.number().int().min(1).optional(),
201
+ allowedTypes: z.array(z.string()).optional(),
202
+ multiple: z.boolean().optional()
203
+ });
204
+ var userConfigSchema = baseConfigSchema.extend({
205
+ allowedRoles: z.array(z.string()).optional(),
206
+ multiple: z.boolean().optional()
207
+ });
208
+ var relationConfigSchema = baseConfigSchema.extend({
209
+ targets: z.array(relationTargetSchema).min(1),
210
+ cardinality: z.enum(["one", "many"]),
211
+ minItems: z.number().int().min(0).optional(),
212
+ maxItems: z.number().int().min(1).optional()
213
+ });
214
+ var ratingConfigSchema = baseConfigSchema.extend({
215
+ max: z.number().int().min(1).optional(),
216
+ iconType: z.enum(["star", "heart", "thumbs", "number"]).optional()
217
+ });
218
+ var formulaConfigSchema = baseConfigSchema.extend({
219
+ expression: z.string().min(1),
220
+ returnType: z.enum(["text", "number", "boolean", "date"]),
221
+ decimals: z.number().int().min(0).max(10).optional(),
222
+ allowRelations: z.boolean().optional()
223
+ });
224
+ var rollupConfigSchema = baseConfigSchema.extend({
225
+ relationAttribute: z.string().min(1).optional(),
226
+ relationPath: z.string().optional(),
227
+ targetAttribute: z.string().min(1),
228
+ function: z.enum([
229
+ // Numeric aggregates
230
+ "sum",
231
+ "avg",
232
+ // Date aggregates
233
+ "earliest",
234
+ "latest",
235
+ // Count (universal)
236
+ "count",
237
+ "countValues",
238
+ "countUniqueValues",
239
+ "countEmpty",
240
+ // Percent (universal)
241
+ "percentEmpty",
242
+ "percentNotEmpty",
243
+ // Lookup (universal)
244
+ "original"
245
+ ]),
246
+ decimals: z.number().int().min(0).max(10).optional(),
247
+ targetAttributeType: z.string().optional(),
248
+ targetAttributeOptions: z.array(
249
+ z.object({
250
+ id: z.string(),
251
+ label: z.string(),
252
+ value: z.string(),
253
+ color: z.string().optional(),
254
+ icon: z.string().optional(),
255
+ description: z.string().optional(),
256
+ group: z.enum(["idle", "in_progress", "finished"]).optional()
257
+ })
258
+ ).optional()
259
+ });
260
+ var documentConfigSchema = baseConfigSchema.extend({
261
+ templateId: z.string().optional(),
262
+ allowedTemplates: z.array(z.string()).optional(),
263
+ multiple: z.boolean().optional(),
264
+ maxDocuments: z.number().int().min(1).optional(),
265
+ autoProcess: z.boolean().optional()
266
+ });
267
+ var attributeConfigSchemas = {
268
+ text: textConfigSchema,
269
+ textarea: textareaConfigSchema,
270
+ richtext: richtextConfigSchema,
271
+ number: numberConfigSchema,
272
+ checkbox: checkboxConfigSchema,
273
+ date: dateConfigSchema,
274
+ phone: phoneConfigSchema,
275
+ currency: currencyConfigSchema,
276
+ status: statusConfigSchema,
277
+ location: locationConfigSchema,
278
+ select: selectConfigSchema,
279
+ multiselect: multiselectConfigSchema,
280
+ file: fileConfigSchema,
281
+ user: userConfigSchema,
282
+ relation: relationConfigSchema,
283
+ rating: ratingConfigSchema,
284
+ formula: formulaConfigSchema,
285
+ rollup: rollupConfigSchema,
286
+ document: documentConfigSchema
287
+ };
288
+ function getAttributeConfigSchema(type) {
289
+ return attributeConfigSchemas[type];
290
+ }
291
+ function validateAttributeConfig(type, config) {
292
+ const schema = getAttributeConfigSchema(type);
293
+ const result = schema.safeParse(config);
294
+ if (result.success) {
295
+ return { success: true, data: result.data };
296
+ }
297
+ return {
298
+ success: false,
299
+ errors: formatZodErrors(result.error).map((err) => `${err.path.join(".")}: ${err.message}`)
300
+ };
301
+ }
302
+ function parseAttributeConfig(type, config) {
303
+ const schema = getAttributeConfigSchema(type);
304
+ return schema.strip().parse(config);
305
+ }
306
+ function safeParseAttributeConfig(type, config) {
307
+ const schema = getAttributeConfigSchema(type);
308
+ const result = schema.strip().safeParse(config);
309
+ return result.success ? result.data : void 0;
310
+ }
311
+ function createTextValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
312
+ let schema = z.string();
313
+ if (attr.minLength !== void 0) {
314
+ schema = schema.min(attr.minLength, messages.minLength(attr, attr.minLength));
315
+ }
316
+ if (attr.maxLength !== void 0) {
317
+ schema = schema.max(attr.maxLength, messages.maxLength(attr, attr.maxLength));
318
+ }
319
+ if (attr.pattern) {
320
+ schema = schema.regex(getCachedRegex(attr.pattern), messages.invalidPattern(attr));
321
+ }
322
+ return schema;
323
+ }
324
+ function createNumberValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
325
+ let schema = z.number();
326
+ if (attr.min !== void 0) {
327
+ schema = schema.min(attr.min, messages.minValue(attr, attr.min));
328
+ }
329
+ if (attr.max !== void 0) {
330
+ schema = schema.max(attr.max, messages.maxValue(attr, attr.max));
331
+ }
332
+ if (attr.unit === "integer") {
333
+ schema = schema.int(messages.mustBeInteger(attr));
334
+ }
335
+ return schema;
336
+ }
337
+ function createCheckboxValidator(_attr, _messages = DEFAULT_VALIDATION_MESSAGES) {
338
+ return z.boolean();
339
+ }
340
+ function createDateValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
341
+ return z.coerce.date({ message: messages.invalidDate(attr) });
342
+ }
343
+ function createPhoneValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
344
+ return z.object(
345
+ {
346
+ countryCode: z.string().length(3),
347
+ phoneNumber: z.string().min(1)
348
+ },
349
+ { message: messages.invalidPhone(attr) }
350
+ ).refine((val) => isValidIso3(val.countryCode), {
351
+ message: "Invalid country code"
352
+ }).transform((val) => ({
353
+ countryCode: val.countryCode,
354
+ phoneNumber: normalizePhoneNumber(val.phoneNumber, val.countryCode)
355
+ })).refine((val) => validatePhoneNumber(val.phoneNumber, val.countryCode), {
356
+ message: messages.invalidPhone(attr)
357
+ });
358
+ }
359
+ function createCurrencyValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
360
+ return z.object(
361
+ {
362
+ code: z.string().length(3),
363
+ value: z.number().min(0)
364
+ },
365
+ { message: messages.invalidCurrency(attr) }
366
+ );
367
+ }
368
+ function createStatusValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
369
+ const validValues = attr.options.map((opt) => opt.value);
370
+ const validLabels = attr.options.map((opt) => opt.label);
371
+ return z.enum(validValues, {
372
+ message: messages.invalidOption(attr, validLabels)
373
+ });
374
+ }
375
+ function createSelectValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
376
+ const validValues = attr.options.map((opt) => opt.value);
377
+ const validLabels = attr.options.map((opt) => opt.label);
378
+ return z.enum(validValues, {
379
+ message: messages.invalidOption(attr, validLabels)
380
+ });
381
+ }
382
+ function createMultiselectValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
383
+ const validValues = attr.options.map((opt) => opt.value);
384
+ const validLabels = attr.options.map((opt) => opt.label);
385
+ return z.array(
386
+ z.enum(validValues, {
387
+ message: messages.invalidOption(attr, validLabels)
388
+ })
389
+ );
390
+ }
391
+ function createLocationValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
392
+ return z.object(
393
+ {
394
+ address: z.string().optional(),
395
+ address2: z.string().optional(),
396
+ city: z.string().optional(),
397
+ state: z.string().optional(),
398
+ postalCode: z.string().optional(),
399
+ country: z.string().length(3).optional(),
400
+ latitude: z.number().optional(),
401
+ longitude: z.number().optional()
402
+ },
403
+ { message: messages.invalidLocation(attr) }
404
+ );
405
+ }
406
+ function createFileValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
407
+ const uuidSchema = z.uuid({
408
+ message: messages.invalidId(attr)
409
+ });
410
+ if (attr.multiple) {
411
+ let arraySchema = z.array(uuidSchema);
412
+ if (attr.maxFiles) {
413
+ arraySchema = arraySchema.max(attr.maxFiles, messages.maxItems(attr, attr.maxFiles));
414
+ }
415
+ return arraySchema;
416
+ }
417
+ return uuidSchema;
418
+ }
419
+ function createUserValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
420
+ const uuidSchema = z.uuid({
421
+ message: messages.invalidId(attr)
422
+ });
423
+ if (attr.multiple) {
424
+ return z.array(uuidSchema);
425
+ }
426
+ return uuidSchema;
427
+ }
428
+ function extractRelationId(item) {
429
+ if (typeof item === "object" && item !== null && "id" in item) {
430
+ return item.id;
431
+ }
432
+ return item;
433
+ }
434
+ function createSingleRelationValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
435
+ const uuidSchema = z.uuid({
436
+ message: messages.invalidId(attr)
437
+ });
438
+ return z.preprocess((val) => extractRelationId(val), z.union([uuidSchema, z.null()]));
439
+ }
440
+ function createMultiRelationValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
441
+ const uuidSchema = z.uuid({
442
+ message: messages.invalidId(attr)
443
+ });
444
+ let arraySchema = z.array(uuidSchema);
445
+ if (attr.minItems !== void 0) {
446
+ arraySchema = arraySchema.min(attr.minItems, messages.minItems(attr, attr.minItems));
447
+ }
448
+ if (attr.maxItems !== void 0) {
449
+ arraySchema = arraySchema.max(attr.maxItems, messages.maxItems(attr, attr.maxItems));
450
+ }
451
+ return z.preprocess(
452
+ (val) => Array.isArray(val) ? val.map(extractRelationId) : val,
453
+ arraySchema
454
+ );
455
+ }
456
+ function createRelationValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
457
+ if (attr.cardinality === "many") {
458
+ return createMultiRelationValidator(attr, messages);
459
+ }
460
+ return createSingleRelationValidator(attr, messages);
461
+ }
462
+ function createRatingValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
463
+ let schema = z.number().min(0);
464
+ if (attr.max !== void 0) {
465
+ schema = schema.max(attr.max, messages.maxValue(attr, attr.max));
466
+ }
467
+ return schema;
468
+ }
469
+ function createFormulaValidator(_attr, _messages = DEFAULT_VALIDATION_MESSAGES) {
470
+ return z.unknown();
471
+ }
472
+ function createRollupValidator(_attr, _messages = DEFAULT_VALIDATION_MESSAGES) {
473
+ return z.unknown();
474
+ }
475
+ function createTextAreaValidator(_attr, _messages = DEFAULT_VALIDATION_MESSAGES) {
476
+ return z.string();
477
+ }
478
+ function createRichtextValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
479
+ return z.string({
480
+ message: messages.invalidRichtext(attr)
481
+ });
482
+ }
483
+ function createAttributeValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
484
+ switch (attr.type) {
485
+ case "text":
486
+ return createTextValidator(attr, messages);
487
+ case "textarea":
488
+ return createTextAreaValidator(attr, messages);
489
+ case "richtext":
490
+ return createRichtextValidator(attr, messages);
491
+ case "number":
492
+ return createNumberValidator(attr, messages);
493
+ case "checkbox":
494
+ return createCheckboxValidator(attr, messages);
495
+ case "date":
496
+ return createDateValidator(attr, messages);
497
+ case "phone":
498
+ return createPhoneValidator(attr, messages);
499
+ case "currency":
500
+ return createCurrencyValidator(attr, messages);
501
+ case "status":
502
+ return createStatusValidator(attr, messages);
503
+ case "location":
504
+ return createLocationValidator(attr, messages);
505
+ case "select":
506
+ return createSelectValidator(attr, messages);
507
+ case "multiselect":
508
+ return createMultiselectValidator(attr, messages);
509
+ case "file":
510
+ return createFileValidator(attr, messages);
511
+ case "user":
512
+ return createUserValidator(attr, messages);
513
+ case "relation":
514
+ return createRelationValidator(attr, messages);
515
+ case "rating":
516
+ return createRatingValidator(attr, messages);
517
+ case "formula":
518
+ return createFormulaValidator(attr, messages);
519
+ case "rollup":
520
+ return createRollupValidator(attr, messages);
521
+ default:
522
+ return z.unknown();
523
+ }
524
+ }
525
+ function isEmptyValue(value) {
526
+ if (value === null || value === void 0) return true;
527
+ if (typeof value === "string" && value.trim() === "") return true;
528
+ if (value instanceof Date) return false;
529
+ if (typeof value === "object" && !Array.isArray(value)) {
530
+ return Object.values(value).every(
531
+ (v) => v === null || v === void 0 || typeof v === "string" && v.trim() === ""
532
+ );
533
+ }
534
+ return false;
535
+ }
536
+ function withEmptyToNull(validator) {
537
+ return z.preprocess((val) => isEmptyValue(val) ? null : val, validator.nullish());
538
+ }
539
+ function createFormAttributeValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
540
+ const validator = createAttributeValidator(attr, messages);
541
+ if (!attr.required) {
542
+ return withEmptyToNull(validator);
543
+ }
544
+ return validator;
545
+ }
546
+ function createObjectValidator(objectDef) {
547
+ const shape = {};
548
+ for (const attr of objectDef.attributes) {
549
+ const validator = createAttributeValidator(attr);
550
+ shape[attr.name] = attr.required ? validator : withEmptyToNull(validator);
551
+ }
552
+ return z.object(shape).passthrough();
553
+ }
554
+ function validateAttribute(attr, value) {
555
+ const validator = createAttributeValidator(attr);
556
+ if (!attr.required && (value === void 0 || value === null)) {
557
+ return { success: true, data: { [attr.name]: value } };
558
+ }
559
+ const result = validator.safeParse(value);
560
+ if (result.success) {
561
+ return {
562
+ success: true,
563
+ data: { [attr.name]: result.data }
564
+ };
565
+ }
566
+ return {
567
+ success: false,
568
+ errors: formatZodErrors(result.error).map((err) => ({
569
+ path: [attr.name, ...err.path],
570
+ message: err.message
571
+ }))
572
+ };
573
+ }
574
+ function validateObject(objectDef, data) {
575
+ const validator = createObjectValidator(objectDef);
576
+ const result = validator.safeParse(data);
577
+ if (result.success) {
578
+ return {
579
+ success: true,
580
+ data: result.data
581
+ };
582
+ }
583
+ return {
584
+ success: false,
585
+ errors: formatZodErrors(result.error)
586
+ };
587
+ }
588
+ function validateObjectOrThrow(objectDef, data) {
589
+ const result = validateObject(objectDef, data);
590
+ if (!result.success) {
591
+ const errorMessages = result.errors?.map((err) => `${err.path.join(".")}: ${err.message}`).join("\n") || "Unknown validation error";
592
+ throw new Error(`Validation failed for ${objectDef.label}:
593
+ ${errorMessages}`);
594
+ }
595
+ return result.data;
596
+ }
597
+ function createDraftValidator(objectDef) {
598
+ const shape = {};
599
+ for (const attr of objectDef.attributes) {
600
+ const validator = createAttributeValidator(attr);
601
+ shape[attr.name] = withEmptyToNull(validator);
602
+ }
603
+ return z.object(shape).passthrough();
604
+ }
605
+ function validateDraft(objectDef, data) {
606
+ const validator = createDraftValidator(objectDef);
607
+ const result = validator.safeParse(data);
608
+ if (result.success) {
609
+ return {
610
+ success: true,
611
+ data: result.data
612
+ };
613
+ }
614
+ return {
615
+ success: false,
616
+ errors: formatZodErrors(result.error)
617
+ };
618
+ }
619
+ function validateDraftOrThrow(objectDef, data) {
620
+ const result = validateDraft(objectDef, data);
621
+ if (!result.success) {
622
+ const errorMessages = result.errors?.map((err) => `${err.path.join(".")}: ${err.message}`).join("\n") || "Unknown validation error";
623
+ throw new Error(`Draft validation failed for ${objectDef.label}:
624
+ ${errorMessages}`);
625
+ }
626
+ return result.data;
627
+ }
628
+ function isValuePresent(value) {
629
+ if (value === void 0 || value === null) {
630
+ return false;
631
+ }
632
+ if (typeof value === "string" && value.trim() === "") {
633
+ return false;
634
+ }
635
+ return true;
636
+ }
637
+ function getMissingRequiredAttributes(objectDef, data) {
638
+ const missing = [];
639
+ for (const attr of objectDef.attributes) {
640
+ if (attr.required && !isValuePresent(data[attr.name])) {
641
+ missing.push(attr);
642
+ }
643
+ }
644
+ return missing;
645
+ }
646
+ function isRecordComplete(objectDef, data) {
647
+ const missing = getMissingRequiredAttributes(objectDef, data);
648
+ if (missing.length > 0) {
649
+ return false;
650
+ }
651
+ const validation = validateObject(objectDef, data);
652
+ return validation.success;
653
+ }
654
+ function computeRecordStatus(objectDef, data) {
655
+ return isRecordComplete(objectDef, data) ? "complete" : "draft";
656
+ }
657
+
658
+ export {
659
+ normalizePhoneNumber,
660
+ validatePhoneNumber,
661
+ formatPhoneForDisplay,
662
+ parseRawPhoneInput,
663
+ formatZodErrors,
664
+ DEFAULT_VALIDATION_MESSAGES,
665
+ textConfigSchema,
666
+ textareaConfigSchema,
667
+ richtextConfigSchema,
668
+ numberConfigSchema,
669
+ checkboxConfigSchema,
670
+ dateConfigSchema,
671
+ phoneConfigSchema,
672
+ currencyConfigSchema,
673
+ statusConfigSchema,
674
+ locationConfigSchema,
675
+ selectConfigSchema,
676
+ multiselectConfigSchema,
677
+ fileConfigSchema,
678
+ userConfigSchema,
679
+ relationConfigSchema,
680
+ ratingConfigSchema,
681
+ formulaConfigSchema,
682
+ rollupConfigSchema,
683
+ documentConfigSchema,
684
+ attributeConfigSchemas,
685
+ getAttributeConfigSchema,
686
+ validateAttributeConfig,
687
+ parseAttributeConfig,
688
+ safeParseAttributeConfig,
689
+ createTextValidator,
690
+ createNumberValidator,
691
+ createCheckboxValidator,
692
+ createDateValidator,
693
+ createPhoneValidator,
694
+ createCurrencyValidator,
695
+ createStatusValidator,
696
+ createSelectValidator,
697
+ createMultiselectValidator,
698
+ createLocationValidator,
699
+ createFileValidator,
700
+ createUserValidator,
701
+ createSingleRelationValidator,
702
+ createMultiRelationValidator,
703
+ createRelationValidator,
704
+ createRatingValidator,
705
+ createFormulaValidator,
706
+ createRollupValidator,
707
+ createTextAreaValidator,
708
+ createRichtextValidator,
709
+ createAttributeValidator,
710
+ createFormAttributeValidator,
711
+ createObjectValidator,
712
+ validateAttribute,
713
+ validateObject,
714
+ validateObjectOrThrow,
715
+ createDraftValidator,
716
+ validateDraft,
717
+ validateDraftOrThrow,
718
+ getMissingRequiredAttributes,
719
+ isRecordComplete,
720
+ computeRecordStatus
721
+ };