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
@@ -0,0 +1,119 @@
1
+ import assert from "node:assert/strict";
2
+ import fs from "node:fs/promises";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { afterEach, describe, it } from "node:test";
6
+ import { resolvePassphrase } from "./runtime.js";
7
+ function configPath(project) {
8
+ return path.join(os.homedir(), ".config", "vyft", project, "passphrase");
9
+ }
10
+ async function cleanupProject(project) {
11
+ try {
12
+ await fs.rm(path.join(os.homedir(), ".config", "vyft", project), {
13
+ recursive: true,
14
+ });
15
+ }
16
+ catch {
17
+ // ignore
18
+ }
19
+ }
20
+ describe("resolvePassphrase", () => {
21
+ const savedEnv = process.env["VYFT_PASSPHRASE"];
22
+ afterEach(() => {
23
+ if (savedEnv === undefined) {
24
+ delete process.env["VYFT_PASSPHRASE"];
25
+ }
26
+ else {
27
+ process.env["VYFT_PASSPHRASE"] = savedEnv;
28
+ }
29
+ });
30
+ it("returns VYFT_PASSPHRASE env var when set", async () => {
31
+ process.env["VYFT_PASSPHRASE"] = "env-secret";
32
+ const result = await resolvePassphrase("any-project", "deploy");
33
+ assert.equal(result, "env-secret");
34
+ });
35
+ it("returns persisted passphrase when file exists (deploy mode)", async () => {
36
+ delete process.env["VYFT_PASSPHRASE"];
37
+ const project = `test-${Date.now()}`;
38
+ const filePath = configPath(project);
39
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
40
+ await fs.writeFile(filePath, "stored-secret", { mode: 0o600 });
41
+ try {
42
+ const result = await resolvePassphrase(project, "deploy");
43
+ assert.equal(result, "stored-secret");
44
+ }
45
+ finally {
46
+ await cleanupProject(project);
47
+ }
48
+ });
49
+ it("trims trailing newlines from persisted passphrase file", async () => {
50
+ delete process.env["VYFT_PASSPHRASE"];
51
+ const project = `test-trim-${Date.now()}`;
52
+ const filePath = configPath(project);
53
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
54
+ await fs.writeFile(filePath, "my-passphrase\n", { mode: 0o600 });
55
+ try {
56
+ const result = await resolvePassphrase(project, "deploy");
57
+ assert.equal(result, "my-passphrase");
58
+ }
59
+ finally {
60
+ await cleanupProject(project);
61
+ }
62
+ });
63
+ it("treats whitespace-only passphrase file as absent", async () => {
64
+ delete process.env["VYFT_PASSPHRASE"];
65
+ const project = `test-whitespace-${Date.now()}`;
66
+ const filePath = configPath(project);
67
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
68
+ await fs.writeFile(filePath, " \n", { mode: 0o600 });
69
+ try {
70
+ // local mode: should generate a new passphrase since file content is empty after trim
71
+ const result = await resolvePassphrase(project, "local");
72
+ assert.ok(result.length > 0);
73
+ assert.notEqual(result.trim(), "");
74
+ }
75
+ finally {
76
+ await cleanupProject(project);
77
+ }
78
+ });
79
+ it("generates and persists a passphrase in local mode", async () => {
80
+ delete process.env["VYFT_PASSPHRASE"];
81
+ const project = `test-local-${Date.now()}`;
82
+ try {
83
+ const result = await resolvePassphrase(project, "local");
84
+ assert.ok(result.length > 0);
85
+ const saved = await fs.readFile(configPath(project), "utf8");
86
+ assert.equal(saved, result);
87
+ }
88
+ finally {
89
+ await cleanupProject(project);
90
+ }
91
+ });
92
+ it("returns same generated passphrase on subsequent local calls", async () => {
93
+ delete process.env["VYFT_PASSPHRASE"];
94
+ const project = `test-idempotent-${Date.now()}`;
95
+ try {
96
+ const first = await resolvePassphrase(project, "local");
97
+ const second = await resolvePassphrase(project, "local");
98
+ assert.equal(first, second);
99
+ }
100
+ finally {
101
+ await cleanupProject(project);
102
+ }
103
+ });
104
+ it("env var takes precedence over persisted passphrase", async () => {
105
+ const project = `test-priority-${Date.now()}`;
106
+ const filePath = configPath(project);
107
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
108
+ await fs.writeFile(filePath, "file-secret", { mode: 0o600 });
109
+ process.env["VYFT_PASSPHRASE"] = "env-wins";
110
+ try {
111
+ const result = await resolvePassphrase(project, "deploy");
112
+ assert.equal(result, "env-wins");
113
+ }
114
+ finally {
115
+ await cleanupProject(project);
116
+ }
117
+ });
118
+ });
119
+ //# sourceMappingURL=runtime.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.test.js","sourceRoot":"","sources":["../src/runtime.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function fileExists(filePath: string): Promise<boolean>;
2
+ export declare function isEmptyDir(dir: string): Promise<boolean>;
3
+ export declare function addGitignoreEntry(dir: string): Promise<void>;
4
+ //# sourceMappingURL=fs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAEA,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO9D;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,iBAWlD"}
@@ -0,0 +1,33 @@
1
+ import fs from "node:fs/promises";
2
+ export async function fileExists(filePath) {
3
+ try {
4
+ await fs.access(filePath);
5
+ return true;
6
+ }
7
+ catch {
8
+ return false;
9
+ }
10
+ }
11
+ export async function isEmptyDir(dir) {
12
+ try {
13
+ const entries = await fs.readdir(dir);
14
+ return entries.length === 0;
15
+ }
16
+ catch {
17
+ return true;
18
+ }
19
+ }
20
+ export async function addGitignoreEntry(dir) {
21
+ const path = await import("node:path");
22
+ const gitignorePath = path.join(dir, ".gitignore");
23
+ try {
24
+ const content = await fs.readFile(gitignorePath, "utf8");
25
+ if (!content.includes(".vyft")) {
26
+ await fs.appendFile(gitignorePath, "\n.vyft/\n");
27
+ }
28
+ }
29
+ catch {
30
+ await fs.writeFile(gitignorePath, ".vyft/\n");
31
+ }
32
+ }
33
+ //# sourceMappingURL=fs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAW;IACjD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACvC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACzD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,MAAM,EAAE,CAAC,UAAU,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IAChD,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export type PackageManager = "pnpm" | "yarn" | "bun" | "npm";
2
+ export declare function detectPackageManager(cwd: string): Promise<PackageManager>;
3
+ //# sourceMappingURL=pm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pm.d.ts","sourceRoot":"","sources":["../../src/utils/pm.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;AAU7D,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,CAAC,CAKzB"}
@@ -0,0 +1,17 @@
1
+ import path from "node:path";
2
+ import { fileExists } from "./fs.js";
3
+ const LOCK_FILES = [
4
+ ["pnpm-lock.yaml", "pnpm"],
5
+ ["bun.lock", "bun"],
6
+ ["bun.lockb", "bun"],
7
+ ["yarn.lock", "yarn"],
8
+ ["package-lock.json", "npm"],
9
+ ];
10
+ export async function detectPackageManager(cwd) {
11
+ for (const [file, pm] of LOCK_FILES) {
12
+ if (await fileExists(path.join(cwd, file)))
13
+ return pm;
14
+ }
15
+ return "npm";
16
+ }
17
+ //# sourceMappingURL=pm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pm.js","sourceRoot":"","sources":["../../src/utils/pm.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAIrC,MAAM,UAAU,GAA+B;IAC7C,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAC1B,CAAC,UAAU,EAAE,KAAK,CAAC;IACnB,CAAC,WAAW,EAAE,KAAK,CAAC;IACpB,CAAC,WAAW,EAAE,MAAM,CAAC;IACrB,CAAC,mBAAmB,EAAE,KAAK,CAAC;CAC7B,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,GAAW;IAEX,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC;QACpC,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function cancel(msg?: string): never;
2
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/utils/prompts.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,CAAC,GAAG,SAAe,GAAG,KAAK,CAGhD"}
@@ -0,0 +1,6 @@
1
+ import { log } from "@clack/prompts";
2
+ export function cancel(msg = "Cancelled.") {
3
+ log.warn(msg);
4
+ process.exit(0);
5
+ }
6
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/utils/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAErC,MAAM,UAAU,MAAM,CAAC,GAAG,GAAG,YAAY;IACvC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function listTemplates(): Promise<string[]>;
2
+ export declare function copyTemplate(template: string, dest: string): Promise<void>;
3
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/utils/templates.ts"],"names":[],"mappings":"AAkBA,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAGvD;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,iBA2BhE"}
@@ -0,0 +1,48 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ function templatesDir() {
4
+ return path.resolve(import.meta.dirname, "..", "..", "templates");
5
+ }
6
+ async function fetchLatestVersion(pkg) {
7
+ try {
8
+ const res = await fetch(`https://registry.npmjs.org/${pkg}/latest`);
9
+ if (!res.ok)
10
+ return null;
11
+ const data = (await res.json());
12
+ return data.version ?? null;
13
+ }
14
+ catch {
15
+ return null;
16
+ }
17
+ }
18
+ export async function listTemplates() {
19
+ const entries = await fs.readdir(templatesDir(), { withFileTypes: true });
20
+ return entries.filter((e) => e.isDirectory()).map((e) => e.name);
21
+ }
22
+ export async function copyTemplate(template, dest) {
23
+ const src = path.join(templatesDir(), template);
24
+ const entries = await fs.readdir(src, { withFileTypes: true });
25
+ for (const entry of entries) {
26
+ if (!entry.isFile())
27
+ continue;
28
+ const srcFile = path.join(src, entry.name);
29
+ const destFile = path.join(dest, entry.name);
30
+ if (entry.name === "package.json") {
31
+ const raw = await fs.readFile(srcFile, "utf8");
32
+ const pkg = JSON.parse(raw);
33
+ pkg["name"] = path.basename(dest);
34
+ const vyftVersion = await fetchLatestVersion("vyft");
35
+ if (vyftVersion) {
36
+ const deps = pkg["dependencies"];
37
+ if (deps?.["vyft"]) {
38
+ deps["vyft"] = `^${vyftVersion}`;
39
+ }
40
+ }
41
+ await fs.writeFile(destFile, `${JSON.stringify(pkg, null, 2)}\n`);
42
+ }
43
+ else {
44
+ await fs.copyFile(srcFile, destFile);
45
+ }
46
+ }
47
+ }
48
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/utils/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,SAAS,YAAY;IACnB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;AACpE,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,GAAW;IAC3C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,8BAA8B,GAAG,SAAS,CAAC,CAAC;QACpE,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAyB,CAAC;QACxD,OAAO,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1E,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB,EAAE,IAAY;IAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,QAAQ,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAAE,SAAS;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE7C,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAClC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;YACvD,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAElC,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;YACrD,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,IAAI,GAAG,GAAG,CAAC,cAAc,CAAuC,CAAC;gBACvE,IAAI,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC;oBACnB,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,WAAW,EAAE,CAAC;gBACnC,CAAC;YACH,CAAC;YAED,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,65 +1,50 @@
1
1
  {
2
2
  "name": "vyft",
3
- "version": "0.3.0-alpha",
4
- "description": "Deploy apps to Docker Swarm with TypeScript",
5
- "type": "module",
6
- "license": "MIT",
7
- "bin": {
8
- "vyft": "./dist/cli.js"
3
+ "version": "0.4.1-alpha",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/vyftlabs/vyft",
7
+ "directory": "packages/vyft"
9
8
  },
10
- "main": "./dist/index.js",
11
- "types": "./dist/index.d.ts",
9
+ "type": "module",
12
10
  "exports": {
13
11
  ".": {
12
+ "types": "./dist/lib.d.ts",
13
+ "default": "./dist/lib.js"
14
+ },
15
+ "./services": {
16
+ "types": "./dist/services.d.ts",
17
+ "default": "./dist/services.js"
18
+ },
19
+ "./cli": {
14
20
  "types": "./dist/index.d.ts",
15
- "import": "./dist/index.js"
21
+ "default": "./dist/index.js"
16
22
  }
17
23
  },
24
+ "bin": {
25
+ "vyft": "./dist/index.js"
26
+ },
18
27
  "files": [
19
28
  "dist",
20
29
  "templates"
21
30
  ],
22
- "keywords": [
23
- "docker",
24
- "swarm",
25
- "deploy",
26
- "infrastructure",
27
- "devops",
28
- "typescript"
29
- ],
30
- "repository": {
31
- "type": "git",
32
- "url": "git+https://github.com/vyftlabs/vyft.git"
33
- },
34
- "bugs": {
35
- "url": "https://github.com/vyftlabs/vyft/issues"
36
- },
37
- "homepage": "https://github.com/vyftlabs/vyft#readme",
38
- "devDependencies": {
39
- "@biomejs/biome": "^2.4.4",
40
- "@types/dockerode": "^4.0.1",
41
- "@types/node": "^25.3.1",
42
- "@types/tar-fs": "^2.0.4",
43
- "tsx": "^4.21.0",
44
- "typescript": "^5.9.3",
45
- "vitest": "^4.0.18"
46
- },
47
31
  "dependencies": {
48
- "@clack/prompts": "^1.0.1",
32
+ "@clack/prompts": "^1.1.0",
49
33
  "commander": "^14.0.3",
50
- "dockerode": "^4.0.9",
51
- "picocolors": "^1.1.1",
52
- "pino": "^10.3.1",
53
- "tar-fs": "^3.1.1"
54
- },
55
- "engines": {
56
- "node": ">=22"
34
+ "jiti": "^2.6.1",
35
+ "@vyft/core": "0.4.1-alpha",
36
+ "@vyft/provider": "0.4.1-alpha",
37
+ "@vyft/engine": "0.4.1-alpha",
38
+ "@vyft/docker": "0.4.1-alpha",
39
+ "@vyft/local": "0.4.1-alpha",
40
+ "@vyft/platform": "0.4.1-alpha",
41
+ "@vyft/runtime": "0.4.1-alpha",
42
+ "@vyft/std": "0.4.1-alpha",
43
+ "@vyft/store": "0.4.1-alpha"
57
44
  },
58
45
  "scripts": {
59
46
  "build": "tsc",
60
- "lint": "biome check src/",
61
- "format:check": "biome format src/",
62
- "test": "vitest run",
63
- "test:watch": "vitest"
47
+ "test": "node --test 'src/**/*.test.ts'",
48
+ "lint": "biome check ."
64
49
  }
65
50
  }
@@ -0,0 +1,8 @@
1
+ const server = Bun.serve({
2
+ port: process.env.PORT ?? 3000,
3
+ fetch() {
4
+ return new Response("Hello from Vyft!");
5
+ },
6
+ });
7
+
8
+ console.log(`Listening on ${server.url}`);
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "my-vyft-app",
3
+ "description": "A Bun app deployed with Vyft",
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "bun run --watch index.ts"
7
+ },
8
+ "dependencies": {
9
+ "vyft": "latest"
10
+ },
11
+ "devDependencies": {
12
+ "@types/bun": "latest",
13
+ "typescript": "^5.9.3"
14
+ }
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ESNext"],
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "skipLibCheck": true,
10
+ "isolatedModules": true,
11
+ "resolveJsonModule": true,
12
+ "noUncheckedIndexedAccess": true
13
+ },
14
+ "include": ["**/*.ts"]
15
+ }
@@ -0,0 +1,3 @@
1
+ import { service } from "vyft";
2
+
3
+ export const app = service("app");
package/dist/build.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import type { Logger } from "pino";
2
- export interface BuildResult {
3
- outputPath: string;
4
- }
5
- type BuildOptions = {
6
- output?: string;
7
- command?: string;
8
- env?: Record<string, string>;
9
- };
10
- export declare function buildStatic(context: string, options: BuildOptions, log?: Logger): Promise<BuildResult>;
11
- export {};
package/dist/build.js DELETED
@@ -1,39 +0,0 @@
1
- import { existsSync } from "node:fs";
2
- import path from "node:path";
3
- import { spinner } from "@clack/prompts";
4
- import { exec } from "./exec.js";
5
- function resolveBuildCommand(context, optionCommand) {
6
- if (optionCommand)
7
- return optionCommand;
8
- const packageJsonPath = path.join(context, "package.json");
9
- if (existsSync(packageJsonPath)) {
10
- const hasYarn = existsSync(path.join(context, "yarn.lock"));
11
- const hasPnpm = existsSync(path.join(context, "pnpm-lock.yaml"));
12
- if (hasYarn)
13
- return "yarn build";
14
- if (hasPnpm)
15
- return "pnpm build";
16
- return "npm run build";
17
- }
18
- return undefined;
19
- }
20
- export async function buildStatic(context, options, log) {
21
- const buildContext = path.resolve(context);
22
- const outputDir = options.output ?? "./dist";
23
- const outputPath = path.join(buildContext, outputDir);
24
- const buildCommand = resolveBuildCommand(buildContext, options.command);
25
- if (buildCommand) {
26
- const start = performance.now();
27
- log?.info({ command: buildCommand, context: buildContext }, "static build started");
28
- const s = spinner();
29
- s.start(`Building static site (${buildCommand})`);
30
- await exec(buildCommand, buildContext, options.env, log);
31
- s.stop("Build complete");
32
- const durationMs = Math.round(performance.now() - start);
33
- log?.info({ command: buildCommand, context: buildContext, durationMs }, "static build completed");
34
- }
35
- if (!existsSync(outputPath)) {
36
- throw new Error(`Output directory not found: ${outputPath}`);
37
- }
38
- return { outputPath };
39
- }
package/dist/cli.d.ts DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};