@ecomweb/cli 0.7.0 → 0.9.0
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/README.md +56 -32
- package/dist/base-command.d.ts +8 -0
- package/dist/base-command.js +43 -4
- package/dist/base-command.js.map +1 -1
- package/dist/commands/auth/login.d.ts +6 -4
- package/dist/commands/auth/login.js +117 -89
- package/dist/commands/auth/login.js.map +1 -1
- package/dist/commands/auth/logout.js +28 -9
- package/dist/commands/auth/logout.js.map +1 -1
- package/dist/commands/auth/profiles/delete.js +11 -0
- package/dist/commands/auth/profiles/delete.js.map +1 -1
- package/dist/commands/auth/profiles/list.js +2 -2
- package/dist/commands/auth/profiles/list.js.map +1 -1
- package/dist/commands/auth/status.js +17 -9
- package/dist/commands/auth/status.js.map +1 -1
- package/dist/commands/storefront/init.d.ts +2 -1
- package/dist/commands/storefront/init.js +10 -5
- package/dist/commands/storefront/init.js.map +1 -1
- package/dist/commands/{auth/register.d.ts → stores/create.d.ts} +4 -3
- package/dist/commands/stores/create.js +68 -0
- package/dist/commands/stores/create.js.map +1 -0
- package/dist/commands/stores/current.js +1 -1
- package/dist/commands/stores/current.js.map +1 -1
- package/dist/commands/stores/list.js +3 -3
- package/dist/commands/stores/list.js.map +1 -1
- package/dist/commands/stores/switch.js +14 -6
- package/dist/commands/stores/switch.js.map +1 -1
- package/dist/lib/api-client.d.ts +5 -4
- package/dist/lib/api-client.js +32 -16
- package/dist/lib/api-client.js.map +1 -1
- package/dist/lib/codex-skill.d.ts +1 -1
- package/dist/lib/codex-skill.js +12 -8
- package/dist/lib/codex-skill.js.map +1 -1
- package/dist/lib/config.d.ts +6 -18
- package/dist/lib/config.js +35 -64
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/credential-store.d.ts +44 -0
- package/dist/lib/credential-store.js +137 -0
- package/dist/lib/credential-store.js.map +1 -0
- package/dist/lib/device-login.d.ts +22 -0
- package/dist/lib/device-login.js +66 -0
- package/dist/lib/device-login.js.map +1 -0
- package/dist/lib/errors.d.ts +1 -0
- package/dist/lib/errors.js +6 -1
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/file-lock.d.ts +6 -0
- package/dist/lib/file-lock.js +66 -0
- package/dist/lib/file-lock.js.map +1 -0
- package/dist/lib/open-browser.d.ts +13 -0
- package/dist/lib/open-browser.js +38 -0
- package/dist/lib/open-browser.js.map +1 -0
- package/dist/lib/pending-login.d.ts +5 -0
- package/dist/lib/pending-login.js +39 -0
- package/dist/lib/pending-login.js.map +1 -0
- package/dist/lib/project-setup.d.ts +1 -0
- package/dist/lib/project-setup.js +12 -0
- package/dist/lib/project-setup.js.map +1 -1
- package/dist/lib/secure-file.d.ts +1 -0
- package/dist/lib/secure-file.js +15 -0
- package/dist/lib/secure-file.js.map +1 -0
- package/dist/lib/session.d.ts +40 -0
- package/dist/lib/session.js +80 -0
- package/dist/lib/session.js.map +1 -0
- package/dist/lib/store-selection.d.ts +19 -0
- package/dist/lib/store-selection.js +23 -0
- package/dist/lib/store-selection.js.map +1 -0
- package/oclif.manifest.json +1482 -1833
- package/package.json +2 -1
- package/dist/commands/auth/register.js +0 -35
- package/dist/commands/auth/register.js.map +0 -1
- package/dist/commands/auth/verify.d.ts +0 -20
- package/dist/commands/auth/verify.js +0 -43
- package/dist/commands/auth/verify.js.map +0 -1
- package/dist/commands/init.d.ts +0 -22
- package/dist/commands/init.js +0 -84
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -19
- package/dist/commands/setup.js +0 -186
- package/dist/commands/setup.js.map +0 -1
- package/dist/lib/email-login.d.ts +0 -35
- package/dist/lib/email-login.js +0 -86
- package/dist/lib/email-login.js.map +0 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.withFileLock = withFileLock;
|
|
7
|
+
const node_crypto_1 = require("node:crypto");
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const errors_1 = require("./errors");
|
|
11
|
+
function isStale(lockPath, staleMs) {
|
|
12
|
+
try {
|
|
13
|
+
return Date.now() - (0, node_fs_1.statSync)(lockPath).mtimeMs > staleMs;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function release(lockPath, token) {
|
|
20
|
+
let content;
|
|
21
|
+
try {
|
|
22
|
+
content = (0, node_fs_1.readFileSync)(lockPath, "utf8");
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (content.includes(token))
|
|
28
|
+
(0, node_fs_1.rmSync)(lockPath, { force: true });
|
|
29
|
+
}
|
|
30
|
+
async function withFileLock(lockPath, fn, opts = {}) {
|
|
31
|
+
const staleMs = opts.staleMs ?? 30_000;
|
|
32
|
+
const timeoutMs = opts.timeoutMs ?? 10_000;
|
|
33
|
+
const pollMs = opts.pollMs ?? 100;
|
|
34
|
+
(0, node_fs_1.mkdirSync)(node_path_1.default.dirname(lockPath), { recursive: true, mode: 0o700 });
|
|
35
|
+
const token = (0, node_crypto_1.randomBytes)(16).toString("hex");
|
|
36
|
+
const deadline = Date.now() + timeoutMs;
|
|
37
|
+
let fd;
|
|
38
|
+
while (fd === undefined) {
|
|
39
|
+
try {
|
|
40
|
+
fd = (0, node_fs_1.openSync)(lockPath, "wx", 0o600);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error.code !== "EEXIST")
|
|
44
|
+
throw error;
|
|
45
|
+
if (isStale(lockPath, staleMs)) {
|
|
46
|
+
(0, node_fs_1.rmSync)(lockPath, { force: true });
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (Date.now() >= deadline) {
|
|
50
|
+
throw new errors_1.CliError("CREDENTIAL_LOCK_TIMEOUT", `Another ecomweb command is holding ${lockPath}`, errors_1.ExitCode.ERROR, {
|
|
51
|
+
hint: `If no other ecomweb command is running, delete ${lockPath}`,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
await new Promise((r) => setTimeout(r, pollMs));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
(0, node_fs_1.writeSync)(fd, `${process.pid} ${new Date().toISOString()} ${token}\n`);
|
|
59
|
+
return await fn();
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
(0, node_fs_1.closeSync)(fd);
|
|
63
|
+
release(lockPath, token);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=file-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-lock.js","sourceRoot":"","sources":["../../src/lib/file-lock.ts"],"names":[],"mappings":";;;;;AAoCA,oCA2CC;AA/ED,6CAA0C;AAC1C,qCAAoG;AACpG,0DAA6B;AAC7B,qCAA8C;AAS9C,SAAS,OAAO,CAAC,QAAgB,EAAE,OAAe;IAChD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAA,kBAAQ,EAAC,QAAQ,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAGD,SAAS,OAAO,CAAC,QAAgB,EAAE,KAAa;IAC9C,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,IAAA,sBAAY,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,IAAA,gBAAM,EAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACjE,CAAC;AAOM,KAAK,UAAU,YAAY,CAAI,QAAgB,EAAE,EAAoB,EAAE,OAAwB,EAAE;IACtG,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC;IAClC,IAAA,mBAAS,EAAC,mBAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAGpE,MAAM,KAAK,GAAG,IAAA,yBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACxC,IAAI,EAAsB,CAAC;IAC3B,OAAO,EAAE,KAAK,SAAS,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,EAAE,GAAG,IAAA,kBAAQ,EAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,KAAK,CAAC;YACpE,IAAI,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC;gBAC/B,IAAA,gBAAM,EAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAClC,SAAS;YACX,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,IAAI,iBAAQ,CAAC,yBAAyB,EAAE,sCAAsC,QAAQ,EAAE,EAAE,iBAAQ,CAAC,KAAK,EAAE;oBAC9G,IAAI,EAAE,kDAAkD,QAAQ,EAAE;iBACnE,CAAC,CAAC;YACL,CAAC;YACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,IAAA,mBAAS,EAAC,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC;QACvE,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,IAAA,mBAAS,EAAC,EAAE,CAAC,CAAC;QASd,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type SpawnLike = (command: string, args: string[], options: {
|
|
2
|
+
detached: boolean;
|
|
3
|
+
stdio: "ignore";
|
|
4
|
+
}) => {
|
|
5
|
+
on(event: "error", listener: () => void): unknown;
|
|
6
|
+
unref(): void;
|
|
7
|
+
};
|
|
8
|
+
export declare function openBrowser(url: string, deps?: {
|
|
9
|
+
platform?: NodeJS.Platform;
|
|
10
|
+
env?: NodeJS.ProcessEnv;
|
|
11
|
+
spawn?: SpawnLike;
|
|
12
|
+
}): boolean;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.openBrowser = openBrowser;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
function openBrowser(url, deps = {}) {
|
|
6
|
+
const platform = deps.platform ?? process.platform;
|
|
7
|
+
const env = deps.env ?? process.env;
|
|
8
|
+
const spawn = deps.spawn ?? node_child_process_1.spawn;
|
|
9
|
+
if (env.ECOMWEB_NO_BROWSER)
|
|
10
|
+
return false;
|
|
11
|
+
if (!/^https?:\/\//i.test(url))
|
|
12
|
+
return false;
|
|
13
|
+
if (platform === "win32" && /[&|^<>"%\s]/.test(url))
|
|
14
|
+
return false;
|
|
15
|
+
let command;
|
|
16
|
+
let args;
|
|
17
|
+
if (platform === "darwin") {
|
|
18
|
+
[command, args] = ["open", [url]];
|
|
19
|
+
}
|
|
20
|
+
else if (platform === "win32") {
|
|
21
|
+
[command, args] = ["cmd", ["/c", "start", "", url]];
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
if (!env.DISPLAY && !env.WAYLAND_DISPLAY)
|
|
25
|
+
return false;
|
|
26
|
+
[command, args] = ["xdg-open", [url]];
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const child = spawn(command, args, { detached: true, stdio: "ignore" });
|
|
30
|
+
child.on("error", () => { });
|
|
31
|
+
child.unref();
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=open-browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-browser.js","sourceRoot":"","sources":["../../src/lib/open-browser.ts"],"names":[],"mappings":";;AAaA,kCAgCC;AA7CD,2DAAwD;AAaxD,SAAgB,WAAW,CACzB,GAAW,EACX,OAAmF,EAAE;IAErF,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IACnD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAK,0BAAkC,CAAC;IAChE,IAAI,GAAG,CAAC,kBAAkB;QAAE,OAAO,KAAK,CAAC;IAIzC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,QAAQ,KAAK,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAElE,IAAI,OAAe,CAAC;IACpB,IAAI,IAAc,CAAC;IACnB,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,eAAe;YAAE,OAAO,KAAK,CAAC;QACvD,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC5B,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { PendingLogin } from "./device-login";
|
|
2
|
+
export declare const PENDING_REUSE_MARGIN_MS = 30000;
|
|
3
|
+
export declare function writePending(dir: string, profile: string, pending: PendingLogin): void;
|
|
4
|
+
export declare function deletePending(dir: string, profile: string): void;
|
|
5
|
+
export declare function readPending(dir: string, profile: string, apiUrl: string, now: number): PendingLogin | undefined;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PENDING_REUSE_MARGIN_MS = void 0;
|
|
7
|
+
exports.writePending = writePending;
|
|
8
|
+
exports.deletePending = deletePending;
|
|
9
|
+
exports.readPending = readPending;
|
|
10
|
+
const node_fs_1 = require("node:fs");
|
|
11
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const secure_file_1 = require("./secure-file");
|
|
13
|
+
exports.PENDING_REUSE_MARGIN_MS = 30_000;
|
|
14
|
+
const pendingPath = (dir, profile) => node_path_1.default.join(dir, `${profile}.pending.json`);
|
|
15
|
+
function writePending(dir, profile, pending) {
|
|
16
|
+
(0, secure_file_1.writePrivateFile)(pendingPath(dir, profile), JSON.stringify(pending));
|
|
17
|
+
}
|
|
18
|
+
function deletePending(dir, profile) {
|
|
19
|
+
(0, node_fs_1.rmSync)(pendingPath(dir, profile), { force: true });
|
|
20
|
+
}
|
|
21
|
+
function readPending(dir, profile, apiUrl, now) {
|
|
22
|
+
let pending;
|
|
23
|
+
try {
|
|
24
|
+
pending = JSON.parse((0, node_fs_1.readFileSync)(pendingPath(dir, profile), "utf8"));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
if (typeof pending?.device_code !== "string" ||
|
|
30
|
+
!Number.isFinite(pending.expires_at) ||
|
|
31
|
+
!Number.isFinite(pending.interval) ||
|
|
32
|
+
pending.api_url !== apiUrl ||
|
|
33
|
+
pending.expires_at - now < exports.PENDING_REUSE_MARGIN_MS) {
|
|
34
|
+
deletePending(dir, profile);
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
return pending;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=pending-login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pending-login.js","sourceRoot":"","sources":["../../src/lib/pending-login.ts"],"names":[],"mappings":";;;;;;AAUA,oCAEC;AAED,sCAEC;AAMD,kCAkBC;AAxCD,qCAA+C;AAC/C,0DAA6B;AAE7B,+CAAiD;AAGpC,QAAA,uBAAuB,GAAG,MAAM,CAAC;AAE9C,MAAM,WAAW,GAAG,CAAC,GAAW,EAAE,OAAe,EAAE,EAAE,CAAC,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,eAAe,CAAC,CAAC;AAEhG,SAAgB,YAAY,CAAC,GAAW,EAAE,OAAe,EAAE,OAAqB;IAC9E,IAAA,8BAAgB,EAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,SAAgB,aAAa,CAAC,GAAW,EAAE,OAAe;IACxD,IAAA,gBAAM,EAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACrD,CAAC;AAMD,SAAgB,WAAW,CAAC,GAAW,EAAE,OAAe,EAAE,MAAc,EAAE,GAAW;IACnF,IAAI,OAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IACE,OAAO,OAAO,EAAE,WAAW,KAAK,QAAQ;QACxC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC;QACpC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;QAClC,OAAO,CAAC,OAAO,KAAK,MAAM;QAC1B,OAAO,CAAC,UAAU,GAAG,GAAG,GAAG,+BAAuB,EAClD,CAAC;QACD,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC5B,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -3,6 +3,7 @@ export declare const CHILD_STDIO: StdioOptions;
|
|
|
3
3
|
export declare function projectStoreRef(dir: string): string | undefined;
|
|
4
4
|
export declare function projectStoreThemeId(dir: string): string | undefined;
|
|
5
5
|
export declare function writeProjectStoreThemeId(dir: string, id: string, storeRef?: string): void;
|
|
6
|
+
export declare function projectDirName(storeName: string | undefined, storeRef: string): string;
|
|
6
7
|
export type RunCommand = (cmd: string, args: string[], cwd: string) => {
|
|
7
8
|
status: number | null;
|
|
8
9
|
error?: Error;
|
|
@@ -7,6 +7,7 @@ exports.CHILD_STDIO = void 0;
|
|
|
7
7
|
exports.projectStoreRef = projectStoreRef;
|
|
8
8
|
exports.projectStoreThemeId = projectStoreThemeId;
|
|
9
9
|
exports.writeProjectStoreThemeId = writeProjectStoreThemeId;
|
|
10
|
+
exports.projectDirName = projectDirName;
|
|
10
11
|
exports.installDependencies = installDependencies;
|
|
11
12
|
exports.nextSteps = nextSteps;
|
|
12
13
|
exports.writeCloneDevSettings = writeCloneDevSettings;
|
|
@@ -59,6 +60,17 @@ function writeProjectStoreThemeId(dir, id, storeRef) {
|
|
|
59
60
|
const ref = typeof current.storeRef === "string" && current.storeRef ? undefined : storeRef;
|
|
60
61
|
(0, node_fs_1.writeFileSync)(file, JSON.stringify({ ...current, ...(ref && { storeRef: ref }), storeThemeId: id }, null, 2) + "\n");
|
|
61
62
|
}
|
|
63
|
+
function projectDirName(storeName, storeRef) {
|
|
64
|
+
const slug = (storeName ?? "")
|
|
65
|
+
.normalize("NFD")
|
|
66
|
+
.replace(/[\u0300-\u036f]/g, "")
|
|
67
|
+
.replace(/[đĐ]/g, "d")
|
|
68
|
+
.toLowerCase()
|
|
69
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
70
|
+
.slice(0, 36)
|
|
71
|
+
.replace(/^-+|-+$/g, "");
|
|
72
|
+
return slug ? `${slug}-${storeRef}` : `storefront-${storeRef}`;
|
|
73
|
+
}
|
|
62
74
|
const spawnRun = (cmd, args, cwd) => {
|
|
63
75
|
const r = (0, node_child_process_1.spawnSync)(cmd, args, { cwd, stdio: exports.CHILD_STDIO });
|
|
64
76
|
return { status: r.status, error: r.error };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-setup.js","sourceRoot":"","sources":["../../src/lib/project-setup.ts"],"names":[],"mappings":";;;;;;AASA,0CASC;AAMD,kDAUC;AASD,4DAiBC;AAaD,kDAGC;AAGD,8BAcC;AAOD,sDAoBC;
|
|
1
|
+
{"version":3,"file":"project-setup.js","sourceRoot":"","sources":["../../src/lib/project-setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function writePrivateFile(file: string, contents: string): void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.writePrivateFile = writePrivateFile;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
function writePrivateFile(file, contents) {
|
|
10
|
+
(0, node_fs_1.mkdirSync)(node_path_1.default.dirname(file), { recursive: true, mode: 0o700 });
|
|
11
|
+
const tmp = `${file}.${process.pid}.${Date.now()}.tmp`;
|
|
12
|
+
(0, node_fs_1.writeFileSync)(tmp, contents, { mode: 0o600 });
|
|
13
|
+
(0, node_fs_1.renameSync)(tmp, file);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=secure-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-file.js","sourceRoot":"","sources":["../../src/lib/secure-file.ts"],"names":[],"mappings":";;;;;AAQA,4CAKC;AAbD,qCAA+D;AAC/D,0DAA6B;AAO7B,SAAgB,gBAAgB,CAAC,IAAY,EAAE,QAAgB;IAC7D,IAAA,mBAAS,EAAC,mBAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAChE,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;IACvD,IAAA,uBAAa,EAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9C,IAAA,oBAAU,EAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { CredentialStore, StoredSession } from "./credential-store";
|
|
2
|
+
import { CliError } from "./errors";
|
|
3
|
+
export interface TokenResponse {
|
|
4
|
+
access_token: string;
|
|
5
|
+
refresh_token: string;
|
|
6
|
+
expires_at: number;
|
|
7
|
+
expires_in: number;
|
|
8
|
+
user: {
|
|
9
|
+
id: string;
|
|
10
|
+
email: string | null;
|
|
11
|
+
name: string | null;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export interface SessionProvider {
|
|
15
|
+
hasSession(): boolean;
|
|
16
|
+
accessToken(opts?: {
|
|
17
|
+
force?: boolean;
|
|
18
|
+
}): Promise<string>;
|
|
19
|
+
}
|
|
20
|
+
export declare const REFRESH_MARGIN_SECONDS = 60;
|
|
21
|
+
export declare function sessionFromTokens(t: TokenResponse, apiUrl: string): StoredSession;
|
|
22
|
+
export declare function assertSessionForApi(session: StoredSession, apiUrl: string): void;
|
|
23
|
+
export declare function notLoggedIn(): CliError;
|
|
24
|
+
export interface SessionManagerOptions {
|
|
25
|
+
store: CredentialStore;
|
|
26
|
+
profile: string;
|
|
27
|
+
lockPath: string;
|
|
28
|
+
apiUrl: string;
|
|
29
|
+
refresh: (refreshToken: string) => Promise<TokenResponse>;
|
|
30
|
+
now?: () => number;
|
|
31
|
+
}
|
|
32
|
+
export declare class SessionManager implements SessionProvider {
|
|
33
|
+
private readonly opts;
|
|
34
|
+
constructor(opts: SessionManagerOptions);
|
|
35
|
+
hasSession(): boolean;
|
|
36
|
+
accessToken({ force }?: {
|
|
37
|
+
force?: boolean;
|
|
38
|
+
}): Promise<string>;
|
|
39
|
+
private expiringSoon;
|
|
40
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SessionManager = exports.REFRESH_MARGIN_SECONDS = void 0;
|
|
4
|
+
exports.sessionFromTokens = sessionFromTokens;
|
|
5
|
+
exports.assertSessionForApi = assertSessionForApi;
|
|
6
|
+
exports.notLoggedIn = notLoggedIn;
|
|
7
|
+
const errors_1 = require("./errors");
|
|
8
|
+
const file_lock_1 = require("./file-lock");
|
|
9
|
+
exports.REFRESH_MARGIN_SECONDS = 60;
|
|
10
|
+
function sessionFromTokens(t, apiUrl) {
|
|
11
|
+
return {
|
|
12
|
+
access_token: t.access_token,
|
|
13
|
+
refresh_token: t.refresh_token,
|
|
14
|
+
expires_at: t.expires_at,
|
|
15
|
+
email: t.user.email,
|
|
16
|
+
user_id: t.user.id,
|
|
17
|
+
api_url: apiUrl,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function assertSessionForApi(session, apiUrl) {
|
|
21
|
+
if (session.api_url === undefined || session.api_url === apiUrl)
|
|
22
|
+
return;
|
|
23
|
+
throw new errors_1.CliError("SESSION_FOR_OTHER_API", `This profile is signed in to ${session.api_url}, but this command would talk to ${apiUrl}`, errors_1.ExitCode.AUTH_FAILURE, {
|
|
24
|
+
hint: `Use --api-url ${session.api_url} to work with that session, or run: ecomweb auth login --api-url ${apiUrl} (ideally with its own --profile) to sign in to the other API`,
|
|
25
|
+
details: { session_api_url: session.api_url, api_url: apiUrl },
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function notLoggedIn() {
|
|
29
|
+
return new errors_1.CliError("NOT_LOGGED_IN", "Not logged in", errors_1.ExitCode.AUTH_FAILURE, { hint: "Run: ecomweb auth login" });
|
|
30
|
+
}
|
|
31
|
+
function isDeadSession(error) {
|
|
32
|
+
const response = error?.response;
|
|
33
|
+
return response?.status === 401 || response?.data?.code === "AUTH_SESSION_EXPIRED";
|
|
34
|
+
}
|
|
35
|
+
class SessionManager {
|
|
36
|
+
constructor(opts) {
|
|
37
|
+
this.opts = opts;
|
|
38
|
+
}
|
|
39
|
+
hasSession() {
|
|
40
|
+
return this.opts.store.get(this.opts.profile) !== undefined;
|
|
41
|
+
}
|
|
42
|
+
async accessToken({ force = false } = {}) {
|
|
43
|
+
const seen = this.opts.store.get(this.opts.profile);
|
|
44
|
+
if (!seen)
|
|
45
|
+
throw notLoggedIn();
|
|
46
|
+
assertSessionForApi(seen, this.opts.apiUrl);
|
|
47
|
+
if (!force && !this.expiringSoon(seen))
|
|
48
|
+
return seen.access_token;
|
|
49
|
+
return (0, file_lock_1.withFileLock)(this.opts.lockPath, async () => {
|
|
50
|
+
const latest = this.opts.store.get(this.opts.profile);
|
|
51
|
+
if (!latest)
|
|
52
|
+
throw notLoggedIn();
|
|
53
|
+
assertSessionForApi(latest, this.opts.apiUrl);
|
|
54
|
+
if (latest.access_token !== seen.access_token && !this.expiringSoon(latest))
|
|
55
|
+
return latest.access_token;
|
|
56
|
+
if (!force && !this.expiringSoon(latest))
|
|
57
|
+
return latest.access_token;
|
|
58
|
+
let tokens;
|
|
59
|
+
try {
|
|
60
|
+
tokens = await this.opts.refresh(latest.refresh_token);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
if (isDeadSession(error)) {
|
|
64
|
+
this.opts.store.delete(this.opts.profile);
|
|
65
|
+
throw notLoggedIn();
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
const next = sessionFromTokens(tokens, this.opts.apiUrl);
|
|
70
|
+
this.opts.store.set(this.opts.profile, next);
|
|
71
|
+
return next.access_token;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
expiringSoon(session) {
|
|
75
|
+
const nowSeconds = (this.opts.now ?? Date.now)() / 1000;
|
|
76
|
+
return session.expires_at - exports.REFRESH_MARGIN_SECONDS <= nowSeconds;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.SessionManager = SessionManager;
|
|
80
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/lib/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface StoreSummary {
|
|
2
|
+
ref: string;
|
|
3
|
+
name: string;
|
|
4
|
+
}
|
|
5
|
+
export type StoreChoice = {
|
|
6
|
+
kind: "selected";
|
|
7
|
+
store: StoreSummary;
|
|
8
|
+
} | {
|
|
9
|
+
kind: "choose";
|
|
10
|
+
stores: StoreSummary[];
|
|
11
|
+
} | {
|
|
12
|
+
kind: "none";
|
|
13
|
+
};
|
|
14
|
+
export declare function chooseStore(opts: {
|
|
15
|
+
stores: StoreSummary[];
|
|
16
|
+
storeRef?: string;
|
|
17
|
+
currentRef?: string;
|
|
18
|
+
prompt?: (stores: StoreSummary[], currentRef?: string) => Promise<StoreSummary>;
|
|
19
|
+
}): Promise<StoreChoice>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.chooseStore = chooseStore;
|
|
4
|
+
const errors_1 = require("./errors");
|
|
5
|
+
async function chooseStore(opts) {
|
|
6
|
+
const { stores } = opts;
|
|
7
|
+
if (opts.storeRef) {
|
|
8
|
+
const store = stores.find((s) => s.ref === opts.storeRef);
|
|
9
|
+
if (!store) {
|
|
10
|
+
throw new errors_1.CliError("STORE_NOT_FOUND", `You have no store "${opts.storeRef}"`, errors_1.ExitCode.NOT_FOUND, { details: { stores } });
|
|
11
|
+
}
|
|
12
|
+
return { kind: "selected", store };
|
|
13
|
+
}
|
|
14
|
+
if (stores.length === 0)
|
|
15
|
+
return { kind: "none" };
|
|
16
|
+
if (stores.length === 1)
|
|
17
|
+
return { kind: "selected", store: stores[0] };
|
|
18
|
+
if (opts.prompt)
|
|
19
|
+
return { kind: "selected", store: await opts.prompt(stores, opts.currentRef) };
|
|
20
|
+
const current = stores.find((s) => s.ref === opts.currentRef);
|
|
21
|
+
return current ? { kind: "selected", store: current } : { kind: "choose", stores };
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=store-selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-selection.js","sourceRoot":"","sources":["../../src/lib/store-selection.ts"],"names":[],"mappings":";;AAaA,kCAoBC;AAjCD,qCAA8C;AAavC,KAAK,UAAU,WAAW,CAAC,IAMjC;IACC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACxB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1D,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,iBAAQ,CAAC,iBAAiB,EAAE,sBAAsB,IAAI,CAAC,QAAQ,GAAG,EAAE,iBAAQ,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7H,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IACrC,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACjD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;IAChG,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9D,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AACrF,CAAC"}
|