Skip to content

[finding] FindDataRequest.query declares the QueryAST, but the shipped findData ingress also accepts an undeclared wire dialect — so that one slot cannot be compiled #16066

Description

@os-litant

Measured while implementing #15866 (restoring the compile-time check on the REST layer's protocol dispatch sites). Handed back rather than acted on: closing it is a contract decision, not a door fix. ⛔ No severity asserted, no domain routing — that is triage's.

What was measured

#15866 retired the as any casts on 22 protocol-dispatch sites in packages/rest/src/rest-server.ts, typing each request literal against its declared spec contract. 19 of them compiled clean on the first try. Three did not, and all three failed on the same slot:

src/rest-server.ts(8992,34): error TS2353: Object literal may only specify known properties,
    and '$filter' does not exist in type 'QueryInput'.
src/rest-server.ts(9302,33): error TS2561: Object literal may only specify known properties,
    but '$top' does not exist in type 'QueryInput'. Did you mean to write 'top'?
src/rest-server.ts(10167,29): error TS2353: Object literal may only specify known properties,
    and 'filters' does not exist in type 'QueryInput'.

The three doors are the import-job listing, the export chunk loop, and the public reference picker.

The gap, stated from both ends

  • Declared. FindDataRequestSchema.query is QuerySchema, i.e. the QueryAST (packages/spec/src/api/protocol.zod.ts). That is the whole declared vocabulary for the slot.
  • Shipped. @objectstack/metadata-protocol's findData accepts a second dialect through the same slot and folds it: WIRE_QUERY_ALIAS_SLOTS and WIRE_DOLLAR_ALIASES in packages/metadata-protocol/src/protocol.ts map $top to top to limit, $orderby to orderBy, filter / filters / $filter to where, $expand to expand, and so on.

The normalizer's own comment names the situation exactly, which is why this is a gap and not a discovery:

The spec's alias table extended with the wire-only spellings no schema declares: filters (documented plural alias of the filter transport param) and the OData $filter / $expand.

⇒ Two dialects, one slot, one of them declared. Every caller of findData that speaks the wire dialect is unverifiable at build time, and there is no runtime rejection either — the fold accepts it.

⚠️ Why the two obvious repairs are both wrong

So the question this card actually asks is: does the wire dialect belong in the declared contract as its own named input type, or should these three server-built literals be rewritten to speak the canonical AST? Both are defensible and neither is a door's call to make.

What #15866 did in the meantime

It did not widen anything and did not rewrite the doors. It confined the erasure from one call wide to one slot wide, behind a named, greppable wireDialectQuery helper that carries this card's reasoning. At those three sites the method name, the arity and every other request member are now compiled; only the query value is not.

Not claimed

Not swept: whether callers of findData outside packages/rest speak the wire dialect too, and whether getData / the *Many siblings have an equivalent split. This was scoped to what restoring the check in rest-server.ts surfaced.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions