@stackweld/core 0.2.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/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-lint.log +498 -0
- package/.turbo/turbo-test.log +21 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/dist/__tests__/compatibility-scorer.test.d.ts +2 -0
- package/dist/__tests__/compatibility-scorer.test.d.ts.map +1 -0
- package/dist/__tests__/compatibility-scorer.test.js +226 -0
- package/dist/__tests__/compatibility-scorer.test.js.map +1 -0
- package/dist/__tests__/rules-engine.test.d.ts +2 -0
- package/dist/__tests__/rules-engine.test.d.ts.map +1 -0
- package/dist/__tests__/rules-engine.test.js +161 -0
- package/dist/__tests__/rules-engine.test.js.map +1 -0
- package/dist/__tests__/scaffold-orchestrator.test.d.ts +2 -0
- package/dist/__tests__/scaffold-orchestrator.test.d.ts.map +1 -0
- package/dist/__tests__/scaffold-orchestrator.test.js +149 -0
- package/dist/__tests__/scaffold-orchestrator.test.js.map +1 -0
- package/dist/__tests__/stack-engine.test.d.ts +2 -0
- package/dist/__tests__/stack-engine.test.d.ts.map +1 -0
- package/dist/__tests__/stack-engine.test.js +278 -0
- package/dist/__tests__/stack-engine.test.js.map +1 -0
- package/dist/db/database.d.ts +9 -0
- package/dist/db/database.d.ts.map +1 -0
- package/dist/db/database.js +106 -0
- package/dist/db/database.js.map +1 -0
- package/dist/db/index.d.ts +2 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +2 -0
- package/dist/db/index.js.map +1 -0
- package/dist/engine/compatibility-scorer.d.ts +37 -0
- package/dist/engine/compatibility-scorer.d.ts.map +1 -0
- package/dist/engine/compatibility-scorer.js +178 -0
- package/dist/engine/compatibility-scorer.js.map +1 -0
- package/dist/engine/compose-generator.d.ts +35 -0
- package/dist/engine/compose-generator.d.ts.map +1 -0
- package/dist/engine/compose-generator.js +95 -0
- package/dist/engine/compose-generator.js.map +1 -0
- package/dist/engine/cost-estimator.d.ts +22 -0
- package/dist/engine/cost-estimator.d.ts.map +1 -0
- package/dist/engine/cost-estimator.js +451 -0
- package/dist/engine/cost-estimator.js.map +1 -0
- package/dist/engine/env-analyzer.d.ts +36 -0
- package/dist/engine/env-analyzer.d.ts.map +1 -0
- package/dist/engine/env-analyzer.js +111 -0
- package/dist/engine/env-analyzer.js.map +1 -0
- package/dist/engine/health-checker.d.ts +20 -0
- package/dist/engine/health-checker.d.ts.map +1 -0
- package/dist/engine/health-checker.js +377 -0
- package/dist/engine/health-checker.js.map +1 -0
- package/dist/engine/index.d.ts +11 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +7 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/infra-generator.d.ts +26 -0
- package/dist/engine/infra-generator.d.ts.map +1 -0
- package/dist/engine/infra-generator.js +751 -0
- package/dist/engine/infra-generator.js.map +1 -0
- package/dist/engine/migration-planner.d.ts +34 -0
- package/dist/engine/migration-planner.d.ts.map +1 -0
- package/dist/engine/migration-planner.js +427 -0
- package/dist/engine/migration-planner.js.map +1 -0
- package/dist/engine/performance-profiler.d.ts +22 -0
- package/dist/engine/performance-profiler.d.ts.map +1 -0
- package/dist/engine/performance-profiler.js +292 -0
- package/dist/engine/performance-profiler.js.map +1 -0
- package/dist/engine/plugin-loader.d.ts +36 -0
- package/dist/engine/plugin-loader.d.ts.map +1 -0
- package/dist/engine/plugin-loader.js +157 -0
- package/dist/engine/plugin-loader.js.map +1 -0
- package/dist/engine/preferences.d.ts +24 -0
- package/dist/engine/preferences.d.ts.map +1 -0
- package/dist/engine/preferences.js +62 -0
- package/dist/engine/preferences.js.map +1 -0
- package/dist/engine/rules-engine.d.ts +31 -0
- package/dist/engine/rules-engine.d.ts.map +1 -0
- package/dist/engine/rules-engine.js +179 -0
- package/dist/engine/rules-engine.js.map +1 -0
- package/dist/engine/runtime-manager.d.ts +65 -0
- package/dist/engine/runtime-manager.d.ts.map +1 -0
- package/dist/engine/runtime-manager.js +181 -0
- package/dist/engine/runtime-manager.js.map +1 -0
- package/dist/engine/scaffold-orchestrator.d.ts +103 -0
- package/dist/engine/scaffold-orchestrator.d.ts.map +1 -0
- package/dist/engine/scaffold-orchestrator.js +934 -0
- package/dist/engine/scaffold-orchestrator.js.map +1 -0
- package/dist/engine/stack-detector.d.ts +21 -0
- package/dist/engine/stack-detector.d.ts.map +1 -0
- package/dist/engine/stack-detector.js +313 -0
- package/dist/engine/stack-detector.js.map +1 -0
- package/dist/engine/stack-differ.d.ts +26 -0
- package/dist/engine/stack-differ.d.ts.map +1 -0
- package/dist/engine/stack-differ.js +80 -0
- package/dist/engine/stack-differ.js.map +1 -0
- package/dist/engine/stack-engine.d.ts +54 -0
- package/dist/engine/stack-engine.d.ts.map +1 -0
- package/dist/engine/stack-engine.js +186 -0
- package/dist/engine/stack-engine.js.map +1 -0
- package/dist/engine/stack-serializer.d.ts +32 -0
- package/dist/engine/stack-serializer.d.ts.map +1 -0
- package/dist/engine/stack-serializer.js +75 -0
- package/dist/engine/stack-serializer.js.map +1 -0
- package/dist/engine/standards-linter.d.ts +34 -0
- package/dist/engine/standards-linter.d.ts.map +1 -0
- package/dist/engine/standards-linter.js +162 -0
- package/dist/engine/standards-linter.js.map +1 -0
- package/dist/engine/tech-installer.d.ts +37 -0
- package/dist/engine/tech-installer.d.ts.map +1 -0
- package/dist/engine/tech-installer.js +508 -0
- package/dist/engine/tech-installer.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/project.d.ts +33 -0
- package/dist/types/project.d.ts.map +1 -0
- package/dist/types/project.js +6 -0
- package/dist/types/project.js.map +1 -0
- package/dist/types/stack.d.ts +29 -0
- package/dist/types/stack.d.ts.map +1 -0
- package/dist/types/stack.js +6 -0
- package/dist/types/stack.js.map +1 -0
- package/dist/types/technology.d.ts +47 -0
- package/dist/types/technology.d.ts.map +1 -0
- package/dist/types/technology.js +6 -0
- package/dist/types/technology.js.map +1 -0
- package/dist/types/template.d.ts +34 -0
- package/dist/types/template.d.ts.map +1 -0
- package/dist/types/template.js +6 -0
- package/dist/types/template.js.map +1 -0
- package/dist/types/validation.d.ts +20 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +5 -0
- package/dist/types/validation.js.map +1 -0
- package/package.json +39 -0
- package/src/__tests__/compatibility-scorer.test.ts +264 -0
- package/src/__tests__/rules-engine.test.ts +170 -0
- package/src/__tests__/scaffold-orchestrator.test.ts +161 -0
- package/src/__tests__/stack-engine.test.ts +328 -0
- package/src/db/database.ts +112 -0
- package/src/db/index.ts +1 -0
- package/src/engine/compatibility-scorer.ts +222 -0
- package/src/engine/compose-generator.ts +134 -0
- package/src/engine/cost-estimator.ts +498 -0
- package/src/engine/env-analyzer.ts +156 -0
- package/src/engine/health-checker.ts +421 -0
- package/src/engine/index.ts +17 -0
- package/src/engine/infra-generator.ts +837 -0
- package/src/engine/migration-planner.ts +496 -0
- package/src/engine/performance-profiler.ts +354 -0
- package/src/engine/plugin-loader.ts +216 -0
- package/src/engine/preferences.ts +85 -0
- package/src/engine/rules-engine.ts +204 -0
- package/src/engine/runtime-manager.ts +207 -0
- package/src/engine/scaffold-orchestrator.ts +1052 -0
- package/src/engine/stack-detector.ts +345 -0
- package/src/engine/stack-differ.ts +118 -0
- package/src/engine/stack-engine.ts +258 -0
- package/src/engine/stack-serializer.ts +95 -0
- package/src/engine/standards-linter.ts +210 -0
- package/src/engine/tech-installer.ts +650 -0
- package/src/index.ts +78 -0
- package/src/types/index.ts +10 -0
- package/src/types/project.ts +36 -0
- package/src/types/stack.ts +32 -0
- package/src/types/technology.ts +58 -0
- package/src/types/template.ts +37 -0
- package/src/types/validation.ts +22 -0
- package/tsconfig.json +10 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { scoreCompatibility, scoreStack } from "../engine/compatibility-scorer.js";
|
|
3
|
+
// ─── Test fixtures ────────────────────────────────────
|
|
4
|
+
function makeTech(overrides) {
|
|
5
|
+
return {
|
|
6
|
+
description: "",
|
|
7
|
+
website: "",
|
|
8
|
+
versions: [{ version: "1" }],
|
|
9
|
+
defaultVersion: "1",
|
|
10
|
+
requires: [],
|
|
11
|
+
incompatibleWith: [],
|
|
12
|
+
suggestedWith: [],
|
|
13
|
+
envVars: {},
|
|
14
|
+
configFiles: [],
|
|
15
|
+
lastVerified: "2026-03-22",
|
|
16
|
+
tags: [],
|
|
17
|
+
...overrides,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const nodejs = makeTech({
|
|
21
|
+
id: "nodejs",
|
|
22
|
+
name: "Node.js",
|
|
23
|
+
category: "runtime",
|
|
24
|
+
defaultPort: 3000,
|
|
25
|
+
suggestedWith: ["typescript"],
|
|
26
|
+
});
|
|
27
|
+
const nextjs = makeTech({
|
|
28
|
+
id: "nextjs",
|
|
29
|
+
name: "Next.js",
|
|
30
|
+
category: "frontend",
|
|
31
|
+
defaultPort: 3000,
|
|
32
|
+
requires: ["nodejs", "react"],
|
|
33
|
+
incompatibleWith: ["nuxt", "sveltekit", "remix", "astro", "angular", "qwik", "solidjs"],
|
|
34
|
+
suggestedWith: ["typescript", "tailwindcss", "prisma"],
|
|
35
|
+
});
|
|
36
|
+
const nuxt = makeTech({
|
|
37
|
+
id: "nuxt",
|
|
38
|
+
name: "Nuxt",
|
|
39
|
+
category: "frontend",
|
|
40
|
+
defaultPort: 3000,
|
|
41
|
+
requires: ["nodejs"],
|
|
42
|
+
incompatibleWith: ["nextjs"],
|
|
43
|
+
});
|
|
44
|
+
const react = makeTech({
|
|
45
|
+
id: "react",
|
|
46
|
+
name: "React",
|
|
47
|
+
category: "frontend",
|
|
48
|
+
defaultPort: 3000,
|
|
49
|
+
requires: ["nodejs"],
|
|
50
|
+
suggestedWith: ["tailwindcss"],
|
|
51
|
+
});
|
|
52
|
+
const tailwindcss = makeTech({
|
|
53
|
+
id: "tailwindcss",
|
|
54
|
+
name: "Tailwind CSS",
|
|
55
|
+
category: "styling",
|
|
56
|
+
requires: ["nodejs"],
|
|
57
|
+
suggestedWith: ["react", "nextjs", "vue"],
|
|
58
|
+
});
|
|
59
|
+
const prisma = makeTech({
|
|
60
|
+
id: "prisma",
|
|
61
|
+
name: "Prisma ORM",
|
|
62
|
+
category: "orm",
|
|
63
|
+
requires: ["nodejs"],
|
|
64
|
+
incompatibleWith: ["typeorm", "drizzle", "mongoose"],
|
|
65
|
+
suggestedWith: ["postgresql", "nextjs", "typescript"],
|
|
66
|
+
});
|
|
67
|
+
const express = makeTech({
|
|
68
|
+
id: "express",
|
|
69
|
+
name: "Express",
|
|
70
|
+
category: "backend",
|
|
71
|
+
defaultPort: 3001,
|
|
72
|
+
requires: ["nodejs"],
|
|
73
|
+
incompatibleWith: ["nestjs", "hono", "fastify"],
|
|
74
|
+
suggestedWith: ["typescript", "postgresql"],
|
|
75
|
+
});
|
|
76
|
+
const fastify = makeTech({
|
|
77
|
+
id: "fastify",
|
|
78
|
+
name: "Fastify",
|
|
79
|
+
category: "backend",
|
|
80
|
+
defaultPort: 3001,
|
|
81
|
+
requires: ["nodejs"],
|
|
82
|
+
incompatibleWith: ["nestjs", "hono", "express"],
|
|
83
|
+
suggestedWith: ["typescript", "postgresql", "prisma"],
|
|
84
|
+
});
|
|
85
|
+
const postgresql = makeTech({
|
|
86
|
+
id: "postgresql",
|
|
87
|
+
name: "PostgreSQL",
|
|
88
|
+
category: "database",
|
|
89
|
+
defaultPort: 5432,
|
|
90
|
+
suggestedWith: ["prisma", "drizzle", "sqlalchemy"],
|
|
91
|
+
});
|
|
92
|
+
const redis = makeTech({
|
|
93
|
+
id: "redis",
|
|
94
|
+
name: "Redis",
|
|
95
|
+
category: "database",
|
|
96
|
+
defaultPort: 6379,
|
|
97
|
+
});
|
|
98
|
+
const typescript = makeTech({
|
|
99
|
+
id: "typescript",
|
|
100
|
+
name: "TypeScript",
|
|
101
|
+
category: "devops",
|
|
102
|
+
requires: [],
|
|
103
|
+
});
|
|
104
|
+
// ─── Tests ────────────────────────────────────────────
|
|
105
|
+
describe("scoreCompatibility", () => {
|
|
106
|
+
it("scores nextjs + prisma high (suggested pairing, shared runtime, complementary)", () => {
|
|
107
|
+
const result = scoreCompatibility(nextjs, prisma);
|
|
108
|
+
// +25 suggested (nextjs suggests prisma OR prisma suggests nextjs)
|
|
109
|
+
// +15 shared runtime (both require nodejs)
|
|
110
|
+
// +10 complementary (frontend + orm)
|
|
111
|
+
expect(result.score).toBeGreaterThanOrEqual(75);
|
|
112
|
+
expect(["S", "A"]).toContain(result.grade);
|
|
113
|
+
expect(result.factors.some((f) => f.label === "Suggested pairing")).toBe(true);
|
|
114
|
+
expect(result.factors.some((f) => f.label === "Shared runtime")).toBe(true);
|
|
115
|
+
expect(result.factors.some((f) => f.label === "Complementary categories")).toBe(true);
|
|
116
|
+
});
|
|
117
|
+
it("scores nextjs + nuxt as 0 (incompatible)", () => {
|
|
118
|
+
const result = scoreCompatibility(nextjs, nuxt);
|
|
119
|
+
expect(result.score).toBe(0);
|
|
120
|
+
expect(result.grade).toBe("F");
|
|
121
|
+
expect(result.factors.some((f) => f.label === "Incompatible")).toBe(true);
|
|
122
|
+
expect(result.recommendation).toContain("Incompatible");
|
|
123
|
+
});
|
|
124
|
+
it("scores react + tailwindcss high (suggested, complementary)", () => {
|
|
125
|
+
const result = scoreCompatibility(react, tailwindcss);
|
|
126
|
+
// +25 suggested (both suggest each other)
|
|
127
|
+
// +15 shared runtime (both require nodejs)
|
|
128
|
+
// +10 complementary (frontend + styling)
|
|
129
|
+
expect(result.score).toBeGreaterThanOrEqual(75);
|
|
130
|
+
expect(["S", "A"]).toContain(result.grade);
|
|
131
|
+
expect(result.factors.some((f) => f.label === "Suggested pairing")).toBe(true);
|
|
132
|
+
});
|
|
133
|
+
it("scores express + fastify low (incompatible, same category, same runtime, same port)", () => {
|
|
134
|
+
const result = scoreCompatibility(express, fastify);
|
|
135
|
+
// -50 incompatible, -15 same category+runtime, -5 same port
|
|
136
|
+
expect(result.score).toBe(0); // clamped to 0
|
|
137
|
+
expect(result.grade).toBe("F");
|
|
138
|
+
expect(result.factors.some((f) => f.label === "Incompatible")).toBe(true);
|
|
139
|
+
expect(result.factors.some((f) => f.label === "Same category and runtime")).toBe(true);
|
|
140
|
+
expect(result.factors.some((f) => f.label === "Port conflict")).toBe(true);
|
|
141
|
+
});
|
|
142
|
+
it("scores postgresql + redis as neutral (both databases, different ports, no runtime overlap)", () => {
|
|
143
|
+
const result = scoreCompatibility(postgresql, redis);
|
|
144
|
+
// baseline 50, no shared runtime (neither requires a runtime), no suggested
|
|
145
|
+
// no incompatibility, no same runtime => no -15 penalty
|
|
146
|
+
expect(result.score).toBe(50);
|
|
147
|
+
expect(result.grade).toBe("C");
|
|
148
|
+
});
|
|
149
|
+
it("never exceeds 100", () => {
|
|
150
|
+
// Artificial case: two techs that suggest each other, share runtime, complementary
|
|
151
|
+
const techA = makeTech({
|
|
152
|
+
id: "superA",
|
|
153
|
+
name: "Super A",
|
|
154
|
+
category: "frontend",
|
|
155
|
+
requires: ["nodejs"],
|
|
156
|
+
suggestedWith: ["superB"],
|
|
157
|
+
});
|
|
158
|
+
const techB = makeTech({
|
|
159
|
+
id: "superB",
|
|
160
|
+
name: "Super B",
|
|
161
|
+
category: "backend",
|
|
162
|
+
requires: ["nodejs"],
|
|
163
|
+
suggestedWith: ["superA"],
|
|
164
|
+
});
|
|
165
|
+
const result = scoreCompatibility(techA, techB);
|
|
166
|
+
// 50 + 25 + 15 + 10 = 100
|
|
167
|
+
expect(result.score).toBeLessThanOrEqual(100);
|
|
168
|
+
expect(result.score).toBe(100);
|
|
169
|
+
expect(result.grade).toBe("S");
|
|
170
|
+
});
|
|
171
|
+
it("never goes below 0", () => {
|
|
172
|
+
const result = scoreCompatibility(express, fastify);
|
|
173
|
+
expect(result.score).toBeGreaterThanOrEqual(0);
|
|
174
|
+
});
|
|
175
|
+
it("returns correct grade boundaries", () => {
|
|
176
|
+
// S: 90-100 — test with a score of exactly 90
|
|
177
|
+
// We use nextjs + prisma which should give 50+25+15+10 = 100
|
|
178
|
+
const sResult = scoreCompatibility(nextjs, prisma);
|
|
179
|
+
expect(sResult.score).toBeGreaterThanOrEqual(90);
|
|
180
|
+
expect(sResult.grade).toBe("S");
|
|
181
|
+
});
|
|
182
|
+
it("includes a human-readable recommendation", () => {
|
|
183
|
+
const result = scoreCompatibility(nextjs, prisma);
|
|
184
|
+
expect(typeof result.recommendation).toBe("string");
|
|
185
|
+
expect(result.recommendation.length).toBeGreaterThan(0);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
describe("scoreStack", () => {
|
|
189
|
+
it("returns perfect score for single technology", () => {
|
|
190
|
+
const result = scoreStack([nextjs]);
|
|
191
|
+
expect(result.overall).toBe(100);
|
|
192
|
+
expect(result.grade).toBe("S");
|
|
193
|
+
expect(result.pairs).toHaveLength(0);
|
|
194
|
+
});
|
|
195
|
+
it("scores a full stack with 5+ technologies", () => {
|
|
196
|
+
const stack = [nodejs, nextjs, prisma, postgresql, tailwindcss, typescript];
|
|
197
|
+
const result = scoreStack(stack);
|
|
198
|
+
// Should produce C(6,2) = 15 pairs
|
|
199
|
+
expect(result.pairs).toHaveLength(15);
|
|
200
|
+
// Overall should be the average of all pair scores
|
|
201
|
+
const expectedAvg = Math.round(result.pairs.reduce((s, p) => s + p.score, 0) / result.pairs.length);
|
|
202
|
+
expect(result.overall).toBe(expectedAvg);
|
|
203
|
+
// Should have a valid grade
|
|
204
|
+
expect(["S", "A", "B", "C", "D", "F"]).toContain(result.grade);
|
|
205
|
+
});
|
|
206
|
+
it("reflects bad pairings in overall score", () => {
|
|
207
|
+
// Include incompatible pair: nextjs + nuxt
|
|
208
|
+
const stack = [nodejs, nextjs, nuxt, postgresql];
|
|
209
|
+
const result = scoreStack(stack);
|
|
210
|
+
// The nextjs+nuxt pair should drag down the overall
|
|
211
|
+
const badPair = result.pairs.find((p) => (p.a === "nextjs" && p.b === "nuxt") || (p.a === "nuxt" && p.b === "nextjs"));
|
|
212
|
+
expect(badPair).toBeDefined();
|
|
213
|
+
expect(badPair?.score).toBe(0);
|
|
214
|
+
// Overall should be lower than a stack without incompatible techs
|
|
215
|
+
const goodStack = [nodejs, nextjs, postgresql];
|
|
216
|
+
const goodResult = scoreStack(goodStack);
|
|
217
|
+
expect(goodResult.overall).toBeGreaterThan(result.overall);
|
|
218
|
+
});
|
|
219
|
+
it("pair entries contain correct tech IDs", () => {
|
|
220
|
+
const result = scoreStack([express, postgresql]);
|
|
221
|
+
expect(result.pairs).toHaveLength(1);
|
|
222
|
+
expect(result.pairs[0].a).toBe("express");
|
|
223
|
+
expect(result.pairs[0].b).toBe("postgresql");
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
//# sourceMappingURL=compatibility-scorer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compatibility-scorer.test.js","sourceRoot":"","sources":["../../src/__tests__/compatibility-scorer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules-engine.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/rules-engine.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { RulesEngine } from "../engine/rules-engine.js";
|
|
3
|
+
const mockTechs = [
|
|
4
|
+
{
|
|
5
|
+
id: "nodejs",
|
|
6
|
+
name: "Node.js",
|
|
7
|
+
category: "runtime",
|
|
8
|
+
description: "",
|
|
9
|
+
website: "",
|
|
10
|
+
versions: [{ version: "22" }],
|
|
11
|
+
defaultVersion: "22",
|
|
12
|
+
defaultPort: 3000,
|
|
13
|
+
requires: [],
|
|
14
|
+
incompatibleWith: [],
|
|
15
|
+
suggestedWith: ["typescript"],
|
|
16
|
+
envVars: {},
|
|
17
|
+
configFiles: [],
|
|
18
|
+
lastVerified: "2026-03-22",
|
|
19
|
+
tags: [],
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "nextjs",
|
|
23
|
+
name: "Next.js",
|
|
24
|
+
category: "frontend",
|
|
25
|
+
description: "",
|
|
26
|
+
website: "",
|
|
27
|
+
versions: [{ version: "15" }],
|
|
28
|
+
defaultVersion: "15",
|
|
29
|
+
defaultPort: 3000,
|
|
30
|
+
requires: ["nodejs", "react"],
|
|
31
|
+
incompatibleWith: ["nuxt"],
|
|
32
|
+
suggestedWith: ["typescript", "tailwindcss"],
|
|
33
|
+
envVars: {},
|
|
34
|
+
configFiles: [],
|
|
35
|
+
lastVerified: "2026-03-22",
|
|
36
|
+
tags: [],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "react",
|
|
40
|
+
name: "React",
|
|
41
|
+
category: "frontend",
|
|
42
|
+
description: "",
|
|
43
|
+
website: "",
|
|
44
|
+
versions: [{ version: "19" }],
|
|
45
|
+
defaultVersion: "19",
|
|
46
|
+
defaultPort: 3000,
|
|
47
|
+
requires: ["nodejs"],
|
|
48
|
+
incompatibleWith: [],
|
|
49
|
+
suggestedWith: [],
|
|
50
|
+
envVars: {},
|
|
51
|
+
configFiles: [],
|
|
52
|
+
lastVerified: "2026-03-22",
|
|
53
|
+
tags: [],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: "nuxt",
|
|
57
|
+
name: "Nuxt",
|
|
58
|
+
category: "frontend",
|
|
59
|
+
description: "",
|
|
60
|
+
website: "",
|
|
61
|
+
versions: [{ version: "3" }],
|
|
62
|
+
defaultVersion: "3",
|
|
63
|
+
defaultPort: 3000,
|
|
64
|
+
requires: ["nodejs"],
|
|
65
|
+
incompatibleWith: ["nextjs"],
|
|
66
|
+
suggestedWith: [],
|
|
67
|
+
envVars: {},
|
|
68
|
+
configFiles: [],
|
|
69
|
+
lastVerified: "2026-03-22",
|
|
70
|
+
tags: [],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: "postgresql",
|
|
74
|
+
name: "PostgreSQL",
|
|
75
|
+
category: "database",
|
|
76
|
+
description: "",
|
|
77
|
+
website: "",
|
|
78
|
+
versions: [{ version: "17" }],
|
|
79
|
+
defaultVersion: "17",
|
|
80
|
+
defaultPort: 5432,
|
|
81
|
+
requires: [],
|
|
82
|
+
incompatibleWith: [],
|
|
83
|
+
suggestedWith: [],
|
|
84
|
+
envVars: {},
|
|
85
|
+
configFiles: [],
|
|
86
|
+
lastVerified: "2026-03-22",
|
|
87
|
+
tags: [],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: "typescript",
|
|
91
|
+
name: "TypeScript",
|
|
92
|
+
category: "devops",
|
|
93
|
+
description: "",
|
|
94
|
+
website: "",
|
|
95
|
+
versions: [{ version: "5" }],
|
|
96
|
+
defaultVersion: "5",
|
|
97
|
+
requires: [],
|
|
98
|
+
incompatibleWith: [],
|
|
99
|
+
suggestedWith: [],
|
|
100
|
+
envVars: {},
|
|
101
|
+
configFiles: [],
|
|
102
|
+
lastVerified: "2026-03-22",
|
|
103
|
+
tags: [],
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
describe("RulesEngine", () => {
|
|
107
|
+
const engine = new RulesEngine(mockTechs);
|
|
108
|
+
it("validates a simple valid stack", () => {
|
|
109
|
+
const selected = [
|
|
110
|
+
{ technologyId: "nodejs", version: "22" },
|
|
111
|
+
{ technologyId: "postgresql", version: "17" },
|
|
112
|
+
];
|
|
113
|
+
const result = engine.validate(selected);
|
|
114
|
+
expect(result.valid).toBe(true);
|
|
115
|
+
expect(result.issues.filter((i) => i.severity === "error")).toHaveLength(0);
|
|
116
|
+
});
|
|
117
|
+
it("auto-resolves missing dependencies", () => {
|
|
118
|
+
const selected = [{ technologyId: "nextjs", version: "15" }];
|
|
119
|
+
const result = engine.validate(selected);
|
|
120
|
+
expect(result.resolvedDependencies).toContain("nodejs");
|
|
121
|
+
expect(result.resolvedDependencies).toContain("react");
|
|
122
|
+
expect(result.issues.some((i) => i.code === "AUTO_DEPENDENCY")).toBe(true);
|
|
123
|
+
});
|
|
124
|
+
it("detects incompatible technologies", () => {
|
|
125
|
+
const selected = [
|
|
126
|
+
{ technologyId: "nodejs", version: "22" },
|
|
127
|
+
{ technologyId: "nextjs", version: "15" },
|
|
128
|
+
{ technologyId: "nuxt", version: "3" },
|
|
129
|
+
];
|
|
130
|
+
const result = engine.validate(selected);
|
|
131
|
+
expect(result.valid).toBe(false);
|
|
132
|
+
expect(result.issues.some((i) => i.code === "INCOMPATIBLE")).toBe(true);
|
|
133
|
+
});
|
|
134
|
+
it("detects and resolves port conflicts", () => {
|
|
135
|
+
const selected = [
|
|
136
|
+
{ technologyId: "nodejs", version: "22" },
|
|
137
|
+
{ technologyId: "react", version: "19" },
|
|
138
|
+
{ technologyId: "nextjs", version: "15" },
|
|
139
|
+
];
|
|
140
|
+
const result = engine.validate(selected);
|
|
141
|
+
const ports = Object.values(result.portAssignments);
|
|
142
|
+
const uniquePorts = new Set(ports);
|
|
143
|
+
expect(ports.length).toBe(uniquePorts.size); // No duplicates
|
|
144
|
+
});
|
|
145
|
+
it("detects unknown technologies", () => {
|
|
146
|
+
const selected = [{ technologyId: "doesnotexist", version: "1" }];
|
|
147
|
+
const result = engine.validate(selected);
|
|
148
|
+
expect(result.valid).toBe(false);
|
|
149
|
+
expect(result.issues.some((i) => i.code === "UNKNOWN_TECHNOLOGY")).toBe(true);
|
|
150
|
+
});
|
|
151
|
+
it("returns suggestions for selected stack", () => {
|
|
152
|
+
const suggestions = engine.getSuggestions(["nodejs"]);
|
|
153
|
+
expect(suggestions.some((s) => s.id === "typescript")).toBe(true);
|
|
154
|
+
});
|
|
155
|
+
it("gets technologies by category", () => {
|
|
156
|
+
const frontends = engine.getByCategory("frontend");
|
|
157
|
+
expect(frontends.length).toBeGreaterThan(0);
|
|
158
|
+
expect(frontends.every((t) => t.category === "frontend")).toBe(true);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
//# sourceMappingURL=rules-engine.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules-engine.test.js","sourceRoot":"","sources":["../../src/__tests__/rules-engine.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-orchestrator.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/scaffold-orchestrator.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { ScaffoldOrchestrator } from "../engine/scaffold-orchestrator.js";
|
|
3
|
+
const mockTechs = [
|
|
4
|
+
{
|
|
5
|
+
id: "nodejs",
|
|
6
|
+
name: "Node.js",
|
|
7
|
+
category: "runtime",
|
|
8
|
+
description: "JavaScript runtime",
|
|
9
|
+
website: "https://nodejs.org",
|
|
10
|
+
versions: [{ version: "22" }],
|
|
11
|
+
defaultVersion: "22",
|
|
12
|
+
defaultPort: 3000,
|
|
13
|
+
requires: [],
|
|
14
|
+
incompatibleWith: [],
|
|
15
|
+
suggestedWith: [],
|
|
16
|
+
envVars: { NODE_ENV: "development", PORT: "3000" },
|
|
17
|
+
configFiles: ["package.json"],
|
|
18
|
+
lastVerified: "2026-03-22",
|
|
19
|
+
tags: ["nodejs"],
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "postgresql",
|
|
23
|
+
name: "PostgreSQL",
|
|
24
|
+
category: "database",
|
|
25
|
+
description: "Relational database",
|
|
26
|
+
website: "https://postgresql.org",
|
|
27
|
+
versions: [{ version: "17" }],
|
|
28
|
+
defaultVersion: "17",
|
|
29
|
+
defaultPort: 5432,
|
|
30
|
+
requires: [],
|
|
31
|
+
incompatibleWith: [],
|
|
32
|
+
suggestedWith: [],
|
|
33
|
+
dockerImage: "postgres:17",
|
|
34
|
+
healthCheck: {
|
|
35
|
+
command: "pg_isready -U postgres",
|
|
36
|
+
interval: "5s",
|
|
37
|
+
timeout: "5s",
|
|
38
|
+
retries: 5,
|
|
39
|
+
},
|
|
40
|
+
envVars: {
|
|
41
|
+
POSTGRES_USER: "postgres",
|
|
42
|
+
POSTGRES_PASSWORD: "postgres",
|
|
43
|
+
POSTGRES_DB: "app",
|
|
44
|
+
},
|
|
45
|
+
configFiles: [],
|
|
46
|
+
lastVerified: "2026-03-22",
|
|
47
|
+
tags: ["postgresql"],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: "redis",
|
|
51
|
+
name: "Redis",
|
|
52
|
+
category: "database",
|
|
53
|
+
description: "In-memory store",
|
|
54
|
+
website: "https://redis.io",
|
|
55
|
+
versions: [{ version: "7" }],
|
|
56
|
+
defaultVersion: "7",
|
|
57
|
+
defaultPort: 6379,
|
|
58
|
+
requires: [],
|
|
59
|
+
incompatibleWith: [],
|
|
60
|
+
suggestedWith: [],
|
|
61
|
+
dockerImage: "redis:7-alpine",
|
|
62
|
+
healthCheck: {
|
|
63
|
+
command: "redis-cli ping",
|
|
64
|
+
interval: "5s",
|
|
65
|
+
timeout: "5s",
|
|
66
|
+
retries: 5,
|
|
67
|
+
},
|
|
68
|
+
envVars: { REDIS_URL: "redis://localhost:6379/0" },
|
|
69
|
+
configFiles: [],
|
|
70
|
+
lastVerified: "2026-03-22",
|
|
71
|
+
tags: ["redis"],
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
const mockStack = {
|
|
75
|
+
id: "test-stack",
|
|
76
|
+
name: "Test Stack",
|
|
77
|
+
description: "A test stack",
|
|
78
|
+
profile: "standard",
|
|
79
|
+
technologies: [
|
|
80
|
+
{ technologyId: "nodejs", version: "22", port: 3000 },
|
|
81
|
+
{ technologyId: "postgresql", version: "17", port: 5432 },
|
|
82
|
+
{ technologyId: "redis", version: "7", port: 6379 },
|
|
83
|
+
],
|
|
84
|
+
createdAt: "2026-03-22T00:00:00Z",
|
|
85
|
+
updatedAt: "2026-03-22T00:00:00Z",
|
|
86
|
+
version: 1,
|
|
87
|
+
tags: ["test"],
|
|
88
|
+
};
|
|
89
|
+
describe("ScaffoldOrchestrator", () => {
|
|
90
|
+
const orchestrator = new ScaffoldOrchestrator(mockTechs);
|
|
91
|
+
it("generates all scaffold files", () => {
|
|
92
|
+
const output = orchestrator.generate(mockStack);
|
|
93
|
+
expect(output.dockerCompose).not.toBeNull();
|
|
94
|
+
expect(output.envExample).toBeTruthy();
|
|
95
|
+
expect(output.readme).toBeTruthy();
|
|
96
|
+
expect(output.gitignore).toBeTruthy();
|
|
97
|
+
expect(output.devcontainer).toBeTruthy();
|
|
98
|
+
});
|
|
99
|
+
it("generates docker-compose with correct services", () => {
|
|
100
|
+
const compose = orchestrator.generateDockerCompose(mockStack, mockTechs);
|
|
101
|
+
expect(compose).toContain("postgresql:");
|
|
102
|
+
expect(compose).toContain("image: postgres:17");
|
|
103
|
+
expect(compose).toContain("redis:");
|
|
104
|
+
expect(compose).toContain("image: redis:7-alpine");
|
|
105
|
+
expect(compose).toContain("5432:5432");
|
|
106
|
+
expect(compose).toContain("6379:6379");
|
|
107
|
+
expect(compose).toContain("pg_isready");
|
|
108
|
+
expect(compose).toContain("redis-cli ping");
|
|
109
|
+
expect(compose).toContain("volumes:");
|
|
110
|
+
// Should NOT include nodejs (no docker image)
|
|
111
|
+
expect(compose).not.toContain("nodejs:");
|
|
112
|
+
});
|
|
113
|
+
it("generates .env.example with all env vars", () => {
|
|
114
|
+
const env = orchestrator.generateEnvExample(mockStack, mockTechs);
|
|
115
|
+
expect(env).toContain("NODE_ENV=development");
|
|
116
|
+
expect(env).toContain("POSTGRES_USER=postgres");
|
|
117
|
+
expect(env).toContain("REDIS_URL=redis://localhost:6379/0");
|
|
118
|
+
});
|
|
119
|
+
it("generates README with stack table", () => {
|
|
120
|
+
const readme = orchestrator.generateReadme(mockStack, mockTechs);
|
|
121
|
+
expect(readme).toContain("# Test Stack");
|
|
122
|
+
expect(readme).toContain("Node.js");
|
|
123
|
+
expect(readme).toContain("PostgreSQL");
|
|
124
|
+
expect(readme).toContain("docker compose up");
|
|
125
|
+
});
|
|
126
|
+
it("generates .gitignore with relevant patterns", () => {
|
|
127
|
+
const gitignore = orchestrator.generateGitignore(mockTechs);
|
|
128
|
+
expect(gitignore).toContain("node_modules/");
|
|
129
|
+
expect(gitignore).toContain(".env");
|
|
130
|
+
expect(gitignore).toContain("*.db");
|
|
131
|
+
});
|
|
132
|
+
it("generates devcontainer.json", () => {
|
|
133
|
+
const devcontainer = JSON.parse(orchestrator.generateDevcontainer(mockStack, mockTechs));
|
|
134
|
+
expect(devcontainer.name).toBe("Test Stack");
|
|
135
|
+
expect(devcontainer.forwardPorts).toContain(3000);
|
|
136
|
+
expect(devcontainer.forwardPorts).toContain(5432);
|
|
137
|
+
expect(devcontainer.features).toHaveProperty("ghcr.io/devcontainers/features/node:1");
|
|
138
|
+
expect(devcontainer.features).toHaveProperty("ghcr.io/devcontainers/features/docker-in-docker:2");
|
|
139
|
+
});
|
|
140
|
+
it("returns null docker-compose when no docker services", () => {
|
|
141
|
+
const noDockerStack = {
|
|
142
|
+
...mockStack,
|
|
143
|
+
technologies: [{ technologyId: "nodejs", version: "22", port: 3000 }],
|
|
144
|
+
};
|
|
145
|
+
const output = orchestrator.generate(noDockerStack);
|
|
146
|
+
expect(output.dockerCompose).toBeNull();
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
//# sourceMappingURL=scaffold-orchestrator.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-orchestrator.test.js","sourceRoot":"","sources":["../../src/__tests__/scaffold-orchestrator.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack-engine.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/stack-engine.test.ts"],"names":[],"mappings":""}
|