@stndrds/schema 0.1.0-alpha.67 → 1.0.0-alpha.100

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 (156) hide show
  1. package/dist/attributes-CH89Z_J-.d.mts +675 -0
  2. package/dist/attributes-dw-jLtYS.d.ts +675 -0
  3. package/dist/chunk-2LUHLHLE.mjs +8 -0
  4. package/dist/chunk-3RFFA4EV.mjs +14 -0
  5. package/dist/chunk-4DMDOSFN.js +10 -0
  6. package/dist/chunk-4IVCBFJA.mjs +12 -0
  7. package/dist/chunk-5CBTJS7J.js +22 -0
  8. package/dist/chunk-5SQEKHPW.js +78 -0
  9. package/dist/chunk-6IFD5732.js +10 -0
  10. package/dist/chunk-6MXQAQBB.mjs +18 -0
  11. package/dist/chunk-7FSIBNRH.mjs +25 -0
  12. package/dist/chunk-ALV6GETG.mjs +10 -0
  13. package/dist/chunk-ANP6HGMJ.js +64 -0
  14. package/dist/chunk-ATA4XHB4.js +20 -0
  15. package/dist/chunk-BEN6TE7Y.js +11 -0
  16. package/dist/chunk-BZTLI773.mjs +8 -0
  17. package/dist/chunk-C7KW4NAD.js +20 -0
  18. package/dist/chunk-CE25ADK5.js +212 -0
  19. package/dist/chunk-E6XO2STS.js +61 -0
  20. package/dist/chunk-EKG35CSO.mjs +1 -0
  21. package/dist/chunk-ERG77ADK.mjs +18 -0
  22. package/dist/chunk-FKETRWAF.js +10 -0
  23. package/dist/chunk-FKPYFM6G.mjs +14 -0
  24. package/dist/chunk-H3VBSMVW.js +105 -0
  25. package/dist/chunk-HJNLL34O.js +12 -0
  26. package/dist/chunk-IMEPIVTR.js +217 -0
  27. package/dist/chunk-JEDANRCG.mjs +74 -0
  28. package/dist/chunk-KC2FFNL4.js +16 -0
  29. package/dist/chunk-OO2LJ6GP.js +32 -0
  30. package/dist/chunk-P4NGPF5L.mjs +99 -0
  31. package/dist/chunk-PGHTIMRD.mjs +199 -0
  32. package/dist/chunk-PZT3CIHD.mjs +192 -0
  33. package/dist/chunk-QPDXDX7A.js +16 -0
  34. package/dist/chunk-R6JFUC32.js +2 -0
  35. package/dist/chunk-RDGBQM3N.mjs +20 -0
  36. package/dist/chunk-RDXQ4CYT.mjs +9 -0
  37. package/dist/chunk-STKN6A5M.js +14 -0
  38. package/dist/chunk-TV4G2KMD.mjs +8 -0
  39. package/dist/chunk-UPEQEX2D.js +10 -0
  40. package/dist/chunk-VC4E3OSZ.mjs +8 -0
  41. package/dist/{chunk-V2RPPE2Y.mjs → chunk-XAORXFAX.mjs} +20 -9
  42. package/dist/chunk-XPFWKISJ.mjs +60 -0
  43. package/dist/chunk-ZJNX6UXB.mjs +28 -0
  44. package/dist/chunk-ZWMMEQI7.js +28 -0
  45. package/dist/index-CftmKoRP.d.mts +2053 -0
  46. package/dist/index-Dh_XiNFt.d.ts +2053 -0
  47. package/dist/index.d.mts +4406 -490
  48. package/dist/index.d.ts +4406 -490
  49. package/dist/index.js +6598 -1729
  50. package/dist/index.mjs +5260 -938
  51. package/dist/types-D-0QbsA9.d.ts +39 -0
  52. package/dist/types-Ms3HtAmo.d.mts +39 -0
  53. package/dist/utils.d.mts +20 -1
  54. package/dist/utils.d.ts +20 -1
  55. package/dist/utils.js +38 -19
  56. package/dist/utils.mjs +1 -19
  57. package/dist/validation/all.d.mts +23 -0
  58. package/dist/validation/all.d.ts +23 -0
  59. package/dist/validation/all.js +265 -0
  60. package/dist/validation/all.mjs +20 -0
  61. package/dist/validation/complex/currency.d.mts +15 -0
  62. package/dist/validation/complex/currency.d.ts +15 -0
  63. package/dist/validation/complex/currency.js +12 -0
  64. package/dist/validation/complex/currency.mjs +3 -0
  65. package/dist/validation/complex/file.d.mts +13 -0
  66. package/dist/validation/complex/file.d.ts +13 -0
  67. package/dist/validation/complex/file.js +12 -0
  68. package/dist/validation/complex/file.mjs +3 -0
  69. package/dist/validation/complex/location.d.mts +22 -0
  70. package/dist/validation/complex/location.d.ts +22 -0
  71. package/dist/validation/complex/location.js +12 -0
  72. package/dist/validation/complex/location.mjs +3 -0
  73. package/dist/validation/complex/phone.d.mts +22 -0
  74. package/dist/validation/complex/phone.d.ts +22 -0
  75. package/dist/validation/complex/phone.js +12 -0
  76. package/dist/validation/complex/phone.mjs +3 -0
  77. package/dist/validation/complex/relation.d.mts +25 -0
  78. package/dist/validation/complex/relation.d.ts +25 -0
  79. package/dist/validation/complex/relation.js +20 -0
  80. package/dist/validation/complex/relation.mjs +3 -0
  81. package/dist/validation/complex/richtext.d.mts +13 -0
  82. package/dist/validation/complex/richtext.d.ts +13 -0
  83. package/dist/validation/complex/richtext.js +12 -0
  84. package/dist/validation/complex/richtext.mjs +3 -0
  85. package/dist/validation/complex/select.d.mts +20 -0
  86. package/dist/validation/complex/select.d.ts +20 -0
  87. package/dist/validation/complex/select.js +20 -0
  88. package/dist/validation/complex/select.mjs +3 -0
  89. package/dist/validation/complex/user.d.mts +13 -0
  90. package/dist/validation/complex/user.d.ts +13 -0
  91. package/dist/validation/complex/user.js +12 -0
  92. package/dist/validation/complex/user.mjs +3 -0
  93. package/dist/validation/computed/formula.d.mts +14 -0
  94. package/dist/validation/computed/formula.d.ts +14 -0
  95. package/dist/validation/computed/formula.js +12 -0
  96. package/dist/validation/computed/formula.mjs +3 -0
  97. package/dist/validation/computed/rollup.d.mts +14 -0
  98. package/dist/validation/computed/rollup.d.ts +14 -0
  99. package/dist/validation/computed/rollup.js +12 -0
  100. package/dist/validation/computed/rollup.mjs +3 -0
  101. package/dist/validation/config/index.d.mts +421 -0
  102. package/dist/validation/config/index.d.ts +421 -0
  103. package/dist/validation/config/index.js +103 -0
  104. package/dist/validation/config/index.mjs +2 -0
  105. package/dist/validation/core/index.d.mts +68 -0
  106. package/dist/validation/core/index.d.ts +68 -0
  107. package/dist/validation/core/index.js +23 -0
  108. package/dist/validation/core/index.mjs +2 -0
  109. package/dist/validation/object/index.d.mts +6 -0
  110. package/dist/validation/object/index.d.ts +6 -0
  111. package/dist/validation/object/index.js +71 -0
  112. package/dist/validation/object/index.mjs +18 -0
  113. package/dist/validation/primitives/checkbox.d.mts +12 -0
  114. package/dist/validation/primitives/checkbox.d.ts +12 -0
  115. package/dist/validation/primitives/checkbox.js +12 -0
  116. package/dist/validation/primitives/checkbox.mjs +3 -0
  117. package/dist/validation/primitives/date.d.mts +12 -0
  118. package/dist/validation/primitives/date.d.ts +12 -0
  119. package/dist/validation/primitives/date.js +12 -0
  120. package/dist/validation/primitives/date.mjs +3 -0
  121. package/dist/validation/primitives/number.d.mts +12 -0
  122. package/dist/validation/primitives/number.d.ts +12 -0
  123. package/dist/validation/primitives/number.js +12 -0
  124. package/dist/validation/primitives/number.mjs +3 -0
  125. package/dist/validation/primitives/rating.d.mts +12 -0
  126. package/dist/validation/primitives/rating.d.ts +12 -0
  127. package/dist/validation/primitives/rating.js +12 -0
  128. package/dist/validation/primitives/rating.mjs +3 -0
  129. package/dist/validation/primitives/text.d.mts +17 -0
  130. package/dist/validation/primitives/text.d.ts +17 -0
  131. package/dist/validation/primitives/text.js +16 -0
  132. package/dist/validation/primitives/text.mjs +3 -0
  133. package/dist/validation/validators.d.mts +21 -2
  134. package/dist/validation/validators.d.ts +21 -2
  135. package/dist/validation/validators.js +265 -121
  136. package/dist/validation/validators.mjs +20 -121
  137. package/package.json +109 -13
  138. package/dist/chunk-36UBIXJN.js +0 -82
  139. package/dist/chunk-3RG5ZIWI.js +0 -10
  140. package/dist/chunk-A6T4UUZ2.mjs +0 -18669
  141. package/dist/chunk-NEVERCM3.js +0 -41
  142. package/dist/chunk-SV4BCGQU.mjs +0 -617
  143. package/dist/chunk-TOTUS3YS.js +0 -18669
  144. package/dist/chunk-U4AB53AM.js +0 -617
  145. package/dist/chunk-V5QXU2OK.mjs +0 -82
  146. package/dist/chunk-Y6FXYEAI.mjs +0 -10
  147. package/dist/default-roles-42X3TJI5.mjs +0 -21
  148. package/dist/default-roles-C3FYDYMN.js +0 -21
  149. package/dist/runtime-BgtwoMx5.d.ts +0 -12759
  150. package/dist/runtime-DQlTgVZJ.d.mts +0 -12759
  151. package/dist/runtime.d.mts +0 -6
  152. package/dist/runtime.d.ts +0 -6
  153. package/dist/runtime.js +0 -323
  154. package/dist/runtime.mjs +0 -323
  155. package/dist/validators-BROsLGn4.d.mts +0 -1556
  156. package/dist/validators-CEzdvxEq.d.ts +0 -1556
@@ -0,0 +1,105 @@
1
+ 'use strict';
2
+
3
+ var chunk5SQEKHPW_js = require('./chunk-5SQEKHPW.js');
4
+ var constants = require('@stndrds/constants');
5
+ var zod = require('zod');
6
+ var libphonenumberJs = require('libphonenumber-js');
7
+
8
+ function digitsOnly(input) {
9
+ return input.replace(/\D/g, "");
10
+ }
11
+ function getIso2(iso3) {
12
+ const country = constants.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 = libphonenumberJs.parsePhoneNumberFromString(phoneNumber, iso2);
22
+ if (parsed) {
23
+ return parsed.nationalNumber;
24
+ }
25
+ const country = constants.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 constants.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 = constants.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 = libphonenumberJs.parsePhoneNumberFromString(withTrunk, iso2);
44
+ if (parsed?.isValid()) return true;
45
+ const parsedDirect = libphonenumberJs.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 = constants.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 = libphonenumberJs.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/complex/phone.ts
84
+ function createPhoneValidator(attr, messages = chunk5SQEKHPW_js.DEFAULT_VALIDATION_MESSAGES) {
85
+ return zod.z.object(
86
+ {
87
+ countryCode: zod.z.string().length(3),
88
+ phoneNumber: zod.z.string().min(1)
89
+ },
90
+ { message: messages.invalidPhone(attr) }
91
+ ).refine((val) => constants.isValidIso3(val.countryCode), {
92
+ message: "Invalid country code"
93
+ }).transform((val) => ({
94
+ countryCode: val.countryCode,
95
+ phoneNumber: normalizePhoneNumber(val.phoneNumber, val.countryCode)
96
+ })).refine((val) => validatePhoneNumber(val.phoneNumber, val.countryCode), {
97
+ message: messages.invalidPhone(attr)
98
+ });
99
+ }
100
+
101
+ exports.createPhoneValidator = createPhoneValidator;
102
+ exports.formatPhoneForDisplay = formatPhoneForDisplay;
103
+ exports.normalizePhoneNumber = normalizePhoneNumber;
104
+ exports.parseRawPhoneInput = parseRawPhoneInput;
105
+ exports.validatePhoneNumber = validatePhoneNumber;
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ var chunk5SQEKHPW_js = require('./chunk-5SQEKHPW.js');
4
+ var zod = require('zod');
5
+
6
+ function createRichtextValidator(attr, messages = chunk5SQEKHPW_js.DEFAULT_VALIDATION_MESSAGES) {
7
+ return zod.z.string({
8
+ message: messages.invalidRichtext(attr)
9
+ });
10
+ }
11
+
12
+ exports.createRichtextValidator = createRichtextValidator;
@@ -0,0 +1,217 @@
1
+ 'use strict';
2
+
3
+ var chunkBEN6TE7Y_js = require('./chunk-BEN6TE7Y.js');
4
+ var zod = require('zod');
5
+
6
+ var baseConfigSchema = zod.z.object({
7
+ disabled: zod.z.boolean().optional(),
8
+ placeholder: zod.z.string().optional(),
9
+ description: zod.z.string().optional(),
10
+ defaultValue: zod.z.unknown().optional(),
11
+ icon: zod.z.string().optional(),
12
+ order: zod.z.number().int().optional(),
13
+ hidden: zod.z.boolean().optional(),
14
+ archived: zod.z.boolean().optional(),
15
+ deprecated: zod.z.boolean().optional(),
16
+ metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
17
+ });
18
+ var optionSchema = zod.z.object({
19
+ id: zod.z.string().min(1),
20
+ label: zod.z.string().min(1),
21
+ value: zod.z.string().min(1),
22
+ color: zod.z.string().optional(),
23
+ icon: zod.z.string().optional(),
24
+ description: zod.z.string().optional(),
25
+ group: zod.z.enum(["idle", "in_progress", "finished"]).optional(),
26
+ inverse: zod.z.string().optional()
27
+ });
28
+ var optionsArraySchema = zod.z.array(optionSchema).min(1).refine(
29
+ (options) => {
30
+ const values = options.map((o) => o.value);
31
+ return new Set(values).size === values.length;
32
+ },
33
+ { message: "Duplicate option values are not allowed" }
34
+ );
35
+ var relationTargetSchema = zod.z.object({
36
+ object: zod.z.string().min(1),
37
+ displayTemplate: zod.z.string().optional(),
38
+ filter: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
39
+ });
40
+ var textConfigSchema = baseConfigSchema.extend({
41
+ minLength: zod.z.number().int().min(0).optional(),
42
+ maxLength: zod.z.number().int().min(1).optional(),
43
+ pattern: zod.z.string().optional()
44
+ });
45
+ var textareaConfigSchema = baseConfigSchema;
46
+ var richtextConfigSchema = baseConfigSchema.extend({
47
+ features: zod.z.array(
48
+ zod.z.enum(["headings", "bold", "italic", "lists", "links", "images", "codeBlocks", "tables"])
49
+ ).optional()
50
+ });
51
+ var numberConfigSchema = baseConfigSchema.extend({
52
+ min: zod.z.number().optional(),
53
+ max: zod.z.number().optional(),
54
+ unit: zod.z.enum(["integer", "decimal", "percentage"]).optional(),
55
+ decimals: zod.z.number().int().min(0).optional()
56
+ });
57
+ var checkboxConfigSchema = baseConfigSchema;
58
+ var dateConfigSchema = baseConfigSchema.extend({
59
+ dateFormat: zod.z.enum(["short", "long", "full", "relative"]).optional(),
60
+ minDate: zod.z.string().optional(),
61
+ maxDate: zod.z.string().optional()
62
+ });
63
+ var phoneConfigSchema = baseConfigSchema.extend({
64
+ defaultCountryCode: zod.z.string().length(3).optional()
65
+ });
66
+ var currencyConfigSchema = baseConfigSchema.extend({
67
+ defaultCurrency: zod.z.string().length(3).optional(),
68
+ allowedCurrencies: zod.z.array(zod.z.string().length(3)).optional()
69
+ });
70
+ var statusConfigSchema = baseConfigSchema.extend({
71
+ options: optionsArraySchema
72
+ });
73
+ var locationConfigSchema = baseConfigSchema.extend({
74
+ granularity: zod.z.enum(["full", "address", "city", "state", "country", "coordinates"]),
75
+ enableAutocomplete: zod.z.boolean().optional(),
76
+ enableMap: zod.z.boolean().optional(),
77
+ defaultCountry: zod.z.string().length(3).optional(),
78
+ allowedCountries: zod.z.array(zod.z.string().length(3)).optional(),
79
+ displayFormat: zod.z.enum(["single_line", "multi_line", "compact"]).optional()
80
+ });
81
+ var selectConfigSchema = baseConfigSchema.extend({
82
+ options: optionsArraySchema
83
+ });
84
+ var multiselectConfigSchema = baseConfigSchema.extend({
85
+ options: optionsArraySchema
86
+ });
87
+ var fileConfigSchema = baseConfigSchema.extend({
88
+ maxFiles: zod.z.number().int().min(1).optional(),
89
+ maxSize: zod.z.number().int().min(1).optional(),
90
+ allowedTypes: zod.z.array(zod.z.string()).optional(),
91
+ multiple: zod.z.boolean().optional()
92
+ });
93
+ var userConfigSchema = baseConfigSchema.extend({
94
+ allowedRoles: zod.z.array(zod.z.string()).optional(),
95
+ multiple: zod.z.boolean().optional()
96
+ });
97
+ var relationConfigSchema = baseConfigSchema.extend({
98
+ targets: zod.z.array(relationTargetSchema).min(1),
99
+ cardinality: zod.z.enum(["one", "many"]),
100
+ minItems: zod.z.number().int().min(0).optional(),
101
+ maxItems: zod.z.number().int().min(1).optional()
102
+ });
103
+ var ratingConfigSchema = baseConfigSchema.extend({
104
+ max: zod.z.number().int().min(1).optional(),
105
+ iconType: zod.z.enum(["star", "heart", "thumbs", "number"]).optional()
106
+ });
107
+ var formulaConfigSchema = baseConfigSchema.extend({
108
+ expression: zod.z.string().min(1),
109
+ returnType: zod.z.enum(["text", "number", "boolean", "date"]),
110
+ decimals: zod.z.number().int().min(0).max(10).optional(),
111
+ allowRelations: zod.z.boolean().optional()
112
+ });
113
+ var rollupConfigSchema = baseConfigSchema.extend({
114
+ relationAttribute: zod.z.string().min(1).optional(),
115
+ relationPath: zod.z.string().optional(),
116
+ targetAttribute: zod.z.string().min(1),
117
+ function: zod.z.enum([
118
+ "sum",
119
+ "avg",
120
+ "earliest",
121
+ "latest",
122
+ "count",
123
+ "countValues",
124
+ "countUniqueValues",
125
+ "countEmpty",
126
+ "percentEmpty",
127
+ "percentNotEmpty",
128
+ "original"
129
+ ]),
130
+ decimals: zod.z.number().int().min(0).max(10).optional(),
131
+ targetAttributeType: zod.z.string().optional(),
132
+ targetAttributeOptions: zod.z.array(
133
+ zod.z.object({
134
+ id: zod.z.string(),
135
+ label: zod.z.string(),
136
+ value: zod.z.string(),
137
+ color: zod.z.string().optional(),
138
+ icon: zod.z.string().optional(),
139
+ description: zod.z.string().optional(),
140
+ group: zod.z.enum(["idle", "in_progress", "finished"]).optional()
141
+ })
142
+ ).optional()
143
+ });
144
+ var documentConfigSchema = baseConfigSchema.extend({
145
+ multiple: zod.z.boolean().optional(),
146
+ maxDocuments: zod.z.number().int().min(1).optional(),
147
+ autoProcess: zod.z.boolean().optional()
148
+ });
149
+ var attributeConfigSchemas = {
150
+ text: textConfigSchema,
151
+ textarea: textareaConfigSchema,
152
+ richtext: richtextConfigSchema,
153
+ number: numberConfigSchema,
154
+ checkbox: checkboxConfigSchema,
155
+ date: dateConfigSchema,
156
+ phone: phoneConfigSchema,
157
+ currency: currencyConfigSchema,
158
+ status: statusConfigSchema,
159
+ location: locationConfigSchema,
160
+ select: selectConfigSchema,
161
+ multiselect: multiselectConfigSchema,
162
+ file: fileConfigSchema,
163
+ user: userConfigSchema,
164
+ relation: relationConfigSchema,
165
+ rating: ratingConfigSchema,
166
+ formula: formulaConfigSchema,
167
+ rollup: rollupConfigSchema,
168
+ document: documentConfigSchema
169
+ };
170
+ function getAttributeConfigSchema(type) {
171
+ return attributeConfigSchemas[type];
172
+ }
173
+ function validateAttributeConfig(type, config) {
174
+ const schema = getAttributeConfigSchema(type);
175
+ const result = schema.safeParse(config);
176
+ if (result.success) {
177
+ return { success: true, data: result.data };
178
+ }
179
+ return {
180
+ success: false,
181
+ errors: chunkBEN6TE7Y_js.formatZodErrors(result.error).map((err) => `${err.path.join(".")}: ${err.message}`)
182
+ };
183
+ }
184
+ function parseAttributeConfig(type, config) {
185
+ const schema = getAttributeConfigSchema(type);
186
+ return schema.strip().parse(config);
187
+ }
188
+ function safeParseAttributeConfig(type, config) {
189
+ const schema = getAttributeConfigSchema(type);
190
+ const result = schema.strip().safeParse(config);
191
+ return result.success ? result.data : void 0;
192
+ }
193
+
194
+ exports.attributeConfigSchemas = attributeConfigSchemas;
195
+ exports.checkboxConfigSchema = checkboxConfigSchema;
196
+ exports.currencyConfigSchema = currencyConfigSchema;
197
+ exports.dateConfigSchema = dateConfigSchema;
198
+ exports.documentConfigSchema = documentConfigSchema;
199
+ exports.fileConfigSchema = fileConfigSchema;
200
+ exports.formulaConfigSchema = formulaConfigSchema;
201
+ exports.getAttributeConfigSchema = getAttributeConfigSchema;
202
+ exports.locationConfigSchema = locationConfigSchema;
203
+ exports.multiselectConfigSchema = multiselectConfigSchema;
204
+ exports.numberConfigSchema = numberConfigSchema;
205
+ exports.parseAttributeConfig = parseAttributeConfig;
206
+ exports.phoneConfigSchema = phoneConfigSchema;
207
+ exports.ratingConfigSchema = ratingConfigSchema;
208
+ exports.relationConfigSchema = relationConfigSchema;
209
+ exports.richtextConfigSchema = richtextConfigSchema;
210
+ exports.rollupConfigSchema = rollupConfigSchema;
211
+ exports.safeParseAttributeConfig = safeParseAttributeConfig;
212
+ exports.selectConfigSchema = selectConfigSchema;
213
+ exports.statusConfigSchema = statusConfigSchema;
214
+ exports.textConfigSchema = textConfigSchema;
215
+ exports.textareaConfigSchema = textareaConfigSchema;
216
+ exports.userConfigSchema = userConfigSchema;
217
+ exports.validateAttributeConfig = validateAttributeConfig;
@@ -0,0 +1,74 @@
1
+ // src/validation/core/messages.ts
2
+ var DEFAULT_VALIDATION_MESSAGES = {
3
+ required: (attr) => `${attr.label} is required`,
4
+ invalidType: (attr, expected) => `${attr.label} must be a ${expected}`,
5
+ minLength: (attr, min) => `${attr.label} must be at least ${min} characters`,
6
+ maxLength: (attr, max) => `${attr.label} must be at most ${max} characters`,
7
+ invalidPattern: (attr) => `${attr.label} format is invalid`,
8
+ minValue: (attr, min) => `${attr.label} must be at least ${min}`,
9
+ maxValue: (attr, max) => `${attr.label} must be at most ${max}`,
10
+ mustBeInteger: (attr) => `${attr.label} must be an integer`,
11
+ invalidDate: (attr) => `${attr.label} must be a valid date`,
12
+ invalidOption: (attr, options) => `${attr.label} must be one of: ${options.join(", ")}`,
13
+ invalidId: (attr) => `${attr.label} must be a valid ID`,
14
+ minItems: (attr, min) => `${attr.label} must have at least ${min} item${min > 1 ? "s" : ""}`,
15
+ maxItems: (attr, max) => `${attr.label} must have at most ${max} item${max > 1 ? "s" : ""}`,
16
+ invalidRichtext: (attr) => `${attr.label} must be valid rich text content`,
17
+ invalidPhone: (attr) => `${attr.label} must be a valid phone number`,
18
+ invalidCurrency: (attr) => `${attr.label} must be a valid currency value`,
19
+ invalidLocation: (attr) => `${attr.label} must be a valid location`
20
+ };
21
+
22
+ // src/lib/lru-cache.ts
23
+ var LRUCache = class {
24
+ constructor(capacity) {
25
+ if (capacity <= 0) {
26
+ throw new Error("LRU cache capacity must be greater than 0");
27
+ }
28
+ this.capacity = capacity;
29
+ this.cache = /* @__PURE__ */ new Map();
30
+ }
31
+ get(key) {
32
+ const value = this.cache.get(key);
33
+ if (value !== void 0) {
34
+ this.cache.delete(key);
35
+ this.cache.set(key, value);
36
+ }
37
+ return value;
38
+ }
39
+ set(key, value) {
40
+ if (this.cache.has(key)) {
41
+ this.cache.delete(key);
42
+ } else if (this.cache.size >= this.capacity) {
43
+ const firstKey = this.cache.keys().next().value;
44
+ if (firstKey !== void 0) {
45
+ this.cache.delete(firstKey);
46
+ }
47
+ }
48
+ this.cache.set(key, value);
49
+ }
50
+ has(key) {
51
+ return this.cache.has(key);
52
+ }
53
+ clear() {
54
+ this.cache.clear();
55
+ }
56
+ get size() {
57
+ return this.cache.size;
58
+ }
59
+ };
60
+
61
+ // src/validation/core/regex-cache.ts
62
+ function createRegexCache(capacity = 100) {
63
+ return new LRUCache(capacity);
64
+ }
65
+ function getCachedRegex(cache, pattern) {
66
+ let cached = cache.get(pattern);
67
+ if (!cached) {
68
+ cached = new RegExp(pattern);
69
+ cache.set(pattern, cached);
70
+ }
71
+ return cached;
72
+ }
73
+
74
+ export { DEFAULT_VALIDATION_MESSAGES, createRegexCache, getCachedRegex };
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ var chunk5SQEKHPW_js = require('./chunk-5SQEKHPW.js');
4
+ var zod = require('zod');
5
+
6
+ function createUserValidator(attr, messages = chunk5SQEKHPW_js.DEFAULT_VALIDATION_MESSAGES) {
7
+ const uuidSchema = zod.z.uuid({
8
+ message: messages.invalidId(attr)
9
+ });
10
+ if (attr.multiple) {
11
+ return zod.z.array(uuidSchema);
12
+ }
13
+ return uuidSchema;
14
+ }
15
+
16
+ exports.createUserValidator = createUserValidator;
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ var chunk5SQEKHPW_js = require('./chunk-5SQEKHPW.js');
4
+ var zod = require('zod');
5
+
6
+ function createSelectValidator(attr, messages = chunk5SQEKHPW_js.DEFAULT_VALIDATION_MESSAGES) {
7
+ const validValues = attr.options.map((opt) => opt.value);
8
+ const validLabels = attr.options.map((opt) => opt.label);
9
+ return zod.z.enum(validValues, {
10
+ message: messages.invalidOption(attr, validLabels)
11
+ });
12
+ }
13
+ function createMultiselectValidator(attr, messages = chunk5SQEKHPW_js.DEFAULT_VALIDATION_MESSAGES) {
14
+ const validValues = attr.options.map((opt) => opt.value);
15
+ const validLabels = attr.options.map((opt) => opt.label);
16
+ return zod.z.array(
17
+ zod.z.enum(validValues, {
18
+ message: messages.invalidOption(attr, validLabels)
19
+ })
20
+ );
21
+ }
22
+ function createStatusValidator(attr, messages = chunk5SQEKHPW_js.DEFAULT_VALIDATION_MESSAGES) {
23
+ const validValues = attr.options.map((opt) => opt.value);
24
+ const validLabels = attr.options.map((opt) => opt.label);
25
+ return zod.z.enum(validValues, {
26
+ message: messages.invalidOption(attr, validLabels)
27
+ });
28
+ }
29
+
30
+ exports.createMultiselectValidator = createMultiselectValidator;
31
+ exports.createSelectValidator = createSelectValidator;
32
+ exports.createStatusValidator = createStatusValidator;
@@ -0,0 +1,99 @@
1
+ import { DEFAULT_VALIDATION_MESSAGES } from './chunk-JEDANRCG.mjs';
2
+ import { getCountryByIso3, stripTrunkPrefix, isValidIso3 } from '@stndrds/constants';
3
+ import { z } from 'zod';
4
+ import { parsePhoneNumberFromString } from 'libphonenumber-js';
5
+
6
+ function digitsOnly(input) {
7
+ return input.replace(/\D/g, "");
8
+ }
9
+ function getIso2(iso3) {
10
+ const country = getCountryByIso3(iso3);
11
+ return country?.iso2;
12
+ }
13
+ function normalizePhoneNumber(phoneNumber, countryIso3) {
14
+ if (!phoneNumber) return "";
15
+ const iso2 = getIso2(countryIso3);
16
+ if (!iso2) {
17
+ return digitsOnly(phoneNumber);
18
+ }
19
+ const parsed = parsePhoneNumberFromString(phoneNumber, iso2);
20
+ if (parsed) {
21
+ return parsed.nationalNumber;
22
+ }
23
+ const country = getCountryByIso3(countryIso3);
24
+ const digits = digitsOnly(phoneNumber);
25
+ if (country) {
26
+ const callingCode = country.phoneCode.replace("+", "");
27
+ const withoutCC = digits.startsWith(callingCode) ? digits.slice(callingCode.length) : digits;
28
+ return stripTrunkPrefix(withoutCC, country.phoneTrunkPrefix ?? "");
29
+ }
30
+ return digits;
31
+ }
32
+ function validatePhoneNumber(phoneNumber, countryIso3) {
33
+ if (!phoneNumber) return false;
34
+ const iso2 = getIso2(countryIso3);
35
+ if (!iso2) return false;
36
+ const country = getCountryByIso3(countryIso3);
37
+ if (!country) return false;
38
+ const trunkPrefix = country.phoneTrunkPrefix ?? "";
39
+ const digits = digitsOnly(phoneNumber);
40
+ const withTrunk = trunkPrefix + digits;
41
+ const parsed = parsePhoneNumberFromString(withTrunk, iso2);
42
+ if (parsed?.isValid()) return true;
43
+ const parsedDirect = parsePhoneNumberFromString(phoneNumber, iso2);
44
+ if (parsedDirect?.isValid()) return true;
45
+ const maxDigits = country.phoneMaxDigits ?? 15;
46
+ const expectedWithoutTrunk = maxDigits - trunkPrefix.length;
47
+ return digits.length === expectedWithoutTrunk || digits.length === maxDigits;
48
+ }
49
+ function formatPhoneForDisplay(phone) {
50
+ if (!phone.phoneNumber) return "";
51
+ const iso2 = getIso2(phone.countryCode);
52
+ const country = getCountryByIso3(phone.countryCode);
53
+ const dial = country?.phoneCode ?? "";
54
+ if (!iso2) {
55
+ return `${dial} ${phone.phoneNumber}`.trim();
56
+ }
57
+ const e164 = `${dial}${digitsOnly(phone.phoneNumber)}`;
58
+ const parsed = parsePhoneNumberFromString(e164);
59
+ if (parsed) {
60
+ return parsed.formatInternational();
61
+ }
62
+ return `${dial} ${phone.phoneNumber}`.trim();
63
+ }
64
+ function parseRawPhoneInput(rawInput, countryIso3) {
65
+ if (!rawInput || rawInput.trim() === "") {
66
+ return { success: false, error: "Phone number is empty" };
67
+ }
68
+ const normalized = normalizePhoneNumber(rawInput, countryIso3);
69
+ if (!normalized) {
70
+ return { success: false, error: "Could not extract digits from input" };
71
+ }
72
+ if (!validatePhoneNumber(normalized, countryIso3)) {
73
+ return { success: false, error: "Invalid phone number for country" };
74
+ }
75
+ return {
76
+ success: true,
77
+ phone: { countryCode: countryIso3, phoneNumber: normalized }
78
+ };
79
+ }
80
+
81
+ // src/validation/complex/phone.ts
82
+ function createPhoneValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
83
+ return z.object(
84
+ {
85
+ countryCode: z.string().length(3),
86
+ phoneNumber: z.string().min(1)
87
+ },
88
+ { message: messages.invalidPhone(attr) }
89
+ ).refine((val) => isValidIso3(val.countryCode), {
90
+ message: "Invalid country code"
91
+ }).transform((val) => ({
92
+ countryCode: val.countryCode,
93
+ phoneNumber: normalizePhoneNumber(val.phoneNumber, val.countryCode)
94
+ })).refine((val) => validatePhoneNumber(val.phoneNumber, val.countryCode), {
95
+ message: messages.invalidPhone(attr)
96
+ });
97
+ }
98
+
99
+ export { createPhoneValidator, formatPhoneForDisplay, normalizePhoneNumber, parseRawPhoneInput, validatePhoneNumber };