@pushto/cli 0.2.1 → 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 (184) 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 +230 -150
  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 +289 -54
  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 +52 -7
  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 +50 -23
  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 +21 -1
  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 +117 -14
  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.map +1 -1
  114. package/dist/lib/api.js +22 -4
  115. package/dist/lib/api.js.map +1 -1
  116. package/dist/lib/ask.d.ts +15 -0
  117. package/dist/lib/ask.d.ts.map +1 -0
  118. package/dist/lib/ask.js +24 -0
  119. package/dist/lib/ask.js.map +1 -0
  120. package/dist/lib/build-runner.d.ts +25 -0
  121. package/dist/lib/build-runner.d.ts.map +1 -0
  122. package/dist/lib/build-runner.js +141 -0
  123. package/dist/lib/build-runner.js.map +1 -0
  124. package/dist/lib/config.d.ts +6 -0
  125. package/dist/lib/config.d.ts.map +1 -1
  126. package/dist/lib/config.js +7 -1
  127. package/dist/lib/config.js.map +1 -1
  128. package/dist/lib/cron-tail.d.ts +10 -0
  129. package/dist/lib/cron-tail.d.ts.map +1 -0
  130. package/dist/lib/cron-tail.js +5 -0
  131. package/dist/lib/cron-tail.js.map +1 -0
  132. package/dist/lib/detect-static-framework.d.ts +31 -0
  133. package/dist/lib/detect-static-framework.d.ts.map +1 -0
  134. package/dist/lib/detect-static-framework.js +96 -0
  135. package/dist/lib/detect-static-framework.js.map +1 -0
  136. package/dist/lib/env-parse.d.ts +48 -0
  137. package/dist/lib/env-parse.d.ts.map +1 -0
  138. package/dist/lib/env-parse.js +91 -0
  139. package/dist/lib/env-parse.js.map +1 -0
  140. package/dist/lib/errors.d.ts +111 -0
  141. package/dist/lib/errors.d.ts.map +1 -0
  142. package/dist/lib/errors.js +64 -0
  143. package/dist/lib/errors.js.map +1 -0
  144. package/dist/lib/file-walker.d.ts +23 -0
  145. package/dist/lib/file-walker.d.ts.map +1 -0
  146. package/dist/lib/file-walker.js +114 -0
  147. package/dist/lib/file-walker.js.map +1 -0
  148. package/dist/lib/interactive.d.ts +13 -0
  149. package/dist/lib/interactive.d.ts.map +1 -0
  150. package/dist/lib/interactive.js +24 -0
  151. package/dist/lib/interactive.js.map +1 -0
  152. package/dist/lib/output.d.ts +24 -0
  153. package/dist/lib/output.d.ts.map +1 -0
  154. package/dist/lib/output.js +71 -0
  155. package/dist/lib/output.js.map +1 -0
  156. package/dist/lib/prepare-artifact.d.ts +22 -0
  157. package/dist/lib/prepare-artifact.d.ts.map +1 -0
  158. package/dist/lib/prepare-artifact.js +26 -0
  159. package/dist/lib/prepare-artifact.js.map +1 -0
  160. package/dist/lib/preview-args.d.ts +20 -0
  161. package/dist/lib/preview-args.d.ts.map +1 -0
  162. package/dist/lib/preview-args.js +19 -0
  163. package/dist/lib/preview-args.js.map +1 -0
  164. package/dist/lib/safe-json.d.ts +7 -2
  165. package/dist/lib/safe-json.d.ts.map +1 -1
  166. package/dist/lib/safe-json.js +23 -4
  167. package/dist/lib/safe-json.js.map +1 -1
  168. package/dist/lib/update-check.d.ts +17 -0
  169. package/dist/lib/update-check.d.ts.map +1 -0
  170. package/dist/lib/update-check.js +81 -0
  171. package/dist/lib/update-check.js.map +1 -0
  172. package/dist/lib/upload-limits.d.ts +17 -0
  173. package/dist/lib/upload-limits.d.ts.map +1 -0
  174. package/dist/lib/upload-limits.js +17 -0
  175. package/dist/lib/upload-limits.js.map +1 -0
  176. package/dist/lib/zip-project.d.ts +19 -0
  177. package/dist/lib/zip-project.d.ts.map +1 -0
  178. package/dist/lib/zip-project.js +39 -0
  179. package/dist/lib/zip-project.js.map +1 -0
  180. package/dist/version.d.ts +2 -0
  181. package/dist/version.d.ts.map +1 -0
  182. package/dist/version.js +16 -0
  183. package/dist/version.js.map +1 -0
  184. package/package.json +5 -8
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The `pushto preview` action grammar, as one pure function.
3
+ *
4
+ * The command's help and docs/cli teach "(create, ls, rm)". Before this
5
+ * seam the dispatcher had no `create` verb — any unknown action word was
6
+ * treated as a directory, so the documented `pushto preview create` died
7
+ * with "not a directory: create". A bare positional directory
8
+ * (`pushto preview dist`) still works.
9
+ */
10
+ export type PreviewAction = {
11
+ kind: 'create';
12
+ dir: string;
13
+ } | {
14
+ kind: 'ls';
15
+ } | {
16
+ kind: 'rm';
17
+ ref: string | undefined;
18
+ };
19
+ export declare const resolvePreviewAction: (action: string, args: string[]) => PreviewAction;
20
+ //# sourceMappingURL=preview-args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-args.d.ts","sourceRoot":"","sources":["../../src/lib/preview-args.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GACd;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAE5C,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,EAAE,MAAM,MAAM,EAAE,KAAG,aAKrE,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The `pushto preview` action grammar, as one pure function.
3
+ *
4
+ * The command's help and docs/cli teach "(create, ls, rm)". Before this
5
+ * seam the dispatcher had no `create` verb — any unknown action word was
6
+ * treated as a directory, so the documented `pushto preview create` died
7
+ * with "not a directory: create". A bare positional directory
8
+ * (`pushto preview dist`) still works.
9
+ */
10
+ export const resolvePreviewAction = (action, args) => {
11
+ if (action === 'ls' || action === 'list')
12
+ return { kind: 'ls' };
13
+ if (action === 'rm' || action === 'delete')
14
+ return { kind: 'rm', ref: args[0] };
15
+ if (action === 'create')
16
+ return { kind: 'create', dir: args[0] ?? '.' };
17
+ return { kind: 'create', dir: action.length > 0 ? action : '.' };
18
+ };
19
+ //# sourceMappingURL=preview-args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-args.js","sourceRoot":"","sources":["../../src/lib/preview-args.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAc,EAAE,IAAc,EAAiB,EAAE;IACpF,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAChE,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAChF,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;IACxE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;AACnE,CAAC,CAAC"}
@@ -1,7 +1,12 @@
1
1
  /**
2
2
  * Safely parse a Response as JSON.
3
- * Returns the parsed object, or a fallback error object if the response
4
- * isn't valid JSON (e.g., HTML error pages from the server).
3
+ * Returns the parsed object, or an `{ error }` envelope when the body
4
+ * isn't valid JSON. The error string includes the HTTP status, the
5
+ * request path, and a body preview so a downstream "> ${data.error}"
6
+ * print still tells the user (and us) what actually failed.
7
+ *
8
+ * Replaces the old "server returned non-JSON: " message that lost all
9
+ * context when the body was empty (e.g. an unhandled 500 from the API).
5
10
  */
6
11
  export declare const safeJson: <T = Record<string, unknown>>(res: Response) => Promise<T>;
7
12
  //# sourceMappingURL=safe-json.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"safe-json.d.ts","sourceRoot":"","sources":["../../src/lib/safe-json.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,QAAQ,GAAU,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxD,KAAK,QAAQ,KACZ,OAAO,CAAC,CAAC,CAOX,CAAC"}
1
+ {"version":3,"file":"safe-json.d.ts","sourceRoot":"","sources":["../../src/lib/safe-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ,GAAU,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxD,KAAK,QAAQ,KACZ,OAAO,CAAC,CAAC,CAuBX,CAAC"}
@@ -1,15 +1,34 @@
1
1
  /**
2
2
  * Safely parse a Response as JSON.
3
- * Returns the parsed object, or a fallback error object if the response
4
- * isn't valid JSON (e.g., HTML error pages from the server).
3
+ * Returns the parsed object, or an `{ error }` envelope when the body
4
+ * isn't valid JSON. The error string includes the HTTP status, the
5
+ * request path, and a body preview so a downstream "> ${data.error}"
6
+ * print still tells the user (and us) what actually failed.
7
+ *
8
+ * Replaces the old "server returned non-JSON: " message that lost all
9
+ * context when the body was empty (e.g. an unhandled 500 from the API).
5
10
  */
6
11
  export const safeJson = async (res) => {
7
12
  const text = await res.text();
13
+ if (text) {
14
+ try {
15
+ return JSON.parse(text);
16
+ }
17
+ catch {
18
+ // fall through
19
+ }
20
+ }
21
+ let path = '';
8
22
  try {
9
- return JSON.parse(text);
23
+ path = new URL(res.url).pathname;
10
24
  }
11
25
  catch {
12
- return { error: `server returned non-JSON: ${text.slice(0, 100)}` };
26
+ // res.url may be empty in some runtimes
13
27
  }
28
+ const where = path ? ` from ${path}` : '';
29
+ const error = text
30
+ ? `pushto.host returned ${res.status}${where}. body: ${text.slice(0, 200)}`
31
+ : `pushto.host returned ${res.status}${where} with an empty body — likely a server crash. try again, or email support@pushto.host if it sticks.`;
32
+ return { error };
14
33
  };
15
34
  //# sourceMappingURL=safe-json.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"safe-json.js","sourceRoot":"","sources":["../../src/lib/safe-json.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAC3B,GAAa,EACD,EAAE;IACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,6BAA6B,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAO,CAAC;IAC3E,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"safe-json.js","sourceRoot":"","sources":["../../src/lib/safe-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAC3B,GAAa,EACD,EAAE;IACd,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;IACH,CAAC;IAED,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,wCAAwC;IAC1C,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAE1C,MAAM,KAAK,GAAG,IAAI;QAChB,CAAC,CAAC,wBAAwB,GAAG,CAAC,MAAM,GAAG,KAAK,WAAW,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;QAC3E,CAAC,CAAC,wBAAwB,GAAG,CAAC,MAAM,GAAG,KAAK,oGAAoG,CAAC;IAEnJ,OAAO,EAAE,KAAK,EAAO,CAAC;AACxB,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ interface UpdateInfo {
2
+ current: string;
3
+ latest: string;
4
+ needsUpdate: boolean;
5
+ }
6
+ /**
7
+ * Check npm registry for a newer version of @pushto/cli.
8
+ * Caches the result for 24 hours to avoid slowing down every invocation.
9
+ * Returns null if the check was skipped (cached) or failed (network error).
10
+ */
11
+ export declare const checkForUpdate: (force?: boolean) => Promise<UpdateInfo | null>;
12
+ /** Read the version baked into this CLI build. The build script overwrites
13
+ * src/version.ts with the real value before each `bun build --compile`.
14
+ * Local dev (tsx src/index.ts) keeps the committed "0.0.0-dev". */
15
+ export declare const getCurrentVersion: () => string;
16
+ export {};
17
+ //# sourceMappingURL=update-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../../src/lib/update-check.ts"],"names":[],"mappings":"AAGA,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;CACtB;AAID;;;;GAIG;AACH,eAAO,MAAM,cAAc,GACzB,eAAa,KACZ,OAAO,CAAC,UAAU,GAAG,IAAI,CAiC3B,CAAC;AAoCF;;oEAEoE;AACpE,eAAO,MAAM,iBAAiB,QAAO,MAAiB,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { config } from './config.js';
2
+ import { VERSION } from '../version.js';
3
+ const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
4
+ /**
5
+ * Check npm registry for a newer version of @pushto/cli.
6
+ * Caches the result for 24 hours to avoid slowing down every invocation.
7
+ * Returns null if the check was skipped (cached) or failed (network error).
8
+ */
9
+ export const checkForUpdate = async (force = false) => {
10
+ const lastCheck = config.get('lastUpdateCheck');
11
+ if (!force && lastCheck && Date.now() - lastCheck < CHECK_INTERVAL_MS) {
12
+ // Return cached result if we checked recently
13
+ const cached = config.get('latestVersion');
14
+ if (cached) {
15
+ const current = getCurrentVersion();
16
+ return { current, latest: cached, needsUpdate: isNewer(cached, current) };
17
+ }
18
+ return null;
19
+ }
20
+ try {
21
+ const controller = new AbortController();
22
+ const timeout = setTimeout(() => controller.abort(), 3000);
23
+ const latest = await fetchLatestVersion(controller.signal);
24
+ clearTimeout(timeout);
25
+ if (!latest)
26
+ return null;
27
+ config.set('lastUpdateCheck', Date.now());
28
+ config.set('latestVersion', latest);
29
+ const current = getCurrentVersion();
30
+ return { current, latest, needsUpdate: isNewer(latest, current) };
31
+ }
32
+ catch {
33
+ // Network error, offline, timeout — don't bother the user
34
+ return null;
35
+ }
36
+ };
37
+ // Pick the right "latest version" source for how this CLI was installed.
38
+ // Homebrew binaries get versioned by GitHub releases on the homebrew-tap
39
+ // repo (the source repo is private). npm-installed CLIs check the npm
40
+ // registry. Mixing them caused the infinite "upgrade available → brew says
41
+ // already current → re-prompt" loop in <0.4.0.
42
+ const fetchLatestVersion = async (signal) => {
43
+ if (isBrewBinary()) {
44
+ const res = await fetch('https://api.github.com/repos/mydude-industries/homebrew-tap/releases/latest', { signal, headers: { Accept: 'application/vnd.github+json' } });
45
+ if (!res.ok)
46
+ return null;
47
+ const data = (await res.json());
48
+ return data.tag_name?.replace(/^v/, '') ?? null;
49
+ }
50
+ const res = await fetch('https://registry.npmjs.org/@pushto/cli/latest', { signal });
51
+ if (!res.ok)
52
+ return null;
53
+ const data = (await res.json());
54
+ return data.version ?? null;
55
+ };
56
+ const isBrewBinary = () => {
57
+ const exe = process.execPath;
58
+ return (exe.includes('/Cellar/') ||
59
+ exe.startsWith('/opt/homebrew/') ||
60
+ exe.includes('/linuxbrew/') ||
61
+ exe.includes('/home/linuxbrew/'));
62
+ };
63
+ /** Read the version baked into this CLI build. The build script overwrites
64
+ * src/version.ts with the real value before each `bun build --compile`.
65
+ * Local dev (tsx src/index.ts) keeps the committed "0.0.0-dev". */
66
+ export const getCurrentVersion = () => VERSION;
67
+ /** True if `a` is a newer semver than `b`. */
68
+ const isNewer = (a, b) => {
69
+ const pa = a.split('.').map(Number);
70
+ const pb = b.split('.').map(Number);
71
+ for (let i = 0; i < 3; i++) {
72
+ const av = pa[i] ?? 0;
73
+ const bv = pb[i] ?? 0;
74
+ if (av > bv)
75
+ return true;
76
+ if (av < bv)
77
+ return false;
78
+ }
79
+ return false;
80
+ };
81
+ //# sourceMappingURL=update-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/lib/update-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Upload-size cap that matches the server-side validation in
3
+ * apps/web/app/api/cli/projects/[slug]/upload/route.ts (line ~83).
4
+ *
5
+ * Single source of truth so doctor and deploy can't disagree:
6
+ * - doctor uses it to warn before the user even tries
7
+ * - deploy uses it to fail fast LOCALLY before wasting a ~30s upload
8
+ * that the server will 413 anyway
9
+ *
10
+ * If you bump this, bump the server check at the same time. Pre-fix,
11
+ * deploy.ts had its own MAX_ZIP_BYTES = 500MB constant — uploads
12
+ * between 50MB and 500MB went up the wire and got rejected after
13
+ * the long upload finished.
14
+ */
15
+ export declare const SERVER_UPLOAD_CAP_BYTES: number;
16
+ export declare const fmtMB: (bytes: number) => string;
17
+ //# sourceMappingURL=upload-limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-limits.d.ts","sourceRoot":"","sources":["../../src/lib/upload-limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,uBAAuB,QAAmB,CAAC;AAExD,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,KAAG,MAAiD,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Upload-size cap that matches the server-side validation in
3
+ * apps/web/app/api/cli/projects/[slug]/upload/route.ts (line ~83).
4
+ *
5
+ * Single source of truth so doctor and deploy can't disagree:
6
+ * - doctor uses it to warn before the user even tries
7
+ * - deploy uses it to fail fast LOCALLY before wasting a ~30s upload
8
+ * that the server will 413 anyway
9
+ *
10
+ * If you bump this, bump the server check at the same time. Pre-fix,
11
+ * deploy.ts had its own MAX_ZIP_BYTES = 500MB constant — uploads
12
+ * between 50MB and 500MB went up the wire and got rejected after
13
+ * the long upload finished.
14
+ */
15
+ export const SERVER_UPLOAD_CAP_BYTES = 50 * 1024 * 1024;
16
+ export const fmtMB = (bytes) => `${(bytes / 1024 / 1024).toFixed(1)}MB`;
17
+ //# sourceMappingURL=upload-limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-limits.js","sourceRoot":"","sources":["../../src/lib/upload-limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAExD,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Git metadata for the current working tree. Falls back to safe defaults
3
+ * outside a git repo so a deploy/preview from a plain folder still works.
4
+ */
5
+ export declare const getGitInfo: () => {
6
+ hash: string | null;
7
+ message: string | null;
8
+ branch: string;
9
+ };
10
+ /**
11
+ * Zip a directory's deployable files into an in-memory buffer. Respects
12
+ * .gitignore/.pushtoignore + the ALWAYS_IGNORE footgun list via walkProject.
13
+ * Shared by `pushto` (deploy) and `pushto preview` so the two can't drift.
14
+ */
15
+ export declare const zipDirectory: (dir: string) => Promise<{
16
+ buffer: Buffer;
17
+ fileCount: number;
18
+ }>;
19
+ //# sourceMappingURL=zip-project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zip-project.d.ts","sourceRoot":"","sources":["../../src/lib/zip-project.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,eAAO,MAAM,UAAU,QAAO;IAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAS1F,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAiBvF,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { execSync } from 'node:child_process';
2
+ import archiver from 'archiver';
3
+ import { walkProject } from './file-walker.js';
4
+ /**
5
+ * Git metadata for the current working tree. Falls back to safe defaults
6
+ * outside a git repo so a deploy/preview from a plain folder still works.
7
+ */
8
+ export const getGitInfo = () => {
9
+ try {
10
+ const hash = execSync('git rev-parse --short HEAD', { stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim();
11
+ const message = execSync('git log -1 --pretty=%s', { stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim();
12
+ const branch = execSync('git rev-parse --abbrev-ref HEAD', { stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim();
13
+ return { hash, message, branch };
14
+ }
15
+ catch {
16
+ return { hash: null, message: null, branch: 'main' };
17
+ }
18
+ };
19
+ /**
20
+ * Zip a directory's deployable files into an in-memory buffer. Respects
21
+ * .gitignore/.pushtoignore + the ALWAYS_IGNORE footgun list via walkProject.
22
+ * Shared by `pushto` (deploy) and `pushto preview` so the two can't drift.
23
+ */
24
+ export const zipDirectory = (dir) => {
25
+ return new Promise((resolve, reject) => {
26
+ const archive = archiver('zip', { zlib: { level: 9 } });
27
+ const chunks = [];
28
+ archive.on('data', (chunk) => chunks.push(chunk));
29
+ archive.on('end', () => resolve({ buffer: Buffer.concat(chunks), fileCount }));
30
+ archive.on('error', reject);
31
+ const files = walkProject(dir);
32
+ const fileCount = files.length;
33
+ for (const file of files) {
34
+ archive.file(file.fullPath, { name: file.archivePath });
35
+ }
36
+ archive.finalize();
37
+ });
38
+ };
39
+ //# sourceMappingURL=zip-project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zip-project.js","sourceRoot":"","sources":["../../src/lib/zip-project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,GAAoE,EAAE;IAC9F,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,4BAA4B,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QAC7G,MAAM,OAAO,GAAG,QAAQ,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QAC5G,MAAM,MAAM,GAAG,QAAQ,CAAC,iCAAiC,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QACpH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACvD,CAAC;AACH,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAW,EAAkD,EAAE;IAC1F,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACxD,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QAC/E,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAE5B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO,CAAC,QAAQ,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const VERSION = "0.4.6";
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,OAAO,UAAU,CAAC"}
@@ -0,0 +1,16 @@
1
+ // AUTO-GENERATED FILE — DO NOT EDIT BY HAND.
2
+ //
3
+ // The literal "0.4.6" below is a placeholder. In CI release
4
+ // builds (scripts/build-binaries.sh), `sed` replaces it with the real version
5
+ // string before each `bun build --compile` invocation, and the build asserts
6
+ // the version was actually embedded by greping the binary. This is the
7
+ // approach that finally stuck after `bun build --define` and the `cat >
8
+ // version.ts` overwrite both lost the version on darwin-arm64 cross-compiles
9
+ // (linux-amd64 worked fine — the failure mode was platform-specific and
10
+ // silent).
11
+ //
12
+ // In local dev (`tsx src/index.ts`) the placeholder stays put and `pushto
13
+ // --version` reports the literal "0.4.6" — a giveaway
14
+ // that you're on the source tree, not a release build.
15
+ export const VERSION = "0.4.6";
16
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,EAAE;AACF,4DAA4D;AAC5D,8EAA8E;AAC9E,6EAA6E;AAC7E,uEAAuE;AACvE,wEAAwE;AACxE,6EAA6E;AAC7E,wEAAwE;AACxE,WAAW;AACX,EAAE;AACF,0EAA0E;AAC1E,sDAAsD;AACtD,uDAAuD;AACvD,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushto/cli",
3
- "version": "0.2.1",
3
+ "version": "0.4.6",
4
4
  "description": "Deploy to pushto.host from your terminal",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,8 +11,10 @@
11
11
  ],
12
12
  "scripts": {
13
13
  "build": "tsc",
14
- "dev": "tsx src/index.ts",
14
+ "start": "tsx src/index.ts",
15
15
  "lint": "tsc --noEmit",
16
+ "typecheck": "tsc --noEmit",
17
+ "test": "vitest run",
16
18
  "prepublishOnly": "npm run build"
17
19
  },
18
20
  "dependencies": {
@@ -20,12 +22,7 @@
20
22
  "chalk": "^5.4.0",
21
23
  "commander": "^13.0.0",
22
24
  "conf": "^13.0.0",
25
+ "ignore": "^7.0.0",
23
26
  "ora": "^8.1.0"
24
- },
25
- "devDependencies": {
26
- "@types/archiver": "^7.0.0",
27
- "@types/node": "^22.10.0",
28
- "tsx": "^4.19.0",
29
- "typescript": "^5.7.0"
30
27
  }
31
28
  }