@atlashub/smartstack-mcp 1.1.0 → 1.2.1
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/README.md +96 -140
- package/dist/index.js +117 -79
- package/dist/index.js.map +1 -1
- package/package.json +65 -65
package/dist/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
#!/usr/bin/env node
|
|
3
2
|
|
|
4
3
|
// src/server.ts
|
|
5
4
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -132,11 +131,24 @@ var defaultConfig = {
|
|
|
132
131
|
apiEnabled: process.env.SMARTSTACK_API_ENABLED !== "false"
|
|
133
132
|
},
|
|
134
133
|
conventions: {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
134
|
+
schemas: {
|
|
135
|
+
platform: "core",
|
|
136
|
+
extensions: "extensions"
|
|
138
137
|
},
|
|
139
|
-
|
|
138
|
+
tablePrefixes: [
|
|
139
|
+
"auth_",
|
|
140
|
+
"nav_",
|
|
141
|
+
"usr_",
|
|
142
|
+
"ai_",
|
|
143
|
+
"cfg_",
|
|
144
|
+
"wkf_",
|
|
145
|
+
"support_",
|
|
146
|
+
"entra_",
|
|
147
|
+
"ref_",
|
|
148
|
+
"loc_",
|
|
149
|
+
"lic_"
|
|
150
|
+
],
|
|
151
|
+
migrationFormat: "{context}_v{version}_{sequence}_{Description}",
|
|
140
152
|
namespaces: {
|
|
141
153
|
domain: "SmartStack.Domain",
|
|
142
154
|
application: "SmartStack.Application",
|
|
@@ -210,9 +222,9 @@ function mergeConfig(base, override) {
|
|
|
210
222
|
conventions: {
|
|
211
223
|
...base.conventions,
|
|
212
224
|
...override.conventions,
|
|
213
|
-
|
|
214
|
-
...base.conventions.
|
|
215
|
-
...override.conventions?.
|
|
225
|
+
schemas: {
|
|
226
|
+
...base.conventions.schemas,
|
|
227
|
+
...override.conventions?.schemas
|
|
216
228
|
},
|
|
217
229
|
namespaces: {
|
|
218
230
|
...base.conventions.namespaces,
|
|
@@ -520,7 +532,7 @@ async function findControllerFiles(apiPath) {
|
|
|
520
532
|
import path5 from "path";
|
|
521
533
|
var validateConventionsTool = {
|
|
522
534
|
name: "validate_conventions",
|
|
523
|
-
description: "Validate AtlasHub/SmartStack conventions: SQL schemas (core/extensions), domain table prefixes (auth_, nav_, ai_, etc.), migration naming (
|
|
535
|
+
description: "Validate AtlasHub/SmartStack conventions: SQL schemas (core/extensions), domain table prefixes (auth_, nav_, ai_, etc.), migration naming ({context}_v{version}_{sequence}_*), service interfaces (I*Service), namespace structure",
|
|
524
536
|
inputSchema: {
|
|
525
537
|
type: "object",
|
|
526
538
|
properties: {
|
|
@@ -662,7 +674,7 @@ async function validateMigrationNaming(structure, _config, result) {
|
|
|
662
674
|
return;
|
|
663
675
|
}
|
|
664
676
|
const migrationFiles = await findFiles("*.cs", { cwd: structure.migrations });
|
|
665
|
-
const migrationPattern = /^(\d
|
|
677
|
+
const migrationPattern = /^(\w+)_v(\d+\.\d+\.\d+)_(\d{3})_(.+)\.cs$/;
|
|
666
678
|
const designerPattern = /\.Designer\.cs$/;
|
|
667
679
|
for (const file of migrationFiles) {
|
|
668
680
|
const fileName = path5.basename(file);
|
|
@@ -675,7 +687,7 @@ async function validateMigrationNaming(structure, _config, result) {
|
|
|
675
687
|
category: "migrations",
|
|
676
688
|
message: `Migration "${fileName}" does not follow naming convention`,
|
|
677
689
|
file: path5.relative(structure.root, file),
|
|
678
|
-
suggestion: `Expected format:
|
|
690
|
+
suggestion: `Expected format: {context}_v{version}_{sequence}_{Description}.cs (e.g., core_v1.0.0_001_CreateAuthUsers.cs)`
|
|
679
691
|
});
|
|
680
692
|
}
|
|
681
693
|
}
|
|
@@ -683,18 +695,22 @@ async function validateMigrationNaming(structure, _config, result) {
|
|
|
683
695
|
for (let i = 1; i < orderedMigrations.length; i++) {
|
|
684
696
|
const prev = orderedMigrations[i - 1];
|
|
685
697
|
const curr = orderedMigrations[i];
|
|
686
|
-
const
|
|
687
|
-
const
|
|
688
|
-
if (
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
698
|
+
const prevMatch = migrationPattern.exec(prev);
|
|
699
|
+
const currMatch = migrationPattern.exec(curr);
|
|
700
|
+
if (prevMatch && currMatch) {
|
|
701
|
+
const prevVersion = prevMatch[2];
|
|
702
|
+
const currVersion = currMatch[2];
|
|
703
|
+
if (currVersion < prevVersion) {
|
|
704
|
+
result.warnings.push({
|
|
705
|
+
type: "warning",
|
|
706
|
+
category: "migrations",
|
|
707
|
+
message: `Migration order issue: "${curr}" (v${currVersion}) comes before "${prev}" (v${prevVersion})`
|
|
708
|
+
});
|
|
709
|
+
}
|
|
694
710
|
}
|
|
695
711
|
}
|
|
696
712
|
}
|
|
697
|
-
async function validateServiceInterfaces(structure,
|
|
713
|
+
async function validateServiceInterfaces(structure, _config, result) {
|
|
698
714
|
if (!structure.application) {
|
|
699
715
|
result.warnings.push({
|
|
700
716
|
type: "warning",
|
|
@@ -858,7 +874,7 @@ async function handleCheckMigrations(args, config) {
|
|
|
858
874
|
async function parseMigrations(migrationsPath, rootPath) {
|
|
859
875
|
const files = await findFiles("*.cs", { cwd: migrationsPath });
|
|
860
876
|
const migrations = [];
|
|
861
|
-
const pattern = /^(\d
|
|
877
|
+
const pattern = /^(\w+)_v(\d+\.\d+\.\d+)_(\d{3})_(.+)\.cs$/;
|
|
862
878
|
for (const file of files) {
|
|
863
879
|
const fileName = path6.basename(file);
|
|
864
880
|
if (fileName.includes(".Designer.") || fileName.includes("ModelSnapshot")) {
|
|
@@ -868,10 +884,13 @@ async function parseMigrations(migrationsPath, rootPath) {
|
|
|
868
884
|
if (match) {
|
|
869
885
|
migrations.push({
|
|
870
886
|
name: fileName.replace(".cs", ""),
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
887
|
+
context: match[1],
|
|
888
|
+
// DbContext (core, extensions, etc.)
|
|
889
|
+
version: match[2],
|
|
890
|
+
// Semver version (1.0.0, 1.2.0, etc.)
|
|
891
|
+
sequence: match[3],
|
|
892
|
+
// Sequence number (001, 002, etc.)
|
|
893
|
+
description: match[4],
|
|
875
894
|
file: path6.relative(rootPath, file),
|
|
876
895
|
applied: true
|
|
877
896
|
// We'd need DB connection to check this
|
|
@@ -879,8 +898,9 @@ async function parseMigrations(migrationsPath, rootPath) {
|
|
|
879
898
|
} else {
|
|
880
899
|
migrations.push({
|
|
881
900
|
name: fileName.replace(".cs", ""),
|
|
882
|
-
|
|
883
|
-
|
|
901
|
+
context: "Unknown",
|
|
902
|
+
version: "0.0.0",
|
|
903
|
+
sequence: "000",
|
|
884
904
|
description: fileName.replace(".cs", ""),
|
|
885
905
|
file: path6.relative(rootPath, file),
|
|
886
906
|
applied: true
|
|
@@ -888,51 +908,63 @@ async function parseMigrations(migrationsPath, rootPath) {
|
|
|
888
908
|
}
|
|
889
909
|
}
|
|
890
910
|
return migrations.sort((a, b) => {
|
|
891
|
-
const
|
|
892
|
-
if (
|
|
893
|
-
return a.
|
|
911
|
+
const versionCompare = compareVersions(a.version, b.version);
|
|
912
|
+
if (versionCompare !== 0) return versionCompare;
|
|
913
|
+
return a.sequence.localeCompare(b.sequence);
|
|
894
914
|
});
|
|
895
915
|
}
|
|
916
|
+
function compareVersions(a, b) {
|
|
917
|
+
const partsA = a.split(".").map(Number);
|
|
918
|
+
const partsB = b.split(".").map(Number);
|
|
919
|
+
for (let i = 0; i < 3; i++) {
|
|
920
|
+
if (partsA[i] > partsB[i]) return 1;
|
|
921
|
+
if (partsA[i] < partsB[i]) return -1;
|
|
922
|
+
}
|
|
923
|
+
return 0;
|
|
924
|
+
}
|
|
896
925
|
function checkNamingConventions(result, _config) {
|
|
897
926
|
for (const migration of result.migrations) {
|
|
898
|
-
if (
|
|
927
|
+
if (migration.context === "Unknown") {
|
|
899
928
|
result.conflicts.push({
|
|
900
929
|
type: "naming",
|
|
901
930
|
description: `Migration "${migration.name}" does not follow naming convention`,
|
|
902
931
|
files: [migration.file],
|
|
903
|
-
resolution: `Rename to format:
|
|
932
|
+
resolution: `Rename to format: {context}_v{version}_{sequence}_{Description} (e.g., core_v1.0.0_001_CreateAuthUsers)`
|
|
904
933
|
});
|
|
905
934
|
}
|
|
906
|
-
if (migration.
|
|
935
|
+
if (migration.version === "0.0.0") {
|
|
907
936
|
result.conflicts.push({
|
|
908
937
|
type: "naming",
|
|
909
|
-
description: `Migration "${migration.name}" missing
|
|
938
|
+
description: `Migration "${migration.name}" missing version number`,
|
|
910
939
|
files: [migration.file],
|
|
911
|
-
resolution: `Use format:
|
|
940
|
+
resolution: `Use format: {context}_v{version}_{sequence}_{Description} where version is semver (1.0.0, 1.2.0, etc.)`
|
|
912
941
|
});
|
|
913
942
|
}
|
|
914
943
|
}
|
|
915
944
|
}
|
|
916
945
|
function checkChronologicalOrder(result) {
|
|
917
|
-
const migrations = result.migrations.filter((m) => m.
|
|
946
|
+
const migrations = result.migrations.filter((m) => m.context !== "Unknown");
|
|
918
947
|
for (let i = 1; i < migrations.length; i++) {
|
|
919
948
|
const prev = migrations[i - 1];
|
|
920
949
|
const curr = migrations[i];
|
|
921
|
-
if (curr.
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
950
|
+
if (curr.context === prev.context) {
|
|
951
|
+
const versionCompare = compareVersions(curr.version, prev.version);
|
|
952
|
+
if (versionCompare < 0) {
|
|
953
|
+
result.conflicts.push({
|
|
954
|
+
type: "order",
|
|
955
|
+
description: `Migration "${curr.name}" (v${curr.version}) is versioned before "${prev.name}" (v${prev.version})`,
|
|
956
|
+
files: [curr.file, prev.file],
|
|
957
|
+
resolution: "Reorder migrations or update version numbers"
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
if (curr.version === prev.version && curr.sequence === prev.sequence) {
|
|
961
|
+
result.conflicts.push({
|
|
962
|
+
type: "order",
|
|
963
|
+
description: `Migrations "${curr.name}" and "${prev.name}" have same version and sequence`,
|
|
964
|
+
files: [curr.file, prev.file],
|
|
965
|
+
resolution: "Use different sequence numbers (001, 002, etc.) for migrations in the same version"
|
|
966
|
+
});
|
|
967
|
+
}
|
|
936
968
|
}
|
|
937
969
|
}
|
|
938
970
|
}
|
|
@@ -987,7 +1019,7 @@ async function checkModelSnapshot(result, structure) {
|
|
|
987
1019
|
}
|
|
988
1020
|
const snapshotContent = await readText(snapshotFiles[0]);
|
|
989
1021
|
for (const migration of result.migrations) {
|
|
990
|
-
if (migration.
|
|
1022
|
+
if (migration.context !== "Unknown" && !snapshotContent.includes(migration.name)) {
|
|
991
1023
|
result.conflicts.push({
|
|
992
1024
|
type: "dependency",
|
|
993
1025
|
description: `Migration "${migration.name}" not referenced in ModelSnapshot`,
|
|
@@ -1005,12 +1037,12 @@ function generateSuggestions(result) {
|
|
|
1005
1037
|
}
|
|
1006
1038
|
if (result.conflicts.some((c) => c.type === "naming")) {
|
|
1007
1039
|
result.suggestions.push(
|
|
1008
|
-
"Use convention:
|
|
1040
|
+
"Use convention: {context}_v{version}_{sequence}_{Description} for migration naming (e.g., core_v1.0.0_001_CreateAuthUsers)"
|
|
1009
1041
|
);
|
|
1010
1042
|
}
|
|
1011
1043
|
if (result.conflicts.some((c) => c.type === "order")) {
|
|
1012
1044
|
result.suggestions.push(
|
|
1013
|
-
"Ensure migrations are created in
|
|
1045
|
+
"Ensure migrations are created in version order to avoid conflicts"
|
|
1014
1046
|
);
|
|
1015
1047
|
}
|
|
1016
1048
|
if (result.migrations.length > 20) {
|
|
@@ -1034,11 +1066,11 @@ function formatResult2(result, currentBranch, compareBranch) {
|
|
|
1034
1066
|
lines.push("");
|
|
1035
1067
|
lines.push("## Migrations");
|
|
1036
1068
|
lines.push("");
|
|
1037
|
-
lines.push("| Name |
|
|
1038
|
-
lines.push("
|
|
1069
|
+
lines.push("| Name | Context | Version | Sequence | Description |");
|
|
1070
|
+
lines.push("|------|---------|---------|----------|-------------|");
|
|
1039
1071
|
for (const migration of result.migrations) {
|
|
1040
1072
|
lines.push(
|
|
1041
|
-
`| ${migration.name} | ${migration.
|
|
1073
|
+
`| ${migration.name} | ${migration.context} | ${migration.version} | ${migration.sequence} | ${migration.description} |`
|
|
1042
1074
|
);
|
|
1043
1075
|
}
|
|
1044
1076
|
lines.push("");
|
|
@@ -1269,7 +1301,7 @@ public class {{name}}Configuration : IEntityTypeConfiguration<{{domainNamespace}
|
|
|
1269
1301
|
baseEntity,
|
|
1270
1302
|
infrastructureNamespace: config.conventions.namespaces.infrastructure,
|
|
1271
1303
|
domainNamespace: config.conventions.namespaces.domain,
|
|
1272
|
-
|
|
1304
|
+
schema: config.conventions.schemas.platform
|
|
1273
1305
|
};
|
|
1274
1306
|
const entityContent = Handlebars.compile(entityTemplate)(context);
|
|
1275
1307
|
const configContent = Handlebars.compile(configTemplate)(context);
|
|
@@ -1965,28 +1997,37 @@ Migrations MUST follow this naming pattern:
|
|
|
1965
1997
|
${migrationFormat}
|
|
1966
1998
|
\`\`\`
|
|
1967
1999
|
|
|
2000
|
+
| Part | Description | Example |
|
|
2001
|
+
|------|-------------|---------|
|
|
2002
|
+
| \`{context}\` | DbContext name | \`core\`, \`extensions\` |
|
|
2003
|
+
| \`{version}\` | Semver version | \`v1.0.0\`, \`v1.2.0\` |
|
|
2004
|
+
| \`{sequence}\` | Order in version | \`001\`, \`002\` |
|
|
2005
|
+
| \`{Description}\` | Action (PascalCase) | \`CreateAuthUsers\` |
|
|
2006
|
+
|
|
1968
2007
|
**Examples:**
|
|
1969
|
-
- \`
|
|
1970
|
-
- \`
|
|
1971
|
-
- \`
|
|
2008
|
+
- \`core_v1.0.0_001_InitialSchema.cs\`
|
|
2009
|
+
- \`core_v1.0.0_002_CreateAuthUsers.cs\`
|
|
2010
|
+
- \`core_v1.2.0_001_AddUserProfiles.cs\`
|
|
2011
|
+
- \`extensions_v1.0.0_001_AddClientFeatures.cs\`
|
|
1972
2012
|
|
|
1973
2013
|
### Creating Migrations
|
|
1974
2014
|
|
|
1975
2015
|
\`\`\`bash
|
|
1976
2016
|
# Create a new migration
|
|
1977
|
-
dotnet ef migrations add
|
|
2017
|
+
dotnet ef migrations add core_v1.0.0_001_InitialSchema
|
|
1978
2018
|
|
|
1979
2019
|
# With context specified
|
|
1980
|
-
dotnet ef migrations add
|
|
2020
|
+
dotnet ef migrations add core_v1.2.0_001_AddUserProfiles --context ApplicationDbContext
|
|
1981
2021
|
\`\`\`
|
|
1982
2022
|
|
|
1983
2023
|
### Migration Rules
|
|
1984
2024
|
|
|
1985
2025
|
1. **One migration per feature** - Group related changes in a single migration
|
|
1986
|
-
2. **
|
|
1987
|
-
3. **Sequence numbers** - Use NNN (001, 002, etc.) for migrations
|
|
1988
|
-
4. **
|
|
1989
|
-
5. **
|
|
2026
|
+
2. **Version-based naming** - Use semver (v1.0.0, v1.2.0) to link migrations to releases
|
|
2027
|
+
3. **Sequence numbers** - Use NNN (001, 002, etc.) for migrations in the same version
|
|
2028
|
+
4. **Context prefix** - Use \`core_\` for platform tables, \`extensions_\` for client extensions
|
|
2029
|
+
5. **Descriptive names** - Use clear PascalCase descriptions (CreateAuthUsers, AddUserProfiles, etc.)
|
|
2030
|
+
6. **Schema must be specified** - All tables must specify their schema in ToTable()
|
|
1990
2031
|
|
|
1991
2032
|
---
|
|
1992
2033
|
|
|
@@ -2153,7 +2194,7 @@ public interface IUserServiceHooks
|
|
|
2153
2194
|
| Platform schema | \`${schemas.platform}\` | \`.ToTable("auth_Users", "${schemas.platform}")\` |
|
|
2154
2195
|
| Extensions schema | \`${schemas.extensions}\` | \`.ToTable("client_Custom", "${schemas.extensions}")\` |
|
|
2155
2196
|
| Table prefixes | \`${tablePrefixes.slice(0, 5).join(", ")}\`, etc. | \`auth_Users\`, \`nav_Modules\` |
|
|
2156
|
-
| Migration | \`
|
|
2197
|
+
| Migration | \`{context}_v{version}_{seq}_{Desc}\` | \`core_v1.0.0_001_CreateAuthUsers\` |
|
|
2157
2198
|
| Interface | \`I<Name>Service\` | \`IUserService\` |
|
|
2158
2199
|
| Implementation | \`<Name>Service\` | \`UserService\` |
|
|
2159
2200
|
| Domain namespace | \`${namespaces.domain}\` | - |
|
|
@@ -2256,7 +2297,8 @@ async function getProjectInfoResource(config) {
|
|
|
2256
2297
|
lines.push(JSON.stringify({
|
|
2257
2298
|
smartstack: config.smartstack,
|
|
2258
2299
|
conventions: {
|
|
2259
|
-
|
|
2300
|
+
schemas: config.conventions.schemas,
|
|
2301
|
+
tablePrefixes: config.conventions.tablePrefixes,
|
|
2260
2302
|
migrationFormat: config.conventions.migrationFormat
|
|
2261
2303
|
}
|
|
2262
2304
|
}, null, 2));
|
|
@@ -2319,7 +2361,7 @@ async function getApiEndpointsResource(config, endpointFilter) {
|
|
|
2319
2361
|
) : allEndpoints;
|
|
2320
2362
|
return formatEndpoints(endpoints, endpointFilter);
|
|
2321
2363
|
}
|
|
2322
|
-
async function parseController(filePath,
|
|
2364
|
+
async function parseController(filePath, _rootPath) {
|
|
2323
2365
|
const content = await readText(filePath);
|
|
2324
2366
|
const fileName = path10.basename(filePath, ".cs");
|
|
2325
2367
|
const controllerName = fileName.replace("Controller", "");
|
|
@@ -2327,10 +2369,8 @@ async function parseController(filePath, rootPath) {
|
|
|
2327
2369
|
const routeMatch = content.match(/\[Route\s*\(\s*"([^"]+)"\s*\)\]/);
|
|
2328
2370
|
const baseRoute = routeMatch ? routeMatch[1].replace("[controller]", controllerName.toLowerCase()) : `/api/${controllerName.toLowerCase()}`;
|
|
2329
2371
|
const classAuthorize = /\[Authorize\s*(?:\([^)]*\))?\s*\]\s*(?:\[.*\]\s*)*public\s+class/.test(content);
|
|
2330
|
-
const methodPattern = /\/\/\/\s*<summary>\s*\n\s*\/\/\/\s*([^\n]+)\s*\n\s*\/\/\/\s*<\/summary>[\s\S]*?(?=\[Http)|(\[Http(Get|Post|Put|Patch|Delete)(?:\s*\(\s*"([^"]*)"\s*\))?\][\s\S]*?public\s+(?:async\s+)?(?:Task<)?(?:ActionResult<)?(\w+)(?:[<>[\],\s\w]*)?\s+(\w+)\s*\(([^)]*)\))/g;
|
|
2331
|
-
let lastSummary = "";
|
|
2332
|
-
let match;
|
|
2333
2372
|
const httpMethods = ["HttpGet", "HttpPost", "HttpPut", "HttpPatch", "HttpDelete"];
|
|
2373
|
+
let match;
|
|
2334
2374
|
for (const httpMethod of httpMethods) {
|
|
2335
2375
|
const regex = new RegExp(
|
|
2336
2376
|
`\\[${httpMethod}(?:\\s*\\(\\s*"([^"]*)"\\s*\\))?\\]\\s*(?:\\[.*?\\]\\s*)*public\\s+(?:async\\s+)?(?:Task<)?(?:ActionResult<)?(\\w+)(?:[<>\\[\\],\\s\\w]*)?\\s+(\\w+)\\s*\\(([^)]*)\\)`,
|
|
@@ -2500,13 +2540,11 @@ async function getDbSchemaResource(config, tableFilter) {
|
|
|
2500
2540
|
) : entities;
|
|
2501
2541
|
return formatSchema(filteredEntities, tableFilter, config);
|
|
2502
2542
|
}
|
|
2503
|
-
async function parseEntity(filePath, rootPath,
|
|
2543
|
+
async function parseEntity(filePath, rootPath, _config) {
|
|
2504
2544
|
const content = await readText(filePath);
|
|
2505
|
-
const fileName = path11.basename(filePath, ".cs");
|
|
2506
2545
|
const classMatch = content.match(/public\s+(?:class|record)\s+(\w+)(?:\s*:\s*(\w+))?/);
|
|
2507
2546
|
if (!classMatch) return null;
|
|
2508
2547
|
const entityName = classMatch[1];
|
|
2509
|
-
const baseClass = classMatch[2];
|
|
2510
2548
|
if (entityName.endsWith("Dto") || entityName.endsWith("Command") || entityName.endsWith("Query") || entityName.endsWith("Handler")) {
|
|
2511
2549
|
return null;
|
|
2512
2550
|
}
|
|
@@ -2556,7 +2594,7 @@ async function parseEntity(filePath, rootPath, config) {
|
|
|
2556
2594
|
isPrimaryKey: propertyName === "Id" || propertyName === `${entityName}Id`
|
|
2557
2595
|
});
|
|
2558
2596
|
}
|
|
2559
|
-
const tableName =
|
|
2597
|
+
const tableName = `cfg_${entityName}s`;
|
|
2560
2598
|
return {
|
|
2561
2599
|
name: entityName,
|
|
2562
2600
|
tableName,
|
|
@@ -2565,7 +2603,7 @@ async function parseEntity(filePath, rootPath, config) {
|
|
|
2565
2603
|
file: path11.relative(rootPath, filePath)
|
|
2566
2604
|
};
|
|
2567
2605
|
}
|
|
2568
|
-
async function enrichFromConfigurations(entities, infrastructurePath,
|
|
2606
|
+
async function enrichFromConfigurations(entities, infrastructurePath, _config) {
|
|
2569
2607
|
const configFiles = await findFiles("**/Configurations/**/*.cs", {
|
|
2570
2608
|
cwd: infrastructurePath
|
|
2571
2609
|
});
|
|
@@ -2619,7 +2657,7 @@ function mapCSharpType(csharpType) {
|
|
|
2619
2657
|
const baseType = csharpType.replace("?", "");
|
|
2620
2658
|
return typeMap[baseType] || "nvarchar";
|
|
2621
2659
|
}
|
|
2622
|
-
function formatSchema(entities, filter,
|
|
2660
|
+
function formatSchema(entities, filter, _config) {
|
|
2623
2661
|
const lines = [];
|
|
2624
2662
|
lines.push("# SmartStack Database Schema");
|
|
2625
2663
|
lines.push("");
|