|
| 1 | +--- |
| 2 | +'@objectstack/rest': minor |
| 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-②: yes (widening) — `@objectstack/rest`'s root entry gains five value exports (`createMetaListAnswer`, `translateMetaList`, `metaRequestLocale`, `isPublicAudienceRead`, `STORED_VERSION_DOOR_POLICY`) and six type exports (`MetaListAnswer`, `MetaListAnswerSources`, `MetaListRequest`, `MetaListTranslationSources`, `MetaPublicReadRoute`, `MetaRequestHttp`), so its published surface grows; nothing it exported before is removed, renamed or narrowed. `@objectstack/runtime` publishes no new surface and stays a `patch`. |
| 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