@metaobjectsdev/runtime-ts 0.8.1-rc.1 → 0.9.0-rc.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-object.js","sourceRoot":"","sources":["../src/extract-object.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import type { FastifyInstance } from "fastify";
2
2
  import type { ZodTypeAny } from "zod";
3
3
  import type { ObjectManager } from "../object-manager.js";
4
4
  import type { RouteShorthandOptions } from "fastify";
5
+ import type { SortAllowlist } from "../drizzle-fastify/filter-allowlist.js";
5
6
  export type CrudVerb = "list" | "get" | "create" | "update" | "delete";
6
7
  export interface CrudRoutesOptions {
7
8
  fastify: FastifyInstance;
@@ -39,6 +40,14 @@ export interface CrudRoutesOptions {
39
40
  * uses PUT for updates.
40
41
  */
41
42
  updateMethod?: "patch" | "put";
43
+ /**
44
+ * Per-entity sort allowlist (`<Entity>SortAllowlist` from codegen). When set,
45
+ * a `?sort=field:dir` referencing a field NOT in the allowlist (or an invalid
46
+ * order) is rejected with HTTP 400 `{ error: "invalid_sort" }` — matching the
47
+ * cross-port REST contract and the drizzle-fastify mount. When absent, `?sort`
48
+ * is ignored (legacy back-compat: limit/offset only).
49
+ */
50
+ sortAllowlist?: SortAllowlist;
42
51
  }
43
52
  /**
44
53
  * Mount the 5 standard REST endpoints for an entity:
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fastify/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAMrD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,eAAe,CAAC;IACzB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,YAAY,EAAE,UAAU,CAAC;IACzB,yEAAyE;IACzE,YAAY,EAAE,UAAU,CAAC;IACzB;;;OAGG;IACH,EAAE,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC7B;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;CAChC;AAID;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAO7D;AAOD,KAAK,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;AAW3D,wBAAgB,cAAc,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAQ5D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAM3D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAY9D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CA4B9D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAM9D;AAMD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAGpD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fastify/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAEtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAO5E,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,eAAe,CAAC;IACzB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,YAAY,EAAE,UAAU,CAAC;IACzB,yEAAyE;IACzE,YAAY,EAAE,UAAU,CAAC;IACzB;;;OAGG;IACH,EAAE,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC7B;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAC/B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAID;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAO7D;AAOD,KAAK,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;AAW3D,wBAAgB,cAAc,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAgC5D;AAmBD,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAM3D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAY9D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CA4B9D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAM9D;AAMD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAGpD"}
@@ -10,6 +10,8 @@
10
10
  // Type-only Fastify imports keep the optional-peer story clean: the .d.ts
11
11
  // reference is needed for the public API, but at runtime there's no
12
12
  // `require("fastify")`.
13
+ import qs from "qs";
14
+ import { isTruthyFlag, contractErrorCode } from "../drizzle-fastify/util.js";
13
15
  const ALL_VERBS = ["list", "get", "create", "update", "delete"];
14
16
  /**
15
17
  * Mount the 5 standard REST endpoints for an entity:
@@ -42,16 +44,54 @@ function routeOpts(opts) {
42
44
  return opts.routeOptions ?? {};
43
45
  }
44
46
  export function mountListRoute(opts) {
45
- opts.fastify.get(opts.path, routeOpts(opts), async (req) => {
46
- const { limit, offset } = req.query;
47
+ opts.fastify.get(opts.path, routeOpts(opts), async (req, reply) => {
48
+ // Re-parse the raw URL with qs so the top-level withCount flag and the
49
+ // sort=field:dir param are available regardless of Fastify's query parser.
50
+ const rawSearch = req.raw.url?.includes("?")
51
+ ? req.raw.url.slice(req.raw.url.indexOf("?") + 1)
52
+ : "";
53
+ const parsed = qs.parse(rawSearch);
54
+ const withCount = isTruthyFlag(parsed["withCount"]);
47
55
  const readOpts = {};
56
+ const { limit, offset } = req.query;
48
57
  if (limit !== undefined)
49
58
  readOpts.limit = Number(limit);
50
59
  if (offset !== undefined)
51
60
  readOpts.offset = Number(offset);
52
- return (await opts.om()).findMany(opts.entity, undefined, readOpts);
61
+ // Sort allowlist gate (cross-port REST contract). Only enforced when a
62
+ // sortAllowlist is configured; absent → ?sort is ignored (back-compat).
63
+ if (opts.sortAllowlist && typeof parsed["sort"] === "string") {
64
+ const sortParse = parseSort(parsed["sort"], opts.sortAllowlist);
65
+ if (sortParse.error) {
66
+ return reply.code(400).send({ error: contractErrorCode(sortParse.error) });
67
+ }
68
+ if (sortParse.orderBy)
69
+ readOpts.orderBy = sortParse.orderBy;
70
+ }
71
+ const om = await opts.om();
72
+ const rows = await om.findMany(opts.entity, undefined, readOpts);
73
+ if (!withCount)
74
+ return rows;
75
+ // total is the UNPAGINATED count (no limit/offset).
76
+ const total = await om.count(opts.entity);
77
+ return { rows, total };
53
78
  });
54
79
  }
80
+ /**
81
+ * Validate a `sort=field:dir` spec against the allowlist. Mirrors the
82
+ * drizzle-fastify filter-parser's sort semantics + internal error codes
83
+ * (`sort.unknown_field` / `sort.invalid_order`) so both mounts emit the same
84
+ * `invalid_sort` envelope at the HTTP boundary.
85
+ */
86
+ function parseSort(spec, sortAllowlist) {
87
+ const [field, orderRaw] = spec.split(":");
88
+ if (!field || !sortAllowlist[field])
89
+ return { error: "sort.unknown_field" };
90
+ const order = (orderRaw ?? "asc").toLowerCase();
91
+ if (order !== "asc" && order !== "desc")
92
+ return { error: "sort.invalid_order" };
93
+ return { orderBy: [field, order] };
94
+ }
55
95
  export function mountGetRoute(opts) {
56
96
  opts.fastify.get(`${opts.path}/:id`, routeOpts(opts), async (req, reply) => {
57
97
  const { id } = req.params;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fastify/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fastify/index.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -6,4 +6,5 @@ export type { FieldViewSpec, EntityViewSpec } from "./view.js";
6
6
  export type { ValidationResult } from "./validator-runner.js";
7
7
  export type { ValidationFailure } from "./errors.js";
8
8
  export { RuntimeError, ValidationError, NotFoundError, ConstraintViolationError, MetadataError, UnsafeNameError, } from "./errors.js";
9
+ export { extractObject, extractSchemaFor, assemble, MAX_NEST_DEPTH, } from "./extract-object.js";
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -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;AAC9D,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"}
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;AAC9D,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"}
package/dist/index.js CHANGED
@@ -1,3 +1,7 @@
1
1
  export { ObjectManager } from "./object-manager.js";
2
2
  export { RuntimeError, ValidationError, NotFoundError, ConstraintViolationError, MetadataError, UnsafeNameError, } from "./errors.js";
3
+ // FR-010 Phase B — metadata-driven runtime extract. The descriptor-driven extract ENGINE lives in
4
+ // the metadata-free @metaobjectsdev/render package; this bridge wires it to the Phase A runtime
5
+ // object model (MetaObject.newInstance() + the MetaField SPI), mirroring the JVM `om` siting.
6
+ export { extractObject, extractSchemaFor, assemble, MAX_NEST_DEPTH, } from "./extract-object.js";
3
7
  //# sourceMappingURL=index.js.map
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;AAgBpD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,aAAa,EACb,wBAAwB,EACxB,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAgBpD,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"}
@@ -1,6 +1,6 @@
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 { TYPE_FIELD, TYPE_VALIDATOR, VALIDATOR_SUBTYPE_REQUIRED, VALIDATOR_SUBTYPE_LENGTH, VALIDATOR_SUBTYPE_REGEX, FIELD_SUBTYPE_STRING, FIELD_SUBTYPE_INT, FIELD_SUBTYPE_LONG, FIELD_SUBTYPE_SHORT, FIELD_SUBTYPE_BYTE, FIELD_SUBTYPE_DOUBLE, FIELD_SUBTYPE_FLOAT, FIELD_SUBTYPE_BOOLEAN, FIELD_ATTR_REQUIRED, FIELD_ATTR_MAX_LENGTH, FIELD_ATTR_DEFAULT, VALIDATOR_ATTR_MIN, VALIDATOR_ATTR_MAX, VALIDATOR_ATTR_PATTERN, } from "@metaobjectsdev/metadata";
3
+ 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_SHORT, FIELD_SUBTYPE_BYTE, FIELD_SUBTYPE_DOUBLE, FIELD_SUBTYPE_FLOAT, FIELD_SUBTYPE_BOOLEAN, FIELD_SUBTYPE_UUID, FIELD_ATTR_REQUIRED, FIELD_ATTR_MAX_LENGTH, FIELD_ATTR_DEFAULT, VALIDATOR_ATTR_MIN, VALIDATOR_ATTR_MAX, VALIDATOR_ATTR_PATTERN, } from "@metaobjectsdev/metadata";
4
4
  const NUMERIC_FIELD_SUBTYPES = new Set([
5
5
  FIELD_SUBTYPE_INT, FIELD_SUBTYPE_LONG, FIELD_SUBTYPE_SHORT, FIELD_SUBTYPE_BYTE,
6
6
  FIELD_SUBTYPE_DOUBLE, FIELD_SUBTYPE_FLOAT,
@@ -138,7 +138,7 @@ function resolveMinLength(field) {
138
138
  return undefined;
139
139
  }
140
140
  function checkType(subType, value) {
141
- if (subType === FIELD_SUBTYPE_STRING) {
141
+ if (subType === FIELD_SUBTYPE_STRING || subType === FIELD_SUBTYPE_UUID) {
142
142
  if (typeof value !== "string")
143
143
  return `expected string`;
144
144
  }
@@ -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": "0.8.1-rc.1",
3
+ "version": "0.9.0-rc.1",
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",
@@ -53,7 +53,8 @@
53
53
  "access": "public"
54
54
  },
55
55
  "dependencies": {
56
- "@metaobjectsdev/metadata": "0.8.1-rc.1",
56
+ "@metaobjectsdev/metadata": "0.9.0-rc.1",
57
+ "@metaobjectsdev/render": "0.9.0-rc.1",
57
58
  "qs": "^6.13.0"
58
59
  },
59
60
  "peerDependencies": {
@@ -16,13 +16,13 @@
16
16
 
17
17
  import type { FastifyInstance, RouteShorthandOptions } from "fastify";
18
18
  import type { ZodTypeAny } from "zod";
19
- import { eq, count, and } from "drizzle-orm";
19
+ import { eq, count, and, asc } from "drizzle-orm";
20
20
  import qs from "qs";
21
21
  import type { FilterAllowlist, SortAllowlist } from "./filter-allowlist.js";
22
22
  export type { FilterAllowlist, SortAllowlist } from "./filter-allowlist.js";
23
23
  import { parseFilterParams, FilterParseError } from "./filter-parser.js";
24
- import { isTruthyFlag } from "./util.js";
25
- export { isTruthyFlag } from "./util.js";
24
+ import { isTruthyFlag, contractErrorCode } from "./util.js";
25
+ export { isTruthyFlag, contractErrorCode } from "./util.js";
26
26
 
27
27
  // ---------------------------------------------------------------------------
28
28
  // Loose types — we don't bind to a specific Drizzle backend so the helper
@@ -109,29 +109,39 @@ export function mountListRoute(opts: VerbOptions): void {
109
109
  ? and(parsed.where, parsed.searchWhere)
110
110
  : (parsed.where ?? parsed.searchWhere);
111
111
  if (combinedWhere) { q = q.where(combinedWhere); where = combinedWhere; }
112
+ // Default to stable id-ascending order when the caller specifies no
113
+ // sort — the cross-port contract asserts deterministic ordering for
114
+ // pagination + filter scenarios (Postgres otherwise returns rows in an
115
+ // unspecified order).
112
116
  if (parsed.orderBy) q = q.orderBy(...parsed.orderBy);
117
+ else if (opts.table.id !== undefined) q = q.orderBy(asc(opts.table.id));
113
118
  if (parsed.limit !== undefined) q = q.limit(parsed.limit);
114
119
  if (parsed.offset !== undefined) q = q.offset(parsed.offset);
115
120
  } else {
116
121
  // Legacy path — no allowlists configured. Only limit/offset.
117
122
  const { limit, offset } = req.query as { limit?: string; offset?: string };
123
+ if (opts.table.id !== undefined) q = q.orderBy(asc(opts.table.id));
118
124
  if (limit !== undefined) q = q.limit(Number(limit));
119
125
  if (offset !== undefined) q = q.offset(Number(offset));
120
126
  }
121
127
 
122
- const rows = await q.all();
128
+ // Await the query directly rather than calling `.all()`: the
129
+ // drizzle-orm node-postgres query builder is thenable but has no `.all()`
130
+ // method (that is a libsql/better-sqlite3-only API). Awaiting works on
131
+ // both dialects and is what makes this helper genuinely Postgres-capable.
132
+ const rows = await q;
123
133
 
124
134
  if (!withCount) return rows;
125
135
 
126
136
  // Count query: same WHERE, no limit/offset/orderBy.
127
137
  let cq = opts.db.select({ c: count() }).from(opts.table).$dynamic();
128
138
  if (where) cq = cq.where(where);
129
- const countRow = (await cq.all())[0] as { c: number } | undefined;
139
+ const countRow = (await cq)[0] as { c: number } | undefined;
130
140
  const total = countRow?.c ?? 0;
131
141
  return { rows, total };
132
142
  } catch (err) {
133
143
  if (err instanceof FilterParseError) {
134
- return reply.code(400).send({ error: err.code, ...(err.details ?? {}) });
144
+ return reply.code(400).send({ error: contractErrorCode(err.code), ...(err.details ?? {}) });
135
145
  }
136
146
  throw err;
137
147
  }
@@ -141,11 +151,15 @@ export function mountListRoute(opts: VerbOptions): void {
141
151
  export function mountGetRoute(opts: VerbOptions): void {
142
152
  opts.fastify.get(`${opts.path}/:id`, routeOpts(opts), async (req, reply) => {
143
153
  const { id } = req.params as { id: string };
144
- const row = await opts.db
154
+ // Await + take the first row rather than `.get()` — `.get()` is a
155
+ // libsql/better-sqlite3-only method; the node-postgres builder is thenable
156
+ // but has no `.get()`. Awaiting works on both dialects.
157
+ const rows = await opts.db
145
158
  .select()
146
159
  .from(opts.table)
147
160
  .where(eq(opts.table.id, parseId(id)))
148
- .get();
161
+ .limit(1);
162
+ const row = (rows as unknown[])[0];
149
163
  return row ?? reply.code(404).send({ error: "not_found" });
150
164
  });
151
165
  }
@@ -182,11 +196,20 @@ export function mountUpdateRoute(opts: VerbOptions): void {
182
196
  };
183
197
  const path = `${opts.path}/:id`;
184
198
  const ro = routeOpts(opts);
199
+ // Cross-port REST contract (FR-008): the update verb is reachable via BOTH
200
+ // PATCH and PUT, each routed to the same handler (the Java/Kotlin/C#/Python
201
+ // controllers map both methods to the update path). Mount both by default so
202
+ // the generated TS routes match. `updateMethod` remains an explicit
203
+ // single-verb override for a consumer that wants to restrict the surface.
185
204
  // biome-ignore lint/suspicious/noExplicitAny: handler signature is generic
205
+ const h = handler as any;
186
206
  if (opts.updateMethod === "put") {
187
- opts.fastify.put(path, ro, handler as any);
207
+ opts.fastify.put(path, ro, h);
208
+ } else if (opts.updateMethod === "patch") {
209
+ opts.fastify.patch(path, ro, h);
188
210
  } else {
189
- opts.fastify.patch(path, ro, handler as any);
211
+ opts.fastify.patch(path, ro, h);
212
+ opts.fastify.put(path, ro, h);
190
213
  }
191
214
  }
192
215
 
@@ -3,7 +3,7 @@ import { sql, eq, and, count } from "drizzle-orm";
3
3
  import qs from "qs";
4
4
  import { parseFilterParams, FilterParseError } from "./filter-parser.js";
5
5
  import type { FilterAllowlist, SortAllowlist } from "./filter-allowlist.js";
6
- import { isTruthyFlag } from "./util.js";
6
+ import { isTruthyFlag, contractErrorCode } from "./util.js";
7
7
 
8
8
  // biome-ignore lint/suspicious/noExplicitAny: dynamic dispatch over user-supplied views
9
9
  type AnyView = any;
@@ -140,19 +140,23 @@ export function mountReadOnlyCrudRoutes(opts: MountReadOnlyOptions): void {
140
140
  if (result.orderBy) q = q.orderBy(...result.orderBy);
141
141
  if (result.limit !== undefined) q = q.limit(result.limit);
142
142
  if (result.offset !== undefined) q = q.offset(result.offset);
143
- const rows = await q.all();
143
+ // Await directly `.all()` is libsql/better-sqlite3-only; the
144
+ // node-postgres builder is thenable. (The useRawSql branch above keeps
145
+ // db.all(sql.raw(...)) because that is the libsql raw-exec API, only
146
+ // reachable for `.existing()` empty-column views which are sqlite-only.)
147
+ const rows = await q;
144
148
 
145
149
  if (!withCount) return rows;
146
150
 
147
151
  // Count query: same WHERE, no limit/offset/orderBy.
148
152
  let cq = db.select({ c: count() }).from(view);
149
153
  if (combinedWhere) cq = cq.where(combinedWhere);
150
- const countRow = (await cq.all())[0] as { c: number } | undefined;
154
+ const countRow = (await cq)[0] as { c: number } | undefined;
151
155
  const total = countRow?.c ?? 0;
152
156
  return { rows, total };
153
157
  } catch (err) {
154
158
  if (err instanceof FilterParseError) {
155
- reply.code(400).send({ error: err.code, message: err.message });
159
+ reply.code(400).send({ error: contractErrorCode(err.code), message: err.message });
156
160
  return;
157
161
  }
158
162
  throw err;
@@ -174,9 +178,11 @@ export function mountReadOnlyCrudRoutes(opts: MountReadOnlyOptions): void {
174
178
  }
175
179
  // biome-ignore lint/suspicious/noExplicitAny: Drizzle table/view column ref
176
180
  const colRef = (view as any)[idCol];
177
- const row = await db.select().from(view).where(
181
+ // Await + first row rather than `.get()` (libsql/better-sqlite3-only).
182
+ const rows = await db.select().from(view).where(
178
183
  colRef !== undefined ? eq(colRef, Number(id)) : undefined
179
- ).get();
184
+ ).limit(1);
185
+ const row = (rows as unknown[])[0];
180
186
  return row ?? reply.code(404).send({ error: "not_found" });
181
187
  });
182
188
 
@@ -8,3 +8,27 @@ export function isTruthyFlag(v: unknown): boolean {
8
8
  if (typeof v === "boolean") return v;
9
9
  return String(v) === "1";
10
10
  }
11
+
12
+ // Cross-port REST contract error envelope (FR-008/009). The internal
13
+ // FilterParseError carries fine-grained dotted codes (filter.unknown_field,
14
+ // sort.unknown_field, ...); the HTTP wire contract that every port's generated
15
+ // API must emit uses the coarser invalid_filter_field / invalid_filter_op /
16
+ // invalid_filter_value / invalid_sort envelope. Map at the HTTP boundary so the
17
+ // internal codes stay stable while the response conforms cross-port.
18
+ export function contractErrorCode(internal: string): string {
19
+ switch (internal) {
20
+ case "filter.unknown_field":
21
+ return "invalid_filter_field";
22
+ case "filter.unsupported_op":
23
+ return "invalid_filter_op";
24
+ case "filter.invalid_value":
25
+ return "invalid_filter_value";
26
+ case "sort.unknown_field":
27
+ case "sort.invalid_order":
28
+ return "invalid_sort";
29
+ default:
30
+ // Implementation-specific guards (nesting depth, in-list size, leading
31
+ // wildcard) are not part of the cross-port contract surface; pass through.
32
+ return internal;
33
+ }
34
+ }