vyft 0.3.0-alpha → 0.4.1-alpha

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.
Files changed (184) hide show
  1. package/LICENSE +191 -21
  2. package/README.md +3 -49
  3. package/dist/commands/context/add.d.ts +4 -0
  4. package/dist/commands/context/add.d.ts.map +1 -0
  5. package/dist/commands/context/add.js +98 -0
  6. package/dist/commands/context/add.js.map +1 -0
  7. package/dist/commands/context/index.d.ts +4 -0
  8. package/dist/commands/context/index.d.ts.map +1 -0
  9. package/dist/commands/context/index.js +12 -0
  10. package/dist/commands/context/index.js.map +1 -0
  11. package/dist/commands/context/list.d.ts +4 -0
  12. package/dist/commands/context/list.d.ts.map +1 -0
  13. package/dist/commands/context/list.js +25 -0
  14. package/dist/commands/context/list.js.map +1 -0
  15. package/dist/commands/context/remove.d.ts +4 -0
  16. package/dist/commands/context/remove.d.ts.map +1 -0
  17. package/dist/commands/context/remove.js +36 -0
  18. package/dist/commands/context/remove.js.map +1 -0
  19. package/dist/commands/context/use.d.ts +4 -0
  20. package/dist/commands/context/use.d.ts.map +1 -0
  21. package/dist/commands/context/use.js +32 -0
  22. package/dist/commands/context/use.js.map +1 -0
  23. package/dist/commands/deploy.d.ts +4 -0
  24. package/dist/commands/deploy.d.ts.map +1 -0
  25. package/dist/commands/deploy.js +55 -0
  26. package/dist/commands/deploy.js.map +1 -0
  27. package/dist/commands/destroy.d.ts +4 -0
  28. package/dist/commands/destroy.d.ts.map +1 -0
  29. package/dist/commands/destroy.js +70 -0
  30. package/dist/commands/destroy.js.map +1 -0
  31. package/dist/commands/diff.d.ts +4 -0
  32. package/dist/commands/diff.d.ts.map +1 -0
  33. package/dist/commands/diff.js +52 -0
  34. package/dist/commands/diff.js.map +1 -0
  35. package/dist/commands/init.d.ts +4 -0
  36. package/dist/commands/init.d.ts.map +1 -0
  37. package/dist/commands/init.js +92 -0
  38. package/dist/commands/init.js.map +1 -0
  39. package/dist/commands/local/detect.d.ts +7 -0
  40. package/dist/commands/local/detect.d.ts.map +1 -0
  41. package/dist/commands/local/detect.js +146 -0
  42. package/dist/commands/local/detect.js.map +1 -0
  43. package/dist/commands/local/dev.d.ts +4 -0
  44. package/dist/commands/local/dev.d.ts.map +1 -0
  45. package/dist/commands/local/dev.js +339 -0
  46. package/dist/commands/local/dev.js.map +1 -0
  47. package/dist/commands/local/down.d.ts +4 -0
  48. package/dist/commands/local/down.d.ts.map +1 -0
  49. package/dist/commands/local/down.js +61 -0
  50. package/dist/commands/local/down.js.map +1 -0
  51. package/dist/commands/local/index.d.ts +4 -0
  52. package/dist/commands/local/index.d.ts.map +1 -0
  53. package/dist/commands/local/index.js +12 -0
  54. package/dist/commands/local/index.js.map +1 -0
  55. package/dist/commands/local/reset.d.ts +4 -0
  56. package/dist/commands/local/reset.d.ts.map +1 -0
  57. package/dist/commands/local/reset.js +67 -0
  58. package/dist/commands/local/reset.js.map +1 -0
  59. package/dist/commands/local/up.d.ts +4 -0
  60. package/dist/commands/local/up.d.ts.map +1 -0
  61. package/dist/commands/local/up.js +58 -0
  62. package/dist/commands/local/up.js.map +1 -0
  63. package/dist/commands/refresh.d.ts +4 -0
  64. package/dist/commands/refresh.d.ts.map +1 -0
  65. package/dist/commands/refresh.js +39 -0
  66. package/dist/commands/refresh.js.map +1 -0
  67. package/dist/config.d.ts +8 -0
  68. package/dist/config.d.ts.map +1 -0
  69. package/dist/config.js +69 -0
  70. package/dist/config.js.map +1 -0
  71. package/dist/contexts.d.ts +21 -0
  72. package/dist/contexts.d.ts.map +1 -0
  73. package/dist/contexts.js +72 -0
  74. package/dist/contexts.js.map +1 -0
  75. package/dist/index.d.ts +2 -8
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +23 -6
  78. package/dist/index.js.map +1 -0
  79. package/dist/lib.d.ts +7 -0
  80. package/dist/lib.d.ts.map +1 -0
  81. package/dist/lib.js +6 -0
  82. package/dist/lib.js.map +1 -0
  83. package/dist/providers.d.ts +9 -0
  84. package/dist/providers.d.ts.map +1 -0
  85. package/dist/providers.js +41 -0
  86. package/dist/providers.js.map +1 -0
  87. package/dist/runtime.d.ts +18 -9
  88. package/dist/runtime.d.ts.map +1 -0
  89. package/dist/runtime.js +154 -0
  90. package/dist/runtime.js.map +1 -0
  91. package/dist/runtime.test.d.ts +2 -0
  92. package/dist/runtime.test.d.ts.map +1 -0
  93. package/dist/runtime.test.js +119 -0
  94. package/dist/runtime.test.js.map +1 -0
  95. package/dist/utils/fs.d.ts +4 -0
  96. package/dist/utils/fs.d.ts.map +1 -0
  97. package/dist/utils/fs.js +33 -0
  98. package/dist/utils/fs.js.map +1 -0
  99. package/dist/utils/pm.d.ts +3 -0
  100. package/dist/utils/pm.d.ts.map +1 -0
  101. package/dist/utils/pm.js +17 -0
  102. package/dist/utils/pm.js.map +1 -0
  103. package/dist/utils/prompts.d.ts +2 -0
  104. package/dist/utils/prompts.d.ts.map +1 -0
  105. package/dist/utils/prompts.js +6 -0
  106. package/dist/utils/prompts.js.map +1 -0
  107. package/dist/utils/templates.d.ts +3 -0
  108. package/dist/utils/templates.d.ts.map +1 -0
  109. package/dist/utils/templates.js +48 -0
  110. package/dist/utils/templates.js.map +1 -0
  111. package/package.json +31 -46
  112. package/templates/bun/index.ts +8 -0
  113. package/templates/bun/package.json +15 -0
  114. package/templates/bun/tsconfig.json +15 -0
  115. package/templates/bun/vyft.config.ts +3 -0
  116. package/dist/build.d.ts +0 -11
  117. package/dist/build.js +0 -39
  118. package/dist/cli.d.ts +0 -2
  119. package/dist/cli.js +0 -398
  120. package/dist/context.d.ts +0 -39
  121. package/dist/context.js +0 -101
  122. package/dist/docker.d.ts +0 -62
  123. package/dist/docker.js +0 -876
  124. package/dist/exec.d.ts +0 -2
  125. package/dist/exec.js +0 -28
  126. package/dist/init.d.ts +0 -1
  127. package/dist/init.js +0 -117
  128. package/dist/interpolate.d.ts +0 -13
  129. package/dist/interpolate.js +0 -19
  130. package/dist/logger.d.ts +0 -2
  131. package/dist/logger.js +0 -10
  132. package/dist/proxy.d.ts +0 -16
  133. package/dist/proxy.js +0 -0
  134. package/dist/resource.d.ts +0 -174
  135. package/dist/resource.js +0 -45
  136. package/dist/services/index.d.ts +0 -24
  137. package/dist/services/index.js +0 -20
  138. package/dist/services/minio.d.ts +0 -36
  139. package/dist/services/minio.js +0 -53
  140. package/dist/services/mongo.d.ts +0 -28
  141. package/dist/services/mongo.js +0 -45
  142. package/dist/services/mysql.d.ts +0 -28
  143. package/dist/services/mysql.js +0 -44
  144. package/dist/services/nats.d.ts +0 -26
  145. package/dist/services/nats.js +0 -38
  146. package/dist/services/postgres.d.ts +0 -28
  147. package/dist/services/postgres.js +0 -45
  148. package/dist/services/rabbitmq.d.ts +0 -28
  149. package/dist/services/rabbitmq.js +0 -44
  150. package/dist/services/redis.d.ts +0 -28
  151. package/dist/services/redis.js +0 -49
  152. package/dist/services/storage.d.ts +0 -39
  153. package/dist/services/storage.js +0 -94
  154. package/dist/swarm/factories.d.ts +0 -16
  155. package/dist/swarm/factories.js +0 -63
  156. package/dist/swarm/index.d.ts +0 -20
  157. package/dist/swarm/index.js +0 -5
  158. package/dist/swarm/proxy.d.ts +0 -24
  159. package/dist/swarm/proxy.js +0 -339
  160. package/dist/swarm/types.d.ts +0 -26
  161. package/dist/swarm/types.js +0 -0
  162. package/dist/symbols.d.ts +0 -13
  163. package/dist/symbols.js +0 -2
  164. package/templates/fullstack/apps/api/Dockerfile +0 -22
  165. package/templates/fullstack/apps/api/package.json +0 -26
  166. package/templates/fullstack/apps/api/src/auth.ts +0 -21
  167. package/templates/fullstack/apps/api/src/db.ts +0 -16
  168. package/templates/fullstack/apps/api/src/index.ts +0 -17
  169. package/templates/fullstack/apps/api/src/router.ts +0 -11
  170. package/templates/fullstack/apps/api/src/schema.ts +0 -11
  171. package/templates/fullstack/apps/api/tsconfig.json +0 -8
  172. package/templates/fullstack/apps/web/index.html +0 -12
  173. package/templates/fullstack/apps/web/package.json +0 -21
  174. package/templates/fullstack/apps/web/src/app.tsx +0 -8
  175. package/templates/fullstack/apps/web/src/main.tsx +0 -9
  176. package/templates/fullstack/apps/web/tsconfig.json +0 -7
  177. package/templates/fullstack/apps/web/vite.config.ts +0 -14
  178. package/templates/fullstack/compose.yaml +0 -14
  179. package/templates/fullstack/dockerignore +0 -7
  180. package/templates/fullstack/gitignore +0 -3
  181. package/templates/fullstack/package.json +0 -18
  182. package/templates/fullstack/pnpm-workspace.yaml +0 -2
  183. package/templates/fullstack/tsconfig.json +0 -11
  184. package/templates/fullstack/vyft.config.ts +0 -22
package/dist/cli.js DELETED
@@ -1,398 +0,0 @@
1
- #!/usr/bin/env node
2
- import { randomBytes } from "node:crypto";
3
- import { access, readFile } from "node:fs/promises";
4
- import path from "node:path";
5
- import { intro, log, outro } from "@clack/prompts";
6
- import { Command } from "commander";
7
- import pc from "picocolors";
8
- import { getCurrentContextName, listContexts, removeContext, resolveContext, saveContext, setCurrentContext, } from "./context.js";
9
- import { DockerClient } from "./docker.js";
10
- import { init } from "./init.js";
11
- import { logger } from "./logger.js";
12
- import { VYFT_RUNTIME } from "./symbols.js";
13
- const DEPLOY_ORDER = {
14
- secret: 0,
15
- volume: 1,
16
- service: 2,
17
- site: 3,
18
- };
19
- const DESTROY_ORDER = {
20
- site: 0,
21
- service: 1,
22
- volume: 2,
23
- secret: 3,
24
- };
25
- async function findProjectName(configPath) {
26
- let dir = path.dirname(configPath);
27
- while (dir !== path.dirname(dir)) {
28
- try {
29
- const pkgPath = path.join(dir, "package.json");
30
- const content = await readFile(pkgPath, "utf-8");
31
- const pkg = JSON.parse(content);
32
- if (pkg.name) {
33
- return pkg.name;
34
- }
35
- }
36
- catch {
37
- // No package.json here, keep walking up
38
- }
39
- dir = path.dirname(dir);
40
- }
41
- throw new Error("Could not find package.json with a name field");
42
- }
43
- function isResource(value) {
44
- return (typeof value === "object" &&
45
- value !== null &&
46
- "type" in value &&
47
- "id" in value &&
48
- typeof value.type === "string" &&
49
- typeof value.id === "string");
50
- }
51
- function collectResources(exports) {
52
- const seen = new Set();
53
- const resources = [];
54
- for (const value of Object.values(exports)) {
55
- if (isResource(value)) {
56
- if (!seen.has(value.id)) {
57
- seen.add(value.id);
58
- resources.push(value);
59
- }
60
- }
61
- else if (typeof value === "object" && value !== null) {
62
- for (const nested of Object.values(value)) {
63
- if (isResource(nested) && !seen.has(nested.id)) {
64
- seen.add(nested.id);
65
- resources.push(nested);
66
- }
67
- }
68
- }
69
- }
70
- return resources;
71
- }
72
- function topoSortServices(services) {
73
- const byId = new Map(services.map((s) => [s.id, s]));
74
- const visited = new Set();
75
- const result = [];
76
- function visit(svc) {
77
- if (visited.has(svc.id))
78
- return;
79
- visited.add(svc.id);
80
- for (const dep of svc.config.dependsOn ?? []) {
81
- const depSvc = byId.get(dep.id);
82
- if (depSvc)
83
- visit(depSvc);
84
- }
85
- result.push(svc);
86
- }
87
- for (const svc of services)
88
- visit(svc);
89
- return result;
90
- }
91
- function hasRuntime(value) {
92
- return (typeof value === "object" &&
93
- value !== null &&
94
- VYFT_RUNTIME in value);
95
- }
96
- function getContextHost() {
97
- const ctx = resolveContext(program.opts().context);
98
- return ctx?.host;
99
- }
100
- function createRuntime(resources, project, sessionLogger) {
101
- const host = getContextHost();
102
- const ref = resources.find((r) => hasRuntime(r));
103
- if (ref && hasRuntime(ref)) {
104
- const meta = ref[VYFT_RUNTIME];
105
- switch (meta.name) {
106
- case "swarm":
107
- return new DockerClient(project, { host, parentLogger: sessionLogger });
108
- default:
109
- throw new Error(`Unknown runtime: ${meta.name}`);
110
- }
111
- }
112
- return new DockerClient(project, { host, parentLogger: sessionLogger });
113
- }
114
- async function deploy(configFile, verbose) {
115
- const sessionId = randomBytes(4).toString("hex");
116
- const sessionLog = logger.child({ sessionId, command: "deploy" });
117
- const start = performance.now();
118
- const project = await findProjectName(configFile);
119
- process.env.VYFT_PROJECT = project;
120
- intro(`Deploying ${project}`);
121
- const config = await import(configFile);
122
- const resources = collectResources(config);
123
- if (resources.length === 0) {
124
- log.warn("No resources found");
125
- outro();
126
- return;
127
- }
128
- sessionLog.info({ project, resourceCount: resources.length }, "deploy started");
129
- resources.sort((a, b) => DEPLOY_ORDER[a.type] - DEPLOY_ORDER[b.type]);
130
- // Topologically sort services so dependencies deploy first
131
- const services = resources.filter((r) => r.type === "service");
132
- const nonServices = resources.filter((r) => r.type !== "service");
133
- const sorted = topoSortServices(services);
134
- const ordered = [...nonServices, ...sorted];
135
- // Collect which service IDs have dependents waiting on them
136
- const depTargets = new Set();
137
- for (const svc of services) {
138
- for (const dep of svc.config.dependsOn ?? []) {
139
- depTargets.add(dep.id);
140
- }
141
- }
142
- const docker = createRuntime(resources, project, sessionLog);
143
- docker.verbose = verbose;
144
- await docker.ensureInfrastructure();
145
- const currentResources = await docker.listManagedResources();
146
- let created = 0;
147
- let skipped = 0;
148
- for (const resource of ordered) {
149
- const exists = await docker.exists(resource);
150
- if (exists && resource.type !== "service" && resource.type !== "site") {
151
- log.success(resource.id);
152
- skipped++;
153
- }
154
- else {
155
- await docker.create(resource);
156
- created++;
157
- }
158
- // Wait for services that other services depend on
159
- if (resource.type === "service" && depTargets.has(resource.id)) {
160
- await docker.waitForHealthy(resource.id);
161
- }
162
- }
163
- const desiredIds = new Set(resources.map((r) => r.id));
164
- // Keep derived secrets whose parent service is still desired
165
- for (const r of currentResources) {
166
- if (r.derived && r.parentService && desiredIds.has(r.parentService)) {
167
- desiredIds.add(r.id);
168
- }
169
- }
170
- const toRemove = currentResources.filter((r) => !desiredIds.has(r.id));
171
- let removed = 0;
172
- if (toRemove.length > 0) {
173
- toRemove.sort((a, b) => DESTROY_ORDER[a.type] - DESTROY_ORDER[b.type]);
174
- for (const { id, type } of toRemove) {
175
- const resource = { id, type };
176
- if (await docker.exists(resource)) {
177
- await docker.remove(resource);
178
- removed++;
179
- }
180
- }
181
- }
182
- const durationMs = Math.round(performance.now() - start);
183
- sessionLog.info({ project, created, removed, skipped, durationMs }, "deploy completed");
184
- outro("Deploy complete");
185
- }
186
- async function destroy(searchDir, host) {
187
- const sessionId = randomBytes(4).toString("hex");
188
- const sessionLog = logger.child({ sessionId, command: "destroy" });
189
- const start = performance.now();
190
- const project = await findProjectName(path.join(searchDir, "dummy"));
191
- intro(`Destroying ${project}`);
192
- const docker = new DockerClient(project, {
193
- host,
194
- parentLogger: sessionLog,
195
- });
196
- const currentResources = await docker.listManagedResources();
197
- if (currentResources.length === 0) {
198
- log.warn("No resources found");
199
- outro();
200
- return;
201
- }
202
- sessionLog.info({ project, resourceCount: currentResources.length }, "destroy started");
203
- const sorted = [...currentResources].sort((a, b) => DESTROY_ORDER[a.type] - DESTROY_ORDER[b.type]);
204
- let removed = 0;
205
- for (const { id, type } of sorted) {
206
- const resource = { id, type };
207
- if (await docker.exists(resource)) {
208
- await docker.remove(resource);
209
- removed++;
210
- }
211
- }
212
- await docker.removeProjectNetwork();
213
- const durationMs = Math.round(performance.now() - start);
214
- sessionLog.info({ project, removed, durationMs }, "destroy completed");
215
- outro("Destroy complete");
216
- }
217
- const program = new Command();
218
- program
219
- .name("vyft")
220
- .description("Deploy apps to Docker Swarm with TypeScript")
221
- .version("0.1.0")
222
- .option("--context <name>", "override active context for this invocation");
223
- program
224
- .command("init")
225
- .description("Create a new project")
226
- .argument("[directory]", "directory to create the project in")
227
- .action(async (directory) => {
228
- await init(directory);
229
- });
230
- program
231
- .command("deploy")
232
- .description("Deploy resources from a config file")
233
- .argument("[config-file]", "path to config file", "vyft.config.ts")
234
- .option("--verbose", "show build output", false)
235
- .action(async (configFile, opts) => {
236
- const absolutePath = path.resolve(process.cwd(), configFile);
237
- if (configFile === "vyft.config.ts") {
238
- try {
239
- await access(absolutePath);
240
- }
241
- catch {
242
- program.error("No config file specified and vyft.config.ts not found");
243
- }
244
- }
245
- try {
246
- await deploy(absolutePath, opts.verbose);
247
- }
248
- catch (err) {
249
- logger.fatal({ err }, "deploy failed");
250
- throw err;
251
- }
252
- });
253
- const proxy = program.command("proxy").description("Manage the proxy");
254
- proxy
255
- .command("logs")
256
- .description("View proxy request logs")
257
- .option("-f, --follow", "stream logs continuously", false)
258
- .option("--tail <n>", "number of lines to show", "100")
259
- .action(async (opts) => {
260
- const project = await findProjectName(path.join(process.cwd(), "package.json"));
261
- const docker = new DockerClient(project, { host: getContextHost() });
262
- await docker.proxy.logs({
263
- follow: opts.follow,
264
- tail: parseInt(opts.tail, 10),
265
- });
266
- });
267
- program
268
- .command("logs")
269
- .description("View service logs")
270
- .argument("[services...]", "service names to filter (short names without project prefix)")
271
- .option("-f, --follow", "stream logs continuously", false)
272
- .option("--tail <n>", "number of lines to show", "100")
273
- .action(async (services, opts) => {
274
- const project = await findProjectName(path.join(process.cwd(), "package.json"));
275
- const docker = new DockerClient(project, { host: getContextHost() });
276
- // Support comma-separated names: "api,web" -> ["api", "web"]
277
- const parsed = services.flatMap((s) => s.split(","));
278
- const logs = docker.serviceLogs({
279
- follow: opts.follow,
280
- tail: parseInt(opts.tail, 10),
281
- services: parsed.length > 0 ? parsed : undefined,
282
- });
283
- const colors = [
284
- pc.cyan,
285
- pc.magenta,
286
- pc.green,
287
- pc.yellow,
288
- pc.blue,
289
- pc.red,
290
- ];
291
- const colorMap = new Map();
292
- let colorIdx = 0;
293
- for await (const entry of logs) {
294
- if (!colorMap.has(entry.service)) {
295
- colorMap.set(entry.service, colors[colorIdx++ % colors.length]);
296
- }
297
- const color = colorMap.get(entry.service);
298
- const prefix = parsed.length === 1
299
- ? ""
300
- : `${color(pc.bold(entry.service))} ${pc.dim("|")} `;
301
- const line = entry.text.endsWith("\n") ? entry.text : `${entry.text}\n`;
302
- const dest = entry.stream === "stderr" ? process.stderr : process.stdout;
303
- dest.write(`${prefix}${line}`);
304
- }
305
- });
306
- program
307
- .command("destroy")
308
- .description("Destroy all deployed resources")
309
- .argument("[config-file]", "path to config file (used to locate project)")
310
- .action(async (configFile) => {
311
- const absolutePath = configFile
312
- ? path.resolve(process.cwd(), configFile)
313
- : process.cwd();
314
- try {
315
- await destroy(absolutePath, getContextHost());
316
- }
317
- catch (err) {
318
- logger.fatal({ err }, "destroy failed");
319
- throw err;
320
- }
321
- });
322
- const context = program
323
- .command("context")
324
- .description("Manage deployment contexts");
325
- context
326
- .command("create")
327
- .description("Create a new context")
328
- .argument("<name>", "context name")
329
- .requiredOption("--host <endpoint>", "Docker endpoint (e.g. ssh://root@1.2.3.4)")
330
- .option("--runtime <rt>", "runtime backend", "swarm")
331
- .option("--description <text>", "optional description")
332
- .action((name, opts) => {
333
- saveContext({
334
- name,
335
- host: opts.host,
336
- runtime: opts.runtime,
337
- description: opts.description,
338
- });
339
- console.log(`Context "${name}" created`);
340
- });
341
- context
342
- .command("ls")
343
- .description("List all contexts")
344
- .action(() => {
345
- const contexts = listContexts();
346
- if (contexts.length === 0) {
347
- console.log("No contexts configured. Create one with: vyft context create <name> --host <endpoint>");
348
- return;
349
- }
350
- const current = getCurrentContextName();
351
- for (const ctx of contexts) {
352
- const marker = ctx.name === current ? "* " : " ";
353
- const desc = ctx.description ? ` - ${ctx.description}` : "";
354
- const host = ctx.host ? ` (${ctx.host})` : "";
355
- console.log(`${marker}${ctx.name}${host}${desc}`);
356
- }
357
- });
358
- context
359
- .command("show")
360
- .description("Print current context name")
361
- .action(() => {
362
- const name = getCurrentContextName();
363
- if (!name) {
364
- console.log("No context set");
365
- }
366
- else {
367
- console.log(name);
368
- }
369
- });
370
- context
371
- .command("use")
372
- .description("Set the active context")
373
- .argument("<name>", "context name")
374
- .action((name) => {
375
- setCurrentContext(name);
376
- console.log(`Switched to context "${name}"`);
377
- });
378
- context
379
- .command("rm")
380
- .description("Remove a context")
381
- .argument("<name>", "context name")
382
- .action((name) => {
383
- removeContext(name);
384
- console.log(`Context "${name}" removed`);
385
- });
386
- context
387
- .command("inspect")
388
- .description("Print context as JSON")
389
- .argument("[name]", "context name (defaults to current)")
390
- .action((name) => {
391
- const ctx = resolveContext(name);
392
- if (!ctx) {
393
- console.log("No context set");
394
- return;
395
- }
396
- console.log(JSON.stringify(ctx, null, 2));
397
- });
398
- await program.parseAsync();
package/dist/context.d.ts DELETED
@@ -1,39 +0,0 @@
1
- /** A named deployment target storing a host endpoint and runtime backend. */
2
- export interface VyftContext {
3
- /** Unique context name (e.g. `"prod"`, `"staging"`). */
4
- name: string;
5
- /** Docker endpoint (e.g. `"ssh://root@1.2.3.4"`). `undefined` means local socket. */
6
- host?: string;
7
- /** Runtime backend. Currently only `"swarm"`. */
8
- runtime: string;
9
- /** Optional human-readable description. */
10
- description?: string;
11
- }
12
- /** Returns the vyft config directory, creating it if necessary. Respects `$XDG_CONFIG_HOME`. */
13
- export declare function configDir(): string;
14
- /** Load a context by name. Returns `undefined` if no matching file exists. */
15
- export declare function getContext(name: string): VyftContext | undefined;
16
- /** List all explicitly created contexts. */
17
- export declare function listContexts(): VyftContext[];
18
- /**
19
- * Persist a context to disk.
20
- */
21
- export declare function saveContext(ctx: VyftContext): void;
22
- /**
23
- * Delete a context from disk.
24
- * @throws If the context is currently active or doesn't exist.
25
- */
26
- export declare function removeContext(name: string): void;
27
- /** Read the active context name from `config.json`. Returns `undefined` when no context is set. */
28
- export declare function getCurrentContextName(): string | undefined;
29
- /**
30
- * Set the active context.
31
- * @throws If the named context doesn't exist.
32
- */
33
- export declare function setCurrentContext(name: string): void;
34
- /**
35
- * Resolve a context by name. If no override is given, uses the current active context.
36
- * Returns `undefined` when no context is configured and no override is provided.
37
- * @throws If a named context doesn't exist.
38
- */
39
- export declare function resolveContext(override?: string): VyftContext | undefined;
package/dist/context.js DELETED
@@ -1,101 +0,0 @@
1
- import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
2
- import os from "node:os";
3
- import path from "node:path";
4
- /** Returns the vyft config directory, creating it if necessary. Respects `$XDG_CONFIG_HOME`. */
5
- export function configDir() {
6
- const xdg = process.env.XDG_CONFIG_HOME;
7
- const dir = xdg
8
- ? path.join(xdg, "vyft")
9
- : path.join(os.homedir(), ".config", "vyft");
10
- mkdirSync(path.join(dir, "contexts"), { recursive: true });
11
- return dir;
12
- }
13
- /** Load a context by name. Returns `undefined` if no matching file exists. */
14
- export function getContext(name) {
15
- const file = path.join(configDir(), "contexts", `${name}.json`);
16
- if (!existsSync(file))
17
- return undefined;
18
- return JSON.parse(readFileSync(file, "utf-8"));
19
- }
20
- /** List all explicitly created contexts. */
21
- export function listContexts() {
22
- const dir = configDir();
23
- const contextsDir = path.join(dir, "contexts");
24
- const results = [];
25
- if (!existsSync(contextsDir))
26
- return results;
27
- for (const file of readdirSync(contextsDir)) {
28
- if (!file.endsWith(".json"))
29
- continue;
30
- try {
31
- const ctx = JSON.parse(readFileSync(path.join(contextsDir, file), "utf-8"));
32
- results.push(ctx);
33
- }
34
- catch {
35
- // skip malformed files
36
- }
37
- }
38
- return results;
39
- }
40
- /**
41
- * Persist a context to disk.
42
- */
43
- export function saveContext(ctx) {
44
- const file = path.join(configDir(), "contexts", `${ctx.name}.json`);
45
- writeFileSync(file, `${JSON.stringify(ctx, null, 2)}\n`);
46
- }
47
- /**
48
- * Delete a context from disk.
49
- * @throws If the context is currently active or doesn't exist.
50
- */
51
- export function removeContext(name) {
52
- const current = getCurrentContextName();
53
- if (name === current) {
54
- throw new Error(`Cannot remove "${name}" because it is the active context. Switch first with: vyft context use <other>`);
55
- }
56
- const file = path.join(configDir(), "contexts", `${name}.json`);
57
- if (!existsSync(file)) {
58
- throw new Error(`Context "${name}" does not exist`);
59
- }
60
- rmSync(file);
61
- }
62
- /** Read the active context name from `config.json`. Returns `undefined` when no context is set. */
63
- export function getCurrentContextName() {
64
- const file = path.join(configDir(), "config.json");
65
- if (!existsSync(file))
66
- return undefined;
67
- try {
68
- const config = JSON.parse(readFileSync(file, "utf-8"));
69
- return config.currentContext;
70
- }
71
- catch {
72
- return undefined;
73
- }
74
- }
75
- /**
76
- * Set the active context.
77
- * @throws If the named context doesn't exist.
78
- */
79
- export function setCurrentContext(name) {
80
- const ctx = getContext(name);
81
- if (!ctx)
82
- throw new Error(`Context "${name}" does not exist`);
83
- const file = path.join(configDir(), "config.json");
84
- const config = { currentContext: name };
85
- writeFileSync(file, `${JSON.stringify(config, null, 2)}\n`);
86
- }
87
- /**
88
- * Resolve a context by name. If no override is given, uses the current active context.
89
- * Returns `undefined` when no context is configured and no override is provided.
90
- * @throws If a named context doesn't exist.
91
- */
92
- export function resolveContext(override) {
93
- const name = override ?? getCurrentContextName();
94
- if (!name)
95
- return undefined;
96
- const ctx = getContext(name);
97
- if (!ctx) {
98
- throw new Error(`Context "${name}" not found`);
99
- }
100
- return ctx;
101
- }
package/dist/docker.d.ts DELETED
@@ -1,62 +0,0 @@
1
- import type { Logger } from "pino";
2
- import type { ReverseProxy } from "./proxy.js";
3
- import type { Resource, ResourceType } from "./resource.js";
4
- import type { Runtime } from "./runtime.js";
5
- export declare function parseRoute(route: string): {
6
- host: string;
7
- path?: string;
8
- };
9
- export interface ManagedResource {
10
- id: string;
11
- type: ResourceType;
12
- route?: string;
13
- derived?: boolean;
14
- parentService?: string;
15
- }
16
- export declare class DockerClient implements Runtime {
17
- private docker;
18
- private localDocker;
19
- private isRemote;
20
- private project;
21
- private secretValues;
22
- private log;
23
- proxy: ReverseProxy;
24
- verbose: boolean;
25
- constructor(project: string, opts?: {
26
- host?: string;
27
- parentLogger?: Logger;
28
- });
29
- private ensureNetwork;
30
- ensureInfrastructure(): Promise<void>;
31
- listManagedResources(): Promise<ManagedResource[]>;
32
- create(resource: Resource): Promise<void>;
33
- exists(resource: Resource): Promise<boolean>;
34
- remove(resource: Resource): Promise<void>;
35
- private createVolume;
36
- private volumeExists;
37
- private removeVolume;
38
- private createSecret;
39
- private secretExists;
40
- private removeSecret;
41
- private storeSecretData;
42
- private lookupSecretId;
43
- private createDerivedSecret;
44
- private resolveEnv;
45
- private createService;
46
- private serviceExists;
47
- waitForHealthy(id: string, timeoutMs?: number): Promise<void>;
48
- private removeService;
49
- private pullImage;
50
- private createStatic;
51
- private removeStatic;
52
- serviceLogs(options: {
53
- follow?: boolean;
54
- tail?: number;
55
- services?: string[];
56
- }): AsyncGenerator<{
57
- service: string;
58
- stream: "stdout" | "stderr";
59
- text: string;
60
- }>;
61
- removeProjectNetwork(): Promise<void>;
62
- }