|
| 1 | +--- |
| 2 | +"@objectstack/plugin-hono-server": patch |
| 3 | +"@objectstack/hono": patch |
| 4 | +"@objectstack/runtime": patch |
| 5 | +--- |
| 6 | + |
| 7 | +fix(hono,plugin-hono-server,runtime): one CORS source and one registry key — the last derivable copies from the #3786 sweep |
| 8 | + |
| 9 | +Re-ran the sweep across all 72 packages. The earlier pass globbed `packages/*/src`, |
| 10 | +which is one level deep, so it missed everything under `packages/plugins/` and |
| 11 | +`packages/adapters/` — the "sweep is basically clean" report was based on an |
| 12 | +incomplete scan. |
| 13 | + |
| 14 | +**A stale CORS default, on the one description callers actually read.** |
| 15 | +`HonoCorsOptions.allowHeaders`' TSDoc promised |
| 16 | +`['Content-Type', 'Authorization', 'X-Requested-With']` "which is sufficient for |
| 17 | +cookie and bearer-token auth". The real default carries three more: |
| 18 | +`X-Tenant-ID` and `X-Environment-Id` (multi-tenant routing) and `If-Match` (the |
| 19 | +OCC token on record PATCHes, objectui#2572). Sizing a custom `allowHeaders` |
| 20 | +against that sentence drops all three and every cross-origin save fails with |
| 21 | +"Failed to fetch". |
| 22 | + |
| 23 | +The instructive part: **three** Hono CORS sites each carried their own copy of |
| 24 | +the defaults under "keep in sync" comments, and the copies all agreed. What |
| 25 | +drifted was the *doc* — the only description with no counterpart to be diffed |
| 26 | +against, and the only one a caller reads. |
| 27 | + |
| 28 | +Both defaults are now single constants, `DEFAULT_CORS_ALLOW_HEADERS` and |
| 29 | +`DEFAULT_CORS_EXPOSE_HEADERS`, exported from `@objectstack/plugin-hono-server` |
| 30 | +and imported by the adapter (which already depends on it — no new edge). The |
| 31 | +TSDoc links them rather than restating, and documents an asymmetry it never |
| 32 | +mentioned: `allowHeaders` REPLACES the default, `exposeHeaders` MERGES with it. |
| 33 | + |
| 34 | +`hono-plugin.test.ts` stopped stubbing `./adapter` wholesale and keeps the real |
| 35 | +constants via `importOriginal` — it asserts exact header lists, so a mocked copy |
| 36 | +would make the test agree with itself rather than with what ships. Verified: |
| 37 | +removing `If-Match` from the constant fails `should allow If-Match by default`, |
| 38 | +by name. |
| 39 | + |
| 40 | +**A third copy, in the public protocol docs.** `content/docs/protocol/kernel/ |
| 41 | +http-protocol.mdx` advertised `Access-Control-Allow-Headers: Authorization, |
| 42 | +Content-Type` — two of the six — and methods missing `PUT` and `HEAD`, with no |
| 43 | +mention of the exposed headers at all. That is the copy an integrator builds a |
| 44 | +client against: reading it, you would not know `If-Match` is permitted (so you |
| 45 | +would not attempt OCC) or that `set-auth-token` is readable (so a rotated |
| 46 | +session would look like a bug). Corrected, with the three non-obvious allowed |
| 47 | +headers and the two exposed ones explained, and a pointer to the constants as |
| 48 | +the source of truth. |
| 49 | + |
| 50 | +**A hand-copied service-registry key.** `runtime`'s share-links domain resolved |
| 51 | +`'shareLinks'` as a string literal, copied from `SHARE_LINK_SERVICE` — whose own |
| 52 | +doc-comment says "keep in sync with the SharingPlugin registration". It now |
| 53 | +imports the constant. A drifted copy resolves nothing, so every share link |
| 54 | +answers 501 "Sharing is not configured for this environment" on an environment |
| 55 | +where it is configured perfectly well. |
| 56 | + |
| 57 | +**Plus a duplicate ledger entry**, which is the same defect one level up: |
| 58 | +`check-generated.ts` carried two `NO_GENERATOR` entries for |
| 59 | +`check:strictness-ledger`, because #4203 and #4252 each added one without seeing |
| 60 | +the other. Functionally harmless (the ledger is read into a `Set`) but it leaves |
| 61 | +two comments telling overlapping versions of the same story. #4203's is kept — |
| 62 | +it is the more complete account and it is the PR that fixed the underlying |
| 63 | +problem. |
| 64 | + |
| 65 | +Checked and deliberately left alone: `ApprovalStatus` (5 values) and |
| 66 | +`ApprovalActionKind` (12 values) versus their `plugin-approvals` selects — diffed |
| 67 | +verbatim, no drift today, still hand-copied across a package boundary. |
0 commit comments