@stndrds/schema 1.0.0-alpha.95 → 1.0.0-alpha.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attributes-C-bhC0k5.d.ts +673 -0
- package/dist/attributes-DB76JqXm.d.mts +673 -0
- package/dist/chunk-2TEWGEUI.js +212 -0
- package/dist/chunk-4RGFTMQR.mjs +8 -0
- package/dist/chunk-5TLM4QXO.mjs +8 -0
- package/dist/chunk-67PQMHQA.mjs +199 -0
- package/dist/chunk-6HHSX6LP.js +64 -0
- package/dist/chunk-AHPXNPJC.js +105 -0
- package/dist/chunk-BEN6TE7Y.js +11 -0
- package/dist/chunk-BH3RPSC5.js +22 -0
- package/dist/chunk-BIQ35DLC.mjs +78 -0
- package/dist/chunk-CKZHFJQT.js +16 -0
- package/dist/chunk-E6XO2STS.js +11 -11
- package/dist/chunk-EIWGW2ML.mjs +99 -0
- package/dist/chunk-EKG35CSO.mjs +1 -0
- package/dist/chunk-IMEPIVTR.js +217 -0
- package/dist/chunk-J4ORNCAH.js +10 -0
- package/dist/chunk-KC4F3HB7.js +32 -0
- package/dist/chunk-LHXE7LLD.js +28 -0
- package/dist/chunk-MD6XGXTU.mjs +18 -0
- package/dist/chunk-N47XKY4R.js +14 -0
- package/dist/chunk-NXXSNUDI.mjs +8 -0
- package/dist/chunk-PKG3E5MW.mjs +18 -0
- package/dist/chunk-PZT3CIHD.mjs +192 -0
- package/dist/chunk-QL3UGPUG.mjs +60 -0
- package/dist/chunk-QY65ZSBL.js +16 -0
- package/dist/chunk-R6JFUC32.js +2 -0
- package/dist/chunk-RDXQ4CYT.mjs +9 -0
- package/dist/chunk-S5VJ2FZE.js +12 -0
- package/dist/chunk-SVII65W7.mjs +14 -0
- package/dist/chunk-U7VN3RUE.mjs +25 -0
- package/dist/chunk-VCPYYLCS.js +83 -0
- package/dist/chunk-VD3P2A6Q.js +10 -0
- package/dist/chunk-VPEV3W34.mjs +10 -0
- package/dist/chunk-WGFQMQMV.mjs +14 -0
- package/dist/chunk-X6VDDXG7.mjs +12 -0
- package/dist/chunk-XAORXFAX.mjs +1 -10
- package/dist/chunk-XEOG24K6.mjs +8 -0
- package/dist/chunk-XK6XC3V4.js +10 -0
- package/dist/chunk-XZ5B5MTG.js +20 -0
- package/dist/chunk-YKHC2AW6.js +10 -0
- package/dist/chunk-Z2T7ONKU.js +20 -0
- package/dist/chunk-ZFL7DXAE.mjs +28 -0
- package/dist/chunk-ZM7W2ZCF.mjs +20 -0
- package/dist/{validators-5XMwJOlV.d.ts → index-Bt-0XNSh.d.ts} +14 -1499
- package/dist/{validators-BCw4Sn01.d.mts → index-C9tOwUbK.d.mts} +14 -1499
- package/dist/index.d.mts +1267 -976
- package/dist/index.d.ts +1267 -976
- package/dist/index.js +1293 -1001
- package/dist/index.mjs +529 -785
- package/dist/types-B7nS2D1A.d.ts +39 -0
- package/dist/types-CjXbGsy8.d.mts +39 -0
- package/dist/utils.js +38 -20
- package/dist/utils.mjs +1 -20
- package/dist/validation/all.d.mts +23 -0
- package/dist/validation/all.d.ts +23 -0
- package/dist/validation/all.js +265 -0
- package/dist/validation/all.mjs +20 -0
- package/dist/validation/complex/currency.d.mts +15 -0
- package/dist/validation/complex/currency.d.ts +15 -0
- package/dist/validation/complex/currency.js +12 -0
- package/dist/validation/complex/currency.mjs +3 -0
- package/dist/validation/complex/file.d.mts +13 -0
- package/dist/validation/complex/file.d.ts +13 -0
- package/dist/validation/complex/file.js +12 -0
- package/dist/validation/complex/file.mjs +3 -0
- package/dist/validation/complex/location.d.mts +22 -0
- package/dist/validation/complex/location.d.ts +22 -0
- package/dist/validation/complex/location.js +12 -0
- package/dist/validation/complex/location.mjs +3 -0
- package/dist/validation/complex/phone.d.mts +22 -0
- package/dist/validation/complex/phone.d.ts +22 -0
- package/dist/validation/complex/phone.js +12 -0
- package/dist/validation/complex/phone.mjs +3 -0
- package/dist/validation/complex/relation.d.mts +25 -0
- package/dist/validation/complex/relation.d.ts +25 -0
- package/dist/validation/complex/relation.js +20 -0
- package/dist/validation/complex/relation.mjs +3 -0
- package/dist/validation/complex/richtext.d.mts +13 -0
- package/dist/validation/complex/richtext.d.ts +13 -0
- package/dist/validation/complex/richtext.js +12 -0
- package/dist/validation/complex/richtext.mjs +3 -0
- package/dist/validation/complex/select.d.mts +20 -0
- package/dist/validation/complex/select.d.ts +20 -0
- package/dist/validation/complex/select.js +20 -0
- package/dist/validation/complex/select.mjs +3 -0
- package/dist/validation/complex/user.d.mts +13 -0
- package/dist/validation/complex/user.d.ts +13 -0
- package/dist/validation/complex/user.js +12 -0
- package/dist/validation/complex/user.mjs +3 -0
- package/dist/validation/computed/formula.d.mts +14 -0
- package/dist/validation/computed/formula.d.ts +14 -0
- package/dist/validation/computed/formula.js +12 -0
- package/dist/validation/computed/formula.mjs +3 -0
- package/dist/validation/computed/rollup.d.mts +14 -0
- package/dist/validation/computed/rollup.d.ts +14 -0
- package/dist/validation/computed/rollup.js +12 -0
- package/dist/validation/computed/rollup.mjs +3 -0
- package/dist/validation/config/index.d.mts +421 -0
- package/dist/validation/config/index.d.ts +421 -0
- package/dist/validation/config/index.js +103 -0
- package/dist/validation/config/index.mjs +2 -0
- package/dist/validation/core/index.d.mts +85 -0
- package/dist/validation/core/index.d.ts +85 -0
- package/dist/validation/core/index.js +27 -0
- package/dist/validation/core/index.mjs +2 -0
- package/dist/validation/object/index.d.mts +6 -0
- package/dist/validation/object/index.d.ts +6 -0
- package/dist/validation/object/index.js +71 -0
- package/dist/validation/object/index.mjs +18 -0
- package/dist/validation/primitives/checkbox.d.mts +12 -0
- package/dist/validation/primitives/checkbox.d.ts +12 -0
- package/dist/validation/primitives/checkbox.js +12 -0
- package/dist/validation/primitives/checkbox.mjs +3 -0
- package/dist/validation/primitives/date.d.mts +12 -0
- package/dist/validation/primitives/date.d.ts +12 -0
- package/dist/validation/primitives/date.js +12 -0
- package/dist/validation/primitives/date.mjs +3 -0
- package/dist/validation/primitives/number.d.mts +12 -0
- package/dist/validation/primitives/number.d.ts +12 -0
- package/dist/validation/primitives/number.js +12 -0
- package/dist/validation/primitives/number.mjs +3 -0
- package/dist/validation/primitives/rating.d.mts +12 -0
- package/dist/validation/primitives/rating.d.ts +12 -0
- package/dist/validation/primitives/rating.js +12 -0
- package/dist/validation/primitives/rating.mjs +3 -0
- package/dist/validation/primitives/text.d.mts +17 -0
- package/dist/validation/primitives/text.d.ts +17 -0
- package/dist/validation/primitives/text.js +16 -0
- package/dist/validation/primitives/text.mjs +3 -0
- package/dist/validation/validators.d.mts +21 -2
- package/dist/validation/validators.d.ts +21 -2
- package/dist/validation/validators.js +265 -120
- package/dist/validation/validators.mjs +20 -120
- package/package.json +108 -5
- package/dist/chunk-4362R5F2.mjs +0 -780
- package/dist/chunk-7QUI6TSO.js +0 -780
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkXK6XC3V4_js = require('./chunk-XK6XC3V4.js');
|
|
4
|
+
var chunkVD3P2A6Q_js = require('./chunk-VD3P2A6Q.js');
|
|
5
|
+
var chunkXZ5B5MTG_js = require('./chunk-XZ5B5MTG.js');
|
|
6
|
+
var chunkN47XKY4R_js = require('./chunk-N47XKY4R.js');
|
|
7
|
+
var chunkLHXE7LLD_js = require('./chunk-LHXE7LLD.js');
|
|
8
|
+
var chunk6HHSX6LP_js = require('./chunk-6HHSX6LP.js');
|
|
9
|
+
var chunkS5VJ2FZE_js = require('./chunk-S5VJ2FZE.js');
|
|
10
|
+
var chunkKC4F3HB7_js = require('./chunk-KC4F3HB7.js');
|
|
11
|
+
var chunkCKZHFJQT_js = require('./chunk-CKZHFJQT.js');
|
|
12
|
+
var chunkJ4ORNCAH_js = require('./chunk-J4ORNCAH.js');
|
|
13
|
+
var chunkYKHC2AW6_js = require('./chunk-YKHC2AW6.js');
|
|
14
|
+
var chunkQY65ZSBL_js = require('./chunk-QY65ZSBL.js');
|
|
15
|
+
var chunkZ2T7ONKU_js = require('./chunk-Z2T7ONKU.js');
|
|
16
|
+
var chunkBH3RPSC5_js = require('./chunk-BH3RPSC5.js');
|
|
17
|
+
var chunkAHPXNPJC_js = require('./chunk-AHPXNPJC.js');
|
|
18
|
+
var chunkVCPYYLCS_js = require('./chunk-VCPYYLCS.js');
|
|
19
|
+
var chunkBEN6TE7Y_js = require('./chunk-BEN6TE7Y.js');
|
|
20
|
+
var zod = require('zod');
|
|
21
|
+
|
|
22
|
+
function isEmptyValue(value) {
|
|
23
|
+
if (value === null || value === void 0) return true;
|
|
24
|
+
if (typeof value === "string" && value.trim() === "") return true;
|
|
25
|
+
if (value instanceof Date) return false;
|
|
26
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
27
|
+
return Object.values(value).every(
|
|
28
|
+
(v) => v === null || v === void 0 || typeof v === "string" && v.trim() === ""
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
function withEmptyToNull(validator) {
|
|
34
|
+
return zod.z.preprocess((val) => isEmptyValue(val) ? null : val, validator.nullish());
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/validation/object/attribute-factory.ts
|
|
38
|
+
function createAttributeValidator(attr, messages = chunkVCPYYLCS_js.DEFAULT_VALIDATION_MESSAGES) {
|
|
39
|
+
switch (attr.type) {
|
|
40
|
+
case "text":
|
|
41
|
+
return chunkLHXE7LLD_js.createTextValidator(attr, messages);
|
|
42
|
+
case "textarea":
|
|
43
|
+
return chunkLHXE7LLD_js.createTextAreaValidator(attr, messages);
|
|
44
|
+
case "richtext":
|
|
45
|
+
return chunkS5VJ2FZE_js.createRichtextValidator(attr, messages);
|
|
46
|
+
case "number":
|
|
47
|
+
return chunkXZ5B5MTG_js.createNumberValidator(attr, messages);
|
|
48
|
+
case "checkbox":
|
|
49
|
+
return chunkXK6XC3V4_js.createCheckboxValidator(attr, messages);
|
|
50
|
+
case "date":
|
|
51
|
+
return chunkVD3P2A6Q_js.createDateValidator(attr, messages);
|
|
52
|
+
case "phone":
|
|
53
|
+
return chunkAHPXNPJC_js.createPhoneValidator(attr, messages);
|
|
54
|
+
case "currency":
|
|
55
|
+
return chunkQY65ZSBL_js.createCurrencyValidator(attr, messages);
|
|
56
|
+
case "status":
|
|
57
|
+
return chunkKC4F3HB7_js.createStatusValidator(attr, messages);
|
|
58
|
+
case "location":
|
|
59
|
+
return chunkBH3RPSC5_js.createLocationValidator(attr, messages);
|
|
60
|
+
case "select":
|
|
61
|
+
return chunkKC4F3HB7_js.createSelectValidator(attr, messages);
|
|
62
|
+
case "multiselect":
|
|
63
|
+
return chunkKC4F3HB7_js.createMultiselectValidator(attr, messages);
|
|
64
|
+
case "file":
|
|
65
|
+
return chunkZ2T7ONKU_js.createFileValidator(attr, messages);
|
|
66
|
+
case "user":
|
|
67
|
+
return chunkCKZHFJQT_js.createUserValidator(attr, messages);
|
|
68
|
+
case "relation":
|
|
69
|
+
return chunk6HHSX6LP_js.createRelationValidator(attr, messages);
|
|
70
|
+
case "rating":
|
|
71
|
+
return chunkN47XKY4R_js.createRatingValidator(attr, messages);
|
|
72
|
+
case "formula":
|
|
73
|
+
return chunkJ4ORNCAH_js.createFormulaValidator(attr, messages);
|
|
74
|
+
case "rollup":
|
|
75
|
+
return chunkYKHC2AW6_js.createRollupValidator(attr, messages);
|
|
76
|
+
default:
|
|
77
|
+
return zod.z.unknown();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function createFormAttributeValidator(attr, messages = chunkVCPYYLCS_js.DEFAULT_VALIDATION_MESSAGES) {
|
|
81
|
+
const validator = createAttributeValidator(attr, messages);
|
|
82
|
+
if (!attr.required) {
|
|
83
|
+
return withEmptyToNull(validator);
|
|
84
|
+
}
|
|
85
|
+
return validator;
|
|
86
|
+
}
|
|
87
|
+
function createObjectValidator(objectDef) {
|
|
88
|
+
const shape = {};
|
|
89
|
+
for (const attr of objectDef.attributes) {
|
|
90
|
+
const validator = createAttributeValidator(attr);
|
|
91
|
+
shape[attr.name] = attr.required ? validator : withEmptyToNull(validator);
|
|
92
|
+
}
|
|
93
|
+
return zod.z.object(shape).passthrough();
|
|
94
|
+
}
|
|
95
|
+
function createDraftValidator(objectDef) {
|
|
96
|
+
const shape = {};
|
|
97
|
+
for (const attr of objectDef.attributes) {
|
|
98
|
+
const validator = createAttributeValidator(attr);
|
|
99
|
+
shape[attr.name] = withEmptyToNull(validator);
|
|
100
|
+
}
|
|
101
|
+
return zod.z.object(shape).passthrough();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/validation/object/helpers.ts
|
|
105
|
+
function validateAttribute(attr, value) {
|
|
106
|
+
const validator = createAttributeValidator(attr);
|
|
107
|
+
if (!attr.required && (value === void 0 || value === null)) {
|
|
108
|
+
return { success: true, data: { [attr.name]: value } };
|
|
109
|
+
}
|
|
110
|
+
const result = validator.safeParse(value);
|
|
111
|
+
if (result.success) {
|
|
112
|
+
return {
|
|
113
|
+
success: true,
|
|
114
|
+
data: { [attr.name]: result.data }
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
success: false,
|
|
119
|
+
errors: chunkBEN6TE7Y_js.formatZodErrors(result.error).map((err) => ({
|
|
120
|
+
path: [attr.name, ...err.path],
|
|
121
|
+
message: err.message
|
|
122
|
+
}))
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function validateObject(objectDef, data) {
|
|
126
|
+
const validator = createObjectValidator(objectDef);
|
|
127
|
+
const result = validator.safeParse(data);
|
|
128
|
+
if (result.success) {
|
|
129
|
+
return {
|
|
130
|
+
success: true,
|
|
131
|
+
data: result.data
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
success: false,
|
|
136
|
+
errors: chunkBEN6TE7Y_js.formatZodErrors(result.error)
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function validateObjectOrThrow(objectDef, data) {
|
|
140
|
+
const result = validateObject(objectDef, data);
|
|
141
|
+
if (!result.success) {
|
|
142
|
+
const errorMessages = result.errors?.map((err) => `${err.path.join(".")}: ${err.message}`).join("\n") || "Unknown validation error";
|
|
143
|
+
throw new Error(`Validation failed for ${objectDef.label}:
|
|
144
|
+
${errorMessages}`);
|
|
145
|
+
}
|
|
146
|
+
return result.data;
|
|
147
|
+
}
|
|
148
|
+
function validateDraft(objectDef, data) {
|
|
149
|
+
const validator = createDraftValidator(objectDef);
|
|
150
|
+
const result = validator.safeParse(data);
|
|
151
|
+
if (result.success) {
|
|
152
|
+
return {
|
|
153
|
+
success: true,
|
|
154
|
+
data: result.data
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
success: false,
|
|
159
|
+
errors: chunkBEN6TE7Y_js.formatZodErrors(result.error)
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function validateDraftOrThrow(objectDef, data) {
|
|
163
|
+
const result = validateDraft(objectDef, data);
|
|
164
|
+
if (!result.success) {
|
|
165
|
+
const errorMessages = result.errors?.map((err) => `${err.path.join(".")}: ${err.message}`).join("\n") || "Unknown validation error";
|
|
166
|
+
throw new Error(`Draft validation failed for ${objectDef.label}:
|
|
167
|
+
${errorMessages}`);
|
|
168
|
+
}
|
|
169
|
+
return result.data;
|
|
170
|
+
}
|
|
171
|
+
function isValuePresent(value) {
|
|
172
|
+
if (value === void 0 || value === null) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
if (typeof value === "string" && value.trim() === "") {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
function getMissingRequiredAttributes(objectDef, data) {
|
|
181
|
+
const missing = [];
|
|
182
|
+
for (const attr of objectDef.attributes) {
|
|
183
|
+
if (attr.required && !isValuePresent(data[attr.name])) {
|
|
184
|
+
missing.push(attr);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return missing;
|
|
188
|
+
}
|
|
189
|
+
function isRecordComplete(objectDef, data) {
|
|
190
|
+
const missing = getMissingRequiredAttributes(objectDef, data);
|
|
191
|
+
if (missing.length > 0) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
const validation = validateObject(objectDef, data);
|
|
195
|
+
return validation.success;
|
|
196
|
+
}
|
|
197
|
+
function computeRecordStatus(objectDef, data) {
|
|
198
|
+
return isRecordComplete(objectDef, data) ? "complete" : "draft";
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
exports.computeRecordStatus = computeRecordStatus;
|
|
202
|
+
exports.createAttributeValidator = createAttributeValidator;
|
|
203
|
+
exports.createDraftValidator = createDraftValidator;
|
|
204
|
+
exports.createFormAttributeValidator = createFormAttributeValidator;
|
|
205
|
+
exports.createObjectValidator = createObjectValidator;
|
|
206
|
+
exports.getMissingRequiredAttributes = getMissingRequiredAttributes;
|
|
207
|
+
exports.isRecordComplete = isRecordComplete;
|
|
208
|
+
exports.validateAttribute = validateAttribute;
|
|
209
|
+
exports.validateDraft = validateDraft;
|
|
210
|
+
exports.validateDraftOrThrow = validateDraftOrThrow;
|
|
211
|
+
exports.validateObject = validateObject;
|
|
212
|
+
exports.validateObjectOrThrow = validateObjectOrThrow;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { createCheckboxValidator } from './chunk-5TLM4QXO.mjs';
|
|
2
|
+
import { createDateValidator } from './chunk-XEOG24K6.mjs';
|
|
3
|
+
import { createNumberValidator } from './chunk-PKG3E5MW.mjs';
|
|
4
|
+
import { createRatingValidator } from './chunk-X6VDDXG7.mjs';
|
|
5
|
+
import { createTextAreaValidator, createTextValidator } from './chunk-U7VN3RUE.mjs';
|
|
6
|
+
import { createRelationValidator } from './chunk-QL3UGPUG.mjs';
|
|
7
|
+
import { createRichtextValidator } from './chunk-VPEV3W34.mjs';
|
|
8
|
+
import { createMultiselectValidator, createSelectValidator, createStatusValidator } from './chunk-ZFL7DXAE.mjs';
|
|
9
|
+
import { createUserValidator } from './chunk-WGFQMQMV.mjs';
|
|
10
|
+
import { createFormulaValidator } from './chunk-4RGFTMQR.mjs';
|
|
11
|
+
import { createRollupValidator } from './chunk-NXXSNUDI.mjs';
|
|
12
|
+
import { createCurrencyValidator } from './chunk-SVII65W7.mjs';
|
|
13
|
+
import { createFileValidator } from './chunk-MD6XGXTU.mjs';
|
|
14
|
+
import { createLocationValidator } from './chunk-ZM7W2ZCF.mjs';
|
|
15
|
+
import { createPhoneValidator } from './chunk-EIWGW2ML.mjs';
|
|
16
|
+
import { DEFAULT_VALIDATION_MESSAGES } from './chunk-BIQ35DLC.mjs';
|
|
17
|
+
import { formatZodErrors } from './chunk-RDXQ4CYT.mjs';
|
|
18
|
+
import { z } from 'zod';
|
|
19
|
+
|
|
20
|
+
function isEmptyValue(value) {
|
|
21
|
+
if (value === null || value === void 0) return true;
|
|
22
|
+
if (typeof value === "string" && value.trim() === "") return true;
|
|
23
|
+
if (value instanceof Date) return false;
|
|
24
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
25
|
+
return Object.values(value).every(
|
|
26
|
+
(v) => v === null || v === void 0 || typeof v === "string" && v.trim() === ""
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
function withEmptyToNull(validator) {
|
|
32
|
+
return z.preprocess((val) => isEmptyValue(val) ? null : val, validator.nullish());
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/validation/object/attribute-factory.ts
|
|
36
|
+
function createAttributeValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
|
|
37
|
+
switch (attr.type) {
|
|
38
|
+
case "text":
|
|
39
|
+
return createTextValidator(attr, messages);
|
|
40
|
+
case "textarea":
|
|
41
|
+
return createTextAreaValidator(attr, messages);
|
|
42
|
+
case "richtext":
|
|
43
|
+
return createRichtextValidator(attr, messages);
|
|
44
|
+
case "number":
|
|
45
|
+
return createNumberValidator(attr, messages);
|
|
46
|
+
case "checkbox":
|
|
47
|
+
return createCheckboxValidator(attr, messages);
|
|
48
|
+
case "date":
|
|
49
|
+
return createDateValidator(attr, messages);
|
|
50
|
+
case "phone":
|
|
51
|
+
return createPhoneValidator(attr, messages);
|
|
52
|
+
case "currency":
|
|
53
|
+
return createCurrencyValidator(attr, messages);
|
|
54
|
+
case "status":
|
|
55
|
+
return createStatusValidator(attr, messages);
|
|
56
|
+
case "location":
|
|
57
|
+
return createLocationValidator(attr, messages);
|
|
58
|
+
case "select":
|
|
59
|
+
return createSelectValidator(attr, messages);
|
|
60
|
+
case "multiselect":
|
|
61
|
+
return createMultiselectValidator(attr, messages);
|
|
62
|
+
case "file":
|
|
63
|
+
return createFileValidator(attr, messages);
|
|
64
|
+
case "user":
|
|
65
|
+
return createUserValidator(attr, messages);
|
|
66
|
+
case "relation":
|
|
67
|
+
return createRelationValidator(attr, messages);
|
|
68
|
+
case "rating":
|
|
69
|
+
return createRatingValidator(attr, messages);
|
|
70
|
+
case "formula":
|
|
71
|
+
return createFormulaValidator(attr, messages);
|
|
72
|
+
case "rollup":
|
|
73
|
+
return createRollupValidator(attr, messages);
|
|
74
|
+
default:
|
|
75
|
+
return z.unknown();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function createFormAttributeValidator(attr, messages = DEFAULT_VALIDATION_MESSAGES) {
|
|
79
|
+
const validator = createAttributeValidator(attr, messages);
|
|
80
|
+
if (!attr.required) {
|
|
81
|
+
return withEmptyToNull(validator);
|
|
82
|
+
}
|
|
83
|
+
return validator;
|
|
84
|
+
}
|
|
85
|
+
function createObjectValidator(objectDef) {
|
|
86
|
+
const shape = {};
|
|
87
|
+
for (const attr of objectDef.attributes) {
|
|
88
|
+
const validator = createAttributeValidator(attr);
|
|
89
|
+
shape[attr.name] = attr.required ? validator : withEmptyToNull(validator);
|
|
90
|
+
}
|
|
91
|
+
return z.object(shape).passthrough();
|
|
92
|
+
}
|
|
93
|
+
function createDraftValidator(objectDef) {
|
|
94
|
+
const shape = {};
|
|
95
|
+
for (const attr of objectDef.attributes) {
|
|
96
|
+
const validator = createAttributeValidator(attr);
|
|
97
|
+
shape[attr.name] = withEmptyToNull(validator);
|
|
98
|
+
}
|
|
99
|
+
return z.object(shape).passthrough();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// src/validation/object/helpers.ts
|
|
103
|
+
function validateAttribute(attr, value) {
|
|
104
|
+
const validator = createAttributeValidator(attr);
|
|
105
|
+
if (!attr.required && (value === void 0 || value === null)) {
|
|
106
|
+
return { success: true, data: { [attr.name]: value } };
|
|
107
|
+
}
|
|
108
|
+
const result = validator.safeParse(value);
|
|
109
|
+
if (result.success) {
|
|
110
|
+
return {
|
|
111
|
+
success: true,
|
|
112
|
+
data: { [attr.name]: result.data }
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
success: false,
|
|
117
|
+
errors: formatZodErrors(result.error).map((err) => ({
|
|
118
|
+
path: [attr.name, ...err.path],
|
|
119
|
+
message: err.message
|
|
120
|
+
}))
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function validateObject(objectDef, data) {
|
|
124
|
+
const validator = createObjectValidator(objectDef);
|
|
125
|
+
const result = validator.safeParse(data);
|
|
126
|
+
if (result.success) {
|
|
127
|
+
return {
|
|
128
|
+
success: true,
|
|
129
|
+
data: result.data
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
success: false,
|
|
134
|
+
errors: formatZodErrors(result.error)
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function validateObjectOrThrow(objectDef, data) {
|
|
138
|
+
const result = validateObject(objectDef, data);
|
|
139
|
+
if (!result.success) {
|
|
140
|
+
const errorMessages = result.errors?.map((err) => `${err.path.join(".")}: ${err.message}`).join("\n") || "Unknown validation error";
|
|
141
|
+
throw new Error(`Validation failed for ${objectDef.label}:
|
|
142
|
+
${errorMessages}`);
|
|
143
|
+
}
|
|
144
|
+
return result.data;
|
|
145
|
+
}
|
|
146
|
+
function validateDraft(objectDef, data) {
|
|
147
|
+
const validator = createDraftValidator(objectDef);
|
|
148
|
+
const result = validator.safeParse(data);
|
|
149
|
+
if (result.success) {
|
|
150
|
+
return {
|
|
151
|
+
success: true,
|
|
152
|
+
data: result.data
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
success: false,
|
|
157
|
+
errors: formatZodErrors(result.error)
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function validateDraftOrThrow(objectDef, data) {
|
|
161
|
+
const result = validateDraft(objectDef, data);
|
|
162
|
+
if (!result.success) {
|
|
163
|
+
const errorMessages = result.errors?.map((err) => `${err.path.join(".")}: ${err.message}`).join("\n") || "Unknown validation error";
|
|
164
|
+
throw new Error(`Draft validation failed for ${objectDef.label}:
|
|
165
|
+
${errorMessages}`);
|
|
166
|
+
}
|
|
167
|
+
return result.data;
|
|
168
|
+
}
|
|
169
|
+
function isValuePresent(value) {
|
|
170
|
+
if (value === void 0 || value === null) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
if (typeof value === "string" && value.trim() === "") {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
function getMissingRequiredAttributes(objectDef, data) {
|
|
179
|
+
const missing = [];
|
|
180
|
+
for (const attr of objectDef.attributes) {
|
|
181
|
+
if (attr.required && !isValuePresent(data[attr.name])) {
|
|
182
|
+
missing.push(attr);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return missing;
|
|
186
|
+
}
|
|
187
|
+
function isRecordComplete(objectDef, data) {
|
|
188
|
+
const missing = getMissingRequiredAttributes(objectDef, data);
|
|
189
|
+
if (missing.length > 0) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
const validation = validateObject(objectDef, data);
|
|
193
|
+
return validation.success;
|
|
194
|
+
}
|
|
195
|
+
function computeRecordStatus(objectDef, data) {
|
|
196
|
+
return isRecordComplete(objectDef, data) ? "complete" : "draft";
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export { computeRecordStatus, createAttributeValidator, createDraftValidator, createFormAttributeValidator, createObjectValidator, getMissingRequiredAttributes, isRecordComplete, validateAttribute, validateDraft, validateDraftOrThrow, validateObject, validateObjectOrThrow };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkVCPYYLCS_js = require('./chunk-VCPYYLCS.js');
|
|
4
|
+
var zod = require('zod');
|
|
5
|
+
|
|
6
|
+
function extractRelationId(item) {
|
|
7
|
+
if (typeof item === "object" && item !== null && "id" in item) {
|
|
8
|
+
return item.id;
|
|
9
|
+
}
|
|
10
|
+
return item;
|
|
11
|
+
}
|
|
12
|
+
function createSingleRelationValidator(attr, messages = chunkVCPYYLCS_js.DEFAULT_VALIDATION_MESSAGES) {
|
|
13
|
+
const uuidSchema = zod.z.uuid({
|
|
14
|
+
message: messages.invalidId(attr)
|
|
15
|
+
});
|
|
16
|
+
const nullableUuidSchema = zod.z.union([uuidSchema, zod.z.null()]);
|
|
17
|
+
return zod.z.union([
|
|
18
|
+
nullableUuidSchema,
|
|
19
|
+
zod.z.object({
|
|
20
|
+
id: uuidSchema,
|
|
21
|
+
props: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
22
|
+
}).passthrough()
|
|
23
|
+
// Allow additional properties (bilateral relations may have extra metadata)
|
|
24
|
+
]);
|
|
25
|
+
}
|
|
26
|
+
function createMultiRelationValidator(attr, messages = chunkVCPYYLCS_js.DEFAULT_VALIDATION_MESSAGES) {
|
|
27
|
+
const uuidSchema = zod.z.uuid({
|
|
28
|
+
message: messages.invalidId(attr)
|
|
29
|
+
});
|
|
30
|
+
const itemSchema = zod.z.union([
|
|
31
|
+
uuidSchema,
|
|
32
|
+
zod.z.object({
|
|
33
|
+
id: uuidSchema,
|
|
34
|
+
props: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
35
|
+
}).passthrough()
|
|
36
|
+
// Allow additional properties
|
|
37
|
+
]);
|
|
38
|
+
let arraySchema = zod.z.array(itemSchema);
|
|
39
|
+
if (attr.minItems !== void 0) {
|
|
40
|
+
arraySchema = arraySchema.min(attr.minItems, messages.minItems(attr, attr.minItems));
|
|
41
|
+
}
|
|
42
|
+
if (attr.maxItems !== void 0) {
|
|
43
|
+
arraySchema = arraySchema.max(attr.maxItems, messages.maxItems(attr, attr.maxItems));
|
|
44
|
+
}
|
|
45
|
+
return arraySchema.refine(
|
|
46
|
+
(items) => {
|
|
47
|
+
return items.every((item) => {
|
|
48
|
+
const id = extractRelationId(item);
|
|
49
|
+
return typeof id === "string" && uuidSchema.safeParse(id).success;
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
{ message: messages.invalidId(attr) }
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
function createRelationValidator(attr, messages = chunkVCPYYLCS_js.DEFAULT_VALIDATION_MESSAGES) {
|
|
56
|
+
if (attr.cardinality === "many") {
|
|
57
|
+
return createMultiRelationValidator(attr, messages);
|
|
58
|
+
}
|
|
59
|
+
return createSingleRelationValidator(attr, messages);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
exports.createMultiRelationValidator = createMultiRelationValidator;
|
|
63
|
+
exports.createRelationValidator = createRelationValidator;
|
|
64
|
+
exports.createSingleRelationValidator = createSingleRelationValidator;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkVCPYYLCS_js = require('./chunk-VCPYYLCS.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 = chunkVCPYYLCS_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,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkVCPYYLCS_js = require('./chunk-VCPYYLCS.js');
|
|
4
|
+
var zod = require('zod');
|
|
5
|
+
|
|
6
|
+
function createLocationValidator(attr, messages = chunkVCPYYLCS_js.DEFAULT_VALIDATION_MESSAGES) {
|
|
7
|
+
return zod.z.object(
|
|
8
|
+
{
|
|
9
|
+
address: zod.z.string().optional(),
|
|
10
|
+
address2: zod.z.string().optional(),
|
|
11
|
+
city: zod.z.string().optional(),
|
|
12
|
+
state: zod.z.string().optional(),
|
|
13
|
+
postalCode: zod.z.string().optional(),
|
|
14
|
+
country: zod.z.string().length(3).optional(),
|
|
15
|
+
latitude: zod.z.number().optional(),
|
|
16
|
+
longitude: zod.z.number().optional()
|
|
17
|
+
},
|
|
18
|
+
{ message: messages.invalidLocation(attr) }
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
exports.createLocationValidator = createLocationValidator;
|