@happyvertical/smrt-core 0.44.0 → 0.45.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.md +8 -8
- package/agents/change-feed.md +3 -2
- package/agents/generators.md +34 -0
- package/agents/revision-guard.md +66 -0
- package/dist/browser.js +2 -1
- package/dist/cascade.d.ts +5 -9
- package/dist/cascade.d.ts.map +1 -1
- package/dist/cascade.js +65 -30
- package/dist/cascade.js.map +1 -1
- package/dist/change-feed.d.ts +60 -1
- package/dist/change-feed.d.ts.map +1 -1
- package/dist/change-feed.js +464 -27
- package/dist/change-feed.js.map +1 -1
- package/dist/change-signals.d.ts.map +1 -1
- package/dist/change-signals.js +13 -11
- package/dist/change-signals.js.map +1 -1
- package/dist/embedded-write-queue.d.ts +8 -0
- package/dist/embedded-write-queue.d.ts.map +1 -1
- package/dist/embedded-write-queue.js +12 -2
- package/dist/embedded-write-queue.js.map +1 -1
- package/dist/generators/cli.d.ts.map +1 -1
- package/dist/generators/cli.js +10 -18
- package/dist/generators/cli.js.map +1 -1
- package/dist/generators/custom-action.d.ts +216 -0
- package/dist/generators/custom-action.d.ts.map +1 -1
- package/dist/generators/custom-action.js +256 -1
- package/dist/generators/custom-action.js.map +1 -1
- package/dist/generators/index.d.ts +2 -1
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +3 -2
- package/dist/generators/mcp.d.ts.map +1 -1
- package/dist/generators/mcp.js +14 -39
- package/dist/generators/mcp.js.map +1 -1
- package/dist/generators/preflight-route.d.ts +151 -0
- package/dist/generators/preflight-route.d.ts.map +1 -0
- package/dist/generators/preflight-route.js +194 -0
- package/dist/generators/preflight-route.js.map +1 -0
- package/dist/generators/rest.d.ts +12 -0
- package/dist/generators/rest.d.ts.map +1 -1
- package/dist/generators/rest.js +14 -15
- package/dist/generators/rest.js.map +1 -1
- package/dist/generators/tool-schema.d.ts.map +1 -1
- package/dist/generators/tool-schema.js +2 -8
- package/dist/generators/tool-schema.js.map +1 -1
- package/dist/generators.js +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/dist/knowledge.d.ts.map +1 -1
- package/dist/knowledge.js +283 -35
- package/dist/knowledge.js.map +1 -1
- package/dist/manifest/static-manifest.d.ts.map +1 -1
- package/dist/manifest/static-manifest.js +6 -2
- 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 +8 -2
- package/dist/object.d.ts +31 -1
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +57 -9
- package/dist/object.js.map +1 -1
- package/dist/registry/framework-base-classes.d.ts +10 -0
- package/dist/registry/framework-base-classes.d.ts.map +1 -0
- package/dist/registry/framework-base-classes.js +92 -0
- package/dist/registry/framework-base-classes.js.map +1 -0
- package/dist/registry/schema-builder.d.ts.map +1 -1
- package/dist/registry/schema-builder.js +2 -0
- package/dist/registry/schema-builder.js.map +1 -1
- package/dist/registry/types.d.ts +27 -6
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry.d.ts +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +2 -1
- package/dist/registry.js.map +1 -1
- package/dist/revision-guard.d.ts +84 -0
- package/dist/revision-guard.d.ts.map +1 -0
- package/dist/revision-guard.js +120 -0
- package/dist/revision-guard.js.map +1 -0
- package/dist/scanner/manifest-generator.d.ts +46 -16
- package/dist/scanner/manifest-generator.d.ts.map +1 -1
- package/dist/scanner/manifest-generator.js +198 -45
- package/dist/scanner/manifest-generator.js.map +1 -1
- package/dist/smrt-knowledge.json +18 -9
- package/dist/system/bootstrap.d.ts.map +1 -1
- package/dist/system/bootstrap.js +2 -1
- package/dist/system/bootstrap.js.map +1 -1
- package/dist/system/schema.d.ts +75 -2
- package/dist/system/schema.d.ts.map +1 -1
- package/dist/system/schema.js +326 -4
- package/dist/system/schema.js.map +1 -1
- package/dist/vite-plugin/index.d.ts.map +1 -1
- package/dist/vite-plugin/index.js +48 -23
- package/dist/vite-plugin/index.js.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.d.ts +33 -7
- package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.js +88 -17
- 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 +2 -0
- package/dist/vite-plugin/sync-apply-route.js.map +1 -1
- package/dist/vite-plugin/web-collections.d.ts.map +1 -1
- package/dist/vite-plugin/web-collections.js +28 -5
- package/dist/vite-plugin/web-collections.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sveltekit-generator.d.ts","sourceRoot":"","sources":["../../src/vite-plugin/sveltekit-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"sveltekit-generator.d.ts","sourceRoot":"","sources":["../../src/vite-plugin/sveltekit-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAYvE,OAAO,KAAK,EAGV,aAAa,EAEd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAEV,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAY1B,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iFAAiF;IACjF,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACrC;;;;;;;;;;;;;;OAcG;IACH,WAAW,CAAC,EAAE;QACZ,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;CACH;AAYD,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC;IAC7B,MAAM,EAAE,aAAa,CAAC;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAqxBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKtD;AA+BD,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,EACjC,SAAS,EAAE,OAAO,EAClB,YAAY,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,EAC5C,YAAY,GAAE,MAAM,GAAG,YAEb,GACT,4BAA4B,CAwB9B;AAiUD;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CA6Ff;AAy0BD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,qBAAqB,EAChC,QAAQ,CAAC,EAAE,mBAAmB,GAC7B,GAAG,CAAC,MAAM,CAAC,CA6Cb;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAuDD;;;;;;;;;;GAUG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,mBAAmB,GAC5B,wBAAwB,EAAE,CAsB5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,mBAAmB,GAC5B,IAAI,CA2BN"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MAX_LIST_LIMIT, buildDefaultListOrderBy } from "../query-bounds.js";
|
|
2
|
-
import { resolveCustomActionMetadata } from "../generators/custom-action.js";
|
|
2
|
+
import { resolveCustomActionMetadata, resolveCustomActionNames } from "../generators/custom-action.js";
|
|
3
|
+
import { isFrameworkBaseClass } from "../registry/framework-base-classes.js";
|
|
3
4
|
import { generateConditionalGetRouteHelper } from "../generators/conditional-get.js";
|
|
4
5
|
import { AUTO_GENERATED_ROUTE_HEADER } from "./route-header.js";
|
|
5
6
|
import { generateChangesRoute } from "./changes-route.js";
|
|
@@ -764,6 +765,7 @@ async function generateSvelteKitRoutes(projectRoot, manifest, options) {
|
|
|
764
765
|
let generatedCount = 0;
|
|
765
766
|
let skippedCollections = 0;
|
|
766
767
|
for (const [className, objectDef] of Object.entries(manifest.objects)) {
|
|
768
|
+
if (isFrameworkBaseClass(objectDef.className, objectDef.packageName)) continue;
|
|
767
769
|
if (isCollectionManifestClass(manifest, objectDef)) {
|
|
768
770
|
const collectionRoutePaths = await generateCollectionRoutesForObject(projectRoot, className, objectDef, manifest, options);
|
|
769
771
|
generatedRoutePaths.push(...collectionRoutePaths);
|
|
@@ -1295,9 +1297,54 @@ function resolveApiActionSet(objectDef, manifest) {
|
|
|
1295
1297
|
return actions;
|
|
1296
1298
|
}
|
|
1297
1299
|
/**
|
|
1298
|
-
*
|
|
1299
|
-
*
|
|
1300
|
-
*
|
|
1300
|
+
* Resolve the effective CLI command set for an object, for the cli↔api
|
|
1301
|
+
* coherence lint. Two distinct resolutions, chosen by whether `cli.include`
|
|
1302
|
+
* is spelled out:
|
|
1303
|
+
*
|
|
1304
|
+
* **Explicit `cli.include`** (preserves the lint's exact pre-#2638
|
|
1305
|
+
* algorithm): the literal `include − exclude`, verbatim, whether or not an
|
|
1306
|
+
* entry resolves to a real CRUD verb or a scanned public method. This is
|
|
1307
|
+
* deliberate, not an oversight -- an `include` entry that names a typo, a
|
|
1308
|
+
* getter (never in the manifest's `methods` map), or a private/protected
|
|
1309
|
+
* method (the scanner drops these rather than recording `isPublic: false`,
|
|
1310
|
+
* so nothing else catches it) must still surface as "unreachable" so the
|
|
1311
|
+
* build fails loudly on the config mistake, the same way it always has.
|
|
1312
|
+
* Resolving it instead through `resolveCustomActionNames` -- which only
|
|
1313
|
+
* iterates real scanned methods -- would silently drop such an entry with no
|
|
1314
|
+
* error at all (final review, #2638).
|
|
1315
|
+
*
|
|
1316
|
+
* **Bare `cli: true`/`cli: {}`** (#2638, the new case this lint now
|
|
1317
|
+
* inspects): every public custom method minus exclude, exactly the "every
|
|
1318
|
+
* public method minus exclude" resolution `CLIGenerator.listCommands()`
|
|
1319
|
+
* already applies (via `resolveCustomActionNames`, reused not
|
|
1320
|
+
* reimplemented) -- lifecycle methods excluded, same as everywhere else.
|
|
1321
|
+
* CRUD verbs are NOT checked in this branch: a class that closes its API
|
|
1322
|
+
* entirely (`api: false`) while keeping a default-open, CLI/MCP-only admin
|
|
1323
|
+
* surface (`cli: true`/omitted) is a common, intentional combination (see
|
|
1324
|
+
* `cli.skipApiCheck`'s own "in-process, no HTTP" doc comment); blanket-
|
|
1325
|
+
* checking CRUD reachability for every such class would flag that existing,
|
|
1326
|
+
* legitimate pattern across the whole codebase, not just the #2638 defect
|
|
1327
|
+
* (confirmed by running this against the full monorepo build during
|
|
1328
|
+
* development — it did exactly that).
|
|
1329
|
+
*/
|
|
1330
|
+
function resolveCliActionSet(objectDef) {
|
|
1331
|
+
const cliConfig = objectDef.decoratorConfig?.cli;
|
|
1332
|
+
if (cliConfig === false) return /* @__PURE__ */ new Set();
|
|
1333
|
+
const included = typeof cliConfig === "object" ? cliConfig.include : void 0;
|
|
1334
|
+
const excluded = typeof cliConfig === "object" && Array.isArray(cliConfig.exclude) ? cliConfig.exclude : [];
|
|
1335
|
+
if (included) return new Set(included.filter((cmd) => !excluded.includes(cmd)));
|
|
1336
|
+
return resolveCustomActionNames(Object.entries(objectDef.methods || {}), {
|
|
1337
|
+
include: void 0,
|
|
1338
|
+
exclude: excluded
|
|
1339
|
+
}, STANDARD_API_ACTIONS);
|
|
1340
|
+
}
|
|
1341
|
+
/**
|
|
1342
|
+
* Inspect a manifest and return classes whose effective CLI command set —
|
|
1343
|
+
* `cli.include`/`cli.exclude` when spelled out, or (#2638) the same "every
|
|
1344
|
+
* public method minus exclude" default `cli: true`/`cli: {}` resolves to —
|
|
1345
|
+
* references a command not exposed via the API. Classes that opt out via
|
|
1346
|
+
* `cli: { skipApiCheck: true }` are skipped, and so is a class with
|
|
1347
|
+
* `cli: false` (no CLI surface at all).
|
|
1301
1348
|
*
|
|
1302
1349
|
* Throws nothing; returns the violation list so callers can choose to throw
|
|
1303
1350
|
* or warn.
|
|
@@ -1306,14 +1353,12 @@ function findCliApiCoherenceViolations(manifest) {
|
|
|
1306
1353
|
const violations = [];
|
|
1307
1354
|
for (const [className, objectDef] of Object.entries(manifest.objects)) {
|
|
1308
1355
|
const cliConfig = objectDef.decoratorConfig?.cli;
|
|
1309
|
-
if (
|
|
1310
|
-
if (cliConfig.skipApiCheck) continue;
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
const effectiveCliCommands = cliConfig.include.filter((cmd) => !cliExclude.includes(cmd));
|
|
1314
|
-
if (effectiveCliCommands.length === 0) continue;
|
|
1356
|
+
if (cliConfig === false) continue;
|
|
1357
|
+
if (typeof cliConfig === "object" && cliConfig.skipApiCheck) continue;
|
|
1358
|
+
const effectiveCliCommands = resolveCliActionSet(objectDef);
|
|
1359
|
+
if (effectiveCliCommands.size === 0) continue;
|
|
1315
1360
|
const apiActionSet = resolveApiActionSet(objectDef, manifest);
|
|
1316
|
-
const unreachable = effectiveCliCommands.filter((action) => !apiActionSet.has(action));
|
|
1361
|
+
const unreachable = [...effectiveCliCommands].filter((action) => !apiActionSet.has(action)).sort();
|
|
1317
1362
|
if (unreachable.length > 0) violations.push({
|
|
1318
1363
|
className,
|
|
1319
1364
|
unreachable
|
|
@@ -1322,15 +1367,41 @@ function findCliApiCoherenceViolations(manifest) {
|
|
|
1322
1367
|
return violations;
|
|
1323
1368
|
}
|
|
1324
1369
|
/**
|
|
1325
|
-
* Throw if any class in the manifest has `cli.include`
|
|
1326
|
-
* reachable via the API. Default build-time gate; opt-out
|
|
1327
|
-
* `cli: { skipApiCheck: true }` (or globally via the vite
|
|
1328
|
-
* `validateCliApiCoherence: false`).
|
|
1370
|
+
* Throw if any class in the manifest has an EXPLICIT `cli.include` command
|
|
1371
|
+
* that isn't reachable via the API. Default build-time gate; opt-out
|
|
1372
|
+
* per-class via `cli: { skipApiCheck: true }` (or globally via the vite
|
|
1373
|
+
* plugin option `validateCliApiCoherence: false`).
|
|
1374
|
+
*
|
|
1375
|
+
* This is deliberately narrower than `findCliApiCoherenceViolations` above.
|
|
1376
|
+
* That function is now fully correct for the broader `cli: true`/`cli: {}`
|
|
1377
|
+
* default surface too (#2638: same "every public method minus exclude"
|
|
1378
|
+
* resolution `listCommands()` uses, so a bare `cli: true` is inspected the
|
|
1379
|
+
* same as an explicit `include`). But `smrtPlugin()`'s default
|
|
1380
|
+
* `validateCliApiCoherence: true` calls this THROWING gate unconditionally
|
|
1381
|
+
* from every consuming package's own build (`configResolved`,
|
|
1382
|
+
* `vite-plugin/index.ts`) -- and a full-monorepo build during #2638
|
|
1383
|
+
* development showed that broader surface has thousands of pre-existing
|
|
1384
|
+
* public getters/business-logic methods (e.g.
|
|
1385
|
+
* `@happyvertical/smrt-ads:AdGroup.hasStarted`,
|
|
1386
|
+
* `@happyvertical/smrt-tags:Tag.getParent`) across ~28 packages that were
|
|
1387
|
+
* never meant to be REST-reachable and have no API route today. That
|
|
1388
|
+
* over-exposure is real, pre-existing, and unrelated to #2638's framework-
|
|
1389
|
+
* lifecycle-method defect -- flipping this gate to enforce it unconditionally
|
|
1390
|
+
* would break every one of those packages' builds today, which is a
|
|
1391
|
+
* repo-wide triage effort (add routes, or an explicit `cli.exclude`/
|
|
1392
|
+
* `skipApiCheck` per owner) this PR did not undertake and is out of its
|
|
1393
|
+
* file boundary. So the gate keeps its pre-#2638 blast radius -- classes
|
|
1394
|
+
* that spell out a non-empty `cli.include` -- while `findCliApiCoherenceViolations`
|
|
1395
|
+
* is complete and available (and covered by its own tests) for the broader
|
|
1396
|
+
* check once that pre-existing surface is triaged.
|
|
1329
1397
|
*/
|
|
1330
1398
|
function validateCliIncludeAgainstApi(manifest) {
|
|
1331
|
-
const violations = findCliApiCoherenceViolations(manifest)
|
|
1399
|
+
const violations = findCliApiCoherenceViolations(manifest).filter(({ className }) => {
|
|
1400
|
+
const cliConfig = manifest.objects[className]?.decoratorConfig?.cli;
|
|
1401
|
+
return typeof cliConfig === "object" && Array.isArray(cliConfig.include) && cliConfig.include.length > 0;
|
|
1402
|
+
});
|
|
1332
1403
|
if (violations.length === 0) return;
|
|
1333
|
-
const messages = violations.flatMap(({ className, unreachable }) => unreachable.map((action) => `[smrt] ${className}.${action} is
|
|
1404
|
+
const messages = violations.flatMap(({ className, unreachable }) => unreachable.map((action) => `[smrt] ${className}.${action} is exposed as a CLI command but is not exposed via the api.\n Either:\n - Add '${action}' to api.include, or\n - Remove '${action}' from cli.include / add it to cli.exclude.\n The CLI invokes methods over HTTP; methods without API routes are unreachable.\n If this CLI is intentionally invoked in-process (no HTTP), set\n \`cli: { skipApiCheck: true }\` on the @smrt() decorator to acknowledge.`));
|
|
1334
1405
|
throw new Error(messages.join("\n\n"));
|
|
1335
1406
|
}
|
|
1336
1407
|
/**
|