From c1c35ba70a0cc6bfbbf41c14cadca61d4cddd773 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Nov 2026 04:01:18 +0000 Subject: [PATCH] docs(metadata-protocol, objectql): docblocks say a code package's objectExtensions are registered as extend contributors, never stored as items (#28874) Co-Authored-By: Claude --- .changeset/28874-object-extension-docblocks.md | 11 +++++++++++ .../src/protocol-object-extension-item.ts | 13 ++++++++----- packages/metadata-protocol/src/protocol.ts | 11 +++++++---- packages/objectql/src/registry.ts | 12 ++++++++---- 4 files changed, 34 insertions(+), 13 deletions(-) create mode 100644 .changeset/28874-object-extension-docblocks.md diff --git a/.changeset/28874-object-extension-docblocks.md b/.changeset/28874-object-extension-docblocks.md new file mode 100644 index 00000000000..79a4cfd528c --- /dev/null +++ b/.changeset/28874-object-extension-docblocks.md @@ -0,0 +1,11 @@ +--- +'@objectstack/metadata-protocol': patch +'@objectstack/objectql': patch +--- + +docs(metadata-protocol, objectql): three docblocks say where a code package's `objectExtensions` go: never stored as `object_extension` items or into the metadata service, but registered by the engine's `registerApp` as `'extend'` contributors (#28874) + +Clause-②: no +Metadata-protocol: none + +Comment only, with no behaviour change. The header of `protocol-object-extension-item.ts`, the `foldObjectExtendersFromRegistry` docblock in `protocol.ts` and the `SchemaRegistry#foldObjectExtendersOnto` docblock each said that a compiled artifact's `objectExtensions` are stored (as `object_extension` items, or as a separate collection of the metadata service). They are not. The ObjectQL engine's `registerApp` registers each one as an `'extend'` contributor of its target object. The artifact loader maps the collection to `object_extension` but files no item from it, because an extension carries `extend` and no `name`. The type's items are the stored rows the `/api/v1/meta` doors write. The wording matches the `@objectstack/spec` registry row comment (#28873). A patch changeset is used because the corrected docblocks ship in each package's `dist` declarations. diff --git a/packages/metadata-protocol/src/protocol-object-extension-item.ts b/packages/metadata-protocol/src/protocol-object-extension-item.ts index ac9becd8319..9cca7765995 100644 --- a/packages/metadata-protocol/src/protocol-object-extension-item.ts +++ b/packages/metadata-protocol/src/protocol-object-extension-item.ts @@ -4,11 +4,14 @@ * [#28574, ADR-0146 D10 / D2 / D3] An object extension is an authorable item * of a writable package. * - * `object_extension` is the type the artifact loader already stores a code - * package's `objectExtensions` under; since #28574 it is also a row a running - * deployment writes. Studio's add-field on a base object (N-23c) writes - * exactly this: an extension in the base's paired `.custom`, its fields - * suffixed `__c`, the base untouched. The row is stored under the writing + * A code package's `objectExtensions` are never stored as items of this type: + * the ObjectQL engine's `registerApp` registers each one as an `'extend'` + * contributor of its target object. The artifact loader maps that collection + * to this type name but files no item from it, because an extension carries + * `extend` and no `name`. This type's items are the stored rows the + * `/api/v1/meta` doors write (#28574). Studio's add-field on a base object + * (N-23c) writes exactly this: an extension in the base's paired `.custom`, + * its fields suffixed `__c`, the base untouched. The row is stored under the writing * package with the TARGET object's name as its row name — one extension per * package per target — and its body is `ObjectExtensionSchema` as it stands: * it carries `extend` and no `name`. diff --git a/packages/metadata-protocol/src/protocol.ts b/packages/metadata-protocol/src/protocol.ts index 7ffb87a253d..2d7039bbfa5 100644 --- a/packages/metadata-protocol/src/protocol.ts +++ b/packages/metadata-protocol/src/protocol.ts @@ -9350,10 +9350,13 @@ export class ObjectStackProtocolImplementation implements * object's resolved schema is DEFINED (ADR-0029 D9.2 / D9.6) as a base layer * with its `extend` contributors folded on, and the MetadataService copy is * only the base layer. A deployment that ingests a compiled artifact - * (`artifactSource`, i.e. every sealed/served runtime) registers `objects` - * and `objectExtensions` into that service as SEPARATE collections, so the - * body this method receives is the owner's declaration with no extender in - * it. Serving it unfolded is what made the showcase's three + * (`artifactSource`, i.e. every sealed/served runtime) registers its + * `objects` into that service, and its `objectExtensions` never reach it as + * items: the ObjectQL engine's `registerApp` registers each one as an + * `'extend'` contributor of its target object, and the artifact loader files + * no item from that collection, because an extension carries `extend` and no + * `name`. So the body this method receives is the owner's declaration with + * no extender in it. Serving it unfolded is what made the showcase's three * `objectExtensions` fields readable through `GET /meta/object`, writable * through the data API, and absent from `GET /meta/object/:name` — the read * the edit and new forms derive from. diff --git a/packages/objectql/src/registry.ts b/packages/objectql/src/registry.ts index 9165fce5f7c..0a5a0848469 100644 --- a/packages/objectql/src/registry.ts +++ b/packages/objectql/src/registry.ts @@ -5326,10 +5326,14 @@ export class SchemaRegistry { * Why this is public API rather than the protocol reaching for the * contributor list: `GET /meta/object/:name` reaches an object body through a * source this registry never sees — the copy `MetadataPlugin` registers into - * the `metadata` SERVICE when a deployment ingests a compiled artifact, where - * `objects` and `objectExtensions` are stored as SEPARATE collections. That - * body is ONE LAYER, and serving a layer as the resolved schema is what - * dropped every `objectExtensions` field from the by-name read (and from both + * the `metadata` SERVICE when a deployment ingests a compiled artifact. That + * service holds the owner's declaration only: a code package's + * `objectExtensions` are never stored there as items, because the ObjectQL + * engine's `registerApp` registers each one as an `'extend'` contributor + * here, and `MetadataPlugin` files no item from that collection (an + * extension carries `extend` and no `name`). That body is ONE LAYER, and + * serving a layer as the resolved schema is what dropped every + * `objectExtensions` field from the by-name read (and from both * layers of `?layers=true`) while `GET /meta/object` — which reads * `resolveObject` — kept them. Two folds would re-open exactly that seam one * level down, so there is one.