@happyvertical/smrt-core 0.40.42 → 0.40.44
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 +12 -1
- package/README.md +24 -0
- package/agents/generators.md +3 -1
- package/dist/decorators/index.d.ts +12 -0
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js.map +1 -1
- package/dist/generators/mcp.d.ts.map +1 -1
- package/dist/generators/mcp.js +1 -1
- package/dist/generators/mcp.js.map +1 -1
- package/dist/generators/tool-schema.d.ts.map +1 -1
- package/dist/generators/tool-schema.js +1 -1
- package/dist/generators/tool-schema.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/manifest/static-manifest.js +2 -2
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.js +1 -1
- package/dist/manifest/test-manifest-stub.d.ts.map +1 -1
- package/dist/manifest/test-manifest-stub.js +100 -2
- package/dist/manifest/test-manifest-stub.js.map +1 -1
- package/dist/manifest.json +2 -2
- package/dist/prebuild/index.d.ts.map +1 -1
- package/dist/prebuild/index.js +23 -1
- package/dist/prebuild/index.js.map +1 -1
- package/dist/registry/types.d.ts +6 -0
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/scanner/types.d.ts +30 -0
- package/dist/scanner/types.d.ts.map +1 -1
- package/dist/smrt-knowledge.json +8 -8
- package/dist/vite-plugin/index.d.ts.map +1 -1
- package/dist/vite-plugin/index.js +16 -4
- package/dist/vite-plugin/index.js.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.js +64 -35
- package/dist/vite-plugin/sveltekit-generator.js.map +1 -1
- package/dist/vite-plugin/web-collections.d.ts +22 -2
- package/dist/vite-plugin/web-collections.d.ts.map +1 -1
- package/dist/vite-plugin/web-collections.js +37 -3
- package/dist/vite-plugin/web-collections.js.map +1 -1
- package/package.json +4 -4
|
@@ -19,6 +19,9 @@ var STANDARD_API_ACTIONS = [
|
|
|
19
19
|
"update",
|
|
20
20
|
"delete"
|
|
21
21
|
];
|
|
22
|
+
var GITIGNORE_MANAGED_BLOCK_START = "# BEGIN SMRT auto-generated routes (Vite plugin)";
|
|
23
|
+
var GITIGNORE_MANAGED_BLOCK_END = "# END SMRT auto-generated routes (Vite plugin)";
|
|
24
|
+
var LEGACY_GITIGNORE_HEADER = "# SMRT auto-generated routes (from Vite plugin)";
|
|
22
25
|
/**
|
|
23
26
|
* Extract simple class name from potentially qualified name.
|
|
24
27
|
* Qualified names follow the pattern: @scope/package:ClassName
|
|
@@ -635,25 +638,28 @@ async function generateSvelteKitRoutes(projectRoot, manifest, options) {
|
|
|
635
638
|
clearGeneratedRouteFiles(join(projectRoot, options.routesDir));
|
|
636
639
|
clearGeneratedKnowledgeRoute(projectRoot, options);
|
|
637
640
|
await generateSmrtConfigFile(projectRoot, manifest, options);
|
|
641
|
+
const generatedRoutePaths = [];
|
|
638
642
|
let generatedCount = 0;
|
|
639
643
|
let skippedCollections = 0;
|
|
640
644
|
for (const [className, objectDef] of Object.entries(manifest.objects)) {
|
|
641
645
|
if (isCollectionManifestClass(manifest, objectDef)) {
|
|
642
|
-
|
|
646
|
+
const collectionRoutePaths = await generateCollectionRoutesForObject(projectRoot, className, objectDef, manifest, options);
|
|
647
|
+
generatedRoutePaths.push(...collectionRoutePaths);
|
|
648
|
+
if (collectionRoutePaths.length > 0) generatedCount++;
|
|
643
649
|
else {
|
|
644
650
|
console.log(`[smrt] Skipping ${className} - no collection API routes to generate`);
|
|
645
651
|
skippedCollections++;
|
|
646
652
|
}
|
|
647
653
|
continue;
|
|
648
654
|
}
|
|
649
|
-
await generateRoutesForObject(projectRoot, className, objectDef, manifest, options);
|
|
655
|
+
generatedRoutePaths.push(...await generateRoutesForObject(projectRoot, className, objectDef, manifest, options));
|
|
650
656
|
generatedCount++;
|
|
651
657
|
}
|
|
652
|
-
if (options.knowledge?.api?.enabled) generateKnowledgeRoute(projectRoot, options);
|
|
653
|
-
generateSyncApplyRoute(projectRoot, manifest, options);
|
|
654
|
-
generateChangesRoute(projectRoot, manifest, options);
|
|
655
|
-
generateEventsRoute(projectRoot, manifest, options, computeWebManifestHash(manifest));
|
|
656
|
-
updateGitignore(projectRoot, options);
|
|
658
|
+
if (options.knowledge?.api?.enabled) generatedRoutePaths.push(generateKnowledgeRoute(projectRoot, options));
|
|
659
|
+
if (generateSyncApplyRoute(projectRoot, manifest, options)) generatedRoutePaths.push(join(projectRoot, options.routesDir, "sync", "apply", "+server.ts"));
|
|
660
|
+
if (generateChangesRoute(projectRoot, manifest, options)) generatedRoutePaths.push(join(projectRoot, options.routesDir, "_changes", "+server.ts"));
|
|
661
|
+
if (generateEventsRoute(projectRoot, manifest, options, computeWebManifestHash(manifest))) generatedRoutePaths.push(join(projectRoot, options.routesDir, "_events", "+server.ts"));
|
|
662
|
+
updateGitignore(projectRoot, options, generatedRoutePaths);
|
|
657
663
|
const skippedMsg = skippedCollections > 0 ? ` (skipped ${skippedCollections} collection classes)` : "";
|
|
658
664
|
console.log(`[smrt] Generated routes for ${generatedCount} SMRT objects${skippedMsg}`);
|
|
659
665
|
}
|
|
@@ -686,7 +692,7 @@ function clearGeneratedKnowledgeRoute(projectRoot, options) {
|
|
|
686
692
|
if (readFileSync(routePath, "utf-8").startsWith("// Auto-generated by @smrt/core vite plugin")) unlinkSync(routePath);
|
|
687
693
|
}
|
|
688
694
|
function generateKnowledgeRoute(projectRoot, options) {
|
|
689
|
-
writeRoute(knowledgeRouteDir(projectRoot, options), "+server.ts", generateKnowledgeRouteTemplate(options.knowledge ?? {}, readKnowledgeRouteArtifact(projectRoot)));
|
|
695
|
+
return writeRoute(knowledgeRouteDir(projectRoot, options), "+server.ts", generateKnowledgeRouteTemplate(options.knowledge ?? {}, readKnowledgeRouteArtifact(projectRoot)));
|
|
690
696
|
}
|
|
691
697
|
function readKnowledgeRouteArtifact(projectRoot) {
|
|
692
698
|
for (const relativePath of [".smrt/smrt-knowledge.json", "dist/smrt-knowledge.json"]) {
|
|
@@ -938,16 +944,20 @@ export async function getCollection<
|
|
|
938
944
|
async function generateRoutesForObject(projectRoot, className, objectDef, manifest, options) {
|
|
939
945
|
const collectionName = objectDef.collection;
|
|
940
946
|
const routeDir = join(projectRoot, options.routesDir, collectionName);
|
|
947
|
+
const generatedRoutePaths = [];
|
|
941
948
|
const apiConfig = objectDef.decoratorConfig?.api;
|
|
942
949
|
if (apiConfig === false) {
|
|
943
950
|
console.log(`[smrt] Skipping ${className} - API disabled`);
|
|
944
|
-
return;
|
|
951
|
+
return generatedRoutePaths;
|
|
945
952
|
}
|
|
946
953
|
const includedActions = resolveStandardCrudActions(apiConfig);
|
|
947
|
-
if (includedActions.includes("list") || includedActions.includes("create"))
|
|
954
|
+
if (includedActions.includes("list") || includedActions.includes("create")) {
|
|
955
|
+
const collectionRoute = generateCollectionRouteTemplate(projectRoot, className, objectDef, manifest, includedActions, options, routeDir);
|
|
956
|
+
generatedRoutePaths.push(writeRoute(routeDir, "+server.ts", collectionRoute));
|
|
957
|
+
}
|
|
948
958
|
if (includedActions.includes("get") || includedActions.includes("update") || includedActions.includes("delete")) {
|
|
949
959
|
const itemRoute = generateItemRouteTemplate(projectRoot, className, objectDef, manifest, includedActions, options, join(routeDir, "[id]"));
|
|
950
|
-
writeRoute(join(routeDir, "[id]"), "+server.ts", itemRoute);
|
|
960
|
+
generatedRoutePaths.push(writeRoute(join(routeDir, "[id]"), "+server.ts", itemRoute));
|
|
951
961
|
}
|
|
952
962
|
const customActions = Object.entries(objectDef.methods).filter(([name, method]) => !STANDARD_API_ACTIONS.includes(name) && method.isPublic && shouldIncludeInApi(name, apiConfig));
|
|
953
963
|
const actionSpecs = [];
|
|
@@ -971,20 +981,24 @@ async function generateRoutesForObject(projectRoot, className, objectDef, manife
|
|
|
971
981
|
}
|
|
972
982
|
});
|
|
973
983
|
}
|
|
974
|
-
for (const [actionRouteDir, routeSpecs] of groupCustomActionRoutes(actionSpecs))
|
|
984
|
+
for (const [actionRouteDir, routeSpecs] of groupCustomActionRoutes(actionSpecs)) {
|
|
985
|
+
const actionRoute = generateActionRouteTemplate(projectRoot, actionRouteDir, routeSpecs, objectDef, manifest, options);
|
|
986
|
+
generatedRoutePaths.push(writeRoute(actionRouteDir, "+server.ts", actionRoute));
|
|
987
|
+
}
|
|
988
|
+
return generatedRoutePaths;
|
|
975
989
|
}
|
|
976
990
|
async function generateCollectionRoutesForObject(projectRoot, className, objectDef, manifest, options) {
|
|
991
|
+
const generatedRoutePaths = [];
|
|
977
992
|
const apiConfig = objectDef.decoratorConfig?.api;
|
|
978
993
|
if (apiConfig === false) {
|
|
979
994
|
console.log(`[smrt] Skipping ${className} - API disabled`);
|
|
980
|
-
return
|
|
995
|
+
return generatedRoutePaths;
|
|
981
996
|
}
|
|
982
997
|
const routeDir = join(projectRoot, options.routesDir, objectDef.collection);
|
|
983
998
|
const lookupClassName = findItemClassRegistryKey(className, objectDef, manifest);
|
|
984
999
|
const lookupObjectDef = findObjectDefByRegistryKey(manifest, lookupClassName);
|
|
985
1000
|
const customActions = Object.entries(objectDef.methods).filter(([name, method]) => !STANDARD_API_ACTIONS.includes(name) && method.isPublic && shouldIncludeInApi(name, apiConfig));
|
|
986
|
-
if (customActions.length === 0) return
|
|
987
|
-
let generatedAnyRoutes = false;
|
|
1001
|
+
if (customActions.length === 0) return generatedRoutePaths;
|
|
988
1002
|
const actionSpecs = [];
|
|
989
1003
|
for (const [actionName, actionDef] of customActions) {
|
|
990
1004
|
const routeConfig = resolveApiActionRouteConfig(actionName, actionDef, apiConfig, { kebabRoutes: options.kebabRoutes }, "collection");
|
|
@@ -1006,10 +1020,10 @@ async function generateCollectionRoutesForObject(projectRoot, className, objectD
|
|
|
1006
1020
|
});
|
|
1007
1021
|
}
|
|
1008
1022
|
for (const [actionRouteDir, routeSpecs] of groupCustomActionRoutes(actionSpecs)) {
|
|
1009
|
-
|
|
1010
|
-
|
|
1023
|
+
const actionRoute = generateActionRouteTemplate(projectRoot, actionRouteDir, routeSpecs, objectDef, manifest, options);
|
|
1024
|
+
generatedRoutePaths.push(writeRoute(actionRouteDir, "+server.ts", actionRoute));
|
|
1011
1025
|
}
|
|
1012
|
-
return
|
|
1026
|
+
return generatedRoutePaths;
|
|
1013
1027
|
}
|
|
1014
1028
|
/**
|
|
1015
1029
|
* Resolve the list of standard CRUD actions exposed by the API for a given
|
|
@@ -1120,6 +1134,7 @@ function writeRoute(dir, filename, content) {
|
|
|
1120
1134
|
const filePath = join(dir, filename);
|
|
1121
1135
|
writeFileSync(filePath, content, "utf-8");
|
|
1122
1136
|
console.log(`[smrt] Generated: ${filePath}`);
|
|
1137
|
+
return filePath;
|
|
1123
1138
|
} catch (error) {
|
|
1124
1139
|
console.error(`[smrt] [ERROR] Failed to write route file:`);
|
|
1125
1140
|
console.error(`[smrt] [ERROR] Directory: ${dir}`);
|
|
@@ -1582,28 +1597,42 @@ function rolesFrom(value: unknown): string[] {
|
|
|
1582
1597
|
/**
|
|
1583
1598
|
* Updates .gitignore to exclude auto-generated routes
|
|
1584
1599
|
*/
|
|
1585
|
-
function updateGitignore(projectRoot, options) {
|
|
1600
|
+
function updateGitignore(projectRoot, options, generatedRoutePaths) {
|
|
1586
1601
|
const gitignorePath = join(projectRoot, ".gitignore");
|
|
1587
|
-
const patternsToAdd = ["# SMRT auto-generated routes (from Vite plugin)", `${options.routesDir}/**/+server.ts`];
|
|
1588
|
-
if (options.knowledge?.api?.enabled) {
|
|
1589
|
-
const knowledgeRoute = relative(projectRoot, join(knowledgeRouteDir(projectRoot, options), "+server.ts")).replaceAll("\\", "/");
|
|
1590
|
-
patternsToAdd.push(knowledgeRoute);
|
|
1591
|
-
}
|
|
1592
1602
|
let gitignoreContent = "";
|
|
1593
1603
|
if (existsSync(gitignorePath)) gitignoreContent = readFileSync(gitignorePath, "utf-8");
|
|
1594
|
-
|
|
1595
|
-
const
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1604
|
+
const generatedPaths = [...new Set(generatedRoutePaths.map((path) => gitignorePatternForPath(relative(projectRoot, path))))].sort((a, b) => a.localeCompare(b));
|
|
1605
|
+
const updatedContent = updateGeneratedRouteIgnoreBlock(gitignoreContent, options.routesDir, generatedPaths);
|
|
1606
|
+
if (updatedContent !== gitignoreContent) {
|
|
1607
|
+
writeFileSync(gitignorePath, updatedContent, "utf-8");
|
|
1608
|
+
console.log("[smrt] Updated .gitignore with generated route paths");
|
|
1599
1609
|
}
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1610
|
+
}
|
|
1611
|
+
function gitignorePatternForPath(path) {
|
|
1612
|
+
return path.replaceAll("\\", "/").replaceAll(/([*?[\]\\!#])/g, "\\$1");
|
|
1613
|
+
}
|
|
1614
|
+
function updateGeneratedRouteIgnoreBlock(gitignoreContent, routesDir, generatedPaths) {
|
|
1615
|
+
const lines = gitignoreContent.split("\n");
|
|
1616
|
+
const startIndex = lines.indexOf(GITIGNORE_MANAGED_BLOCK_START);
|
|
1617
|
+
const endIndex = lines.indexOf(GITIGNORE_MANAGED_BLOCK_END);
|
|
1618
|
+
const managedBlock = [
|
|
1619
|
+
GITIGNORE_MANAGED_BLOCK_START,
|
|
1620
|
+
...generatedPaths,
|
|
1621
|
+
GITIGNORE_MANAGED_BLOCK_END
|
|
1622
|
+
];
|
|
1623
|
+
if (startIndex !== -1 || endIndex !== -1) {
|
|
1624
|
+
if (startIndex === -1 || endIndex < startIndex) return gitignoreContent;
|
|
1625
|
+
lines.splice(startIndex, endIndex - startIndex + 1, ...generatedPaths.length > 0 ? managedBlock : []);
|
|
1626
|
+
return lines.join("\n");
|
|
1606
1627
|
}
|
|
1628
|
+
const legacyPattern = `${routesDir.replaceAll("\\", "/")}/**/+server.ts`;
|
|
1629
|
+
const legacyIndex = lines.findIndex((line, index) => line === LEGACY_GITIGNORE_HEADER && lines[index + 1] === legacyPattern);
|
|
1630
|
+
if (legacyIndex !== -1) lines.splice(legacyIndex, 2);
|
|
1631
|
+
if (generatedPaths.length === 0) return lines.join("\n");
|
|
1632
|
+
let updatedContent = lines.join("\n");
|
|
1633
|
+
if (updatedContent.length > 0 && !updatedContent.endsWith("\n")) updatedContent += "\n";
|
|
1634
|
+
if (updatedContent.length > 0 && !updatedContent.endsWith("\n\n")) updatedContent += "\n";
|
|
1635
|
+
return `${updatedContent}${managedBlock.join("\n")}\n`;
|
|
1607
1636
|
}
|
|
1608
1637
|
//#endregion
|
|
1609
1638
|
export { findCliApiCoherenceViolations, generateSvelteKitRoutes, methodNameToKebab, resolveApiActionRouteConfig, resolveApiActionSet, validateCliIncludeAgainstApi };
|