@happyvertical/smrt-core 0.55.24 → 0.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/collection-reads.md +6 -3
- package/agents/generators.md +16 -0
- package/agents/object-runtime.md +3 -0
- package/agents/recipes.md +7 -4
- package/dist/browser.d.ts +1 -0
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +2 -1
- package/dist/collection.d.ts +4 -0
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +19 -9
- package/dist/collection.js.map +1 -1
- package/dist/consumer-plugin/hosted-sti-collections.d.ts.map +1 -1
- package/dist/consumer-plugin/hosted-sti-collections.js +4 -2
- package/dist/consumer-plugin/hosted-sti-collections.js.map +1 -1
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js.map +1 -1
- package/dist/generators/mcp.d.ts.map +1 -1
- package/dist/generators/mcp.js +4 -2
- package/dist/generators/mcp.js.map +1 -1
- package/dist/generators/preflight-route.d.ts.map +1 -1
- package/dist/generators/preflight-route.js +3 -1
- package/dist/generators/preflight-route.js.map +1 -1
- package/dist/generators/rest.d.ts.map +1 -1
- package/dist/generators/rest.js +5 -0
- package/dist/generators/rest.js.map +1 -1
- package/dist/generators/swagger.d.ts.map +1 -1
- package/dist/generators/swagger.js +3 -1
- package/dist/generators/swagger.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/manifest/static-manifest.d.ts.map +1 -1
- package/dist/manifest/static-manifest.js +9 -1
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.js +1 -1
- package/dist/manifest/store.js.map +1 -1
- package/dist/manifest.json +9 -1
- package/dist/object.d.ts +2 -0
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +51 -0
- package/dist/object.js.map +1 -1
- package/dist/operation-permission.d.ts +10 -0
- package/dist/operation-permission.d.ts.map +1 -0
- package/dist/operation-permission.js +36 -0
- package/dist/operation-permission.js.map +1 -0
- package/dist/registry/class-registration.d.ts.map +1 -1
- package/dist/registry/class-registration.js +12 -0
- package/dist/registry/class-registration.js.map +1 -1
- package/dist/registry/types.d.ts +5 -3
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/scanner/manifest-generator.d.ts.map +1 -1
- package/dist/scanner/manifest-generator.js +47 -0
- package/dist/scanner/manifest-generator.js.map +1 -1
- package/dist/scanner/types.d.ts +5 -0
- package/dist/scanner/types.d.ts.map +1 -1
- package/dist/scanner/types.js.map +1 -1
- package/dist/smrt-knowledge.json +16 -11
- package/dist/vite-plugin/api-client-entries.d.ts.map +1 -1
- package/dist/vite-plugin/api-client-entries.js +1 -0
- package/dist/vite-plugin/api-client-entries.js.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.d.ts +0 -4
- package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.js +36 -24
- package/dist/vite-plugin/sveltekit-generator.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preflight-route.d.ts","sourceRoot":"","sources":["../../src/generators/preflight-route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAWH,8EAA8E;AAC9E,eAAO,MAAM,gCAAgC,eAAe,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B;;;;EAI/B,CAAC;AAEZ;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,KAAK,EAAE,SAAS,CAAC;IACjB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,8EAA8E;IAC9E,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uCAAuC;IACvC,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,CACtC,OAAO,EAAE,6BAA6B,KACnC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IACrC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAYD;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAChD,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,QAAQ,CAAC,CAwBnB;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAgCR;AAgBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,
|
|
1
|
+
{"version":3,"file":"preflight-route.d.ts","sourceRoot":"","sources":["../../src/generators/preflight-route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAWH,8EAA8E;AAC9E,eAAO,MAAM,gCAAgC,eAAe,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B;;;;EAI/B,CAAC;AAEZ;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,KAAK,EAAE,SAAS,CAAC;IACjB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,8EAA8E;IAC9E,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uCAAuC;IACvC,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,CACtC,OAAO,EAAE,6BAA6B,KACnC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IACrC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAYD;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAChD,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,QAAQ,CAAC,CAwBnB;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAgCR;AAgBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CA0BT;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CAuCT;AAeD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CAQT;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,MAAM,EAAE,CAiBV"}
|
|
@@ -143,7 +143,9 @@ function readRegisteredMethod(objectName, action) {
|
|
|
143
143
|
*/
|
|
144
144
|
function isApiActionEnabledForObject(objectName, action) {
|
|
145
145
|
if (!objectName) return true;
|
|
146
|
-
const
|
|
146
|
+
const config = ObjectRegistry.getConfig(objectName);
|
|
147
|
+
if (config.abstract && action !== "list" && action !== "get") return false;
|
|
148
|
+
const apiConfig = config.api;
|
|
147
149
|
if (apiConfig === false) return false;
|
|
148
150
|
if (apiConfig && typeof apiConfig === "object") {
|
|
149
151
|
if (apiConfig.include && !apiConfig.include.includes(action)) return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preflight-route.js","names":[],"sources":["../../src/generators/preflight-route.ts"],"sourcesContent":["/**\n * Generated `_preflight` HTTP route for browser-plane playbook preflight\n * (issue #2590).\n *\n * Handles `GET {basePath}/_preflight?key=<playbook key>` in the REST generator:\n * an advisory, read-effect, idempotent report of what a caller's playbook would\n * be allowed to do — *predicted*, never granted. Every step is authorized again\n * where it executes; this route is capability **selection**, never\n * authorization (epic #2585 invariant 2).\n *\n * ## `authMiddleware` is never invoked here\n *\n * Generated REST authorization is\n * `authMiddleware?: (objectName, action) => (req) => Promise<Request | Response>`\n * — request-bound, `Response`-returning rather than boolean, and free to consult\n * session stores, rate-limit, or audit. It is not a dry-run predicate, and a\n * synthetic-`Request` dry run of it would be a side effect the caller never\n * asked for.\n *\n * That is enforced **structurally**, not by discipline:\n * {@link PlaybookPreflightRouteOptions} has no `authMiddleware` member and no\n * function-valued auth member of any kind. `rest.ts` passes the boolean\n * `appAuthConfigured` and nothing else, so there is no handle in this module to\n * invoke even by mistake. The app-auth layer is consequently reported as\n * `unknown`, which is the honest answer.\n *\n * ## Why the provider is injected\n *\n * Resolution and verdict shaping live in `@happyvertical/smrt-playbooks`, which\n * depends on this package. Core therefore owns the route and the static-layer\n * facts (`ObjectRegistry` is core's), and takes the evaluator as a seam — the\n * dependency stays one-way.\n */\n\nimport { ObjectRegistry } from '../registry.js';\nimport type { MethodDefinition } from '../scanner/types.js';\nimport { PRIVATE_READ_CACHE_CONTROL } from './conditional-get.js';\nimport {\n declaresRuntimeRestRoute,\n readMethodDecoratorConfig,\n resolveEffectiveActionMetadata,\n} from './custom-action.js';\n\n/** Path segment the preflight route is served at, under the API base path. */\nexport const PLAYBOOK_PREFLIGHT_ROUTE_SEGMENT = '_preflight';\n\n/**\n * Capability classification of the preflight route: a read, safely repeatable,\n * and closed-world. It is admitted by a default read-only browser exposure\n * policy without an opt-in, because it reports on the system rather than\n * changing it.\n */\nexport const PLAYBOOK_PREFLIGHT_CAPABILITY = Object.freeze({\n effect: 'read',\n idempotent: true,\n openWorld: false,\n} as const);\n\n/**\n * The request handed to a preflight provider. Deliberately carries no request,\n * no headers, and no auth handle — only the caller-scoped facts the static\n * layers need.\n */\nexport interface PlaybookPreflightRouteRequest {\n /** The requested playbook key. */\n key: string;\n /** Always `'browser'` from this route. */\n plane: 'browser';\n /** The caller's published permission slugs, when the API context has them. */\n permissions?: Iterable<string>;\n /** Whether an app auth middleware is wired. A boolean; never the function. */\n appAuthConfigured: boolean;\n /** The generator's `APIContext.db`. */\n db?: unknown;\n}\n\n/**\n * Host-supplied browser-plane preflight evaluator, wired from\n * `@happyvertical/smrt-playbooks`. Returns a JSON-serializable report.\n */\nexport type PlaybookPreflightProvider = (\n request: PlaybookPreflightRouteRequest,\n) => Promise<unknown>;\n\n/**\n * Options for {@link handlePlaybookPreflightRoute}.\n *\n * There is intentionally no `authMiddleware` member — see the module docs.\n */\nexport interface PlaybookPreflightRouteOptions {\n provider?: PlaybookPreflightProvider;\n permissions?: Iterable<string>;\n appAuthConfigured: boolean;\n db?: unknown;\n}\n\nfunction jsonResponse(body: unknown, status: number): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: {\n 'Content-Type': 'application/json',\n 'Cache-Control': PRIVATE_READ_CACHE_CONTROL,\n },\n });\n}\n\n/**\n * Serves `GET {basePath}/_preflight?key=<key>`.\n *\n * Unresolvable keys are the provider's concern: it returns the same uniform\n * \"unavailable\" body for an unknown key as for an unauthorized one, and this\n * route serves whatever it returns with an unconditional 200, so the HTTP layer\n * adds no way to tell them apart either.\n */\nexport async function handlePlaybookPreflightRoute(\n req: Request,\n options: PlaybookPreflightRouteOptions,\n): Promise<Response> {\n if (!options.provider) {\n // Route not wired for this deployment. Says nothing about any key.\n return jsonResponse({ error: 'Not found' }, 404);\n }\n\n if (req.method !== 'GET') {\n return jsonResponse({ error: 'Method not allowed' }, 405);\n }\n\n const key = new URL(req.url).searchParams.get('key');\n if (!key) {\n return jsonResponse({ error: \"Query parameter 'key' is required\" }, 400);\n }\n\n const report = await options.provider({\n key,\n plane: 'browser',\n ...(options.permissions ? { permissions: options.permissions } : {}),\n appAuthConfigured: options.appAuthConfigured,\n db: options.db,\n });\n\n return jsonResponse(report, 200);\n}\n\n/**\n * Resolves a qualified model reference (`@happyvertical/smrt-commerce:Order`)\n * to the name the registry and the REST generator key configuration by.\n *\n * Returns `undefined` for anything this build does not register, so the caller\n * fails closed rather than reporting on a model that has no route.\n */\nexport function resolveRegisteredObjectName(model: string): string | undefined {\n const registered = model.includes(':')\n ? ObjectRegistry.getClassByQualifiedName(model, {\n source: 'playbook step model (REST preflight)',\n })\n : ObjectRegistry.getClass(model);\n return registered?.name;\n}\n\n/**\n * The HTTP method a REST action is served by.\n *\n * CRUD actions map to their fixed verbs. A custom action is served under the\n * method its own declaration supplies — `@method({ httpMethod })` first, then\n * `api.routes[action].method`, defaulting to `POST` exactly as\n * `dispatchCustomCollectionAction` does — because guessing `POST` for a\n * declared `GET` action would make preflight report a false `deny` on a\n * `public: 'read'` model, hiding a playbook the caller can actually run, which\n * is the tool-listing case this exists to serve. Without an `objectName` to\n * read the declaration from, the fail-closed `POST` remains.\n */\nexport function restMethodForApiAction(\n action: string,\n objectName?: string,\n): string {\n switch (action) {\n case 'list':\n case 'get':\n return 'GET';\n case 'create':\n return 'POST';\n case 'update':\n return 'PUT';\n case 'delete':\n return 'DELETE';\n default:\n break;\n }\n\n if (!objectName) {\n return 'POST';\n }\n\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (!apiConfig || typeof apiConfig !== 'object') {\n return 'POST';\n }\n\n const effective = resolveEffectiveActionMetadata({\n actionName: action,\n ...(readRegisteredMethod(objectName, action)\n ? { method: readRegisteredMethod(objectName, action) }\n : {}),\n apiConfig,\n });\n return (effective.httpMethod ?? 'POST').toUpperCase();\n}\n\n/**\n * The method view backing `action`: the manifest entry when the registry has\n * one, with its `@method()` config backfilled from the live decorator store\n * when it does not — the unscanned-runtime posture, where reading only the\n * manifest would silently ignore `@method({ expose: false })` (#2686). Mirrors\n * `APIGenerator.runtimeMethod`, which decides the dispatch this predicts.\n */\nfunction readRegisteredMethod(\n objectName: string,\n action: string,\n): MethodDefinition | undefined {\n return ObjectRegistry.resolveRuntimeMethod(objectName, action).method;\n}\n\n/**\n * Whether `@smrt({ api })` exposes `action` on `objectName`.\n *\n * The generator's own action gate, lifted to a module function so preflight and\n * the live route read the same rule from one place. Accepts any action name so\n * a custom action is gated by the same `include`/`exclude` lists.\n *\n * @remarks An absent `objectName` returns `true` — fail-**open**, because the\n * live route reaches this only after it has already resolved a model, and an\n * unnamed object there means \"not gated by this rule\". A caller *predicting*\n * rather than serving has no such guarantee and must reject an unresolvable\n * model before asking (see `createRestPreflightLayerSource`).\n */\nexport function isApiActionEnabledForObject(\n objectName: string | undefined,\n action: string,\n): boolean {\n if (!objectName) {\n return true;\n }\n\n const apiConfig = ObjectRegistry.getConfig(objectName).api;\n\n if (apiConfig === false) {\n return false;\n }\n\n if (apiConfig && typeof apiConfig === 'object') {\n if (apiConfig.include && !apiConfig.include.includes(action)) {\n return false;\n }\n\n if (apiConfig.exclude?.includes(action)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Whether `action` names a route the generated REST surface can actually\n * dispatch on `objectName`.\n *\n * CRUD actions always have a route. A custom action exists only when it is\n * DECLARED — historically an `api.routes` entry, and since #2686 also a\n * `@method()` supplying route-shaping metadata. `dispatchCustomCollectionAction`\n * iterates exactly that union, so an action outside it can never execute no\n * matter what `include`/`exclude` say. Exposure alone would report a typo'd or\n * removed custom action as `allow`, and an agent would then start the earlier\n * steps of a non-atomic playbook before dying on it — the failure preflight\n * exists to prevent. This prediction and that dispatch must stay one rule.\n */\nexport function isRestActionRoutable(\n objectName: string | undefined,\n action: string,\n): boolean {\n if (!objectName) return false;\n if (\n action === 'list' ||\n action === 'get' ||\n action === 'create' ||\n action === 'update' ||\n action === 'delete'\n ) {\n return true;\n }\n\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (!apiConfig || typeof apiConfig !== 'object') {\n return false;\n }\n\n const registered = readRegisteredMethod(objectName, action);\n\n // `@method({ expose: false })` outranks a legacy `api.routes` entry for the\n // same method, and dispatch honors that. Checking it BEFORE the routes map is\n // what keeps the two one rule: otherwise a withheld action that still carried\n // a route declaration predicted `allow` for an operation the transport\n // refuses (#2686).\n if (readMethodDecoratorConfig(registered)?.expose === false) return false;\n\n if (\n apiConfig.routes &&\n Object.hasOwn(apiConfig.routes as Record<string, unknown>, action)\n ) {\n return isHostableByRuntimeRest(objectName, action);\n }\n\n // Shared with `APIGenerator.declaredCollectionActions`, which decides the\n // dispatch this predicate exists to predict.\n return (\n declaresRuntimeRestRoute(registered) &&\n isHostableByRuntimeRest(objectName, action)\n );\n}\n\n/**\n * Whether this transport can HOST the action at all.\n *\n * It serves only collection-scoped custom actions, so an item-scoped\n * declaration — the `@method()` decorator's most common shape, on a model\n * instance method — answers 404 in dispatch. Predicting `allow` for it is the\n * false-`allow` this module exists to prevent, so routability is the\n * conjunction of \"declared\" and \"hostable\" (#2686).\n */\nfunction isHostableByRuntimeRest(objectName: string, action: string): boolean {\n return ObjectRegistry.isCollectionHostedMethod(objectName, action);\n}\n\n/**\n * Fail-closed authorization posture (#1540): true only when the object opts out\n * of auth via `@smrt({ api: { public } })` — `true` for every method, `'read'`\n * for safe (GET) methods only.\n */\nexport function isRestRoutePublic(\n objectName: string | undefined,\n method: string,\n): boolean {\n if (!objectName) return false;\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (!apiConfig || typeof apiConfig !== 'object') return false;\n const publicAccess = (apiConfig as { public?: boolean | 'read' }).public;\n if (publicAccess === true) return true;\n if (publicAccess === 'read') return method.toUpperCase() === 'GET';\n return false;\n}\n\n/**\n * Field-level read-permission slugs declared by `objectName`.\n *\n * Reads the model's own and inherited fields only — deliberately **not** the\n * STI base-plus-descendants union used for cache policy. That union answers\n * \"does any variant carry a read-permission field?\"; used here it would report\n * a sibling variant's slugs as required for a step naming this concrete model.\n */\nexport function restFieldReadPermissions(\n objectName: string | undefined,\n): string[] {\n if (!objectName) return [];\n const registered = ObjectRegistry.getClass(objectName);\n const className = registered?.qualifiedName ?? registered?.name ?? objectName;\n const fields =\n registered?.inheritedFields ?? ObjectRegistry.getFields(className);\n const slugs = new Set<string>();\n for (const [, def] of fields) {\n const slug =\n typeof def?.readPermission === 'string'\n ? def.readPermission\n : typeof def?._meta?.readPermission === 'string'\n ? (def._meta.readPermission as string)\n : undefined;\n if (slug) slugs.add(slug);\n }\n return [...slugs].sort();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,IAAa,mCAAmC;;;;;;;AAQhD,IAAa,gCAAgC,OAAO,OAAO;CACzD,QAAQ;CACR,YAAY;CACZ,WAAW;AACb,CAAU;AAwCV,SAAS,aAAa,MAAe,QAA0B;CAC7D,OAAO,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG;EACxC;EACA,SAAS;GACP,gBAAgB;GAChB,iBAAiB;EACnB;CACF,CAAC;AACH;;;;;;;;;AAUA,eAAsB,6BACpB,KACA,SACmB;CACnB,IAAI,CAAC,QAAQ,UAEX,OAAO,aAAa,EAAE,OAAO,YAAY,GAAG,GAAG;CAGjD,IAAI,IAAI,WAAW,OACjB,OAAO,aAAa,EAAE,OAAO,qBAAqB,GAAG,GAAG;CAG1D,MAAM,MAAM,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC,aAAa,IAAI,KAAK;CACnD,IAAI,CAAC,KACH,OAAO,aAAa,EAAE,OAAO,oCAAoC,GAAG,GAAG;CAWzE,OAAO,aAAa,MARC,QAAQ,SAAS;EACpC;EACA,OAAO;EACP,GAAI,QAAQ,cAAc,EAAE,aAAa,QAAQ,YAAY,IAAI,CAAC;EAClE,mBAAmB,QAAQ;EAC3B,IAAI,QAAQ;CACd,CAAC,GAE2B,GAAG;AACjC;;;;;;;;AASA,SAAgB,4BAA4B,OAAmC;CAM7E,QALmB,MAAM,SAAS,GAAG,IACjC,eAAe,wBAAwB,OAAO,EAC5C,QAAQ,uCACV,CAAC,IACD,eAAe,SAAS,KAAK,EAAA,EACd;AACrB;;;;;;;;;;;;;AAcA,SAAgB,uBACd,QACA,YACQ;CACR,QAAQ,QAAR;EACE,KAAK;EACL,KAAK,OACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,KAAK,UACH,OAAO;EACT,SACE;CACJ;CAEA,IAAI,CAAC,YACH,OAAO;CAGT,MAAM,YAAY,eAAe,UAAU,UAAU,CAAC,EAAE;CACxD,IAAI,CAAC,aAAa,OAAO,cAAc,UACrC,OAAO;CAUT,QAPkB,+BAA+B;EAC/C,YAAY;EACZ,GAAI,qBAAqB,YAAY,MAAM,IACvC,EAAE,QAAQ,qBAAqB,YAAY,MAAM,EAAE,IACnD,CAAC;EACL;CACF,CACQ,CAAA,CAAU,cAAc,OAAA,CAAQ,YAAY;AACtD;;;;;;;;AASA,SAAS,qBACP,YACA,QAC8B;CAC9B,OAAO,eAAe,qBAAqB,YAAY,MAAM,CAAC,CAAC;AACjE;;;;;;;;;;;;;;AAeA,SAAgB,4BACd,YACA,QACS;CACT,IAAI,CAAC,YACH,OAAO;CAGT,MAAM,YAAY,eAAe,UAAU,UAAU,CAAC,CAAC;CAEvD,IAAI,cAAc,OAChB,OAAO;CAGT,IAAI,aAAa,OAAO,cAAc,UAAU;EAC9C,IAAI,UAAU,WAAW,CAAC,UAAU,QAAQ,SAAS,MAAM,GACzD,OAAO;EAGT,IAAI,UAAU,SAAS,SAAS,MAAM,GACpC,OAAO;CAEX;CAEA,OAAO;AACT;;;;;;;;;;;;;;AAeA,SAAgB,qBACd,YACA,QACS;CACT,IAAI,CAAC,YAAY,OAAO;CACxB,IACE,WAAW,UACX,WAAW,SACX,WAAW,YACX,WAAW,YACX,WAAW,UAEX,OAAO;CAGT,MAAM,YAAY,eAAe,UAAU,UAAU,CAAC,EAAE;CACxD,IAAI,CAAC,aAAa,OAAO,cAAc,UACrC,OAAO;CAGT,MAAM,aAAa,qBAAqB,YAAY,MAAM;CAO1D,IAAI,0BAA0B,UAAU,CAAC,EAAE,WAAW,OAAO,OAAO;CAEpE,IACE,UAAU,UACV,OAAO,OAAO,UAAU,QAAmC,MAAM,GAEjE,OAAO,wBAAwB,YAAY,MAAM;CAKnD,OACE,yBAAyB,UAAU,KACnC,wBAAwB,YAAY,MAAM;AAE9C;;;;;;;;;;AAWA,SAAS,wBAAwB,YAAoB,QAAyB;CAC5E,OAAO,eAAe,yBAAyB,YAAY,MAAM;AACnE;;;;;;AAOA,SAAgB,kBACd,YACA,QACS;CACT,IAAI,CAAC,YAAY,OAAO;CACxB,MAAM,YAAY,eAAe,UAAU,UAAU,CAAC,EAAE;CACxD,IAAI,CAAC,aAAa,OAAO,cAAc,UAAU,OAAO;CACxD,MAAM,eAAgB,UAA4C;CAClE,IAAI,iBAAiB,MAAM,OAAO;CAClC,IAAI,iBAAiB,QAAQ,OAAO,OAAO,YAAY,MAAM;CAC7D,OAAO;AACT;;;;;;;;;AAUA,SAAgB,yBACd,YACU;CACV,IAAI,CAAC,YAAY,OAAO,CAAC;CACzB,MAAM,aAAa,eAAe,SAAS,UAAU;CACrD,MAAM,YAAY,YAAY,iBAAiB,YAAY,QAAQ;CACnE,MAAM,SACJ,YAAY,mBAAmB,eAAe,UAAU,SAAS;CACnE,MAAM,wBAAQ,IAAI,IAAY;CAC9B,KAAK,MAAM,GAAG,QAAQ,QAAQ;EAC5B,MAAM,OACJ,OAAO,KAAK,mBAAmB,WAC3B,IAAI,iBACJ,OAAO,KAAK,OAAO,mBAAmB,WACnC,IAAI,MAAM,iBACX,KAAA;EACR,IAAI,MAAM,MAAM,IAAI,IAAI;CAC1B;CACA,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK;AACzB"}
|
|
1
|
+
{"version":3,"file":"preflight-route.js","names":[],"sources":["../../src/generators/preflight-route.ts"],"sourcesContent":["/**\n * Generated `_preflight` HTTP route for browser-plane playbook preflight\n * (issue #2590).\n *\n * Handles `GET {basePath}/_preflight?key=<playbook key>` in the REST generator:\n * an advisory, read-effect, idempotent report of what a caller's playbook would\n * be allowed to do — *predicted*, never granted. Every step is authorized again\n * where it executes; this route is capability **selection**, never\n * authorization (epic #2585 invariant 2).\n *\n * ## `authMiddleware` is never invoked here\n *\n * Generated REST authorization is\n * `authMiddleware?: (objectName, action) => (req) => Promise<Request | Response>`\n * — request-bound, `Response`-returning rather than boolean, and free to consult\n * session stores, rate-limit, or audit. It is not a dry-run predicate, and a\n * synthetic-`Request` dry run of it would be a side effect the caller never\n * asked for.\n *\n * That is enforced **structurally**, not by discipline:\n * {@link PlaybookPreflightRouteOptions} has no `authMiddleware` member and no\n * function-valued auth member of any kind. `rest.ts` passes the boolean\n * `appAuthConfigured` and nothing else, so there is no handle in this module to\n * invoke even by mistake. The app-auth layer is consequently reported as\n * `unknown`, which is the honest answer.\n *\n * ## Why the provider is injected\n *\n * Resolution and verdict shaping live in `@happyvertical/smrt-playbooks`, which\n * depends on this package. Core therefore owns the route and the static-layer\n * facts (`ObjectRegistry` is core's), and takes the evaluator as a seam — the\n * dependency stays one-way.\n */\n\nimport { ObjectRegistry } from '../registry.js';\nimport type { MethodDefinition } from '../scanner/types.js';\nimport { PRIVATE_READ_CACHE_CONTROL } from './conditional-get.js';\nimport {\n declaresRuntimeRestRoute,\n readMethodDecoratorConfig,\n resolveEffectiveActionMetadata,\n} from './custom-action.js';\n\n/** Path segment the preflight route is served at, under the API base path. */\nexport const PLAYBOOK_PREFLIGHT_ROUTE_SEGMENT = '_preflight';\n\n/**\n * Capability classification of the preflight route: a read, safely repeatable,\n * and closed-world. It is admitted by a default read-only browser exposure\n * policy without an opt-in, because it reports on the system rather than\n * changing it.\n */\nexport const PLAYBOOK_PREFLIGHT_CAPABILITY = Object.freeze({\n effect: 'read',\n idempotent: true,\n openWorld: false,\n} as const);\n\n/**\n * The request handed to a preflight provider. Deliberately carries no request,\n * no headers, and no auth handle — only the caller-scoped facts the static\n * layers need.\n */\nexport interface PlaybookPreflightRouteRequest {\n /** The requested playbook key. */\n key: string;\n /** Always `'browser'` from this route. */\n plane: 'browser';\n /** The caller's published permission slugs, when the API context has them. */\n permissions?: Iterable<string>;\n /** Whether an app auth middleware is wired. A boolean; never the function. */\n appAuthConfigured: boolean;\n /** The generator's `APIContext.db`. */\n db?: unknown;\n}\n\n/**\n * Host-supplied browser-plane preflight evaluator, wired from\n * `@happyvertical/smrt-playbooks`. Returns a JSON-serializable report.\n */\nexport type PlaybookPreflightProvider = (\n request: PlaybookPreflightRouteRequest,\n) => Promise<unknown>;\n\n/**\n * Options for {@link handlePlaybookPreflightRoute}.\n *\n * There is intentionally no `authMiddleware` member — see the module docs.\n */\nexport interface PlaybookPreflightRouteOptions {\n provider?: PlaybookPreflightProvider;\n permissions?: Iterable<string>;\n appAuthConfigured: boolean;\n db?: unknown;\n}\n\nfunction jsonResponse(body: unknown, status: number): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: {\n 'Content-Type': 'application/json',\n 'Cache-Control': PRIVATE_READ_CACHE_CONTROL,\n },\n });\n}\n\n/**\n * Serves `GET {basePath}/_preflight?key=<key>`.\n *\n * Unresolvable keys are the provider's concern: it returns the same uniform\n * \"unavailable\" body for an unknown key as for an unauthorized one, and this\n * route serves whatever it returns with an unconditional 200, so the HTTP layer\n * adds no way to tell them apart either.\n */\nexport async function handlePlaybookPreflightRoute(\n req: Request,\n options: PlaybookPreflightRouteOptions,\n): Promise<Response> {\n if (!options.provider) {\n // Route not wired for this deployment. Says nothing about any key.\n return jsonResponse({ error: 'Not found' }, 404);\n }\n\n if (req.method !== 'GET') {\n return jsonResponse({ error: 'Method not allowed' }, 405);\n }\n\n const key = new URL(req.url).searchParams.get('key');\n if (!key) {\n return jsonResponse({ error: \"Query parameter 'key' is required\" }, 400);\n }\n\n const report = await options.provider({\n key,\n plane: 'browser',\n ...(options.permissions ? { permissions: options.permissions } : {}),\n appAuthConfigured: options.appAuthConfigured,\n db: options.db,\n });\n\n return jsonResponse(report, 200);\n}\n\n/**\n * Resolves a qualified model reference (`@happyvertical/smrt-commerce:Order`)\n * to the name the registry and the REST generator key configuration by.\n *\n * Returns `undefined` for anything this build does not register, so the caller\n * fails closed rather than reporting on a model that has no route.\n */\nexport function resolveRegisteredObjectName(model: string): string | undefined {\n const registered = model.includes(':')\n ? ObjectRegistry.getClassByQualifiedName(model, {\n source: 'playbook step model (REST preflight)',\n })\n : ObjectRegistry.getClass(model);\n return registered?.name;\n}\n\n/**\n * The HTTP method a REST action is served by.\n *\n * CRUD actions map to their fixed verbs. A custom action is served under the\n * method its own declaration supplies — `@method({ httpMethod })` first, then\n * `api.routes[action].method`, defaulting to `POST` exactly as\n * `dispatchCustomCollectionAction` does — because guessing `POST` for a\n * declared `GET` action would make preflight report a false `deny` on a\n * `public: 'read'` model, hiding a playbook the caller can actually run, which\n * is the tool-listing case this exists to serve. Without an `objectName` to\n * read the declaration from, the fail-closed `POST` remains.\n */\nexport function restMethodForApiAction(\n action: string,\n objectName?: string,\n): string {\n switch (action) {\n case 'list':\n case 'get':\n return 'GET';\n case 'create':\n return 'POST';\n case 'update':\n return 'PUT';\n case 'delete':\n return 'DELETE';\n default:\n break;\n }\n\n if (!objectName) {\n return 'POST';\n }\n\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (!apiConfig || typeof apiConfig !== 'object') {\n return 'POST';\n }\n\n const effective = resolveEffectiveActionMetadata({\n actionName: action,\n ...(readRegisteredMethod(objectName, action)\n ? { method: readRegisteredMethod(objectName, action) }\n : {}),\n apiConfig,\n });\n return (effective.httpMethod ?? 'POST').toUpperCase();\n}\n\n/**\n * The method view backing `action`: the manifest entry when the registry has\n * one, with its `@method()` config backfilled from the live decorator store\n * when it does not — the unscanned-runtime posture, where reading only the\n * manifest would silently ignore `@method({ expose: false })` (#2686). Mirrors\n * `APIGenerator.runtimeMethod`, which decides the dispatch this predicts.\n */\nfunction readRegisteredMethod(\n objectName: string,\n action: string,\n): MethodDefinition | undefined {\n return ObjectRegistry.resolveRuntimeMethod(objectName, action).method;\n}\n\n/**\n * Whether `@smrt({ api })` exposes `action` on `objectName`.\n *\n * The generator's own action gate, lifted to a module function so preflight and\n * the live route read the same rule from one place. Accepts any action name so\n * a custom action is gated by the same `include`/`exclude` lists.\n *\n * @remarks An absent `objectName` returns `true` — fail-**open**, because the\n * live route reaches this only after it has already resolved a model, and an\n * unnamed object there means \"not gated by this rule\". A caller *predicting*\n * rather than serving has no such guarantee and must reject an unresolvable\n * model before asking (see `createRestPreflightLayerSource`).\n */\nexport function isApiActionEnabledForObject(\n objectName: string | undefined,\n action: string,\n): boolean {\n if (!objectName) {\n return true;\n }\n\n const config = ObjectRegistry.getConfig(objectName);\n if (config.abstract && action !== 'list' && action !== 'get') {\n return false;\n }\n const apiConfig = config.api;\n\n if (apiConfig === false) {\n return false;\n }\n\n if (apiConfig && typeof apiConfig === 'object') {\n if (apiConfig.include && !apiConfig.include.includes(action)) {\n return false;\n }\n\n if (apiConfig.exclude?.includes(action)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Whether `action` names a route the generated REST surface can actually\n * dispatch on `objectName`.\n *\n * CRUD actions always have a route. A custom action exists only when it is\n * DECLARED — historically an `api.routes` entry, and since #2686 also a\n * `@method()` supplying route-shaping metadata. `dispatchCustomCollectionAction`\n * iterates exactly that union, so an action outside it can never execute no\n * matter what `include`/`exclude` say. Exposure alone would report a typo'd or\n * removed custom action as `allow`, and an agent would then start the earlier\n * steps of a non-atomic playbook before dying on it — the failure preflight\n * exists to prevent. This prediction and that dispatch must stay one rule.\n */\nexport function isRestActionRoutable(\n objectName: string | undefined,\n action: string,\n): boolean {\n if (!objectName) return false;\n if (\n action === 'list' ||\n action === 'get' ||\n action === 'create' ||\n action === 'update' ||\n action === 'delete'\n ) {\n return true;\n }\n\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (!apiConfig || typeof apiConfig !== 'object') {\n return false;\n }\n\n const registered = readRegisteredMethod(objectName, action);\n\n // `@method({ expose: false })` outranks a legacy `api.routes` entry for the\n // same method, and dispatch honors that. Checking it BEFORE the routes map is\n // what keeps the two one rule: otherwise a withheld action that still carried\n // a route declaration predicted `allow` for an operation the transport\n // refuses (#2686).\n if (readMethodDecoratorConfig(registered)?.expose === false) return false;\n\n if (\n apiConfig.routes &&\n Object.hasOwn(apiConfig.routes as Record<string, unknown>, action)\n ) {\n return isHostableByRuntimeRest(objectName, action);\n }\n\n // Shared with `APIGenerator.declaredCollectionActions`, which decides the\n // dispatch this predicate exists to predict.\n return (\n declaresRuntimeRestRoute(registered) &&\n isHostableByRuntimeRest(objectName, action)\n );\n}\n\n/**\n * Whether this transport can HOST the action at all.\n *\n * It serves only collection-scoped custom actions, so an item-scoped\n * declaration — the `@method()` decorator's most common shape, on a model\n * instance method — answers 404 in dispatch. Predicting `allow` for it is the\n * false-`allow` this module exists to prevent, so routability is the\n * conjunction of \"declared\" and \"hostable\" (#2686).\n */\nfunction isHostableByRuntimeRest(objectName: string, action: string): boolean {\n return ObjectRegistry.isCollectionHostedMethod(objectName, action);\n}\n\n/**\n * Fail-closed authorization posture (#1540): true only when the object opts out\n * of auth via `@smrt({ api: { public } })` — `true` for every method, `'read'`\n * for safe (GET) methods only.\n */\nexport function isRestRoutePublic(\n objectName: string | undefined,\n method: string,\n): boolean {\n if (!objectName) return false;\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (!apiConfig || typeof apiConfig !== 'object') return false;\n const publicAccess = (apiConfig as { public?: boolean | 'read' }).public;\n if (publicAccess === true) return true;\n if (publicAccess === 'read') return method.toUpperCase() === 'GET';\n return false;\n}\n\n/**\n * Field-level read-permission slugs declared by `objectName`.\n *\n * Reads the model's own and inherited fields only — deliberately **not** the\n * STI base-plus-descendants union used for cache policy. That union answers\n * \"does any variant carry a read-permission field?\"; used here it would report\n * a sibling variant's slugs as required for a step naming this concrete model.\n */\nexport function restFieldReadPermissions(\n objectName: string | undefined,\n): string[] {\n if (!objectName) return [];\n const registered = ObjectRegistry.getClass(objectName);\n const className = registered?.qualifiedName ?? registered?.name ?? objectName;\n const fields =\n registered?.inheritedFields ?? ObjectRegistry.getFields(className);\n const slugs = new Set<string>();\n for (const [, def] of fields) {\n const slug =\n typeof def?.readPermission === 'string'\n ? def.readPermission\n : typeof def?._meta?.readPermission === 'string'\n ? (def._meta.readPermission as string)\n : undefined;\n if (slug) slugs.add(slug);\n }\n return [...slugs].sort();\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rest.d.ts","sourceRoot":"","sources":["../../src/generators/rest.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"rest.d.ts","sourceRoot":"","sources":["../../src/generators/rest.ts"],"names":[],"mappings":"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"}
|
package/dist/generators/rest.js
CHANGED
|
@@ -453,6 +453,11 @@ var APIGenerator = class {
|
|
|
453
453
|
if (routePath.includes("/") || routePath !== pathSegment) continue;
|
|
454
454
|
const routeMethod = (effective.httpMethod || "POST").toUpperCase();
|
|
455
455
|
if (routeMethod !== req.method.toUpperCase()) continue;
|
|
456
|
+
if (ObjectRegistry.getConfig(objectName).abstract) {
|
|
457
|
+
const refusal = this.refuseWithheldAction(req, actionName, "abstract");
|
|
458
|
+
if (refusal) return refusal;
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
456
461
|
if (apiConfig.include && !apiConfig.include.includes(actionName)) {
|
|
457
462
|
const refusal = this.refuseWithheldAction(req, actionName, "api.include");
|
|
458
463
|
if (refusal) return refusal;
|