@pushto/cli 0.4.6 → 0.4.10
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__/auth-add.test.d.ts +2 -0
- package/dist/commands/__tests__/auth-add.test.d.ts.map +1 -0
- package/dist/commands/__tests__/auth-add.test.js +27 -0
- package/dist/commands/__tests__/auth-add.test.js.map +1 -0
- package/dist/commands/__tests__/deploy-target.test.d.ts +2 -0
- package/dist/commands/__tests__/deploy-target.test.d.ts.map +1 -0
- package/dist/commands/__tests__/deploy-target.test.js +43 -0
- package/dist/commands/__tests__/deploy-target.test.js.map +1 -0
- package/dist/commands/__tests__/headless-smoke.test.js +35 -1
- package/dist/commands/__tests__/headless-smoke.test.js.map +1 -1
- package/dist/commands/__tests__/upgrade-trust.test.d.ts +2 -0
- package/dist/commands/__tests__/upgrade-trust.test.d.ts.map +1 -0
- package/dist/commands/__tests__/upgrade-trust.test.js +26 -0
- package/dist/commands/__tests__/upgrade-trust.test.js.map +1 -0
- package/dist/commands/auth.d.ts +13 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +100 -1
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/deploy.d.ts +27 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +66 -8
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +20 -45
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/link.d.ts +10 -0
- package/dist/commands/link.d.ts.map +1 -0
- package/dist/commands/link.js +78 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/preview.d.ts.map +1 -1
- package/dist/commands/preview.js +7 -4
- package/dist/commands/preview.js.map +1 -1
- package/dist/commands/upgrade.d.ts +2 -0
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +52 -1
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/commands/use.d.ts.map +1 -1
- package/dist/commands/use.js +2 -1
- package/dist/commands/use.js.map +1 -1
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- 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__/resolve-slug.test.d.ts +2 -0
- package/dist/lib/__tests__/resolve-slug.test.d.ts.map +1 -0
- package/dist/lib/__tests__/resolve-slug.test.js +54 -0
- package/dist/lib/__tests__/resolve-slug.test.js.map +1 -0
- package/dist/lib/__tests__/snippet-insert.test.d.ts +2 -0
- package/dist/lib/__tests__/snippet-insert.test.d.ts.map +1 -0
- package/dist/lib/__tests__/snippet-insert.test.js +69 -0
- package/dist/lib/__tests__/snippet-insert.test.js.map +1 -0
- package/dist/lib/create-project.d.ts +19 -0
- package/dist/lib/create-project.d.ts.map +1 -0
- package/dist/lib/create-project.js +51 -0
- package/dist/lib/create-project.js.map +1 -0
- package/dist/lib/project-name.d.ts +6 -0
- package/dist/lib/project-name.d.ts.map +1 -0
- package/dist/lib/project-name.js +10 -0
- package/dist/lib/project-name.js.map +1 -0
- package/dist/lib/resolve-slug.d.ts +13 -3
- package/dist/lib/resolve-slug.d.ts.map +1 -1
- package/dist/lib/resolve-slug.js +21 -9
- package/dist/lib/resolve-slug.js.map +1 -1
- package/dist/lib/snippet-insert.d.ts +36 -0
- package/dist/lib/snippet-insert.d.ts.map +1 -0
- package/dist/lib/snippet-insert.js +74 -0
- package/dist/lib/snippet-insert.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +3 -3
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-add.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/auth-add.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import { resolveEnableConsent } from '../auth.js';
|
|
3
|
+
describe('resolveEnableConsent', () => {
|
|
4
|
+
it('never touches stdin when prompting is not allowed and --yes is absent', async () => {
|
|
5
|
+
const ask = vi.fn();
|
|
6
|
+
const result = await resolveEnableConsent({ canPrompt: false, yes: false, ask });
|
|
7
|
+
expect(result).toBe('abort');
|
|
8
|
+
expect(ask).not.toHaveBeenCalled();
|
|
9
|
+
});
|
|
10
|
+
it('--yes enables without asking, even on a real terminal', async () => {
|
|
11
|
+
const ask = vi.fn();
|
|
12
|
+
const result = await resolveEnableConsent({ canPrompt: true, yes: true, ask });
|
|
13
|
+
expect(result).toBe('enable');
|
|
14
|
+
expect(ask).not.toHaveBeenCalled();
|
|
15
|
+
});
|
|
16
|
+
it('asks a human on a real terminal — y means enable', async () => {
|
|
17
|
+
const ask = vi.fn().mockResolvedValue('y');
|
|
18
|
+
expect(await resolveEnableConsent({ canPrompt: true, yes: false, ask })).toBe('enable');
|
|
19
|
+
});
|
|
20
|
+
it('anything but y/yes aborts', async () => {
|
|
21
|
+
const ask = vi.fn().mockResolvedValue('n');
|
|
22
|
+
expect(await resolveEnableConsent({ canPrompt: true, yes: false, ask })).toBe('abort');
|
|
23
|
+
ask.mockResolvedValue('');
|
|
24
|
+
expect(await resolveEnableConsent({ canPrompt: true, yes: false, ask })).toBe('abort');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=auth-add.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-add.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/auth-add.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAElD,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,EAAkC,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QACjF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,EAAkC,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/E,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,EAAkC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC3E,MAAM,CAAC,MAAM,oBAAoB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,EAAkC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC3E,MAAM,CAAC,MAAM,oBAAoB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvF,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAC1B,MAAM,CAAC,MAAM,oBAAoB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-target.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/deploy-target.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { decideDeployTarget } from '../deploy.js';
|
|
3
|
+
/**
|
|
4
|
+
* PINs the policy for what a bare `pushto` targets.
|
|
5
|
+
*
|
|
6
|
+
* The 2026-07-30 incident: a fresh directory (soiaa) with no .pushto fell
|
|
7
|
+
* back to the global slug and shipped its files into an unrelated project
|
|
8
|
+
* (offload-test). The policy now: a deploy target comes from the directory's
|
|
9
|
+
* own link or gets created for this directory — never inherited from global
|
|
10
|
+
* state. Humans are offered a project named after the directory, --yes takes
|
|
11
|
+
* that documented default silently, and headless callers fail NO_PROJECT.
|
|
12
|
+
*/
|
|
13
|
+
describe('decideDeployTarget', () => {
|
|
14
|
+
it('uses the directory link when present, ignoring everything else', () => {
|
|
15
|
+
const d = decideDeployTarget({ localSlug: 'soiaa', dirName: 'whatever', canPrompt: false, yes: true });
|
|
16
|
+
expect(d).toEqual({ action: 'use', slug: 'soiaa' });
|
|
17
|
+
});
|
|
18
|
+
it('offers to create a project named after the directory for a human', () => {
|
|
19
|
+
const d = decideDeployTarget({ localSlug: undefined, dirName: 'soiaa', canPrompt: true, yes: false });
|
|
20
|
+
expect(d).toEqual({ action: 'offer-create', slug: 'soiaa' });
|
|
21
|
+
});
|
|
22
|
+
it('slugifies the directory name with the init rules', () => {
|
|
23
|
+
const d = decideDeployTarget({ localSlug: undefined, dirName: 'My Cool App!', canPrompt: true, yes: false });
|
|
24
|
+
expect(d).toEqual({ action: 'offer-create', slug: 'my-cool-app' });
|
|
25
|
+
});
|
|
26
|
+
it('creates silently under --yes (the documented default)', () => {
|
|
27
|
+
const d = decideDeployTarget({ localSlug: undefined, dirName: 'soiaa', canPrompt: false, yes: true });
|
|
28
|
+
expect(d).toEqual({ action: 'auto-create', slug: 'soiaa' });
|
|
29
|
+
});
|
|
30
|
+
it('fails headless with no --yes instead of touching the global slug', () => {
|
|
31
|
+
const d = decideDeployTarget({ localSlug: undefined, dirName: 'soiaa', canPrompt: false, yes: false });
|
|
32
|
+
expect(d).toEqual({ action: 'fail', reason: 'non-interactive' });
|
|
33
|
+
});
|
|
34
|
+
it('fails when the directory name cannot become a valid slug', () => {
|
|
35
|
+
const d = decideDeployTarget({ localSlug: undefined, dirName: 'ab', canPrompt: true, yes: false });
|
|
36
|
+
expect(d).toEqual({ action: 'fail', reason: 'unnameable' });
|
|
37
|
+
});
|
|
38
|
+
it('--yes cannot conjure a name for an unnameable directory', () => {
|
|
39
|
+
const d = decideDeployTarget({ localSlug: undefined, dirName: '__', canPrompt: false, yes: true });
|
|
40
|
+
expect(d).toEqual({ action: 'fail', reason: 'unnameable' });
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
//# sourceMappingURL=deploy-target.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy-target.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/deploy-target.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,9 +10,10 @@ const HERE = path.dirname(fileURLToPath(import.meta.url));
|
|
|
10
10
|
const CLI_ROOT = path.resolve(HERE, '../../..');
|
|
11
11
|
const REPO_ROOT = path.resolve(CLI_ROOT, '../..');
|
|
12
12
|
const ENTRY = path.join(CLI_ROOT, 'dist', 'cli.js');
|
|
13
|
-
const runHeadless = (args) => {
|
|
13
|
+
const runHeadless = (args, opts = {}) => {
|
|
14
14
|
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'pushto-home-'));
|
|
15
15
|
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'pushto-cwd-'));
|
|
16
|
+
opts.seedHome?.(home);
|
|
16
17
|
return new Promise((resolve) => {
|
|
17
18
|
const child = spawn(process.execPath, [ENTRY, ...args], {
|
|
18
19
|
cwd,
|
|
@@ -25,6 +26,7 @@ const runHeadless = (args) => {
|
|
|
25
26
|
PUSHTO_TOKEN: '',
|
|
26
27
|
CI: '1',
|
|
27
28
|
PUSHTO_NONINTERACTIVE: '1',
|
|
29
|
+
...opts.env,
|
|
28
30
|
},
|
|
29
31
|
});
|
|
30
32
|
let stdout = '';
|
|
@@ -76,6 +78,38 @@ describe('headless cli', () => {
|
|
|
76
78
|
expect(parsed.error.code, `${name} code`).toBe('NOT_AUTHENTICATED');
|
|
77
79
|
}
|
|
78
80
|
}, 90_000);
|
|
81
|
+
/**
|
|
82
|
+
* PINs the soiaa → offload-test fix at the binary level. The temp HOME
|
|
83
|
+
* carries a global projectSlug (as if `pushto use`/`init` ran elsewhere)
|
|
84
|
+
* and a real token via PUSHTO_TOKEN, but the cwd has no .pushto. Pre-fix,
|
|
85
|
+
* deploy followed the global slug and shipped the directory into the
|
|
86
|
+
* wrong project. Post-fix it must refuse with NO_PROJECT before touching
|
|
87
|
+
* the network — apiUrl points at a dead port so any regression that
|
|
88
|
+
* reaches for the network fails fast and loud, not against prod.
|
|
89
|
+
*/
|
|
90
|
+
it('deploy never follows the global slug from an unlinked directory', async () => {
|
|
91
|
+
const seedHome = (home) => {
|
|
92
|
+
const cfg = JSON.stringify({ projectSlug: 'offload-test', apiUrl: 'http://127.0.0.1:9' });
|
|
93
|
+
const locations = [
|
|
94
|
+
path.join(home, 'Library', 'Preferences', 'pushto-nodejs'),
|
|
95
|
+
path.join(home, '.config', 'pushto-nodejs'),
|
|
96
|
+
];
|
|
97
|
+
for (const dir of locations) {
|
|
98
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
99
|
+
fs.writeFileSync(path.join(dir, 'config.json'), cfg);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const res = await runHeadless(['deploy', '--json'], {
|
|
103
|
+
env: { PUSHTO_TOKEN: 'test-token' },
|
|
104
|
+
seedHome,
|
|
105
|
+
});
|
|
106
|
+
expect(res.timedOut).toBe(false);
|
|
107
|
+
expect(res.code).toBe(20);
|
|
108
|
+
const parsed = JSON.parse(res.stdout);
|
|
109
|
+
expect(parsed.ok).toBe(false);
|
|
110
|
+
expect(parsed.error.code).toBe('NO_PROJECT');
|
|
111
|
+
expect(parsed.error.fix?.cmd).toContain('pushto init');
|
|
112
|
+
}, 30_000);
|
|
79
113
|
it('db reports not-authenticated in json, exit 10', async () => {
|
|
80
114
|
const res = await runHeadless(['db', 'provision', '--json']);
|
|
81
115
|
expect(res.timedOut).toBe(false);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headless-smoke.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/headless-smoke.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AAChD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAClD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AA0BpD,MAAM,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"headless-smoke.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/headless-smoke.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade-trust.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/upgrade-trust.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { parseTapTrusted } from '../upgrade.js';
|
|
3
|
+
/**
|
|
4
|
+
* Homebrew ≥6 refuses to load formulae from untrusted third-party taps
|
|
5
|
+
* (default-on via HOMEBREW_REQUIRE_TAP_TRUST), and its error message
|
|
6
|
+
* suggests a formula-level trust that does NOT unblock `brew upgrade` —
|
|
7
|
+
* only tap-level trust does. `pushto upgrade` pre-flights the tap's trust
|
|
8
|
+
* state from `brew tap-info` output; this pins the parse.
|
|
9
|
+
*/
|
|
10
|
+
describe('parseTapTrusted', () => {
|
|
11
|
+
it('reads Trusted from tap-info output', () => {
|
|
12
|
+
expect(parseTapTrusted('mydude-industries/tap: Installed\nTrusted\n1 formula')).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
it('reads Untrusted from tap-info output', () => {
|
|
15
|
+
expect(parseTapTrusted('mydude-industries/tap: Installed\nUntrusted\n1 formula')).toBe(false);
|
|
16
|
+
});
|
|
17
|
+
it('returns null when the output has no trust line (older brew)', () => {
|
|
18
|
+
expect(parseTapTrusted('mydude-industries/tap: Installed\n1 formula')).toBeNull();
|
|
19
|
+
});
|
|
20
|
+
it('does not mistake Untrusted for Trusted', () => {
|
|
21
|
+
// "Untrusted" contains the substring "trusted" — the parse must be
|
|
22
|
+
// line-anchored or the untrusted state reads as trusted.
|
|
23
|
+
expect(parseTapTrusted('Untrusted')).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
//# sourceMappingURL=upgrade-trust.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade-trust.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/upgrade-trust.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;GAMG;AAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,eAAe,CAAC,sDAAsD,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,eAAe,CAAC,wDAAwD,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,CAAC,eAAe,CAAC,6CAA6C,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACpF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,mEAAmE;QACnE,yDAAyD;QACzD,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/commands/auth.d.ts
CHANGED
|
@@ -1,2 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Whether to flip auth on for the user. Pure so the test can prove the
|
|
3
|
+
* no-stdin path never reaches for stdin (readline never settles on EOF —
|
|
4
|
+
* the deploy hang, 2026-07-24).
|
|
5
|
+
*/
|
|
6
|
+
export declare const resolveEnableConsent: (args: {
|
|
7
|
+
canPrompt: boolean;
|
|
8
|
+
yes: boolean;
|
|
9
|
+
ask: (q: string) => Promise<string>;
|
|
10
|
+
}) => Promise<"enable" | "abort">;
|
|
11
|
+
export declare const auth: (action: string, args: string[], opts?: {
|
|
12
|
+
yes?: boolean;
|
|
13
|
+
}) => Promise<void>;
|
|
2
14
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AA8CA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAU,MAAM;IAC/C,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACrC,KAAG,OAAO,CAAC,QAAQ,GAAG,OAAO,CAK7B,CAAC;AAEF,eAAO,MAAM,IAAI,GACf,QAAQ,MAAM,EACd,MAAM,MAAM,EAAE,EACd,OAAM;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAO,KAC3B,OAAO,CAAC,IAAI,CAuJd,CAAC"}
|
package/dist/commands/auth.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
2
4
|
import { getToken } from '../lib/config.js';
|
|
3
5
|
import { resolveSlug } from '../lib/resolve-slug.js';
|
|
4
6
|
import { api } from '../lib/api.js';
|
|
5
7
|
import { safeJson } from '../lib/safe-json.js';
|
|
8
|
+
import { canPrompt } from '../lib/interactive.js';
|
|
9
|
+
import { ask } from '../lib/ask.js';
|
|
10
|
+
import { authSnippet, isAlreadyWired, insertBeforeBody, detectTarget, reactWrapperSource, } from '../lib/snippet-insert.js';
|
|
6
11
|
const ensureAuthed = () => {
|
|
7
12
|
const token = getToken();
|
|
8
13
|
if (!token) {
|
|
@@ -19,10 +24,24 @@ const ensureAuthed = () => {
|
|
|
19
24
|
};
|
|
20
25
|
const usage = () => {
|
|
21
26
|
console.log(chalk.dim(' usage:'));
|
|
27
|
+
console.log(chalk.cyan(' pushto auth add') + chalk.dim(' put the login widget in this project'));
|
|
22
28
|
console.log(chalk.cyan(' pushto auth users') + chalk.dim(' list end-users'));
|
|
23
29
|
console.log(chalk.cyan(' pushto auth users rm <email|id>') + chalk.dim(' remove a user'));
|
|
24
30
|
};
|
|
25
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Whether to flip auth on for the user. Pure so the test can prove the
|
|
33
|
+
* no-stdin path never reaches for stdin (readline never settles on EOF —
|
|
34
|
+
* the deploy hang, 2026-07-24).
|
|
35
|
+
*/
|
|
36
|
+
export const resolveEnableConsent = async (args) => {
|
|
37
|
+
if (args.yes)
|
|
38
|
+
return 'enable';
|
|
39
|
+
if (!args.canPrompt)
|
|
40
|
+
return 'abort';
|
|
41
|
+
const answer = (await args.ask('auth is off for this project. turn it on? (y/N): ')).toLowerCase();
|
|
42
|
+
return answer === 'y' || answer === 'yes' ? 'enable' : 'abort';
|
|
43
|
+
};
|
|
44
|
+
export const auth = async (action, args, opts = {}) => {
|
|
26
45
|
if (!action || action === 'help')
|
|
27
46
|
return usage();
|
|
28
47
|
const slug = ensureAuthed();
|
|
@@ -72,6 +91,86 @@ export const auth = async (action, args) => {
|
|
|
72
91
|
}
|
|
73
92
|
return;
|
|
74
93
|
}
|
|
94
|
+
if (action === 'add') {
|
|
95
|
+
const statusRes = await api(`/cli/projects/${slug}/auth`, { method: 'GET' });
|
|
96
|
+
let status = await safeJson(statusRes);
|
|
97
|
+
if (!statusRes.ok) {
|
|
98
|
+
if (status.code === 'PAID_FEATURE') {
|
|
99
|
+
console.log(chalk.yellow('> pushto auth is part of the full experience.'));
|
|
100
|
+
console.log(chalk.dim(' upgrade at https://pushto.host/dashboard/billing'));
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
console.log(chalk.red(`> ${status.error ?? 'could not read auth status.'}`));
|
|
104
|
+
}
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
if (!status.enabled) {
|
|
108
|
+
const consent = await resolveEnableConsent({
|
|
109
|
+
canPrompt: canPrompt({ yes: opts.yes }),
|
|
110
|
+
yes: opts.yes ?? false,
|
|
111
|
+
ask,
|
|
112
|
+
});
|
|
113
|
+
if (consent === 'abort') {
|
|
114
|
+
console.log(chalk.yellow('> auth is off for this project.'));
|
|
115
|
+
console.log(chalk.dim(' run ') + chalk.cyan('pushto auth add --yes') +
|
|
116
|
+
chalk.dim(' to turn it on, or enable it in the dashboard.'));
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
const enableRes = await api(`/cli/projects/${slug}/auth`, { method: 'POST' });
|
|
120
|
+
const enabled = await safeJson(enableRes);
|
|
121
|
+
if (!enableRes.ok) {
|
|
122
|
+
console.log(chalk.red(`> ${enabled.error ?? 'could not enable auth.'}`));
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
console.log(chalk.green('> auth is on. login endpoints are live.'));
|
|
126
|
+
if (enabled.restartWarning)
|
|
127
|
+
console.log(chalk.yellow(` ${enabled.restartWarning}`));
|
|
128
|
+
status = { ...status, ...enabled, enabled: true };
|
|
129
|
+
}
|
|
130
|
+
if (!status.apiKey) {
|
|
131
|
+
console.log(chalk.red('> auth is on but no api key came back. try again in a moment.'));
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
const snippet = authSnippet(status.projectId, status.apiKey);
|
|
135
|
+
const target = detectTarget(process.cwd());
|
|
136
|
+
if (target.kind === 'html') {
|
|
137
|
+
const html = readFileSync(target.path, 'utf8');
|
|
138
|
+
if (isAlreadyWired(html)) {
|
|
139
|
+
console.log(chalk.green(`> ${target.path} already has the widget. nothing to do.`));
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const updated = insertBeforeBody(html, snippet);
|
|
143
|
+
if (updated === null) {
|
|
144
|
+
console.log(chalk.yellow(`> ${target.path} has no </body> tag, so nothing was touched.`));
|
|
145
|
+
console.log(chalk.dim(' put these two lines in the page where you want the login box:'));
|
|
146
|
+
console.log(`\n${snippet}\n`);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
writeFileSync(target.path, updated);
|
|
150
|
+
console.log(chalk.green(`> added the login widget to ${target.path}.`));
|
|
151
|
+
console.log(chalk.dim(' next deploy ships it. run ') + chalk.cyan('pushto') + chalk.dim(' when ready.'));
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (target.kind === 'react') {
|
|
155
|
+
const wrapperPath = join(process.cwd(), 'src', 'pushto-auth.tsx');
|
|
156
|
+
if (existsSync(wrapperPath)) {
|
|
157
|
+
console.log(chalk.green(`> ${wrapperPath} already exists. nothing to do.`));
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
mkdirSync(join(process.cwd(), 'src'), { recursive: true });
|
|
161
|
+
writeFileSync(wrapperPath, reactWrapperSource(status.projectId, status.apiKey));
|
|
162
|
+
console.log(chalk.green('> wrote src/pushto-auth.tsx.'));
|
|
163
|
+
}
|
|
164
|
+
console.log(chalk.dim(' drop this anywhere you want the login box:'));
|
|
165
|
+
console.log(chalk.cyan("\n import { PushtoAuth } from './pushto-auth';\n <PushtoAuth />\n"));
|
|
166
|
+
console.log(chalk.dim(' next deploy ships it.'));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
console.log(chalk.dim(' put these two lines in the page where you want the login box:'));
|
|
170
|
+
console.log(`\n${snippet}\n`);
|
|
171
|
+
console.log(chalk.dim(' next deploy ships it.'));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
75
174
|
usage();
|
|
76
175
|
};
|
|
77
176
|
//# sourceMappingURL=auth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,33 @@ export declare const resolveCustomDomain: (args: {
|
|
|
10
10
|
canPrompt: boolean;
|
|
11
11
|
ask: (question: string) => Promise<string>;
|
|
12
12
|
}) => Promise<string | null>;
|
|
13
|
+
export type DeployTarget = {
|
|
14
|
+
action: 'use';
|
|
15
|
+
slug: string;
|
|
16
|
+
} | {
|
|
17
|
+
action: 'offer-create';
|
|
18
|
+
slug: string;
|
|
19
|
+
} | {
|
|
20
|
+
action: 'auto-create';
|
|
21
|
+
slug: string;
|
|
22
|
+
} | {
|
|
23
|
+
action: 'fail';
|
|
24
|
+
reason: 'non-interactive' | 'unnameable';
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Which project a bare `pushto` targets. Only ever the directory's own
|
|
28
|
+
* .pushto link — the global slug (last init/use) directs control commands,
|
|
29
|
+
* not uploads of THIS directory's files; following it shipped soiaa into
|
|
30
|
+
* offload-test (2026-07-30). With nothing linked: a human is offered a
|
|
31
|
+
* project named after the directory, --yes takes that documented default
|
|
32
|
+
* silently, and headless callers get NO_PROJECT.
|
|
33
|
+
*/
|
|
34
|
+
export declare const decideDeployTarget: (args: {
|
|
35
|
+
localSlug: string | undefined;
|
|
36
|
+
dirName: string;
|
|
37
|
+
canPrompt: boolean;
|
|
38
|
+
yes: boolean;
|
|
39
|
+
}) => DeployTarget;
|
|
13
40
|
export declare const deploy: (opts?: {
|
|
14
41
|
json?: boolean;
|
|
15
42
|
yes?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAmBA;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAAU,MAAM;IAC9C,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5C,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAKxB,CAAC;AAEF,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,iBAAiB,GAAG,YAAY,CAAA;CAAE,CAAC;AAEjE;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM;IACvC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,OAAO,CAAC;CACd,KAAG,YAQH,CAAC;AAqDF,eAAO,MAAM,MAAM,GAAU,OAAM;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAO,KAAG,OAAO,CAAC,IAAI,CAiavF,CAAC"}
|
package/dist/commands/deploy.js
CHANGED
|
@@ -4,7 +4,10 @@ import fs from 'node:fs';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { getToken } from '../lib/config.js';
|
|
6
6
|
import { api, deploySignal } from '../lib/api.js';
|
|
7
|
-
import {
|
|
7
|
+
import { readLocalSlug } from '../lib/resolve-slug.js';
|
|
8
|
+
import { slugifyProjectName, MIN_SLUG_LENGTH } from '../lib/project-name.js';
|
|
9
|
+
import { createAndLinkProject } from '../lib/create-project.js';
|
|
10
|
+
import { exitCodeFor } from '../lib/errors.js';
|
|
8
11
|
import { safeJson } from '../lib/safe-json.js';
|
|
9
12
|
import { getGitInfo, zipDirectory } from '../lib/zip-project.js';
|
|
10
13
|
import { SERVER_UPLOAD_CAP_BYTES, fmtMB } from '../lib/upload-limits.js';
|
|
@@ -12,7 +15,7 @@ import { parseEnvFile } from '../lib/env-parse.js';
|
|
|
12
15
|
import { prepareArtifact } from '../lib/prepare-artifact.js';
|
|
13
16
|
import { canPrompt } from '../lib/interactive.js';
|
|
14
17
|
import { ask } from '../lib/ask.js';
|
|
15
|
-
import { fail } from '../lib/output.js';
|
|
18
|
+
import { fail, spinnerStream } from '../lib/output.js';
|
|
16
19
|
/**
|
|
17
20
|
* Decide whether to ask for a custom domain, and never reach for stdin when
|
|
18
21
|
* the answer is no. Pre-fix this logic was inline and called ask()
|
|
@@ -28,6 +31,66 @@ export const resolveCustomDomain = async (args) => {
|
|
|
28
31
|
const answer = await args.ask(chalk.dim(' custom domain? (enter to skip): '));
|
|
29
32
|
return answer ? answer : null;
|
|
30
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* Which project a bare `pushto` targets. Only ever the directory's own
|
|
36
|
+
* .pushto link — the global slug (last init/use) directs control commands,
|
|
37
|
+
* not uploads of THIS directory's files; following it shipped soiaa into
|
|
38
|
+
* offload-test (2026-07-30). With nothing linked: a human is offered a
|
|
39
|
+
* project named after the directory, --yes takes that documented default
|
|
40
|
+
* silently, and headless callers get NO_PROJECT.
|
|
41
|
+
*/
|
|
42
|
+
export const decideDeployTarget = (args) => {
|
|
43
|
+
if (args.localSlug)
|
|
44
|
+
return { action: 'use', slug: args.localSlug };
|
|
45
|
+
const candidate = slugifyProjectName(args.dirName);
|
|
46
|
+
if (candidate.length < MIN_SLUG_LENGTH)
|
|
47
|
+
return { action: 'fail', reason: 'unnameable' };
|
|
48
|
+
if (args.yes)
|
|
49
|
+
return { action: 'auto-create', slug: candidate };
|
|
50
|
+
if (args.canPrompt)
|
|
51
|
+
return { action: 'offer-create', slug: candidate };
|
|
52
|
+
return { action: 'fail', reason: 'non-interactive' };
|
|
53
|
+
};
|
|
54
|
+
const acquireDeploySlug = async (opts) => {
|
|
55
|
+
const target = decideDeployTarget({
|
|
56
|
+
localSlug: readLocalSlug(),
|
|
57
|
+
dirName: path.basename(process.cwd()),
|
|
58
|
+
canPrompt: canPrompt(opts),
|
|
59
|
+
yes: Boolean(opts.yes),
|
|
60
|
+
});
|
|
61
|
+
if (target.action === 'use')
|
|
62
|
+
return target.slug;
|
|
63
|
+
if (target.action === 'fail') {
|
|
64
|
+
if (target.reason === 'unnameable') {
|
|
65
|
+
return fail('NO_PROJECT', "no project is linked to this directory, and its name won't work as a project name.", opts, { fix: { label: 'name it yourself', cmd: 'pushto init <name>', prose: 'run {cmd} to name it yourself.' } });
|
|
66
|
+
}
|
|
67
|
+
return fail('NO_PROJECT', 'no project is linked to this directory.', opts, {
|
|
68
|
+
fix: {
|
|
69
|
+
label: 'create one',
|
|
70
|
+
cmd: 'pushto init <name>',
|
|
71
|
+
prose: 'run {cmd} to create one, or link an existing project with pushto link <slug>.',
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (target.action === 'offer-create') {
|
|
76
|
+
console.log(chalk.dim('> nothing is linked to this directory yet.'));
|
|
77
|
+
const answer = await ask(chalk.dim(' create ') + chalk.cyan(`${target.slug}.pushto.host`) + chalk.dim(' from it? (Y/n): '));
|
|
78
|
+
if (answer && !/^y(es)?$/i.test(answer)) {
|
|
79
|
+
console.log(chalk.dim(' okay — nothing deployed.'));
|
|
80
|
+
console.log(chalk.dim(' pick your own name: ') + chalk.cyan('pushto init <name>'));
|
|
81
|
+
console.log(chalk.dim(' or deploy an existing project from here: ') + chalk.cyan('pushto link <slug>'));
|
|
82
|
+
process.exit(exitCodeFor('NO_PROJECT'));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const spinner = ora({ text: `creating ${target.slug}...`, stream: spinnerStream(opts) }).start();
|
|
86
|
+
const created = await createAndLinkProject(target.slug);
|
|
87
|
+
if (!created.ok) {
|
|
88
|
+
spinner.stop();
|
|
89
|
+
fail(created.network ? 'NETWORK' : 'SERVER_ERROR', created.error, opts);
|
|
90
|
+
}
|
|
91
|
+
spinner.succeed(chalk.green(`> ${target.slug} is ready — first deploy coming up.`));
|
|
92
|
+
return target.slug;
|
|
93
|
+
};
|
|
31
94
|
export const deploy = async (opts = {}) => {
|
|
32
95
|
const token = getToken();
|
|
33
96
|
if (!token) {
|
|
@@ -36,12 +99,7 @@ export const deploy = async (opts = {}) => {
|
|
|
36
99
|
fix: { label: 'sign in', cmd: 'pushto login', prose: 'run {cmd} first.' },
|
|
37
100
|
});
|
|
38
101
|
}
|
|
39
|
-
const slug =
|
|
40
|
-
if (!slug) {
|
|
41
|
-
fail('NO_PROJECT', 'no project here.', opts, {
|
|
42
|
-
fix: { label: 'get started', cmd: 'pushto init <name>', prose: 'run {cmd} to get started.' },
|
|
43
|
-
});
|
|
44
|
-
}
|
|
102
|
+
const slug = await acquireDeploySlug(opts);
|
|
45
103
|
// Echo the slug + cwd up front so users in the wrong directory (stale
|
|
46
104
|
// .pushto from a project they forgot, or `pushto` accidentally run from
|
|
47
105
|
// a parent dir that has its own .pushto) catch the mistake BEFORE we
|