@stackweld/core 0.2.1 → 0.3.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/LICENSE +21 -0
- package/README.md +54 -0
- package/dist/__tests__/compatibility-scorer.test.d.ts +1 -1
- package/dist/__tests__/rules-engine.test.d.ts +1 -1
- package/dist/__tests__/scaffold-orchestrator.test.d.ts +1 -1
- package/dist/__tests__/stack-engine.test.d.ts +1 -1
- package/dist/db/database.d.ts +1 -1
- package/dist/engine/compatibility-scorer.d.ts +16 -19
- package/dist/engine/compose-generator.d.ts +21 -23
- package/dist/engine/cost-estimator.d.ts +13 -13
- package/dist/engine/env-analyzer.d.ts +14 -14
- package/dist/engine/health-checker.d.ts +12 -12
- package/dist/engine/health-checker.js +14 -6
- package/dist/engine/infra-generator.d.ts +14 -17
- package/dist/engine/migration-planner.d.ts +18 -22
- package/dist/engine/performance-profiler.d.ts +13 -13
- package/dist/engine/preferences.d.ts +7 -7
- package/dist/engine/runtime-manager.d.ts +46 -56
- package/dist/engine/runtime-manager.js +24 -10
- package/dist/engine/scaffold-orchestrator.js +42 -6
- package/dist/engine/stack-detector.d.ts +10 -10
- package/dist/engine/stack-differ.d.ts +15 -15
- package/dist/engine/stack-differ.js +76 -72
- package/dist/engine/stack-serializer.d.ts +8 -8
- package/dist/engine/tech-installer.d.ts +12 -12
- package/dist/engine/tech-installer.js +3 -2
- package/dist/types/project.d.ts +19 -19
- package/dist/types/project.js +1 -1
- package/dist/types/stack.d.ts +18 -18
- package/dist/types/stack.js +1 -1
- package/dist/types/technology.d.ts +28 -37
- package/dist/types/technology.js +1 -1
- package/dist/types/template.d.ts +22 -22
- package/dist/types/template.js +1 -1
- package/dist/types/validation.d.ts +12 -12
- package/dist/types/validation.js +1 -1
- package/package.json +16 -10
- package/.turbo/turbo-build.log +0 -4
- package/.turbo/turbo-lint.log +0 -498
- package/.turbo/turbo-test.log +0 -21
- package/.turbo/turbo-typecheck.log +0 -4
- package/dist/__tests__/compatibility-scorer.test.d.ts.map +0 -1
- package/dist/__tests__/compatibility-scorer.test.js.map +0 -1
- package/dist/__tests__/rules-engine.test.d.ts.map +0 -1
- package/dist/__tests__/rules-engine.test.js.map +0 -1
- package/dist/__tests__/scaffold-orchestrator.test.d.ts.map +0 -1
- package/dist/__tests__/scaffold-orchestrator.test.js.map +0 -1
- package/dist/__tests__/stack-engine.test.d.ts.map +0 -1
- package/dist/__tests__/stack-engine.test.js.map +0 -1
- package/dist/db/database.d.ts.map +0 -1
- package/dist/db/database.js.map +0 -1
- package/dist/db/index.d.ts.map +0 -1
- package/dist/db/index.js.map +0 -1
- package/dist/engine/compatibility-scorer.d.ts.map +0 -1
- package/dist/engine/compatibility-scorer.js.map +0 -1
- package/dist/engine/compose-generator.d.ts.map +0 -1
- package/dist/engine/compose-generator.js.map +0 -1
- package/dist/engine/cost-estimator.d.ts.map +0 -1
- package/dist/engine/cost-estimator.js.map +0 -1
- package/dist/engine/env-analyzer.d.ts.map +0 -1
- package/dist/engine/env-analyzer.js.map +0 -1
- package/dist/engine/health-checker.d.ts.map +0 -1
- package/dist/engine/health-checker.js.map +0 -1
- package/dist/engine/index.d.ts.map +0 -1
- package/dist/engine/index.js.map +0 -1
- package/dist/engine/infra-generator.d.ts.map +0 -1
- package/dist/engine/infra-generator.js.map +0 -1
- package/dist/engine/migration-planner.d.ts.map +0 -1
- package/dist/engine/migration-planner.js.map +0 -1
- package/dist/engine/performance-profiler.d.ts.map +0 -1
- package/dist/engine/performance-profiler.js.map +0 -1
- package/dist/engine/plugin-loader.d.ts.map +0 -1
- package/dist/engine/plugin-loader.js.map +0 -1
- package/dist/engine/preferences.d.ts.map +0 -1
- package/dist/engine/preferences.js.map +0 -1
- package/dist/engine/rules-engine.d.ts.map +0 -1
- package/dist/engine/rules-engine.js.map +0 -1
- package/dist/engine/runtime-manager.d.ts.map +0 -1
- package/dist/engine/runtime-manager.js.map +0 -1
- package/dist/engine/scaffold-orchestrator.d.ts.map +0 -1
- package/dist/engine/scaffold-orchestrator.js.map +0 -1
- package/dist/engine/stack-detector.d.ts.map +0 -1
- package/dist/engine/stack-detector.js.map +0 -1
- package/dist/engine/stack-differ.d.ts.map +0 -1
- package/dist/engine/stack-differ.js.map +0 -1
- package/dist/engine/stack-engine.d.ts.map +0 -1
- package/dist/engine/stack-engine.js.map +0 -1
- package/dist/engine/stack-serializer.d.ts.map +0 -1
- package/dist/engine/stack-serializer.js.map +0 -1
- package/dist/engine/standards-linter.d.ts.map +0 -1
- package/dist/engine/standards-linter.js.map +0 -1
- package/dist/engine/tech-installer.d.ts.map +0 -1
- package/dist/engine/tech-installer.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/types/project.d.ts.map +0 -1
- package/dist/types/project.js.map +0 -1
- package/dist/types/stack.d.ts.map +0 -1
- package/dist/types/stack.js.map +0 -1
- package/dist/types/technology.d.ts.map +0 -1
- package/dist/types/technology.js.map +0 -1
- package/dist/types/template.d.ts.map +0 -1
- package/dist/types/template.js.map +0 -1
- package/dist/types/validation.d.ts.map +0 -1
- package/dist/types/validation.js.map +0 -1
- package/src/__tests__/compatibility-scorer.test.ts +0 -264
- package/src/__tests__/rules-engine.test.ts +0 -170
- package/src/__tests__/scaffold-orchestrator.test.ts +0 -161
- package/src/__tests__/stack-engine.test.ts +0 -328
- package/src/db/database.ts +0 -112
- package/src/db/index.ts +0 -1
- package/src/engine/compatibility-scorer.ts +0 -222
- package/src/engine/compose-generator.ts +0 -134
- package/src/engine/cost-estimator.ts +0 -498
- package/src/engine/env-analyzer.ts +0 -156
- package/src/engine/health-checker.ts +0 -421
- package/src/engine/index.ts +0 -17
- package/src/engine/infra-generator.ts +0 -837
- package/src/engine/migration-planner.ts +0 -496
- package/src/engine/performance-profiler.ts +0 -354
- package/src/engine/plugin-loader.ts +0 -216
- package/src/engine/preferences.ts +0 -85
- package/src/engine/rules-engine.ts +0 -204
- package/src/engine/runtime-manager.ts +0 -207
- package/src/engine/scaffold-orchestrator.ts +0 -1052
- package/src/engine/stack-detector.ts +0 -345
- package/src/engine/stack-differ.ts +0 -118
- package/src/engine/stack-engine.ts +0 -258
- package/src/engine/stack-serializer.ts +0 -95
- package/src/engine/standards-linter.ts +0 -210
- package/src/engine/tech-installer.ts +0 -650
- package/src/index.ts +0 -78
- package/src/types/index.ts +0 -10
- package/src/types/project.ts +0 -36
- package/src/types/stack.ts +0 -32
- package/src/types/technology.ts +0 -58
- package/src/types/template.ts +0 -37
- package/src/types/validation.ts +0 -22
- package/tsconfig.json +0 -10
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compatibility Scorer — Calculates a 0-100 score for technology combinations.
|
|
3
|
-
* Goes beyond binary compatible/incompatible to show nuanced pairing quality.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Technology } from "../types/index.js";
|
|
7
|
-
|
|
8
|
-
export interface CompatibilityResult {
|
|
9
|
-
score: number; // 0-100
|
|
10
|
-
grade: "S" | "A" | "B" | "C" | "D" | "F";
|
|
11
|
-
factors: CompatibilityFactor[];
|
|
12
|
-
recommendation: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface CompatibilityFactor {
|
|
16
|
-
label: string;
|
|
17
|
-
points: number;
|
|
18
|
-
description: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface StackScoreResult {
|
|
22
|
-
overall: number;
|
|
23
|
-
grade: string;
|
|
24
|
-
pairs: Array<{ a: string; b: string; score: number }>;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// ─── Complementary category pairs ─────────────────────
|
|
28
|
-
|
|
29
|
-
const COMPLEMENTARY_PAIRS: ReadonlySet<string> = new Set([
|
|
30
|
-
"frontend:backend",
|
|
31
|
-
"backend:frontend",
|
|
32
|
-
"database:orm",
|
|
33
|
-
"orm:database",
|
|
34
|
-
"frontend:styling",
|
|
35
|
-
"styling:frontend",
|
|
36
|
-
"frontend:orm",
|
|
37
|
-
"orm:frontend",
|
|
38
|
-
"backend:database",
|
|
39
|
-
"database:backend",
|
|
40
|
-
"runtime:frontend",
|
|
41
|
-
"frontend:runtime",
|
|
42
|
-
"runtime:backend",
|
|
43
|
-
"backend:runtime",
|
|
44
|
-
"backend:auth",
|
|
45
|
-
"auth:backend",
|
|
46
|
-
"frontend:auth",
|
|
47
|
-
"auth:frontend",
|
|
48
|
-
]);
|
|
49
|
-
|
|
50
|
-
// ─── Grade thresholds & recommendations ───────────────
|
|
51
|
-
|
|
52
|
-
function getGrade(score: number): "S" | "A" | "B" | "C" | "D" | "F" {
|
|
53
|
-
if (score >= 90) return "S";
|
|
54
|
-
if (score >= 75) return "A";
|
|
55
|
-
if (score >= 60) return "B";
|
|
56
|
-
if (score >= 45) return "C";
|
|
57
|
-
if (score >= 25) return "D";
|
|
58
|
-
return "F";
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const RECOMMENDATIONS: Record<"S" | "A" | "B" | "C" | "D" | "F", string> = {
|
|
62
|
-
S: "Excellent combination — these technologies are designed to work together.",
|
|
63
|
-
A: "Strong pairing with good ecosystem support.",
|
|
64
|
-
B: "Compatible — works well with minor configuration needed.",
|
|
65
|
-
C: "Neutral — no known issues but limited synergy.",
|
|
66
|
-
D: "Weak pairing — consider alternatives.",
|
|
67
|
-
F: "Incompatible — these technologies conflict.",
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
// ─── Runtime detection ────────────────────────────────
|
|
71
|
-
|
|
72
|
-
function getRuntime(tech: Technology): string | null {
|
|
73
|
-
if (tech.category === "runtime") return tech.id;
|
|
74
|
-
for (const req of tech.requires) {
|
|
75
|
-
if (["nodejs", "python", "go", "rust", "php", "bun", "deno"].includes(req)) {
|
|
76
|
-
return req;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// ─── Core scoring ─────────────────────────────────────
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Score the compatibility between two technologies (0-100).
|
|
86
|
-
*/
|
|
87
|
-
export function scoreCompatibility(techA: Technology, techB: Technology): CompatibilityResult {
|
|
88
|
-
const factors: CompatibilityFactor[] = [];
|
|
89
|
-
let score = 50; // neutral baseline
|
|
90
|
-
|
|
91
|
-
// +25 if suggested pairing (either direction)
|
|
92
|
-
const aSuggestsB = techA.suggestedWith.includes(techB.id);
|
|
93
|
-
const bSuggestsA = techB.suggestedWith.includes(techA.id);
|
|
94
|
-
if (aSuggestsB || bSuggestsA) {
|
|
95
|
-
factors.push({
|
|
96
|
-
label: "Suggested pairing",
|
|
97
|
-
points: 25,
|
|
98
|
-
description:
|
|
99
|
-
aSuggestsB && bSuggestsA
|
|
100
|
-
? `${techA.name} and ${techB.name} mutually recommend each other`
|
|
101
|
-
: aSuggestsB
|
|
102
|
-
? `${techA.name} suggests ${techB.name}`
|
|
103
|
-
: `${techB.name} suggests ${techA.name}`,
|
|
104
|
-
});
|
|
105
|
-
score += 25;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// +15 if shared runtime
|
|
109
|
-
const runtimeA = getRuntime(techA);
|
|
110
|
-
const runtimeB = getRuntime(techB);
|
|
111
|
-
if (runtimeA && runtimeB && runtimeA === runtimeB && techA.id !== techB.id) {
|
|
112
|
-
const runtimeName = runtimeA === "nodejs" ? "Node.js" : runtimeA;
|
|
113
|
-
factors.push({
|
|
114
|
-
label: "Shared runtime",
|
|
115
|
-
points: 15,
|
|
116
|
-
description: `Both use ${runtimeName}`,
|
|
117
|
-
});
|
|
118
|
-
score += 15;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// +10 if complementary categories
|
|
122
|
-
const catPair = `${techA.category}:${techB.category}`;
|
|
123
|
-
if (COMPLEMENTARY_PAIRS.has(catPair)) {
|
|
124
|
-
factors.push({
|
|
125
|
-
label: "Complementary categories",
|
|
126
|
-
points: 10,
|
|
127
|
-
description: `${techA.category} + ${techB.category}`,
|
|
128
|
-
});
|
|
129
|
-
score += 10;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// -50 if incompatible (either direction) — applied after positives, then clamp
|
|
133
|
-
const aIncompatB = techA.incompatibleWith.includes(techB.id);
|
|
134
|
-
const bIncompatA = techB.incompatibleWith.includes(techA.id);
|
|
135
|
-
if (aIncompatB || bIncompatA) {
|
|
136
|
-
factors.push({
|
|
137
|
-
label: "Incompatible",
|
|
138
|
-
points: -50,
|
|
139
|
-
description:
|
|
140
|
-
aIncompatB && bIncompatA
|
|
141
|
-
? `${techA.name} and ${techB.name} are mutually incompatible`
|
|
142
|
-
: aIncompatB
|
|
143
|
-
? `${techA.name} lists ${techB.name} as incompatible`
|
|
144
|
-
: `${techB.name} lists ${techA.name} as incompatible`,
|
|
145
|
-
});
|
|
146
|
-
score -= 50;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// -15 if same category AND same runtime (competing technologies)
|
|
150
|
-
if (
|
|
151
|
-
techA.category === techB.category &&
|
|
152
|
-
techA.id !== techB.id &&
|
|
153
|
-
runtimeA &&
|
|
154
|
-
runtimeB &&
|
|
155
|
-
runtimeA === runtimeB
|
|
156
|
-
) {
|
|
157
|
-
factors.push({
|
|
158
|
-
label: "Same category and runtime",
|
|
159
|
-
points: -15,
|
|
160
|
-
description: `Both are ${techA.category} technologies for ${runtimeA === "nodejs" ? "Node.js" : runtimeA}`,
|
|
161
|
-
});
|
|
162
|
-
score -= 15;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// -5 if same default port (minor conflict)
|
|
166
|
-
if (
|
|
167
|
-
techA.defaultPort &&
|
|
168
|
-
techB.defaultPort &&
|
|
169
|
-
techA.defaultPort === techB.defaultPort &&
|
|
170
|
-
techA.id !== techB.id
|
|
171
|
-
) {
|
|
172
|
-
factors.push({
|
|
173
|
-
label: "Port conflict",
|
|
174
|
-
points: -5,
|
|
175
|
-
description: `Both default to port ${techA.defaultPort}`,
|
|
176
|
-
});
|
|
177
|
-
score -= 5;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Clamp
|
|
181
|
-
score = Math.max(0, Math.min(100, score));
|
|
182
|
-
|
|
183
|
-
const grade = getGrade(score);
|
|
184
|
-
|
|
185
|
-
return {
|
|
186
|
-
score,
|
|
187
|
-
grade,
|
|
188
|
-
factors,
|
|
189
|
-
recommendation: RECOMMENDATIONS[grade],
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Score an entire stack by evaluating all unique pairs.
|
|
195
|
-
*/
|
|
196
|
-
export function scoreStack(technologies: Technology[]): StackScoreResult {
|
|
197
|
-
if (technologies.length < 2) {
|
|
198
|
-
return { overall: 100, grade: "S", pairs: [] };
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const pairs: Array<{ a: string; b: string; score: number }> = [];
|
|
202
|
-
|
|
203
|
-
for (let i = 0; i < technologies.length; i++) {
|
|
204
|
-
for (let j = i + 1; j < technologies.length; j++) {
|
|
205
|
-
const result = scoreCompatibility(technologies[i], technologies[j]);
|
|
206
|
-
pairs.push({
|
|
207
|
-
a: technologies[i].id,
|
|
208
|
-
b: technologies[j].id,
|
|
209
|
-
score: result.score,
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const overall =
|
|
215
|
-
pairs.length > 0 ? Math.round(pairs.reduce((sum, p) => sum + p.score, 0) / pairs.length) : 100;
|
|
216
|
-
|
|
217
|
-
return {
|
|
218
|
-
overall,
|
|
219
|
-
grade: getGrade(overall),
|
|
220
|
-
pairs,
|
|
221
|
-
};
|
|
222
|
-
}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compose Generator — Pure function that generates docker-compose.yml content.
|
|
3
|
-
* No disk I/O — returns structured data for preview or writing.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface ComposePreviewResult {
|
|
7
|
-
yaml: string;
|
|
8
|
-
services: string[];
|
|
9
|
-
ports: Record<string, number>;
|
|
10
|
-
volumes: string[];
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface ComposeTechnology {
|
|
14
|
-
id: string;
|
|
15
|
-
name: string;
|
|
16
|
-
category?: string;
|
|
17
|
-
dockerImage?: string;
|
|
18
|
-
defaultPort?: number;
|
|
19
|
-
envVars?: Record<string, string>;
|
|
20
|
-
healthCheck?: {
|
|
21
|
-
endpoint?: string;
|
|
22
|
-
command?: string;
|
|
23
|
-
interval?: string;
|
|
24
|
-
timeout?: string;
|
|
25
|
-
retries?: number;
|
|
26
|
-
};
|
|
27
|
-
port?: number; // Override port from stack definition
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const DATA_MOUNTS: Record<string, string> = {
|
|
31
|
-
postgresql: "/var/lib/postgresql/data",
|
|
32
|
-
mysql: "/var/lib/mysql",
|
|
33
|
-
mongodb: "/data/db",
|
|
34
|
-
redis: "/data",
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Generate a docker-compose.yml preview from a list of technologies.
|
|
39
|
-
* Only includes technologies that have a `dockerImage`.
|
|
40
|
-
*/
|
|
41
|
-
export function generateComposePreview(
|
|
42
|
-
technologies: ComposeTechnology[],
|
|
43
|
-
projectName: string,
|
|
44
|
-
): ComposePreviewResult {
|
|
45
|
-
const services: string[] = [];
|
|
46
|
-
const ports: Record<string, number> = {};
|
|
47
|
-
const volumes: string[] = [];
|
|
48
|
-
const lines: string[] = ["services:"];
|
|
49
|
-
|
|
50
|
-
const networkName = `${projectName.toLowerCase().replace(/[^a-z0-9-]/g, "-")}_net`;
|
|
51
|
-
|
|
52
|
-
for (const tech of technologies) {
|
|
53
|
-
if (!tech.dockerImage) continue;
|
|
54
|
-
|
|
55
|
-
services.push(tech.id);
|
|
56
|
-
const port = tech.port ?? tech.defaultPort;
|
|
57
|
-
|
|
58
|
-
lines.push(` ${tech.id}:`);
|
|
59
|
-
lines.push(` image: ${tech.dockerImage}`);
|
|
60
|
-
lines.push(" restart: unless-stopped");
|
|
61
|
-
|
|
62
|
-
// Ports
|
|
63
|
-
if (port) {
|
|
64
|
-
lines.push(" ports:");
|
|
65
|
-
lines.push(` - "${port}:${port}"`);
|
|
66
|
-
ports[tech.id] = port;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Environment variables
|
|
70
|
-
const envVars = tech.envVars ? Object.entries(tech.envVars) : [];
|
|
71
|
-
if (envVars.length > 0) {
|
|
72
|
-
lines.push(" environment:");
|
|
73
|
-
for (const [key, value] of envVars) {
|
|
74
|
-
lines.push(` ${key}: "${value}"`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Health check
|
|
79
|
-
if (tech.healthCheck) {
|
|
80
|
-
lines.push(" healthcheck:");
|
|
81
|
-
if (tech.healthCheck.command) {
|
|
82
|
-
lines.push(` test: ["CMD-SHELL", "${tech.healthCheck.command}"]`);
|
|
83
|
-
} else if (tech.healthCheck.endpoint) {
|
|
84
|
-
lines.push(` test: ["CMD-SHELL", "curl -f ${tech.healthCheck.endpoint} || exit 1"]`);
|
|
85
|
-
}
|
|
86
|
-
if (tech.healthCheck.interval) {
|
|
87
|
-
lines.push(` interval: ${tech.healthCheck.interval}`);
|
|
88
|
-
}
|
|
89
|
-
if (tech.healthCheck.timeout) {
|
|
90
|
-
lines.push(` timeout: ${tech.healthCheck.timeout}`);
|
|
91
|
-
}
|
|
92
|
-
if (tech.healthCheck.retries) {
|
|
93
|
-
lines.push(` retries: ${tech.healthCheck.retries}`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Volumes for databases
|
|
98
|
-
const mountPath = DATA_MOUNTS[tech.id];
|
|
99
|
-
if (mountPath && tech.category === "database") {
|
|
100
|
-
const volName = `${tech.id}_data`;
|
|
101
|
-
lines.push(" volumes:");
|
|
102
|
-
lines.push(` - ${volName}:${mountPath}`);
|
|
103
|
-
volumes.push(volName);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Network
|
|
107
|
-
lines.push(" networks:");
|
|
108
|
-
lines.push(` - ${networkName}`);
|
|
109
|
-
|
|
110
|
-
lines.push("");
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Named volumes
|
|
114
|
-
if (volumes.length > 0) {
|
|
115
|
-
lines.push("volumes:");
|
|
116
|
-
for (const vol of volumes) {
|
|
117
|
-
lines.push(` ${vol}:`);
|
|
118
|
-
}
|
|
119
|
-
lines.push("");
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Network
|
|
123
|
-
lines.push("networks:");
|
|
124
|
-
lines.push(` ${networkName}:`);
|
|
125
|
-
lines.push(" driver: bridge");
|
|
126
|
-
lines.push("");
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
yaml: lines.join("\n"),
|
|
130
|
-
services,
|
|
131
|
-
ports,
|
|
132
|
-
volumes,
|
|
133
|
-
};
|
|
134
|
-
}
|