@metaobjectsdev/runtime-ts 1.0.9 → 1.0.10
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/README.md +1 -1
- package/dist/constraint-errors.d.ts.map +1 -1
- package/dist/constraint-errors.js +3 -1
- package/dist/constraint-errors.js.map +1 -1
- package/dist/drivers/drizzle-driver.d.ts +2 -1
- package/dist/drivers/drizzle-driver.d.ts.map +1 -1
- package/dist/drivers/drizzle-driver.js +44 -0
- package/dist/drivers/drizzle-driver.js.map +1 -1
- package/dist/drivers/kysely-driver.d.ts +3 -1
- package/dist/drivers/kysely-driver.d.ts.map +1 -1
- package/dist/drivers/kysely-driver.js +37 -4
- package/dist/drivers/kysely-driver.js.map +1 -1
- package/dist/drivers/mysql-support.d.ts +19 -0
- package/dist/drivers/mysql-support.d.ts.map +1 -0
- package/dist/drivers/mysql-support.js +64 -0
- package/dist/drivers/mysql-support.js.map +1 -0
- package/dist/drizzle-fastify/filter-parser.d.ts +2 -1
- package/dist/drizzle-fastify/filter-parser.d.ts.map +1 -1
- package/dist/drizzle-fastify/filter-parser.js +11 -4
- package/dist/drizzle-fastify/filter-parser.js.map +1 -1
- package/dist/drizzle-fastify/index.d.ts +2 -1
- package/dist/drizzle-fastify/index.d.ts.map +1 -1
- package/dist/drizzle-fastify/index.js +23 -30
- package/dist/drizzle-fastify/index.js.map +1 -1
- package/dist/drizzle-fastify/mount-read-only.d.ts +2 -1
- package/dist/drizzle-fastify/mount-read-only.d.ts.map +1 -1
- package/dist/drizzle-fastify/mount-read-only.js +9 -3
- package/dist/drizzle-fastify/mount-read-only.js.map +1 -1
- package/dist/drizzle-fastify/util.d.ts +6 -0
- package/dist/drizzle-fastify/util.d.ts.map +1 -1
- package/dist/drizzle-fastify/util.js +28 -0
- package/dist/drizzle-fastify/util.js.map +1 -1
- package/dist/extract-object.d.ts.map +1 -1
- package/dist/extract-object.js +13 -2
- package/dist/extract-object.js.map +1 -1
- package/dist/hono/index.d.ts +2 -1
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/index.js +21 -30
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/mount-read-only.d.ts +2 -1
- package/dist/hono/mount-read-only.d.ts.map +1 -1
- package/dist/hono/mount-read-only.js +9 -3
- package/dist/hono/mount-read-only.js.map +1 -1
- package/dist/object-manager.d.ts.map +1 -1
- package/dist/object-manager.js +2 -1
- package/dist/object-manager.js.map +1 -1
- package/dist/persistence-driver.d.ts +8 -1
- package/dist/persistence-driver.d.ts.map +1 -1
- package/dist/query-builder.d.ts +2 -0
- package/dist/query-builder.d.ts.map +1 -1
- package/dist/query-builder.js +5 -0
- package/dist/query-builder.js.map +1 -1
- package/dist/sql-dialect.d.ts +11 -0
- package/dist/sql-dialect.d.ts.map +1 -0
- package/dist/sql-dialect.js +16 -0
- package/dist/sql-dialect.js.map +1 -0
- package/dist/type-coercer.d.ts.map +1 -1
- package/dist/type-coercer.js +63 -4
- package/dist/type-coercer.js.map +1 -1
- package/dist/validator-runner.d.ts.map +1 -1
- package/dist/validator-runner.js +102 -73
- package/dist/validator-runner.js.map +1 -1
- package/package.json +3 -3
- package/src/constraint-errors.ts +3 -1
- package/src/drivers/drizzle-driver.ts +47 -4
- package/src/drivers/kysely-driver.ts +43 -7
- package/src/drivers/mysql-support.ts +77 -0
- package/src/drizzle-fastify/filter-parser.ts +16 -7
- package/src/drizzle-fastify/index.ts +23 -26
- package/src/drizzle-fastify/mount-read-only.ts +10 -4
- package/src/drizzle-fastify/util.ts +23 -0
- package/src/extract-object.ts +18 -0
- package/src/hono/index.ts +21 -26
- package/src/hono/mount-read-only.ts +10 -4
- package/src/object-manager.ts +2 -1
- package/src/persistence-driver.ts +8 -1
- package/src/query-builder.ts +9 -0
- package/src/sql-dialect.ts +21 -0
- package/src/type-coercer.ts +55 -3
- package/src/validator-runner.ts +100 -70
package/dist/type-coercer.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Read/write value coercion at the persistence boundary.
|
|
2
2
|
//
|
|
3
3
|
// - SQLite has no native boolean: booleans are stored as 0/1 ints, so we map
|
|
4
|
-
// boolean↔int on the way in/out
|
|
4
|
+
// boolean↔int on the way in/out. MySQL's BOOLEAN is TINYINT(1) and mysql2 reads it
|
|
5
|
+
// back as 0/1, so it takes the same mapping.
|
|
5
6
|
// - JSONB-backed object/map fields: the driver (node-postgres) does NOT
|
|
6
7
|
// serialize a plain JS object to a jsonb column — it must arrive as a JSON
|
|
7
8
|
// string, or the write fails / writes "[object Object]". A `field.object`
|
|
@@ -12,11 +13,11 @@
|
|
|
12
13
|
// Date/timestamp coercion (ISO string ↔ Date) is deferred: pg accepts ISO
|
|
13
14
|
// strings for temporal columns directly, and the temporal read parsers pin the
|
|
14
15
|
// wire form.
|
|
15
|
-
import { TYPE_FIELD, FIELD_SUBTYPE_BOOLEAN, FIELD_SUBTYPE_ENUM, FIELD_SUBTYPE_OBJECT, FIELD_ATTR_STORAGE, FIELD_ATTR_DB_COLUMN_TYPE, FIELD_ATTR_INT_VALUE_MAP, STORAGE_JSONB, STORAGE_FLATTENED, DB_COLUMN_TYPE_JSONB, } from "@metaobjectsdev/metadata";
|
|
16
|
+
import { TYPE_FIELD, FIELD_SUBTYPE_BOOLEAN, FIELD_SUBTYPE_ENUM, FIELD_SUBTYPE_OBJECT, FIELD_SUBTYPE_TIMESTAMP, FIELD_ATTR_STORAGE, FIELD_ATTR_DB_COLUMN_TYPE, FIELD_ATTR_INT_VALUE_MAP, STORAGE_JSONB, STORAGE_FLATTENED, DB_COLUMN_TYPE_JSONB, } from "@metaobjectsdev/metadata";
|
|
16
17
|
export function coerceRowOnRead(entity, row, dialect) {
|
|
17
|
-
const hydrated = deserializeJsonbObjectFields(entity, row);
|
|
18
|
+
const hydrated = parseJsonTextArrays(entity, deserializeJsonbObjectFields(entity, row));
|
|
18
19
|
const decoded = decodeIntBackedEnums(entity, hydrated);
|
|
19
|
-
if (dialect !== "sqlite")
|
|
20
|
+
if (dialect !== "sqlite" && dialect !== "mysql")
|
|
20
21
|
return decoded;
|
|
21
22
|
return mapBooleansFromInt(entity, decoded);
|
|
22
23
|
}
|
|
@@ -125,6 +126,8 @@ export function coerceRowOnWrite(entity, row, dialect) {
|
|
|
125
126
|
// (SQLite has one integer storage class), so the symbol→int encode is not gated
|
|
126
127
|
// on the dialect the way the boolean mapping below is.
|
|
127
128
|
const encoded = encodeIntBackedEnums(entity, jsonbColumned);
|
|
129
|
+
if (dialect === "mysql")
|
|
130
|
+
return mapBooleansToInt(entity, isoTimestampsToDates(entity, encoded));
|
|
128
131
|
if (dialect !== "sqlite")
|
|
129
132
|
return encoded;
|
|
130
133
|
return mapBooleansToInt(entity, encoded);
|
|
@@ -232,4 +235,60 @@ function mapBooleansToInt(entity, row) {
|
|
|
232
235
|
}
|
|
233
236
|
return out;
|
|
234
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* MySQL: a `DATETIME` rejects the ISO wire form (`…T…Z` is ERROR 1292), so a
|
|
240
|
+
* `field.timestamp` string is handed to the driver as a `Date`. mysql2 writes it in the
|
|
241
|
+
* pool's `timezone` and reads it back the same way, so the instant round-trips; create the
|
|
242
|
+
* pool with `timezone: "Z"` to store the UTC wall clock, as the generated Drizzle tier and
|
|
243
|
+
* the Java port do.
|
|
244
|
+
*/
|
|
245
|
+
function isoTimestampsToDates(entity, row) {
|
|
246
|
+
let out = null;
|
|
247
|
+
// ADR-0039: resolving — a timestamp may be inherited from a base via extends.
|
|
248
|
+
for (const child of entity.children()) {
|
|
249
|
+
if (child.type !== TYPE_FIELD || child.subType !== FIELD_SUBTYPE_TIMESTAMP)
|
|
250
|
+
continue;
|
|
251
|
+
if (!(child.name in row))
|
|
252
|
+
continue;
|
|
253
|
+
const v = row[child.name];
|
|
254
|
+
if (typeof v !== "string")
|
|
255
|
+
continue;
|
|
256
|
+
const d = new Date(v);
|
|
257
|
+
if (Number.isNaN(d.getTime()))
|
|
258
|
+
continue;
|
|
259
|
+
out ??= { ...row };
|
|
260
|
+
out[child.name] = d;
|
|
261
|
+
}
|
|
262
|
+
return out ?? row;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* A scalar array (`field.string isArray`, …) read back as JSON TEXT — SQLite's JSON-in-TEXT
|
|
266
|
+
* column through a driver that does not parse it (Kysely) — becomes the array again. A
|
|
267
|
+
* value that is already an array (Postgres native arrays, mysql2's parsed JSON, Drizzle's
|
|
268
|
+
* JSON column modes) passes through.
|
|
269
|
+
*/
|
|
270
|
+
function parseJsonTextArrays(entity, row) {
|
|
271
|
+
let out = null;
|
|
272
|
+
// ADR-0039: resolving — an array field may be inherited via extends.
|
|
273
|
+
for (const child of entity.children()) {
|
|
274
|
+
if (child.type !== TYPE_FIELD || child.subType === FIELD_SUBTYPE_OBJECT)
|
|
275
|
+
continue;
|
|
276
|
+
if (!child.resolvedIsArray())
|
|
277
|
+
continue;
|
|
278
|
+
const v = row[child.name];
|
|
279
|
+
if (typeof v !== "string" || !v.startsWith("["))
|
|
280
|
+
continue;
|
|
281
|
+
try {
|
|
282
|
+
const parsed = JSON.parse(v);
|
|
283
|
+
if (!Array.isArray(parsed))
|
|
284
|
+
continue;
|
|
285
|
+
out ??= { ...row };
|
|
286
|
+
out[child.name] = parsed;
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
// Not JSON: leave the stored text as it is.
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return out ?? row;
|
|
293
|
+
}
|
|
235
294
|
//# sourceMappingURL=type-coercer.js.map
|
package/dist/type-coercer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-coercer.js","sourceRoot":"","sources":["../src/type-coercer.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,EAAE;AACF,8EAA8E;AAC9E,
|
|
1
|
+
{"version":3,"file":"type-coercer.js","sourceRoot":"","sources":["../src/type-coercer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator-runner.d.ts","sourceRoot":"","sources":["../src/validator-runner.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAYrE,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;IAClB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,QAAQ,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,GAAE,iBAAsB,GAC3B,gBAAgB,
|
|
1
|
+
{"version":3,"file":"validator-runner.d.ts","sourceRoot":"","sources":["../src/validator-runner.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAYrE,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;IAClB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,QAAQ,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,GAAE,iBAAsB,GAC3B,gBAAgB,CA6GlB"}
|
package/dist/validator-runner.js
CHANGED
|
@@ -72,7 +72,7 @@ export function runValidators(entity, data, opts = {}) {
|
|
|
72
72
|
if (field.subType === FIELD_SUBTYPE_OBJECT) {
|
|
73
73
|
const vo = resolveVoRef(field);
|
|
74
74
|
if (vo !== undefined) {
|
|
75
|
-
if (field.
|
|
75
|
+
if (field.resolvedIsArray() && !Array.isArray(value)) {
|
|
76
76
|
errors.push({
|
|
77
77
|
field: field.name, rule: "type",
|
|
78
78
|
message: `'${field.name}' must be an array of ${vo.name}`,
|
|
@@ -80,7 +80,7 @@ export function runValidators(entity, data, opts = {}) {
|
|
|
80
80
|
});
|
|
81
81
|
continue;
|
|
82
82
|
}
|
|
83
|
-
const elements = field.
|
|
83
|
+
const elements = field.resolvedIsArray() ? value : [value];
|
|
84
84
|
elements.forEach((el, i) => {
|
|
85
85
|
if (typeof el !== "object" || el === null || Array.isArray(el)) {
|
|
86
86
|
errors.push({
|
|
@@ -95,7 +95,7 @@ export function runValidators(entity, data, opts = {}) {
|
|
|
95
95
|
for (const e of sub.errors) {
|
|
96
96
|
errors.push({
|
|
97
97
|
...e,
|
|
98
|
-
field: field.
|
|
98
|
+
field: field.resolvedIsArray() ? `${field.name}[${i}].${e.field}` : `${field.name}.${e.field}`,
|
|
99
99
|
});
|
|
100
100
|
}
|
|
101
101
|
}
|
|
@@ -103,81 +103,26 @@ export function runValidators(entity, data, opts = {}) {
|
|
|
103
103
|
}
|
|
104
104
|
continue;
|
|
105
105
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
message: typeError,
|
|
112
|
-
expected: field.subType,
|
|
113
|
-
received: typeof value,
|
|
114
|
-
});
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
const maxLen = resolveMaxLength(field);
|
|
118
|
-
const minLen = resolveMinLength(field);
|
|
119
|
-
if (typeof value === "string") {
|
|
120
|
-
if (maxLen !== undefined && value.length > maxLen) {
|
|
121
|
-
errors.push({
|
|
122
|
-
field: field.name,
|
|
123
|
-
rule: "length",
|
|
124
|
-
message: `'${field.name}' must be at most ${maxLen} chars (got ${value.length})`,
|
|
125
|
-
expected: { max: maxLen },
|
|
126
|
-
received: value.length,
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
// FR-036 Pin 1: a @required string is non-empty. The effective floor is
|
|
130
|
-
// max(@min, 1) so the runtime OM rejects "" for a required string exactly as
|
|
131
|
-
// the generated Zod InsertSchema (.min(1)) does — the two enforcement surfaces
|
|
132
|
-
// stay in lockstep. A non-required field keeps its authored @min.
|
|
133
|
-
const effectiveMin = Math.max(minLen ?? 0, required ? 1 : 0);
|
|
134
|
-
if (effectiveMin > 0 && value.length < effectiveMin) {
|
|
135
|
-
errors.push({
|
|
136
|
-
field: field.name,
|
|
137
|
-
rule: "length",
|
|
138
|
-
message: `'${field.name}' must be at least ${effectiveMin} chars (got ${value.length})`,
|
|
139
|
-
expected: { min: effectiveMin },
|
|
140
|
-
received: value.length,
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
// ADR-0039: effective children — a validator may be inherited via extends.
|
|
145
|
-
for (const child of field.children()) {
|
|
146
|
-
if (child.type !== TYPE_VALIDATOR)
|
|
147
|
-
continue;
|
|
148
|
-
if (child.subType !== VALIDATOR_SUBTYPE_REGEX)
|
|
149
|
-
continue;
|
|
150
|
-
// ADR-0039: effective attr — @pattern may be inherited.
|
|
151
|
-
const pattern = child.attr(VALIDATOR_ATTR_PATTERN);
|
|
152
|
-
if (typeof pattern !== "string")
|
|
153
|
-
continue;
|
|
154
|
-
if (typeof value !== "string")
|
|
155
|
-
continue;
|
|
156
|
-
let regex;
|
|
157
|
-
try {
|
|
158
|
-
// FR-036 Pin 2: validator.regex @pattern is FULL-MATCH — anchor as ^(?:…)$
|
|
159
|
-
// so the runtime OM matches the generated Zod schema's full-match semantic.
|
|
160
|
-
regex = new RegExp(`^(?:${pattern})$`);
|
|
161
|
-
}
|
|
162
|
-
catch {
|
|
106
|
+
// A scalar array (`field.string isArray`, …) — stored as a native array or a JSON array.
|
|
107
|
+
// Each element is checked against the element rules; an element error names its index,
|
|
108
|
+
// as the value-object branch above does. ADR-0039: resolving `isArray`.
|
|
109
|
+
if (field.resolvedIsArray()) {
|
|
110
|
+
if (!Array.isArray(value)) {
|
|
163
111
|
errors.push({
|
|
164
|
-
field: field.name,
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
expected: pattern,
|
|
112
|
+
field: field.name, rule: "type",
|
|
113
|
+
message: `'${field.name}' must be an array`,
|
|
114
|
+
expected: "array", received: typeof value,
|
|
168
115
|
});
|
|
169
116
|
continue;
|
|
170
117
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
received: value,
|
|
178
|
-
});
|
|
179
|
-
}
|
|
118
|
+
value.forEach((el, i) => {
|
|
119
|
+
if (el === null || el === undefined)
|
|
120
|
+
return;
|
|
121
|
+
errors.push(...scalarErrors(field, el, false, `${field.name}[${i}]`));
|
|
122
|
+
});
|
|
123
|
+
continue;
|
|
180
124
|
}
|
|
125
|
+
errors.push(...scalarErrors(field, value, required, field.name));
|
|
181
126
|
}
|
|
182
127
|
return errors.length === 0 ? { ok: true } : { ok: false, errors };
|
|
183
128
|
}
|
|
@@ -268,4 +213,88 @@ function checkType(subType, value) {
|
|
|
268
213
|
}
|
|
269
214
|
return null;
|
|
270
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* The type, length and regex errors for one scalar value of `field` — the whole field
|
|
218
|
+
* value, or one element of a scalar array (then `required` is false: element presence is not
|
|
219
|
+
* the field's `@required`, and `label` is `name[i]`).
|
|
220
|
+
*/
|
|
221
|
+
function scalarErrors(field, value, required, label) {
|
|
222
|
+
const errors = [];
|
|
223
|
+
const typeError = checkType(field.subType, value);
|
|
224
|
+
if (typeError !== null) {
|
|
225
|
+
errors.push({
|
|
226
|
+
field: label,
|
|
227
|
+
rule: "type",
|
|
228
|
+
message: typeError,
|
|
229
|
+
expected: field.subType,
|
|
230
|
+
received: typeof value,
|
|
231
|
+
});
|
|
232
|
+
return errors;
|
|
233
|
+
}
|
|
234
|
+
const maxLen = resolveMaxLength(field);
|
|
235
|
+
const minLen = resolveMinLength(field);
|
|
236
|
+
if (typeof value === "string") {
|
|
237
|
+
if (maxLen !== undefined && value.length > maxLen) {
|
|
238
|
+
errors.push({
|
|
239
|
+
field: label,
|
|
240
|
+
rule: "length",
|
|
241
|
+
message: `'${label}' must be at most ${maxLen} chars (got ${value.length})`,
|
|
242
|
+
expected: { max: maxLen },
|
|
243
|
+
received: value.length,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
// FR-036 Pin 1: a @required string is non-empty. The effective floor is
|
|
247
|
+
// max(@min, 1) so the runtime OM rejects "" for a required string exactly as
|
|
248
|
+
// the generated Zod InsertSchema (.min(1)) does — the two enforcement surfaces
|
|
249
|
+
// stay in lockstep. A non-required field keeps its authored @min.
|
|
250
|
+
const effectiveMin = Math.max(minLen ?? 0, required ? 1 : 0);
|
|
251
|
+
if (effectiveMin > 0 && value.length < effectiveMin) {
|
|
252
|
+
errors.push({
|
|
253
|
+
field: label,
|
|
254
|
+
rule: "length",
|
|
255
|
+
message: `'${label}' must be at least ${effectiveMin} chars (got ${value.length})`,
|
|
256
|
+
expected: { min: effectiveMin },
|
|
257
|
+
received: value.length,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// ADR-0039: effective children — a validator may be inherited via extends.
|
|
262
|
+
for (const child of field.children()) {
|
|
263
|
+
if (child.type !== TYPE_VALIDATOR)
|
|
264
|
+
continue;
|
|
265
|
+
if (child.subType !== VALIDATOR_SUBTYPE_REGEX)
|
|
266
|
+
continue;
|
|
267
|
+
// ADR-0039: effective attr — @pattern may be inherited.
|
|
268
|
+
const pattern = child.attr(VALIDATOR_ATTR_PATTERN);
|
|
269
|
+
if (typeof pattern !== "string")
|
|
270
|
+
continue;
|
|
271
|
+
if (typeof value !== "string")
|
|
272
|
+
continue;
|
|
273
|
+
let regex;
|
|
274
|
+
try {
|
|
275
|
+
// FR-036 Pin 2: validator.regex @pattern is FULL-MATCH — anchor as ^(?:…)$
|
|
276
|
+
// so the runtime OM matches the generated Zod schema's full-match semantic.
|
|
277
|
+
regex = new RegExp(`^(?:${pattern})$`);
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
errors.push({
|
|
281
|
+
field: label,
|
|
282
|
+
rule: "regex",
|
|
283
|
+
message: `'${label}' has an invalid validator pattern: ${pattern}`,
|
|
284
|
+
expected: pattern,
|
|
285
|
+
});
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (!regex.test(value)) {
|
|
289
|
+
errors.push({
|
|
290
|
+
field: label,
|
|
291
|
+
rule: "regex",
|
|
292
|
+
message: `'${label}' does not match required pattern`,
|
|
293
|
+
expected: pattern,
|
|
294
|
+
received: value,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return errors;
|
|
299
|
+
}
|
|
271
300
|
//# sourceMappingURL=validator-runner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator-runner.js","sourceRoot":"","sources":["../src/validator-runner.ts"],"names":[],"mappings":"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
|
|
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": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
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": "1.0.
|
|
68
|
-
"@metaobjectsdev/render": "1.0.
|
|
67
|
+
"@metaobjectsdev/metadata": "1.0.10",
|
|
68
|
+
"@metaobjectsdev/render": "1.0.10",
|
|
69
69
|
"qs": "^6.13.0"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
package/src/constraint-errors.ts
CHANGED
|
@@ -63,11 +63,12 @@ export function classifyConstraintError(err: unknown): ConstraintFailure | undef
|
|
|
63
63
|
// Postgres SQLSTATE 23xxx — integrity constraint violation.
|
|
64
64
|
const kind: ConstraintKind | undefined =
|
|
65
65
|
haystack.includes("23503") ||
|
|
66
|
-
haystack.includes("FOREIGN KEY") ||
|
|
66
|
+
haystack.includes("FOREIGN KEY") || // also MySQL 1451/1452 message text
|
|
67
67
|
haystack.includes("SQLITE_CONSTRAINT_FOREIGNKEY") // extended code: no space
|
|
68
68
|
? "foreign_key"
|
|
69
69
|
: haystack.includes("23505") ||
|
|
70
70
|
haystack.includes("SQLITE_CONSTRAINT_UNIQUE") ||
|
|
71
|
+
haystack.includes("ER_DUP_ENTRY") || // MySQL 1062
|
|
71
72
|
haystack.includes("UNIQUE CONSTRAINT")
|
|
72
73
|
? "unique"
|
|
73
74
|
: haystack.includes("23514") ||
|
|
@@ -76,6 +77,7 @@ export function classifyConstraintError(err: unknown): ConstraintFailure | undef
|
|
|
76
77
|
? "check"
|
|
77
78
|
: haystack.includes("23502") ||
|
|
78
79
|
haystack.includes("SQLITE_CONSTRAINT_NOTNULL") ||
|
|
80
|
+
haystack.includes("ER_BAD_NULL_ERROR") || // MySQL 1048
|
|
79
81
|
haystack.includes("NOT NULL")
|
|
80
82
|
? "not_null"
|
|
81
83
|
: undefined;
|
|
@@ -41,10 +41,11 @@ import type {
|
|
|
41
41
|
UpdateManySpec,
|
|
42
42
|
DeleteSpec,
|
|
43
43
|
DeleteManySpec,
|
|
44
|
-
WhereClause,
|
|
44
|
+
WhereClause, PrimitiveValue,
|
|
45
45
|
Row,
|
|
46
46
|
} from "../persistence-driver.js";
|
|
47
47
|
import { ConstraintViolationError } from "../errors.js";
|
|
48
|
+
import { insertedKey, mysqlConstraintKind } from "./mysql-support.js";
|
|
48
49
|
|
|
49
50
|
// ---------------------------------------------------------------------------
|
|
50
51
|
// Public surface
|
|
@@ -71,7 +72,8 @@ export interface DrizzleDriverOptions {
|
|
|
71
72
|
* JS variable name doesn't have to match the SQL table name.
|
|
72
73
|
*/
|
|
73
74
|
schema: Record<string, unknown>;
|
|
74
|
-
|
|
75
|
+
/** `mysql`: a `drizzle-orm/mysql2` instance. */
|
|
76
|
+
dialect: "sqlite" | "postgres" | "mysql";
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
export interface DrizzleDriverPublic extends PersistenceDriver {
|
|
@@ -116,7 +118,7 @@ function isDrizzleTable(v: unknown): boolean {
|
|
|
116
118
|
function makeDrizzleDriver(
|
|
117
119
|
db: AnyDrizzleDB,
|
|
118
120
|
tables: TableIndex,
|
|
119
|
-
dialect: "sqlite" | "postgres",
|
|
121
|
+
dialect: "sqlite" | "postgres" | "mysql",
|
|
120
122
|
): DrizzleDriverPublic {
|
|
121
123
|
function requireTable(name: string): AnyTable {
|
|
122
124
|
const t = tables.get(name);
|
|
@@ -207,6 +209,24 @@ function makeDrizzleDriver(
|
|
|
207
209
|
return out;
|
|
208
210
|
}
|
|
209
211
|
|
|
212
|
+
// MySQL has no RETURNING: insert, then read the row back by its key.
|
|
213
|
+
async function insertAndReadBack(table: AnyTable, tableName: string, values: Row, returning: string[], key: string[] | undefined): Promise<Row> {
|
|
214
|
+
const result = await db.insert(table).values(toJsValues(table, values));
|
|
215
|
+
const header = (Array.isArray(result) ? result[0] : result) as { insertId?: number | bigint } | undefined;
|
|
216
|
+
const keyValues = key !== undefined && key.length > 0 ? insertedKey(key, values, header?.insertId) : undefined;
|
|
217
|
+
if (keyValues === undefined) {
|
|
218
|
+
throw new Error(`drizzleDriver.insert: cannot read back the row inserted into '${tableName}' (no primary-key value)`);
|
|
219
|
+
}
|
|
220
|
+
const where: WhereClause = {
|
|
221
|
+
kind: "and",
|
|
222
|
+
clauses: Object.entries(keyValues).map(([column, value]) => ({ kind: "eq" as const, column, value: value as PrimitiveValue })),
|
|
223
|
+
};
|
|
224
|
+
const selectArg = buildSelectMap(table, returning);
|
|
225
|
+
const rows = (await db.select(selectArg).from(table).where(applyWhere(table, where, table)).limit(1)) as Row[];
|
|
226
|
+
if (!rows[0]) throw new Error(`drizzleDriver.insert: no row found after insert into '${tableName}'`);
|
|
227
|
+
return toDbKeyedRow(table, jsKeyedFromSelect(rows[0], selectArg));
|
|
228
|
+
}
|
|
229
|
+
|
|
210
230
|
return {
|
|
211
231
|
db,
|
|
212
232
|
dialect,
|
|
@@ -250,6 +270,7 @@ function makeDrizzleDriver(
|
|
|
250
270
|
async insert(spec: InsertSpec): Promise<Row> {
|
|
251
271
|
const table = requireTable(spec.table);
|
|
252
272
|
try {
|
|
273
|
+
if (dialect === "mysql") return await insertAndReadBack(table, spec.table, spec.values, spec.returning, spec.key);
|
|
253
274
|
const result = await db
|
|
254
275
|
.insert(table)
|
|
255
276
|
.values(toJsValues(table, spec.values))
|
|
@@ -267,6 +288,11 @@ function makeDrizzleDriver(
|
|
|
267
288
|
async insertMany(spec: InsertManySpec): Promise<Row[]> {
|
|
268
289
|
const table = requireTable(spec.table);
|
|
269
290
|
try {
|
|
291
|
+
if (dialect === "mysql") {
|
|
292
|
+
const out: Row[] = [];
|
|
293
|
+
for (const row of spec.rows) out.push(await insertAndReadBack(table, spec.table, row, spec.returning, spec.key));
|
|
294
|
+
return out;
|
|
295
|
+
}
|
|
270
296
|
const values = spec.rows.map((r) => toJsValues(table, r));
|
|
271
297
|
const rows = (await db
|
|
272
298
|
.insert(table)
|
|
@@ -286,6 +312,14 @@ function makeDrizzleDriver(
|
|
|
286
312
|
let q = db.update(table).set(toJsValues(table, spec.values));
|
|
287
313
|
const w = applyWhere(table, spec.where, table);
|
|
288
314
|
if (w !== undefined) q = q.where(w);
|
|
315
|
+
if (dialect === "mysql") {
|
|
316
|
+
await q;
|
|
317
|
+
const selectArg = buildSelectMap(table, spec.returning);
|
|
318
|
+
let s = db.select(selectArg).from(table);
|
|
319
|
+
if (w !== undefined) s = s.where(w);
|
|
320
|
+
const found = ((await s.limit(1)) as Row[])[0];
|
|
321
|
+
return found ? toDbKeyedRow(table, jsKeyedFromSelect(found, selectArg)) : null;
|
|
322
|
+
}
|
|
289
323
|
const rows = (await q.returning(buildSelectMap(table, spec.returning))) as Row[];
|
|
290
324
|
const first = rows[0];
|
|
291
325
|
return first
|
|
@@ -378,6 +412,10 @@ function extractRowCount(result: unknown): number {
|
|
|
378
412
|
// Drizzle's update/delete return shape varies by backend. We support the
|
|
379
413
|
// common shapes; unknown shapes fall through to 0.
|
|
380
414
|
if (typeof result === "number") return result;
|
|
415
|
+
// mysql2: `[ResultSetHeader, fields]`, the count on the header.
|
|
416
|
+
if (Array.isArray(result) && typeof (result[0] as { affectedRows?: unknown } | undefined)?.affectedRows === "number") {
|
|
417
|
+
return (result[0] as { affectedRows: number }).affectedRows;
|
|
418
|
+
}
|
|
381
419
|
if (Array.isArray(result)) return result.length;
|
|
382
420
|
if (result && typeof result === "object") {
|
|
383
421
|
const obj = result as { rowsAffected?: number | bigint; rowCount?: number };
|
|
@@ -427,11 +465,16 @@ function buildExpression(w: WhereClause, cols: Map<string, AnyColumn>): unknown
|
|
|
427
465
|
// type regardless of which driver they wired up.
|
|
428
466
|
// ---------------------------------------------------------------------------
|
|
429
467
|
|
|
430
|
-
function mapDriverError(err: unknown, table: string, dialect: "sqlite" | "postgres"): unknown {
|
|
468
|
+
function mapDriverError(err: unknown, table: string, dialect: "sqlite" | "postgres" | "mysql"): unknown {
|
|
431
469
|
if (!(err instanceof Error)) return err;
|
|
432
470
|
const msg = err.message;
|
|
433
471
|
const code = (err as { code?: string }).code;
|
|
434
472
|
|
|
473
|
+
if (dialect === "mysql") {
|
|
474
|
+
const kind = mysqlConstraintKind(err);
|
|
475
|
+
return kind === null ? err : new ConstraintViolationError(msg, { kind, table, cause: err });
|
|
476
|
+
}
|
|
477
|
+
|
|
435
478
|
if (dialect === "sqlite") {
|
|
436
479
|
const kind = sqliteConstraintKind(code, msg);
|
|
437
480
|
if (kind !== null) {
|