@merchbase/cli 1.0.2 → 3.0.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/CHANGELOG.md +20 -0
- package/README.md +20 -2
- package/dist/auth.d.ts +22 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +76 -0
- package/dist/auth.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +212 -94
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +6 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +52 -3
- package/dist/config.js.map +1 -1
- package/dist/help.d.ts +1 -1
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +154 -27
- package/dist/help.js.map +1 -1
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +17 -2
- package/dist/output.js.map +1 -1
- package/dist/secret-input.d.ts +3 -0
- package/dist/secret-input.d.ts.map +1 -0
- package/dist/secret-input.js +53 -0
- package/dist/secret-input.js.map +1 -0
- package/dist/secure-store.d.ts +23 -0
- package/dist/secure-store.d.ts.map +1 -0
- package/dist/secure-store.js +156 -0
- package/dist/secure-store.js.map +1 -0
- package/dist/setup-help.d.ts +1 -1
- package/dist/setup-help.d.ts.map +1 -1
- package/dist/setup-help.js +15 -35
- package/dist/setup-help.js.map +1 -1
- package/package.json +8 -7
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export const readSecretFromStdin = async () => {
|
|
2
|
+
let value = "";
|
|
3
|
+
for await (const chunk of process.stdin) {
|
|
4
|
+
value += String(chunk);
|
|
5
|
+
}
|
|
6
|
+
return value.trim();
|
|
7
|
+
};
|
|
8
|
+
export const readSecretFromPrompt = (prompt) => {
|
|
9
|
+
if (!(process.stdin.isTTY && process.stdin.setRawMode)) {
|
|
10
|
+
throw createCliError("BAD_REQUEST", "auth set needs <api-key>, --stdin, or an interactive terminal prompt.");
|
|
11
|
+
}
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const input = process.stdin;
|
|
14
|
+
const onData = (chunk) => {
|
|
15
|
+
const text = chunk.toString("utf8");
|
|
16
|
+
for (const character of text) {
|
|
17
|
+
if (character === "\u0003") {
|
|
18
|
+
cleanup();
|
|
19
|
+
process.stdout.write("\n");
|
|
20
|
+
reject(createCliError("ABORTED", "auth set was canceled."));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (character === "\r" || character === "\n") {
|
|
24
|
+
cleanup();
|
|
25
|
+
process.stdout.write("\n");
|
|
26
|
+
resolve(buffer.trim());
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (character === "\u007f") {
|
|
30
|
+
buffer = buffer.slice(0, -1);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
buffer += character;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const cleanup = () => {
|
|
37
|
+
input.off("data", onData);
|
|
38
|
+
input.setRawMode(false);
|
|
39
|
+
input.pause();
|
|
40
|
+
};
|
|
41
|
+
let buffer = "";
|
|
42
|
+
process.stdout.write(prompt);
|
|
43
|
+
input.setRawMode(true);
|
|
44
|
+
input.resume();
|
|
45
|
+
input.on("data", onData);
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
const createCliError = (code, message) => {
|
|
49
|
+
const error = new Error(message);
|
|
50
|
+
error.code = code;
|
|
51
|
+
return error;
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=secret-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-input.js","sourceRoot":"","sources":["../src/secret-input.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,IAAI,EAAE;IAC1C,IAAI,KAAK,GAAG,EAAE,CAAC;IAEf,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACtC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAc,EAAE,EAAE;IACnD,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QACrD,MAAM,cAAc,CAChB,aAAa,EACb,uEAAuE,CAC1E,CAAC;IACN,CAAC;IAED,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE;YAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAEpC,KAAK,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC;gBAC3B,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;oBACzB,OAAO,EAAE,CAAC;oBACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC3B,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,wBAAwB,CAAC,CAAC,CAAC;oBAC5D,OAAO;gBACX,CAAC;gBAED,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;oBAC3C,OAAO,EAAE,CAAC;oBACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC3B,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;oBACvB,OAAO;gBACX,CAAC;gBAED,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;oBACzB,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;oBAC7B,OAAO;gBACX,CAAC;gBAED,MAAM,IAAI,SAAS,CAAC;YACxB,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,GAAG,EAAE;YACjB,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC1B,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACxB,KAAK,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC,CAAC;QAEF,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7B,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACvB,KAAK,CAAC,MAAM,EAAE,CAAC;QACf,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,OAAe,EAAE,EAAE;IACrD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAA6B,CAAC;IAC7D,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
interface CommandResult {
|
|
2
|
+
stderr: string;
|
|
3
|
+
stdout: string;
|
|
4
|
+
}
|
|
5
|
+
type SecureStoreCommandRunner = (file: string, args: string[]) => Promise<CommandResult>;
|
|
6
|
+
export interface SecureStoreStatus {
|
|
7
|
+
account: string;
|
|
8
|
+
available: boolean;
|
|
9
|
+
configured: boolean;
|
|
10
|
+
kind: "macos-keychain" | "unsupported";
|
|
11
|
+
reason?: string;
|
|
12
|
+
service: string;
|
|
13
|
+
}
|
|
14
|
+
export interface SecureStore {
|
|
15
|
+
clearApiKey(): Promise<boolean>;
|
|
16
|
+
getStatus(): Promise<SecureStoreStatus>;
|
|
17
|
+
readApiKey(): Promise<string | null>;
|
|
18
|
+
writeApiKey(apiKey: string): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export declare const createSecureStore: (runCommand?: SecureStoreCommandRunner, platform?: NodeJS.Platform) => SecureStore;
|
|
21
|
+
export declare const secureStore: SecureStore;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=secure-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-store.d.ts","sourceRoot":"","sources":["../src/secure-store.ts"],"names":[],"mappings":"AAiBA,UAAU,aAAa;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,KAAK,wBAAwB,GAAG,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,KACb,OAAO,CAAC,aAAa,CAAC,CAAC;AAE5B,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,gBAAgB,GAAG,aAAa,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IACxB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,SAAS,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACxC,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACrC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAiJD,eAAO,MAAM,iBAAiB,GAC1B,aAAY,wBAAgD,EAC5D,0BAA2B,KAC5B,WAMF,CAAC;AAEF,eAAO,MAAM,WAAW,aAAsB,CAAC"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
const execFileAsync = promisify(execFile);
|
|
4
|
+
const KEYCHAIN_ACCOUNT = "default";
|
|
5
|
+
const KEYCHAIN_SERVICE = "merchbase-cli";
|
|
6
|
+
const MACOS_MISSING_SECRET_PATTERNS = [
|
|
7
|
+
"could not be found in the keychain",
|
|
8
|
+
"the specified item could not be found in the keychain",
|
|
9
|
+
];
|
|
10
|
+
const runSecureStoreCommand = async (file, args) => {
|
|
11
|
+
const result = await execFileAsync(file, args, {
|
|
12
|
+
encoding: "utf8",
|
|
13
|
+
});
|
|
14
|
+
return {
|
|
15
|
+
stderr: result.stderr,
|
|
16
|
+
stdout: result.stdout,
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
const createMacOsSecureStore = (runCommand) => {
|
|
20
|
+
const readApiKey = async () => {
|
|
21
|
+
try {
|
|
22
|
+
const result = await runCommand("security", [
|
|
23
|
+
"find-generic-password",
|
|
24
|
+
"-a",
|
|
25
|
+
KEYCHAIN_ACCOUNT,
|
|
26
|
+
"-s",
|
|
27
|
+
KEYCHAIN_SERVICE,
|
|
28
|
+
"-w",
|
|
29
|
+
]);
|
|
30
|
+
return toOptionalSecret(result.stdout);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (isMissingSecretError(error)) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
throw createSecureStoreError("INTERNAL_ERROR", "Failed to read MerchBase auth from macOS Keychain.");
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
return {
|
|
40
|
+
clearApiKey: async () => {
|
|
41
|
+
try {
|
|
42
|
+
await runCommand("security", [
|
|
43
|
+
"delete-generic-password",
|
|
44
|
+
"-a",
|
|
45
|
+
KEYCHAIN_ACCOUNT,
|
|
46
|
+
"-s",
|
|
47
|
+
KEYCHAIN_SERVICE,
|
|
48
|
+
]);
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (isMissingSecretError(error)) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
throw createSecureStoreError("INTERNAL_ERROR", "Failed to clear MerchBase auth from macOS Keychain.");
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
getStatus: async () => {
|
|
59
|
+
try {
|
|
60
|
+
await runCommand("security", ["list-keychains"]);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return makeStatus({
|
|
64
|
+
available: false,
|
|
65
|
+
configured: false,
|
|
66
|
+
kind: "macos-keychain",
|
|
67
|
+
reason: "macOS Keychain is unavailable from this runtime.",
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
return makeStatus({
|
|
72
|
+
available: true,
|
|
73
|
+
configured: (await readApiKey()) !== null,
|
|
74
|
+
kind: "macos-keychain",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
return makeStatus({
|
|
79
|
+
available: false,
|
|
80
|
+
configured: false,
|
|
81
|
+
kind: "macos-keychain",
|
|
82
|
+
reason: error instanceof Error
|
|
83
|
+
? error.message
|
|
84
|
+
: "macOS Keychain auth is unavailable.",
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
readApiKey,
|
|
89
|
+
writeApiKey: async (apiKey) => {
|
|
90
|
+
try {
|
|
91
|
+
await runCommand("security", [
|
|
92
|
+
"add-generic-password",
|
|
93
|
+
"-a",
|
|
94
|
+
KEYCHAIN_ACCOUNT,
|
|
95
|
+
"-s",
|
|
96
|
+
KEYCHAIN_SERVICE,
|
|
97
|
+
"-w",
|
|
98
|
+
apiKey,
|
|
99
|
+
"-U",
|
|
100
|
+
"-T",
|
|
101
|
+
"/usr/bin/security",
|
|
102
|
+
]);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
throw createSecureStoreError("INTERNAL_ERROR", "Failed to store MerchBase auth in macOS Keychain.");
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
const unsupportedSecureStore = {
|
|
111
|
+
clearApiKey: () => Promise.reject(createSecureStoreError("PRECONDITION_FAILED", "Secure auth storage is currently supported on macOS Keychain only. Export MERCHBASE_API_KEY for this runtime.")),
|
|
112
|
+
getStatus: () => Promise.resolve(makeStatus({
|
|
113
|
+
available: false,
|
|
114
|
+
configured: false,
|
|
115
|
+
kind: "unsupported",
|
|
116
|
+
reason: "Secure auth storage is currently supported on macOS Keychain only.",
|
|
117
|
+
})),
|
|
118
|
+
readApiKey: () => Promise.resolve(null),
|
|
119
|
+
writeApiKey: () => Promise.reject(createSecureStoreError("PRECONDITION_FAILED", "Secure auth storage is currently supported on macOS Keychain only. Export MERCHBASE_API_KEY for this runtime.")),
|
|
120
|
+
};
|
|
121
|
+
export const createSecureStore = (runCommand = runSecureStoreCommand, platform = process.platform) => {
|
|
122
|
+
if (platform === "darwin") {
|
|
123
|
+
return createMacOsSecureStore(runCommand);
|
|
124
|
+
}
|
|
125
|
+
return unsupportedSecureStore;
|
|
126
|
+
};
|
|
127
|
+
export const secureStore = createSecureStore();
|
|
128
|
+
const makeStatus = (status) => ({
|
|
129
|
+
account: KEYCHAIN_ACCOUNT,
|
|
130
|
+
service: KEYCHAIN_SERVICE,
|
|
131
|
+
...status,
|
|
132
|
+
});
|
|
133
|
+
const toOptionalSecret = (value) => {
|
|
134
|
+
const trimmed = value.trim();
|
|
135
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
136
|
+
};
|
|
137
|
+
const isMissingSecretError = (error) => {
|
|
138
|
+
const message = toCommandErrorMessage(error);
|
|
139
|
+
return MACOS_MISSING_SECRET_PATTERNS.some((pattern) => message.includes(pattern));
|
|
140
|
+
};
|
|
141
|
+
const toCommandErrorMessage = (error) => {
|
|
142
|
+
if (!error || typeof error !== "object") {
|
|
143
|
+
return "";
|
|
144
|
+
}
|
|
145
|
+
const commandError = error;
|
|
146
|
+
return [commandError.stderr, commandError.stdout, commandError.message]
|
|
147
|
+
.filter((value) => Boolean(value))
|
|
148
|
+
.join("\n")
|
|
149
|
+
.toLowerCase();
|
|
150
|
+
};
|
|
151
|
+
const createSecureStoreError = (code, message) => {
|
|
152
|
+
const error = new Error(message);
|
|
153
|
+
error.code = code;
|
|
154
|
+
return error;
|
|
155
|
+
};
|
|
156
|
+
//# sourceMappingURL=secure-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-store.js","sourceRoot":"","sources":["../src/secure-store.ts"],"names":[],"mappings":"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"}
|
package/dist/setup-help.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export type CliSetupHelpTarget = "global" | "merch-account-get"
|
|
1
|
+
export type CliSetupHelpTarget = "global" | "merch-account-get";
|
|
2
2
|
export declare const buildSetupHelpText: (target: CliSetupHelpTarget) => Promise<string | null>;
|
|
3
3
|
//# sourceMappingURL=setup-help.d.ts.map
|
package/dist/setup-help.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-help.d.ts","sourceRoot":"","sources":["../src/setup-help.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setup-help.d.ts","sourceRoot":"","sources":["../src/setup-help.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,mBAAmB,CAAC;AAUhE,eAAO,MAAM,kBAAkB,GAC3B,QAAQ,kBAAkB,KAC3B,OAAO,CAAC,MAAM,GAAG,IAAI,CAOvB,CAAC"}
|
package/dist/setup-help.js
CHANGED
|
@@ -1,40 +1,29 @@
|
|
|
1
1
|
import { createMerchbaseClient, } from "@merchbase/http-client";
|
|
2
|
+
import { getMissingAuthMessage, resolveAuthState } from "./auth.js";
|
|
2
3
|
import { loadConfig } from "./config.js";
|
|
3
|
-
const API_KEY_ENV_VAR = "MERCHBASE_API_KEY";
|
|
4
|
-
const ACCOUNT_SETUP_LINE = "Set the default account with `merchbase config set account <accountId> [marketplace]`.";
|
|
5
4
|
const REMOTE_STEP_KEYS_BY_TARGET = {
|
|
6
|
-
global: ["ingestion-client", "
|
|
7
|
-
"merch-account-get": ["ingestion-client", "
|
|
8
|
-
"merch-account-sync": ["ingestion-client"],
|
|
9
|
-
"products-sync": ["ingestion-client", "merch-account"],
|
|
10
|
-
"sales-sync": ["ingestion-client", "merch-account"],
|
|
11
|
-
};
|
|
12
|
-
const CLI_ACTIONS_BY_API_PATH = {
|
|
13
|
-
"api.public.merchAccount.sync": "`merchbase merch-account sync`",
|
|
5
|
+
global: ["ingestion-client", "find-account", "sync-metadata"],
|
|
6
|
+
"merch-account-get": ["ingestion-client", "find-account", "sync-metadata"],
|
|
14
7
|
};
|
|
15
8
|
export const buildSetupHelpText = async (target) => {
|
|
16
9
|
const lines = await getSetupHelpLines(target);
|
|
17
10
|
if (lines.length === 0) {
|
|
18
11
|
return null;
|
|
19
12
|
}
|
|
20
|
-
return ["
|
|
13
|
+
return ["Readiness:", ...lines.map((line) => ` ${line}`)].join("\n");
|
|
21
14
|
};
|
|
22
15
|
const getSetupHelpLines = async (target) => {
|
|
23
16
|
const config = await loadConfig();
|
|
24
|
-
const
|
|
17
|
+
const auth = await resolveAuthState();
|
|
25
18
|
const lines = [];
|
|
26
|
-
if (!apiKey) {
|
|
27
|
-
lines.push(
|
|
28
|
-
}
|
|
29
|
-
if (!config.account) {
|
|
30
|
-
lines.push(ACCOUNT_SETUP_LINE);
|
|
19
|
+
if (!auth.apiKey) {
|
|
20
|
+
lines.push(getMissingAuthMessage());
|
|
31
21
|
}
|
|
32
|
-
if (!
|
|
22
|
+
if (!auth.apiKey) {
|
|
33
23
|
return lines;
|
|
34
24
|
}
|
|
35
25
|
const setupStatus = await loadRemoteSetupStatus({
|
|
36
|
-
|
|
37
|
-
apiKey,
|
|
26
|
+
apiKey: auth.apiKey,
|
|
38
27
|
baseUrl: config.baseUrl,
|
|
39
28
|
marketplace: config.marketplace,
|
|
40
29
|
});
|
|
@@ -44,9 +33,7 @@ const getSetupHelpLines = async (target) => {
|
|
|
44
33
|
return [...lines, ...getRemoteSetupLines(target, setupStatus)];
|
|
45
34
|
};
|
|
46
35
|
const loadRemoteSetupStatus = async (input) => {
|
|
47
|
-
const headers = {
|
|
48
|
-
"x-merchbase-account": input.accountId,
|
|
49
|
-
};
|
|
36
|
+
const headers = {};
|
|
50
37
|
if (input.marketplace) {
|
|
51
38
|
headers["x-merchbase-marketplace"] = input.marketplace;
|
|
52
39
|
}
|
|
@@ -72,19 +59,12 @@ const formatRemoteSetupLine = (step) => {
|
|
|
72
59
|
if (step.key === "ingestion-client") {
|
|
73
60
|
return "Connect an ingestion client for the selected account.";
|
|
74
61
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
: null;
|
|
78
|
-
if (action) {
|
|
79
|
-
return `Run ${action}.`;
|
|
62
|
+
if (step.key === "find-account") {
|
|
63
|
+
return "Enable automatic planning; account discovery runs before merch data is available.";
|
|
80
64
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const resolveApiKey = () => {
|
|
84
|
-
const apiKey = process.env[API_KEY_ENV_VAR]?.trim();
|
|
85
|
-
if (!apiKey || apiKey === "null" || apiKey === "undefined") {
|
|
86
|
-
return undefined;
|
|
65
|
+
if (step.key === "sync-metadata") {
|
|
66
|
+
return "Enable automatic planning; account metadata sync runs before product and sales reads are complete.";
|
|
87
67
|
}
|
|
88
|
-
return
|
|
68
|
+
return step.title.endsWith(".") ? step.title : `${step.title}.`;
|
|
89
69
|
};
|
|
90
70
|
//# sourceMappingURL=setup-help.js.map
|
package/dist/setup-help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-help.js","sourceRoot":"","sources":["../src/setup-help.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,qBAAqB,GAIxB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"setup-help.js","sourceRoot":"","sources":["../src/setup-help.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@merchbase/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "MerchBase CLI for MerchBase Core APIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -22,22 +22,23 @@
|
|
|
22
22
|
"README.md"
|
|
23
23
|
],
|
|
24
24
|
"publishConfig": {
|
|
25
|
-
"access": "public"
|
|
25
|
+
"access": "public",
|
|
26
|
+
"provenance": true
|
|
26
27
|
},
|
|
27
28
|
"scripts": {
|
|
28
29
|
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
29
|
-
"dev": "tsx src/index.ts",
|
|
30
|
+
"dev": "tmp=$(mktemp) && bun run --cwd ../.. http-client:build >\"$tmp\" 2>&1 || { cat \"$tmp\" >&2; rm -f \"$tmp\"; exit 1; }; rm -f \"$tmp\" && tsx src/index.ts",
|
|
30
31
|
"prepack": "bun run --cwd ../.. http-client:build && bun run build",
|
|
31
32
|
"start": "node dist/index.js",
|
|
32
33
|
"test": "vitest run --config vitest.config.ts"
|
|
33
34
|
},
|
|
34
35
|
"dependencies": {
|
|
35
|
-
"@merchbase/http-client": "
|
|
36
|
-
"commander": "
|
|
36
|
+
"@merchbase/http-client": "3.0.0",
|
|
37
|
+
"commander": "12.1.0"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
|
-
"@types/node": "
|
|
40
|
-
"tsx": "
|
|
40
|
+
"@types/node": "24.10.13",
|
|
41
|
+
"tsx": "4.21.0"
|
|
41
42
|
},
|
|
42
43
|
"packageManager": "bun@1.1.27"
|
|
43
44
|
}
|