@happyvertical/smrt-core 0.55.11 → 0.55.13
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/cookbook.md +23 -3
- package/agents/object-runtime.md +11 -0
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +4 -1
- 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 +6 -2
- package/dist/consumer-plugin/hosted-sti-collections.js.map +1 -1
- package/dist/cookbook/engine/document.d.ts.map +1 -1
- package/dist/cookbook/engine/document.js +16 -18
- package/dist/cookbook/engine/document.js.map +1 -1
- package/dist/cookbook/engine/types.d.ts +2 -0
- package/dist/cookbook/engine/types.d.ts.map +1 -1
- package/dist/cookbook/engine/types.js.map +1 -1
- package/dist/cookbook/v1.schema.json +60 -3
- package/dist/cookbook/validate.d.ts +40 -4
- package/dist/cookbook/validate.d.ts.map +1 -1
- package/dist/cookbook/validate.js +228 -58
- package/dist/cookbook/validate.js.map +1 -1
- package/dist/dispatch/bus.d.ts +9 -4
- package/dist/dispatch/bus.d.ts.map +1 -1
- package/dist/dispatch/bus.js +11 -6
- package/dist/dispatch/bus.js.map +1 -1
- package/dist/dispatch/collections/Dispatches.d.ts +15 -5
- package/dist/dispatch/collections/Dispatches.d.ts.map +1 -1
- package/dist/dispatch/collections/Dispatches.js +29 -9
- package/dist/dispatch/collections/Dispatches.js.map +1 -1
- package/dist/dispatch/types.d.ts +5 -1
- package/dist/dispatch/types.d.ts.map +1 -1
- package/dist/manifest/static-manifest.js +1 -1
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.js +1 -1
- package/dist/manifest.json +1 -1
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +5 -1
- package/dist/object.js.map +1 -1
- package/dist/scanner/types.d.ts +8 -0
- package/dist/scanner/types.d.ts.map +1 -1
- package/dist/scanner/types.js.map +1 -1
- package/dist/smrt-knowledge.json +7 -7
- package/dist/utils.d.ts +21 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +52 -2
- package/dist/utils.js.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.js +4 -1
- package/dist/vite-plugin/sveltekit-generator.js.map +1 -1
- package/dist/vite-plugin/sync-apply-route.d.ts.map +1 -1
- package/dist/vite-plugin/sync-apply-route.js +1 -0
- package/dist/vite-plugin/sync-apply-route.js.map +1 -1
- package/package.json +10 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-sti-collections.d.ts","sourceRoot":"","sources":["../../src/consumer-plugin/hosted-sti-collections.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hosted-sti-collections.d.ts","sourceRoot":"","sources":["../../src/consumer-plugin/hosted-sti-collections.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,qBAAqB,EAEtB,MAAM,qBAAqB,CAAC;AAyC7B;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,CAAC,SAAS,MAAM,EAC3D,QAAQ,EAAE,CAAC,EACX,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,qBAAqB,KAAK,MAAM,GAAG,SAAS,GACrE,CAAC,CAqDH"}
|
|
@@ -14,7 +14,9 @@ import { defaultCollectionName } from "@happyvertical/smrt-scanner";
|
|
|
14
14
|
* A hosted subclass that has not declared a collection gets its class-derived
|
|
15
15
|
* one (`orders`), the name it would have had as a plain model. Its generated
|
|
16
16
|
* route then lists and reads through its own collection, which already scopes
|
|
17
|
-
* every read to the subclass `_meta_type`;
|
|
17
|
+
* every read to the subclass `_meta_type`; permissions do not move with it (the
|
|
18
|
+
* catalog grants the STI base's `contracts.*` slugs only, #3770), so the moved
|
|
19
|
+
* definition records the original collection as `permissionCollection`; the base keeps the shared name and
|
|
18
20
|
* the base-collection semantics (every row of the table). The same rewritten
|
|
19
21
|
* manifest feeds the `@smrt/web` definitions and the generated client, so each
|
|
20
22
|
* hosted class advertises exactly the endpoint its route serves.
|
|
@@ -65,6 +67,7 @@ function separateHostedStiCollections(manifest, hosted, refOf) {
|
|
|
65
67
|
objects[key] = {
|
|
66
68
|
...def,
|
|
67
69
|
collection,
|
|
70
|
+
...collection === def.collection ? {} : { permissionCollection: def.collection },
|
|
68
71
|
...api === void 0 ? {} : { decoratorConfig: {
|
|
69
72
|
...def.decoratorConfig,
|
|
70
73
|
api
|
|
@@ -78,7 +81,8 @@ function separateHostedStiCollections(manifest, hosted, refOf) {
|
|
|
78
81
|
const collection = item ? moved.get(item) : void 0;
|
|
79
82
|
if (collection && def.collection !== collection) objects[key] = {
|
|
80
83
|
...def,
|
|
81
|
-
collection
|
|
84
|
+
collection,
|
|
85
|
+
permissionCollection: def.collection
|
|
82
86
|
};
|
|
83
87
|
}
|
|
84
88
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-sti-collections.js","names":[],"sources":["../../src/consumer-plugin/hosted-sti-collections.ts"],"sourcesContent":["/**\n * Own route collections for hosted STI subclasses (#3749).\n *\n * An STI subclass shares its base's table, and the manifest generator also\n * gives it the base's `collection` unless it declares one\n * (`@smrt({ collection })`, \"collection controls routes/permissions\n * independently of shared storage\"). Hosting `Order` and `ProductionOrder`\n * beside each other would therefore claim `/contracts` twice, and one handler\n * would silently shadow the other.\n *\n * A hosted subclass that has not declared a collection gets its class-derived\n * one (`orders`), the name it would have had as a plain model. Its generated\n * route then lists and reads through its own collection, which already scopes\n * every read to the subclass `_meta_type`; the base keeps the shared name and\n * the base-collection semantics (every row of the table). The same rewritten\n * manifest feeds the `@smrt/web` definitions and the generated client, so each\n * hosted class advertises exactly the endpoint its route serves.\n */\nimport { defaultCollectionName } from '@happyvertical/smrt-scanner';\nimport type {\n SmartObjectDefinition,\n SmartObjectManifest,\n} from '../scanner/types.js';\nimport {\n findManifestObjectByName,\n isCollectionManifestClass,\n isStiChildModel,\n resolveCollectionItemObject,\n} from '../vite-plugin/web-collections.js';\n\n/**\n * The `api` config of the nearest STI ancestor that declares one. An omitted\n * `api` means full CRUD, so a hosted subclass that says nothing would expose\n * `DELETE /orders/:id` even though its base (`Contract`) allows only\n * list/get/create/update. Hosting fails closed: the subclass inherits the base's\n * exposure unless it declares its own (hosting path only; the framework-wide\n * default is unchanged).\n */\nfunction inheritedApi(\n manifest: SmartObjectManifest,\n obj: SmartObjectDefinition,\n): unknown {\n const seen = new Set<string>();\n let child = obj;\n let parentName = child.extendsQualified || child.extends;\n while (parentName && !seen.has(parentName)) {\n seen.add(parentName);\n const parent = findManifestObjectByName(manifest, parentName, child);\n if (!parent) return undefined;\n // Only an STI relative lends its exposure: it shares the table (and so the\n // inherited collection) or is the declared STI base.\n const sti =\n parent.collection === obj.collection ||\n parent.decoratorConfig?.tableStrategy === 'sti';\n if (!sti) return undefined;\n const api = parent.decoratorConfig?.api;\n if (api !== undefined) return api;\n child = parent;\n parentName = parent.extendsQualified || parent.extends;\n }\n return undefined;\n}\n\n/**\n * @param manifest - The aggregated manifest of every consumed package.\n * @param hosted - Provider-qualified refs the consumer hosts.\n * @param refOf - The qualified ref of a manifest entry.\n * @returns The manifest with each hosted, collection-inheriting STI subclass\n * moved to its own collection; `manifest` itself when none needs it.\n */\nexport function separateHostedStiCollections<M extends object>(\n manifest: M,\n hosted: readonly string[],\n refOf: (key: string, def: SmartObjectDefinition) => string | undefined,\n): M {\n const source = manifest as unknown as SmartObjectManifest;\n const wanted = new Set(hosted);\n let objects: SmartObjectManifest['objects'] | undefined;\n const moved = new Map<SmartObjectDefinition, string>();\n for (const [key, def] of Object.entries(source.objects)) {\n const ref = refOf(key, def);\n if (!ref || !wanted.has(ref)) continue;\n // An explicit `collection` is already independent; only an inherited one\n // collides.\n const separable =\n !def.decoratorConfig?.collection && isStiChildModel(source, def);\n const collection = separable\n ? defaultCollectionName(def.className)\n : def.collection;\n const api =\n def.decoratorConfig?.api === undefined\n ? inheritedApi(source, def)\n : undefined;\n if (collection === def.collection && api === undefined) continue;\n if (collection !== def.collection) moved.set(def, collection);\n objects ??= { ...source.objects };\n objects[key] = {\n ...def,\n collection,\n ...(api === undefined\n ? {}\n : { decoratorConfig: { ...def.decoratorConfig, api } }),\n } as SmartObjectDefinition;\n }\n if (!objects) return manifest;\n\n // A collection class follows its item class (the manifest generator gives it\n // the item's collection); left behind it would keep the shared route and\n // collide with its siblings' collection classes on custom-action routes.\n for (const [key, def] of Object.entries(source.objects)) {\n if (!isCollectionManifestClass(source, def)) continue;\n const item = resolveCollectionItemObject(source, def);\n const collection = item ? moved.get(item) : undefined;\n if (collection && def.collection !== collection) {\n objects[key] = {
|
|
1
|
+
{"version":3,"file":"hosted-sti-collections.js","names":[],"sources":["../../src/consumer-plugin/hosted-sti-collections.ts"],"sourcesContent":["/**\n * Own route collections for hosted STI subclasses (#3749).\n *\n * An STI subclass shares its base's table, and the manifest generator also\n * gives it the base's `collection` unless it declares one\n * (`@smrt({ collection })`, \"collection controls routes/permissions\n * independently of shared storage\"). Hosting `Order` and `ProductionOrder`\n * beside each other would therefore claim `/contracts` twice, and one handler\n * would silently shadow the other.\n *\n * A hosted subclass that has not declared a collection gets its class-derived\n * one (`orders`), the name it would have had as a plain model. Its generated\n * route then lists and reads through its own collection, which already scopes\n * every read to the subclass `_meta_type`; permissions do not move with it (the\n * catalog grants the STI base's `contracts.*` slugs only, #3770), so the moved\n * definition records the original collection as `permissionCollection`; the base keeps the shared name and\n * the base-collection semantics (every row of the table). The same rewritten\n * manifest feeds the `@smrt/web` definitions and the generated client, so each\n * hosted class advertises exactly the endpoint its route serves.\n */\nimport { defaultCollectionName } from '@happyvertical/smrt-scanner';\nimport type {\n SmartObjectDefinition,\n SmartObjectManifest,\n} from '../scanner/types.js';\nimport {\n findManifestObjectByName,\n isCollectionManifestClass,\n isStiChildModel,\n resolveCollectionItemObject,\n} from '../vite-plugin/web-collections.js';\n\n/**\n * The `api` config of the nearest STI ancestor that declares one. An omitted\n * `api` means full CRUD, so a hosted subclass that says nothing would expose\n * `DELETE /orders/:id` even though its base (`Contract`) allows only\n * list/get/create/update. Hosting fails closed: the subclass inherits the base's\n * exposure unless it declares its own (hosting path only; the framework-wide\n * default is unchanged).\n */\nfunction inheritedApi(\n manifest: SmartObjectManifest,\n obj: SmartObjectDefinition,\n): unknown {\n const seen = new Set<string>();\n let child = obj;\n let parentName = child.extendsQualified || child.extends;\n while (parentName && !seen.has(parentName)) {\n seen.add(parentName);\n const parent = findManifestObjectByName(manifest, parentName, child);\n if (!parent) return undefined;\n // Only an STI relative lends its exposure: it shares the table (and so the\n // inherited collection) or is the declared STI base.\n const sti =\n parent.collection === obj.collection ||\n parent.decoratorConfig?.tableStrategy === 'sti';\n if (!sti) return undefined;\n const api = parent.decoratorConfig?.api;\n if (api !== undefined) return api;\n child = parent;\n parentName = parent.extendsQualified || parent.extends;\n }\n return undefined;\n}\n\n/**\n * @param manifest - The aggregated manifest of every consumed package.\n * @param hosted - Provider-qualified refs the consumer hosts.\n * @param refOf - The qualified ref of a manifest entry.\n * @returns The manifest with each hosted, collection-inheriting STI subclass\n * moved to its own collection; `manifest` itself when none needs it.\n */\nexport function separateHostedStiCollections<M extends object>(\n manifest: M,\n hosted: readonly string[],\n refOf: (key: string, def: SmartObjectDefinition) => string | undefined,\n): M {\n const source = manifest as unknown as SmartObjectManifest;\n const wanted = new Set(hosted);\n let objects: SmartObjectManifest['objects'] | undefined;\n const moved = new Map<SmartObjectDefinition, string>();\n for (const [key, def] of Object.entries(source.objects)) {\n const ref = refOf(key, def);\n if (!ref || !wanted.has(ref)) continue;\n // An explicit `collection` is already independent; only an inherited one\n // collides.\n const separable =\n !def.decoratorConfig?.collection && isStiChildModel(source, def);\n const collection = separable\n ? defaultCollectionName(def.className)\n : def.collection;\n const api =\n def.decoratorConfig?.api === undefined\n ? inheritedApi(source, def)\n : undefined;\n if (collection === def.collection && api === undefined) continue;\n if (collection !== def.collection) moved.set(def, collection);\n objects ??= { ...source.objects };\n objects[key] = {\n ...def,\n collection,\n // The catalog keeps granting the STI base's slugs; the route must keep\n // requiring them (#3770).\n ...(collection === def.collection\n ? {}\n : { permissionCollection: def.collection }),\n ...(api === undefined\n ? {}\n : { decoratorConfig: { ...def.decoratorConfig, api } }),\n } as SmartObjectDefinition;\n }\n if (!objects) return manifest;\n\n // A collection class follows its item class (the manifest generator gives it\n // the item's collection); left behind it would keep the shared route and\n // collide with its siblings' collection classes on custom-action routes.\n for (const [key, def] of Object.entries(source.objects)) {\n if (!isCollectionManifestClass(source, def)) continue;\n const item = resolveCollectionItemObject(source, def);\n const collection = item ? moved.get(item) : undefined;\n if (collection && def.collection !== collection) {\n objects[key] = {\n ...def,\n collection,\n permissionCollection: def.collection,\n } as SmartObjectDefinition;\n }\n }\n return { ...manifest, objects } as M;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,SAAS,aACP,UACA,KACS;CACT,MAAM,uBAAO,IAAI,IAAY;CAC7B,IAAI,QAAQ;CACZ,IAAI,aAAa,MAAM,oBAAoB,MAAM;CACjD,OAAO,cAAc,CAAC,KAAK,IAAI,UAAU,GAAG;EAC1C,KAAK,IAAI,UAAU;EACnB,MAAM,SAAS,yBAAyB,UAAU,YAAY,KAAK;EACnE,IAAI,CAAC,QAAQ,OAAO,KAAA;EAMpB,IAAI,EAFF,OAAO,eAAe,IAAI,cAC1B,OAAO,iBAAiB,kBAAkB,QAClC,OAAO,KAAA;EACjB,MAAM,MAAM,OAAO,iBAAiB;EACpC,IAAI,QAAQ,KAAA,GAAW,OAAO;EAC9B,QAAQ;EACR,aAAa,OAAO,oBAAoB,OAAO;CACjD;AAEF;;;;;;;;AASA,SAAgB,6BACd,UACA,QACA,OACG;CACH,MAAM,SAAS;CACf,MAAM,SAAS,IAAI,IAAI,MAAM;CAC7B,IAAI;CACJ,MAAM,wBAAQ,IAAI,IAAmC;CACrD,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,OAAO,OAAO,GAAG;EACvD,MAAM,MAAM,MAAM,KAAK,GAAG;EAC1B,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,GAAG,GAAG;EAK9B,MAAM,aADJ,CAAC,IAAI,iBAAiB,cAAc,gBAAgB,QAAQ,GAAG,IAE7D,sBAAsB,IAAI,SAAS,IACnC,IAAI;EACR,MAAM,MACJ,IAAI,iBAAiB,QAAQ,KAAA,IACzB,aAAa,QAAQ,GAAG,IACxB,KAAA;EACN,IAAI,eAAe,IAAI,cAAc,QAAQ,KAAA,GAAW;EACxD,IAAI,eAAe,IAAI,YAAY,MAAM,IAAI,KAAK,UAAU;EAC5D,YAAY,EAAE,GAAG,OAAO,QAAQ;EAChC,QAAQ,OAAO;GACb,GAAG;GACH;GAGA,GAAI,eAAe,IAAI,aACnB,CAAC,IACD,EAAE,sBAAsB,IAAI,WAAW;GAC3C,GAAI,QAAQ,KAAA,IACR,CAAC,IACD,EAAE,iBAAiB;IAAE,GAAG,IAAI;IAAiB;GAAI,EAAE;EACzD;CACF;CACA,IAAI,CAAC,SAAS,OAAO;CAKrB,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,OAAO,OAAO,GAAG;EACvD,IAAI,CAAC,0BAA0B,QAAQ,GAAG,GAAG;EAC7C,MAAM,OAAO,4BAA4B,QAAQ,GAAG;EACpD,MAAM,aAAa,OAAO,MAAM,IAAI,IAAI,IAAI,KAAA;EAC5C,IAAI,cAAc,IAAI,eAAe,YACnC,QAAQ,OAAO;GACb,GAAG;GACH;GACA,sBAAsB,IAAI;EAC5B;CAEJ;CACA,OAAO;EAAE,GAAG;EAAU;CAAQ;AAChC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../../src/cookbook/engine/document.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../../src/cookbook/engine/document.ts"],"names":[],"mappings":"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"}
|
|
@@ -307,12 +307,26 @@ function diagnose(catalog, input) {
|
|
|
307
307
|
});
|
|
308
308
|
const structural = validateCookbook(input);
|
|
309
309
|
if (!structural.ok) {
|
|
310
|
-
for (const
|
|
310
|
+
for (const issue of structural.diagnostics.filter((diagnostic) => diagnostic.severity === "error")) add("error", "invalid_document", issue.path, issue.message);
|
|
311
311
|
return out;
|
|
312
312
|
}
|
|
313
|
-
for (const
|
|
313
|
+
for (const issue of structural.diagnostics) add(issue.severity, issue.code === "migrated_schema" ? "migrated" : issue.code, issue.path, issue.message);
|
|
314
314
|
const doc = structural.cookbook;
|
|
315
315
|
const byId = recipeMap(catalog);
|
|
316
|
+
const nav = buildNav(catalog, {
|
|
317
|
+
...doc,
|
|
318
|
+
layout: void 0
|
|
319
|
+
});
|
|
320
|
+
const checked = validateCookbook(doc, {
|
|
321
|
+
themePresets: catalog.themePresets ?? DEFAULT_THEME_PRESETS,
|
|
322
|
+
layout: {
|
|
323
|
+
sections: nav.map((section) => section.id),
|
|
324
|
+
items: nav.flatMap((section) => section.items.map((item) => item.id)),
|
|
325
|
+
...catalog.placementItems ? { placementItems: catalog.placementItems } : {}
|
|
326
|
+
},
|
|
327
|
+
overviewIds: [...nav.map((section) => section.id), ...(doc.layout?.customSections ?? []).map((section) => section.id)]
|
|
328
|
+
});
|
|
329
|
+
for (const issue of checked.diagnostics) if (issue.code === "unknown_theme_preset" || issue.code === "unknown_layout_id" || issue.code === "unknown_overview") add(issue.code === "unknown_layout_id" && !issue.path.startsWith("layout.placements.") ? "warning" : issue.severity, issue.code === "unknown_theme_preset" ? "unknown_preset" : issue.code, issue.path, issue.message);
|
|
316
330
|
for (const [i, id] of doc.recipes.entries()) if (!byId.has(id)) add("error", "unknown_recipe", `recipes[${i}]`, `Unknown recipe "${id}".`);
|
|
317
331
|
const closure = new Set(withRequirements(doc.recipes, byId));
|
|
318
332
|
for (const id of closure) if (!doc.recipes.includes(id)) add("error", "missing_requirement", "recipes", `A recipe needs "${id}", which is not listed.`);
|
|
@@ -333,22 +347,6 @@ function diagnose(catalog, input) {
|
|
|
333
347
|
if (!covered.has(row.objectRef) && !isSettingRow(catalog, row)) add("warning", "policy_not_covered", at, `${model.name} is not in the app, so this row has no effect.`);
|
|
334
348
|
}
|
|
335
349
|
for (const ref of Object.keys(doc.exposure ?? {})) if (!findModel(catalog, ref)) add("error", "unknown_model", `exposure.${ref}`, `Unknown model "${ref}".`);
|
|
336
|
-
const presets = catalog.themePresets ?? DEFAULT_THEME_PRESETS;
|
|
337
|
-
if (doc.theme?.preset && !presets.includes(doc.theme.preset)) add("error", "unknown_preset", "theme.preset", `Unknown theme preset "${doc.theme.preset}".`);
|
|
338
|
-
if (doc.layout) {
|
|
339
|
-
const nav = buildNav(catalog, {
|
|
340
|
-
...doc,
|
|
341
|
-
layout: void 0
|
|
342
|
-
});
|
|
343
|
-
const ids = /* @__PURE__ */ new Set([...nav.flatMap((s) => [s.id, ...s.items.map((i) => i.id)]), ...(doc.layout.customSections ?? []).map((c) => c.id)]);
|
|
344
|
-
const refs = [
|
|
345
|
-
...(doc.layout.hidden ?? []).map((id, i) => [`layout.hidden[${i}]`, id]),
|
|
346
|
-
...Object.keys(doc.layout.sections ?? {}).map((id) => [`layout.sections.${id}`, id]),
|
|
347
|
-
...Object.keys(doc.layout.items ?? {}).map((id) => [`layout.items.${id}`, id]),
|
|
348
|
-
...(doc.layout.sectionOrder ?? []).map((id, i) => [`layout.sectionOrder[${i}]`, id])
|
|
349
|
-
];
|
|
350
|
-
for (const [path, id] of refs) if (!ids.has(id)) add("warning", "unknown_layout_id", path, `The menu has no section or entry "${id}".`);
|
|
351
|
-
}
|
|
352
350
|
return out;
|
|
353
351
|
}
|
|
354
352
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document.js","names":[],"sources":["../../../src/cookbook/engine/document.ts"],"sourcesContent":["import type {\n Cookbook,\n CookbookPolicyRow,\n CookbookTheme,\n} from '@happyvertical/smrt-types';\nimport {\n COOKBOOK_SCHEMA_URL,\n COOKBOOK_VERSION,\n validateCookbook,\n} from '../validate.js';\nimport {\n COMMERCE_SETTING_TARGETS,\n DEFAULT_COLOR_SCHEME,\n DEFAULT_PRESET,\n DEFAULT_THEME_PRESETS,\n} from './defaults.js';\nimport { buildNav, findModel } from './nav.js';\nimport type {\n Diagnostic,\n EngineCatalog,\n EngineRecipe,\n RecipeChanges,\n SettingTargets,\n} from './types.js';\n\n/*\n * Pure document rules: every function takes a cookbook and returns a new one.\n * The engine holds a document and calls these; nothing here keeps state.\n */\n\nexport const clone = <T>(value: T): T =>\n value === undefined ? value : structuredClone(value);\n\nexport const same = (a: unknown, b: unknown): boolean =>\n JSON.stringify(a ?? null) === JSON.stringify(b ?? null);\n\nexport const emptyCookbook = (): Cookbook => ({\n $schema: COOKBOOK_SCHEMA_URL,\n version: COOKBOOK_VERSION,\n recipes: [],\n features: [],\n policies: [],\n});\n\n/** Does the document hold nothing yet (so replacing it needs no say-so)? */\nexport function isEmptyCookbook(doc: Cookbook): boolean {\n return (\n !doc.recipes.length &&\n !doc.features.length &&\n !doc.policies.length &&\n !Object.keys(doc.exposure ?? {}).length &&\n !doc.layout &&\n !doc.theme &&\n !Object.keys(doc.overviews ?? {}).length\n );\n}\n\nconst sortedUnique = (ids: Iterable<string>) => [...new Set(ids)].sort();\n\n/**\n * The document in its stable shape: sorted ids, sorted policies, empty optional\n * sections absent, key order fixed. Unknown top-level keys are kept (additive\n * fields in v1). Two engines given the same commands export identical text.\n */\nexport function canonical(doc: Cookbook): Cookbook {\n const known = new Set([\n '$schema',\n 'version',\n 'name',\n 'description',\n 'recipes',\n 'features',\n 'policies',\n 'exposure',\n 'layout',\n 'theme',\n 'overviews',\n ]);\n const out: Cookbook = {\n $schema: COOKBOOK_SCHEMA_URL,\n version: COOKBOOK_VERSION,\n ...(doc.name ? { name: doc.name } : {}),\n ...(doc.description ? { description: doc.description } : {}),\n recipes: sortedUnique(doc.recipes),\n features: sortedUnique(doc.features),\n policies: [...doc.policies]\n .sort(\n (a, b) =>\n a.objectRef.localeCompare(b.objectRef) ||\n a.fieldName.localeCompare(b.fieldName),\n )\n .map((row) => ({ ...row })),\n };\n const exposure = Object.fromEntries(\n Object.keys(doc.exposure ?? {})\n .sort()\n .filter((ref) => doc.exposure?.[ref]?.length)\n .map((ref) => [ref, [...(doc.exposure?.[ref] ?? [])].sort()]),\n );\n if (Object.keys(exposure).length) {\n out.exposure = exposure as NonNullable<Cookbook['exposure']>;\n }\n if (doc.layout) out.layout = clone(doc.layout);\n const theme = compactTheme(doc.theme);\n if (theme) out.theme = theme;\n const overviews = Object.entries(doc.overviews ?? {}).sort(([a], [b]) =>\n a < b ? -1 : a > b ? 1 : 0,\n );\n if (overviews.length) {\n out.overviews = Object.fromEntries(\n overviews.map(([id, value]) => [id, clone(value)]),\n );\n }\n for (const [key, value] of Object.entries(doc)) {\n if (!known.has(key))\n (out as unknown as Record<string, unknown>)[key] = clone(value);\n }\n return out;\n}\n\n// ---- recipes ---------------------------------------------------------------\n\nconst recipeMap = (catalog: EngineCatalog) =>\n new Map(catalog.recipes.map((r) => [r.id, r]));\n\n/** `ids` plus everything they transitively require, as a sorted set. */\nexport function withRequirements(\n ids: Iterable<string>,\n recipes: ReadonlyMap<string, EngineRecipe>,\n): string[] {\n const result = new Set<string>();\n const visit = (id: string) => {\n const recipe = recipes.get(id);\n if (!recipe || result.has(id)) return;\n result.add(id);\n for (const required of recipe.requires) visit(required);\n };\n for (const id of ids) visit(id);\n let changed = true;\n while (changed) {\n changed = false;\n for (const id of [...result]) {\n for (const alternatives of recipes.get(id)?.requiresAny ?? []) {\n if (alternatives.some((alt) => result.has(alt))) continue;\n const first = alternatives.find((alt) => recipes.has(alt));\n if (first) {\n visit(first);\n changed = true;\n }\n }\n }\n }\n return sortedUnique(result);\n}\n\n/** Models the added recipes and features cover. */\nexport function coveredModels(\n catalog: EngineCatalog,\n doc: Cookbook,\n): Set<string> {\n const byId = recipeMap(catalog);\n return new Set([\n ...doc.recipes.flatMap((id) => byId.get(id)?.models ?? []),\n ...doc.features,\n ]);\n}\n\nexport function settingTargets(catalog: EngineCatalog): SettingTargets {\n return catalog.settingTargets ?? COMMERCE_SETTING_TARGETS;\n}\n\nfunction isSettingRow(catalog: EngineCatalog, row: CookbookPolicyRow): boolean {\n return Object.values(settingTargets(catalog)).some((targets) =>\n targets.some((t) => t.model === row.objectRef && t.field === row.fieldName),\n );\n}\n\n/** Drop options for models nothing covers any more (settings rows stay). */\nexport function prune(catalog: EngineCatalog, doc: Cookbook): Cookbook {\n const covered = coveredModels(catalog, doc);\n const next: Cookbook = {\n ...doc,\n policies: doc.policies.filter(\n (r) => covered.has(r.objectRef) || isSettingRow(catalog, r),\n ),\n };\n if (doc.exposure) {\n const exposure = Object.fromEntries(\n Object.entries(doc.exposure).filter(([ref]) => covered.has(ref)),\n );\n if (Object.keys(exposure).length) next.exposure = exposure;\n else delete next.exposure;\n }\n return next;\n}\n\nconst knownRecipeIds = (catalog: EngineCatalog, doc: Cookbook) => {\n const byId = recipeMap(catalog);\n return doc.recipes.filter((id) => byId.has(id));\n};\n\nconst unknownRecipeIds = (catalog: EngineCatalog, doc: Cookbook) => {\n const byId = recipeMap(catalog);\n return doc.recipes.filter((id) => !byId.has(id));\n};\n\nfunction diff(\n before: string[],\n after: string[],\n): Pick<RecipeChanges, 'added' | 'removed'> {\n const b = new Set(before);\n const a = new Set(after);\n return {\n added: after.filter((id) => !b.has(id)),\n removed: before.filter((id) => !a.has(id)),\n };\n}\n\nexport function withRecipesAdded(\n catalog: EngineCatalog,\n doc: Cookbook,\n ids: readonly string[],\n): { doc: Cookbook; changes: RecipeChanges } {\n const byId = recipeMap(catalog);\n const before = knownRecipeIds(catalog, doc);\n const known = withRequirements([...before, ...ids], byId);\n const next = {\n ...doc,\n recipes: sortedUnique([...known, ...unknownRecipeIds(catalog, doc)]),\n };\n return { doc: next, changes: { ...diff(before, known), kept: [] } };\n}\n\nexport function withRecipesRemoved(\n catalog: EngineCatalog,\n doc: Cookbook,\n ids: readonly string[],\n): { doc: Cookbook; changes: RecipeChanges } {\n const byId = recipeMap(catalog);\n const before = knownRecipeIds(catalog, doc);\n const removing = new Set(ids);\n const known = withRequirements(\n before.filter((id) => !removing.has(id)),\n byId,\n );\n const next = prune(catalog, {\n ...doc,\n recipes: sortedUnique([...known, ...unknownRecipeIds(catalog, doc)]),\n });\n const { added, removed } = diff(before, known);\n return {\n doc: next,\n changes: {\n added,\n removed,\n kept: ids.filter((id) => known.includes(id) && before.includes(id)),\n },\n };\n}\n\nexport function withFeaturesChanged(\n catalog: EngineCatalog,\n doc: Cookbook,\n ids: readonly string[],\n on: boolean,\n): { doc: Cookbook; changes: RecipeChanges } {\n const set = new Set(doc.features);\n for (const id of ids) {\n if (on) set.add(id);\n else set.delete(id);\n }\n const features = [...set].sort();\n let next: Cookbook = { ...doc, features };\n if (!on) next = prune(catalog, next);\n return {\n doc: next,\n changes: { ...diff(doc.features, features), kept: [] },\n };\n}\n\nexport const mergeChanges = (\n a: RecipeChanges,\n b: RecipeChanges,\n): RecipeChanges => ({\n added: [...a.added, ...b.added],\n removed: [...a.removed, ...b.removed],\n kept: [...a.kept, ...b.kept],\n});\n\n// ---- settings --------------------------------------------------------------\n\nexport interface AppSettings {\n currency: string;\n /** A fraction: 0.0825 is 8.25%. */\n taxRate: number;\n paymentTerms: string;\n}\n\nexport const DEFAULT_SETTINGS: Readonly<AppSettings> = {\n currency: 'USD',\n taxRate: 0,\n paymentTerms: '',\n};\n\nconst SETTING_KEYS = ['currency', 'taxRate', 'paymentTerms'] as const;\n\nfunction rowValue(row: CookbookPolicyRow | undefined): unknown {\n if (row?.defaultValue === undefined || row.defaultValue === null)\n return undefined;\n try {\n return JSON.parse(row.defaultValue);\n } catch {\n return undefined;\n }\n}\n\nconst findRow = (\n policies: readonly CookbookPolicyRow[],\n model: string,\n field: string,\n) =>\n policies.find(\n (r) =>\n r.scopeType === 'app' && r.objectRef === model && r.fieldName === field,\n );\n\n/** The app's settings: the first stored row of each, else the defaults. */\nexport function readSettings(\n catalog: EngineCatalog,\n doc: Cookbook,\n): AppSettings {\n const targets = settingTargets(catalog);\n const out: AppSettings = { ...DEFAULT_SETTINGS };\n const first = (key: keyof AppSettings, type: 'number' | 'string') => {\n for (const { model, field } of targets[key]) {\n const value = rowValue(findRow(doc.policies, model, field));\n if (typeof value === type) return value;\n }\n return undefined;\n };\n const currency = first('currency', 'string');\n const taxRate = first('taxRate', 'number');\n const paymentTerms = first('paymentTerms', 'string');\n if (typeof currency === 'string') out.currency = currency;\n if (typeof taxRate === 'number') out.taxRate = taxRate;\n if (typeof paymentTerms === 'string') out.paymentTerms = paymentTerms;\n return out;\n}\n\nconst isUnset = (v: unknown) => v === undefined || v === null || v === '';\n\nfunction seedDefault(\n catalog: EngineCatalog,\n doc: Cookbook,\n modelId: string,\n field: string,\n): unknown {\n const byId = recipeMap(catalog);\n for (const id of doc.recipes) {\n const hint = byId.get(id)?.options?.[modelId]?.fields?.[field];\n if (hint && 'default' in hint) return hint.default;\n }\n return findModel(catalog, modelId)?.fields?.find((f) => f.name === field)\n ?.default;\n}\n\n/**\n * The document with the settings written as app-scope policy rows. A row is\n * written for every model a setting covers (covered or not, so a recipe added\n * later picks it up) and only where the value differs from what the model\n * starts as; otherwise the row's default is removed. Other row keys are kept.\n */\nexport function writeSettings(\n catalog: EngineCatalog,\n doc: Cookbook,\n settings: AppSettings,\n): Cookbook {\n const targets = settingTargets(catalog);\n let policies = doc.policies.map((row) => ({ ...row }));\n for (const key of SETTING_KEYS) {\n const raw = settings[key];\n const value =\n key === 'paymentTerms'\n ? String(raw).trim()\n : key === 'currency'\n ? String(raw).trim().toUpperCase()\n : raw;\n for (const { model, field } of targets[key]) {\n const seed = seedDefault(catalog, doc, model, field);\n const wanted =\n !isUnset(value) &&\n !(!isUnset(seed) && seed === value) &&\n !(isUnset(seed) && key === 'taxRate' && value === 0);\n const existing = findRow(policies, model, field);\n if (wanted) {\n const encoded = JSON.stringify(value);\n if (existing) existing.defaultValue = encoded;\n else\n policies.push({\n objectRef: model,\n fieldName: field,\n scopeType: 'app',\n defaultValue: encoded,\n });\n } else if (existing) {\n delete existing.defaultValue;\n if (Object.keys(existing).length <= 3) {\n policies = policies.filter((r) => r !== existing);\n }\n }\n }\n }\n return { ...doc, policies };\n}\n\n// ---- theme -----------------------------------------------------------------\n\nexport function compactTheme(\n theme: CookbookTheme | undefined,\n): CookbookTheme | undefined {\n if (!theme) return undefined;\n const out: CookbookTheme = {};\n if (theme.preset) out.preset = theme.preset;\n if (theme.colorScheme) out.colorScheme = theme.colorScheme;\n if (theme.custom) out.custom = { ...theme.custom };\n return Object.keys(out).length ? out : undefined;\n}\n\nexport function describeTheme(theme: CookbookTheme | undefined): string {\n const scheme = theme?.colorScheme ?? DEFAULT_COLOR_SCHEME;\n const base = theme?.custom\n ? `brand colour ${theme.custom.primary}`\n : (theme?.preset ?? DEFAULT_PRESET);\n return scheme === 'system' ? base : `${base}, ${scheme}`;\n}\n\n/** A preset replaces a brand colour; a brand colour sits on the preset; the scheme is kept. */\nexport function withThemePatch(\n doc: Cookbook,\n patch: {\n preset?: string;\n primary?: string;\n colorScheme?: CookbookTheme['colorScheme'];\n },\n): Cookbook {\n const next: CookbookTheme = { ...(doc.theme ?? {}) };\n if (patch.preset) {\n next.preset = patch.preset;\n delete next.custom;\n }\n if (patch.primary) {\n next.custom = {\n primary: patch.primary.toLowerCase(),\n ...(doc.theme?.custom?.fontFamily\n ? { fontFamily: doc.theme.custom.fontFamily }\n : {}),\n };\n }\n if (patch.colorScheme) next.colorScheme = patch.colorScheme;\n const theme = compactTheme(next);\n const out = { ...doc };\n if (theme) out.theme = theme;\n else delete out.theme;\n return out;\n}\n\n// ---- validation ------------------------------------------------------------\n\n/**\n * Check a document against the catalog. Structural errors come from\n * `validateCookbook`; the rest need the catalog: unknown ids, unmet `requires`,\n * policy targets nothing covers, layout ids the menu does not have, theme\n * values. Errors mean the app would not build as written; warnings mean\n * something is carried but unused.\n */\nexport function diagnose(\n catalog: EngineCatalog,\n input: Cookbook,\n): Diagnostic[] {\n const out: Diagnostic[] = [];\n const add = (\n severity: Diagnostic['severity'],\n code: string,\n path: string,\n message: string,\n ) => out.push({ severity, code, path, message });\n\n const structural = validateCookbook(input);\n if (!structural.ok) {\n for (const message of structural.errors) {\n add('error', 'invalid_document', '', message);\n }\n return out;\n }\n for (const message of structural.warnings)\n add('warning', 'migrated', '', message);\n const doc = structural.cookbook;\n const byId = recipeMap(catalog);\n\n for (const [i, id] of doc.recipes.entries()) {\n if (!byId.has(id))\n add(\n 'error',\n 'unknown_recipe',\n `recipes[${i}]`,\n `Unknown recipe \"${id}\".`,\n );\n }\n const closure = new Set(withRequirements(doc.recipes, byId));\n for (const id of closure) {\n if (!doc.recipes.includes(id)) {\n add(\n 'error',\n 'missing_requirement',\n 'recipes',\n `A recipe needs \"${id}\", which is not listed.`,\n );\n }\n }\n for (const [i, id] of doc.features.entries()) {\n const model = findModel(catalog, id);\n if (!model)\n add('error', 'unknown_model', `features[${i}]`, `Unknown model \"${id}\".`);\n else if (model.exposed === false) {\n add(\n 'error',\n 'model_not_exposed',\n `features[${i}]`,\n `${id} cannot be added as a feature.`,\n );\n }\n }\n const covered = coveredModels(catalog, doc);\n for (const [i, row] of doc.policies.entries()) {\n const at = `policies[${i}]`;\n const model = findModel(catalog, row.objectRef);\n if (!model) {\n add(\n 'error',\n 'unknown_model',\n `${at}.objectRef`,\n `Unknown model \"${row.objectRef}\".`,\n );\n continue;\n }\n if (\n model.fields &&\n !model.fields.some((f) => f.name === row.fieldName && !f.system)\n ) {\n add(\n 'error',\n 'unknown_field',\n `${at}.fieldName`,\n `${model.name} has no field \"${row.fieldName}\".`,\n );\n }\n if (!covered.has(row.objectRef) && !isSettingRow(catalog, row)) {\n add(\n 'warning',\n 'policy_not_covered',\n at,\n `${model.name} is not in the app, so this row has no effect.`,\n );\n }\n }\n for (const ref of Object.keys(doc.exposure ?? {})) {\n if (!findModel(catalog, ref)) {\n add(\n 'error',\n 'unknown_model',\n `exposure.${ref}`,\n `Unknown model \"${ref}\".`,\n );\n }\n }\n const presets = catalog.themePresets ?? DEFAULT_THEME_PRESETS;\n if (doc.theme?.preset && !presets.includes(doc.theme.preset)) {\n add(\n 'error',\n 'unknown_preset',\n 'theme.preset',\n `Unknown theme preset \"${doc.theme.preset}\".`,\n );\n }\n if (doc.layout) {\n const nav = buildNav(catalog, { ...doc, layout: undefined });\n const ids = new Set([\n ...nav.flatMap((s) => [s.id, ...s.items.map((i) => i.id)]),\n ...(doc.layout.customSections ?? []).map((c) => c.id),\n ]);\n const refs: [string, string][] = [\n ...(doc.layout.hidden ?? []).map((id, i): [string, string] => [\n `layout.hidden[${i}]`,\n id,\n ]),\n ...Object.keys(doc.layout.sections ?? {}).map((id): [string, string] => [\n `layout.sections.${id}`,\n id,\n ]),\n ...Object.keys(doc.layout.items ?? {}).map((id): [string, string] => [\n `layout.items.${id}`,\n id,\n ]),\n ...(doc.layout.sectionOrder ?? []).map((id, i): [string, string] => [\n `layout.sectionOrder[${i}]`,\n id,\n ]),\n ];\n for (const [path, id] of refs) {\n if (!ids.has(id)) {\n add(\n 'warning',\n 'unknown_layout_id',\n path,\n `The menu has no section or entry \"${id}\".`,\n );\n }\n }\n }\n return out;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"document.js","names":[],"sources":["../../../src/cookbook/engine/document.ts"],"sourcesContent":["import type {\n Cookbook,\n CookbookPolicyRow,\n CookbookTheme,\n} from '@happyvertical/smrt-types';\nimport {\n COOKBOOK_SCHEMA_URL,\n COOKBOOK_VERSION,\n validateCookbook,\n} from '../validate.js';\nimport {\n COMMERCE_SETTING_TARGETS,\n DEFAULT_COLOR_SCHEME,\n DEFAULT_PRESET,\n DEFAULT_THEME_PRESETS,\n} from './defaults.js';\nimport { buildNav, findModel } from './nav.js';\nimport type {\n Diagnostic,\n EngineCatalog,\n EngineRecipe,\n RecipeChanges,\n SettingTargets,\n} from './types.js';\n\n/*\n * Pure document rules: every function takes a cookbook and returns a new one.\n * The engine holds a document and calls these; nothing here keeps state.\n */\n\nexport const clone = <T>(value: T): T =>\n value === undefined ? value : structuredClone(value);\n\nexport const same = (a: unknown, b: unknown): boolean =>\n JSON.stringify(a ?? null) === JSON.stringify(b ?? null);\n\nexport const emptyCookbook = (): Cookbook => ({\n $schema: COOKBOOK_SCHEMA_URL,\n version: COOKBOOK_VERSION,\n recipes: [],\n features: [],\n policies: [],\n});\n\n/** Does the document hold nothing yet (so replacing it needs no say-so)? */\nexport function isEmptyCookbook(doc: Cookbook): boolean {\n return (\n !doc.recipes.length &&\n !doc.features.length &&\n !doc.policies.length &&\n !Object.keys(doc.exposure ?? {}).length &&\n !doc.layout &&\n !doc.theme &&\n !Object.keys(doc.overviews ?? {}).length\n );\n}\n\nconst sortedUnique = (ids: Iterable<string>) => [...new Set(ids)].sort();\n\n/**\n * The document in its stable shape: sorted ids, sorted policies, empty optional\n * sections absent, key order fixed. Unknown top-level keys are kept (additive\n * fields in v1). Two engines given the same commands export identical text.\n */\nexport function canonical(doc: Cookbook): Cookbook {\n const known = new Set([\n '$schema',\n 'version',\n 'name',\n 'description',\n 'recipes',\n 'features',\n 'policies',\n 'exposure',\n 'layout',\n 'theme',\n 'overviews',\n ]);\n const out: Cookbook = {\n $schema: COOKBOOK_SCHEMA_URL,\n version: COOKBOOK_VERSION,\n ...(doc.name ? { name: doc.name } : {}),\n ...(doc.description ? { description: doc.description } : {}),\n recipes: sortedUnique(doc.recipes),\n features: sortedUnique(doc.features),\n policies: [...doc.policies]\n .sort(\n (a, b) =>\n a.objectRef.localeCompare(b.objectRef) ||\n a.fieldName.localeCompare(b.fieldName),\n )\n .map((row) => ({ ...row })),\n };\n const exposure = Object.fromEntries(\n Object.keys(doc.exposure ?? {})\n .sort()\n .filter((ref) => doc.exposure?.[ref]?.length)\n .map((ref) => [ref, [...(doc.exposure?.[ref] ?? [])].sort()]),\n );\n if (Object.keys(exposure).length) {\n out.exposure = exposure as NonNullable<Cookbook['exposure']>;\n }\n if (doc.layout) out.layout = clone(doc.layout);\n const theme = compactTheme(doc.theme);\n if (theme) out.theme = theme;\n const overviews = Object.entries(doc.overviews ?? {}).sort(([a], [b]) =>\n a < b ? -1 : a > b ? 1 : 0,\n );\n if (overviews.length) {\n out.overviews = Object.fromEntries(\n overviews.map(([id, value]) => [id, clone(value)]),\n );\n }\n for (const [key, value] of Object.entries(doc)) {\n if (!known.has(key))\n (out as unknown as Record<string, unknown>)[key] = clone(value);\n }\n return out;\n}\n\n// ---- recipes ---------------------------------------------------------------\n\nconst recipeMap = (catalog: EngineCatalog) =>\n new Map(catalog.recipes.map((r) => [r.id, r]));\n\n/** `ids` plus everything they transitively require, as a sorted set. */\nexport function withRequirements(\n ids: Iterable<string>,\n recipes: ReadonlyMap<string, EngineRecipe>,\n): string[] {\n const result = new Set<string>();\n const visit = (id: string) => {\n const recipe = recipes.get(id);\n if (!recipe || result.has(id)) return;\n result.add(id);\n for (const required of recipe.requires) visit(required);\n };\n for (const id of ids) visit(id);\n let changed = true;\n while (changed) {\n changed = false;\n for (const id of [...result]) {\n for (const alternatives of recipes.get(id)?.requiresAny ?? []) {\n if (alternatives.some((alt) => result.has(alt))) continue;\n const first = alternatives.find((alt) => recipes.has(alt));\n if (first) {\n visit(first);\n changed = true;\n }\n }\n }\n }\n return sortedUnique(result);\n}\n\n/** Models the added recipes and features cover. */\nexport function coveredModels(\n catalog: EngineCatalog,\n doc: Cookbook,\n): Set<string> {\n const byId = recipeMap(catalog);\n return new Set([\n ...doc.recipes.flatMap((id) => byId.get(id)?.models ?? []),\n ...doc.features,\n ]);\n}\n\nexport function settingTargets(catalog: EngineCatalog): SettingTargets {\n return catalog.settingTargets ?? COMMERCE_SETTING_TARGETS;\n}\n\nfunction isSettingRow(catalog: EngineCatalog, row: CookbookPolicyRow): boolean {\n return Object.values(settingTargets(catalog)).some((targets) =>\n targets.some((t) => t.model === row.objectRef && t.field === row.fieldName),\n );\n}\n\n/** Drop options for models nothing covers any more (settings rows stay). */\nexport function prune(catalog: EngineCatalog, doc: Cookbook): Cookbook {\n const covered = coveredModels(catalog, doc);\n const next: Cookbook = {\n ...doc,\n policies: doc.policies.filter(\n (r) => covered.has(r.objectRef) || isSettingRow(catalog, r),\n ),\n };\n if (doc.exposure) {\n const exposure = Object.fromEntries(\n Object.entries(doc.exposure).filter(([ref]) => covered.has(ref)),\n );\n if (Object.keys(exposure).length) next.exposure = exposure;\n else delete next.exposure;\n }\n return next;\n}\n\nconst knownRecipeIds = (catalog: EngineCatalog, doc: Cookbook) => {\n const byId = recipeMap(catalog);\n return doc.recipes.filter((id) => byId.has(id));\n};\n\nconst unknownRecipeIds = (catalog: EngineCatalog, doc: Cookbook) => {\n const byId = recipeMap(catalog);\n return doc.recipes.filter((id) => !byId.has(id));\n};\n\nfunction diff(\n before: string[],\n after: string[],\n): Pick<RecipeChanges, 'added' | 'removed'> {\n const b = new Set(before);\n const a = new Set(after);\n return {\n added: after.filter((id) => !b.has(id)),\n removed: before.filter((id) => !a.has(id)),\n };\n}\n\nexport function withRecipesAdded(\n catalog: EngineCatalog,\n doc: Cookbook,\n ids: readonly string[],\n): { doc: Cookbook; changes: RecipeChanges } {\n const byId = recipeMap(catalog);\n const before = knownRecipeIds(catalog, doc);\n const known = withRequirements([...before, ...ids], byId);\n const next = {\n ...doc,\n recipes: sortedUnique([...known, ...unknownRecipeIds(catalog, doc)]),\n };\n return { doc: next, changes: { ...diff(before, known), kept: [] } };\n}\n\nexport function withRecipesRemoved(\n catalog: EngineCatalog,\n doc: Cookbook,\n ids: readonly string[],\n): { doc: Cookbook; changes: RecipeChanges } {\n const byId = recipeMap(catalog);\n const before = knownRecipeIds(catalog, doc);\n const removing = new Set(ids);\n const known = withRequirements(\n before.filter((id) => !removing.has(id)),\n byId,\n );\n const next = prune(catalog, {\n ...doc,\n recipes: sortedUnique([...known, ...unknownRecipeIds(catalog, doc)]),\n });\n const { added, removed } = diff(before, known);\n return {\n doc: next,\n changes: {\n added,\n removed,\n kept: ids.filter((id) => known.includes(id) && before.includes(id)),\n },\n };\n}\n\nexport function withFeaturesChanged(\n catalog: EngineCatalog,\n doc: Cookbook,\n ids: readonly string[],\n on: boolean,\n): { doc: Cookbook; changes: RecipeChanges } {\n const set = new Set(doc.features);\n for (const id of ids) {\n if (on) set.add(id);\n else set.delete(id);\n }\n const features = [...set].sort();\n let next: Cookbook = { ...doc, features };\n if (!on) next = prune(catalog, next);\n return {\n doc: next,\n changes: { ...diff(doc.features, features), kept: [] },\n };\n}\n\nexport const mergeChanges = (\n a: RecipeChanges,\n b: RecipeChanges,\n): RecipeChanges => ({\n added: [...a.added, ...b.added],\n removed: [...a.removed, ...b.removed],\n kept: [...a.kept, ...b.kept],\n});\n\n// ---- settings --------------------------------------------------------------\n\nexport interface AppSettings {\n currency: string;\n /** A fraction: 0.0825 is 8.25%. */\n taxRate: number;\n paymentTerms: string;\n}\n\nexport const DEFAULT_SETTINGS: Readonly<AppSettings> = {\n currency: 'USD',\n taxRate: 0,\n paymentTerms: '',\n};\n\nconst SETTING_KEYS = ['currency', 'taxRate', 'paymentTerms'] as const;\n\nfunction rowValue(row: CookbookPolicyRow | undefined): unknown {\n if (row?.defaultValue === undefined || row.defaultValue === null)\n return undefined;\n try {\n return JSON.parse(row.defaultValue);\n } catch {\n return undefined;\n }\n}\n\nconst findRow = (\n policies: readonly CookbookPolicyRow[],\n model: string,\n field: string,\n) =>\n policies.find(\n (r) =>\n r.scopeType === 'app' && r.objectRef === model && r.fieldName === field,\n );\n\n/** The app's settings: the first stored row of each, else the defaults. */\nexport function readSettings(\n catalog: EngineCatalog,\n doc: Cookbook,\n): AppSettings {\n const targets = settingTargets(catalog);\n const out: AppSettings = { ...DEFAULT_SETTINGS };\n const first = (key: keyof AppSettings, type: 'number' | 'string') => {\n for (const { model, field } of targets[key]) {\n const value = rowValue(findRow(doc.policies, model, field));\n if (typeof value === type) return value;\n }\n return undefined;\n };\n const currency = first('currency', 'string');\n const taxRate = first('taxRate', 'number');\n const paymentTerms = first('paymentTerms', 'string');\n if (typeof currency === 'string') out.currency = currency;\n if (typeof taxRate === 'number') out.taxRate = taxRate;\n if (typeof paymentTerms === 'string') out.paymentTerms = paymentTerms;\n return out;\n}\n\nconst isUnset = (v: unknown) => v === undefined || v === null || v === '';\n\nfunction seedDefault(\n catalog: EngineCatalog,\n doc: Cookbook,\n modelId: string,\n field: string,\n): unknown {\n const byId = recipeMap(catalog);\n for (const id of doc.recipes) {\n const hint = byId.get(id)?.options?.[modelId]?.fields?.[field];\n if (hint && 'default' in hint) return hint.default;\n }\n return findModel(catalog, modelId)?.fields?.find((f) => f.name === field)\n ?.default;\n}\n\n/**\n * The document with the settings written as app-scope policy rows. A row is\n * written for every model a setting covers (covered or not, so a recipe added\n * later picks it up) and only where the value differs from what the model\n * starts as; otherwise the row's default is removed. Other row keys are kept.\n */\nexport function writeSettings(\n catalog: EngineCatalog,\n doc: Cookbook,\n settings: AppSettings,\n): Cookbook {\n const targets = settingTargets(catalog);\n let policies = doc.policies.map((row) => ({ ...row }));\n for (const key of SETTING_KEYS) {\n const raw = settings[key];\n const value =\n key === 'paymentTerms'\n ? String(raw).trim()\n : key === 'currency'\n ? String(raw).trim().toUpperCase()\n : raw;\n for (const { model, field } of targets[key]) {\n const seed = seedDefault(catalog, doc, model, field);\n const wanted =\n !isUnset(value) &&\n !(!isUnset(seed) && seed === value) &&\n !(isUnset(seed) && key === 'taxRate' && value === 0);\n const existing = findRow(policies, model, field);\n if (wanted) {\n const encoded = JSON.stringify(value);\n if (existing) existing.defaultValue = encoded;\n else\n policies.push({\n objectRef: model,\n fieldName: field,\n scopeType: 'app',\n defaultValue: encoded,\n });\n } else if (existing) {\n delete existing.defaultValue;\n if (Object.keys(existing).length <= 3) {\n policies = policies.filter((r) => r !== existing);\n }\n }\n }\n }\n return { ...doc, policies };\n}\n\n// ---- theme -----------------------------------------------------------------\n\nexport function compactTheme(\n theme: CookbookTheme | undefined,\n): CookbookTheme | undefined {\n if (!theme) return undefined;\n const out: CookbookTheme = {};\n if (theme.preset) out.preset = theme.preset;\n if (theme.colorScheme) out.colorScheme = theme.colorScheme;\n if (theme.custom) out.custom = { ...theme.custom };\n return Object.keys(out).length ? out : undefined;\n}\n\nexport function describeTheme(theme: CookbookTheme | undefined): string {\n const scheme = theme?.colorScheme ?? DEFAULT_COLOR_SCHEME;\n const base = theme?.custom\n ? `brand colour ${theme.custom.primary}`\n : (theme?.preset ?? DEFAULT_PRESET);\n return scheme === 'system' ? base : `${base}, ${scheme}`;\n}\n\n/** A preset replaces a brand colour; a brand colour sits on the preset; the scheme is kept. */\nexport function withThemePatch(\n doc: Cookbook,\n patch: {\n preset?: string;\n primary?: string;\n colorScheme?: CookbookTheme['colorScheme'];\n },\n): Cookbook {\n const next: CookbookTheme = { ...(doc.theme ?? {}) };\n if (patch.preset) {\n next.preset = patch.preset;\n delete next.custom;\n }\n if (patch.primary) {\n next.custom = {\n primary: patch.primary.toLowerCase(),\n ...(doc.theme?.custom?.fontFamily\n ? { fontFamily: doc.theme.custom.fontFamily }\n : {}),\n };\n }\n if (patch.colorScheme) next.colorScheme = patch.colorScheme;\n const theme = compactTheme(next);\n const out = { ...doc };\n if (theme) out.theme = theme;\n else delete out.theme;\n return out;\n}\n\n// ---- validation ------------------------------------------------------------\n\n/**\n * Check a document against the catalog. Structural errors come from\n * `validateCookbook`; the rest need the catalog: unknown ids, unmet `requires`,\n * policy targets nothing covers, layout ids the menu does not have, theme\n * values. Errors mean the app would not build as written; warnings mean\n * something is carried but unused.\n */\nexport function diagnose(\n catalog: EngineCatalog,\n input: Cookbook,\n): Diagnostic[] {\n const out: Diagnostic[] = [];\n const add = (\n severity: Diagnostic['severity'],\n code: string,\n path: string,\n message: string,\n ) => out.push({ severity, code, path, message });\n\n const structural = validateCookbook(input);\n if (!structural.ok) {\n for (const issue of structural.diagnostics.filter(\n (diagnostic) => diagnostic.severity === 'error',\n )) {\n add('error', 'invalid_document', issue.path, issue.message);\n }\n return out;\n }\n for (const issue of structural.diagnostics) {\n add(\n issue.severity,\n issue.code === 'migrated_schema' ? 'migrated' : issue.code,\n issue.path,\n issue.message,\n );\n }\n const doc = structural.cookbook;\n const byId = recipeMap(catalog);\n\n const nav = buildNav(catalog, { ...doc, layout: undefined });\n const checked = validateCookbook(doc, {\n themePresets: catalog.themePresets ?? DEFAULT_THEME_PRESETS,\n layout: {\n sections: nav.map((section) => section.id),\n items: nav.flatMap((section) => section.items.map((item) => item.id)),\n ...(catalog.placementItems\n ? { placementItems: catalog.placementItems }\n : {}),\n },\n overviewIds: [\n ...nav.map((section) => section.id),\n ...(doc.layout?.customSections ?? []).map((section) => section.id),\n ],\n });\n for (const issue of checked.diagnostics) {\n if (\n issue.code === 'unknown_theme_preset' ||\n issue.code === 'unknown_layout_id' ||\n issue.code === 'unknown_overview'\n ) {\n add(\n issue.code === 'unknown_layout_id' &&\n !issue.path.startsWith('layout.placements.')\n ? 'warning'\n : issue.severity,\n issue.code === 'unknown_theme_preset' ? 'unknown_preset' : issue.code,\n issue.path,\n issue.message,\n );\n }\n }\n\n for (const [i, id] of doc.recipes.entries()) {\n if (!byId.has(id))\n add(\n 'error',\n 'unknown_recipe',\n `recipes[${i}]`,\n `Unknown recipe \"${id}\".`,\n );\n }\n const closure = new Set(withRequirements(doc.recipes, byId));\n for (const id of closure) {\n if (!doc.recipes.includes(id)) {\n add(\n 'error',\n 'missing_requirement',\n 'recipes',\n `A recipe needs \"${id}\", which is not listed.`,\n );\n }\n }\n for (const [i, id] of doc.features.entries()) {\n const model = findModel(catalog, id);\n if (!model)\n add('error', 'unknown_model', `features[${i}]`, `Unknown model \"${id}\".`);\n else if (model.exposed === false) {\n add(\n 'error',\n 'model_not_exposed',\n `features[${i}]`,\n `${id} cannot be added as a feature.`,\n );\n }\n }\n const covered = coveredModels(catalog, doc);\n for (const [i, row] of doc.policies.entries()) {\n const at = `policies[${i}]`;\n const model = findModel(catalog, row.objectRef);\n if (!model) {\n add(\n 'error',\n 'unknown_model',\n `${at}.objectRef`,\n `Unknown model \"${row.objectRef}\".`,\n );\n continue;\n }\n if (\n model.fields &&\n !model.fields.some((f) => f.name === row.fieldName && !f.system)\n ) {\n add(\n 'error',\n 'unknown_field',\n `${at}.fieldName`,\n `${model.name} has no field \"${row.fieldName}\".`,\n );\n }\n if (!covered.has(row.objectRef) && !isSettingRow(catalog, row)) {\n add(\n 'warning',\n 'policy_not_covered',\n at,\n `${model.name} is not in the app, so this row has no effect.`,\n );\n }\n }\n for (const ref of Object.keys(doc.exposure ?? {})) {\n if (!findModel(catalog, ref)) {\n add(\n 'error',\n 'unknown_model',\n `exposure.${ref}`,\n `Unknown model \"${ref}\".`,\n );\n }\n }\n return out;\n}\n"],"mappings":"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"}
|
|
@@ -55,6 +55,8 @@ export interface EngineCatalog {
|
|
|
55
55
|
recipes: readonly EngineRecipe[];
|
|
56
56
|
models: readonly EngineModel[];
|
|
57
57
|
cookbooks?: readonly EngineLibraryCookbook[];
|
|
58
|
+
/** Movable shell item ids resolved by the host (`dock:`, `slot:`, recipe, or host ids). */
|
|
59
|
+
placementItems?: readonly string[];
|
|
58
60
|
/** Theme preset names; default {@link DEFAULT_THEME_PRESETS}. */
|
|
59
61
|
themePresets?: readonly string[];
|
|
60
62
|
/** ISO 4217 codes; default any three capital letters. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cookbook/engine/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cookbook/engine/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../../src/cookbook/engine/types.ts"],"sourcesContent":["/**\n * Cookbook command engine, contract v1 (#3753).\n *\n * Plain data in, plain data out: no SvelteKit, browser storage, planner\n * singleton or inference dependency, and no Node imports, so the same engine\n * runs in a browser planner, a CLI, an MCP server or a website. Adapters own\n * navigation/focus, persistence and transport; the engine owns the document.\n */\nimport type { Cookbook, RecipeDefinition } from '@happyvertical/smrt-types';\n\n/**\n * The command set version. A change an older client could not send or read\n * bumps it; adding a command or an optional field does not.\n */\nexport const COOKBOOK_COMMANDS_VERSION = 1;\n\n/** The part of a manifest recipe the engine reads (a `RecipeDefinition` fits). */\nexport type EngineRecipe = Pick<\n RecipeDefinition,\n 'id' | 'label' | 'models' | 'nav' | 'requires'\n> &\n Partial<\n Pick<RecipeDefinition, 'requiresAny' | 'group' | 'section' | 'options'>\n >;\n\n/** One field of a catalog model, for `set_policy` and settings defaults. */\nexport interface EngineField {\n name: string;\n /** System fields (id, timestamps) cannot be given a policy. */\n system?: boolean;\n /** The field's own starting value, so a setting equal to it writes no row. */\n default?: unknown;\n}\n\n/** One catalog model. Same shape as smrt-svelte's `CookbookModelInfo`, plus fields. */\nexport interface EngineModel {\n /** Qualified name, `@scope/pkg:Class`. */\n id: string;\n name: string;\n /** Package id used in item ids: `commerce` for `@happyvertical/smrt-commerce`. */\n packageId: string;\n description?: string;\n /** Has an API, MCP or CLI surface; only exposed models can be added as features. */\n exposed?: boolean;\n /** When given, `set_policy` rejects a field not listed. */\n fields?: readonly EngineField[];\n}\n\n/** A ready-made cookbook the catalog offers (a library entry). */\nexport interface EngineLibraryCookbook {\n id: string;\n name: string;\n document: Cookbook;\n}\n\n/** Which model fields each app setting is the default of. */\nexport type SettingTargets = Record<\n 'currency' | 'taxRate' | 'paymentTerms',\n readonly { model: string; field: string }[]\n>;\n\n/**\n * Everything the engine resolves ids against, as data: recipes and models from\n * published manifests, optionally a library of cookbooks. Nothing here is\n * bundled with the engine.\n */\nexport interface EngineCatalog {\n recipes: readonly EngineRecipe[];\n models: readonly EngineModel[];\n cookbooks?: readonly EngineLibraryCookbook[];\n /** Theme preset names; default {@link DEFAULT_THEME_PRESETS}. */\n themePresets?: readonly string[];\n /** ISO 4217 codes; default any three capital letters. */\n currencies?: readonly string[];\n /** Default {@link COMMERCE_SETTING_TARGETS}. */\n settingTargets?: SettingTargets;\n}\n\n/** Input of each command, keyed by the command's (tool) name. */\nexport interface CommandInputs {\n /** Switch recipes on, with everything they `require`. */\n add_recipes: { ids: string[] };\n /** Switch recipes off; ones another recipe needs are kept (and reported). */\n remove_recipes: { ids: string[] };\n /** Add models no recipe covers, by qualified name. */\n add_features: { ids: string[] };\n remove_features: { ids: string[] };\n /** Add the recipes and features of a library cookbook to what is there. */\n add_cookbook: { id: string };\n /** Remove what a library cookbook added (recipes others need are kept). */\n remove_cookbook: { id: string };\n /** Select a library cookbook, replacing the app (needs `replace` if non-empty). */\n apply_cookbook: { id: string; replace?: boolean };\n /** Import a cookbook document, replacing the app (needs `replace` if non-empty). */\n import_cookbook: { document: unknown; replace?: boolean };\n /** App settings; tax rate in percent, 0 to 100. */\n set_settings: { currency?: string; taxRate?: number; paymentTerms?: string };\n /** Set (or clear with null) one field's policy row. App scope. */\n set_policy: {\n model: string;\n field: string;\n defaultValue?: unknown;\n visibility?: 'basic' | 'advanced' | 'hidden' | null;\n label?: string | null;\n help?: string | null;\n };\n set_theme: {\n preset?: string;\n primary?: string;\n colorScheme?: 'light' | 'dark' | 'system';\n };\n reset_theme: Record<string, never>;\n /** Name (and describe) the app; null clears. */\n set_name: { name?: string | null; description?: string | null };\n rename_section: { id: string; label: string };\n /** `null` restores the entry's own name. */\n rename_item: { id: string; label: string | null };\n hide: { id: string };\n show: { id: string };\n /** Check the current document and report typed diagnostics. Changes nothing. */\n validate: Record<string, never>;\n /** The cookbook as `<name>.cookbook.json` text. Changes nothing. */\n export_cookbook: { name?: string };\n /** Undo an earlier change by the `undoId` its receipt carried. */\n undo: { undoId: string; force?: boolean };\n}\n\nexport type CommandName = keyof CommandInputs;\n\n/** A command as a client sends it. */\nexport type CookbookCommand = {\n [N in CommandName]: {\n name: N;\n input: CommandInputs[N];\n /** Retry key: a repeated id returns the first receipt and applies nothing. */\n id?: string;\n /** Refuse with `conflict` unless the plan is still at this revision. */\n expectedRevision?: number;\n };\n}[CommandName];\n\n/** Stable strings a client can switch on. */\nexport type CommandErrorCode =\n | 'unknown_command'\n | 'invalid_input'\n | 'not_found'\n /** A destructive command needs `replace: true` (or `force: true`). */\n | 'confirmation_required'\n /** The plan moved on since the caller looked (`expectedRevision`, undo). */\n | 'conflict'\n /** A command id was reused with a different command. */\n | 'id_reuse'\n /** An atomic batch failed; `details.index` names the command, nothing applied. */\n | 'batch_failed'\n | 'failed';\n\nexport interface CommandError {\n code: CommandErrorCode;\n message: string;\n /** Where the problem is, as a path into the input (`input.ids[1]`). */\n path?: string;\n details?: Record<string, unknown>;\n}\n\n/** What a recipe/feature command did, after `requires` ran. */\nexport interface RecipeChanges {\n added: string[];\n removed: string[];\n /** Asked to remove, but another recipe still needs them. */\n kept: string[];\n}\n\nexport interface PlanSnapshot {\n version: typeof COOKBOOK_COMMANDS_VERSION;\n /** Counts applied changes; equal histories give equal revisions. */\n revision: number;\n app: { name: string; description: string | null; cookbook: string | null };\n recipes: { id: string; label: string }[];\n features: string[];\n /** Recipe and feature ids this catalog lacks; kept on export. */\n unavailable: string[];\n settings: { currency: string; taxRate: number; paymentTerms: string };\n theme: {\n text: string;\n preset: string | null;\n primary: string | null;\n colorScheme: string;\n };\n sections: {\n id: string;\n label: string;\n hidden: boolean;\n items: { id: string; label: string; hidden: boolean }[];\n }[];\n policies: number;\n /** Undo ids still available, newest last. */\n undo: string[];\n}\n\nexport interface CommandReceipt {\n name: CommandName;\n /** The command id, when one was sent. */\n id?: string;\n summary: string;\n changed: boolean;\n revisionBefore: number;\n revisionAfter: number;\n undoId?: string;\n changes?: RecipeChanges;\n /** Non-fatal notes (an import's legacy `$schema` migration). */\n warnings?: string[];\n}\n\nexport type CommandResult =\n | {\n ok: true;\n id?: string;\n /** True when this is the stored result of an earlier run of the same id. */\n replayed?: boolean;\n snapshot: PlanSnapshot;\n receipt: CommandReceipt;\n data?: unknown;\n }\n | { ok: false; id?: string; replayed?: boolean; error: CommandError };\n\nexport interface RunOptions {\n expectedRevision?: number;\n}\n\n/** Several commands applied all-or-nothing. */\nexport interface CommandBatch {\n id?: string;\n commands: readonly unknown[];\n expectedRevision?: number;\n}\n\nexport type BatchResult =\n | {\n ok: true;\n id?: string;\n replayed?: boolean;\n snapshot: PlanSnapshot;\n receipt: {\n id?: string;\n count: number;\n changed: boolean;\n revisionBefore: number;\n revisionAfter: number;\n undoId?: string;\n };\n /** One result per command, in order. */\n results: Extract<CommandResult, { ok: true }>[];\n }\n | {\n ok: false;\n id?: string;\n replayed?: boolean;\n error: CommandError;\n /** The state is exactly as before the batch. */\n snapshot: PlanSnapshot;\n };\n\n/** One diagnostic from `validate`. */\nexport interface Diagnostic {\n severity: 'error' | 'warning';\n code: string;\n path: string;\n message: string;\n}\n\nexport interface ValidateData {\n ok: boolean;\n diagnostics: Diagnostic[];\n}\n\nexport interface ExportData {\n fileName: string;\n text: string;\n cookbook: Cookbook;\n}\n\n/** A journal row: enough to answer a retry of `id` after a restart. */\nexport interface JournalEntry {\n id: string;\n fingerprint: string;\n result: CommandResult | BatchResult;\n}\n\n/** The engine's whole state as plain JSON, to persist and resume from. */\nexport interface EngineState {\n version: typeof COOKBOOK_COMMANDS_VERSION;\n revision: number;\n /** The library cookbook the plan was last set up from, if any. */\n applied: string | null;\n cookbook: Cookbook;\n journal: JournalEntry[];\n}\n\nexport interface JsonSchema {\n [key: string]: unknown;\n}\n\n/** One command as an LLM or MCP tool definition. */\nexport interface CommandTool {\n name: CommandName;\n description: string;\n inputSchema: JsonSchema;\n}\n"],"mappings":";;;;;AAcA,IAAa,4BAA4B"}
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../../src/cookbook/engine/types.ts"],"sourcesContent":["/**\n * Cookbook command engine, contract v1 (#3753).\n *\n * Plain data in, plain data out: no SvelteKit, browser storage, planner\n * singleton or inference dependency, and no Node imports, so the same engine\n * runs in a browser planner, a CLI, an MCP server or a website. Adapters own\n * navigation/focus, persistence and transport; the engine owns the document.\n */\nimport type { Cookbook, RecipeDefinition } from '@happyvertical/smrt-types';\n\n/**\n * The command set version. A change an older client could not send or read\n * bumps it; adding a command or an optional field does not.\n */\nexport const COOKBOOK_COMMANDS_VERSION = 1;\n\n/** The part of a manifest recipe the engine reads (a `RecipeDefinition` fits). */\nexport type EngineRecipe = Pick<\n RecipeDefinition,\n 'id' | 'label' | 'models' | 'nav' | 'requires'\n> &\n Partial<\n Pick<RecipeDefinition, 'requiresAny' | 'group' | 'section' | 'options'>\n >;\n\n/** One field of a catalog model, for `set_policy` and settings defaults. */\nexport interface EngineField {\n name: string;\n /** System fields (id, timestamps) cannot be given a policy. */\n system?: boolean;\n /** The field's own starting value, so a setting equal to it writes no row. */\n default?: unknown;\n}\n\n/** One catalog model. Same shape as smrt-svelte's `CookbookModelInfo`, plus fields. */\nexport interface EngineModel {\n /** Qualified name, `@scope/pkg:Class`. */\n id: string;\n name: string;\n /** Package id used in item ids: `commerce` for `@happyvertical/smrt-commerce`. */\n packageId: string;\n description?: string;\n /** Has an API, MCP or CLI surface; only exposed models can be added as features. */\n exposed?: boolean;\n /** When given, `set_policy` rejects a field not listed. */\n fields?: readonly EngineField[];\n}\n\n/** A ready-made cookbook the catalog offers (a library entry). */\nexport interface EngineLibraryCookbook {\n id: string;\n name: string;\n document: Cookbook;\n}\n\n/** Which model fields each app setting is the default of. */\nexport type SettingTargets = Record<\n 'currency' | 'taxRate' | 'paymentTerms',\n readonly { model: string; field: string }[]\n>;\n\n/**\n * Everything the engine resolves ids against, as data: recipes and models from\n * published manifests, optionally a library of cookbooks. Nothing here is\n * bundled with the engine.\n */\nexport interface EngineCatalog {\n recipes: readonly EngineRecipe[];\n models: readonly EngineModel[];\n cookbooks?: readonly EngineLibraryCookbook[];\n /** Movable shell item ids resolved by the host (`dock:`, `slot:`, recipe, or host ids). */\n placementItems?: readonly string[];\n /** Theme preset names; default {@link DEFAULT_THEME_PRESETS}. */\n themePresets?: readonly string[];\n /** ISO 4217 codes; default any three capital letters. */\n currencies?: readonly string[];\n /** Default {@link COMMERCE_SETTING_TARGETS}. */\n settingTargets?: SettingTargets;\n}\n\n/** Input of each command, keyed by the command's (tool) name. */\nexport interface CommandInputs {\n /** Switch recipes on, with everything they `require`. */\n add_recipes: { ids: string[] };\n /** Switch recipes off; ones another recipe needs are kept (and reported). */\n remove_recipes: { ids: string[] };\n /** Add models no recipe covers, by qualified name. */\n add_features: { ids: string[] };\n remove_features: { ids: string[] };\n /** Add the recipes and features of a library cookbook to what is there. */\n add_cookbook: { id: string };\n /** Remove what a library cookbook added (recipes others need are kept). */\n remove_cookbook: { id: string };\n /** Select a library cookbook, replacing the app (needs `replace` if non-empty). */\n apply_cookbook: { id: string; replace?: boolean };\n /** Import a cookbook document, replacing the app (needs `replace` if non-empty). */\n import_cookbook: { document: unknown; replace?: boolean };\n /** App settings; tax rate in percent, 0 to 100. */\n set_settings: { currency?: string; taxRate?: number; paymentTerms?: string };\n /** Set (or clear with null) one field's policy row. App scope. */\n set_policy: {\n model: string;\n field: string;\n defaultValue?: unknown;\n visibility?: 'basic' | 'advanced' | 'hidden' | null;\n label?: string | null;\n help?: string | null;\n };\n set_theme: {\n preset?: string;\n primary?: string;\n colorScheme?: 'light' | 'dark' | 'system';\n };\n reset_theme: Record<string, never>;\n /** Name (and describe) the app; null clears. */\n set_name: { name?: string | null; description?: string | null };\n rename_section: { id: string; label: string };\n /** `null` restores the entry's own name. */\n rename_item: { id: string; label: string | null };\n hide: { id: string };\n show: { id: string };\n /** Check the current document and report typed diagnostics. Changes nothing. */\n validate: Record<string, never>;\n /** The cookbook as `<name>.cookbook.json` text. Changes nothing. */\n export_cookbook: { name?: string };\n /** Undo an earlier change by the `undoId` its receipt carried. */\n undo: { undoId: string; force?: boolean };\n}\n\nexport type CommandName = keyof CommandInputs;\n\n/** A command as a client sends it. */\nexport type CookbookCommand = {\n [N in CommandName]: {\n name: N;\n input: CommandInputs[N];\n /** Retry key: a repeated id returns the first receipt and applies nothing. */\n id?: string;\n /** Refuse with `conflict` unless the plan is still at this revision. */\n expectedRevision?: number;\n };\n}[CommandName];\n\n/** Stable strings a client can switch on. */\nexport type CommandErrorCode =\n | 'unknown_command'\n | 'invalid_input'\n | 'not_found'\n /** A destructive command needs `replace: true` (or `force: true`). */\n | 'confirmation_required'\n /** The plan moved on since the caller looked (`expectedRevision`, undo). */\n | 'conflict'\n /** A command id was reused with a different command. */\n | 'id_reuse'\n /** An atomic batch failed; `details.index` names the command, nothing applied. */\n | 'batch_failed'\n | 'failed';\n\nexport interface CommandError {\n code: CommandErrorCode;\n message: string;\n /** Where the problem is, as a path into the input (`input.ids[1]`). */\n path?: string;\n details?: Record<string, unknown>;\n}\n\n/** What a recipe/feature command did, after `requires` ran. */\nexport interface RecipeChanges {\n added: string[];\n removed: string[];\n /** Asked to remove, but another recipe still needs them. */\n kept: string[];\n}\n\nexport interface PlanSnapshot {\n version: typeof COOKBOOK_COMMANDS_VERSION;\n /** Counts applied changes; equal histories give equal revisions. */\n revision: number;\n app: { name: string; description: string | null; cookbook: string | null };\n recipes: { id: string; label: string }[];\n features: string[];\n /** Recipe and feature ids this catalog lacks; kept on export. */\n unavailable: string[];\n settings: { currency: string; taxRate: number; paymentTerms: string };\n theme: {\n text: string;\n preset: string | null;\n primary: string | null;\n colorScheme: string;\n };\n sections: {\n id: string;\n label: string;\n hidden: boolean;\n items: { id: string; label: string; hidden: boolean }[];\n }[];\n policies: number;\n /** Undo ids still available, newest last. */\n undo: string[];\n}\n\nexport interface CommandReceipt {\n name: CommandName;\n /** The command id, when one was sent. */\n id?: string;\n summary: string;\n changed: boolean;\n revisionBefore: number;\n revisionAfter: number;\n undoId?: string;\n changes?: RecipeChanges;\n /** Non-fatal notes (an import's legacy `$schema` migration). */\n warnings?: string[];\n}\n\nexport type CommandResult =\n | {\n ok: true;\n id?: string;\n /** True when this is the stored result of an earlier run of the same id. */\n replayed?: boolean;\n snapshot: PlanSnapshot;\n receipt: CommandReceipt;\n data?: unknown;\n }\n | { ok: false; id?: string; replayed?: boolean; error: CommandError };\n\nexport interface RunOptions {\n expectedRevision?: number;\n}\n\n/** Several commands applied all-or-nothing. */\nexport interface CommandBatch {\n id?: string;\n commands: readonly unknown[];\n expectedRevision?: number;\n}\n\nexport type BatchResult =\n | {\n ok: true;\n id?: string;\n replayed?: boolean;\n snapshot: PlanSnapshot;\n receipt: {\n id?: string;\n count: number;\n changed: boolean;\n revisionBefore: number;\n revisionAfter: number;\n undoId?: string;\n };\n /** One result per command, in order. */\n results: Extract<CommandResult, { ok: true }>[];\n }\n | {\n ok: false;\n id?: string;\n replayed?: boolean;\n error: CommandError;\n /** The state is exactly as before the batch. */\n snapshot: PlanSnapshot;\n };\n\n/** One diagnostic from `validate`. */\nexport interface Diagnostic {\n severity: 'error' | 'warning';\n code: string;\n path: string;\n message: string;\n}\n\nexport interface ValidateData {\n ok: boolean;\n diagnostics: Diagnostic[];\n}\n\nexport interface ExportData {\n fileName: string;\n text: string;\n cookbook: Cookbook;\n}\n\n/** A journal row: enough to answer a retry of `id` after a restart. */\nexport interface JournalEntry {\n id: string;\n fingerprint: string;\n result: CommandResult | BatchResult;\n}\n\n/** The engine's whole state as plain JSON, to persist and resume from. */\nexport interface EngineState {\n version: typeof COOKBOOK_COMMANDS_VERSION;\n revision: number;\n /** The library cookbook the plan was last set up from, if any. */\n applied: string | null;\n cookbook: Cookbook;\n journal: JournalEntry[];\n}\n\nexport interface JsonSchema {\n [key: string]: unknown;\n}\n\n/** One command as an LLM or MCP tool definition. */\nexport interface CommandTool {\n name: CommandName;\n description: string;\n inputSchema: JsonSchema;\n}\n"],"mappings":";;;;;AAcA,IAAa,4BAA4B"}
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"theme": { "$ref": "#/$defs/theme" },
|
|
30
30
|
"overviews": {
|
|
31
31
|
"type": "object",
|
|
32
|
+
"propertyNames": { "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,95}$" },
|
|
32
33
|
"additionalProperties": { "$ref": "#/$defs/overviewOverride" }
|
|
33
34
|
}
|
|
34
35
|
},
|
|
@@ -68,7 +69,7 @@
|
|
|
68
69
|
},
|
|
69
70
|
"placements": {
|
|
70
71
|
"type": "object",
|
|
71
|
-
"additionalProperties": { "
|
|
72
|
+
"additionalProperties": { "$ref": "#/$defs/shellSlot" }
|
|
72
73
|
},
|
|
73
74
|
"sections": {
|
|
74
75
|
"type": "object",
|
|
@@ -96,6 +97,20 @@
|
|
|
96
97
|
},
|
|
97
98
|
"additionalProperties": true
|
|
98
99
|
},
|
|
100
|
+
"shellSlot": {
|
|
101
|
+
"enum": [
|
|
102
|
+
"header.start",
|
|
103
|
+
"header.center",
|
|
104
|
+
"header.end",
|
|
105
|
+
"footer.start",
|
|
106
|
+
"footer.center",
|
|
107
|
+
"footer.end",
|
|
108
|
+
"leftSidebar.header",
|
|
109
|
+
"leftSidebar.footer",
|
|
110
|
+
"rightSidebar.header",
|
|
111
|
+
"rightSidebar.footer"
|
|
112
|
+
]
|
|
113
|
+
},
|
|
99
114
|
"theme": {
|
|
100
115
|
"type": "object",
|
|
101
116
|
"properties": {
|
|
@@ -119,13 +134,55 @@
|
|
|
119
134
|
"version": { "const": 1 },
|
|
120
135
|
"order": { "$ref": "#/$defs/stringList" },
|
|
121
136
|
"removed": { "$ref": "#/$defs/stringList" },
|
|
122
|
-
"added": { "type": "array", "items": { "
|
|
137
|
+
"added": { "type": "array", "items": { "$ref": "#/$defs/overviewWidget" } },
|
|
123
138
|
"changed": {
|
|
124
139
|
"type": "object",
|
|
125
|
-
"
|
|
140
|
+
"propertyNames": { "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$" },
|
|
141
|
+
"additionalProperties": { "$ref": "#/$defs/overviewPatch" }
|
|
126
142
|
}
|
|
127
143
|
},
|
|
128
144
|
"additionalProperties": true
|
|
145
|
+
},
|
|
146
|
+
"overviewWidget": {
|
|
147
|
+
"type": "object",
|
|
148
|
+
"required": ["id", "type", "span", "options"],
|
|
149
|
+
"properties": {
|
|
150
|
+
"id": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$" },
|
|
151
|
+
"type": { "type": "string", "pattern": "^[a-z][a-z0-9-]{0,31}$" },
|
|
152
|
+
"span": { "type": "integer", "minimum": 1, "maximum": 4 },
|
|
153
|
+
"options": {
|
|
154
|
+
"type": "object",
|
|
155
|
+
"additionalProperties": {
|
|
156
|
+
"anyOf": [
|
|
157
|
+
{ "type": "string" },
|
|
158
|
+
{ "type": "number" },
|
|
159
|
+
{ "type": "boolean" },
|
|
160
|
+
{ "type": "null" }
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
"version": { "type": "integer", "minimum": 1 }
|
|
165
|
+
},
|
|
166
|
+
"additionalProperties": true
|
|
167
|
+
},
|
|
168
|
+
"overviewPatch": {
|
|
169
|
+
"type": "object",
|
|
170
|
+
"properties": {
|
|
171
|
+
"span": { "type": "integer", "minimum": 1, "maximum": 4 },
|
|
172
|
+
"options": {
|
|
173
|
+
"type": "object",
|
|
174
|
+
"additionalProperties": {
|
|
175
|
+
"anyOf": [
|
|
176
|
+
{ "type": "string" },
|
|
177
|
+
{ "type": "number" },
|
|
178
|
+
{ "type": "boolean" },
|
|
179
|
+
{ "type": "null" }
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
"version": { "type": "integer", "minimum": 1 }
|
|
184
|
+
},
|
|
185
|
+
"additionalProperties": true
|
|
129
186
|
}
|
|
130
187
|
}
|
|
131
188
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Cookbook } from '@happyvertical/smrt-types';
|
|
1
|
+
import type { Cookbook, CookbookOverviewOverride } from '@happyvertical/smrt-types';
|
|
2
2
|
export type { Cookbook } from '@happyvertical/smrt-types';
|
|
3
3
|
/** What a v1 document carries in `$schema`. */
|
|
4
4
|
export declare const COOKBOOK_SCHEMA_URL = "https://s-m-r-t.dev/schemas/cookbook/v1.json";
|
|
@@ -12,14 +12,50 @@ export interface CookbookValidateOptions {
|
|
|
12
12
|
* seam `smrt cookbook validate` fills.
|
|
13
13
|
*/
|
|
14
14
|
recipes?: Iterable<string>;
|
|
15
|
+
/** Built-in or host-registered theme preset ids. */
|
|
16
|
+
themePresets?: Iterable<string>;
|
|
17
|
+
/** Manifest-derived ids the cookbook layout may reference. */
|
|
18
|
+
layout?: {
|
|
19
|
+
sections?: Iterable<string>;
|
|
20
|
+
items?: Iterable<string>;
|
|
21
|
+
/** Movable shell item ids resolved by the host (`dock:`, `slot:`, or host ids). */
|
|
22
|
+
placementItems?: Iterable<string>;
|
|
23
|
+
};
|
|
24
|
+
/** Overview page ids defined by the resolved app shell. */
|
|
25
|
+
overviewIds?: Iterable<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Validate and canonicalize one structurally valid override against its page
|
|
28
|
+
* definition and widget registry. The callback is trusted host code; the
|
|
29
|
+
* cookbook value remains plain data and is never executed.
|
|
30
|
+
*/
|
|
31
|
+
validateOverview?: (id: string, override: CookbookOverviewOverride) => CookbookOverviewValidation;
|
|
15
32
|
}
|
|
33
|
+
export interface CookbookDiagnostic {
|
|
34
|
+
severity: 'error' | 'warning';
|
|
35
|
+
/** Stable machine-readable category. Host validators may add their own. */
|
|
36
|
+
code: string;
|
|
37
|
+
/** Path into the cookbook, using the existing dotted/indexed notation. */
|
|
38
|
+
path: string;
|
|
39
|
+
message: string;
|
|
40
|
+
}
|
|
41
|
+
export type CookbookOverviewValidation = {
|
|
42
|
+
ok: true;
|
|
43
|
+
/** `null` means the canonical override is empty and should be omitted. */
|
|
44
|
+
override: CookbookOverviewOverride | null;
|
|
45
|
+
diagnostics?: readonly CookbookDiagnostic[];
|
|
46
|
+
} | {
|
|
47
|
+
ok: false;
|
|
48
|
+
diagnostics: readonly CookbookDiagnostic[];
|
|
49
|
+
};
|
|
16
50
|
export type CookbookValidation = {
|
|
17
51
|
ok: true;
|
|
18
52
|
cookbook: Cookbook;
|
|
19
53
|
warnings: string[];
|
|
54
|
+
diagnostics: CookbookDiagnostic[];
|
|
20
55
|
} | {
|
|
21
56
|
ok: false;
|
|
22
57
|
errors: string[];
|
|
58
|
+
diagnostics: CookbookDiagnostic[];
|
|
23
59
|
};
|
|
24
60
|
/**
|
|
25
61
|
* Structural validation of an unknown value (parsed JSON). Returns the
|
|
@@ -27,9 +63,9 @@ export type CookbookValidation = {
|
|
|
27
63
|
* recipes sorted and unique) or every problem found, each a readable line
|
|
28
64
|
* naming the path. Unknown top-level keys are kept (additive fields in v1).
|
|
29
65
|
*
|
|
30
|
-
* Deep checks
|
|
31
|
-
*
|
|
32
|
-
*
|
|
66
|
+
* Deep checks use optional host-supplied catalogs. A structurally valid
|
|
67
|
+
* cookbook remains portable when those catalogs are absent. Invalid overview
|
|
68
|
+
* entries are dropped and reported, following the v1 overview contract.
|
|
33
69
|
*/
|
|
34
70
|
export declare function validateCookbook(input: unknown, options?: CookbookValidateOptions): CookbookValidation;
|
|
35
71
|
/** Parse JSON text, then {@link validateCookbook} it. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/cookbook/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/cookbook/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EAGR,wBAAwB,EAKzB,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D,+CAA+C;AAC/C,eAAO,MAAM,mBAAmB,iDACgB,CAAC;AACjD,oFAAoF;AACpF,eAAO,MAAM,0BAA0B,kDACU,CAAC;AAClD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3B,oDAAoD;IACpD,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,8DAA8D;IAC9D,MAAM,CAAC,EAAE;QACP,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC5B,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QACzB,mFAAmF;QACnF,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;KACnC,CAAC;IACF,2DAA2D;IAC3D,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CACjB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,wBAAwB,KAC/B,0BAA0B,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,0BAA0B,GAClC;IACE,EAAE,EAAE,IAAI,CAAC;IACT,0EAA0E;IAC1E,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;CAC7C,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,WAAW,EAAE,SAAS,kBAAkB,EAAE,CAAA;CAAE,CAAC;AAE9D,MAAM,MAAM,kBAAkB,GAC1B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,kBAAkB,EAAE,CAAC;CACnC,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,kBAAkB,EAAE,CAAA;CAAE,CAAC;AAqavE;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,uBAA4B,GACpC,kBAAkB,CA4UpB;AAED,yDAAyD;AACzD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,uBAA4B,GACpC,kBAAkB,CAmBpB"}
|