@metaobjectsdev/runtime-ts 1.0.9-rc.4 → 1.0.9-rc.5

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 CHANGED
@@ -89,6 +89,39 @@ type Filter =
89
89
 
90
90
  `$or` and nested operators are not yet shipped.
91
91
 
92
+ ## What is core here, and what `meta eject` hands you
93
+
94
+ This package has two tiers, and only the first is a MetaObjects guarantee
95
+ ([ADR-0034 Amendment 3](https://github.com/metaobjectsdev/metaobjects/blob/main/spec/decisions/ADR-0034-codegen-scaffold-and-own.md)):
96
+
97
+ | Entry | Tier | What it is |
98
+ |---|---|---|
99
+ | `.` and `./drivers` | **Core** | The metadata-driven runtime: `ObjectManager`, the query builder, the validator runner, the relation / M:N / TPH resolvers, type coercion, the constraint-error mapping, `extractObject`. Conformance-gated; a defect here is a MetaObjects bug. |
100
+ | `./drizzle-fastify`, `./hono`, `./fastify` | **Helper** | The HTTP adapters that mount CRUD on a web framework: the mount helpers, the filter/sort parser, the error envelopes, pagination. Reference code, not a promise. |
101
+
102
+ Generated route files are the only callers of the helper tier, and they are yours once
103
+ you run `meta eject routes` (or `routes-hono`, or `entity` for the allowlist types). Eject
104
+ copies the adapter **source** the generated code calls — verbatim, from this package's
105
+ `src/` — into your repo at `codegen/runtime/`, and the ejected generators point their
106
+ output there. After that your generated and copied code import nothing from this package;
107
+ you install what the copy imports instead (`qs`, the framework, `@metaobjectsdev/metadata`).
108
+ Fix an adapter defect in your copy without waiting for a release.
109
+
110
+ To take a later upstream fix into your copy, compare the file with the version you have
111
+ installed and apply what you want:
112
+
113
+ ```bash
114
+ meta eject --list # marks each codegen/runtime/ file identical to / DIFFERING from this package
115
+ diff -u node_modules/@metaobjectsdev/runtime-ts/src/route-errors.ts codegen/runtime/route-errors.ts
116
+ ```
117
+
118
+ A file you never changed can be refreshed wholesale with `meta eject routes --force`
119
+ (which also replaces the generator — commit first). A project that has not ejected keeps
120
+ importing `@metaobjectsdev/runtime-ts/drizzle-fastify` and `/hono` exactly as before. The
121
+ `./fastify` entry (the `ObjectManager`-backed mount) has no generator calling it, so eject
122
+ never copies it; it is still helper-tier, so copy it by hand if you mount it and want to
123
+ own it.
124
+
92
125
  ## Driver compatibility note
93
126
 
94
127
  Generated CRUD uses Kysely's `.returning()` API. Works on:
@@ -39,6 +39,22 @@ export interface FilterFieldRule {
39
39
  * still checked against the union of the three temporal formats.
40
40
  */
41
41
  readonly format?: FilterValueFormat;
42
+ /**
43
+ * `format: "timestamp"` only. Set by codegen for a `field.timestamp` that is an instant —
44
+ * the default, i.e. NOT `@localTime`. A bound with no zone is then read as UTC and a
45
+ * date-only bound as midnight UTC, the same rule the generated write schema stores such
46
+ * a value by, so `filter[dueAt][gte]=2026-10-06T00:00:00Z` finds a row sent as
47
+ * `"2026-10-06"`. Absent (an `@localTime` wall clock, or an allowlist generated before
48
+ * this existed), only a bound that carries a zone is rewritten to UTC.
49
+ */
50
+ readonly instant?: boolean;
51
+ /**
52
+ * `subType: "number"` only. Set by codegen for `field.int` / `field.long` /
53
+ * `field.currency` (integer minor units): a bound that is not a whole number
54
+ * (`filter[dailyRateCents][gte]=40.5`) answers `invalid_filter_value`. Absent, any
55
+ * finite number is accepted, as before.
56
+ */
57
+ readonly integer?: boolean;
42
58
  /**
43
59
  * The declared members of a `field.enum` (`@values`), set by codegen. A value that is
44
60
  * not a member is rejected with `invalid_filter_value`. Absent, the parser falls back
@@ -1 +1 @@
1
- {"version":3,"file":"filter-allowlist.d.ts","sourceRoot":"","sources":["../../src/drizzle-fastify/filter-allowlist.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EACL,UAAU,EACV,cAAc,EACd,aAAa,EAKb,KAAK,QAAQ,EACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,CAAC;AAEpE,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,gDAKvB,CAAC;AACX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,SAAS,QAAQ,EAAE,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;AAExE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACxC;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;AAEpE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,CAKR"}
1
+ {"version":3,"file":"filter-allowlist.d.ts","sourceRoot":"","sources":["../../src/drizzle-fastify/filter-allowlist.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EACL,UAAU,EACV,cAAc,EACd,aAAa,EAKb,KAAK,QAAQ,EACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,CAAC;AAEpE,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,gDAKvB,CAAC;AACX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,SAAS,QAAQ,EAAE,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IACpC;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;AAExE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACxC;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;AAEpE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,CAKR"}
@@ -1 +1 @@
1
- {"version":3,"file":"filter-allowlist.js","sourceRoot":"","sources":["../../src/drizzle-fastify/filter-allowlist.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,2EAA2E;AAC3E,mFAAmF;AACnF,OAAO,EACL,UAAU,EACV,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,GAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAiB,CAAC;AAIpE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,kBAAkB;IAClB,kBAAkB;IAClB,uBAAuB;IACvB,kBAAkB;CACV,CAAC;AA4CX;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa,CAC3B,SAAwB,EACxB,KAAa,EACb,QAA4B;IAE5B,qFAAqF;IACrF,qFAAqF;IACrF,8EAA8E;IAC9E,OAAO,QAAQ,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,YAAY,IAAI,KAAK,CAAC;AAC7D,CAAC"}
1
+ {"version":3,"file":"filter-allowlist.js","sourceRoot":"","sources":["../../src/drizzle-fastify/filter-allowlist.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,2EAA2E;AAC3E,mFAAmF;AACnF,OAAO,EACL,UAAU,EACV,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,GAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAiB,CAAC;AAIpE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,kBAAkB;IAClB,kBAAkB;IAClB,uBAAuB;IACvB,kBAAkB;CACV,CAAC;AA4DX;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa,CAC3B,SAAwB,EACxB,KAAa,EACb,QAA4B;IAE5B,qFAAqF;IACrF,qFAAqF;IACrF,8EAA8E;IAC9E,OAAO,QAAQ,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,YAAY,IAAI,KAAK,CAAC;AAC7D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"filter-parser.d.ts","sourceRoot":"","sources":["../../src/drizzle-fastify/filter-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,GAAG,EAAE,KAAK,UAAU,EAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAA6B,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAMvG,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAK5H,KAAK,QAAQ,GAAG,GAAG,CAAC;AAEpB,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,EAAE,QAAQ,CAAC;IAChB,SAAS,EAAE,eAAe,CAAC;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,GAAG,CAAC;CACnB;AA8DD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,iBAAiB,CA8C1E;AAwGD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAWzD"}
1
+ {"version":3,"file":"filter-parser.d.ts","sourceRoot":"","sources":["../../src/drizzle-fastify/filter-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,GAAG,EAAE,KAAK,UAAU,EAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAA6B,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAMvG,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAQ5H,KAAK,QAAQ,GAAG,GAAG,CAAC;AAEpB,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,EAAE,QAAQ,CAAC;IAChB,SAAS,EAAE,eAAe,CAAC;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,GAAG,CAAC;CACnB;AA8DD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,iBAAiB,CA8C1E;AAwGD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAWzD"}
@@ -4,7 +4,7 @@ import { FilterParseError, parsePageBound, SORT_EXPECTED } from "./list-params.j
4
4
  // Re-exported so existing importers keep one door; the definitions live in the
5
5
  // drizzle-free list-params module, which the ObjectManager Fastify mount also uses.
6
6
  export { FilterParseError, parsePageBound, PAGINATION_EXPECTED, RAW_VIEW_MAX_LIMIT, SORT_EXPECTED } from "./list-params.js";
7
- import { ANY_TEMPORAL_EXPECTED, FORMAT_EXPECTED, matchesAnyTemporal, matchesFormat, utcIsoIfZoned } from "./filter-value-format.js";
7
+ import { ANY_TEMPORAL_EXPECTED, FORMAT_EXPECTED, PLUS_OFFSET_HINT, looksLikeUnencodedPlusOffset, matchesAnyTemporal, matchesFormat, utcIsoIfZoned, utcIsoInstant, } from "./filter-value-format.js";
8
8
  import { FIELD_SUBTYPE_TIMESTAMP } from "@metaobjectsdev/metadata";
9
9
  const DEFAULT_MAX_NESTING = 5;
10
10
  const DEFAULT_MAX_IN_LIST = 100;
@@ -210,7 +210,8 @@ export function likePatternToGlob(pattern) {
210
210
  return out;
211
211
  }
212
212
  function invalidValue(field, op, s, expected, extra = {}) {
213
- return new FilterParseError("filter.invalid_value", `Field "${field}" op "${op}" requires ${expected}, got "${s}".`, { field, op, expected, ...extra });
213
+ const hint = typeof extra["hint"] === "string" ? ` Hint: ${extra["hint"]}.` : "";
214
+ return new FilterParseError("filter.invalid_value", `Field "${field}" op "${op}" requires ${expected}, got "${s}".${hint}`, { field, op, expected, ...extra });
214
215
  }
215
216
  /** A Drizzle column's own enum members (`text(..., { enum })`, `pgEnum`), if it has them. */
216
217
  function columnEnumValues(col) {
@@ -230,8 +231,15 @@ function assertWellFormed(s, rule, col, field, op) {
230
231
  throw invalidValue(field, op, s, `one of: ${members.join(", ")}`, { allowed: [...members] });
231
232
  }
232
233
  if (rule.format !== undefined) {
233
- if (!matchesFormat(rule.format, s))
234
- throw invalidValue(field, op, s, FORMAT_EXPECTED[rule.format]);
234
+ if (!matchesFormat(rule.format, s)) {
235
+ // `filter[dueAt][lt]=2026-10-06T00:00:00+00:00` sent unencoded arrives with a space
236
+ // where the `+` was; "expected timestamp" alone does not say why a valid-looking
237
+ // value failed, so the answer names the fix.
238
+ const hint = rule.format === FIELD_SUBTYPE_TIMESTAMP && looksLikeUnencodedPlusOffset(s)
239
+ ? { hint: PLUS_OFFSET_HINT }
240
+ : {};
241
+ throw invalidValue(field, op, s, FORMAT_EXPECTED[rule.format], hint);
242
+ }
235
243
  }
236
244
  else if (rule.subType === "datetime" && !matchesAnyTemporal(s)) {
237
245
  throw invalidValue(field, op, s, ANY_TEMPORAL_EXPECTED);
@@ -243,14 +251,25 @@ function coerce(value, rule, col, field, op) {
243
251
  return null;
244
252
  const s = typeof value === "string" ? value : String(value);
245
253
  assertWellFormed(s, rule, col, field, op);
246
- // A zoned timestamp bound is compared in the same UTC spelling the generated schemas
247
- // store (see utcIsoIfZoned): on SQLite/D1 the column is TEXT and compares as text. A
248
- // Date-bound (`dateValues`) column parses the instant itself and is left alone.
249
- if (rule.format === FIELD_SUBTYPE_TIMESTAMP && rule.dateValues !== true) {
250
- return coerceAs(utcIsoIfZoned(s), rule.subType, field, op, rule.dateValues);
254
+ // A timestamp bound is compared in the same UTC spelling the generated schemas store:
255
+ // on SQLite/D1 the column is TEXT and compares as text. An instant field (`instant`, i.e.
256
+ // not @localTime) reads a zoneless or date-only bound as UTC, as its write schema does —
257
+ // also before a Date-bound (`dateValues`) column's `new Date(...)`, which would otherwise
258
+ // read a zoneless string in the SERVER's local zone. Without `instant`, only a zoned
259
+ // bound is rewritten, and a Date-bound column parses the value itself.
260
+ if (rule.format === FIELD_SUBTYPE_TIMESTAMP) {
261
+ const bound = rule.instant === true ? utcIsoInstant(s) : rule.dateValues === true ? s : utcIsoIfZoned(s);
262
+ return coerceAs(bound, rule.subType, field, op, rule.dateValues);
263
+ }
264
+ const coerced = coerceAs(s, rule.subType, field, op, rule.dateValues);
265
+ // field.int / field.long / field.currency: a fractional bound is not a value of the field.
266
+ if (rule.integer === true && typeof coerced === "number" && !Number.isInteger(coerced)) {
267
+ throw invalidValue(field, op, s, INTEGER_EXPECTED);
251
268
  }
252
- return coerceAs(s, rule.subType, field, op, rule.dateValues);
269
+ return coerced;
253
270
  }
271
+ /** `expected` for a non-whole bound on an integer-valued field (`integer: true`). */
272
+ const INTEGER_EXPECTED = "integer (a whole number)";
254
273
  function coerceAs(value, subType, field, op, dateValues) {
255
274
  if (value === null || value === undefined)
256
275
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"filter-parser.js","sourceRoot":"","sources":["../../src/drizzle-fastify/filter-parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"filter-parser.js","sourceRoot":"","sources":["../../src/drizzle-fastify/filter-parser.ts"],"names":[],"mappings":"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"}
@@ -16,19 +16,18 @@ export declare const FORMAT_EXPECTED: Readonly<Record<FilterValueFormat, string>
16
16
  /** `expected` for a temporal rule that does not say WHICH temporal format it is. */
17
17
  export declare const ANY_TEMPORAL_EXPECTED = "date, time or timestamp (ISO 8601)";
18
18
  export declare function matchesFormat(format: FilterValueFormat, s: string): boolean;
19
+ /** A zoned timestamp bound in UTC; a naive or date-only one unchanged (a wall clock). */
20
+ export declare function utcIsoIfZoned(s: string): string;
19
21
  /**
20
- * A zoned timestamp bound rewritten to its instant's `toISOString()` spelling; any other
21
- * value (a naive timestamp, a date-only bound) is returned unchanged.
22
- *
23
- * The generated insert/update schemas store every zoned `field.timestamp` value in that
24
- * same fixed-width UTC form, because SQLite and D1 compare the TEXT column as text: a row
25
- * sent as `2026-09-21T01:00:00+05:00` (20:00Z) and a bound of `2026-09-20T21:00:00+00:00`
26
- * only order correctly once both are spelled in UTC. A naive value names no zone, so it is
27
- * never guessed at. Postgres compares timestamptz instants and reads either spelling the
28
- * same way. The rebuilt string is the ECMAScript date-time format `Date.parse` must accept,
29
- * so this does not rely on an engine reading `+05` or a six-digit fraction.
22
+ * A `field.timestamp` INSTANT bound (not `@localTime`) in UTC: a zoned value at its
23
+ * instant, a zoneless one read as UTC, a date alone as midnight UTC — the rule the
24
+ * generated write schema (codegen-ts `utcIsoTimestamp`) stores the column by. A default
25
+ * timestamp's wire form is "always UTC" (docs/features/api-contract.md, "Type encodings").
30
26
  */
31
- export declare function utcIsoIfZoned(s: string): string;
27
+ export declare function utcIsoInstant(s: string): string;
28
+ /** The `hint` for a timestamp bound that fails only because its `+` offset was not encoded. */
29
+ export declare const PLUS_OFFSET_HINT = "a \"+\" in a query string decodes to a space: URL-encode the offset's \"+\" as %2B, or use Z for UTC";
30
+ export declare function looksLikeUnencodedPlusOffset(s: string): boolean;
32
31
  /** For a `datetime` rule with no `format` (generated before it existed): any of the three. */
33
32
  export declare function matchesAnyTemporal(s: string): boolean;
34
33
  //# sourceMappingURL=filter-value-format.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter-value-format.d.ts","sourceRoot":"","sources":["../../src/drizzle-fastify/filter-value-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AA8B/D,gFAAgF;AAChF,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAKvE,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,qBAAqB,uCAAuC,CAAC;AAE1E,wBAAgB,aAAa,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAE3E;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAO/C;AAED,8FAA8F;AAC9F,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAErD"}
1
+ {"version":3,"file":"filter-value-format.d.ts","sourceRoot":"","sources":["../../src/drizzle-fastify/filter-value-format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AA8B/D,gFAAgF;AAChF,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAKvE,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,qBAAqB,uCAAuC,CAAC;AAE1E,wBAAgB,aAAa,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAE3E;AAqCD,yFAAyF;AACzF,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE/C;AASD,+FAA+F;AAC/F,eAAO,MAAM,gBAAgB,yGAC2E,CAAC;AAEzG,wBAAgB,4BAA4B,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,8FAA8F;AAC9F,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAErD"}
@@ -47,28 +47,62 @@ export const ANY_TEMPORAL_EXPECTED = "date, time or timestamp (ISO 8601)";
47
47
  export function matchesFormat(format, s) {
48
48
  return CHECKS[format](s);
49
49
  }
50
- /** A timestamp with a time part AND an explicit zone (`Z` or `±HH[[:]MM]`). */
51
- const ZONED_TIMESTAMP_RE = /^(\d{4}-\d{2}-\d{2})[Tt ](\d{2}:\d{2})(?::(\d{2})(?:\.(\d+))?)?(?:([Zz])|([+-]\d{2}):?(\d{2})?)$/;
50
+ /** A timestamp: a date, then optionally a time part, then optionally a zone (`Z` or `±HH[[:]MM]`). */
51
+ const TIMESTAMP_PARTS_RE = /^(\d{4}-\d{2}-\d{2})(?:[Tt ](\d{2}:\d{2})(?::(\d{2})(?:\.(\d+))?)?(?:([Zz])|([+-]\d{2}):?(\d{2})?)?)?$/;
52
+ /** Already the canonical UTC spelling: `YYYY-MM-DDTHH:MM:SS[.f…]Z`. Kept byte-for-byte. */
53
+ const CANONICAL_UTC_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;
52
54
  /**
53
- * A zoned timestamp bound rewritten to its instant's `toISOString()` spelling; any other
54
- * value (a naive timestamp, a date-only bound) is returned unchanged.
55
+ * A timestamp bound in the canonical UTC spelling of its instant — `YYYY-MM-DDTHH:MM:SS[.fff]Z`,
56
+ * millisecond resolution, no trailing zeros, no fraction when it is zero (the wire form
57
+ * fixtures/persistence-conformance/normalization.md pins). A value already spelled that way
58
+ * is returned as sent; any other value carrying a zone is rewritten; a zoneless or date-only
59
+ * value only when `zonelessIsUtc`, and then read as UTC (a date alone as midnight UTC).
60
+ * Anything else is returned unchanged.
55
61
  *
56
- * The generated insert/update schemas store every zoned `field.timestamp` value in that
57
- * same fixed-width UTC form, because SQLite and D1 compare the TEXT column as text: a row
58
- * sent as `2026-09-21T01:00:00+05:00` (20:00Z) and a bound of `2026-09-20T21:00:00+00:00`
59
- * only order correctly once both are spelled in UTC. A naive value names no zone, so it is
60
- * never guessed at. Postgres compares timestamptz instants and reads either spelling the
61
- * same way. The rebuilt string is the ECMAScript date-time format `Date.parse` must accept,
62
- * so this does not rely on an engine reading `+05` or a six-digit fraction.
62
+ * The generated insert/update schemas store a `field.timestamp` instant by the same rule
63
+ * (codegen-ts `utcIsoTimestamp`), because SQLite and D1 compare the TEXT column as text: a
64
+ * row sent as `2026-09-21T01:00:00+05:00` (20:00Z) and a bound of `2026-09-20T21:00:00+00:00`
65
+ * only order correctly once both are spelled in UTC. Postgres compares timestamptz instants
66
+ * and reads either spelling the same way. The string handed to `Date.parse` is the
67
+ * ECMAScript date-time format it must accept, so this does not rely on an engine reading
68
+ * `+05`, a six-digit fraction, or a zoneless string (which ECMAScript reads as LOCAL time).
63
69
  */
64
- export function utcIsoIfZoned(s) {
65
- const m = ZONED_TIMESTAMP_RE.exec(s);
70
+ function utcIso(s, zonelessIsUtc) {
71
+ if (CANONICAL_UTC_RE.test(s))
72
+ return s;
73
+ const m = TIMESTAMP_PARTS_RE.exec(s);
66
74
  if (m === null)
67
75
  return s;
68
76
  const [, date, hm, sec, frac, z, oh, om] = m;
77
+ const zoned = z !== undefined || oh !== undefined;
78
+ if (!zoned && !zonelessIsUtc)
79
+ return s;
69
80
  const ms = (frac ?? "").slice(0, 3).padEnd(3, "0");
70
- const t = Date.parse(`${date}T${hm}:${sec ?? "00"}.${ms}${z === undefined ? `${oh}:${om ?? "00"}` : "Z"}`);
71
- return Number.isNaN(t) ? s : new Date(t).toISOString();
81
+ const t = Date.parse(`${date}T${hm ?? "00:00"}:${sec ?? "00"}.${ms}${oh === undefined ? "Z" : `${oh}:${om ?? "00"}`}`);
82
+ return Number.isNaN(t) ? s : new Date(t).toISOString().replace(/\.?0+Z$/, "Z");
83
+ }
84
+ /** A zoned timestamp bound in UTC; a naive or date-only one unchanged (a wall clock). */
85
+ export function utcIsoIfZoned(s) {
86
+ return utcIso(s, false);
87
+ }
88
+ /**
89
+ * A `field.timestamp` INSTANT bound (not `@localTime`) in UTC: a zoned value at its
90
+ * instant, a zoneless one read as UTC, a date alone as midnight UTC — the rule the
91
+ * generated write schema (codegen-ts `utcIsoTimestamp`) stores the column by. A default
92
+ * timestamp's wire form is "always UTC" (docs/features/api-contract.md, "Type encodings").
93
+ */
94
+ export function utcIsoInstant(s) {
95
+ return utcIso(s, true);
96
+ }
97
+ /**
98
+ * A timestamp bound whose offset arrived as a space: `…T00:00:00+00:00` sent unencoded in a
99
+ * query string, where `+` decodes to a space, reaches the parser as `…T00:00:00 00:00`.
100
+ */
101
+ const SPACE_FOR_PLUS_OFFSET_RE = /^\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)? \d{2}(?::?\d{2})?$/;
102
+ /** The `hint` for a timestamp bound that fails only because its `+` offset was not encoded. */
103
+ export const PLUS_OFFSET_HINT = "a \"+\" in a query string decodes to a space: URL-encode the offset's \"+\" as %2B, or use Z for UTC";
104
+ export function looksLikeUnencodedPlusOffset(s) {
105
+ return SPACE_FOR_PLUS_OFFSET_RE.test(s);
72
106
  }
73
107
  /** For a `datetime` rule with no `format` (generated before it existed): any of the three. */
74
108
  export function matchesAnyTemporal(s) {
@@ -1 +1 @@
1
- {"version":3,"file":"filter-value-format.js","sourceRoot":"","sources":["../../src/drizzle-fastify/filter-value-format.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"filter-value-format.js","sourceRoot":"","sources":["../../src/drizzle-fastify/filter-value-format.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,21 @@
22
22
  */
23
23
  import type { FastifyReply, FastifyRequest, RouteShorthandOptions } from "fastify";
24
24
  export declare function contractRouteErrorHandler(error: unknown, _request: FastifyRequest, reply: FastifyReply): FastifyReply;
25
- /** The adopter's route options plus the contract error handler — unless they set their own. */
25
+ /**
26
+ * `onRequest` hook: on a bodyless method whose body is EMPTY, drop a declared
27
+ * `content-type` so Fastify has nothing to parse.
28
+ *
29
+ * Many HTTP clients send `content-type: application/json` on every request. Fastify's JSON
30
+ * parser refuses an empty body declared as JSON (`FST_ERR_CTP_EMPTY_JSON_BODY`), which the
31
+ * handler above answers as `invalid_json` — so `DELETE /rentals/3` with that header and no
32
+ * body was a 400. With no content-type and no body, Fastify skips parsing and the route
33
+ * runs. A DELETE that DOES carry bytes is parsed as before, and POST/PUT/PATCH are never
34
+ * touched: an empty body there is still `invalid_json`.
35
+ */
36
+ export declare function acceptEmptyBodyOnBodylessMethod(request: FastifyRequest, _reply: FastifyReply, done: () => void): void;
37
+ /**
38
+ * The adopter's route options plus the contract error handler — unless they set their own —
39
+ * and the empty-body hook above, ahead of any `onRequest` hooks the adopter passed.
40
+ */
26
41
  export declare function withContractErrorHandler(ro: RouteShorthandOptions | undefined): RouteShorthandOptions;
27
42
  //# sourceMappingURL=route-error-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"route-error-handler.d.ts","sourceRoot":"","sources":["../../src/drizzle-fastify/route-error-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAWnF,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,YAAY,GAClB,YAAY,CAQd;AAED,+FAA+F;AAC/F,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,qBAAqB,GAAG,SAAS,GAAG,qBAAqB,CAIrG"}
1
+ {"version":3,"file":"route-error-handler.d.ts","sourceRoot":"","sources":["../../src/drizzle-fastify/route-error-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAWnF,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,YAAY,GAClB,YAAY,CAQd;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,MAAM,IAAI,GACf,IAAI,CAWN;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,qBAAqB,GAAG,SAAS,GAAG,qBAAqB,CAMrG"}
@@ -31,11 +31,40 @@ export function contractRouteErrorHandler(error, _request, reply) {
31
31
  logUnexpectedError(error);
32
32
  return reply.code(HTTP_STATUS_INTERNAL).send(INTERNAL_ERROR_BODY);
33
33
  }
34
- /** The adopter's route options plus the contract error handler — unless they set their own. */
34
+ /** Methods that carry no request body in the contract. Fastify already skips parsing for
35
+ * GET and HEAD, but it parses a DELETE body like a POST one. */
36
+ const BODYLESS_METHODS = new Set(["GET", "HEAD", "DELETE"]);
37
+ /**
38
+ * `onRequest` hook: on a bodyless method whose body is EMPTY, drop a declared
39
+ * `content-type` so Fastify has nothing to parse.
40
+ *
41
+ * Many HTTP clients send `content-type: application/json` on every request. Fastify's JSON
42
+ * parser refuses an empty body declared as JSON (`FST_ERR_CTP_EMPTY_JSON_BODY`), which the
43
+ * handler above answers as `invalid_json` — so `DELETE /rentals/3` with that header and no
44
+ * body was a 400. With no content-type and no body, Fastify skips parsing and the route
45
+ * runs. A DELETE that DOES carry bytes is parsed as before, and POST/PUT/PATCH are never
46
+ * touched: an empty body there is still `invalid_json`.
47
+ */
48
+ export function acceptEmptyBodyOnBodylessMethod(request, _reply, done) {
49
+ const headers = request.raw.headers;
50
+ if (BODYLESS_METHODS.has(request.method) &&
51
+ headers["content-type"] !== undefined &&
52
+ headers["transfer-encoding"] === undefined &&
53
+ (headers["content-length"] === undefined || headers["content-length"] === "0")) {
54
+ delete headers["content-type"];
55
+ }
56
+ done();
57
+ }
58
+ /**
59
+ * The adopter's route options plus the contract error handler — unless they set their own —
60
+ * and the empty-body hook above, ahead of any `onRequest` hooks the adopter passed.
61
+ */
35
62
  export function withContractErrorHandler(ro) {
36
63
  const base = ro ?? {};
64
+ const adopterHooks = base.onRequest === undefined ? [] : Array.isArray(base.onRequest) ? base.onRequest : [base.onRequest];
65
+ const withHook = { ...base, onRequest: [acceptEmptyBodyOnBodylessMethod, ...adopterHooks] };
37
66
  if (base.errorHandler !== undefined)
38
- return base;
39
- return { ...base, errorHandler: contractRouteErrorHandler };
67
+ return withHook;
68
+ return { ...withHook, errorHandler: contractRouteErrorHandler };
40
69
  }
41
70
  //# sourceMappingURL=route-error-handler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"route-error-handler.js","sourceRoot":"","sources":["../../src/drizzle-fastify/route-error-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,UAAU,yBAAyB,CACvC,KAAc,EACd,QAAwB,EACxB,KAAmB;IAEnB,IAAI,wBAAwB,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACrE,CAAC;IACD,wFAAwF;IACxF,IAAI,uBAAuB,CAAC,KAAK,CAAC;QAAE,MAAM,KAAK,CAAC;IAChD,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AACpE,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,wBAAwB,CAAC,EAAqC;IAC5E,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC;IACtB,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACjD,OAAO,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,yBAAyB,EAAE,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"route-error-handler.js","sourceRoot":"","sources":["../../src/drizzle-fastify/route-error-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,EACvB,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,UAAU,yBAAyB,CACvC,KAAc,EACd,QAAwB,EACxB,KAAmB;IAEnB,IAAI,wBAAwB,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACrE,CAAC;IACD,wFAAwF;IACxF,IAAI,uBAAuB,CAAC,KAAK,CAAC;QAAE,MAAM,KAAK,CAAC;IAChD,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC1B,OAAO,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;AACpE,CAAC;AAED;iEACiE;AACjE,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEjF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,+BAA+B,CAC7C,OAAuB,EACvB,MAAoB,EACpB,IAAgB;IAEhB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;IACpC,IACE,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;QACpC,OAAO,CAAC,cAAc,CAAC,KAAK,SAAS;QACrC,OAAO,CAAC,mBAAmB,CAAC,KAAK,SAAS;QAC1C,CAAC,OAAO,CAAC,gBAAgB,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC,KAAK,GAAG,CAAC,EAC9E,CAAC;QACD,OAAO,OAAO,CAAC,cAAc,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,EAAE,CAAC;AACT,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,EAAqC;IAC5E,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC;IACtB,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3H,MAAM,QAAQ,GAA0B,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,CAAC,+BAA+B,EAAE,GAAG,YAAY,CAAC,EAAE,CAAC;IACnH,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IACrD,OAAO,EAAE,GAAG,QAAQ,EAAE,YAAY,EAAE,yBAAyB,EAAE,CAAC;AAClE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metaobjectsdev/runtime-ts",
3
- "version": "1.0.9-rc.4",
3
+ "version": "1.0.9-rc.5",
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.9-rc.4",
68
- "@metaobjectsdev/render": "1.0.9-rc.4",
67
+ "@metaobjectsdev/metadata": "1.0.9-rc.5",
68
+ "@metaobjectsdev/render": "1.0.9-rc.5",
69
69
  "qs": "^6.13.0"
70
70
  },
71
71
  "peerDependencies": {
@@ -59,6 +59,22 @@ export interface FilterFieldRule {
59
59
  * still checked against the union of the three temporal formats.
60
60
  */
61
61
  readonly format?: FilterValueFormat;
62
+ /**
63
+ * `format: "timestamp"` only. Set by codegen for a `field.timestamp` that is an instant —
64
+ * the default, i.e. NOT `@localTime`. A bound with no zone is then read as UTC and a
65
+ * date-only bound as midnight UTC, the same rule the generated write schema stores such
66
+ * a value by, so `filter[dueAt][gte]=2026-10-06T00:00:00Z` finds a row sent as
67
+ * `"2026-10-06"`. Absent (an `@localTime` wall clock, or an allowlist generated before
68
+ * this existed), only a bound that carries a zone is rewritten to UTC.
69
+ */
70
+ readonly instant?: boolean;
71
+ /**
72
+ * `subType: "number"` only. Set by codegen for `field.int` / `field.long` /
73
+ * `field.currency` (integer minor units): a bound that is not a whole number
74
+ * (`filter[dailyRateCents][gte]=40.5`) answers `invalid_filter_value`. Absent, any
75
+ * finite number is accepted, as before.
76
+ */
77
+ readonly integer?: boolean;
62
78
  /**
63
79
  * The declared members of a `field.enum` (`@values`), set by codegen. A value that is
64
80
  * not a member is rejected with `invalid_filter_value`. Absent, the parser falls back
@@ -10,7 +10,10 @@ import { FilterParseError, parsePageBound, SORT_EXPECTED } from "./list-params.j
10
10
  // Re-exported so existing importers keep one door; the definitions live in the
11
11
  // drizzle-free list-params module, which the ObjectManager Fastify mount also uses.
12
12
  export { FilterParseError, parsePageBound, PAGINATION_EXPECTED, RAW_VIEW_MAX_LIMIT, SORT_EXPECTED } from "./list-params.js";
13
- import { ANY_TEMPORAL_EXPECTED, FORMAT_EXPECTED, matchesAnyTemporal, matchesFormat, utcIsoIfZoned } from "./filter-value-format.js";
13
+ import {
14
+ ANY_TEMPORAL_EXPECTED, FORMAT_EXPECTED, PLUS_OFFSET_HINT,
15
+ looksLikeUnencodedPlusOffset, matchesAnyTemporal, matchesFormat, utcIsoIfZoned, utcIsoInstant,
16
+ } from "./filter-value-format.js";
14
17
  import { FIELD_SUBTYPE_TIMESTAMP } from "@metaobjectsdev/metadata";
15
18
 
16
19
  // biome-ignore lint/suspicious/noExplicitAny: dynamic dispatch over user's Drizzle table
@@ -273,9 +276,10 @@ function invalidValue(
273
276
  expected: string,
274
277
  extra: Record<string, unknown> = {},
275
278
  ): FilterParseError {
279
+ const hint = typeof extra["hint"] === "string" ? ` Hint: ${extra["hint"]}.` : "";
276
280
  return new FilterParseError(
277
281
  "filter.invalid_value",
278
- `Field "${field}" op "${op}" requires ${expected}, got "${s}".`,
282
+ `Field "${field}" op "${op}" requires ${expected}, got "${s}".${hint}`,
279
283
  { field, op, expected, ...extra },
280
284
  );
281
285
  }
@@ -299,7 +303,15 @@ function assertWellFormed(s: string, rule: FilterFieldRule, col: unknown, field:
299
303
  throw invalidValue(field, op, s, `one of: ${members.join(", ")}`, { allowed: [...members] });
300
304
  }
301
305
  if (rule.format !== undefined) {
302
- if (!matchesFormat(rule.format, s)) throw invalidValue(field, op, s, FORMAT_EXPECTED[rule.format]);
306
+ if (!matchesFormat(rule.format, s)) {
307
+ // `filter[dueAt][lt]=2026-10-06T00:00:00+00:00` sent unencoded arrives with a space
308
+ // where the `+` was; "expected timestamp" alone does not say why a valid-looking
309
+ // value failed, so the answer names the fix.
310
+ const hint = rule.format === FIELD_SUBTYPE_TIMESTAMP && looksLikeUnencodedPlusOffset(s)
311
+ ? { hint: PLUS_OFFSET_HINT }
312
+ : {};
313
+ throw invalidValue(field, op, s, FORMAT_EXPECTED[rule.format], hint);
314
+ }
303
315
  } else if (rule.subType === "datetime" && !matchesAnyTemporal(s)) {
304
316
  throw invalidValue(field, op, s, ANY_TEMPORAL_EXPECTED);
305
317
  }
@@ -310,15 +322,27 @@ function coerce(value: unknown, rule: FilterFieldRule, col: unknown, field: stri
310
322
  if (value === null || value === undefined) return null;
311
323
  const s = typeof value === "string" ? value : String(value);
312
324
  assertWellFormed(s, rule, col, field, op);
313
- // A zoned timestamp bound is compared in the same UTC spelling the generated schemas
314
- // store (see utcIsoIfZoned): on SQLite/D1 the column is TEXT and compares as text. A
315
- // Date-bound (`dateValues`) column parses the instant itself and is left alone.
316
- if (rule.format === FIELD_SUBTYPE_TIMESTAMP && rule.dateValues !== true) {
317
- return coerceAs(utcIsoIfZoned(s), rule.subType, field, op, rule.dateValues);
325
+ // A timestamp bound is compared in the same UTC spelling the generated schemas store:
326
+ // on SQLite/D1 the column is TEXT and compares as text. An instant field (`instant`, i.e.
327
+ // not @localTime) reads a zoneless or date-only bound as UTC, as its write schema does —
328
+ // also before a Date-bound (`dateValues`) column's `new Date(...)`, which would otherwise
329
+ // read a zoneless string in the SERVER's local zone. Without `instant`, only a zoned
330
+ // bound is rewritten, and a Date-bound column parses the value itself.
331
+ if (rule.format === FIELD_SUBTYPE_TIMESTAMP) {
332
+ const bound = rule.instant === true ? utcIsoInstant(s) : rule.dateValues === true ? s : utcIsoIfZoned(s);
333
+ return coerceAs(bound, rule.subType, field, op, rule.dateValues);
318
334
  }
319
- return coerceAs(s, rule.subType, field, op, rule.dateValues);
335
+ const coerced = coerceAs(s, rule.subType, field, op, rule.dateValues);
336
+ // field.int / field.long / field.currency: a fractional bound is not a value of the field.
337
+ if (rule.integer === true && typeof coerced === "number" && !Number.isInteger(coerced)) {
338
+ throw invalidValue(field, op, s, INTEGER_EXPECTED);
339
+ }
340
+ return coerced;
320
341
  }
321
342
 
343
+ /** `expected` for a non-whole bound on an integer-valued field (`integer: true`). */
344
+ const INTEGER_EXPECTED = "integer (a whole number)";
345
+
322
346
  function coerceAs(value: unknown, subType: string, field: string, op: string, dateValues?: boolean): unknown {
323
347
  if (value === null || value === undefined) return null;
324
348
  const s = typeof value === "string" ? value : String(value);
@@ -62,29 +62,69 @@ export function matchesFormat(format: FilterValueFormat, s: string): boolean {
62
62
  return CHECKS[format](s);
63
63
  }
64
64
 
65
- /** A timestamp with a time part AND an explicit zone (`Z` or `±HH[[:]MM]`). */
66
- const ZONED_TIMESTAMP_RE =
67
- /^(\d{4}-\d{2}-\d{2})[Tt ](\d{2}:\d{2})(?::(\d{2})(?:\.(\d+))?)?(?:([Zz])|([+-]\d{2}):?(\d{2})?)$/;
65
+ /** A timestamp: a date, then optionally a time part, then optionally a zone (`Z` or `±HH[[:]MM]`). */
66
+ const TIMESTAMP_PARTS_RE =
67
+ /^(\d{4}-\d{2}-\d{2})(?:[Tt ](\d{2}:\d{2})(?::(\d{2})(?:\.(\d+))?)?(?:([Zz])|([+-]\d{2}):?(\d{2})?)?)?$/;
68
+
69
+ /** Already the canonical UTC spelling: `YYYY-MM-DDTHH:MM:SS[.f…]Z`. Kept byte-for-byte. */
70
+ const CANONICAL_UTC_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;
68
71
 
69
72
  /**
70
- * A zoned timestamp bound rewritten to its instant's `toISOString()` spelling; any other
71
- * value (a naive timestamp, a date-only bound) is returned unchanged.
73
+ * A timestamp bound in the canonical UTC spelling of its instant — `YYYY-MM-DDTHH:MM:SS[.fff]Z`,
74
+ * millisecond resolution, no trailing zeros, no fraction when it is zero (the wire form
75
+ * fixtures/persistence-conformance/normalization.md pins). A value already spelled that way
76
+ * is returned as sent; any other value carrying a zone is rewritten; a zoneless or date-only
77
+ * value only when `zonelessIsUtc`, and then read as UTC (a date alone as midnight UTC).
78
+ * Anything else is returned unchanged.
72
79
  *
73
- * The generated insert/update schemas store every zoned `field.timestamp` value in that
74
- * same fixed-width UTC form, because SQLite and D1 compare the TEXT column as text: a row
75
- * sent as `2026-09-21T01:00:00+05:00` (20:00Z) and a bound of `2026-09-20T21:00:00+00:00`
76
- * only order correctly once both are spelled in UTC. A naive value names no zone, so it is
77
- * never guessed at. Postgres compares timestamptz instants and reads either spelling the
78
- * same way. The rebuilt string is the ECMAScript date-time format `Date.parse` must accept,
79
- * so this does not rely on an engine reading `+05` or a six-digit fraction.
80
+ * The generated insert/update schemas store a `field.timestamp` instant by the same rule
81
+ * (codegen-ts `utcIsoTimestamp`), because SQLite and D1 compare the TEXT column as text: a
82
+ * row sent as `2026-09-21T01:00:00+05:00` (20:00Z) and a bound of `2026-09-20T21:00:00+00:00`
83
+ * only order correctly once both are spelled in UTC. Postgres compares timestamptz instants
84
+ * and reads either spelling the same way. The string handed to `Date.parse` is the
85
+ * ECMAScript date-time format it must accept, so this does not rely on an engine reading
86
+ * `+05`, a six-digit fraction, or a zoneless string (which ECMAScript reads as LOCAL time).
80
87
  */
81
- export function utcIsoIfZoned(s: string): string {
82
- const m = ZONED_TIMESTAMP_RE.exec(s);
88
+ function utcIso(s: string, zonelessIsUtc: boolean): string {
89
+ if (CANONICAL_UTC_RE.test(s)) return s;
90
+ const m = TIMESTAMP_PARTS_RE.exec(s);
83
91
  if (m === null) return s;
84
92
  const [, date, hm, sec, frac, z, oh, om] = m;
93
+ const zoned = z !== undefined || oh !== undefined;
94
+ if (!zoned && !zonelessIsUtc) return s;
85
95
  const ms = (frac ?? "").slice(0, 3).padEnd(3, "0");
86
- const t = Date.parse(`${date}T${hm}:${sec ?? "00"}.${ms}${z === undefined ? `${oh}:${om ?? "00"}` : "Z"}`);
87
- return Number.isNaN(t) ? s : new Date(t).toISOString();
96
+ const t = Date.parse(`${date}T${hm ?? "00:00"}:${sec ?? "00"}.${ms}${oh === undefined ? "Z" : `${oh}:${om ?? "00"}`}`);
97
+ return Number.isNaN(t) ? s : new Date(t).toISOString().replace(/\.?0+Z$/, "Z");
98
+ }
99
+
100
+ /** A zoned timestamp bound in UTC; a naive or date-only one unchanged (a wall clock). */
101
+ export function utcIsoIfZoned(s: string): string {
102
+ return utcIso(s, false);
103
+ }
104
+
105
+ /**
106
+ * A `field.timestamp` INSTANT bound (not `@localTime`) in UTC: a zoned value at its
107
+ * instant, a zoneless one read as UTC, a date alone as midnight UTC — the rule the
108
+ * generated write schema (codegen-ts `utcIsoTimestamp`) stores the column by. A default
109
+ * timestamp's wire form is "always UTC" (docs/features/api-contract.md, "Type encodings").
110
+ */
111
+ export function utcIsoInstant(s: string): string {
112
+ return utcIso(s, true);
113
+ }
114
+
115
+ /**
116
+ * A timestamp bound whose offset arrived as a space: `…T00:00:00+00:00` sent unencoded in a
117
+ * query string, where `+` decodes to a space, reaches the parser as `…T00:00:00 00:00`.
118
+ */
119
+ const SPACE_FOR_PLUS_OFFSET_RE =
120
+ /^\d{4}-\d{2}-\d{2}[Tt ]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)? \d{2}(?::?\d{2})?$/;
121
+
122
+ /** The `hint` for a timestamp bound that fails only because its `+` offset was not encoded. */
123
+ export const PLUS_OFFSET_HINT =
124
+ "a \"+\" in a query string decodes to a space: URL-encode the offset's \"+\" as %2B, or use Z for UTC";
125
+
126
+ export function looksLikeUnencodedPlusOffset(s: string): boolean {
127
+ return SPACE_FOR_PLUS_OFFSET_RE.test(s);
88
128
  }
89
129
 
90
130
  /** For a `datetime` rule with no `format` (generated before it existed): any of the three. */
@@ -46,9 +46,46 @@ export function contractRouteErrorHandler(
46
46
  return reply.code(HTTP_STATUS_INTERNAL).send(INTERNAL_ERROR_BODY);
47
47
  }
48
48
 
49
- /** The adopter's route options plus the contract error handler — unless they set their own. */
49
+ /** Methods that carry no request body in the contract. Fastify already skips parsing for
50
+ * GET and HEAD, but it parses a DELETE body like a POST one. */
51
+ const BODYLESS_METHODS: ReadonlySet<string> = new Set(["GET", "HEAD", "DELETE"]);
52
+
53
+ /**
54
+ * `onRequest` hook: on a bodyless method whose body is EMPTY, drop a declared
55
+ * `content-type` so Fastify has nothing to parse.
56
+ *
57
+ * Many HTTP clients send `content-type: application/json` on every request. Fastify's JSON
58
+ * parser refuses an empty body declared as JSON (`FST_ERR_CTP_EMPTY_JSON_BODY`), which the
59
+ * handler above answers as `invalid_json` — so `DELETE /rentals/3` with that header and no
60
+ * body was a 400. With no content-type and no body, Fastify skips parsing and the route
61
+ * runs. A DELETE that DOES carry bytes is parsed as before, and POST/PUT/PATCH are never
62
+ * touched: an empty body there is still `invalid_json`.
63
+ */
64
+ export function acceptEmptyBodyOnBodylessMethod(
65
+ request: FastifyRequest,
66
+ _reply: FastifyReply,
67
+ done: () => void,
68
+ ): void {
69
+ const headers = request.raw.headers;
70
+ if (
71
+ BODYLESS_METHODS.has(request.method) &&
72
+ headers["content-type"] !== undefined &&
73
+ headers["transfer-encoding"] === undefined &&
74
+ (headers["content-length"] === undefined || headers["content-length"] === "0")
75
+ ) {
76
+ delete headers["content-type"];
77
+ }
78
+ done();
79
+ }
80
+
81
+ /**
82
+ * The adopter's route options plus the contract error handler — unless they set their own —
83
+ * and the empty-body hook above, ahead of any `onRequest` hooks the adopter passed.
84
+ */
50
85
  export function withContractErrorHandler(ro: RouteShorthandOptions | undefined): RouteShorthandOptions {
51
86
  const base = ro ?? {};
52
- if (base.errorHandler !== undefined) return base;
53
- return { ...base, errorHandler: contractRouteErrorHandler };
87
+ const adopterHooks = base.onRequest === undefined ? [] : Array.isArray(base.onRequest) ? base.onRequest : [base.onRequest];
88
+ const withHook: RouteShorthandOptions = { ...base, onRequest: [acceptEmptyBodyOnBodylessMethod, ...adopterHooks] };
89
+ if (base.errorHandler !== undefined) return withHook;
90
+ return { ...withHook, errorHandler: contractRouteErrorHandler };
54
91
  }