@pushto/cli 0.2.1 → 0.4.9
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/cli.js +0 -0
- 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__/npm-packaging.test.d.ts +2 -0
- package/dist/lib/__tests__/npm-packaging.test.d.ts.map +1 -0
- package/dist/lib/__tests__/npm-packaging.test.js +81 -0
- package/dist/lib/__tests__/npm-packaging.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,55 @@
|
|
|
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 { prepareArtifact } from '../prepare-artifact.js';
|
|
6
|
+
import { ARTIFACT_META_NAME } from '../build-runner.js';
|
|
7
|
+
let dir;
|
|
8
|
+
beforeEach(() => { dir = fs.mkdtempSync(path.join(os.tmpdir(), 'pushto-prep-')); });
|
|
9
|
+
afterEach(() => {
|
|
10
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
11
|
+
// Remove all exit listeners added during this test to avoid leaking listeners
|
|
12
|
+
// between tests. Vitest runs this in a worker, but exit hooks persist in the
|
|
13
|
+
// process, so we clean up to avoid interference with later tests.
|
|
14
|
+
process.removeAllListeners('exit');
|
|
15
|
+
});
|
|
16
|
+
describe('prepareArtifact', () => {
|
|
17
|
+
it('non-framework project passes through as source', async () => {
|
|
18
|
+
fs.writeFileSync(path.join(dir, 'index.html'), '<h1>hi</h1>');
|
|
19
|
+
const r = await prepareArtifact(dir, () => undefined);
|
|
20
|
+
expect(r).toEqual({ kind: 'source', zipDir: dir });
|
|
21
|
+
});
|
|
22
|
+
it('framework project builds and returns the artifact dir with the meta marker present', async () => {
|
|
23
|
+
fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify({
|
|
24
|
+
devDependencies: { vite: '^5.0.0' },
|
|
25
|
+
scripts: { build: 'node -e "require(\'fs\').mkdirSync(\'dist\',{recursive:true});require(\'fs\').writeFileSync(\'dist/index.html\',\'built\')"' },
|
|
26
|
+
}));
|
|
27
|
+
fs.mkdirSync(path.join(dir, 'node_modules'), { recursive: true });
|
|
28
|
+
const beforeListenerCount = process.listenerCount('exit');
|
|
29
|
+
const r = await prepareArtifact(dir, () => undefined);
|
|
30
|
+
expect(r.kind).toBe('artifact');
|
|
31
|
+
if (r.kind === 'artifact') {
|
|
32
|
+
// Verify exit hook was registered
|
|
33
|
+
expect(process.listenerCount('exit')).toBe(beforeListenerCount + 1);
|
|
34
|
+
expect(r.framework).toBe('vite');
|
|
35
|
+
expect(r.zipDir).toBe(path.join(dir, 'dist'));
|
|
36
|
+
const meta = JSON.parse(fs.readFileSync(path.join(r.zipDir, ARTIFACT_META_NAME), 'utf-8'));
|
|
37
|
+
expect(meta).toMatchObject({ framework: 'vite', spa: true });
|
|
38
|
+
// Verify cleanup is idempotent — calling twice should not throw and marker should stay gone
|
|
39
|
+
r.cleanup();
|
|
40
|
+
expect(fs.existsSync(path.join(r.zipDir, ARTIFACT_META_NAME))).toBe(false);
|
|
41
|
+
r.cleanup(); // Second call should not throw
|
|
42
|
+
expect(fs.existsSync(path.join(r.zipDir, ARTIFACT_META_NAME))).toBe(false);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
it('framework project with a failing build returns failed and writes no meta', async () => {
|
|
46
|
+
fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify({
|
|
47
|
+
devDependencies: { vite: '^5.0.0' },
|
|
48
|
+
scripts: { build: 'node -e "process.exit(1)"' },
|
|
49
|
+
}));
|
|
50
|
+
fs.mkdirSync(path.join(dir, 'node_modules'), { recursive: true });
|
|
51
|
+
const r = await prepareArtifact(dir, () => undefined);
|
|
52
|
+
expect(r.kind).toBe('failed');
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=prepare-artifact.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prepare-artifact.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/prepare-artifact.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-args.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/preview-args.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { resolvePreviewAction } from '../preview-args.js';
|
|
3
|
+
/**
|
|
4
|
+
* PINs for the `pushto preview` dispatcher's action grammar.
|
|
5
|
+
*
|
|
6
|
+
* docs/cli and the command's own help have taught "(create, ls, rm)" since
|
|
7
|
+
* the command shipped — but the dispatcher treated ANY unknown action word
|
|
8
|
+
* as a directory, so the documented `pushto preview create --branch x`
|
|
9
|
+
* died with "not a directory: create". The verb now exists; a positional
|
|
10
|
+
* directory still works.
|
|
11
|
+
*/
|
|
12
|
+
describe('resolvePreviewAction', () => {
|
|
13
|
+
it('bare invocation creates from the current directory', () => {
|
|
14
|
+
expect(resolvePreviewAction('', [])).toEqual({ kind: 'create', dir: '.' });
|
|
15
|
+
});
|
|
16
|
+
it('the documented `create` verb creates from the current directory', () => {
|
|
17
|
+
expect(resolvePreviewAction('create', [])).toEqual({ kind: 'create', dir: '.' });
|
|
18
|
+
});
|
|
19
|
+
it('`create <dir>` targets that directory', () => {
|
|
20
|
+
expect(resolvePreviewAction('create', ['dist'])).toEqual({ kind: 'create', dir: 'dist' });
|
|
21
|
+
});
|
|
22
|
+
it('a bare positional directory still works (pushto preview dist)', () => {
|
|
23
|
+
expect(resolvePreviewAction('dist', [])).toEqual({ kind: 'create', dir: 'dist' });
|
|
24
|
+
});
|
|
25
|
+
it('ls and list both list', () => {
|
|
26
|
+
expect(resolvePreviewAction('ls', [])).toEqual({ kind: 'ls' });
|
|
27
|
+
expect(resolvePreviewAction('list', [])).toEqual({ kind: 'ls' });
|
|
28
|
+
});
|
|
29
|
+
it('rm and delete both remove, carrying the ref', () => {
|
|
30
|
+
expect(resolvePreviewAction('rm', ['feature-x'])).toEqual({ kind: 'rm', ref: 'feature-x' });
|
|
31
|
+
expect(resolvePreviewAction('delete', ['abc123'])).toEqual({ kind: 'rm', ref: 'abc123' });
|
|
32
|
+
});
|
|
33
|
+
it('rm without a ref reports the miss instead of guessing', () => {
|
|
34
|
+
expect(resolvePreviewAction('rm', [])).toEqual({ kind: 'rm', ref: undefined });
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=preview-args.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-args.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/preview-args.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;;;;;;;GAQG;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,oBAAoB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IACnF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;QAC5F,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/lib/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAgEA,eAAO,MAAM,GAAG,GAAU,MAAM,MAAM,EAAE,UAAS,WAAgB,KAAG,OAAO,CAAC,QAAQ,CA4BnF,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,YAAY,QAAO,WAAqD,CAAC"}
|
package/dist/lib/api.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { config, getToken, getRefreshToken, setToken, clearToken, isTokenExpired } from './config.js';
|
|
2
2
|
/** Default timeout for API requests (30 seconds) */
|
|
3
3
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
4
|
-
/** Extended timeout for upload/deploy operations (
|
|
5
|
-
|
|
4
|
+
/** Extended timeout for upload/deploy operations (10 minutes).
|
|
5
|
+
* Matches the web route's MAX_WAIT poll budget so the CLI doesn't abort
|
|
6
|
+
* with `network error` while the server is still legitimately polling
|
|
7
|
+
* the deploy-agent for a slow first build (Rust workspace, large
|
|
8
|
+
* Next.js app). When the server times out, it returns 504 with
|
|
9
|
+
* `stillBuilding: true` and the CLI shows a "still building" message. */
|
|
10
|
+
const DEPLOY_TIMEOUT_MS = 600_000;
|
|
6
11
|
/** Timeout for token refresh requests (10 seconds) */
|
|
7
12
|
const REFRESH_TIMEOUT_MS = 10_000;
|
|
8
13
|
/**
|
|
@@ -24,8 +29,18 @@ const ensureFreshToken = async () => {
|
|
|
24
29
|
signal: AbortSignal.timeout(REFRESH_TIMEOUT_MS),
|
|
25
30
|
});
|
|
26
31
|
if (res.status === 401 || res.status === 403) {
|
|
27
|
-
// Refresh token is expired/revoked — clear credentials
|
|
32
|
+
// Refresh token is expired/revoked — clear credentials AND tell the
|
|
33
|
+
// user exactly what to do. Without this hint, the upcoming API call
|
|
34
|
+
// returns a generic "not authenticated" and the user has no idea
|
|
35
|
+
// their multi-week session just rolled off — they assume their
|
|
36
|
+
// login is broken or pushto is broken.
|
|
37
|
+
//
|
|
38
|
+
// Stderr keeps the message out of any captured stdout (e.g. when
|
|
39
|
+
// the user pipes `pushto env list | grep ...` and we don't want to
|
|
40
|
+
// pollute the pipe). Plain text — no chalk import here to keep this
|
|
41
|
+
// module dependency-free for the auth-bootstrap path.
|
|
28
42
|
clearToken();
|
|
43
|
+
process.stderr.write('your pushto session expired. run `pushto login` to sign back in.\n');
|
|
29
44
|
return;
|
|
30
45
|
}
|
|
31
46
|
if (!res.ok)
|
|
@@ -48,7 +63,10 @@ export const api = async (path, options = {}) => {
|
|
|
48
63
|
const headers = {
|
|
49
64
|
...existingHeaders,
|
|
50
65
|
};
|
|
51
|
-
|
|
66
|
+
// Skip Content-Type for FormData — fetch needs to generate its own
|
|
67
|
+
// multipart/form-data boundary, which it only does when Content-Type is unset.
|
|
68
|
+
const isFormData = typeof FormData !== 'undefined' && options.body instanceof FormData;
|
|
69
|
+
if (!headers['Content-Type'] && !isFormData) {
|
|
52
70
|
headers['Content-Type'] = 'application/json';
|
|
53
71
|
}
|
|
54
72
|
if (token) {
|
package/dist/lib/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEtG,oDAAoD;AACpD,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The only readline interface in the CLI.
|
|
3
|
+
*
|
|
4
|
+
* Callers MUST gate this behind canPrompt() from ./interactive.js. It lives
|
|
5
|
+
* here rather than in a command so the guard
|
|
6
|
+
* (apps/web/scripts/guard-cli-interactive.mjs) can prove no command reaches
|
|
7
|
+
* for stdin on its own — which is exactly how the deploy hang happened.
|
|
8
|
+
*
|
|
9
|
+
* Note what this cannot do: readline's question callback never fires on EOF,
|
|
10
|
+
* so with stdin closed the returned promise never settles. There is no
|
|
11
|
+
* timeout and no rejection to catch. That is not a bug to fix here; it is
|
|
12
|
+
* why the decision to call this at all belongs to canPrompt().
|
|
13
|
+
*/
|
|
14
|
+
export declare const ask: (question: string) => Promise<string>;
|
|
15
|
+
//# sourceMappingURL=ask.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../src/lib/ask.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,GAAG,GAAI,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,CAQpD,CAAC"}
|
package/dist/lib/ask.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline';
|
|
2
|
+
/**
|
|
3
|
+
* The only readline interface in the CLI.
|
|
4
|
+
*
|
|
5
|
+
* Callers MUST gate this behind canPrompt() from ./interactive.js. It lives
|
|
6
|
+
* here rather than in a command so the guard
|
|
7
|
+
* (apps/web/scripts/guard-cli-interactive.mjs) can prove no command reaches
|
|
8
|
+
* for stdin on its own — which is exactly how the deploy hang happened.
|
|
9
|
+
*
|
|
10
|
+
* Note what this cannot do: readline's question callback never fires on EOF,
|
|
11
|
+
* so with stdin closed the returned promise never settles. There is no
|
|
12
|
+
* timeout and no rejection to catch. That is not a bug to fix here; it is
|
|
13
|
+
* why the decision to call this at all belongs to canPrompt().
|
|
14
|
+
*/
|
|
15
|
+
export const ask = (question) => {
|
|
16
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
17
|
+
return new Promise((resolve) => {
|
|
18
|
+
rl.question(question, (answer) => {
|
|
19
|
+
rl.close();
|
|
20
|
+
resolve(answer.trim());
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=ask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../src/lib/ask.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,QAAgB,EAAmB,EAAE;IACvD,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;YAC/B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { StaticFrameworkDetection } from './detect-static-framework.js';
|
|
2
|
+
/**
|
|
3
|
+
* Runs a static-output framework build on the user's machine and resolves
|
|
4
|
+
* where the artifact landed. Every failure returns { ok: false } with the
|
|
5
|
+
* captured output — the caller never uploads on failure, and never falls
|
|
6
|
+
* back to stale output (honest failure beats stale success).
|
|
7
|
+
*/
|
|
8
|
+
export declare const ARTIFACT_META_NAME = "_pushto_meta.json";
|
|
9
|
+
export type BuildOutcome = {
|
|
10
|
+
ok: true;
|
|
11
|
+
outputDir: string;
|
|
12
|
+
typeWarnings: string | null;
|
|
13
|
+
} | {
|
|
14
|
+
ok: false;
|
|
15
|
+
message: string;
|
|
16
|
+
buildOutput: string;
|
|
17
|
+
};
|
|
18
|
+
export declare const runStaticBuild: (dir: string, detection: StaticFrameworkDetection, opts?: {
|
|
19
|
+
log?: (line: string) => void;
|
|
20
|
+
}) => Promise<BuildOutcome>;
|
|
21
|
+
export declare const writeArtifactMeta: (outputDir: string, meta: {
|
|
22
|
+
framework: string;
|
|
23
|
+
spa: boolean;
|
|
24
|
+
}) => (() => void);
|
|
25
|
+
//# sourceMappingURL=build-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-runner.d.ts","sourceRoot":"","sources":["../../src/lib/build-runner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAE7E;;;;;GAKG;AAEH,eAAO,MAAM,kBAAkB,sBAAsB,CAAC;AAUtD,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC5D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAyExD,eAAO,MAAM,cAAc,GACzB,KAAK,MAAM,EACX,WAAW,wBAAwB,EACnC,OAAO;IAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,KACtC,OAAO,CAAC,YAAY,CA0DtB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,WAAW,MAAM,EACjB,MAAM;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,KACxC,CAAC,MAAM,IAAI,CAMb,CAAC"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* Runs a static-output framework build on the user's machine and resolves
|
|
6
|
+
* where the artifact landed. Every failure returns { ok: false } with the
|
|
7
|
+
* captured output — the caller never uploads on failure, and never falls
|
|
8
|
+
* back to stale output (honest failure beats stale success).
|
|
9
|
+
*/
|
|
10
|
+
export const ARTIFACT_META_NAME = '_pushto_meta.json';
|
|
11
|
+
const BUILD_TIMEOUT_MS = 10 * 60 * 1000; // generous: old laptops, cold gatsby
|
|
12
|
+
const FALLBACK_SCAN_DIRS = ['dist', 'build', 'out', '_site'];
|
|
13
|
+
/** The stock Vite React-TS scaffold build script. Only this exact shape
|
|
14
|
+
* earns the tsc-fallback retry (Scott's call, spec decision #4): any
|
|
15
|
+
* customized script is the user's contract and fails honestly. */
|
|
16
|
+
const STOCK_TSC_VITE = /^\s*tsc(?:\s+-b)?\s*&&\s*vite\s+build\s*$/;
|
|
17
|
+
const detectPm = (dir) => {
|
|
18
|
+
if (fs.existsSync(path.join(dir, 'pnpm-lock.yaml')))
|
|
19
|
+
return 'pnpm';
|
|
20
|
+
if (fs.existsSync(path.join(dir, 'yarn.lock')))
|
|
21
|
+
return 'yarn';
|
|
22
|
+
return 'npm';
|
|
23
|
+
};
|
|
24
|
+
const exec = (cmd, cwd) => new Promise((resolve) => {
|
|
25
|
+
const [bin, ...args] = cmd;
|
|
26
|
+
const child = spawn(bin, args, {
|
|
27
|
+
cwd,
|
|
28
|
+
// Windows needs a shell to resolve npm.cmd / pnpm.cmd shims.
|
|
29
|
+
shell: process.platform === 'win32',
|
|
30
|
+
});
|
|
31
|
+
const chunks = [];
|
|
32
|
+
child.stdout.on('data', (d) => chunks.push(d.toString()));
|
|
33
|
+
child.stderr.on('data', (d) => chunks.push(d.toString()));
|
|
34
|
+
const timer = setTimeout(() => {
|
|
35
|
+
child.kill('SIGKILL');
|
|
36
|
+
chunks.push('\n(build timed out after 10 minutes)');
|
|
37
|
+
}, BUILD_TIMEOUT_MS);
|
|
38
|
+
child.on('close', (code) => {
|
|
39
|
+
clearTimeout(timer);
|
|
40
|
+
resolve({ code: code ?? 1, output: chunks.join('') });
|
|
41
|
+
});
|
|
42
|
+
child.on('error', (err) => {
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
resolve({ code: 1, output: String(err) });
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
const installCmd = (pm) => pm === 'pnpm' ? ['pnpm', 'install'] : pm === 'yarn' ? ['yarn', 'install'] : ['npm', 'install'];
|
|
48
|
+
const runScriptCmd = (pm, script) => pm === 'pnpm' ? ['pnpm', 'run', script] : pm === 'yarn' ? ['yarn', 'run', script] : ['npm', 'run', script];
|
|
49
|
+
/** Run a local bin directly (the tsc-fallback retry). */
|
|
50
|
+
const execLocalBinCmd = (pm, bin, args) => pm === 'pnpm' ? ['pnpm', 'exec', bin, ...args]
|
|
51
|
+
: pm === 'yarn' ? ['yarn', bin, ...args]
|
|
52
|
+
: ['npx', '--no-install', bin, ...args];
|
|
53
|
+
/** First candidate dir containing an index.html written after buildStart. */
|
|
54
|
+
const resolveOutputDir = (dir, candidates, buildStart) => {
|
|
55
|
+
const all = [...candidates, ...FALLBACK_SCAN_DIRS.filter((d) => !candidates.includes(d))];
|
|
56
|
+
for (const c of all) {
|
|
57
|
+
const indexPath = path.join(dir, c, 'index.html');
|
|
58
|
+
try {
|
|
59
|
+
const stat = fs.statSync(indexPath);
|
|
60
|
+
if (stat.mtimeMs >= buildStart)
|
|
61
|
+
return path.join(dir, c);
|
|
62
|
+
}
|
|
63
|
+
catch { /* not there — next candidate */ }
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
};
|
|
67
|
+
/** The real build command per framework — the message must name a fix
|
|
68
|
+
* that actually works when pasted into package.json. */
|
|
69
|
+
const BUILD_SCRIPT_SUGGESTION = {
|
|
70
|
+
vite: 'vite build',
|
|
71
|
+
astro: 'astro build',
|
|
72
|
+
gatsby: 'gatsby build',
|
|
73
|
+
angular: 'ng build',
|
|
74
|
+
cra: 'react-scripts build',
|
|
75
|
+
eleventy: 'eleventy',
|
|
76
|
+
};
|
|
77
|
+
export const runStaticBuild = async (dir, detection, opts) => {
|
|
78
|
+
const log = opts?.log ?? (() => undefined);
|
|
79
|
+
const pm = detectPm(dir);
|
|
80
|
+
const pkgRaw = fs.readFileSync(path.join(dir, 'package.json'), 'utf-8');
|
|
81
|
+
// JSON.parse returns any; scripts is optional-chained below, so an
|
|
82
|
+
// unexpected shape yields undefined rather than a crash.
|
|
83
|
+
const pkg = JSON.parse(pkgRaw);
|
|
84
|
+
const buildScript = pkg.scripts?.build;
|
|
85
|
+
if (!buildScript) {
|
|
86
|
+
return {
|
|
87
|
+
ok: false,
|
|
88
|
+
buildOutput: '',
|
|
89
|
+
message: `your package.json has no build script. ${detection.framework} projects need one. add "build": "${BUILD_SCRIPT_SUGGESTION[detection.framework]}" and run pushto again.`,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (!fs.existsSync(path.join(dir, 'node_modules'))) {
|
|
93
|
+
log(`installing dependencies (${pm})...`);
|
|
94
|
+
const install = await exec(installCmd(pm), dir);
|
|
95
|
+
if (install.code !== 0) {
|
|
96
|
+
return { ok: false, message: 'dependency install failed. run the install yourself to see the full story, then pushto again.', buildOutput: install.output };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const buildStart = Date.now();
|
|
100
|
+
log(`building (${detection.framework})...`);
|
|
101
|
+
const build = await exec(runScriptCmd(pm, 'build'), dir);
|
|
102
|
+
let typeWarnings = null;
|
|
103
|
+
if (build.code !== 0) {
|
|
104
|
+
// Stock-scaffold typecheck fallback: dev mode never typechecks, so
|
|
105
|
+
// AI-scaffolded apps that work in dev routinely die here on type
|
|
106
|
+
// errors. For the EXACT stock script shape only, retry vite alone,
|
|
107
|
+
// ship, and surface the type errors as a warning.
|
|
108
|
+
if (detection.framework === 'vite' && STOCK_TSC_VITE.test(buildScript)) {
|
|
109
|
+
log('type errors found. retrying with vite alone...');
|
|
110
|
+
const retry = await exec(execLocalBinCmd(pm, 'vite', ['build']), dir);
|
|
111
|
+
if (retry.code !== 0) {
|
|
112
|
+
return { ok: false, message: 'the build failed. the output below is the real story. fix it, or run the build yourself to iterate faster.', buildOutput: retry.output };
|
|
113
|
+
}
|
|
114
|
+
typeWarnings = build.output;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
return { ok: false, message: 'the build failed. the output below is the real story. fix it, or run the build yourself to iterate faster.', buildOutput: build.output };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const outputDir = resolveOutputDir(dir, detection.outputDirs, buildStart);
|
|
121
|
+
if (!outputDir) {
|
|
122
|
+
const looked = [...detection.outputDirs, ...FALLBACK_SCAN_DIRS].join(', ');
|
|
123
|
+
return {
|
|
124
|
+
ok: false,
|
|
125
|
+
buildOutput: build.output,
|
|
126
|
+
message: `the build finished but produced no fresh index.html. looked in: ${looked}. if your build outputs somewhere else, point it at one of those. server-rendered setups need the container path instead.`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return { ok: true, outputDir, typeWarnings };
|
|
130
|
+
};
|
|
131
|
+
export const writeArtifactMeta = (outputDir, meta) => {
|
|
132
|
+
const metaPath = path.join(outputDir, ARTIFACT_META_NAME);
|
|
133
|
+
fs.writeFileSync(metaPath, JSON.stringify({ ...meta, generator: 'pushto-cli' }));
|
|
134
|
+
return () => {
|
|
135
|
+
try {
|
|
136
|
+
fs.rmSync(metaPath, { force: true });
|
|
137
|
+
}
|
|
138
|
+
catch { /* best effort */ }
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=build-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-runner.js","sourceRoot":"","sources":["../../src/lib/build-runner.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -6,6 +6,12 @@ interface PushtoConfig {
|
|
|
6
6
|
projectSlug?: string;
|
|
7
7
|
}
|
|
8
8
|
export declare const config: Conf<PushtoConfig>;
|
|
9
|
+
/**
|
|
10
|
+
* PUSHTO_TOKEN wins over stored config so a headless caller never has to run
|
|
11
|
+
* the browser login flow. An empty value is treated as unset, so
|
|
12
|
+
* `PUSHTO_TOKEN= pushto deploy` falls back rather than authenticating as "".
|
|
13
|
+
* This is also the bootstrap path for MCP auth, which expects a bearer token.
|
|
14
|
+
*/
|
|
9
15
|
export declare const getToken: () => string | undefined;
|
|
10
16
|
export declare const getRefreshToken: () => string | undefined;
|
|
11
17
|
export declare const setToken: (token: string, refreshToken?: string) => void;
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,MAAM,oBAKjB,CAAC;AAEH,eAAO,MAAM,QAAQ,QAAO,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,MAAM,oBAKjB,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,QAAO,MAAM,GAAG,SAA4D,CAAC;AAClG,eAAO,MAAM,eAAe,QAAO,MAAM,GAAG,SAAuC,CAAC;AAEpF,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,EAAE,eAAe,MAAM,KAAG,IAG/D,CAAC;AAEF,eAAO,MAAM,UAAU,QAAO,IAG7B,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,MAAM,GAAG,SAAsC,CAAC;AAElF,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,IAE7C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,OAejC,CAAC"}
|
package/dist/lib/config.js
CHANGED
|
@@ -5,7 +5,13 @@ export const config = new Conf({
|
|
|
5
5
|
apiUrl: 'https://pushto.host',
|
|
6
6
|
},
|
|
7
7
|
});
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* PUSHTO_TOKEN wins over stored config so a headless caller never has to run
|
|
10
|
+
* the browser login flow. An empty value is treated as unset, so
|
|
11
|
+
* `PUSHTO_TOKEN= pushto deploy` falls back rather than authenticating as "".
|
|
12
|
+
* This is also the bootstrap path for MCP auth, which expects a bearer token.
|
|
13
|
+
*/
|
|
14
|
+
export const getToken = () => process.env.PUSHTO_TOKEN || config.get('token');
|
|
9
15
|
export const getRefreshToken = () => config.get('refreshToken');
|
|
10
16
|
export const setToken = (token, refreshToken) => {
|
|
11
17
|
config.set('token', token);
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AASxB,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAe;IAC3C,WAAW,EAAE,QAAQ;IACrB,QAAQ,EAAE;QACR,MAAM,EAAE,qBAAqB;KAC9B;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAuB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AASxB,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAe;IAC3C,WAAW,EAAE,QAAQ;IACrB,QAAQ,EAAE;QACR,MAAM,EAAE,qBAAqB;KAC9B;CACF,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAuB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAClG,MAAM,CAAC,MAAM,eAAe,GAAG,GAAuB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAEpF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,YAAqB,EAAQ,EAAE;IACrE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3B,IAAI,YAAY;QAAE,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;AAC7D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,GAAS,EAAE;IACnC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvB,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AAChC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAuB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAElF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAQ,EAAE;IACnD,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAY,EAAE;IAC1C,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QACvE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAa,CAAC;QAClC,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACzC,0CAA0C;QAC1C,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Follow-loop primitive for `pushto cron tail`: the history endpoint
|
|
3
|
+
* returns newest-first, a live tail prints unseen rows oldest-first.
|
|
4
|
+
*/
|
|
5
|
+
export interface TailExecution {
|
|
6
|
+
id: string;
|
|
7
|
+
executedAt: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const selectNewExecutions: <T extends TailExecution>(seen: Set<string>, executions: T[]) => T[];
|
|
10
|
+
//# sourceMappingURL=cron-tail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron-tail.d.ts","sourceRoot":"","sources":["../../src/lib/cron-tail.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,aAAa,EACzD,MAAM,GAAG,CAAC,MAAM,CAAC,EACjB,YAAY,CAAC,EAAE,KACd,CAAC,EAIoF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron-tail.js","sourceRoot":"","sources":["../../src/lib/cron-tail.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,IAAiB,EACjB,UAAe,EACV,EAAE,CACP,UAAU;KACP,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KAC9B,KAAK,EAAE;KACP,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI-side detection for static-output frameworks — the ones `pushto`
|
|
3
|
+
* builds locally and ships as an artifact (spec: docs/superpowers/specs/
|
|
4
|
+
* 2026-07-10-static-build-pipeline-design.md).
|
|
5
|
+
*
|
|
6
|
+
* This table deliberately does NOT import @pushto/shared: the published
|
|
7
|
+
* CLI ships standalone (npm + Homebrew Bun-compile). The shared
|
|
8
|
+
* FRAMEWORK_TABLE in packages/shared/src/constants.ts is the truth; a
|
|
9
|
+
* sync test in apps/web/__tests__/frameworks-docs-sync.test.ts fails CI
|
|
10
|
+
* if the two drift.
|
|
11
|
+
*/
|
|
12
|
+
export interface CliFrameworkEntry {
|
|
13
|
+
id: 'vite' | 'astro' | 'gatsby' | 'angular' | 'cra' | 'eleventy';
|
|
14
|
+
deps: readonly string[];
|
|
15
|
+
configFiles: readonly string[];
|
|
16
|
+
outputDirs: readonly string[];
|
|
17
|
+
spa: boolean;
|
|
18
|
+
/** `scripts.start` commands that are the framework's OWN dev server
|
|
19
|
+
* (stock CRA/Angular/Gatsby/Eleventy scaffolds all ship one). Mirrors
|
|
20
|
+
* packages/shared/src/constants.ts's FrameworkEntry.devStartCommands —
|
|
21
|
+
* the sync test compares the two field-for-field. */
|
|
22
|
+
devStartCommands: readonly string[];
|
|
23
|
+
}
|
|
24
|
+
export declare const STATIC_BUILD_FRAMEWORKS: readonly CliFrameworkEntry[];
|
|
25
|
+
export interface StaticFrameworkDetection {
|
|
26
|
+
framework: CliFrameworkEntry['id'];
|
|
27
|
+
spa: boolean;
|
|
28
|
+
outputDirs: string[];
|
|
29
|
+
}
|
|
30
|
+
export declare const detectStaticFramework: (dir: string) => StaticFrameworkDetection | null;
|
|
31
|
+
//# sourceMappingURL=detect-static-framework.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-static-framework.d.ts","sourceRoot":"","sources":["../../src/lib/detect-static-framework.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,UAAU,CAAC;IACjE,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,GAAG,EAAE,OAAO,CAAC;IACb;;;0DAGsD;IACtD,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAMD,eAAO,MAAM,uBAAuB,EAAE,SAAS,iBAAiB,EAOtD,CAAC;AASX,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACnC,GAAG,EAAE,OAAO,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAgDD,eAAO,MAAM,qBAAqB,GAAI,KAAK,MAAM,KAAG,wBAAwB,GAAG,IA4C9E,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
// Order matters: specific frameworks first, the vite catch-all LAST
|
|
4
|
+
// (astro/gatsby/etc. may pull vite in transitively; direct-dep checks
|
|
5
|
+
// keep this unambiguous, but a user adding vite as a sibling devDep
|
|
6
|
+
// must still land on the specific framework).
|
|
7
|
+
export const STATIC_BUILD_FRAMEWORKS = [
|
|
8
|
+
{ id: 'astro', deps: ['astro'], configFiles: [], outputDirs: ['dist'], spa: false, devStartCommands: ['astro dev', 'astro preview'] },
|
|
9
|
+
{ id: 'gatsby', deps: ['gatsby'], configFiles: [], outputDirs: ['public'], spa: false, devStartCommands: ['gatsby develop', 'gatsby serve'] },
|
|
10
|
+
{ id: 'angular', deps: ['@angular/core'], configFiles: ['angular.json'], outputDirs: ['ANGULAR_JSON'], spa: true, devStartCommands: ['ng serve'] },
|
|
11
|
+
{ id: 'cra', deps: ['react-scripts'], configFiles: [], outputDirs: ['build'], spa: true, devStartCommands: ['react-scripts start'] },
|
|
12
|
+
{ id: 'eleventy', deps: ['@11ty/eleventy'], configFiles: [], outputDirs: ['_site'], spa: false, devStartCommands: ['eleventy --serve', 'npx @11ty/eleventy --serve', 'npx eleventy --serve', '@11ty/eleventy --serve'] },
|
|
13
|
+
{ id: 'vite', deps: ['vite'], configFiles: ['vite.config.js', 'vite.config.ts', 'vite.config.mjs', 'vite.config.mts'], outputDirs: ['dist'], spa: true, devStartCommands: ['vite', 'vite dev', 'vite preview'] },
|
|
14
|
+
];
|
|
15
|
+
// A dep from this list means the project is SSR-shaped and belongs on
|
|
16
|
+
// the container path even though vite is probably also present.
|
|
17
|
+
const SSR_MARKERS = [
|
|
18
|
+
'next', 'nuxt', '@sveltejs/kit',
|
|
19
|
+
'@solidjs/start', 'solid-start',
|
|
20
|
+
];
|
|
21
|
+
const readJson = (file) => {
|
|
22
|
+
try {
|
|
23
|
+
// JSON.parse returns any; treat as unknown and narrow field-by-field below
|
|
24
|
+
return JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
/** Expand angular.json into concrete output-dir candidates. */
|
|
31
|
+
const angularOutputDirs = (dir) => {
|
|
32
|
+
const parsed = readJson(path.join(dir, 'angular.json'));
|
|
33
|
+
const projects = parsed && typeof parsed === 'object'
|
|
34
|
+
? // Shape probed optionally; every access below is optional-chained, so wrong shape yields undefined
|
|
35
|
+
parsed.projects
|
|
36
|
+
: undefined;
|
|
37
|
+
const name = projects ? Object.keys(projects)[0] : undefined;
|
|
38
|
+
if (!name)
|
|
39
|
+
return ['dist'];
|
|
40
|
+
const project = projects?.[name];
|
|
41
|
+
const outputPath = project && typeof project === 'object'
|
|
42
|
+
? // Shape probed optionally with nested optional chains; wrong structure yields undefined, not a crash
|
|
43
|
+
(project
|
|
44
|
+
.architect?.build?.options?.outputPath)
|
|
45
|
+
: undefined;
|
|
46
|
+
// outputPath can be a string or (v17 application builder) { base: string }
|
|
47
|
+
const base = typeof outputPath === 'string'
|
|
48
|
+
? outputPath
|
|
49
|
+
: outputPath && typeof outputPath === 'object' && typeof
|
|
50
|
+
// Narrowed to object; check for base property before accessing
|
|
51
|
+
outputPath.base === 'string'
|
|
52
|
+
? // Base is now proven string; safe to cast
|
|
53
|
+
outputPath.base
|
|
54
|
+
: `dist/${name}`;
|
|
55
|
+
return [`${base}/browser`, base];
|
|
56
|
+
};
|
|
57
|
+
export const detectStaticFramework = (dir) => {
|
|
58
|
+
const pkgPath = path.join(dir, 'package.json');
|
|
59
|
+
if (!fs.existsSync(pkgPath))
|
|
60
|
+
return null;
|
|
61
|
+
const parsed = readJson(pkgPath);
|
|
62
|
+
if (!parsed || typeof parsed !== 'object')
|
|
63
|
+
return null;
|
|
64
|
+
// Proven to be a non-null object above; narrow to PkgJson shape
|
|
65
|
+
const pkg = parsed;
|
|
66
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
67
|
+
// Tie-breaker 1: SSR frameworks are container-path regardless of scripts.
|
|
68
|
+
if (SSR_MARKERS.some((d) => d in allDeps) ||
|
|
69
|
+
Object.keys(allDeps).some((d) => d.startsWith('@remix-run/'))) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
for (const entry of STATIC_BUILD_FRAMEWORKS) {
|
|
73
|
+
const byDep = entry.deps.some((d) => d in allDeps);
|
|
74
|
+
const byConfig = entry.configFiles.some((f) => fs.existsSync(path.join(dir, f)));
|
|
75
|
+
if (!byDep && !byConfig)
|
|
76
|
+
continue;
|
|
77
|
+
// Tie-breaker 2: a start script means "this is a server" — UNLESS it's
|
|
78
|
+
// just the matched framework's own dev server (stock CRA/Angular/
|
|
79
|
+
// Gatsby/Eleventy scaffolds all ship one; the old rule treated any
|
|
80
|
+
// start script as dynamic and routed every one of them past the
|
|
81
|
+
// static-build path). Word-boundary match: the command IS the dev
|
|
82
|
+
// command, or continues with a space (flags) — `vite-custom-wrapper.js`
|
|
83
|
+
// must not match `vite`.
|
|
84
|
+
const rawStart = pkg.scripts?.start;
|
|
85
|
+
if (rawStart) {
|
|
86
|
+
const cmd = rawStart.trim();
|
|
87
|
+
const isOwnDevServer = entry.devStartCommands.some((c) => cmd === c || cmd.startsWith(`${c} `));
|
|
88
|
+
if (!isOwnDevServer)
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const outputDirs = entry.outputDirs[0] === 'ANGULAR_JSON' ? angularOutputDirs(dir) : [...entry.outputDirs];
|
|
92
|
+
return { framework: entry.id, spa: entry.spa, outputDirs };
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=detect-static-framework.js.map
|