Skip to content

Commit f60be9b

Browse files
Elon Muskclaude
andauthored
docs(rest): give registerMetadataEndpointsInner the JSDoc header it never had (#10037)
It was the only `registerXxxEndpoints` in the class without one, and the largest and most-mounted of them. The header records what the signature cannot show: that `this.routeManager` is a wrapping registrar for the duration of the call (which is why the body is a separate method at all), that `basePath` makes the body run once per base and is the sole source of `isScoped`, which route families mount here, and the two ordering facts that are load-bearing rather than cosmetic. Comment-only. No behaviour, no imports, no test. Claude-Session: https://claude.ai/code/session_019bmVFqoQPq63zhKrxdYG1r Co-authored-by: Claude <noreply@anthropic.com>
1 parent c1731d0 commit f60be9b

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

packages/rest/src/rest-server.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3706,6 +3706,53 @@ export class RestServer {
37063706
}
37073707
}
37083708

3709+
/**
3710+
* The metadata route table itself — every `{basePath}{metadata.prefix}/…`
3711+
* route, in one body so that they share one registration order.
3712+
*
3713+
* ⚠️ **`this.routeManager` is not the real route manager while this
3714+
* runs.** {@link registerMetadataEndpoints} swaps in a wrapping registrar
3715+
* for exactly the duration of this call and restores it in a `finally`,
3716+
* so every `register(...)` below is handed a handler already wrapped in
3717+
* the anonymous-deny gate. That swap is why this body is a separate
3718+
* method rather than inlined — it needs a call boundary to scope it to.
3719+
* Two consequences when editing here: a route added below inherits the
3720+
* gate for free (the point — the next new route cannot forget it), and a
3721+
* route that must NOT be gated cannot simply be added below. It belongs
3722+
* outside the swap, with its own reason written down.
3723+
*
3724+
* **`basePath` decides both mount and shape, and this body runs once per
3725+
* base.** `registerRoutes` calls it for the unscoped base (`/api/v1`) and
3726+
* for the environment-scoped one (`/api/v1/environments/:environmentId`)
3727+
* per `enableProjectScoping` / `projectResolution`, so every route below
3728+
* is mounted up to twice. `isScoped` is derived from that string and from
3729+
* nothing else, and it alone decides whether a handler reads
3730+
* `req.params.environmentId` or passes `undefined`. Keep per-call state
3731+
* local: the two passes share this method, not their routes.
3732+
*
3733+
* What actually mounts is gated further by `metadata.endpoints.types` /
3734+
* `.items` / `.item` — the routes below are the maximum, not a guarantee.
3735+
*
3736+
* Families, in registration order: the type list (`/meta`, and its
3737+
* `/meta/types` spelling) → whole-store operations (`/diagnostics`,
3738+
* `/_drafts`, `/_migrate-stored`) → the per-type list (`/:type`) → the
3739+
* book tree (`/book/:name/tree`) → the per-item read/write
3740+
* (`/:type/:name`) with its sub-resources (`references`, `layers`,
3741+
* `history`, `audit`, `diff`, `publish`, `rollback`, `published`, and the
3742+
* object FSM read `state/:field`) → the compound-name twins spelled
3743+
* `/:type/:section/:name`.
3744+
*
3745+
* Two ordering facts are load-bearing rather than cosmetic. Matching is
3746+
* first-match-wins, so a literal-prefixed route must stay ABOVE the
3747+
* `:type`-parameterised route it shares a SEGMENT COUNT with — the three
3748+
* collisions that implies are pinned by
3749+
* `meta-route-registration-order.test.ts`, and dropping below the line is
3750+
* how `/meta/types` once answered as an empty metadata type. And a
3751+
* compound-name twin is the SAME operation reached by a name spelled in
3752+
* two segments, so a gate or an org scope added to one door must be added
3753+
* to its twin — gating one and not the other leaves the twin as the
3754+
* bypass.
3755+
*/
37093756
private registerMetadataEndpointsInner(basePath: string): void {
37103757
const { metadata } = this.config;
37113758
const metaPath = `${basePath}${metadata.prefix}`;

0 commit comments

Comments
 (0)