@plasius/schema 1.2.6 → 1.2.7
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/index.cjs +85 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -4
- package/dist/index.d.ts +20 -4
- package/dist/index.js +85 -26
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.d.cts
CHANGED
|
@@ -8,6 +8,21 @@ interface PII {
|
|
|
8
8
|
purpose?: string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
interface ValidationIssueInput {
|
|
12
|
+
code: string;
|
|
13
|
+
message: string;
|
|
14
|
+
path?: string;
|
|
15
|
+
}
|
|
16
|
+
interface ValidationIssue {
|
|
17
|
+
path: string;
|
|
18
|
+
code: string;
|
|
19
|
+
message: string;
|
|
20
|
+
}
|
|
21
|
+
type FieldValidatorResult = boolean | string | ValidationIssueInput | ValidationIssueInput[];
|
|
22
|
+
type FieldValidator<T = unknown> = {
|
|
23
|
+
bivarianceHack(value: T): FieldValidatorResult;
|
|
24
|
+
}["bivarianceHack"];
|
|
25
|
+
|
|
11
26
|
type FieldType$1 = "string" | "number" | "boolean" | "object" | "array" | "ref";
|
|
12
27
|
|
|
13
28
|
type FieldExposure = "public" | "internal";
|
|
@@ -18,7 +33,7 @@ declare class FieldBuilder<TExternal = unknown, TInternal = TExternal> {
|
|
|
18
33
|
isSystem: boolean;
|
|
19
34
|
isImmutable: boolean;
|
|
20
35
|
isRequired: boolean;
|
|
21
|
-
_validator?:
|
|
36
|
+
_validator?: FieldValidator<TInternal>;
|
|
22
37
|
_description: string;
|
|
23
38
|
_version: string;
|
|
24
39
|
_default?: TInternal | (() => TInternal);
|
|
@@ -50,7 +65,7 @@ declare class FieldBuilder<TExternal = unknown, TInternal = TExternal> {
|
|
|
50
65
|
public(): FieldBuilder<TExternal, TInternal>;
|
|
51
66
|
required(): FieldBuilder<TExternal, TInternal>;
|
|
52
67
|
optional(): FieldBuilder<TExternal, TInternal>;
|
|
53
|
-
validator(fn:
|
|
68
|
+
validator(fn: FieldValidator<TInternal>): FieldBuilder<TExternal, TInternal>;
|
|
54
69
|
description(desc: string): FieldBuilder<TExternal, TInternal>;
|
|
55
70
|
default(value: TInternal | (() => TInternal)): FieldBuilder<TExternal, TInternal>;
|
|
56
71
|
/**
|
|
@@ -162,7 +177,7 @@ interface FieldDefinition<T = unknown> {
|
|
|
162
177
|
_shape?: SchemaShape;
|
|
163
178
|
pii?: PII;
|
|
164
179
|
exposure?: FieldExposure;
|
|
165
|
-
validator?:
|
|
180
|
+
validator?: FieldValidator<T>;
|
|
166
181
|
}
|
|
167
182
|
interface ValidateCompositionOptions {
|
|
168
183
|
resolveEntity: (type: string, id: string) => Promise<any | null>;
|
|
@@ -230,6 +245,7 @@ interface ValidationResult<T> {
|
|
|
230
245
|
valid: boolean;
|
|
231
246
|
value?: DeepReadonly<T>;
|
|
232
247
|
errors?: string[];
|
|
248
|
+
issues?: ValidationIssue[];
|
|
233
249
|
}
|
|
234
250
|
type RefEntityId<T extends string = string> = {
|
|
235
251
|
type: T;
|
|
@@ -636,4 +652,4 @@ declare function isPrivateUseSubtag(value: string): boolean;
|
|
|
636
652
|
*/
|
|
637
653
|
declare function validateLanguage(value: unknown): boolean;
|
|
638
654
|
|
|
639
|
-
export { type DeepReadonly, FieldBuilder, type FieldDefinition, type FieldExposure, type FieldType, type FieldTypeMap, type Infer, IsoLanguageCode, type PIIEnforcement, type RefEntityId, type Schema, type SchemaOptions, type SchemaShape, type SchemaUpgradeFunction, type SchemaUpgradeResult, type SchemaUpgradeSpec, type SchemaUpgradeStep, type SerializeOptions, type ValidateCompositionOptions, type ValidationResult, createComponentSchema, createSchema, field, getAllComponentSchemas, getAllSchemas, getComponentSchema, getSchemaForType, isExtensionSingleton, isExtensionSubtag, isIsoLanguageCode, isPrivateUseSingleton, isPrivateUseSubtag, isRegionSubtag, isScriptSubtag, isVariantSubtag, isoCountryCodes, isoCurrencyCodes, registerComponentSchema, renderSchemaDescription, validateCountryCode, validateCurrencyCode, validateDateTimeISO, validateEmail, validateLanguage, validateName, validatePercentage, validatePhone, validateRichText, validateSafeText, validateSemVer, validateUUID, validateUrl, validateUserId, validateUserIdArray };
|
|
655
|
+
export { type DeepReadonly, FieldBuilder, type FieldDefinition, type FieldExposure, type FieldType, type FieldTypeMap, type FieldValidator, type FieldValidatorResult, type Infer, IsoLanguageCode, type PIIEnforcement, type RefEntityId, type Schema, type SchemaOptions, type SchemaShape, type SchemaUpgradeFunction, type SchemaUpgradeResult, type SchemaUpgradeSpec, type SchemaUpgradeStep, type SerializeOptions, type ValidateCompositionOptions, type ValidationIssue, type ValidationIssueInput, type ValidationResult, createComponentSchema, createSchema, field, getAllComponentSchemas, getAllSchemas, getComponentSchema, getSchemaForType, isExtensionSingleton, isExtensionSubtag, isIsoLanguageCode, isPrivateUseSingleton, isPrivateUseSubtag, isRegionSubtag, isScriptSubtag, isVariantSubtag, isoCountryCodes, isoCurrencyCodes, registerComponentSchema, renderSchemaDescription, validateCountryCode, validateCurrencyCode, validateDateTimeISO, validateEmail, validateLanguage, validateName, validatePercentage, validatePhone, validateRichText, validateSafeText, validateSemVer, validateUUID, validateUrl, validateUserId, validateUserIdArray };
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,21 @@ interface PII {
|
|
|
8
8
|
purpose?: string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
interface ValidationIssueInput {
|
|
12
|
+
code: string;
|
|
13
|
+
message: string;
|
|
14
|
+
path?: string;
|
|
15
|
+
}
|
|
16
|
+
interface ValidationIssue {
|
|
17
|
+
path: string;
|
|
18
|
+
code: string;
|
|
19
|
+
message: string;
|
|
20
|
+
}
|
|
21
|
+
type FieldValidatorResult = boolean | string | ValidationIssueInput | ValidationIssueInput[];
|
|
22
|
+
type FieldValidator<T = unknown> = {
|
|
23
|
+
bivarianceHack(value: T): FieldValidatorResult;
|
|
24
|
+
}["bivarianceHack"];
|
|
25
|
+
|
|
11
26
|
type FieldType$1 = "string" | "number" | "boolean" | "object" | "array" | "ref";
|
|
12
27
|
|
|
13
28
|
type FieldExposure = "public" | "internal";
|
|
@@ -18,7 +33,7 @@ declare class FieldBuilder<TExternal = unknown, TInternal = TExternal> {
|
|
|
18
33
|
isSystem: boolean;
|
|
19
34
|
isImmutable: boolean;
|
|
20
35
|
isRequired: boolean;
|
|
21
|
-
_validator?:
|
|
36
|
+
_validator?: FieldValidator<TInternal>;
|
|
22
37
|
_description: string;
|
|
23
38
|
_version: string;
|
|
24
39
|
_default?: TInternal | (() => TInternal);
|
|
@@ -50,7 +65,7 @@ declare class FieldBuilder<TExternal = unknown, TInternal = TExternal> {
|
|
|
50
65
|
public(): FieldBuilder<TExternal, TInternal>;
|
|
51
66
|
required(): FieldBuilder<TExternal, TInternal>;
|
|
52
67
|
optional(): FieldBuilder<TExternal, TInternal>;
|
|
53
|
-
validator(fn:
|
|
68
|
+
validator(fn: FieldValidator<TInternal>): FieldBuilder<TExternal, TInternal>;
|
|
54
69
|
description(desc: string): FieldBuilder<TExternal, TInternal>;
|
|
55
70
|
default(value: TInternal | (() => TInternal)): FieldBuilder<TExternal, TInternal>;
|
|
56
71
|
/**
|
|
@@ -162,7 +177,7 @@ interface FieldDefinition<T = unknown> {
|
|
|
162
177
|
_shape?: SchemaShape;
|
|
163
178
|
pii?: PII;
|
|
164
179
|
exposure?: FieldExposure;
|
|
165
|
-
validator?:
|
|
180
|
+
validator?: FieldValidator<T>;
|
|
166
181
|
}
|
|
167
182
|
interface ValidateCompositionOptions {
|
|
168
183
|
resolveEntity: (type: string, id: string) => Promise<any | null>;
|
|
@@ -230,6 +245,7 @@ interface ValidationResult<T> {
|
|
|
230
245
|
valid: boolean;
|
|
231
246
|
value?: DeepReadonly<T>;
|
|
232
247
|
errors?: string[];
|
|
248
|
+
issues?: ValidationIssue[];
|
|
233
249
|
}
|
|
234
250
|
type RefEntityId<T extends string = string> = {
|
|
235
251
|
type: T;
|
|
@@ -636,4 +652,4 @@ declare function isPrivateUseSubtag(value: string): boolean;
|
|
|
636
652
|
*/
|
|
637
653
|
declare function validateLanguage(value: unknown): boolean;
|
|
638
654
|
|
|
639
|
-
export { type DeepReadonly, FieldBuilder, type FieldDefinition, type FieldExposure, type FieldType, type FieldTypeMap, type Infer, IsoLanguageCode, type PIIEnforcement, type RefEntityId, type Schema, type SchemaOptions, type SchemaShape, type SchemaUpgradeFunction, type SchemaUpgradeResult, type SchemaUpgradeSpec, type SchemaUpgradeStep, type SerializeOptions, type ValidateCompositionOptions, type ValidationResult, createComponentSchema, createSchema, field, getAllComponentSchemas, getAllSchemas, getComponentSchema, getSchemaForType, isExtensionSingleton, isExtensionSubtag, isIsoLanguageCode, isPrivateUseSingleton, isPrivateUseSubtag, isRegionSubtag, isScriptSubtag, isVariantSubtag, isoCountryCodes, isoCurrencyCodes, registerComponentSchema, renderSchemaDescription, validateCountryCode, validateCurrencyCode, validateDateTimeISO, validateEmail, validateLanguage, validateName, validatePercentage, validatePhone, validateRichText, validateSafeText, validateSemVer, validateUUID, validateUrl, validateUserId, validateUserIdArray };
|
|
655
|
+
export { type DeepReadonly, FieldBuilder, type FieldDefinition, type FieldExposure, type FieldType, type FieldTypeMap, type FieldValidator, type FieldValidatorResult, type Infer, IsoLanguageCode, type PIIEnforcement, type RefEntityId, type Schema, type SchemaOptions, type SchemaShape, type SchemaUpgradeFunction, type SchemaUpgradeResult, type SchemaUpgradeSpec, type SchemaUpgradeStep, type SerializeOptions, type ValidateCompositionOptions, type ValidationIssue, type ValidationIssueInput, type ValidationResult, createComponentSchema, createSchema, field, getAllComponentSchemas, getAllSchemas, getComponentSchema, getSchemaForType, isExtensionSingleton, isExtensionSubtag, isIsoLanguageCode, isPrivateUseSingleton, isPrivateUseSubtag, isRegionSubtag, isScriptSubtag, isVariantSubtag, isoCountryCodes, isoCurrencyCodes, registerComponentSchema, renderSchemaDescription, validateCountryCode, validateCurrencyCode, validateDateTimeISO, validateEmail, validateLanguage, validateName, validatePercentage, validatePhone, validateRichText, validateSafeText, validateSemVer, validateUUID, validateUrl, validateUserId, validateUserIdArray };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
// src/field.builder.ts
|
|
2
|
+
function mergeValidatorResult(previousResult, nextValid) {
|
|
3
|
+
if (previousResult !== true) {
|
|
4
|
+
return previousResult;
|
|
5
|
+
}
|
|
6
|
+
return nextValid;
|
|
7
|
+
}
|
|
2
8
|
var FieldBuilder = class _FieldBuilder {
|
|
3
9
|
constructor(type, options = {}) {
|
|
4
10
|
this.type = type;
|
|
@@ -94,19 +100,19 @@ var FieldBuilder = class _FieldBuilder {
|
|
|
94
100
|
const prevValidator = this._validator;
|
|
95
101
|
this._validator = (value) => {
|
|
96
102
|
const valid = typeof value === "number" && value >= min;
|
|
97
|
-
return prevValidator ? prevValidator(value)
|
|
103
|
+
return prevValidator ? mergeValidatorResult(prevValidator(value), valid) : valid;
|
|
98
104
|
};
|
|
99
105
|
} else if (this.type === "string") {
|
|
100
106
|
const prevValidator = this._validator;
|
|
101
107
|
this._validator = (value) => {
|
|
102
108
|
const valid = typeof value === "string" && value.length >= min;
|
|
103
|
-
return prevValidator ? prevValidator(value)
|
|
109
|
+
return prevValidator ? mergeValidatorResult(prevValidator(value), valid) : valid;
|
|
104
110
|
};
|
|
105
111
|
} else if (this.type === "array") {
|
|
106
112
|
const prevValidator = this._validator;
|
|
107
113
|
this._validator = (value) => {
|
|
108
114
|
const valid = Array.isArray(value) && value.length >= min;
|
|
109
|
-
return prevValidator ? prevValidator(value)
|
|
115
|
+
return prevValidator ? mergeValidatorResult(prevValidator(value), valid) : valid;
|
|
110
116
|
};
|
|
111
117
|
} else {
|
|
112
118
|
throw new Error(
|
|
@@ -120,19 +126,19 @@ var FieldBuilder = class _FieldBuilder {
|
|
|
120
126
|
const prevValidator = this._validator;
|
|
121
127
|
this._validator = (value) => {
|
|
122
128
|
const valid = typeof value === "number" && value <= max;
|
|
123
|
-
return prevValidator ? prevValidator(value)
|
|
129
|
+
return prevValidator ? mergeValidatorResult(prevValidator(value), valid) : valid;
|
|
124
130
|
};
|
|
125
131
|
} else if (this.type === "string") {
|
|
126
132
|
const prevValidator = this._validator;
|
|
127
133
|
this._validator = (value) => {
|
|
128
134
|
const valid = typeof value === "string" && value.length <= max;
|
|
129
|
-
return prevValidator ? prevValidator(value)
|
|
135
|
+
return prevValidator ? mergeValidatorResult(prevValidator(value), valid) : valid;
|
|
130
136
|
};
|
|
131
137
|
} else if (this.type === "array") {
|
|
132
138
|
const prevValidator = this._validator;
|
|
133
139
|
this._validator = (value) => {
|
|
134
140
|
const valid = Array.isArray(value) && value.length <= max;
|
|
135
|
-
return prevValidator ? prevValidator(value)
|
|
141
|
+
return prevValidator ? mergeValidatorResult(prevValidator(value), valid) : valid;
|
|
136
142
|
};
|
|
137
143
|
} else {
|
|
138
144
|
throw new Error(
|
|
@@ -148,7 +154,7 @@ var FieldBuilder = class _FieldBuilder {
|
|
|
148
154
|
const prevValidator = this._validator;
|
|
149
155
|
this._validator = (value) => {
|
|
150
156
|
const valid = typeof value === "string" && regex.test(value);
|
|
151
|
-
return prevValidator ? prevValidator(value)
|
|
157
|
+
return prevValidator ? mergeValidatorResult(prevValidator(value), valid) : valid;
|
|
152
158
|
};
|
|
153
159
|
return this;
|
|
154
160
|
}
|
|
@@ -1547,6 +1553,38 @@ function getValidator(def) {
|
|
|
1547
1553
|
function getShape(def) {
|
|
1548
1554
|
return def?._shape ?? def?.shape ?? void 0;
|
|
1549
1555
|
}
|
|
1556
|
+
function normalizeValidationIssue(path, issue, defaultCode) {
|
|
1557
|
+
if (typeof issue === "string") {
|
|
1558
|
+
return {
|
|
1559
|
+
path,
|
|
1560
|
+
code: defaultCode,
|
|
1561
|
+
message: issue
|
|
1562
|
+
};
|
|
1563
|
+
}
|
|
1564
|
+
return {
|
|
1565
|
+
path: issue.path ?? path,
|
|
1566
|
+
code: issue.code || defaultCode,
|
|
1567
|
+
message: issue.message
|
|
1568
|
+
};
|
|
1569
|
+
}
|
|
1570
|
+
function normalizeValidatorIssues(path, result, defaultCode) {
|
|
1571
|
+
if (result === true) {
|
|
1572
|
+
return [];
|
|
1573
|
+
}
|
|
1574
|
+
if (result === false) {
|
|
1575
|
+
return [
|
|
1576
|
+
{
|
|
1577
|
+
path,
|
|
1578
|
+
code: defaultCode,
|
|
1579
|
+
message: `Invalid value for field: ${path}`
|
|
1580
|
+
}
|
|
1581
|
+
];
|
|
1582
|
+
}
|
|
1583
|
+
if (Array.isArray(result)) {
|
|
1584
|
+
return result.map((issue) => normalizeValidationIssue(path, issue, defaultCode));
|
|
1585
|
+
}
|
|
1586
|
+
return [normalizeValidationIssue(path, result, defaultCode)];
|
|
1587
|
+
}
|
|
1550
1588
|
function checkMissingRequired(parentKey, key, value, def, errors) {
|
|
1551
1589
|
if (value === void 0 || value === null) {
|
|
1552
1590
|
const path = parentKey ? `${parentKey}.${key}` : key;
|
|
@@ -1565,13 +1603,16 @@ function checkImmutable(parentKey, key, value, def, existing, errors) {
|
|
|
1565
1603
|
}
|
|
1566
1604
|
return { immutableViolation: false };
|
|
1567
1605
|
}
|
|
1568
|
-
function runCustomValidator(parentKey, key, value, def, errors) {
|
|
1606
|
+
function runCustomValidator(parentKey, key, value, def, errors, issues) {
|
|
1569
1607
|
const validator = getValidator(def);
|
|
1570
1608
|
if (validator && value !== void 0 && value !== null) {
|
|
1571
|
-
const
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
errors.push(
|
|
1609
|
+
const path = parentKey ? `${parentKey}.${key}` : key;
|
|
1610
|
+
const normalizedIssues = normalizeValidatorIssues(path, validator(value), "invalid_value");
|
|
1611
|
+
if (normalizedIssues.length > 0) {
|
|
1612
|
+
errors.push(...normalizedIssues.map((issue) => issue.message));
|
|
1613
|
+
if (issues) {
|
|
1614
|
+
issues.push(...normalizedIssues);
|
|
1615
|
+
}
|
|
1575
1616
|
return { invalid: true };
|
|
1576
1617
|
}
|
|
1577
1618
|
}
|
|
@@ -1611,7 +1652,7 @@ function validateBooleanField(parentKey, key, value, _def, errors) {
|
|
|
1611
1652
|
errors.push(`Field ${path} must be boolean`);
|
|
1612
1653
|
}
|
|
1613
1654
|
}
|
|
1614
|
-
function validateObjectChildren(parentKey, obj, shape, errors, existing, piiEnforcement, logger) {
|
|
1655
|
+
function validateObjectChildren(parentKey, obj, shape, errors, issues, existing, piiEnforcement, logger) {
|
|
1615
1656
|
for (const [childKey, childDef] of Object.entries(shape)) {
|
|
1616
1657
|
let childValue = obj[childKey];
|
|
1617
1658
|
const existingChild = existing && typeof existing === "object" ? existing[childKey] : void 0;
|
|
@@ -1652,7 +1693,8 @@ function validateObjectChildren(parentKey, obj, shape, errors, existing, piiEnfo
|
|
|
1652
1693
|
childKey,
|
|
1653
1694
|
childValue,
|
|
1654
1695
|
childDef,
|
|
1655
|
-
errors
|
|
1696
|
+
errors,
|
|
1697
|
+
issues
|
|
1656
1698
|
);
|
|
1657
1699
|
if (invalid) continue;
|
|
1658
1700
|
validateByType(
|
|
@@ -1661,13 +1703,14 @@ function validateObjectChildren(parentKey, obj, shape, errors, existing, piiEnfo
|
|
|
1661
1703
|
childValue,
|
|
1662
1704
|
childDef,
|
|
1663
1705
|
errors,
|
|
1706
|
+
issues,
|
|
1664
1707
|
existingChild,
|
|
1665
1708
|
piiEnforcement,
|
|
1666
1709
|
logger
|
|
1667
1710
|
);
|
|
1668
1711
|
}
|
|
1669
1712
|
}
|
|
1670
|
-
function validateObjectField(parentKey, key, value, def, errors, existing, piiEnforcement, logger) {
|
|
1713
|
+
function validateObjectField(parentKey, key, value, def, errors, issues, existing, piiEnforcement, logger) {
|
|
1671
1714
|
const path = parentKey ? `${parentKey}.${key}` : key;
|
|
1672
1715
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
1673
1716
|
errors.push(`Field ${path} must be object`);
|
|
@@ -1675,7 +1718,7 @@ function validateObjectField(parentKey, key, value, def, errors, existing, piiEn
|
|
|
1675
1718
|
}
|
|
1676
1719
|
const objShape = getShape(def);
|
|
1677
1720
|
if (objShape)
|
|
1678
|
-
validateObjectChildren(path, value, objShape, errors, existing, piiEnforcement, logger);
|
|
1721
|
+
validateObjectChildren(path, value, objShape, errors, issues, existing, piiEnforcement, logger);
|
|
1679
1722
|
}
|
|
1680
1723
|
function validateArrayOfStrings(parentKey, key, arr, itemDef, errors) {
|
|
1681
1724
|
const path = parentKey ? `${parentKey}.${key}` : key;
|
|
@@ -1734,7 +1777,7 @@ function validateArrayOfBooleans(parentKey, key, arr, _itemDef, errors) {
|
|
|
1734
1777
|
});
|
|
1735
1778
|
}
|
|
1736
1779
|
}
|
|
1737
|
-
function validateArrayOfObjects(parentKey, key, arr, itemDef, errors, existing, piiEnforcement, logger) {
|
|
1780
|
+
function validateArrayOfObjects(parentKey, key, arr, itemDef, errors, issues, existing, piiEnforcement, logger) {
|
|
1738
1781
|
const path = parentKey ? `${parentKey}.${key}` : key;
|
|
1739
1782
|
if (!Array.isArray(arr) || !arr.every((v) => typeof v === "object" && v !== null && !Array.isArray(v))) {
|
|
1740
1783
|
errors.push(`Field ${path} must be object[]`);
|
|
@@ -1788,7 +1831,8 @@ function validateArrayOfObjects(parentKey, key, arr, itemDef, errors, existing,
|
|
|
1788
1831
|
childKey,
|
|
1789
1832
|
childValue,
|
|
1790
1833
|
childDef,
|
|
1791
|
-
errors
|
|
1834
|
+
errors,
|
|
1835
|
+
issues
|
|
1792
1836
|
);
|
|
1793
1837
|
if (invalid) continue;
|
|
1794
1838
|
validateByType(
|
|
@@ -1797,6 +1841,7 @@ function validateArrayOfObjects(parentKey, key, arr, itemDef, errors, existing,
|
|
|
1797
1841
|
childValue,
|
|
1798
1842
|
childDef,
|
|
1799
1843
|
errors,
|
|
1844
|
+
issues,
|
|
1800
1845
|
existingChild,
|
|
1801
1846
|
piiEnforcement,
|
|
1802
1847
|
logger
|
|
@@ -1804,7 +1849,7 @@ function validateArrayOfObjects(parentKey, key, arr, itemDef, errors, existing,
|
|
|
1804
1849
|
}
|
|
1805
1850
|
});
|
|
1806
1851
|
}
|
|
1807
|
-
function validateArrayField(parentKey, key, value, def, errors, existing, piiEnforcement, logger) {
|
|
1852
|
+
function validateArrayField(parentKey, key, value, def, errors, issues, existing, piiEnforcement, logger) {
|
|
1808
1853
|
const path = parentKey ? `${parentKey}.${key}` : key;
|
|
1809
1854
|
if (!Array.isArray(value)) {
|
|
1810
1855
|
errors.push(`Field ${key} must be an array`);
|
|
@@ -1824,6 +1869,7 @@ function validateArrayField(parentKey, key, value, def, errors, existing, piiEnf
|
|
|
1824
1869
|
value,
|
|
1825
1870
|
def.itemType,
|
|
1826
1871
|
errors,
|
|
1872
|
+
issues,
|
|
1827
1873
|
existing,
|
|
1828
1874
|
piiEnforcement,
|
|
1829
1875
|
logger
|
|
@@ -1880,9 +1926,14 @@ function validateArrayField(parentKey, key, value, def, errors, existing, piiEnf
|
|
|
1880
1926
|
if (shortCircuit) continue;
|
|
1881
1927
|
const childValidator = getValidator(childDef);
|
|
1882
1928
|
if (childValidator && childValue !== void 0 && childValue !== null) {
|
|
1883
|
-
const
|
|
1884
|
-
|
|
1885
|
-
|
|
1929
|
+
const normalizedIssues = normalizeValidatorIssues(
|
|
1930
|
+
childPath,
|
|
1931
|
+
childValidator(childValue),
|
|
1932
|
+
"invalid_value"
|
|
1933
|
+
);
|
|
1934
|
+
if (normalizedIssues.length > 0) {
|
|
1935
|
+
errors.push(...normalizedIssues.map((issue) => issue.message));
|
|
1936
|
+
issues.push(...normalizedIssues);
|
|
1886
1937
|
continue;
|
|
1887
1938
|
}
|
|
1888
1939
|
}
|
|
@@ -1892,6 +1943,7 @@ function validateArrayField(parentKey, key, value, def, errors, existing, piiEnf
|
|
|
1892
1943
|
childValue,
|
|
1893
1944
|
childDef,
|
|
1894
1945
|
errors,
|
|
1946
|
+
issues,
|
|
1895
1947
|
existingChild,
|
|
1896
1948
|
piiEnforcement,
|
|
1897
1949
|
logger
|
|
@@ -1917,7 +1969,7 @@ function validateRefField(parentKey, key, value, def, errors, _existing, _piiEnf
|
|
|
1917
1969
|
);
|
|
1918
1970
|
}
|
|
1919
1971
|
}
|
|
1920
|
-
function validateByType(parentKey, key, value, def, errors, existing, piiEnforcement, logger) {
|
|
1972
|
+
function validateByType(parentKey, key, value, def, errors, issues, existing, piiEnforcement, logger) {
|
|
1921
1973
|
const path = parentKey ? `${parentKey}.${key}` : key;
|
|
1922
1974
|
switch (def.type) {
|
|
1923
1975
|
case "string":
|
|
@@ -1933,6 +1985,7 @@ function validateByType(parentKey, key, value, def, errors, existing, piiEnforce
|
|
|
1933
1985
|
value,
|
|
1934
1986
|
def,
|
|
1935
1987
|
errors,
|
|
1988
|
+
issues,
|
|
1936
1989
|
existing,
|
|
1937
1990
|
piiEnforcement,
|
|
1938
1991
|
logger
|
|
@@ -1944,6 +1997,7 @@ function validateByType(parentKey, key, value, def, errors, existing, piiEnforce
|
|
|
1944
1997
|
value,
|
|
1945
1998
|
def,
|
|
1946
1999
|
errors,
|
|
2000
|
+
issues,
|
|
1947
2001
|
existing,
|
|
1948
2002
|
piiEnforcement,
|
|
1949
2003
|
logger
|
|
@@ -1979,6 +2033,7 @@ function createSchema(_shape, entityType, options = {
|
|
|
1979
2033
|
// 🔗 Validate input against the schema
|
|
1980
2034
|
validate(input, existing) {
|
|
1981
2035
|
const errors = [];
|
|
2036
|
+
const issues = [];
|
|
1982
2037
|
const result = {};
|
|
1983
2038
|
const piiMode = options.piiEnforcement ?? "none";
|
|
1984
2039
|
if (typeof input !== "object" || input === null) {
|
|
@@ -2042,16 +2097,19 @@ function createSchema(_shape, entityType, options = {
|
|
|
2042
2097
|
if (shortCircuit) continue;
|
|
2043
2098
|
const validateField = (val) => {
|
|
2044
2099
|
const localErrors = [];
|
|
2100
|
+
const localIssues = [];
|
|
2045
2101
|
const { invalid } = runCustomValidator(
|
|
2046
2102
|
"",
|
|
2047
2103
|
key,
|
|
2048
2104
|
val,
|
|
2049
2105
|
def,
|
|
2050
|
-
localErrors
|
|
2106
|
+
localErrors,
|
|
2107
|
+
localIssues
|
|
2051
2108
|
);
|
|
2052
2109
|
if (!invalid) {
|
|
2053
|
-
validateByType("", key, val, def, localErrors, existingField, piiMode, console);
|
|
2110
|
+
validateByType("", key, val, def, localErrors, localIssues, existingField, piiMode, console);
|
|
2054
2111
|
}
|
|
2112
|
+
issues.push(...localIssues);
|
|
2055
2113
|
return localErrors;
|
|
2056
2114
|
};
|
|
2057
2115
|
let fieldValue = value;
|
|
@@ -2092,7 +2150,8 @@ function createSchema(_shape, entityType, options = {
|
|
|
2092
2150
|
return {
|
|
2093
2151
|
valid: errors.length === 0,
|
|
2094
2152
|
value: result,
|
|
2095
|
-
errors
|
|
2153
|
+
errors,
|
|
2154
|
+
issues
|
|
2096
2155
|
};
|
|
2097
2156
|
},
|
|
2098
2157
|
// specific validator for a schema to allow conditional validation
|