Skip to content

[finding] package-routes.ts re-declares getMetaItems/deletePackage as a narrower local structural type instead of reading the spec's #9846

Description

@huangyiirene

Observed while implementing #9805 (typing the non-door getMetaItems request literals in rest-server.ts). Recording it rather than widening that card — different file, and the fix needs a judgement call this observation does not make.

The observation

PackageRoutesOptions in packages/rest/src/package-routes.ts (around :237) declares its protocol option as a hand-rolled structural shape:

protocol?: {getMetaItems?(req: {type: string}): Promise<{items: any[]}>;deletePackage?(req: {packageId: string;actor?: string;allTenants?: boolean}): Promise<>;};

Both verbs are already declared in packages/specgetMetaItems(request: GetMetaItemsRequest): Promise< GetMetaItemsResponse > on MetadataProtocol (protocol.zod.ts), where the request carries type, packageId, organizationId and (since #9741) previewDrafts. The local re-declaration names only type, and its response names only items (the spec's also carries type).

Not asserted: no defect today. Both call sites (:486, :555) pass exactly { type: 'package' }, which is a valid GetMetaItemsRequest, and both read result?.items defensively. Nothing is broken.

What it is, is the same blindness class #9805 was filed about, one level up: the request type is re-stated locally rather than read from the spec, so the spec is free to move underneath it — a narrowed type vocabulary, a newly required member, a renamed key — and this module keeps compiling green against a shape the protocol no longer has. #9805's sibling sites got compiler coverage by naming the declared type; these two did not, because there is no declared type at this seam to name.

The judgement this does not make: MetadataProtocol declares getMetaItems as a required member while this option declares it optional and feature-detects it at both call sites (typeof … === 'function'). So this cannot simply be swapped for MetadataProtocol — either the option type keeps its optionality while sourcing the request/response types from the spec (getMetaItems?(req: GetMetaItemsRequest): Promise< GetMetaItemsResponse >), or the seam changes what it tolerates, which is a behaviour question. The narrow version is the cheap half and probably the right one.

Repo: objectstack. File: packages/rest/src/package-routes.ts. Related: #9805 (where this was seen; the PR there names it as out of scope), #9741 (the declared meta-read request shapes and the TransportScopedMetaRequest envelope).


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions