@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.
- package/dist/commands/__tests__/deploy-domain.test.d.ts +2 -0
- package/dist/commands/__tests__/deploy-domain.test.d.ts.map +1 -0
- package/dist/commands/__tests__/deploy-domain.test.js +41 -0
- package/dist/commands/__tests__/deploy-domain.test.js.map +1 -0
- package/dist/commands/__tests__/headless-smoke.test.d.ts +2 -0
- package/dist/commands/__tests__/headless-smoke.test.d.ts.map +1 -0
- package/dist/commands/__tests__/headless-smoke.test.js +110 -0
- package/dist/commands/__tests__/headless-smoke.test.js.map +1 -0
- package/dist/commands/auth.d.ts +2 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +77 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/cron.d.ts +2 -0
- package/dist/commands/cron.d.ts.map +1 -0
- package/dist/commands/cron.js +157 -0
- package/dist/commands/cron.js.map +1 -0
- package/dist/commands/db.d.ts +4 -0
- package/dist/commands/db.d.ts.map +1 -0
- package/dist/commands/db.js +63 -0
- package/dist/commands/db.js.map +1 -0
- package/dist/commands/deploy.d.ts +16 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +230 -150
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +289 -54
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/domain.d.ts.map +1 -1
- package/dist/commands/domain.js +52 -7
- package/dist/commands/domain.js.map +1 -1
- package/dist/commands/echo.d.ts +2 -0
- package/dist/commands/echo.d.ts.map +1 -0
- package/dist/commands/echo.js +227 -0
- package/dist/commands/echo.js.map +1 -0
- package/dist/commands/env.d.ts +3 -1
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +76 -50
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/init.d.ts +3 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +58 -11
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +50 -23
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logs.d.ts +3 -1
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +77 -21
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/mail.d.ts +2 -0
- package/dist/commands/mail.d.ts.map +1 -0
- package/dist/commands/mail.js +105 -0
- package/dist/commands/mail.js.map +1 -0
- package/dist/commands/open.d.ts.map +1 -1
- package/dist/commands/open.js +21 -1
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/preview.d.ts +22 -0
- package/dist/commands/preview.d.ts.map +1 -0
- package/dist/commands/preview.js +223 -0
- package/dist/commands/preview.js.map +1 -0
- package/dist/commands/status.d.ts +3 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +62 -12
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +73 -10
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/commands/use.d.ts +2 -0
- package/dist/commands/use.d.ts.map +1 -0
- package/dist/commands/use.js +108 -0
- package/dist/commands/use.js.map +1 -0
- package/dist/commands/vault.d.ts +2 -0
- package/dist/commands/vault.d.ts.map +1 -0
- package/dist/commands/vault.js +119 -0
- package/dist/commands/vault.js.map +1 -0
- package/dist/commands/whoami.d.ts.map +1 -1
- package/dist/commands/whoami.js +12 -1
- package/dist/commands/whoami.js.map +1 -1
- package/dist/index.js +117 -14
- package/dist/index.js.map +1 -1
- package/dist/lib/__tests__/build-runner.test.d.ts +2 -0
- package/dist/lib/__tests__/build-runner.test.d.ts.map +1 -0
- package/dist/lib/__tests__/build-runner.test.js +119 -0
- package/dist/lib/__tests__/build-runner.test.js.map +1 -0
- package/dist/lib/__tests__/cron-tail.test.d.ts +2 -0
- package/dist/lib/__tests__/cron-tail.test.d.ts.map +1 -0
- package/dist/lib/__tests__/cron-tail.test.js +27 -0
- package/dist/lib/__tests__/cron-tail.test.js.map +1 -0
- package/dist/lib/__tests__/detect-static-framework.test.d.ts +2 -0
- package/dist/lib/__tests__/detect-static-framework.test.d.ts.map +1 -0
- package/dist/lib/__tests__/detect-static-framework.test.js +146 -0
- package/dist/lib/__tests__/detect-static-framework.test.js.map +1 -0
- package/dist/lib/__tests__/errors.test.d.ts +2 -0
- package/dist/lib/__tests__/errors.test.d.ts.map +1 -0
- package/dist/lib/__tests__/errors.test.js +56 -0
- package/dist/lib/__tests__/errors.test.js.map +1 -0
- package/dist/lib/__tests__/interactive.test.d.ts +2 -0
- package/dist/lib/__tests__/interactive.test.d.ts.map +1 -0
- package/dist/lib/__tests__/interactive.test.js +79 -0
- package/dist/lib/__tests__/interactive.test.js.map +1 -0
- package/dist/lib/__tests__/output.test.d.ts +2 -0
- package/dist/lib/__tests__/output.test.d.ts.map +1 -0
- package/dist/lib/__tests__/output.test.js +144 -0
- package/dist/lib/__tests__/output.test.js.map +1 -0
- package/dist/lib/__tests__/prepare-artifact.test.d.ts +2 -0
- package/dist/lib/__tests__/prepare-artifact.test.d.ts.map +1 -0
- package/dist/lib/__tests__/prepare-artifact.test.js +55 -0
- package/dist/lib/__tests__/prepare-artifact.test.js.map +1 -0
- package/dist/lib/__tests__/preview-args.test.d.ts +2 -0
- package/dist/lib/__tests__/preview-args.test.d.ts.map +1 -0
- package/dist/lib/__tests__/preview-args.test.js +37 -0
- package/dist/lib/__tests__/preview-args.test.js.map +1 -0
- package/dist/lib/api.d.ts.map +1 -1
- package/dist/lib/api.js +22 -4
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/ask.d.ts +15 -0
- package/dist/lib/ask.d.ts.map +1 -0
- package/dist/lib/ask.js +24 -0
- package/dist/lib/ask.js.map +1 -0
- package/dist/lib/build-runner.d.ts +25 -0
- package/dist/lib/build-runner.d.ts.map +1 -0
- package/dist/lib/build-runner.js +141 -0
- package/dist/lib/build-runner.js.map +1 -0
- package/dist/lib/config.d.ts +6 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +7 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/cron-tail.d.ts +10 -0
- package/dist/lib/cron-tail.d.ts.map +1 -0
- package/dist/lib/cron-tail.js +5 -0
- package/dist/lib/cron-tail.js.map +1 -0
- package/dist/lib/detect-static-framework.d.ts +31 -0
- package/dist/lib/detect-static-framework.d.ts.map +1 -0
- package/dist/lib/detect-static-framework.js +96 -0
- package/dist/lib/detect-static-framework.js.map +1 -0
- package/dist/lib/env-parse.d.ts +48 -0
- package/dist/lib/env-parse.d.ts.map +1 -0
- package/dist/lib/env-parse.js +91 -0
- package/dist/lib/env-parse.js.map +1 -0
- package/dist/lib/errors.d.ts +111 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +64 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/file-walker.d.ts +23 -0
- package/dist/lib/file-walker.d.ts.map +1 -0
- package/dist/lib/file-walker.js +114 -0
- package/dist/lib/file-walker.js.map +1 -0
- package/dist/lib/interactive.d.ts +13 -0
- package/dist/lib/interactive.d.ts.map +1 -0
- package/dist/lib/interactive.js +24 -0
- package/dist/lib/interactive.js.map +1 -0
- package/dist/lib/output.d.ts +24 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +71 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/prepare-artifact.d.ts +22 -0
- package/dist/lib/prepare-artifact.d.ts.map +1 -0
- package/dist/lib/prepare-artifact.js +26 -0
- package/dist/lib/prepare-artifact.js.map +1 -0
- package/dist/lib/preview-args.d.ts +20 -0
- package/dist/lib/preview-args.d.ts.map +1 -0
- package/dist/lib/preview-args.js +19 -0
- package/dist/lib/preview-args.js.map +1 -0
- package/dist/lib/safe-json.d.ts +7 -2
- package/dist/lib/safe-json.d.ts.map +1 -1
- package/dist/lib/safe-json.js +23 -4
- package/dist/lib/safe-json.js.map +1 -1
- package/dist/lib/update-check.d.ts +17 -0
- package/dist/lib/update-check.d.ts.map +1 -0
- package/dist/lib/update-check.js +81 -0
- package/dist/lib/update-check.js.map +1 -0
- package/dist/lib/upload-limits.d.ts +17 -0
- package/dist/lib/upload-limits.d.ts.map +1 -0
- package/dist/lib/upload-limits.js +17 -0
- package/dist/lib/upload-limits.js.map +1 -0
- package/dist/lib/zip-project.d.ts +19 -0
- package/dist/lib/zip-project.d.ts.map +1 -0
- package/dist/lib/zip-project.js +39 -0
- package/dist/lib/zip-project.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +16 -0
- package/dist/version.js.map +1 -0
- package/package.json +5 -8
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a .env file's content into a key/value record.
|
|
3
|
+
*
|
|
4
|
+
* Every surface that accepts a .env file speaks through this parser:
|
|
5
|
+
* `pushto deploy` (auto-import on every deploy), `pushto env push`, and the
|
|
6
|
+
* dashboard's import box + raw editor. Pre-fix the dashboard hand-rolled its
|
|
7
|
+
* own parse and the two drifted — `export KEY=value` lines (copied from a
|
|
8
|
+
* .bashrc) were rejected in the dashboard, and inline comments were stored
|
|
9
|
+
* INTO the value (`PORT=3000 # default port` saved a value of
|
|
10
|
+
* `3000 # default port`).
|
|
11
|
+
*
|
|
12
|
+
* This file exists twice, byte-identical: apps/cli/src/lib/env-parse.ts and
|
|
13
|
+
* apps/web/lib/env-parse.ts. The web app can't import from apps/cli, and the
|
|
14
|
+
* published CLI deliberately carries no workspace deps — a vitest pin
|
|
15
|
+
* (apps/web/lib/__tests__/env-parse.test.ts) keeps the copies in sync
|
|
16
|
+
* instead. Edit one, copy to the other, or the pin fails.
|
|
17
|
+
*
|
|
18
|
+
* Supports:
|
|
19
|
+
* - bare assignments: KEY=value
|
|
20
|
+
* - `export` prefix: export KEY=value ← copied from .bashrc
|
|
21
|
+
* - quoted values: KEY="value with spaces" KEY='single quoted'
|
|
22
|
+
* - inline trailing comment: PORT=3000 # default port (only when value is unquoted)
|
|
23
|
+
* - blank lines + #-comments
|
|
24
|
+
*
|
|
25
|
+
* Does NOT support (and pushto's server-side validator would reject):
|
|
26
|
+
* - multi-line quoted values
|
|
27
|
+
* - escape sequences inside double quotes (treated literally)
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Full parse: valid pairs plus a per-line skip list with reasons, so
|
|
31
|
+
* consumers can tell the user WHICH lines didn't make it and why instead
|
|
32
|
+
* of importing silently-fewer vars than the file holds.
|
|
33
|
+
*/
|
|
34
|
+
export const parseEnvContent = (content) => {
|
|
35
|
+
const vars = {};
|
|
36
|
+
const skipped = [];
|
|
37
|
+
const lines = content.split('\n');
|
|
38
|
+
for (let i = 0; i < lines.length; i++) {
|
|
39
|
+
let trimmed = lines[i].trim();
|
|
40
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
41
|
+
continue;
|
|
42
|
+
// Strip the bash-export prefix that people copy from their shell or
|
|
43
|
+
// .bashrc (`export DATABASE_URL=postgres://...`). Pre-fix this parsed
|
|
44
|
+
// as key=`export DATABASE_URL` which the server rejects on the
|
|
45
|
+
// [A-Z_] validator — DATABASE_URL silently never made it remote
|
|
46
|
+
// despite the success message claiming X vars imported.
|
|
47
|
+
if (trimmed.startsWith('export ')) {
|
|
48
|
+
trimmed = trimmed.slice(7).trim();
|
|
49
|
+
}
|
|
50
|
+
const eqIdx = trimmed.indexOf('=');
|
|
51
|
+
if (eqIdx === -1) {
|
|
52
|
+
skipped.push({ key: `line ${i + 1}`, reason: 'no `=` separator' });
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
56
|
+
let value = trimmed.slice(eqIdx + 1).trim();
|
|
57
|
+
// Strip inline comments AFTER the value (only when not inside quotes).
|
|
58
|
+
// Common pattern: `PORT=3000 # default port`. The space-before-hash
|
|
59
|
+
// requirement avoids eating fragments of values that legitimately
|
|
60
|
+
// contain # (e.g. URLs with fragments, color codes like #ff0000 in
|
|
61
|
+
// some configs).
|
|
62
|
+
if (!value.startsWith('"') && !value.startsWith("'")) {
|
|
63
|
+
const hashIdx = value.indexOf('#');
|
|
64
|
+
if (hashIdx > 0 && /\s/.test(value[hashIdx - 1] ?? '')) {
|
|
65
|
+
value = value.slice(0, hashIdx).trim();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Strip surrounding quotes (matched pair only; a lone quote stays).
|
|
69
|
+
if (value.length >= 2 &&
|
|
70
|
+
((value.startsWith('"') && value.endsWith('"')) ||
|
|
71
|
+
(value.startsWith("'") && value.endsWith("'")))) {
|
|
72
|
+
value = value.slice(1, -1);
|
|
73
|
+
}
|
|
74
|
+
if (!key) {
|
|
75
|
+
skipped.push({ key: `line ${i + 1}`, reason: 'missing key before `=`' });
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (!value) {
|
|
79
|
+
skipped.push({ key, reason: 'empty value' });
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
vars[key] = value;
|
|
83
|
+
}
|
|
84
|
+
return { vars, skipped };
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Record-only view for callers that don't surface skip reasons.
|
|
88
|
+
* Same parse, skips dropped.
|
|
89
|
+
*/
|
|
90
|
+
export const parseEnvFile = (content) => parseEnvContent(content).vars;
|
|
91
|
+
//# sourceMappingURL=env-parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-parse.js","sourceRoot":"","sources":["../../src/lib/env-parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { PushtoError, PushtoErrorFix, PushtoErrorStage } from '@pushto/shared/errors';
|
|
2
|
+
/**
|
|
3
|
+
* Exit bands. A caller that reads only $? still behaves correctly, because
|
|
4
|
+
* the band alone says what to do next.
|
|
5
|
+
*/
|
|
6
|
+
export declare const EXIT: {
|
|
7
|
+
readonly OK: 0;
|
|
8
|
+
/** reserved for genuinely unclassified failures — never reachable from a known code */
|
|
9
|
+
readonly UNCLASSIFIED: 1;
|
|
10
|
+
readonly USAGE: 2;
|
|
11
|
+
readonly AUTH: 10;
|
|
12
|
+
readonly NOT_FOUND: 20;
|
|
13
|
+
readonly INVALID_INPUT: 30;
|
|
14
|
+
readonly BUILD_FAILED: 40;
|
|
15
|
+
readonly QUOTA: 50;
|
|
16
|
+
readonly UPSTREAM: 60;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* The closed registry. Adding a code here is the ONLY way to add one, which
|
|
20
|
+
* is what stops a call site from inventing an exit number under time
|
|
21
|
+
* pressure — the failure mode that produced 112 identical exit(1)s.
|
|
22
|
+
*/
|
|
23
|
+
export declare const CODES: {
|
|
24
|
+
readonly NOT_AUTHENTICATED: {
|
|
25
|
+
readonly band: 10;
|
|
26
|
+
readonly retryable: false;
|
|
27
|
+
};
|
|
28
|
+
readonly SESSION_EXPIRED: {
|
|
29
|
+
readonly band: 10;
|
|
30
|
+
readonly retryable: false;
|
|
31
|
+
};
|
|
32
|
+
readonly NO_PROJECT: {
|
|
33
|
+
readonly band: 20;
|
|
34
|
+
readonly retryable: false;
|
|
35
|
+
};
|
|
36
|
+
readonly PROJECT_NOT_FOUND: {
|
|
37
|
+
readonly band: 20;
|
|
38
|
+
readonly retryable: false;
|
|
39
|
+
};
|
|
40
|
+
readonly NO_DEPLOYMENT: {
|
|
41
|
+
readonly band: 20;
|
|
42
|
+
readonly retryable: false;
|
|
43
|
+
};
|
|
44
|
+
readonly BAD_USAGE: {
|
|
45
|
+
readonly band: 2;
|
|
46
|
+
readonly retryable: false;
|
|
47
|
+
};
|
|
48
|
+
readonly MISSING_ENTRYPOINT: {
|
|
49
|
+
readonly band: 30;
|
|
50
|
+
readonly retryable: false;
|
|
51
|
+
};
|
|
52
|
+
readonly NO_FILES: {
|
|
53
|
+
readonly band: 30;
|
|
54
|
+
readonly retryable: false;
|
|
55
|
+
};
|
|
56
|
+
readonly ARTIFACT_TOO_LARGE: {
|
|
57
|
+
readonly band: 30;
|
|
58
|
+
readonly retryable: false;
|
|
59
|
+
};
|
|
60
|
+
readonly INVALID_ENV_KEY: {
|
|
61
|
+
readonly band: 30;
|
|
62
|
+
readonly retryable: false;
|
|
63
|
+
};
|
|
64
|
+
readonly DB_ALREADY_EXISTS: {
|
|
65
|
+
readonly band: 30;
|
|
66
|
+
readonly retryable: false;
|
|
67
|
+
};
|
|
68
|
+
readonly BUILD_FAILED: {
|
|
69
|
+
readonly band: 40;
|
|
70
|
+
readonly retryable: false;
|
|
71
|
+
};
|
|
72
|
+
readonly CONTAINER_BOOT_FAILED: {
|
|
73
|
+
readonly band: 40;
|
|
74
|
+
readonly retryable: false;
|
|
75
|
+
};
|
|
76
|
+
readonly PAID_FEATURE: {
|
|
77
|
+
readonly band: 50;
|
|
78
|
+
readonly retryable: false;
|
|
79
|
+
};
|
|
80
|
+
readonly QUOTA_EXCEEDED: {
|
|
81
|
+
readonly band: 50;
|
|
82
|
+
readonly retryable: false;
|
|
83
|
+
};
|
|
84
|
+
readonly NETWORK: {
|
|
85
|
+
readonly band: 60;
|
|
86
|
+
readonly retryable: true;
|
|
87
|
+
};
|
|
88
|
+
readonly SERVER_ERROR: {
|
|
89
|
+
readonly band: 60;
|
|
90
|
+
readonly retryable: true;
|
|
91
|
+
};
|
|
92
|
+
readonly DB_PROVISION_FAILED: {
|
|
93
|
+
readonly band: 60;
|
|
94
|
+
readonly retryable: true;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
export type PushtoErrorCode = keyof typeof CODES;
|
|
98
|
+
export declare const exitCodeFor: (code: PushtoErrorCode) => number;
|
|
99
|
+
export declare const isRetryable: (code: PushtoErrorCode) => boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Build an error carrying the retryable bit derived from its code, so a call
|
|
102
|
+
* site can never disagree with the registry about whether a retry is sane.
|
|
103
|
+
* Optional keys are omitted rather than set to undefined, so JSON.stringify
|
|
104
|
+
* produces a clean payload.
|
|
105
|
+
*/
|
|
106
|
+
export declare const buildError: (code: PushtoErrorCode, human: string, extra?: {
|
|
107
|
+
fix?: PushtoErrorFix;
|
|
108
|
+
stage?: PushtoErrorStage;
|
|
109
|
+
details?: Record<string, unknown>;
|
|
110
|
+
}) => PushtoError;
|
|
111
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE3F;;;GAGG;AACH,eAAO,MAAM,IAAI;;IAEf,uFAAuF;;;;;;;;;CAS/E,CAAC;AAOX;;;;GAIG;AACH,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuB2B,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,KAAK,CAAC;AAEjD,eAAO,MAAM,WAAW,GAAI,MAAM,eAAe,KAAG,MAA0B,CAAC;AAE/E,eAAO,MAAM,WAAW,GAAI,MAAM,eAAe,KAAG,OAAgC,CAAC;AAErF;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GACrB,MAAM,eAAe,EACrB,OAAO,MAAM,EACb,QAAQ;IAAE,GAAG,CAAC,EAAE,cAAc,CAAC;IAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,KAC5F,WAMF,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exit bands. A caller that reads only $? still behaves correctly, because
|
|
3
|
+
* the band alone says what to do next.
|
|
4
|
+
*/
|
|
5
|
+
export const EXIT = {
|
|
6
|
+
OK: 0,
|
|
7
|
+
/** reserved for genuinely unclassified failures — never reachable from a known code */
|
|
8
|
+
UNCLASSIFIED: 1,
|
|
9
|
+
USAGE: 2,
|
|
10
|
+
AUTH: 10,
|
|
11
|
+
NOT_FOUND: 20,
|
|
12
|
+
INVALID_INPUT: 30,
|
|
13
|
+
BUILD_FAILED: 40,
|
|
14
|
+
QUOTA: 50,
|
|
15
|
+
UPSTREAM: 60,
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The closed registry. Adding a code here is the ONLY way to add one, which
|
|
19
|
+
* is what stops a call site from inventing an exit number under time
|
|
20
|
+
* pressure — the failure mode that produced 112 identical exit(1)s.
|
|
21
|
+
*/
|
|
22
|
+
export const CODES = {
|
|
23
|
+
NOT_AUTHENTICATED: { band: EXIT.AUTH, retryable: false },
|
|
24
|
+
SESSION_EXPIRED: { band: EXIT.AUTH, retryable: false },
|
|
25
|
+
NO_PROJECT: { band: EXIT.NOT_FOUND, retryable: false },
|
|
26
|
+
PROJECT_NOT_FOUND: { band: EXIT.NOT_FOUND, retryable: false },
|
|
27
|
+
NO_DEPLOYMENT: { band: EXIT.NOT_FOUND, retryable: false },
|
|
28
|
+
BAD_USAGE: { band: EXIT.USAGE, retryable: false },
|
|
29
|
+
MISSING_ENTRYPOINT: { band: EXIT.INVALID_INPUT, retryable: false },
|
|
30
|
+
NO_FILES: { band: EXIT.INVALID_INPUT, retryable: false },
|
|
31
|
+
ARTIFACT_TOO_LARGE: { band: EXIT.INVALID_INPUT, retryable: false },
|
|
32
|
+
INVALID_ENV_KEY: { band: EXIT.INVALID_INPUT, retryable: false },
|
|
33
|
+
// The request was well-formed but wrong for the current state: the project
|
|
34
|
+
// already has a live database. Retrying identically cannot succeed, and the
|
|
35
|
+
// caller's move is to use the existing one, so this sits with invalid input
|
|
36
|
+
// rather than in the upstream/retryable band.
|
|
37
|
+
DB_ALREADY_EXISTS: { band: EXIT.INVALID_INPUT, retryable: false },
|
|
38
|
+
BUILD_FAILED: { band: EXIT.BUILD_FAILED, retryable: false },
|
|
39
|
+
CONTAINER_BOOT_FAILED: { band: EXIT.BUILD_FAILED, retryable: false },
|
|
40
|
+
PAID_FEATURE: { band: EXIT.QUOTA, retryable: false },
|
|
41
|
+
QUOTA_EXCEEDED: { band: EXIT.QUOTA, retryable: false },
|
|
42
|
+
NETWORK: { band: EXIT.UPSTREAM, retryable: true },
|
|
43
|
+
SERVER_ERROR: { band: EXIT.UPSTREAM, retryable: true },
|
|
44
|
+
DB_PROVISION_FAILED: { band: EXIT.UPSTREAM, retryable: true },
|
|
45
|
+
};
|
|
46
|
+
export const exitCodeFor = (code) => CODES[code].band;
|
|
47
|
+
export const isRetryable = (code) => CODES[code].retryable;
|
|
48
|
+
/**
|
|
49
|
+
* Build an error carrying the retryable bit derived from its code, so a call
|
|
50
|
+
* site can never disagree with the registry about whether a retry is sane.
|
|
51
|
+
* Optional keys are omitted rather than set to undefined, so JSON.stringify
|
|
52
|
+
* produces a clean payload.
|
|
53
|
+
*/
|
|
54
|
+
export const buildError = (code, human, extra) => {
|
|
55
|
+
const err = { code, human, retryable: isRetryable(code) };
|
|
56
|
+
if (extra?.fix)
|
|
57
|
+
err.fix = extra.fix;
|
|
58
|
+
if (extra?.stage)
|
|
59
|
+
err.stage = extra.stage;
|
|
60
|
+
if (extra?.details)
|
|
61
|
+
err.details = extra.details;
|
|
62
|
+
return err;
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type Ignore } from 'ignore';
|
|
2
|
+
export declare const ALWAYS_IGNORE: string[];
|
|
3
|
+
export declare const loadIgnoreFilter: (rootDir: string) => Ignore;
|
|
4
|
+
export interface WalkedFile {
|
|
5
|
+
/** Absolute filesystem path. */
|
|
6
|
+
fullPath: string;
|
|
7
|
+
/** Path relative to rootDir, with forward-slash separators (zip-archive style). */
|
|
8
|
+
archivePath: string;
|
|
9
|
+
/** File size in bytes. */
|
|
10
|
+
sizeBytes: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Walk a project directory using the same ignore semantics deploy.ts uses
|
|
14
|
+
* to build the deploy zip. Skips symlinks (traversal protection) and
|
|
15
|
+
* caps depth at 20.
|
|
16
|
+
*
|
|
17
|
+
* Both deploy.ts (zip the matched files) and doctor.ts (preview the
|
|
18
|
+
* matched files: count, total size, biggest) call this. If the two ever
|
|
19
|
+
* disagreed, doctor's "looks fine" would mismatch deploy's "exceeds limit"
|
|
20
|
+
* — frustrating to debug. One source = one truth.
|
|
21
|
+
*/
|
|
22
|
+
export declare const walkProject: (rootDir: string) => WalkedFile[];
|
|
23
|
+
//# sourceMappingURL=file-walker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-walker.d.ts","sourceRoot":"","sources":["../../src/lib/file-walker.ts"],"names":[],"mappings":"AAEA,OAAe,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAY7C,eAAO,MAAM,aAAa,UA0BzB,CAAC;AAWF,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,KAAG,MAclD,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,WAAW,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,GAAI,SAAS,MAAM,KAAG,UAAU,EAyCvD,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import ignore from 'ignore';
|
|
4
|
+
// Always-exclude footguns: things that should never be deployed regardless of
|
|
5
|
+
// what the user's gitignore says. Catches secrets, pushto-internal files, and
|
|
6
|
+
// universally non-deployable build/cache artifacts even if the user forgot
|
|
7
|
+
// to gitignore them. Patterns without a slash match at any directory level
|
|
8
|
+
// per gitignore semantics — so `.venv` here also catches `sdks/python/.venv`
|
|
9
|
+
// (the chartmuse-engine case that had us shipping a 76MB zip).
|
|
10
|
+
//
|
|
11
|
+
// Conservative: only includes things that are NEVER the deployable artifact.
|
|
12
|
+
// `dist`, `build`, `out` are intentionally NOT here — for static sites those
|
|
13
|
+
// ARE what gets deployed.
|
|
14
|
+
export const ALWAYS_IGNORE = [
|
|
15
|
+
// pushto-internal + secrets
|
|
16
|
+
'.git',
|
|
17
|
+
'.pushto',
|
|
18
|
+
'.env',
|
|
19
|
+
'.env.local',
|
|
20
|
+
'.env.*.local',
|
|
21
|
+
'.DS_Store',
|
|
22
|
+
// Node
|
|
23
|
+
'node_modules',
|
|
24
|
+
'.next',
|
|
25
|
+
'.vercel',
|
|
26
|
+
'.turbo',
|
|
27
|
+
// Python — venvs (~hundreds of MB), bytecode (regenerated on import),
|
|
28
|
+
// and test/type-check caches. None of these are ever deployed.
|
|
29
|
+
'.venv',
|
|
30
|
+
'venv',
|
|
31
|
+
'__pycache__',
|
|
32
|
+
'*.pyc',
|
|
33
|
+
'.pytest_cache',
|
|
34
|
+
'.mypy_cache',
|
|
35
|
+
'.ruff_cache',
|
|
36
|
+
// Rust / Java / generic build dirs — multi-GB build output. Source-only
|
|
37
|
+
// deploys; if the user wants to ship a prebuilt binary, they put it
|
|
38
|
+
// somewhere other than `target/`.
|
|
39
|
+
'target',
|
|
40
|
+
];
|
|
41
|
+
// Build an ignore filter that combines ALWAYS_IGNORE with the project's own
|
|
42
|
+
// .gitignore and an optional .pushtoignore. Both files use gitignore syntax
|
|
43
|
+
// (negations, glob patterns, dir-only `foo/` markers).
|
|
44
|
+
//
|
|
45
|
+
// This is what unblocks non-Node projects: every Rust project has `target/`
|
|
46
|
+
// in .gitignore, every Python project has `__pycache__/` and `.venv/`, every
|
|
47
|
+
// Go project has `bin/`. Without reading gitignore, the zipper walked into
|
|
48
|
+
// those and either hit the 500MB cap or ground to a halt on tens of
|
|
49
|
+
// thousands of intermediate files.
|
|
50
|
+
export const loadIgnoreFilter = (rootDir) => {
|
|
51
|
+
const ig = ignore().add(ALWAYS_IGNORE);
|
|
52
|
+
const gitignorePath = path.join(rootDir, '.gitignore');
|
|
53
|
+
if (fs.existsSync(gitignorePath)) {
|
|
54
|
+
ig.add(fs.readFileSync(gitignorePath, 'utf-8'));
|
|
55
|
+
}
|
|
56
|
+
const pushtoignorePath = path.join(rootDir, '.pushtoignore');
|
|
57
|
+
if (fs.existsSync(pushtoignorePath)) {
|
|
58
|
+
ig.add(fs.readFileSync(pushtoignorePath, 'utf-8'));
|
|
59
|
+
}
|
|
60
|
+
return ig;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Walk a project directory using the same ignore semantics deploy.ts uses
|
|
64
|
+
* to build the deploy zip. Skips symlinks (traversal protection) and
|
|
65
|
+
* caps depth at 20.
|
|
66
|
+
*
|
|
67
|
+
* Both deploy.ts (zip the matched files) and doctor.ts (preview the
|
|
68
|
+
* matched files: count, total size, biggest) call this. If the two ever
|
|
69
|
+
* disagreed, doctor's "looks fine" would mismatch deploy's "exceeds limit"
|
|
70
|
+
* — frustrating to debug. One source = one truth.
|
|
71
|
+
*/
|
|
72
|
+
export const walkProject = (rootDir) => {
|
|
73
|
+
const ig = loadIgnoreFilter(rootDir);
|
|
74
|
+
const files = [];
|
|
75
|
+
const MAX_DEPTH = 20;
|
|
76
|
+
const recurse = (dirPath, prefix, depth) => {
|
|
77
|
+
if (depth > MAX_DEPTH)
|
|
78
|
+
return;
|
|
79
|
+
let entries;
|
|
80
|
+
try {
|
|
81
|
+
entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
for (const entry of entries) {
|
|
87
|
+
if (entry.isSymbolicLink())
|
|
88
|
+
continue;
|
|
89
|
+
const archivePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
90
|
+
// Gitignore syntax: directory-only patterns (`target/`) match only when
|
|
91
|
+
// the test path ends in a slash. Always append `/` for directories so
|
|
92
|
+
// both file and dir patterns resolve correctly.
|
|
93
|
+
const testPath = entry.isDirectory() ? `${archivePath}/` : archivePath;
|
|
94
|
+
if (ig.ignores(testPath))
|
|
95
|
+
continue;
|
|
96
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
97
|
+
if (entry.isFile()) {
|
|
98
|
+
try {
|
|
99
|
+
const stat = fs.statSync(fullPath);
|
|
100
|
+
files.push({ fullPath, archivePath, sizeBytes: stat.size });
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// skip unreadable files
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else if (entry.isDirectory()) {
|
|
107
|
+
recurse(fullPath, archivePath, depth + 1);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
recurse(rootDir, '', 0);
|
|
112
|
+
return files;
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=file-walker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-walker.js","sourceRoot":"","sources":["../../src/lib/file-walker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single source of truth for whether a command may block on a human.
|
|
3
|
+
*
|
|
4
|
+
* No command reads process.stdin.isTTY itself — a guard in
|
|
5
|
+
* apps/web/scripts/guard-cli-interactive.mjs fails the build if one does.
|
|
6
|
+
* That centralisation is the whole point: the deploy hang existed because
|
|
7
|
+
* one call site made this decision privately and got it wrong.
|
|
8
|
+
*/
|
|
9
|
+
export declare const canPrompt: (flags?: {
|
|
10
|
+
json?: boolean;
|
|
11
|
+
yes?: boolean;
|
|
12
|
+
}) => boolean;
|
|
13
|
+
//# sourceMappingURL=interactive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../src/lib/interactive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,eAAO,MAAM,SAAS,GAAI,QAAQ;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,KAAG,OAIrE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The single source of truth for whether a command may block on a human.
|
|
3
|
+
*
|
|
4
|
+
* No command reads process.stdin.isTTY itself — a guard in
|
|
5
|
+
* apps/web/scripts/guard-cli-interactive.mjs fails the build if one does.
|
|
6
|
+
* That centralisation is the whole point: the deploy hang existed because
|
|
7
|
+
* one call site made this decision privately and got it wrong.
|
|
8
|
+
*/
|
|
9
|
+
/** "", "0" and "false" all mean not-set, matching shell convention. */
|
|
10
|
+
const envFlagSet = (name) => {
|
|
11
|
+
const raw = process.env[name];
|
|
12
|
+
if (!raw)
|
|
13
|
+
return false;
|
|
14
|
+
const v = raw.toLowerCase();
|
|
15
|
+
return v !== '0' && v !== 'false';
|
|
16
|
+
};
|
|
17
|
+
export const canPrompt = (flags) => {
|
|
18
|
+
if (flags?.json || flags?.yes)
|
|
19
|
+
return false;
|
|
20
|
+
if (envFlagSet('CI') || envFlagSet('PUSHTO_NONINTERACTIVE'))
|
|
21
|
+
return false;
|
|
22
|
+
return Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY);
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=interactive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../src/lib/interactive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,uEAAuE;AACvE,MAAM,UAAU,GAAG,CAAC,IAAY,EAAW,EAAE;IAC3C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC;IACvB,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAC5B,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,OAAO,CAAC;AACpC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAyC,EAAW,EAAE;IAC9E,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,EAAE,GAAG;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,uBAAuB,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1E,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACvE,CAAC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { PushtoError } from '@pushto/shared/errors';
|
|
2
|
+
import { buildError, type PushtoErrorCode } from './errors.js';
|
|
3
|
+
export interface OutputOpts {
|
|
4
|
+
json?: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Under --json, stdout carries exactly one JSON object and nothing else, so
|
|
8
|
+
* `pushto deploy --json | jq` works unfiltered. Everything a human would
|
|
9
|
+
* enjoy — spinners, colour, progress — goes to stderr instead.
|
|
10
|
+
*
|
|
11
|
+
* lib/api.ts already wrote its session-expired notice to stderr to keep user
|
|
12
|
+
* pipes clean; this module finishes that discipline for the whole spine.
|
|
13
|
+
*/
|
|
14
|
+
/** Human-only progress. Never stdout; in json mode it still goes to stderr. */
|
|
15
|
+
export declare const progress: (line: string, opts: OutputOpts) => void;
|
|
16
|
+
/** ora writes to stdout by default. In json mode that would corrupt the payload. */
|
|
17
|
+
export declare const spinnerStream: (opts: OutputOpts) => NodeJS.WriteStream;
|
|
18
|
+
export declare const emitOk: (payload: Record<string, unknown> & {
|
|
19
|
+
human?: string;
|
|
20
|
+
}, opts: OutputOpts) => void;
|
|
21
|
+
export declare const emitErr: (err: PushtoError, opts: OutputOpts) => void;
|
|
22
|
+
/** Render the error and exit on the band its code derives. Never returns. */
|
|
23
|
+
export declare const fail: (code: PushtoErrorCode, human: string, opts: OutputOpts, extra?: Parameters<typeof buildError>[2]) => never;
|
|
24
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAe,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAE5E,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;GAOG;AAEH,+EAA+E;AAC/E,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,EAAE,MAAM,UAAU,KAAG,IAEzD,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,aAAa,GAAI,MAAM,UAAU,KAAG,MAAM,CAAC,WACX,CAAC;AAE9C,eAAO,MAAM,MAAM,GACjB,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EACrD,MAAM,UAAU,KACf,IAOF,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,KAAK,WAAW,EAAE,MAAM,UAAU,KAAG,IA4C5D,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,IAAI,GACf,MAAM,eAAe,EACrB,OAAO,MAAM,EACb,MAAM,UAAU,EAChB,QAAQ,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,KACvC,KAGF,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { buildError, exitCodeFor } from './errors.js';
|
|
3
|
+
/**
|
|
4
|
+
* Under --json, stdout carries exactly one JSON object and nothing else, so
|
|
5
|
+
* `pushto deploy --json | jq` works unfiltered. Everything a human would
|
|
6
|
+
* enjoy — spinners, colour, progress — goes to stderr instead.
|
|
7
|
+
*
|
|
8
|
+
* lib/api.ts already wrote its session-expired notice to stderr to keep user
|
|
9
|
+
* pipes clean; this module finishes that discipline for the whole spine.
|
|
10
|
+
*/
|
|
11
|
+
/** Human-only progress. Never stdout; in json mode it still goes to stderr. */
|
|
12
|
+
export const progress = (line, opts) => {
|
|
13
|
+
process.stderr.write(opts.json ? `${line}\n` : `${chalk.dim(line)}\n`);
|
|
14
|
+
};
|
|
15
|
+
/** ora writes to stdout by default. In json mode that would corrupt the payload. */
|
|
16
|
+
export const spinnerStream = (opts) => opts.json ? process.stderr : process.stdout;
|
|
17
|
+
export const emitOk = (payload, opts) => {
|
|
18
|
+
if (opts.json) {
|
|
19
|
+
const { human: _human, ...rest } = payload;
|
|
20
|
+
process.stdout.write(`${JSON.stringify({ ok: true, ...rest })}\n`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (payload.human)
|
|
24
|
+
process.stdout.write(`${payload.human}\n`);
|
|
25
|
+
};
|
|
26
|
+
export const emitErr = (err, opts) => {
|
|
27
|
+
if (opts.json) {
|
|
28
|
+
// `prose` is a human-render hint carrying a {cmd} placeholder. Machines
|
|
29
|
+
// read label/cmd/href, so it is stripped here rather than shipped as a
|
|
30
|
+
// half-interpolated string a caller might print raw.
|
|
31
|
+
const machineFix = err.fix
|
|
32
|
+
? {
|
|
33
|
+
label: err.fix.label,
|
|
34
|
+
...(err.fix.cmd ? { cmd: err.fix.cmd } : {}),
|
|
35
|
+
...(err.fix.href ? { href: err.fix.href } : {}),
|
|
36
|
+
}
|
|
37
|
+
: undefined;
|
|
38
|
+
// Keys are spread in a fixed order so the payload shape stays stable for
|
|
39
|
+
// consumers that diff or snapshot it. Optional keys are omitted, not set
|
|
40
|
+
// to undefined, because JSON.stringify would drop them inconsistently.
|
|
41
|
+
process.stdout.write(`${JSON.stringify({
|
|
42
|
+
ok: false,
|
|
43
|
+
...(err.stage ? { stage: err.stage } : {}),
|
|
44
|
+
retryable: err.retryable,
|
|
45
|
+
...(err.details ? { details: err.details } : {}),
|
|
46
|
+
error: { code: err.code, human: err.human, ...(machineFix ? { fix: machineFix } : {}) },
|
|
47
|
+
})}\n`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
process.stderr.write(`${chalk.red(`> ${err.human}`)}\n`);
|
|
51
|
+
if (!err.fix)
|
|
52
|
+
return;
|
|
53
|
+
const target = err.fix.cmd ?? err.fix.href;
|
|
54
|
+
if (!target)
|
|
55
|
+
return;
|
|
56
|
+
// `prose` wins so hand-written copy survives the structured shape: the
|
|
57
|
+
// sentence is split on its single {cmd} placeholder and the command is
|
|
58
|
+
// highlighted in place, reproducing the original line exactly.
|
|
59
|
+
if (err.fix.prose) {
|
|
60
|
+
const [before = '', after = ''] = err.fix.prose.split('{cmd}');
|
|
61
|
+
process.stderr.write(`${chalk.dim(` ${before}`)}${chalk.cyan(target)}${chalk.dim(after)}\n`);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
process.stderr.write(`${chalk.dim(` ${err.fix.label}: `)}${chalk.cyan(target)}\n`);
|
|
65
|
+
};
|
|
66
|
+
/** Render the error and exit on the band its code derives. Never returns. */
|
|
67
|
+
export const fail = (code, human, opts, extra) => {
|
|
68
|
+
emitErr(buildError(code, human, extra), opts);
|
|
69
|
+
process.exit(exitCodeFor(code));
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAwB,MAAM,aAAa,CAAC;AAM5E;;;;;;;GAOG;AAEH,+EAA+E;AAC/E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,IAAgB,EAAQ,EAAE;IAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzE,CAAC,CAAC;AAEF,oFAAoF;AACpF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAgB,EAAsB,EAAE,CACpE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;AAE9C,MAAM,CAAC,MAAM,MAAM,GAAG,CACpB,OAAqD,EACrD,IAAgB,EACV,EAAE;IACR,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;QAC3C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;QACnE,OAAO;IACT,CAAC;IACD,IAAI,OAAO,CAAC,KAAK;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;AAChE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAgB,EAAE,IAAgB,EAAQ,EAAE;IAClE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,wEAAwE;QACxE,uEAAuE;QACvE,qDAAqD;QACrD,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG;YACxB,CAAC,CAAC;gBACE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK;gBACpB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5C,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChD;YACH,CAAC,CAAC,SAAS,CAAC;QACd,yEAAyE;QACzE,yEAAyE;QACzE,uEAAuE;QACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,IAAI,CAAC,SAAS,CAAC;YAChB,EAAE,EAAE,KAAK;YACT,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1C,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChD,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;SACxF,CAAC,IAAI,CACP,CAAC;QACF,OAAO;IACT,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,CAAC,GAAG,CAAC,GAAG;QAAE,OAAO;IAErB,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,uEAAuE;IACvE,uEAAuE;IACvE,+DAA+D;IAC/D,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,CAAC,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CACxE,CAAC;QACF,OAAO;IACT,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACtF,CAAC,CAAC;AAEF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,IAAI,GAAG,CAClB,IAAqB,EACrB,KAAa,EACb,IAAgB,EAChB,KAAwC,EACjC,EAAE;IACT,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;AAClC,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one entry point deploy + preview share: decide whether this
|
|
3
|
+
* directory deploys as-is (source) or gets built first (artifact).
|
|
4
|
+
* Keeping it here means `pushto` and `pushto preview` cannot drift —
|
|
5
|
+
* the exact failure the spec calls out (working deploys, blank previews).
|
|
6
|
+
*/
|
|
7
|
+
export type ArtifactPrep = {
|
|
8
|
+
kind: 'source';
|
|
9
|
+
zipDir: string;
|
|
10
|
+
} | {
|
|
11
|
+
kind: 'artifact';
|
|
12
|
+
zipDir: string;
|
|
13
|
+
framework: string;
|
|
14
|
+
typeWarnings: string | null;
|
|
15
|
+
cleanup: () => void;
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'failed';
|
|
18
|
+
message: string;
|
|
19
|
+
buildOutput: string;
|
|
20
|
+
};
|
|
21
|
+
export declare const prepareArtifact: (cwd: string, log: (line: string) => void) => Promise<ArtifactPrep>;
|
|
22
|
+
//# sourceMappingURL=prepare-artifact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare-artifact.d.ts","sourceRoot":"","sources":["../../src/lib/prepare-artifact.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,GACzG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,eAAO,MAAM,eAAe,GAC1B,KAAK,MAAM,EACX,KAAK,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAC1B,OAAO,CAAC,YAAY,CAsBtB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { detectStaticFramework } from './detect-static-framework.js';
|
|
2
|
+
import { runStaticBuild, writeArtifactMeta } from './build-runner.js';
|
|
3
|
+
export const prepareArtifact = async (cwd, log) => {
|
|
4
|
+
const detection = detectStaticFramework(cwd);
|
|
5
|
+
if (!detection)
|
|
6
|
+
return { kind: 'source', zipDir: cwd };
|
|
7
|
+
const build = await runStaticBuild(cwd, detection, { log });
|
|
8
|
+
if (!build.ok)
|
|
9
|
+
return { kind: 'failed', message: build.message, buildOutput: build.buildOutput };
|
|
10
|
+
const cleanup = writeArtifactMeta(build.outputDir, {
|
|
11
|
+
framework: detection.framework,
|
|
12
|
+
spa: detection.spa,
|
|
13
|
+
});
|
|
14
|
+
// The marker must never outlive the command: registering cleanup on
|
|
15
|
+
// process exit covers every failure branch (process.exit calls
|
|
16
|
+
// included), so no call site can forget it. cleanup is idempotent.
|
|
17
|
+
process.once('exit', cleanup);
|
|
18
|
+
return {
|
|
19
|
+
kind: 'artifact',
|
|
20
|
+
zipDir: build.outputDir,
|
|
21
|
+
framework: detection.framework,
|
|
22
|
+
typeWarnings: build.typeWarnings,
|
|
23
|
+
cleanup,
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=prepare-artifact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare-artifact.js","sourceRoot":"","sources":["../../src/lib/prepare-artifact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAatE,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,GAAW,EACX,GAA2B,EACJ,EAAE;IACzB,MAAM,SAAS,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAEvD,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5D,IAAI,CAAC,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC;IAEjG,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,SAAS,EAAE;QACjD,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,GAAG,EAAE,SAAS,CAAC,GAAG;KACnB,CAAC,CAAC;IACH,oEAAoE;IACpE,+DAA+D;IAC/D,mEAAmE;IACnE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,KAAK,CAAC,SAAS;QACvB,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,OAAO;KACR,CAAC;AACJ,CAAC,CAAC"}
|