@metaobjectsdev/runtime-ts 1.0.12 → 1.1.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.
- package/dist/decimal-wire.d.ts +54 -0
- package/dist/decimal-wire.d.ts.map +1 -0
- package/dist/decimal-wire.js +158 -0
- package/dist/decimal-wire.js.map +1 -0
- package/dist/drizzle-fastify/filter-allowlist.d.ts +4 -2
- package/dist/drizzle-fastify/filter-allowlist.d.ts.map +1 -1
- package/dist/drizzle-fastify/filter-allowlist.js +2 -1
- package/dist/drizzle-fastify/filter-allowlist.js.map +1 -1
- package/dist/drizzle-fastify/filter-parser.d.ts.map +1 -1
- package/dist/drizzle-fastify/filter-parser.js +23 -9
- package/dist/drizzle-fastify/filter-parser.js.map +1 -1
- package/dist/drizzle-fastify/filter-value-format.d.ts.map +1 -1
- package/dist/drizzle-fastify/filter-value-format.js +4 -1
- package/dist/drizzle-fastify/filter-value-format.js.map +1 -1
- package/dist/drizzle-fastify/index.d.ts +8 -0
- package/dist/drizzle-fastify/index.d.ts.map +1 -1
- package/dist/drizzle-fastify/index.js +4 -2
- package/dist/drizzle-fastify/index.js.map +1 -1
- package/dist/drizzle-fastify/mount-m2m.d.ts +2 -0
- package/dist/drizzle-fastify/mount-m2m.d.ts.map +1 -1
- package/dist/drizzle-fastify/mount-m2m.js +2 -1
- package/dist/drizzle-fastify/mount-m2m.js.map +1 -1
- package/dist/drizzle-fastify/mount-read-only.d.ts +25 -1
- package/dist/drizzle-fastify/mount-read-only.d.ts.map +1 -1
- package/dist/drizzle-fastify/mount-read-only.js +43 -28
- package/dist/drizzle-fastify/mount-read-only.js.map +1 -1
- package/dist/extract-object.js +5 -7
- package/dist/extract-object.js.map +1 -1
- package/dist/hono/index.d.ts +8 -0
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/index.js +4 -2
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/mount-read-only.d.ts +25 -1
- package/dist/hono/mount-read-only.d.ts.map +1 -1
- package/dist/hono/mount-read-only.js +51 -36
- package/dist/hono/mount-read-only.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/n2m-resolver.d.ts.map +1 -1
- package/dist/n2m-resolver.js +4 -3
- package/dist/n2m-resolver.js.map +1 -1
- package/dist/net-format.d.ts +8 -0
- package/dist/net-format.d.ts.map +1 -0
- package/dist/net-format.js +34 -0
- package/dist/net-format.js.map +1 -0
- package/dist/object-manager.d.ts +20 -7
- package/dist/object-manager.d.ts.map +1 -1
- package/dist/object-manager.js +68 -13
- package/dist/object-manager.js.map +1 -1
- package/dist/query-builder.d.ts.map +1 -1
- package/dist/query-builder.js +11 -2
- package/dist/query-builder.js.map +1 -1
- package/dist/relation-resolver.d.ts.map +1 -1
- package/dist/relation-resolver.js +11 -11
- package/dist/relation-resolver.js.map +1 -1
- package/dist/type-coercer.d.ts +1 -1
- package/dist/type-coercer.d.ts.map +1 -1
- package/dist/type-coercer.js +114 -5
- package/dist/type-coercer.js.map +1 -1
- package/dist/validator-runner.d.ts.map +1 -1
- package/dist/validator-runner.js +192 -35
- package/dist/validator-runner.js.map +1 -1
- package/package.json +3 -3
- package/src/decimal-wire.ts +154 -0
- package/src/drizzle-fastify/filter-allowlist.ts +5 -1
- package/src/drizzle-fastify/filter-parser.ts +22 -9
- package/src/drizzle-fastify/filter-value-format.ts +4 -0
- package/src/drizzle-fastify/index.ts +11 -2
- package/src/drizzle-fastify/mount-m2m.ts +4 -1
- package/src/drizzle-fastify/mount-read-only.ts +68 -31
- package/src/extract-object.ts +5 -7
- package/src/hono/index.ts +11 -2
- package/src/hono/mount-read-only.ts +76 -37
- package/src/index.ts +2 -1
- package/src/n2m-resolver.ts +4 -2
- package/src/net-format.ts +37 -0
- package/src/object-manager.ts +80 -18
- package/src/query-builder.ts +14 -1
- package/src/relation-resolver.ts +15 -14
- package/src/type-coercer.ts +116 -5
- package/src/validator-runner.ts +195 -32
|
@@ -7,6 +7,7 @@ import qs from "qs";
|
|
|
7
7
|
import { parseFilterParams, parsePageBound, RAW_VIEW_MAX_LIMIT, FilterParseError } from "../drizzle-fastify/filter-parser.js";
|
|
8
8
|
import { isTruthyFlag, coerceIdForColumn, rawIdLiteral, contractErrorCode, viewBaseConfig } from "../drizzle-fastify/util.js";
|
|
9
9
|
import { timestampWire } from "../timestamp-wire.js";
|
|
10
|
+
import { withDecimals } from "../decimal-wire.js";
|
|
10
11
|
// An unexpected error on a mounted route answers `500 { error: "internal" }`.
|
|
11
12
|
import { guardRoute } from "./route-guard.js";
|
|
12
13
|
function resolveViewName(view) {
|
|
@@ -78,10 +79,12 @@ async function rawRows(db, dialect, query) {
|
|
|
78
79
|
export function mountReadOnlyCrudRoutes(opts) {
|
|
79
80
|
const { app, path, db, view, filterAllowlist, sortAllowlist, dialect } = opts;
|
|
80
81
|
const idCol = opts.idColumn ?? "id";
|
|
82
|
+
const itemRoutes = opts.itemRoutes !== false;
|
|
81
83
|
const viewName = resolveViewName(view);
|
|
82
84
|
const useRawSql = isEmptyColumnView(view) && !!viewName;
|
|
83
85
|
// The raw-SQL branch has no declared columns, so nothing names a timestamp there.
|
|
84
|
-
const
|
|
86
|
+
const timestamps = timestampWire(view);
|
|
87
|
+
const toWire = withDecimals(timestamps, opts.decimalColumns);
|
|
85
88
|
// ── List ──────────────────────────────────────────────────────────────────
|
|
86
89
|
app.get(path, guardRoute(async (c) => {
|
|
87
90
|
try {
|
|
@@ -152,43 +155,55 @@ export function mountReadOnlyCrudRoutes(opts) {
|
|
|
152
155
|
throw err;
|
|
153
156
|
}
|
|
154
157
|
}));
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
158
|
+
// A keyless object (`itemRoutes: false`) has nothing to address by id: no `/:id` route
|
|
159
|
+
// of any verb, so the framework's own 404 answers.
|
|
160
|
+
if (itemRoutes) {
|
|
161
|
+
// ── Get by ID ─────────────────────────────────────────────────────────────
|
|
162
|
+
app.get(`${path}/:id`, guardRoute(async (c) => {
|
|
163
|
+
const id = c.req.param("id") ?? "";
|
|
164
|
+
if (useRawSql) {
|
|
165
|
+
// biome-ignore lint/suspicious/noExplicitAny: dynamic raw result
|
|
166
|
+
const rows = (await rawRows(db, dialect, sql.raw(`SELECT * FROM ${quoteIdent(dialect, viewName)} WHERE ${quoteIdent(dialect, idCol)} = ${rawIdLiteral(id)} LIMIT 1`)));
|
|
167
|
+
const row = rows[0] ? camelizeRow(rows[0]) : undefined;
|
|
168
|
+
return row ? c.json(row) : c.json({ error: "not_found" }, 404);
|
|
169
|
+
}
|
|
170
|
+
// biome-ignore lint/suspicious/noExplicitAny: Drizzle view column ref
|
|
171
|
+
const colRef = view[idCol];
|
|
172
|
+
// No column under `idColumn`: there is nothing to compare the id against, and a query
|
|
173
|
+
// with no WHERE would answer with the view's first row. No row is addressable.
|
|
174
|
+
if (colRef === undefined) {
|
|
175
|
+
return c.json({ error: "not_found" }, 404);
|
|
176
|
+
}
|
|
177
|
+
// Compare against the PK's real type — a uuid/text key must NOT go through Number().
|
|
178
|
+
const idValue = coerceIdForColumn(colRef, id);
|
|
179
|
+
if (idValue === undefined) {
|
|
180
|
+
return c.json({ error: "invalid_id" }, 400);
|
|
181
|
+
}
|
|
182
|
+
// `.get()` is likewise libsql/better-sqlite3-only; `.limit(1)` + await + [0]
|
|
183
|
+
// is the portable single-row read (#286).
|
|
184
|
+
const rows = await db
|
|
185
|
+
.select()
|
|
186
|
+
.from(view)
|
|
187
|
+
.where(eq(colRef, idValue))
|
|
188
|
+
.limit(1);
|
|
189
|
+
const row = rows[0];
|
|
190
|
+
return row ? c.json(toWire(row)) : c.json({ error: "not_found" }, 404);
|
|
191
|
+
}));
|
|
192
|
+
}
|
|
181
193
|
// ── Mutations explicitly rejected (405) ───────────────────────────────────
|
|
182
|
-
const
|
|
194
|
+
const resource = opts.resource ?? "projection";
|
|
195
|
+
const reject = (c) => c.json({ error: "method_not_allowed", message: `${c.req.method} is not supported on a ${resource} (read-only).` }, 405);
|
|
183
196
|
// biome-ignore lint/suspicious/noExplicitAny: cross-version Hono typing
|
|
184
197
|
app.post(path, reject);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
198
|
+
if (itemRoutes) {
|
|
199
|
+
// biome-ignore lint/suspicious/noExplicitAny: cross-version Hono typing
|
|
200
|
+
app.patch(`${path}/:id`, reject);
|
|
201
|
+
// PUT too — the writable mount serves it, so a projection must reject it rather
|
|
202
|
+
// than 404, which would deny a resource that answers GET on the same path.
|
|
203
|
+
// biome-ignore lint/suspicious/noExplicitAny: cross-version Hono typing
|
|
204
|
+
app.put(`${path}/:id`, reject);
|
|
205
|
+
// biome-ignore lint/suspicious/noExplicitAny: cross-version Hono typing
|
|
206
|
+
app.delete(`${path}/:id`, reject);
|
|
207
|
+
}
|
|
193
208
|
}
|
|
194
209
|
//# sourceMappingURL=mount-read-only.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount-read-only.js","sourceRoot":"","sources":["../../src/hono/mount-read-only.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,8EAA8E;AAC9E,4EAA4E;AAE5E,OAAO,EAAE,UAAU,EAAmB,MAAM,mBAAmB,CAAC;AAEhE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAK9H,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC9H,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,8EAA8E;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"mount-read-only.js","sourceRoot":"","sources":["../../src/hono/mount-read-only.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,8 @@ export type { ObjectManagerOptions, ReadOpts, WriteOpts } from "./object-manager
|
|
|
3
3
|
export type { PersistenceDriver, Dialect, Row, PrimitiveValue, WhereClause, OrderBy, SelectSpec, CountSpec, InsertSpec, InsertManySpec, UpdateSpec, UpdateManySpec, DeleteSpec, DeleteManySpec, } from "./persistence-driver.js";
|
|
4
4
|
export type { Filter, FilterValue, QueryOpts } from "./query-builder.js";
|
|
5
5
|
export type { FieldViewSpec, EntityViewSpec } from "./view.js";
|
|
6
|
-
export
|
|
6
|
+
export { runValidators } from "./validator-runner.js";
|
|
7
|
+
export type { ValidationResult, RunValidatorsOpts } from "./validator-runner.js";
|
|
7
8
|
export type { ValidationFailure } from "./errors.js";
|
|
8
9
|
export { RuntimeError, ValidationError, NotFoundError, ConstraintViolationError, MetadataError, UnsafeNameError, } from "./errors.js";
|
|
9
10
|
export { extractObject, extractSchemaFor, assemble, MAX_NEST_DEPTH, } from "./extract-object.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErF,YAAY,EACV,iBAAiB,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,EAC/C,WAAW,EAAE,OAAO,EACpB,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EACjD,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,GACvD,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEzE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErF,YAAY,EACV,iBAAiB,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,EAC/C,WAAW,EAAE,OAAO,EACpB,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EACjD,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,GACvD,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEzE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACjF,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,aAAa,EACb,wBAAwB,EACxB,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAC;AAKrB,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,QAAQ,EACR,cAAc,GACf,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACpI,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAGjJ,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,cAAc,EACnB,KAAK,iBAAiB,GACvB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { ObjectManager } from "./object-manager.js";
|
|
2
|
+
export { runValidators } from "./validator-runner.js";
|
|
2
3
|
export { RuntimeError, ValidationError, NotFoundError, ConstraintViolationError, MetadataError, UnsafeNameError, } from "./errors.js";
|
|
3
4
|
// FR-010 Phase B — metadata-driven runtime extract. The descriptor-driven extract ENGINE lives in
|
|
4
5
|
// the metadata-free @metaobjectsdev/render package; this bridge wires it to the Phase A runtime
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAcpD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,aAAa,EACb,wBAAwB,EACxB,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,kGAAkG;AAClG,gGAAgG;AAChG,8FAA8F;AAC9F,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,QAAQ,EACR,cAAc,GACf,MAAM,qBAAqB,CAAC;AAE7B,sDAAsD;AACtD,8EAA8E;AAC9E,6EAA6E;AAC7E,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGpI,oFAAoF;AACpF,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,GAGtB,MAAM,wBAAwB,CAAC;AAEhC,2DAA2D;AAC3D,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"n2m-resolver.d.ts","sourceRoot":"","sources":["../src/n2m-resolver.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAwB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"n2m-resolver.d.ts","sourceRoot":"","sources":["../src/n2m-resolver.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAwB,MAAM,0BAA0B,CAAC;AAarG,OAAO,KAAK,EAAE,UAAU,EAA+B,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAE5F,MAAM,WAAW,aAAa;IAC5B,8FAA8F;IAC9F,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,8FAA8F;IAC9F,eAAe,EAAE,MAAM,CAAC;IACxB,8FAA8F;IAC9F,eAAe,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,UAAU,CAAC;IACrB,gFAAgF;IAChF,cAAc,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,UAAU,GAAG,IAAI,CAAC;CACxD;AAED,MAAM,MAAM,cAAc,GAAG,aAAa,CAAC;AAE3C,uGAAuG;AACvG,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,QAAQ,EACtB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,QAAQ,GACb,aAAa,GAAG,IAAI,CA0CtB;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,aAAa,EACnB,YAAY,EAAE,GAAG,EACjB,IAAI,EAAE,QAAQ,EACd,QAAQ,GAAE,oBAAqD,GAC9D,aAAa,CAEf;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,aAAa,EACnB,aAAa,EAAE,GAAG,EAAE,EACpB,IAAI,EAAE,QAAQ,EACd,QAAQ,GAAE,oBAAqD,GAC9D,cAAc,CAEhB;AA0HD,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EACvC,QAAQ,GAAE,oBAAqD,GAC9D,MAAM,CAKR"}
|
package/dist/n2m-resolver.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
// 3. Symmetric self-join (`@symmetric: true`): single-row storage, union on
|
|
18
18
|
// read — junction WHERE sourceField (IN|=) id OR targetField (IN|=) id;
|
|
19
19
|
// for each row the related id is whichever FK column is NOT the source id.
|
|
20
|
-
import { TYPE_OBJECT, TYPE_FIELD, TYPE_RELATIONSHIP, RELATIONSHIP_ATTR_CARDINALITY, RELATIONSHIP_ATTR_OBJECT_REF, RELATIONSHIP_ATTR_THROUGH, CARDINALITY_MANY, DEFAULT_COLUMN_NAMING_STRATEGY, resolveColumnName, deriveM2MFields, } from "@metaobjectsdev/metadata";
|
|
20
|
+
import { TYPE_OBJECT, TYPE_FIELD, TYPE_RELATIONSHIP, RELATIONSHIP_ATTR_CARDINALITY, RELATIONSHIP_ATTR_OBJECT_REF, RELATIONSHIP_ATTR_THROUGH, refTarget, CARDINALITY_MANY, DEFAULT_COLUMN_NAMING_STRATEGY, resolveColumnName, deriveM2MFields, } from "@metaobjectsdev/metadata";
|
|
21
21
|
import { MetadataError } from "./errors.js";
|
|
22
22
|
import { buildSelectSpec, resolvePkFields } from "./query-builder.js";
|
|
23
23
|
/** Returns null if the named relationship is not M:N — caller should try resolveRelationDescriptor. */
|
|
@@ -34,8 +34,9 @@ export function resolveN2mDescriptor(sourceEntity, relationName, root) {
|
|
|
34
34
|
if (child.attr(RELATIONSHIP_ATTR_THROUGH) === undefined)
|
|
35
35
|
continue; // 1:N many — not M:N.
|
|
36
36
|
const rel = child;
|
|
37
|
-
|
|
38
|
-
const
|
|
37
|
+
// ADR-0059 R7: the loader bound @objectRef/@through once; read those targets.
|
|
38
|
+
const targetEntityName = refTarget(rel, RELATIONSHIP_ATTR_OBJECT_REF)?.name;
|
|
39
|
+
const joinEntityName = refTarget(rel, RELATIONSHIP_ATTR_THROUGH)?.name;
|
|
39
40
|
if (!targetEntityName || !joinEntityName) {
|
|
40
41
|
throw new MetadataError(`M:N relationship '${relationName}' on '${sourceEntity.name}' requires @objectRef + @through`, { entity: sourceEntity.name });
|
|
41
42
|
}
|
package/dist/n2m-resolver.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"n2m-resolver.js","sourceRoot":"","sources":["../src/n2m-resolver.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,EAAE;AACF,4EAA4E;AAC5E,uEAAuE;AACvE,+EAA+E;AAC/E,2EAA2E;AAC3E,qEAAqE;AACrE,+EAA+E;AAC/E,4EAA4E;AAC5E,2DAA2D;AAC3D,EAAE;AACF,sDAAsD;AACtD,+EAA+E;AAC/E,2DAA2D;AAC3D,+EAA+E;AAC/E,gEAAgE;AAChE,8EAA8E;AAC9E,6EAA6E;AAC7E,gFAAgF;AAGhF,OAAO,EACL,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAC1C,6BAA6B,EAAE,4BAA4B,EAAE,yBAAyB,EACtF,gBAAgB,EAChB,8BAA8B,EAC9B,iBAAiB,EACjB,eAAe,GAChB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAwBtE,uGAAuG;AACvG,MAAM,UAAU,oBAAoB,CAClC,YAAsB,EACtB,YAAoB,EACpB,IAAc;IAEd,8EAA8E;IAC9E,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC5C,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;YAAE,SAAS;QAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;YAAE,SAAS;QAC1C,iFAAiF;QACjF,IAAI,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,KAAK,gBAAgB;YAAE,SAAS;QAC7E,IAAI,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,KAAK,SAAS;YAAE,SAAS,CAAC,sBAAsB;QAEzF,MAAM,GAAG,GAAG,KAAyB,CAAC;QACtC,MAAM,gBAAgB,GAAG,
|
|
1
|
+
{"version":3,"file":"n2m-resolver.js","sourceRoot":"","sources":["../src/n2m-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** True when `value` is an IPv4 or IPv6 literal. */
|
|
2
|
+
export declare function isInetLiteral(value: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* True when `value` is an absolute URI: a scheme, a non-empty remainder and — when the
|
|
5
|
+
* remainder opens an authority with `//` — a non-empty authority. Padding is stripped first.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isAbsoluteUri(value: string): boolean;
|
|
8
|
+
//# sourceMappingURL=net-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"net-format.d.ts","sourceRoot":"","sources":["../src/net-format.ts"],"names":[],"mappings":"AAeA,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAQD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAMpD"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Run-time format checks for `field.uri` and `field.inet` (#234, ADR-0037 — Contract A).
|
|
2
|
+
//
|
|
3
|
+
// These are deliberately explicit, engine-neutral rules rather than `new URL()` or a
|
|
4
|
+
// platform IP parser: the Python `run_validators` runner applies the SAME patterns, so the
|
|
5
|
+
// two run-time runners agree on every input and not only on the pinned
|
|
6
|
+
// validation-conformance probe set.
|
|
7
|
+
// The IPv4 and IPv6 literal patterns the generated Zod schema uses
|
|
8
|
+
// (`codegen-ts/src/templates/net-regex.ts`) — no hostnames, no CIDR, no padding, no
|
|
9
|
+
// leading-zero octet; IPv6 includes the embedded-IPv4 tails.
|
|
10
|
+
const IPV4_RE = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
|
|
11
|
+
const IPV6_RE = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9]))$/;
|
|
12
|
+
/** True when `value` is an IPv4 or IPv6 literal. */
|
|
13
|
+
export function isInetLiteral(value) {
|
|
14
|
+
return IPV4_RE.test(value) || IPV6_RE.test(value);
|
|
15
|
+
}
|
|
16
|
+
// Leading/trailing C0 controls and spaces, which a URL parser strips before parsing.
|
|
17
|
+
const URI_PAD_RE = /^[\u0000- ]+|[\u0000- ]+$/g;
|
|
18
|
+
// scheme ":" remainder — the remainder may hold anything, including a newline.
|
|
19
|
+
const URI_SCHEME_RE = /^[A-Za-z][A-Za-z0-9+.-]*:([\s\S]*)$/;
|
|
20
|
+
const URI_AUTHORITY_END_RE = /[/?#]/;
|
|
21
|
+
/**
|
|
22
|
+
* True when `value` is an absolute URI: a scheme, a non-empty remainder and — when the
|
|
23
|
+
* remainder opens an authority with `//` — a non-empty authority. Padding is stripped first.
|
|
24
|
+
*/
|
|
25
|
+
export function isAbsoluteUri(value) {
|
|
26
|
+
const rest = URI_SCHEME_RE.exec(value.replace(URI_PAD_RE, ""))?.[1];
|
|
27
|
+
if (rest === undefined || rest.length === 0)
|
|
28
|
+
return false;
|
|
29
|
+
if (!rest.startsWith("//"))
|
|
30
|
+
return true;
|
|
31
|
+
const authority = rest.slice(2).split(URI_AUTHORITY_END_RE)[0] ?? "";
|
|
32
|
+
return authority.length > 0;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=net-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"net-format.js","sourceRoot":"","sources":["../src/net-format.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,EAAE;AACF,qFAAqF;AACrF,2FAA2F;AAC3F,uEAAuE;AACvE,oCAAoC;AAEpC,mEAAmE;AACnE,oFAAoF;AACpF,6DAA6D;AAC7D,MAAM,OAAO,GACX,qHAAqH,CAAC;AACxH,MAAM,OAAO,GACX,2jBAA2jB,CAAC;AAE9jB,oDAAoD;AACpD,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACpD,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,GAAG,4BAA4B,CAAC;AAChD,+EAA+E;AAC/E,MAAM,aAAa,GAAG,qCAAqC,CAAC;AAC5D,MAAM,oBAAoB,GAAG,OAAO,CAAC;AAErC;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACpE,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1D,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACrE,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9B,CAAC"}
|
package/dist/object-manager.d.ts
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import type { MetaData } from "@metaobjectsdev/metadata";
|
|
2
2
|
import type { PersistenceDriver, Row } from "./persistence-driver.js";
|
|
3
3
|
import { type Filter, type QueryOpts } from "./query-builder.js";
|
|
4
|
-
import { type ColumnNamingStrategy } from "@metaobjectsdev/metadata";
|
|
5
4
|
import { type FieldViewSpec, type EntityViewSpec } from "./view.js";
|
|
6
5
|
import type { ValidationResult } from "./validator-runner.js";
|
|
7
6
|
export interface ObjectManagerOptions {
|
|
8
7
|
metadata: MetaData;
|
|
9
8
|
driver: PersistenceDriver;
|
|
10
|
-
/**
|
|
11
|
-
* Column-naming strategy for fields with no `@column` override. Defaults to
|
|
12
|
-
* `"snake_case"`. Must agree with the codegen / migration config that
|
|
13
|
-
* created the schema (a mismatch yields columns the runtime can't address).
|
|
14
|
-
*/
|
|
15
|
-
columnNamingStrategy?: ColumnNamingStrategy;
|
|
16
9
|
}
|
|
17
10
|
export interface ReadOpts extends QueryOpts {
|
|
18
11
|
view?: string;
|
|
@@ -66,6 +59,26 @@ export declare class ObjectManager {
|
|
|
66
59
|
private allDbColumns;
|
|
67
60
|
private applyViewRestriction;
|
|
68
61
|
private requireEntity;
|
|
62
|
+
/** The declared object node, exactly as loaded (a report is NOT swapped for its read model). */
|
|
63
|
+
private requireObject;
|
|
64
|
+
/**
|
|
65
|
+
* FR-044: a report declares no fields — its read shape is derived — so it is read
|
|
66
|
+
* through a detached read model carrying one real field per derived field and the
|
|
67
|
+
* report's own read-only source. Everything downstream (column list, filter and
|
|
68
|
+
* sort resolution, the name map, read coercion) then treats it as it treats a
|
|
69
|
+
* projection. The model is built once per report node and never joins the tree.
|
|
70
|
+
*
|
|
71
|
+
* A report with no read-only source of its own has no view (Table A), so there is
|
|
72
|
+
* nothing to read: refused here rather than falling through to a default table name.
|
|
73
|
+
*/
|
|
74
|
+
private reportReadModelOf;
|
|
75
|
+
/**
|
|
76
|
+
* Resolve an entity for an operation that needs an identity or writes: get-by-id,
|
|
77
|
+
* reference encode/decode, and every create/update/delete. A report (FR-044) is an
|
|
78
|
+
* aggregate over a view — it has no primary key and no write target — so these are
|
|
79
|
+
* refused by name before anything else is looked at (a sourceless report included).
|
|
80
|
+
*/
|
|
81
|
+
private requireIdentified;
|
|
69
82
|
private toJsRow;
|
|
70
83
|
}
|
|
71
84
|
//# sourceMappingURL=object-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-manager.d.ts","sourceRoot":"","sources":["../src/object-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"object-manager.d.ts","sourceRoot":"","sources":["../src/object-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/object-manager.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { physicalNamingGuideUrl } from "@metaobjectsdev/metadata/release-docs";
|
|
2
|
+
import { TYPE_OBJECT, TYPE_FIELD, OBJECT_SUBTYPE_REPORT, isMetaObject, isMetaRoot, isReadOnlySource, reportReadModel, FIELD_SUBTYPE_INT, FIELD_SUBTYPE_LONG, FIELD_SUBTYPE_DOUBLE, FIELD_SUBTYPE_FLOAT, FIELD_SUBTYPE_DECIMAL, } from "@metaobjectsdev/metadata";
|
|
2
3
|
import { buildSelectSpec, buildCountSpec, buildInsertSpec, buildUpdateSpec, buildDeleteSpec, resolvePkFields, compileFilter, primaryKeyColumns, } from "./query-builder.js";
|
|
3
4
|
import { tphSubtypeOf } from "./tph.js";
|
|
4
|
-
import { buildNameMap, resolveTableName,
|
|
5
|
+
import { buildNameMap, resolveTableName, physicalNamingOf, physicalNamingRemovedMessage, } from "@metaobjectsdev/metadata";
|
|
5
6
|
import { coerceRowOnRead, coerceRowOnWrite } from "./type-coercer.js";
|
|
6
7
|
import { decodeRef, encodeRef } from "./ref-codec.js";
|
|
7
8
|
import { runValidators } from "./validator-runner.js";
|
|
@@ -19,7 +20,15 @@ export class ObjectManager {
|
|
|
19
20
|
constructor(opts) {
|
|
20
21
|
this.metadata = opts.metadata;
|
|
21
22
|
this.driver = opts.driver;
|
|
22
|
-
|
|
23
|
+
// ADR-0058: the column rule is the project's one setting (`naming` in
|
|
24
|
+
// .metaobjects/config.json), carried by the loaded root — the same value codegen and
|
|
25
|
+
// `meta migrate` read, so the runtime cannot address columns the schema does not have.
|
|
26
|
+
// The 1.0 option is refused rather than dropped: its value may be the one that matches.
|
|
27
|
+
const removedNaming = opts.columnNamingStrategy;
|
|
28
|
+
if (removedNaming !== undefined) {
|
|
29
|
+
throw new Error(physicalNamingRemovedMessage("the ObjectManager columnNamingStrategy option", String(removedNaming), physicalNamingGuideUrl()));
|
|
30
|
+
}
|
|
31
|
+
this.columnNamingStrategy = physicalNamingOf(this.metadata).columns;
|
|
23
32
|
}
|
|
24
33
|
nameMap(entity) {
|
|
25
34
|
let m = this.nameMapCache.get(entity.name);
|
|
@@ -59,7 +68,7 @@ export class ObjectManager {
|
|
|
59
68
|
return coercePkValue(entity, pkFields[0], id);
|
|
60
69
|
}
|
|
61
70
|
async findById(entityName, id, opts = {}) {
|
|
62
|
-
const entity = this.
|
|
71
|
+
const entity = this.requireIdentified(entityName, "findById");
|
|
63
72
|
const pkField = resolvePkFields(entity)[0];
|
|
64
73
|
return this.findFirst(entityName, { [pkField]: this.coerceIdArg(entity, id) }, opts);
|
|
65
74
|
}
|
|
@@ -96,7 +105,7 @@ export class ObjectManager {
|
|
|
96
105
|
}
|
|
97
106
|
async load(refString) {
|
|
98
107
|
const { entity: entityName, pkValues } = decodeRef(refString);
|
|
99
|
-
const entity = this.
|
|
108
|
+
const entity = this.requireIdentified(entityName, "load");
|
|
100
109
|
const pkFields = resolvePkFields(entity);
|
|
101
110
|
if (pkValues.length !== pkFields.length) {
|
|
102
111
|
throw new MetadataError(`Reference '${refString}' has ${pkValues.length} PK values; entity '${entityName}' expects ${pkFields.length}`, { entity: entityName });
|
|
@@ -110,11 +119,11 @@ export class ObjectManager {
|
|
|
110
119
|
return this.findFirst(entityName, filter);
|
|
111
120
|
}
|
|
112
121
|
refOf(entityName, record) {
|
|
113
|
-
const entity = this.
|
|
122
|
+
const entity = this.requireIdentified(entityName, "refOf");
|
|
114
123
|
return encodeRef(entityName, record, resolvePkFields(entity));
|
|
115
124
|
}
|
|
116
125
|
async create(entityName, data, opts = {}) {
|
|
117
|
-
const entity = this.
|
|
126
|
+
const entity = this.requireIdentified(entityName, "create");
|
|
118
127
|
const driver = opts.tx ?? this.driver;
|
|
119
128
|
const restricted0 = this.applyViewRestriction(entity, data, opts.view);
|
|
120
129
|
// FR-017 TPH: a subtype create injects its discriminator value (the entity
|
|
@@ -133,7 +142,7 @@ export class ObjectManager {
|
|
|
133
142
|
return this.toJsRow(entity, dbRow);
|
|
134
143
|
}
|
|
135
144
|
async update(entityName, id, data, opts = {}) {
|
|
136
|
-
const entity = this.
|
|
145
|
+
const entity = this.requireIdentified(entityName, "update");
|
|
137
146
|
const driver = opts.tx ?? this.driver;
|
|
138
147
|
const restricted0 = this.applyViewRestriction(entity, data, opts.view);
|
|
139
148
|
// FR-017 TPH: the discriminator is immutable — a subtype can't be changed
|
|
@@ -162,7 +171,7 @@ export class ObjectManager {
|
|
|
162
171
|
return this.toJsRow(entity, dbRow);
|
|
163
172
|
}
|
|
164
173
|
async delete(entityName, id, opts = {}) {
|
|
165
|
-
const entity = this.
|
|
174
|
+
const entity = this.requireIdentified(entityName, "delete");
|
|
166
175
|
const driver = opts.tx ?? this.driver;
|
|
167
176
|
// FR-017 TPH: scope the by-id delete to the subtype (cross-subtype → not found).
|
|
168
177
|
const spec = buildDeleteSpec(entity, this.coerceIdArg(entity, id), this.columnNamingStrategy, this.tphScope(entity));
|
|
@@ -176,7 +185,7 @@ export class ObjectManager {
|
|
|
176
185
|
return true;
|
|
177
186
|
}
|
|
178
187
|
async createMany(entityName, dataArray, opts = {}) {
|
|
179
|
-
const entity = this.
|
|
188
|
+
const entity = this.requireIdentified(entityName, "createMany");
|
|
180
189
|
const driver = opts.tx ?? this.driver;
|
|
181
190
|
// Validate + identity-resolve every row before any insert so a late failure can't leave partial state.
|
|
182
191
|
const validatedRows = [];
|
|
@@ -204,7 +213,7 @@ export class ObjectManager {
|
|
|
204
213
|
return dbRows.map((r) => this.toJsRow(entity, r));
|
|
205
214
|
}
|
|
206
215
|
async updateMany(entityName, filter, partial, opts = {}) {
|
|
207
|
-
const entity = this.
|
|
216
|
+
const entity = this.requireIdentified(entityName, "updateMany");
|
|
208
217
|
const driver = opts.tx ?? this.driver;
|
|
209
218
|
const restricted = this.applyViewRestriction(entity, partial, opts.view);
|
|
210
219
|
const v = runValidators(entity, restricted, { partial: true });
|
|
@@ -220,7 +229,7 @@ export class ObjectManager {
|
|
|
220
229
|
return driver.updateMany(spec);
|
|
221
230
|
}
|
|
222
231
|
async deleteMany(entityName, filter, opts = {}) {
|
|
223
|
-
const entity = this.
|
|
232
|
+
const entity = this.requireIdentified(entityName, "deleteMany");
|
|
224
233
|
const driver = opts.tx ?? this.driver;
|
|
225
234
|
const spec = {
|
|
226
235
|
table: resolveTableName(entity),
|
|
@@ -231,7 +240,7 @@ export class ObjectManager {
|
|
|
231
240
|
async transaction(fn) {
|
|
232
241
|
return this.driver.transaction(async (txDriver) => {
|
|
233
242
|
const txOm = new ObjectManager({
|
|
234
|
-
metadata: this.metadata, driver: txDriver,
|
|
243
|
+
metadata: this.metadata, driver: txDriver,
|
|
235
244
|
});
|
|
236
245
|
return fn(txOm);
|
|
237
246
|
});
|
|
@@ -379,6 +388,11 @@ export class ObjectManager {
|
|
|
379
388
|
return data;
|
|
380
389
|
}
|
|
381
390
|
requireEntity(entityName) {
|
|
391
|
+
const entity = this.requireObject(entityName);
|
|
392
|
+
return entity.subType === OBJECT_SUBTYPE_REPORT ? this.reportReadModelOf(entity) : entity;
|
|
393
|
+
}
|
|
394
|
+
/** The declared object node, exactly as loaded (a report is NOT swapped for its read model). */
|
|
395
|
+
requireObject(entityName) {
|
|
382
396
|
if (!VALID_ENTITY_NAME.test(entityName)) {
|
|
383
397
|
throw new UnsafeNameError(`Unsafe entity name '${entityName}'`, { value: entityName });
|
|
384
398
|
}
|
|
@@ -389,6 +403,47 @@ export class ObjectManager {
|
|
|
389
403
|
}
|
|
390
404
|
return entity;
|
|
391
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* FR-044: a report declares no fields — its read shape is derived — so it is read
|
|
408
|
+
* through a detached read model carrying one real field per derived field and the
|
|
409
|
+
* report's own read-only source. Everything downstream (column list, filter and
|
|
410
|
+
* sort resolution, the name map, read coercion) then treats it as it treats a
|
|
411
|
+
* projection. The model is built once per report node and never joins the tree.
|
|
412
|
+
*
|
|
413
|
+
* A report with no read-only source of its own has no view (Table A), so there is
|
|
414
|
+
* nothing to read: refused here rather than falling through to a default table name.
|
|
415
|
+
*/
|
|
416
|
+
reportReadModelOf(report) {
|
|
417
|
+
if (!isMetaObject(report) || !isMetaRoot(this.metadata)) {
|
|
418
|
+
throw new MetadataError(`Report '${report.name}' cannot be read: the ObjectManager's metadata is not a loaded root`, { entity: report.name });
|
|
419
|
+
}
|
|
420
|
+
let model;
|
|
421
|
+
try {
|
|
422
|
+
model = reportReadModel(report, this.metadata);
|
|
423
|
+
}
|
|
424
|
+
catch (cause) {
|
|
425
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
426
|
+
throw new MetadataError(`Report '${report.name}' cannot be read: ${detail}`, { entity: report.name, cause });
|
|
427
|
+
}
|
|
428
|
+
if (!model.children().some((c) => isReadOnlySource(c))) {
|
|
429
|
+
throw new MetadataError(`Report '${report.name}' is not served: it declares no read-only source, so it has no view to read`, { entity: report.name });
|
|
430
|
+
}
|
|
431
|
+
return model;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Resolve an entity for an operation that needs an identity or writes: get-by-id,
|
|
435
|
+
* reference encode/decode, and every create/update/delete. A report (FR-044) is an
|
|
436
|
+
* aggregate over a view — it has no primary key and no write target — so these are
|
|
437
|
+
* refused by name before anything else is looked at (a sourceless report included).
|
|
438
|
+
*/
|
|
439
|
+
requireIdentified(entityName, op) {
|
|
440
|
+
const entity = this.requireObject(entityName);
|
|
441
|
+
if (entity.subType === OBJECT_SUBTYPE_REPORT) {
|
|
442
|
+
throw new MetadataError(`${op} is not supported on '${entityName}': a report is read-only and has no identity ` +
|
|
443
|
+
`(read it with findMany, findFirst or count)`, { entity: entityName });
|
|
444
|
+
}
|
|
445
|
+
return entity;
|
|
446
|
+
}
|
|
392
447
|
toJsRow(entity, dbRow) {
|
|
393
448
|
const { dbToJs } = this.nameMap(entity);
|
|
394
449
|
const out = {};
|