Skip to content

Commit 0771fef

Browse files
committed
chore(changeset): rest + runtime patch for the dispatcher /meta read parity
Claude-Session: https://claude.ai/code/session_01UYBdGBzWSrAMzpW8ah3GbP Co-authored-by: Claude <noreply@anthropic.com>
1 parent 3e23ca9 commit 0771fef

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
'@objectstack/rest': patch
3+
'@objectstack/runtime': patch
4+
---
5+
6+
fix(rest, runtime): the runtime dispatcher's `/meta` reads answer what `RestServer`'s answer — one list chain, one `public`-audience predicate, and the `?state=draft` read (#20320)
7+
8+
Clause-②: no
9+
10+
A host that mounts only the `${prefix}/*` catch-all (`createHonoApp`, and any
11+
adapter written on the public `HttpDispatcher` API) serves `/meta` through the
12+
runtime dispatcher. Its reads now give the same answers as `RestServer`'s
13+
`GET /meta/:type` and `GET /meta/:type/:name`. Until now a dispatcher-only host
14+
answered:
15+
16+
- **`GET /meta/app?id=crm`** — every app the caller may see, not `[crm]`. An
17+
`?id=` that matches nothing listed every app instead of an empty list.
18+
- **`GET /meta/view?object=lead`** — every view, not the lead views sorted for
19+
the switcher.
20+
- **`GET /meta/docs`** (the plural spelling) — every doc WITH its body. The
21+
content slim compared the raw segment, so it ran only for `/meta/doc`.
22+
- **any doc list** — each doc with its `translations` map and in no locale.
23+
`RestServer` collapses each doc to the request's locale.
24+
- **every translatable list** (`app`, `view`, `object`, `page`, `dashboard`,
25+
`action`, `dataset`) — untranslated labels, whatever `Accept-Language` or
26+
`?locale=` asked for, and no `Vary: Accept-Language` header.
27+
- **`GET /meta/api`** — every stored `api` declaration, including ones the
28+
endpoint matcher does not serve (their routes answer 404).
29+
- **an anonymous `GET` of a `public` book or doc** (list or item) —
30+
`401 UNAUTHENTICATED`. `RestServer` serves it (ADR-0046 §6.7).
31+
- **`GET /meta/:type/:name?state=draft` from a caller who may read drafts** —
32+
the ACTIVE item. It should be the pending draft, whole for a caller who may
33+
save the app and pruned per caller for everyone else, or `404 NO_DRAFT` when
34+
nothing is pending. A caller who may not read drafts is still answered the
35+
plain read, byte for byte.
36+
37+
**What changed.** The list route's whole post-read chain moved out of
38+
`RestServer` into `createMetaListAnswer` in `@objectstack/rest`, unchanged. That
39+
chain is the `api` served-set face, the per-caller list gate, `?id=`,
40+
`?object=`, the doc locale collapse and content slim, the transport's own
41+
object mask, and the translation. Every exit of the dispatcher's list branch
42+
now hands its answer to that same function. The anonymous gates on both
43+
transports ask one exported predicate, `isPublicAudienceRead`. It admits only
44+
`GET` reads of book and doc, so every other type keeps the anonymous deny, and
45+
the §6.7 audience gate still refuses `org` and `{ permissionSet }` audiences.
46+
The dispatcher's `?state=draft` read runs the exported
47+
`STORED_VERSION_DOOR_POLICY`, the constant `RestServer`'s draft branch runs.
48+
49+
`RestServer`'s own answers are unchanged: the move is a refactor on that side,
50+
and every existing REST test passes unedited.
51+
52+
New exports from `@objectstack/rest`: `createMetaListAnswer`,
53+
`translateMetaList`, `metaRequestLocale`, `isPublicAudienceRead`,
54+
`STORED_VERSION_DOOR_POLICY` and their types. Nothing is removed or renamed.

0 commit comments

Comments
 (0)