@specverse/engines 4.1.25 → 4.1.27
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/dist/libs/instance-factories/applications/templates/generic/backend-package-json-generator.js +3 -3
- package/dist/libs/instance-factories/applications/templates/generic/main-generator.js +3 -0
- package/dist/libs/instance-factories/applications/templates/react/package-json-generator.js +4 -4
- package/dist/libs/instance-factories/applications/templates/react/runtime-package-json-generator.js +4 -4
- package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +35 -5
- package/libs/instance-factories/applications/templates/generic/backend-package-json-generator.ts +3 -3
- package/libs/instance-factories/applications/templates/generic/main-generator.ts +3 -0
- package/libs/instance-factories/applications/templates/react/package-json-generator.ts +4 -4
- package/libs/instance-factories/applications/templates/react/runtime-package-json-generator.ts +4 -4
- package/libs/instance-factories/cli/templates/commander/command-generator.ts +35 -5
- package/package.json +3 -3
|
@@ -54,9 +54,9 @@ function generateBackendPackageJson(context) {
|
|
|
54
54
|
"prisma": "^5.7.0",
|
|
55
55
|
"vitest": "^3.0.0",
|
|
56
56
|
"@vitest/coverage-v8": "^3.0.0",
|
|
57
|
-
"eslint": "^
|
|
58
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
59
|
-
"@typescript-eslint/parser": "^
|
|
57
|
+
"eslint": "^9.0.0",
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
59
|
+
"@typescript-eslint/parser": "^8.0.0"
|
|
60
60
|
},
|
|
61
61
|
engines: {
|
|
62
62
|
node: ">=20.0.0"
|
|
@@ -99,6 +99,9 @@ ${serviceMap}
|
|
|
99
99
|
credentials: true
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
+
// Health check \u2014 used by smoke tests, container probes, monitors
|
|
103
|
+
app.get('/health', async () => ({ status: 'ok', timestamp: new Date().toISOString() }));
|
|
104
|
+
|
|
102
105
|
// Spec endpoint \u2014 serves the specification for the runtime frontend
|
|
103
106
|
app.get('/api/spec', async () => spec);
|
|
104
107
|
|
|
@@ -35,10 +35,10 @@ function generatePackageJson(context) {
|
|
|
35
35
|
"tailwindcss": "^3.4.13",
|
|
36
36
|
"typescript": "^5.2.0",
|
|
37
37
|
"vite": "^6.0.0",
|
|
38
|
-
"eslint": "^
|
|
39
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
40
|
-
"@typescript-eslint/parser": "^
|
|
41
|
-
"eslint-plugin-react-hooks": "^
|
|
38
|
+
"eslint": "^9.0.0",
|
|
39
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
40
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
41
|
+
"eslint-plugin-react-hooks": "^5.0.0",
|
|
42
42
|
"eslint-plugin-react-refresh": "^0.4.4"
|
|
43
43
|
}
|
|
44
44
|
};
|
package/dist/libs/instance-factories/applications/templates/react/runtime-package-json-generator.js
CHANGED
|
@@ -37,10 +37,10 @@ function generateRuntimePackageJson(context) {
|
|
|
37
37
|
"tailwindcss": "^3.4.13",
|
|
38
38
|
"typescript": "^5.2.0",
|
|
39
39
|
"vite": "^6.0.0",
|
|
40
|
-
"eslint": "^
|
|
41
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
42
|
-
"@typescript-eslint/parser": "^
|
|
43
|
-
"eslint-plugin-react-hooks": "^
|
|
40
|
+
"eslint": "^9.0.0",
|
|
41
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
42
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
43
|
+
"eslint-plugin-react-hooks": "^5.0.0",
|
|
44
44
|
"eslint-plugin-react-refresh": "^0.4.4"
|
|
45
45
|
}
|
|
46
46
|
};
|
|
@@ -424,7 +424,10 @@ import { fileURLToPath } from 'url';`,
|
|
|
424
424
|
}
|
|
425
425
|
|
|
426
426
|
const projectName = name || 'my-project';
|
|
427
|
-
|
|
427
|
+
// Commander applies the --template default ("full-stack"); the
|
|
428
|
+
// fallback here only fires if a caller invoked the action handler
|
|
429
|
+
// directly without going through commander.
|
|
430
|
+
const templateName = options.template || 'full-stack';
|
|
428
431
|
const templateDir = join(templatesDir, templateName);
|
|
429
432
|
|
|
430
433
|
if (!existsSync(templateDir)) {
|
|
@@ -443,7 +446,16 @@ import { fileURLToPath } from 'url';`,
|
|
|
443
446
|
|
|
444
447
|
// Copy template with variable substitution
|
|
445
448
|
const kebab = projectName.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
|
446
|
-
|
|
449
|
+
// PascalCase: split on hyphens / underscores / whitespace, capitalize each segment, join.
|
|
450
|
+
// 'audit-backend-only' -> 'AuditBackendOnly', 'my_app' -> 'MyApp', 'foo' -> 'Foo'.
|
|
451
|
+
// NOTE: regex char class is double-escaped because this whole handler
|
|
452
|
+
// is embedded as a string in the generator template \u2014 \\s here ends
|
|
453
|
+
// up as s in the emitted source.
|
|
454
|
+
const component = projectName
|
|
455
|
+
.split(/[-_\\s]+/)
|
|
456
|
+
.filter(Boolean)
|
|
457
|
+
.map((s: string) => s.charAt(0).toUpperCase() + s.slice(1))
|
|
458
|
+
.join('');
|
|
447
459
|
const vars: Record<string, string> = {
|
|
448
460
|
'{{PROJECT_NAME}}': projectName,
|
|
449
461
|
'{{projectName}}': projectName,
|
|
@@ -478,11 +490,29 @@ import { fileURLToPath } from 'url';`,
|
|
|
478
490
|
console.log('Project created: ' + destDir);
|
|
479
491
|
console.log('Template: ' + templateName);
|
|
480
492
|
console.log('');
|
|
493
|
+
|
|
494
|
+
// Build the "Next steps" hint from the actual scripts the
|
|
495
|
+
// chosen template ships, so we never tell the user to run a
|
|
496
|
+
// command that doesn't exist in their package.json.
|
|
497
|
+
const destPkgPath = join(destDir, 'package.json');
|
|
498
|
+
const destPkg = existsSync(destPkgPath)
|
|
499
|
+
? JSON.parse(readFileSync(destPkgPath, 'utf8'))
|
|
500
|
+
: { scripts: {} };
|
|
501
|
+
const scripts = destPkg.scripts || {};
|
|
481
502
|
console.log('Next steps:');
|
|
482
503
|
console.log(' cd ' + projectName);
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
504
|
+
if (scripts.setup) {
|
|
505
|
+
console.log(' npm run setup # validate, generate code, install deps, setup db');
|
|
506
|
+
}
|
|
507
|
+
if (scripts['dev:backend'] && scripts['dev:frontend']) {
|
|
508
|
+
console.log(' npm run dev:backend # start backend (terminal 1)');
|
|
509
|
+
console.log(' npm run dev:frontend # start frontend (terminal 2)');
|
|
510
|
+
} else if (scripts.dev) {
|
|
511
|
+
console.log(' npm run dev # start dev server');
|
|
512
|
+
}
|
|
513
|
+
if (scripts['test:e2e']) {
|
|
514
|
+
console.log(' npm run test:e2e # run end-to-end tests (after starting dev servers)');
|
|
515
|
+
}`
|
|
486
516
|
},
|
|
487
517
|
// === gen subcommands ===
|
|
488
518
|
"gen.diagrams": {
|
package/libs/instance-factories/applications/templates/generic/backend-package-json-generator.ts
CHANGED
|
@@ -73,9 +73,9 @@ export default function generateBackendPackageJson(context: TemplateContext): st
|
|
|
73
73
|
'prisma': '^5.7.0',
|
|
74
74
|
'vitest': '^3.0.0',
|
|
75
75
|
'@vitest/coverage-v8': '^3.0.0',
|
|
76
|
-
'eslint': '^
|
|
77
|
-
'@typescript-eslint/eslint-plugin': '^
|
|
78
|
-
'@typescript-eslint/parser': '^
|
|
76
|
+
'eslint': '^9.0.0',
|
|
77
|
+
'@typescript-eslint/eslint-plugin': '^8.0.0',
|
|
78
|
+
'@typescript-eslint/parser': '^8.0.0'
|
|
79
79
|
},
|
|
80
80
|
|
|
81
81
|
engines: {
|
|
@@ -132,6 +132,9 @@ ${serviceMap}
|
|
|
132
132
|
credentials: true
|
|
133
133
|
});
|
|
134
134
|
|
|
135
|
+
// Health check — used by smoke tests, container probes, monitors
|
|
136
|
+
app.get('/health', async () => ({ status: 'ok', timestamp: new Date().toISOString() }));
|
|
137
|
+
|
|
135
138
|
// Spec endpoint — serves the specification for the runtime frontend
|
|
136
139
|
app.get('/api/spec', async () => spec);
|
|
137
140
|
|
|
@@ -45,10 +45,10 @@ export default function generatePackageJson(context: TemplateContext): string {
|
|
|
45
45
|
"tailwindcss": "^3.4.13",
|
|
46
46
|
"typescript": "^5.2.0",
|
|
47
47
|
"vite": "^6.0.0",
|
|
48
|
-
"eslint": "^
|
|
49
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
50
|
-
"@typescript-eslint/parser": "^
|
|
51
|
-
"eslint-plugin-react-hooks": "^
|
|
48
|
+
"eslint": "^9.0.0",
|
|
49
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
50
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
51
|
+
"eslint-plugin-react-hooks": "^5.0.0",
|
|
52
52
|
"eslint-plugin-react-refresh": "^0.4.4"
|
|
53
53
|
}
|
|
54
54
|
};
|
package/libs/instance-factories/applications/templates/react/runtime-package-json-generator.ts
CHANGED
|
@@ -54,10 +54,10 @@ export default function generateRuntimePackageJson(context: TemplateContext): st
|
|
|
54
54
|
"tailwindcss": "^3.4.13",
|
|
55
55
|
"typescript": "^5.2.0",
|
|
56
56
|
"vite": "^6.0.0",
|
|
57
|
-
"eslint": "^
|
|
58
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
59
|
-
"@typescript-eslint/parser": "^
|
|
60
|
-
"eslint-plugin-react-hooks": "^
|
|
57
|
+
"eslint": "^9.0.0",
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
59
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
60
|
+
"eslint-plugin-react-hooks": "^5.0.0",
|
|
61
61
|
"eslint-plugin-react-refresh": "^0.4.4"
|
|
62
62
|
}
|
|
63
63
|
};
|
|
@@ -479,7 +479,10 @@ import { fileURLToPath } from 'url';`,
|
|
|
479
479
|
}
|
|
480
480
|
|
|
481
481
|
const projectName = name || 'my-project';
|
|
482
|
-
|
|
482
|
+
// Commander applies the --template default ("full-stack"); the
|
|
483
|
+
// fallback here only fires if a caller invoked the action handler
|
|
484
|
+
// directly without going through commander.
|
|
485
|
+
const templateName = options.template || 'full-stack';
|
|
483
486
|
const templateDir = join(templatesDir, templateName);
|
|
484
487
|
|
|
485
488
|
if (!existsSync(templateDir)) {
|
|
@@ -498,7 +501,16 @@ import { fileURLToPath } from 'url';`,
|
|
|
498
501
|
|
|
499
502
|
// Copy template with variable substitution
|
|
500
503
|
const kebab = projectName.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
|
501
|
-
|
|
504
|
+
// PascalCase: split on hyphens / underscores / whitespace, capitalize each segment, join.
|
|
505
|
+
// 'audit-backend-only' -> 'AuditBackendOnly', 'my_app' -> 'MyApp', 'foo' -> 'Foo'.
|
|
506
|
+
// NOTE: regex char class is double-escaped because this whole handler
|
|
507
|
+
// is embedded as a string in the generator template — \\s here ends
|
|
508
|
+
// up as \s in the emitted source.
|
|
509
|
+
const component = projectName
|
|
510
|
+
.split(/[-_\\s]+/)
|
|
511
|
+
.filter(Boolean)
|
|
512
|
+
.map((s: string) => s.charAt(0).toUpperCase() + s.slice(1))
|
|
513
|
+
.join('');
|
|
502
514
|
const vars: Record<string, string> = {
|
|
503
515
|
'{{PROJECT_NAME}}': projectName,
|
|
504
516
|
'{{projectName}}': projectName,
|
|
@@ -533,11 +545,29 @@ import { fileURLToPath } from 'url';`,
|
|
|
533
545
|
console.log('Project created: ' + destDir);
|
|
534
546
|
console.log('Template: ' + templateName);
|
|
535
547
|
console.log('');
|
|
548
|
+
|
|
549
|
+
// Build the "Next steps" hint from the actual scripts the
|
|
550
|
+
// chosen template ships, so we never tell the user to run a
|
|
551
|
+
// command that doesn't exist in their package.json.
|
|
552
|
+
const destPkgPath = join(destDir, 'package.json');
|
|
553
|
+
const destPkg = existsSync(destPkgPath)
|
|
554
|
+
? JSON.parse(readFileSync(destPkgPath, 'utf8'))
|
|
555
|
+
: { scripts: {} };
|
|
556
|
+
const scripts = destPkg.scripts || {};
|
|
536
557
|
console.log('Next steps:');
|
|
537
558
|
console.log(' cd ' + projectName);
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
559
|
+
if (scripts.setup) {
|
|
560
|
+
console.log(' npm run setup # validate, generate code, install deps, setup db');
|
|
561
|
+
}
|
|
562
|
+
if (scripts['dev:backend'] && scripts['dev:frontend']) {
|
|
563
|
+
console.log(' npm run dev:backend # start backend (terminal 1)');
|
|
564
|
+
console.log(' npm run dev:frontend # start frontend (terminal 2)');
|
|
565
|
+
} else if (scripts.dev) {
|
|
566
|
+
console.log(' npm run dev # start dev server');
|
|
567
|
+
}
|
|
568
|
+
if (scripts['test:e2e']) {
|
|
569
|
+
console.log(' npm run test:e2e # run end-to-end tests (after starting dev servers)');
|
|
570
|
+
}`
|
|
541
571
|
},
|
|
542
572
|
// === gen subcommands ===
|
|
543
573
|
'gen.diagrams': {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@specverse/engines",
|
|
3
|
-
"version": "4.1.
|
|
4
|
-
"description": "SpecVerse toolchain
|
|
3
|
+
"version": "4.1.27",
|
|
4
|
+
"description": "SpecVerse toolchain \u2014 parser, inference, realize, generators, AI, registry",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -65,4 +65,4 @@
|
|
|
65
65
|
"access": "public"
|
|
66
66
|
},
|
|
67
67
|
"license": "MIT"
|
|
68
|
-
}
|
|
68
|
+
}
|