@pushto/cli 0.2.0 → 0.4.6

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 (188) hide show
  1. package/dist/commands/__tests__/deploy-domain.test.d.ts +2 -0
  2. package/dist/commands/__tests__/deploy-domain.test.d.ts.map +1 -0
  3. package/dist/commands/__tests__/deploy-domain.test.js +41 -0
  4. package/dist/commands/__tests__/deploy-domain.test.js.map +1 -0
  5. package/dist/commands/__tests__/headless-smoke.test.d.ts +2 -0
  6. package/dist/commands/__tests__/headless-smoke.test.d.ts.map +1 -0
  7. package/dist/commands/__tests__/headless-smoke.test.js +110 -0
  8. package/dist/commands/__tests__/headless-smoke.test.js.map +1 -0
  9. package/dist/commands/auth.d.ts +2 -0
  10. package/dist/commands/auth.d.ts.map +1 -0
  11. package/dist/commands/auth.js +77 -0
  12. package/dist/commands/auth.js.map +1 -0
  13. package/dist/commands/cron.d.ts +2 -0
  14. package/dist/commands/cron.d.ts.map +1 -0
  15. package/dist/commands/cron.js +157 -0
  16. package/dist/commands/cron.js.map +1 -0
  17. package/dist/commands/db.d.ts +4 -0
  18. package/dist/commands/db.d.ts.map +1 -0
  19. package/dist/commands/db.js +63 -0
  20. package/dist/commands/db.js.map +1 -0
  21. package/dist/commands/deploy.d.ts +16 -1
  22. package/dist/commands/deploy.d.ts.map +1 -1
  23. package/dist/commands/deploy.js +344 -68
  24. package/dist/commands/deploy.js.map +1 -1
  25. package/dist/commands/doctor.d.ts.map +1 -1
  26. package/dist/commands/doctor.js +401 -69
  27. package/dist/commands/doctor.js.map +1 -1
  28. package/dist/commands/domain.d.ts.map +1 -1
  29. package/dist/commands/domain.js +70 -18
  30. package/dist/commands/domain.js.map +1 -1
  31. package/dist/commands/echo.d.ts +2 -0
  32. package/dist/commands/echo.d.ts.map +1 -0
  33. package/dist/commands/echo.js +227 -0
  34. package/dist/commands/echo.js.map +1 -0
  35. package/dist/commands/env.d.ts +3 -1
  36. package/dist/commands/env.d.ts.map +1 -1
  37. package/dist/commands/env.js +76 -50
  38. package/dist/commands/env.js.map +1 -1
  39. package/dist/commands/init.d.ts +3 -1
  40. package/dist/commands/init.d.ts.map +1 -1
  41. package/dist/commands/init.js +58 -11
  42. package/dist/commands/init.js.map +1 -1
  43. package/dist/commands/login.d.ts.map +1 -1
  44. package/dist/commands/login.js +80 -39
  45. package/dist/commands/login.js.map +1 -1
  46. package/dist/commands/logs.d.ts +3 -1
  47. package/dist/commands/logs.d.ts.map +1 -1
  48. package/dist/commands/logs.js +77 -21
  49. package/dist/commands/logs.js.map +1 -1
  50. package/dist/commands/mail.d.ts +2 -0
  51. package/dist/commands/mail.d.ts.map +1 -0
  52. package/dist/commands/mail.js +105 -0
  53. package/dist/commands/mail.js.map +1 -0
  54. package/dist/commands/open.d.ts.map +1 -1
  55. package/dist/commands/open.js +32 -8
  56. package/dist/commands/open.js.map +1 -1
  57. package/dist/commands/preview.d.ts +22 -0
  58. package/dist/commands/preview.d.ts.map +1 -0
  59. package/dist/commands/preview.js +223 -0
  60. package/dist/commands/preview.js.map +1 -0
  61. package/dist/commands/status.d.ts +3 -1
  62. package/dist/commands/status.d.ts.map +1 -1
  63. package/dist/commands/status.js +62 -12
  64. package/dist/commands/status.js.map +1 -1
  65. package/dist/commands/upgrade.d.ts.map +1 -1
  66. package/dist/commands/upgrade.js +73 -10
  67. package/dist/commands/upgrade.js.map +1 -1
  68. package/dist/commands/use.d.ts +2 -0
  69. package/dist/commands/use.d.ts.map +1 -0
  70. package/dist/commands/use.js +108 -0
  71. package/dist/commands/use.js.map +1 -0
  72. package/dist/commands/vault.d.ts +2 -0
  73. package/dist/commands/vault.d.ts.map +1 -0
  74. package/dist/commands/vault.js +119 -0
  75. package/dist/commands/vault.js.map +1 -0
  76. package/dist/commands/whoami.d.ts.map +1 -1
  77. package/dist/commands/whoami.js +12 -1
  78. package/dist/commands/whoami.js.map +1 -1
  79. package/dist/index.js +123 -13
  80. package/dist/index.js.map +1 -1
  81. package/dist/lib/__tests__/build-runner.test.d.ts +2 -0
  82. package/dist/lib/__tests__/build-runner.test.d.ts.map +1 -0
  83. package/dist/lib/__tests__/build-runner.test.js +119 -0
  84. package/dist/lib/__tests__/build-runner.test.js.map +1 -0
  85. package/dist/lib/__tests__/cron-tail.test.d.ts +2 -0
  86. package/dist/lib/__tests__/cron-tail.test.d.ts.map +1 -0
  87. package/dist/lib/__tests__/cron-tail.test.js +27 -0
  88. package/dist/lib/__tests__/cron-tail.test.js.map +1 -0
  89. package/dist/lib/__tests__/detect-static-framework.test.d.ts +2 -0
  90. package/dist/lib/__tests__/detect-static-framework.test.d.ts.map +1 -0
  91. package/dist/lib/__tests__/detect-static-framework.test.js +146 -0
  92. package/dist/lib/__tests__/detect-static-framework.test.js.map +1 -0
  93. package/dist/lib/__tests__/errors.test.d.ts +2 -0
  94. package/dist/lib/__tests__/errors.test.d.ts.map +1 -0
  95. package/dist/lib/__tests__/errors.test.js +56 -0
  96. package/dist/lib/__tests__/errors.test.js.map +1 -0
  97. package/dist/lib/__tests__/interactive.test.d.ts +2 -0
  98. package/dist/lib/__tests__/interactive.test.d.ts.map +1 -0
  99. package/dist/lib/__tests__/interactive.test.js +79 -0
  100. package/dist/lib/__tests__/interactive.test.js.map +1 -0
  101. package/dist/lib/__tests__/output.test.d.ts +2 -0
  102. package/dist/lib/__tests__/output.test.d.ts.map +1 -0
  103. package/dist/lib/__tests__/output.test.js +144 -0
  104. package/dist/lib/__tests__/output.test.js.map +1 -0
  105. package/dist/lib/__tests__/prepare-artifact.test.d.ts +2 -0
  106. package/dist/lib/__tests__/prepare-artifact.test.d.ts.map +1 -0
  107. package/dist/lib/__tests__/prepare-artifact.test.js +55 -0
  108. package/dist/lib/__tests__/prepare-artifact.test.js.map +1 -0
  109. package/dist/lib/__tests__/preview-args.test.d.ts +2 -0
  110. package/dist/lib/__tests__/preview-args.test.d.ts.map +1 -0
  111. package/dist/lib/__tests__/preview-args.test.js +37 -0
  112. package/dist/lib/__tests__/preview-args.test.js.map +1 -0
  113. package/dist/lib/api.d.ts +2 -0
  114. package/dist/lib/api.d.ts.map +1 -1
  115. package/dist/lib/api.js +38 -5
  116. package/dist/lib/api.js.map +1 -1
  117. package/dist/lib/ask.d.ts +15 -0
  118. package/dist/lib/ask.d.ts.map +1 -0
  119. package/dist/lib/ask.js +24 -0
  120. package/dist/lib/ask.js.map +1 -0
  121. package/dist/lib/build-runner.d.ts +25 -0
  122. package/dist/lib/build-runner.d.ts.map +1 -0
  123. package/dist/lib/build-runner.js +141 -0
  124. package/dist/lib/build-runner.js.map +1 -0
  125. package/dist/lib/config.d.ts +6 -0
  126. package/dist/lib/config.d.ts.map +1 -1
  127. package/dist/lib/config.js +13 -2
  128. package/dist/lib/config.js.map +1 -1
  129. package/dist/lib/cron-tail.d.ts +10 -0
  130. package/dist/lib/cron-tail.d.ts.map +1 -0
  131. package/dist/lib/cron-tail.js +5 -0
  132. package/dist/lib/cron-tail.js.map +1 -0
  133. package/dist/lib/detect-static-framework.d.ts +31 -0
  134. package/dist/lib/detect-static-framework.d.ts.map +1 -0
  135. package/dist/lib/detect-static-framework.js +96 -0
  136. package/dist/lib/detect-static-framework.js.map +1 -0
  137. package/dist/lib/env-parse.d.ts +48 -0
  138. package/dist/lib/env-parse.d.ts.map +1 -0
  139. package/dist/lib/env-parse.js +91 -0
  140. package/dist/lib/env-parse.js.map +1 -0
  141. package/dist/lib/errors.d.ts +111 -0
  142. package/dist/lib/errors.d.ts.map +1 -0
  143. package/dist/lib/errors.js +64 -0
  144. package/dist/lib/errors.js.map +1 -0
  145. package/dist/lib/file-walker.d.ts +23 -0
  146. package/dist/lib/file-walker.d.ts.map +1 -0
  147. package/dist/lib/file-walker.js +114 -0
  148. package/dist/lib/file-walker.js.map +1 -0
  149. package/dist/lib/interactive.d.ts +13 -0
  150. package/dist/lib/interactive.d.ts.map +1 -0
  151. package/dist/lib/interactive.js +24 -0
  152. package/dist/lib/interactive.js.map +1 -0
  153. package/dist/lib/output.d.ts +24 -0
  154. package/dist/lib/output.d.ts.map +1 -0
  155. package/dist/lib/output.js +71 -0
  156. package/dist/lib/output.js.map +1 -0
  157. package/dist/lib/prepare-artifact.d.ts +22 -0
  158. package/dist/lib/prepare-artifact.d.ts.map +1 -0
  159. package/dist/lib/prepare-artifact.js +26 -0
  160. package/dist/lib/prepare-artifact.js.map +1 -0
  161. package/dist/lib/preview-args.d.ts +20 -0
  162. package/dist/lib/preview-args.d.ts.map +1 -0
  163. package/dist/lib/preview-args.js +19 -0
  164. package/dist/lib/preview-args.js.map +1 -0
  165. package/dist/lib/resolve-slug.d.ts.map +1 -1
  166. package/dist/lib/resolve-slug.js +9 -2
  167. package/dist/lib/resolve-slug.js.map +1 -1
  168. package/dist/lib/safe-json.d.ts +7 -2
  169. package/dist/lib/safe-json.d.ts.map +1 -1
  170. package/dist/lib/safe-json.js +23 -4
  171. package/dist/lib/safe-json.js.map +1 -1
  172. package/dist/lib/update-check.d.ts +17 -0
  173. package/dist/lib/update-check.d.ts.map +1 -0
  174. package/dist/lib/update-check.js +81 -0
  175. package/dist/lib/update-check.js.map +1 -0
  176. package/dist/lib/upload-limits.d.ts +17 -0
  177. package/dist/lib/upload-limits.d.ts.map +1 -0
  178. package/dist/lib/upload-limits.js +17 -0
  179. package/dist/lib/upload-limits.js.map +1 -0
  180. package/dist/lib/zip-project.d.ts +19 -0
  181. package/dist/lib/zip-project.d.ts.map +1 -0
  182. package/dist/lib/zip-project.js +39 -0
  183. package/dist/lib/zip-project.js.map +1 -0
  184. package/dist/version.d.ts +2 -0
  185. package/dist/version.d.ts.map +1 -0
  186. package/dist/version.js +16 -0
  187. package/dist/version.js.map +1 -0
  188. package/package.json +5 -8
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=build-runner.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-runner.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/build-runner.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,119 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { runStaticBuild, writeArtifactMeta, ARTIFACT_META_NAME } from '../build-runner.js';
6
+ let dir;
7
+ beforeEach(() => { dir = fs.mkdtempSync(path.join(os.tmpdir(), 'pushto-build-')); });
8
+ afterEach(() => { fs.rmSync(dir, { recursive: true, force: true }); });
9
+ const vite = { framework: 'vite', spa: true, outputDirs: ['dist'] };
10
+ const writePkg = (scripts) => {
11
+ fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify({ name: 'fx', private: true, scripts }));
12
+ // node_modules present → the runner must NOT attempt an install
13
+ fs.mkdirSync(path.join(dir, 'node_modules'), { recursive: true });
14
+ };
15
+ /** A .bin shim so `npx --no-install <name>` and `npm run` resolve it. */
16
+ const writeShim = (name, exitCode, body) => {
17
+ const bin = path.join(dir, 'node_modules', '.bin');
18
+ fs.mkdirSync(bin, { recursive: true });
19
+ const file = path.join(bin, name);
20
+ fs.writeFileSync(file, `#!/bin/sh\n${body}\nexit ${exitCode}\n`);
21
+ fs.chmodSync(file, 0o755);
22
+ };
23
+ describe('runStaticBuild', () => {
24
+ it('runs the build script and resolves the expected output dir', async () => {
25
+ writePkg({ build: 'node -e "require(\'fs\').mkdirSync(\'dist\',{recursive:true});require(\'fs\').writeFileSync(\'dist/index.html\',\'hi\')"' });
26
+ const r = await runStaticBuild(dir, vite);
27
+ expect(r).toEqual({ ok: true, outputDir: path.join(dir, 'dist'), typeWarnings: null });
28
+ });
29
+ it('fails honestly when the build script fails (custom script, no fallback)', async () => {
30
+ writePkg({ build: 'node -e "console.error(\'boom\');process.exit(1)"' });
31
+ const r = await runStaticBuild(dir, vite);
32
+ expect(r.ok).toBe(false);
33
+ if (!r.ok)
34
+ expect(r.buildOutput).toContain('boom');
35
+ });
36
+ it('fails honestly when the build produces no index.html anywhere', async () => {
37
+ writePkg({ build: 'node -e "require(\'fs\').mkdirSync(\'dist\',{recursive:true})"' });
38
+ const r = await runStaticBuild(dir, vite);
39
+ expect(r.ok).toBe(false);
40
+ if (!r.ok)
41
+ expect(r.message).toContain('index.html');
42
+ });
43
+ it('fails with a named fix when there is no build script', async () => {
44
+ writePkg({});
45
+ const r = await runStaticBuild(dir, vite);
46
+ expect(r.ok).toBe(false);
47
+ if (!r.ok)
48
+ expect(r.message).toContain('build');
49
+ });
50
+ it('build script suggestion for angular uses ng build, not angular build', async () => {
51
+ const angular = { framework: 'angular', spa: true, outputDirs: ['dist/x/browser'] };
52
+ writePkg({});
53
+ const r = await runStaticBuild(dir, angular);
54
+ expect(r.ok).toBe(false);
55
+ if (!r.ok) {
56
+ expect(r.message).toContain('ng build');
57
+ expect(r.message).not.toContain('angular build');
58
+ }
59
+ });
60
+ it('stock `tsc -b && vite build` shape: tsc fails → retries vite build alone, ships, carries type warnings', async () => {
61
+ writePkg({ build: 'tsc -b && vite build' });
62
+ writeShim('tsc', 2, 'echo "src/App.tsx(3,7): error TS2322" 1>&2');
63
+ writeShim('vite', 0, 'mkdir -p dist && echo hi > dist/index.html');
64
+ const r = await runStaticBuild(dir, vite);
65
+ expect(r.ok).toBe(true);
66
+ if (r.ok) {
67
+ expect(r.outputDir).toBe(path.join(dir, 'dist'));
68
+ expect(r.typeWarnings).toContain('TS2322');
69
+ }
70
+ });
71
+ it('custom script containing tsc is NOT second-guessed', async () => {
72
+ writePkg({ build: 'tsc -b && vite build && node gen-sitemap.js' });
73
+ writeShim('tsc', 2, 'echo "error TS2322" 1>&2');
74
+ writeShim('vite', 0, 'mkdir -p dist && echo hi > dist/index.html');
75
+ const r = await runStaticBuild(dir, vite);
76
+ expect(r.ok).toBe(false);
77
+ });
78
+ it('falls back to scanning conventional dirs when the expected dir is empty', async () => {
79
+ writePkg({ build: 'node -e "require(\'fs\').mkdirSync(\'build\',{recursive:true});require(\'fs\').writeFileSync(\'build/index.html\',\'hi\')"' });
80
+ const r = await runStaticBuild(dir, vite); // expected dist, actual build/
81
+ expect(r.ok).toBe(true);
82
+ if (r.ok)
83
+ expect(r.outputDir).toBe(path.join(dir, 'build'));
84
+ });
85
+ it('stale output is not trusted: pre-existing dist without a fresh build fails', async () => {
86
+ fs.mkdirSync(path.join(dir, 'dist'), { recursive: true });
87
+ fs.writeFileSync(path.join(dir, 'dist', 'index.html'), 'stale');
88
+ // Backdate the stale file so mtime-based freshness sees it as old.
89
+ const old = new Date(Date.now() - 60 * 60 * 1000);
90
+ fs.utimesSync(path.join(dir, 'dist', 'index.html'), old, old);
91
+ writePkg({ build: 'node -e "process.exit(1)"' });
92
+ const r = await runStaticBuild(dir, vite);
93
+ expect(r.ok).toBe(false); // build failed → NEVER ship the stale dir
94
+ });
95
+ it('a successful build with ONLY stale output fails honestly (mtime guard)', async () => {
96
+ fs.mkdirSync(path.join(dir, 'dist'), { recursive: true });
97
+ fs.writeFileSync(path.join(dir, 'dist', 'index.html'), 'stale');
98
+ const old = new Date(Date.now() - 60 * 60 * 1000);
99
+ fs.utimesSync(path.join(dir, 'dist', 'index.html'), old, old);
100
+ fs.utimesSync(path.join(dir, 'dist'), old, old);
101
+ writePkg({ build: 'node -e "process.exit(0)"' }); // succeeds, writes nothing
102
+ const r = await runStaticBuild(dir, vite);
103
+ expect(r.ok).toBe(false); // stale dist/index.html must NOT be shipped
104
+ if (!r.ok)
105
+ expect(r.message).toContain('no fresh index.html');
106
+ });
107
+ });
108
+ describe('writeArtifactMeta', () => {
109
+ it('writes the marker and cleanup removes it', () => {
110
+ const out = path.join(dir, 'dist');
111
+ fs.mkdirSync(out, { recursive: true });
112
+ const cleanup = writeArtifactMeta(out, { framework: 'vite', spa: true });
113
+ const metaPath = path.join(out, ARTIFACT_META_NAME);
114
+ expect(JSON.parse(fs.readFileSync(metaPath, 'utf-8'))).toMatchObject({ framework: 'vite', spa: true });
115
+ cleanup();
116
+ expect(fs.existsSync(metaPath)).toBe(false);
117
+ });
118
+ });
119
+ //# sourceMappingURL=build-runner.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-runner.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/build-runner.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cron-tail.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron-tail.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/cron-tail.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,27 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { selectNewExecutions } from '../cron-tail.js';
3
+ // `pushto cron tail` follows a job live (the docs promise "watch a run's
4
+ // output live" — pre-fix it was a one-shot fetch). The follow loop polls
5
+ // the history endpoint, which returns newest-first; the tail must print
6
+ // only unseen rows, oldest-first, like tail -f.
7
+ const exec = (id, at) => ({ id, executedAt: at });
8
+ describe('selectNewExecutions', () => {
9
+ it('returns only rows not yet seen', () => {
10
+ const seen = new Set(['e1']);
11
+ const out = selectNewExecutions(seen, [exec('e2', '2026-07-19T00:01:00Z'), exec('e1', '2026-07-19T00:00:00Z')]);
12
+ expect(out.map((e) => e.id)).toEqual(['e2']);
13
+ });
14
+ it('orders fresh rows oldest-first for printing', () => {
15
+ const out = selectNewExecutions(new Set(), [
16
+ exec('e3', '2026-07-19T00:03:00Z'),
17
+ exec('e2', '2026-07-19T00:02:00Z'),
18
+ exec('e1', '2026-07-19T00:01:00Z'),
19
+ ]);
20
+ expect(out.map((e) => e.id)).toEqual(['e1', 'e2', 'e3']);
21
+ });
22
+ it('returns nothing when everything is seen', () => {
23
+ const seen = new Set(['e1', 'e2']);
24
+ expect(selectNewExecutions(seen, [exec('e1', '2026-07-19T00:00:00Z'), exec('e2', '2026-07-19T00:01:00Z')])).toEqual([]);
25
+ });
26
+ });
27
+ //# sourceMappingURL=cron-tail.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron-tail.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/cron-tail.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,yEAAyE;AACzE,yEAAyE;AACzE,wEAAwE;AACxE,gDAAgD;AAEhD,MAAM,IAAI,GAAG,CAAC,EAAU,EAAE,EAAU,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;AAElE,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7B,MAAM,GAAG,GAAG,mBAAmB,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAChH,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,GAAG,GAAG,mBAAmB,CAAC,IAAI,GAAG,EAAE,EAAE;YACzC,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC;YAClC,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC;YAClC,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC;SACnC,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACnC,MAAM,CACJ,mBAAmB,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,CACpG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=detect-static-framework.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-static-framework.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/detect-static-framework.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,146 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { detectStaticFramework } from '../detect-static-framework.js';
6
+ let dir;
7
+ beforeEach(() => { dir = fs.mkdtempSync(path.join(os.tmpdir(), 'pushto-detect-')); });
8
+ afterEach(() => { fs.rmSync(dir, { recursive: true, force: true }); });
9
+ const writePkg = (pkg) => {
10
+ fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify(pkg));
11
+ };
12
+ describe('detectStaticFramework', () => {
13
+ it('detects a stock vite scaffold (no start script) as vite, spa', () => {
14
+ writePkg({ devDependencies: { vite: '^5.0.0' }, scripts: { dev: 'vite', build: 'tsc -b && vite build', preview: 'vite preview' } });
15
+ const d = detectStaticFramework(dir);
16
+ expect(d).toEqual({ framework: 'vite', spa: true, outputDirs: ['dist'] });
17
+ });
18
+ it('detects vite via config file when the dep is indirect', () => {
19
+ writePkg({ scripts: { build: 'vite build' } });
20
+ fs.writeFileSync(path.join(dir, 'vite.config.ts'), 'export default {}');
21
+ expect(detectStaticFramework(dir)?.framework).toBe('vite');
22
+ });
23
+ it('start script wins: vite + start stays dynamic (null)', () => {
24
+ writePkg({ dependencies: { vite: '^5.0.0', express: '^4.0.0' }, scripts: { build: 'vite build', start: 'node server.js' } });
25
+ expect(detectStaticFramework(dir)).toBeNull();
26
+ });
27
+ it('SSR frameworks are never static-build: next/nuxt/sveltekit/remix/solidstart', () => {
28
+ for (const deps of [
29
+ { next: '1' }, { nuxt: '1' }, { '@sveltejs/kit': '1' },
30
+ { '@remix-run/node': '1' }, { '@remix-run/dev': '1' }, { '@solidjs/start': '1' },
31
+ ]) {
32
+ writePkg({ dependencies: { ...deps, vite: '^5.0.0' }, scripts: { build: 'x' } });
33
+ expect(detectStaticFramework(dir)).toBeNull();
34
+ }
35
+ });
36
+ it('specific frameworks beat the vite catch-all', () => {
37
+ writePkg({ dependencies: { astro: '^4.0.0' }, scripts: { build: 'astro build' } });
38
+ expect(detectStaticFramework(dir)).toEqual({ framework: 'astro', spa: false, outputDirs: ['dist'] });
39
+ });
40
+ it('detects gatsby (public/), cra (build/), eleventy (_site/)', () => {
41
+ writePkg({ dependencies: { gatsby: '^5.0.0' }, scripts: { build: 'gatsby build' } });
42
+ expect(detectStaticFramework(dir)).toEqual({ framework: 'gatsby', spa: false, outputDirs: ['public'] });
43
+ writePkg({ dependencies: { 'react-scripts': '^5.0.0' }, scripts: { build: 'react-scripts build' } });
44
+ expect(detectStaticFramework(dir)).toEqual({ framework: 'cra', spa: true, outputDirs: ['build'] });
45
+ writePkg({ devDependencies: { '@11ty/eleventy': '^2.0.0' }, scripts: { build: 'eleventy' } });
46
+ expect(detectStaticFramework(dir)).toEqual({ framework: 'eleventy', spa: false, outputDirs: ['_site'] });
47
+ });
48
+ it('angular: expands output candidates from angular.json outputPath', () => {
49
+ writePkg({ dependencies: { '@angular/core': '^17.0.0' }, scripts: { build: 'ng build' } });
50
+ fs.writeFileSync(path.join(dir, 'angular.json'), JSON.stringify({
51
+ projects: { 'my-app': { architect: { build: { options: { outputPath: 'dist/my-app' } } } } },
52
+ }));
53
+ expect(detectStaticFramework(dir)).toEqual({
54
+ framework: 'angular', spa: true,
55
+ outputDirs: ['dist/my-app/browser', 'dist/my-app'],
56
+ });
57
+ });
58
+ it('angular: falls back to dist/<projectName>/browser when outputPath absent', () => {
59
+ writePkg({ dependencies: { '@angular/core': '^17.0.0' }, scripts: { build: 'ng build' } });
60
+ fs.writeFileSync(path.join(dir, 'angular.json'), JSON.stringify({
61
+ projects: { 'my-app': { architect: { build: { options: {} } } } },
62
+ }));
63
+ expect(detectStaticFramework(dir)?.outputDirs).toEqual(['dist/my-app/browser', 'dist/my-app']);
64
+ });
65
+ it('no package.json → null; malformed package.json → null', () => {
66
+ expect(detectStaticFramework(dir)).toBeNull();
67
+ fs.writeFileSync(path.join(dir, 'package.json'), '{nope');
68
+ expect(detectStaticFramework(dir)).toBeNull();
69
+ });
70
+ });
71
+ describe('detectStaticFramework — stock dev-server start scripts do not defeat detection', () => {
72
+ // Stock scaffolds ship a `start` script that runs the framework's OWN
73
+ // dev server, not an app server: CRA `react-scripts start`, Angular
74
+ // `ng serve`, Gatsby `gatsby develop`, Eleventy `eleventy --serve`. The
75
+ // old rule ("any start script means dynamic") routed every one of these
76
+ // past the static-build path even though none of them run a real server.
77
+ it('real CRA script block (react-scripts start/build/test/eject) is still detected as cra', () => {
78
+ writePkg({
79
+ dependencies: { 'react-scripts': '^5.0.0' },
80
+ scripts: {
81
+ start: 'react-scripts start',
82
+ build: 'react-scripts build',
83
+ test: 'react-scripts test',
84
+ eject: 'react-scripts eject',
85
+ },
86
+ });
87
+ expect(detectStaticFramework(dir)).toEqual({ framework: 'cra', spa: true, outputDirs: ['build'] });
88
+ });
89
+ it('real Angular script block (ng serve) is still detected as angular', () => {
90
+ writePkg({
91
+ dependencies: { '@angular/core': '^17.0.0' },
92
+ scripts: { ng: 'ng', start: 'ng serve', build: 'ng build' },
93
+ });
94
+ expect(detectStaticFramework(dir)?.framework).toBe('angular');
95
+ });
96
+ it('real Gatsby script block (gatsby develop) is still detected as gatsby', () => {
97
+ writePkg({
98
+ dependencies: { gatsby: '^5.0.0' },
99
+ scripts: { develop: 'gatsby develop', start: 'gatsby develop', build: 'gatsby build' },
100
+ });
101
+ expect(detectStaticFramework(dir)).toEqual({ framework: 'gatsby', spa: false, outputDirs: ['public'] });
102
+ });
103
+ it('real Eleventy script block (eleventy --serve) is still detected as eleventy', () => {
104
+ writePkg({
105
+ devDependencies: { '@11ty/eleventy': '^2.0.0' },
106
+ scripts: { build: 'eleventy', start: 'eleventy --serve' },
107
+ });
108
+ expect(detectStaticFramework(dir)).toEqual({ framework: 'eleventy', spa: false, outputDirs: ['_site'] });
109
+ });
110
+ it('eleventy-base-blog real scaffold: npx-prefixed start script stays static-build', () => {
111
+ writePkg({
112
+ devDependencies: { '@11ty/eleventy': '^3.0.0' },
113
+ scripts: { build: 'npx @11ty/eleventy', start: 'npx @11ty/eleventy --serve --quiet' },
114
+ });
115
+ expect(detectStaticFramework(dir)?.framework).toBe('eleventy');
116
+ });
117
+ it('cra with a CUSTOM start script stays dynamic (null)', () => {
118
+ writePkg({
119
+ dependencies: { 'react-scripts': '^5.0.0' },
120
+ scripts: { start: 'node server.js', build: 'react-scripts build' },
121
+ });
122
+ expect(detectStaticFramework(dir)).toBeNull();
123
+ });
124
+ it('vite + start script that is just "vite preview" is still static-build (own dev server)', () => {
125
+ writePkg({
126
+ dependencies: { vite: '^5.0.0' },
127
+ scripts: { build: 'vite build', start: 'vite preview' },
128
+ });
129
+ expect(detectStaticFramework(dir)?.framework).toBe('vite');
130
+ });
131
+ it('vite + start script with extra flags still counts as the dev server (word-boundary match)', () => {
132
+ writePkg({
133
+ dependencies: { vite: '^5.0.0' },
134
+ scripts: { build: 'vite build', start: 'vite preview --port 4173' },
135
+ });
136
+ expect(detectStaticFramework(dir)?.framework).toBe('vite');
137
+ });
138
+ it('vite + a lookalike start script that only shares a prefix is NOT a word-boundary match (stays dynamic)', () => {
139
+ writePkg({
140
+ dependencies: { vite: '^5.0.0' },
141
+ scripts: { build: 'vite build', start: 'vite-custom-wrapper.js' },
142
+ });
143
+ expect(detectStaticFramework(dir)).toBeNull();
144
+ });
145
+ });
146
+ //# sourceMappingURL=detect-static-framework.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-static-framework.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/detect-static-framework.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=errors.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/errors.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,56 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { CODES, EXIT, exitCodeFor, isRetryable, buildError } from '../errors.js';
3
+ /**
4
+ * PINs the exit-code contract that makes the CLI machine-consumable.
5
+ *
6
+ * Before this existed, 112 of the CLI's 113 process.exit() calls resolved
7
+ * to 1, so a caller reading $? could not tell "your repo is broken" from
8
+ * "our server blipped". The registry is closed and the band is DERIVED
9
+ * from the code precisely so no future call site gets to pick a number.
10
+ *
11
+ * The "never 1" assertion is the load-bearing one: 1 is reserved for
12
+ * genuinely unclassified failures, so any KNOWN code reaching it means
13
+ * someone added a code without deciding what it means.
14
+ */
15
+ describe('exit code registry', () => {
16
+ it('derives a band for every registered code', () => {
17
+ for (const code of Object.keys(CODES)) {
18
+ expect(typeof exitCodeFor(code)).toBe('number');
19
+ }
20
+ });
21
+ it('never maps a known code to the unclassified band', () => {
22
+ for (const code of Object.keys(CODES)) {
23
+ expect(exitCodeFor(code)).not.toBe(EXIT.UNCLASSIFIED);
24
+ }
25
+ });
26
+ it('marks upstream failures retryable and local failures not', () => {
27
+ expect(isRetryable('NETWORK')).toBe(true);
28
+ expect(isRetryable('SERVER_ERROR')).toBe(true);
29
+ expect(isRetryable('ARTIFACT_TOO_LARGE')).toBe(false);
30
+ expect(isRetryable('NOT_AUTHENTICATED')).toBe(false);
31
+ });
32
+ it('puts auth at 10, local input at 30, quota at 50, upstream at 60', () => {
33
+ expect(exitCodeFor('NOT_AUTHENTICATED')).toBe(10);
34
+ expect(exitCodeFor('MISSING_ENTRYPOINT')).toBe(30);
35
+ expect(exitCodeFor('PAID_FEATURE')).toBe(50);
36
+ expect(exitCodeFor('NETWORK')).toBe(60);
37
+ });
38
+ it('builds an error carrying its own retryable bit', () => {
39
+ const err = buildError('NETWORK', "couldn't reach pushto.host.", {
40
+ fix: { label: 'try again', cmd: 'pushto deploy' },
41
+ });
42
+ expect(err).toEqual({
43
+ code: 'NETWORK',
44
+ human: "couldn't reach pushto.host.",
45
+ retryable: true,
46
+ fix: { label: 'try again', cmd: 'pushto deploy' },
47
+ });
48
+ });
49
+ it('omits optional keys it was not given', () => {
50
+ const err = buildError('NO_PROJECT', 'no project here.');
51
+ expect(err).toEqual({ code: 'NO_PROJECT', human: 'no project here.', retryable: false });
52
+ expect('fix' in err).toBe(false);
53
+ expect('stage' in err).toBe(false);
54
+ });
55
+ });
56
+ //# sourceMappingURL=errors.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/errors.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=interactive.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/interactive.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,79 @@
1
+ import { describe, it, expect, afterEach } from 'vitest';
2
+ import { canPrompt } from '../interactive.js';
3
+ /**
4
+ * PINs the rule that an agent gets correct behavior with ZERO flags.
5
+ *
6
+ * Requiring --yes would not have fixed the deploy hang, because an agent
7
+ * that has never read our docs does not know the flag exists. So prompting
8
+ * is RESOLVED from ambient state, and a flag can only ever turn it further
9
+ * off. Every branch below is a real way a machine invokes us.
10
+ */
11
+ const orig = {
12
+ stdin: process.stdin.isTTY,
13
+ stdout: process.stdout.isTTY,
14
+ ci: process.env.CI,
15
+ ni: process.env.PUSHTO_NONINTERACTIVE,
16
+ };
17
+ const setTTY = (stdin, stdout) => {
18
+ Object.defineProperty(process.stdin, 'isTTY', { value: stdin, configurable: true });
19
+ Object.defineProperty(process.stdout, 'isTTY', { value: stdout, configurable: true });
20
+ };
21
+ afterEach(() => {
22
+ setTTY(orig.stdin, orig.stdout);
23
+ if (orig.ci === undefined)
24
+ delete process.env.CI;
25
+ else
26
+ process.env.CI = orig.ci;
27
+ if (orig.ni === undefined)
28
+ delete process.env.PUSHTO_NONINTERACTIVE;
29
+ else
30
+ process.env.PUSHTO_NONINTERACTIVE = orig.ni;
31
+ });
32
+ describe('canPrompt', () => {
33
+ it('allows prompting for a human on a full terminal', () => {
34
+ setTTY(true, true);
35
+ delete process.env.CI;
36
+ delete process.env.PUSHTO_NONINTERACTIVE;
37
+ expect(canPrompt()).toBe(true);
38
+ });
39
+ it('refuses when stdin is not a tty (the agent case)', () => {
40
+ setTTY(false, true);
41
+ delete process.env.CI;
42
+ delete process.env.PUSHTO_NONINTERACTIVE;
43
+ expect(canPrompt()).toBe(false);
44
+ });
45
+ it('refuses when stdout is piped', () => {
46
+ setTTY(true, false);
47
+ delete process.env.CI;
48
+ delete process.env.PUSHTO_NONINTERACTIVE;
49
+ expect(canPrompt()).toBe(false);
50
+ });
51
+ it('refuses under CI', () => {
52
+ setTTY(true, true);
53
+ process.env.CI = '1';
54
+ delete process.env.PUSHTO_NONINTERACTIVE;
55
+ expect(canPrompt()).toBe(false);
56
+ });
57
+ it('refuses under PUSHTO_NONINTERACTIVE', () => {
58
+ setTTY(true, true);
59
+ delete process.env.CI;
60
+ process.env.PUSHTO_NONINTERACTIVE = '1';
61
+ expect(canPrompt()).toBe(false);
62
+ });
63
+ it('refuses when --json or --yes was passed, even on a real terminal', () => {
64
+ setTTY(true, true);
65
+ delete process.env.CI;
66
+ delete process.env.PUSHTO_NONINTERACTIVE;
67
+ expect(canPrompt({ json: true })).toBe(false);
68
+ expect(canPrompt({ yes: true })).toBe(false);
69
+ });
70
+ it('treats CI="" and CI="false" as not set, matching shell convention', () => {
71
+ setTTY(true, true);
72
+ delete process.env.PUSHTO_NONINTERACTIVE;
73
+ process.env.CI = '';
74
+ expect(canPrompt()).toBe(true);
75
+ process.env.CI = 'false';
76
+ expect(canPrompt()).toBe(true);
77
+ });
78
+ });
79
+ //# sourceMappingURL=interactive.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/interactive.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=output.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/output.test.ts"],"names":[],"mappings":""}