|
| 1 | +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. |
| 2 | + |
| 3 | +/** |
| 4 | + * [#25467 cut 31] The by-name item read's disabled-package face, from |
| 5 | + * `ObjectStackProtocolImplementation`, moved out of `protocol.ts` whole: |
| 6 | + * `readMetaItemFace`, the one body behind `getMetaItem` and |
| 7 | + * `getMetaItemForExecution`. It refuses an object of a disabled package, |
| 8 | + * withholds any other item of one, and otherwise answers what `readMetaItem` |
| 9 | + * answers. |
| 10 | + * |
| 11 | + * A MOVE, not a redesign. The function below is the body of the |
| 12 | + * `ObjectStackProtocolImplementation` method of the same name as it stood, |
| 13 | + * re-indented one level and otherwise unedited. |
| 14 | + * |
| 15 | + * ## How the moved body reaches the class |
| 16 | + * |
| 17 | + * The shape #23050 set for `rest-server.ts` (its `data-action-routes.ts` |
| 18 | + * header carries the full reasoning), as `protocol-batch-data.ts` applies it. |
| 19 | + * The class keeps the method — the published `dist/*.d.ts` lists its name, |
| 20 | + * docblock and declared signature — and its body is one literal of exactly |
| 21 | + * the {@link MetaItemFaceHost} members it reads, plus a `.call`. The `engine` |
| 22 | + * field is handed over as a getter, so the read finds it as it stands at call |
| 23 | + * time; the call to `readMetaItem` is handed over as a closure, so it still |
| 24 | + * reaches the class method. Every caller keeps calling the class method. |
| 25 | + * |
| 26 | + * The disabled-package helpers it reads are `protocol.ts`'s own, and are |
| 27 | + * imported from there. Nothing re-exports this module, so the published |
| 28 | + * surface does not move. |
| 29 | + */ |
| 30 | + |
| 31 | +import type { ObjectStackProtocolImplementation } from './protocol.js'; |
| 32 | +import { |
| 33 | + isItemOfDisabledPackage, |
| 34 | + isObjectOfDisabledPackage, |
| 35 | + noPendingDraftError, |
| 36 | + objectPackageDisabledError, |
| 37 | +} from './protocol.js'; |
| 38 | + |
| 39 | +/** |
| 40 | + * The `ObjectStackProtocolImplementation` members the function below reads — |
| 41 | + * every one of them, and no other; the function's `this` is the `Pick` of |
| 42 | + * them. Each is typed AS the class member (an indexed access on the class), |
| 43 | + * so a change to a member's signature on the class is a change here too. |
| 44 | + */ |
| 45 | +export interface MetaItemFaceHost { |
| 46 | + readonly engine: ObjectStackProtocolImplementation['engine']; |
| 47 | + readonly readMetaItem: ObjectStackProtocolImplementation['readMetaItem']; |
| 48 | +} |
| 49 | + |
| 50 | +/** The body of `ObjectStackProtocolImplementation#readMetaItemFace`; the method's docblock there is its contract. */ |
| 51 | +export async function readMetaItemFace( |
| 52 | + this: Pick<MetaItemFaceHost, 'engine' | 'readMetaItem'>, |
| 53 | + request: { |
| 54 | + type: string, name: string, packageId?: string, state?: 'active' | 'draft', previewDrafts?: boolean, |
| 55 | + member?: string, |
| 56 | + }, |
| 57 | + face: 'served' | 'execution', |
| 58 | +) { |
| 59 | + if (request.type === 'object' && isObjectOfDisabledPackage(this.engine?.registry, request.name)) { |
| 60 | + throw objectPackageDisabledError(request.name); |
| 61 | + } |
| 62 | + const answer = await this.readMetaItem(request, { face }); |
| 63 | + if (request.type === 'object' || request.type === 'package' |
| 64 | + || !isItemOfDisabledPackage(this.engine?.registry, answer?.item)) { |
| 65 | + return answer; |
| 66 | + } |
| 67 | + if (request.state === 'draft') throw noPendingDraftError(request.type, request.name); |
| 68 | + const { item: _withheld, registration: _servedOnly, ...envelope } = answer as typeof answer & { registration?: unknown }; |
| 69 | + return { ...envelope, item: undefined }; |
| 70 | +} |
0 commit comments