@metaobjectsdev/runtime-ts 0.16.0 → 0.17.0
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator-runner.d.ts","sourceRoot":"","sources":["../src/validator-runner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"validator-runner.d.ts","sourceRoot":"","sources":["../src/validator-runner.ts"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAYnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAAE,CAAC;AAqB/C,MAAM,WAAW,iBAAiB;IAChC,gGAAgG;IAChG,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,QAAQ,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,GAAE,iBAAsB,GAC3B,gBAAgB,CAgKlB"}
|
package/dist/validator-runner.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Pure function: NEVER throws. ObjectManager wraps a non-ok result in a ValidationError on writes;
|
|
2
2
|
// om.validate() returns the result directly.
|
|
3
|
-
import {
|
|
3
|
+
import { MetaRoot } from "@metaobjectsdev/metadata";
|
|
4
|
+
import { TYPE_FIELD, TYPE_VALIDATOR, VALIDATOR_SUBTYPE_REQUIRED, VALIDATOR_SUBTYPE_LENGTH, VALIDATOR_SUBTYPE_REGEX, FIELD_SUBTYPE_STRING, FIELD_SUBTYPE_INT, FIELD_SUBTYPE_LONG, FIELD_SUBTYPE_DOUBLE, FIELD_SUBTYPE_FLOAT, FIELD_SUBTYPE_CURRENCY, FIELD_SUBTYPE_BOOLEAN, FIELD_SUBTYPE_UUID, FIELD_SUBTYPE_OBJECT, FIELD_ATTR_REQUIRED, FIELD_ATTR_MAX_LENGTH, FIELD_ATTR_DEFAULT, FIELD_ATTR_DB_COLUMN_TYPE, DB_COLUMN_TYPE_JSONB, FIELD_ATTR_OBJECT_REF, PACKAGE_SEPARATOR, OBJECT_SUBTYPE_VALUE, VALIDATOR_ATTR_MIN, VALIDATOR_ATTR_MAX, VALIDATOR_ATTR_PATTERN, } from "@metaobjectsdev/metadata";
|
|
4
5
|
// JS-safe numeric fields: must arrive as a JS `number` (they fit in 2^53).
|
|
5
6
|
const NUMERIC_FIELD_SUBTYPES = new Set([
|
|
6
7
|
FIELD_SUBTYPE_INT,
|
|
@@ -60,6 +61,46 @@ export function runValidators(entity, data, opts = {}) {
|
|
|
60
61
|
if (field.subType === FIELD_SUBTYPE_STRING && field.ownAttr(FIELD_ATTR_DB_COLUMN_TYPE) === DB_COLUMN_TYPE_JSONB) {
|
|
61
62
|
continue;
|
|
62
63
|
}
|
|
64
|
+
// Value-object column (`field.object @objectRef`): recurse into the VO's
|
|
65
|
+
// member constraints. A present VO is validated in FULL (never partial) —
|
|
66
|
+
// the generated Zod UpdateSchema embeds the VO InsertSchema, so required
|
|
67
|
+
// members must be present + valid even inside a partial parent update. Both
|
|
68
|
+
// single and @isArray VO columns; each array element is a VO. Keeps the
|
|
69
|
+
// runtime OM byte-identical with the generated validator on nested VO.
|
|
70
|
+
if (field.subType === FIELD_SUBTYPE_OBJECT) {
|
|
71
|
+
const vo = resolveVoRef(field);
|
|
72
|
+
if (vo !== undefined) {
|
|
73
|
+
if (field.isArray && !Array.isArray(value)) {
|
|
74
|
+
errors.push({
|
|
75
|
+
field: field.name, rule: "type",
|
|
76
|
+
message: `'${field.name}' must be an array of ${vo.name}`,
|
|
77
|
+
expected: "array", received: typeof value,
|
|
78
|
+
});
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const elements = field.isArray ? value : [value];
|
|
82
|
+
elements.forEach((el, i) => {
|
|
83
|
+
if (typeof el !== "object" || el === null || Array.isArray(el)) {
|
|
84
|
+
errors.push({
|
|
85
|
+
field: field.name, rule: "type",
|
|
86
|
+
message: `'${field.name}' must be a ${vo.name} object`,
|
|
87
|
+
expected: vo.name, received: el === null ? "null" : typeof el,
|
|
88
|
+
});
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const sub = runValidators(vo, el);
|
|
92
|
+
if (!sub.ok) {
|
|
93
|
+
for (const e of sub.errors) {
|
|
94
|
+
errors.push({
|
|
95
|
+
...e,
|
|
96
|
+
field: field.isArray ? `${field.name}[${i}].${e.field}` : `${field.name}.${e.field}`,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
63
104
|
const typeError = checkType(field.subType, value);
|
|
64
105
|
if (typeError !== null) {
|
|
65
106
|
errors.push({
|
|
@@ -138,6 +179,28 @@ export function runValidators(entity, data, opts = {}) {
|
|
|
138
179
|
}
|
|
139
180
|
return errors.length === 0 ? { ok: true } : { ok: false, errors };
|
|
140
181
|
}
|
|
182
|
+
/** Resolve a `field.object`'s `@objectRef` to its value-object MetaData by walking
|
|
183
|
+
* to the tree root. The ref may be a bare name or a `pkg::Name` FQN. Mirrors the
|
|
184
|
+
* extract-object resolver. Returns undefined when unresolvable OR when the target
|
|
185
|
+
* is not an `object.value` (→ no VO recursion). Cross-port parity: C#/Java/Kotlin
|
|
186
|
+
* gate the recursion on the ref being a value object, so a `field.object @objectRef`
|
|
187
|
+
* pointing at a non-value object validates identically (skipped) on every port.
|
|
188
|
+
* ADR-0039: resolving — @objectRef may be inherited via extends. */
|
|
189
|
+
function resolveVoRef(field) {
|
|
190
|
+
const ref = field.attr(FIELD_ATTR_OBJECT_REF);
|
|
191
|
+
if (typeof ref !== "string" || ref.length === 0)
|
|
192
|
+
return undefined;
|
|
193
|
+
const root = field.root();
|
|
194
|
+
if (!(root instanceof MetaRoot))
|
|
195
|
+
return undefined;
|
|
196
|
+
let target = root.findObject(ref);
|
|
197
|
+
if (target === undefined) {
|
|
198
|
+
const sep = ref.lastIndexOf(PACKAGE_SEPARATOR);
|
|
199
|
+
if (sep >= 0)
|
|
200
|
+
target = root.findObject(ref.slice(sep + PACKAGE_SEPARATOR.length));
|
|
201
|
+
}
|
|
202
|
+
return target?.subType === OBJECT_SUBTYPE_VALUE ? target : undefined;
|
|
203
|
+
}
|
|
141
204
|
function isRequired(field) {
|
|
142
205
|
// ADR-0039: effective — @required and a required-validator may be inherited via extends.
|
|
143
206
|
if (field.attr(FIELD_ATTR_REQUIRED) === true)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator-runner.js","sourceRoot":"","sources":["../src/validator-runner.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,6CAA6C;
|
|
1
|
+
{"version":3,"file":"validator-runner.js","sourceRoot":"","sources":["../src/validator-runner.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metaobjectsdev/runtime-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Node-side runtime helpers for MetaObjects: Fastify route builders, Drizzle filter/sort integration, Kysely drivers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
"access": "public"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@metaobjectsdev/metadata": "0.
|
|
68
|
-
"@metaobjectsdev/render": "0.
|
|
67
|
+
"@metaobjectsdev/metadata": "0.17.0",
|
|
68
|
+
"@metaobjectsdev/render": "0.17.0",
|
|
69
69
|
"qs": "^6.13.0"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
package/src/validator-runner.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
// Pure function: NEVER throws. ObjectManager wraps a non-ok result in a ValidationError on writes;
|
|
2
2
|
// om.validate() returns the result directly.
|
|
3
3
|
|
|
4
|
-
import type
|
|
4
|
+
import { MetaRoot, type MetaData } from "@metaobjectsdev/metadata";
|
|
5
5
|
import {
|
|
6
6
|
TYPE_FIELD, TYPE_VALIDATOR,
|
|
7
7
|
VALIDATOR_SUBTYPE_REQUIRED, VALIDATOR_SUBTYPE_LENGTH, VALIDATOR_SUBTYPE_REGEX,
|
|
8
8
|
FIELD_SUBTYPE_STRING, FIELD_SUBTYPE_INT, FIELD_SUBTYPE_LONG,
|
|
9
9
|
FIELD_SUBTYPE_DOUBLE, FIELD_SUBTYPE_FLOAT, FIELD_SUBTYPE_CURRENCY,
|
|
10
|
-
FIELD_SUBTYPE_BOOLEAN, FIELD_SUBTYPE_UUID,
|
|
10
|
+
FIELD_SUBTYPE_BOOLEAN, FIELD_SUBTYPE_UUID, FIELD_SUBTYPE_OBJECT,
|
|
11
11
|
FIELD_ATTR_REQUIRED, FIELD_ATTR_MAX_LENGTH, FIELD_ATTR_DEFAULT,
|
|
12
|
-
FIELD_ATTR_DB_COLUMN_TYPE, DB_COLUMN_TYPE_JSONB,
|
|
12
|
+
FIELD_ATTR_DB_COLUMN_TYPE, DB_COLUMN_TYPE_JSONB, FIELD_ATTR_OBJECT_REF,
|
|
13
|
+
PACKAGE_SEPARATOR, OBJECT_SUBTYPE_VALUE,
|
|
13
14
|
VALIDATOR_ATTR_MIN, VALIDATOR_ATTR_MAX, VALIDATOR_ATTR_PATTERN,
|
|
14
15
|
} from "@metaobjectsdev/metadata";
|
|
15
16
|
import type { ValidationFailure } from "./errors.js";
|
|
@@ -90,6 +91,47 @@ export function runValidators(
|
|
|
90
91
|
continue;
|
|
91
92
|
}
|
|
92
93
|
|
|
94
|
+
// Value-object column (`field.object @objectRef`): recurse into the VO's
|
|
95
|
+
// member constraints. A present VO is validated in FULL (never partial) —
|
|
96
|
+
// the generated Zod UpdateSchema embeds the VO InsertSchema, so required
|
|
97
|
+
// members must be present + valid even inside a partial parent update. Both
|
|
98
|
+
// single and @isArray VO columns; each array element is a VO. Keeps the
|
|
99
|
+
// runtime OM byte-identical with the generated validator on nested VO.
|
|
100
|
+
if (field.subType === FIELD_SUBTYPE_OBJECT) {
|
|
101
|
+
const vo = resolveVoRef(field);
|
|
102
|
+
if (vo !== undefined) {
|
|
103
|
+
if (field.isArray && !Array.isArray(value)) {
|
|
104
|
+
errors.push({
|
|
105
|
+
field: field.name, rule: "type",
|
|
106
|
+
message: `'${field.name}' must be an array of ${vo.name}`,
|
|
107
|
+
expected: "array", received: typeof value,
|
|
108
|
+
});
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const elements: unknown[] = field.isArray ? (value as unknown[]) : [value];
|
|
112
|
+
elements.forEach((el, i) => {
|
|
113
|
+
if (typeof el !== "object" || el === null || Array.isArray(el)) {
|
|
114
|
+
errors.push({
|
|
115
|
+
field: field.name, rule: "type",
|
|
116
|
+
message: `'${field.name}' must be a ${vo.name} object`,
|
|
117
|
+
expected: vo.name, received: el === null ? "null" : typeof el,
|
|
118
|
+
});
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const sub = runValidators(vo, el as Record<string, unknown>);
|
|
122
|
+
if (!sub.ok) {
|
|
123
|
+
for (const e of sub.errors) {
|
|
124
|
+
errors.push({
|
|
125
|
+
...e,
|
|
126
|
+
field: field.isArray ? `${field.name}[${i}].${e.field}` : `${field.name}.${e.field}`,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
|
|
93
135
|
const typeError = checkType(field.subType, value);
|
|
94
136
|
if (typeError !== null) {
|
|
95
137
|
errors.push({
|
|
@@ -167,6 +209,26 @@ export function runValidators(
|
|
|
167
209
|
return errors.length === 0 ? { ok: true } : { ok: false, errors };
|
|
168
210
|
}
|
|
169
211
|
|
|
212
|
+
/** Resolve a `field.object`'s `@objectRef` to its value-object MetaData by walking
|
|
213
|
+
* to the tree root. The ref may be a bare name or a `pkg::Name` FQN. Mirrors the
|
|
214
|
+
* extract-object resolver. Returns undefined when unresolvable OR when the target
|
|
215
|
+
* is not an `object.value` (→ no VO recursion). Cross-port parity: C#/Java/Kotlin
|
|
216
|
+
* gate the recursion on the ref being a value object, so a `field.object @objectRef`
|
|
217
|
+
* pointing at a non-value object validates identically (skipped) on every port.
|
|
218
|
+
* ADR-0039: resolving — @objectRef may be inherited via extends. */
|
|
219
|
+
function resolveVoRef(field: MetaData): MetaData | undefined {
|
|
220
|
+
const ref = field.attr(FIELD_ATTR_OBJECT_REF);
|
|
221
|
+
if (typeof ref !== "string" || ref.length === 0) return undefined;
|
|
222
|
+
const root = field.root();
|
|
223
|
+
if (!(root instanceof MetaRoot)) return undefined;
|
|
224
|
+
let target = root.findObject(ref);
|
|
225
|
+
if (target === undefined) {
|
|
226
|
+
const sep = ref.lastIndexOf(PACKAGE_SEPARATOR);
|
|
227
|
+
if (sep >= 0) target = root.findObject(ref.slice(sep + PACKAGE_SEPARATOR.length));
|
|
228
|
+
}
|
|
229
|
+
return target?.subType === OBJECT_SUBTYPE_VALUE ? target : undefined;
|
|
230
|
+
}
|
|
231
|
+
|
|
170
232
|
function isRequired(field: MetaData): boolean {
|
|
171
233
|
// ADR-0039: effective — @required and a required-validator may be inherited via extends.
|
|
172
234
|
if (field.attr(FIELD_ATTR_REQUIRED) === true) return true;
|