eprolo-cli 1.0.26 → 1.0.28
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/bin/eprolo-cli.js +244 -197
- package/package.json +1 -1
package/bin/eprolo-cli.js
CHANGED
|
@@ -2,56 +2,34 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
4
|
const fs = require("fs");
|
|
5
|
-
const http = require("http");
|
|
6
|
-
const https = require("https");
|
|
7
5
|
const os = require("os");
|
|
8
6
|
const path = require("path");
|
|
9
|
-
const
|
|
7
|
+
const https = require("https");
|
|
10
8
|
|
|
11
|
-
const
|
|
9
|
+
const VERIFY_URL = "https://wixtest.eprolo.com//v1/auth/verify-code";
|
|
12
10
|
const CONFIG_DIR = path.join(os.homedir(), ".dxb-toolkit");
|
|
13
11
|
const CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// 凭据文件读写(~/.dxb-toolkit/config.json)
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
dxb auth logout
|
|
22
|
-
dxb batch submit --store-name <storeName> --action ai_release_products --source-url-list <urls> [--pt-name <platform>] [--data-json <json>] [--task-key <key>]
|
|
23
|
-
dxb status ai --plan-id <planId> --store-name <storeName> [--user-code <userCode>]
|
|
24
|
-
|
|
25
|
-
Options:
|
|
26
|
-
--base-url <url> Override API base URL for this command.
|
|
27
|
-
--user-code <value> 店小宝用户密文 from https://erp.dianxiaobao.net/basic/account/setting.
|
|
28
|
-
--default-store-name <value>
|
|
29
|
-
Optional default authorized shop name for multi-store accounts.
|
|
30
|
-
--account <value> Optional plain account label shown in the plugin authorization card.
|
|
31
|
-
--store-name <value> Target authorized shop name for this task.
|
|
32
|
-
--pt-name <value> Optional target platform for this task, for example icbu.
|
|
33
|
-
--json Print JSON only.
|
|
34
|
-
|
|
35
|
-
Authorization onboarding:
|
|
36
|
-
1. Register or log in to 店小宝: https://erp.dianxiaobao.net/
|
|
37
|
-
2. Copy 用户密文 as userCode: https://erp.dianxiaobao.net/basic/account/setting
|
|
38
|
-
3. Save the profile:
|
|
39
|
-
dxb auth login --user-code <userCode> --default-store-name <storeName>
|
|
40
|
-
|
|
41
|
-
Task targeting:
|
|
42
|
-
店小宝 supports multiple shops. The auth profile may include a default store,
|
|
43
|
-
but an explicit --store-name always wins. Ask the user to specify the
|
|
44
|
-
authorized shop per task when the target is not clear, for example:
|
|
45
|
-
"在 33333 店铺下,用这些货源链接 AI 发品..."
|
|
46
|
-
If the user also provides a platform such as icbu, pass it with --pt-name.
|
|
47
|
-
|
|
48
|
-
Status checks:
|
|
49
|
-
Status APIs also require userCode. The CLI uses the saved auth profile, or
|
|
50
|
-
accepts --user-code for one-off checks. Always pass the same --store-name
|
|
51
|
-
used for submission.
|
|
52
|
-
`);
|
|
17
|
+
function readConfig() {
|
|
18
|
+
if (!fs.existsSync(CONFIG_FILE)) return {};
|
|
19
|
+
return JSON.parse(fs.readFileSync(CONFIG_FILE, "utf8"));
|
|
53
20
|
}
|
|
54
21
|
|
|
22
|
+
function writeConfig(config) {
|
|
23
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
24
|
+
const tmp = CONFIG_FILE + ".tmp";
|
|
25
|
+
fs.writeFileSync(tmp, JSON.stringify(config, null, 2), "utf8");
|
|
26
|
+
fs.renameSync(tmp, CONFIG_FILE);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// 参数解析
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
|
|
55
33
|
function parseArgs(argv) {
|
|
56
34
|
const args = { _: [] };
|
|
57
35
|
for (let i = 0; i < argv.length; i += 1) {
|
|
@@ -72,210 +50,279 @@ function parseArgs(argv) {
|
|
|
72
50
|
return args;
|
|
73
51
|
}
|
|
74
52
|
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
|
|
53
|
+
function readFlag(argv, flag) {
|
|
54
|
+
const idx = argv.indexOf(flag);
|
|
55
|
+
if (idx === -1 || idx + 1 >= argv.length) return undefined;
|
|
56
|
+
return argv[idx + 1];
|
|
78
57
|
}
|
|
79
58
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// HTTP POST 请求
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
84
62
|
|
|
85
|
-
function
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
63
|
+
function postJson(url, body) {
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
const target = new URL(url);
|
|
66
|
+
const payload = JSON.stringify(body);
|
|
67
|
+
const req = https.request(
|
|
68
|
+
{
|
|
69
|
+
hostname: target.hostname,
|
|
70
|
+
port: target.port || 443,
|
|
71
|
+
path: target.pathname + target.search,
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: {
|
|
74
|
+
"Content-Type": "application/json",
|
|
75
|
+
"Content-Length": Buffer.byteLength(payload)
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
(res) => {
|
|
79
|
+
const chunks = [];
|
|
80
|
+
res.on("data", (chunk) => chunks.push(chunk));
|
|
81
|
+
res.on("end", () => {
|
|
82
|
+
const text = Buffer.concat(chunks).toString("utf8");
|
|
83
|
+
let data;
|
|
84
|
+
try {
|
|
85
|
+
data = text ? JSON.parse(text) : {};
|
|
86
|
+
} catch (_) {
|
|
87
|
+
data = { raw: text };
|
|
88
|
+
}
|
|
89
|
+
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
90
|
+
const err = new Error(`HTTP ${res.statusCode}`);
|
|
91
|
+
err.response = data;
|
|
92
|
+
reject(err);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
resolve(data);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
req.on("error", reject);
|
|
100
|
+
req.write(payload);
|
|
101
|
+
req.end();
|
|
95
102
|
});
|
|
96
103
|
}
|
|
97
104
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
// 登录命令
|
|
107
|
+
// 输入:env 通道 DXB_USER_CODE + arg 通道 --default-shop
|
|
108
|
+
// 流程:调用 verify-code 接口校验密文 → 写凭据文件 → exit 0
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
|
|
111
|
+
async function login(argv) {
|
|
112
|
+
// env 通道:框架通过 fieldInjection 注入 DXB_USER_CODE
|
|
113
|
+
const userCode =
|
|
114
|
+
process.env.DXB_USER_CODE ||
|
|
115
|
+
readFlag(argv, "--user-code") ||
|
|
116
|
+
readFlag(argv, "--userCode");
|
|
117
|
+
|
|
118
|
+
if (!userCode) {
|
|
119
|
+
console.error(JSON.stringify({
|
|
120
|
+
success: false,
|
|
121
|
+
errorMessage: "缺少用户密文:请在授权弹窗中填写,或设置环境变量 DXB_USER_CODE"
|
|
122
|
+
}, null, 2));
|
|
123
|
+
process.exit(2);
|
|
124
|
+
}
|
|
103
125
|
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
126
|
+
// arg 通道:框架通过 fieldInjection 追加 --default-shop
|
|
127
|
+
const defaultShop =
|
|
128
|
+
readFlag(argv, "--default-shop") ||
|
|
129
|
+
readFlag(argv, "--default-store-name") ||
|
|
130
|
+
readFlag(argv, "--store-name") ||
|
|
131
|
+
process.env.DXB_STORE_NAME ||
|
|
132
|
+
null;
|
|
133
|
+
|
|
134
|
+
// 账号标识
|
|
135
|
+
const accountAlias =
|
|
136
|
+
readFlag(argv, "--account") ||
|
|
137
|
+
process.env.DXB_ACCOUNT ||
|
|
138
|
+
null;
|
|
139
|
+
|
|
140
|
+
// 调用 verify-code 接口校验密文
|
|
141
|
+
let verifyResult;
|
|
142
|
+
try {
|
|
143
|
+
verifyResult = await postJson(VERIFY_URL, { userCode });
|
|
144
|
+
} catch (err) {
|
|
145
|
+
console.error(JSON.stringify({
|
|
146
|
+
success: false,
|
|
147
|
+
errorMessage: "密文无效或已吊销,请到账号设置页重新复制",
|
|
148
|
+
detail: err.message,
|
|
149
|
+
response: err.response || null
|
|
150
|
+
}, null, 2));
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
110
153
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
154
|
+
// 校验成功,写凭据文件
|
|
155
|
+
const account = accountAlias || verifyResult.account || defaultShop || "unknown";
|
|
156
|
+
const config = {
|
|
157
|
+
account, // 顶层明文,框架读它做卡片标签
|
|
158
|
+
userCode,
|
|
159
|
+
accessToken: verifyResult.accessToken || null,
|
|
160
|
+
refreshToken: verifyResult.refreshToken || null,
|
|
161
|
+
defaultShop: defaultShop || verifyResult.defaultShop || null,
|
|
162
|
+
version: 1
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
writeConfig(config);
|
|
166
|
+
|
|
167
|
+
// 不打印敏感值
|
|
168
|
+
console.log(JSON.stringify({
|
|
169
|
+
success: true,
|
|
170
|
+
connected: true,
|
|
171
|
+
account: config.account,
|
|
172
|
+
defaultShop: config.defaultShop
|
|
173
|
+
}, null, 2));
|
|
174
|
+
process.exit(0);
|
|
114
175
|
}
|
|
115
176
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
// 授权状态
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
119
180
|
|
|
120
|
-
function
|
|
121
|
-
|
|
181
|
+
function authStatus() {
|
|
182
|
+
const config = readConfig();
|
|
183
|
+
const connected = fs.existsSync(CONFIG_FILE) && Boolean(config.userCode);
|
|
184
|
+
console.log(JSON.stringify({
|
|
185
|
+
connected,
|
|
186
|
+
account: config.account || null,
|
|
187
|
+
defaultShop: config.defaultShop || null
|
|
188
|
+
}, null, 2));
|
|
189
|
+
process.exit(0);
|
|
122
190
|
}
|
|
123
191
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
// 授权验证
|
|
194
|
+
// 读取凭据文件 → 调用 verify-code 接口验证密文是否仍然有效
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
127
196
|
|
|
128
|
-
async function
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
197
|
+
async function authVerify(argv) {
|
|
198
|
+
const config = readConfig();
|
|
199
|
+
|
|
200
|
+
if (!config.userCode) {
|
|
201
|
+
console.error(JSON.stringify({
|
|
202
|
+
success: false,
|
|
203
|
+
connected: false,
|
|
204
|
+
errorMessage: "未连接或凭据不存在,请先执行 auth login"
|
|
205
|
+
}, null, 2));
|
|
206
|
+
process.exit(1);
|
|
135
207
|
}
|
|
136
|
-
return { success: true, raw: body };
|
|
137
|
-
}
|
|
138
208
|
|
|
139
|
-
|
|
209
|
+
// 支持传入额外 userCode 覆盖
|
|
210
|
+
const userCode =
|
|
211
|
+
readFlag(argv, "--user-code") ||
|
|
212
|
+
process.env.DXB_USER_CODE ||
|
|
213
|
+
config.userCode;
|
|
214
|
+
|
|
140
215
|
try {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
216
|
+
const result = await postJson(VERIFY_URL, { userCode });
|
|
217
|
+
console.log(JSON.stringify({
|
|
218
|
+
success: true,
|
|
219
|
+
connected: true,
|
|
220
|
+
valid: true,
|
|
221
|
+
account: config.account,
|
|
222
|
+
accountFromServer: result.account || null,
|
|
223
|
+
defaultShop: config.defaultShop
|
|
224
|
+
}, null, 2));
|
|
225
|
+
process.exit(0);
|
|
226
|
+
} catch (err) {
|
|
227
|
+
console.error(JSON.stringify({
|
|
228
|
+
success: false,
|
|
229
|
+
connected: false,
|
|
230
|
+
valid: false,
|
|
231
|
+
errorMessage: "凭据验证失败:密文无效或已过期,请重新登录",
|
|
232
|
+
detail: err.message,
|
|
233
|
+
response: err.response || null
|
|
234
|
+
}, null, 2));
|
|
235
|
+
process.exit(1);
|
|
144
236
|
}
|
|
145
237
|
}
|
|
146
238
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
port: target.port,
|
|
156
|
-
path: `${target.pathname}${target.search}`,
|
|
157
|
-
method: "POST",
|
|
158
|
-
headers: {
|
|
159
|
-
"content-type": "application/json",
|
|
160
|
-
"content-length": Buffer.byteLength(payload)
|
|
161
|
-
}
|
|
162
|
-
}, (res) => {
|
|
163
|
-
const chunks = [];
|
|
164
|
-
res.on("data", (chunk) => chunks.push(chunk));
|
|
165
|
-
res.on("end", () => {
|
|
166
|
-
const text = Buffer.concat(chunks).toString("utf8");
|
|
167
|
-
const data = parseJsonResponse(text);
|
|
168
|
-
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
169
|
-
const err = new Error(`HTTP ${res.statusCode} ${res.statusMessage || ""}`.trim());
|
|
170
|
-
err.response = data;
|
|
171
|
-
reject(err);
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
resolve(data);
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
req.on("error", reject);
|
|
178
|
-
req.write(payload);
|
|
179
|
-
req.end();
|
|
180
|
-
});
|
|
239
|
+
// ---------------------------------------------------------------------------
|
|
240
|
+
// 退出授权
|
|
241
|
+
// ---------------------------------------------------------------------------
|
|
242
|
+
|
|
243
|
+
function authLogout() {
|
|
244
|
+
if (fs.existsSync(CONFIG_FILE)) fs.unlinkSync(CONFIG_FILE);
|
|
245
|
+
console.log(JSON.stringify({ success: true }, null, 2));
|
|
246
|
+
process.exit(0);
|
|
181
247
|
}
|
|
182
248
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
console.log(
|
|
249
|
+
// ---------------------------------------------------------------------------
|
|
250
|
+
// 帮助
|
|
251
|
+
// ---------------------------------------------------------------------------
|
|
252
|
+
|
|
253
|
+
function printHelp() {
|
|
254
|
+
console.log(`DXB CLI
|
|
255
|
+
|
|
256
|
+
Usage:
|
|
257
|
+
eprolo-cli auth login [--default-shop <shop>] [--account <alias>]
|
|
258
|
+
登录:调用 verify-code 校验密文,写凭据文件
|
|
259
|
+
eprolo-cli auth verify [--user-code <code>]
|
|
260
|
+
验证:调用 verify-code 检查密文是否仍然有效
|
|
261
|
+
eprolo-cli auth status
|
|
262
|
+
查看本地授权状态
|
|
263
|
+
eprolo-cli auth logout
|
|
264
|
+
退出授权,删除凭据文件
|
|
265
|
+
|
|
266
|
+
Authorization:
|
|
267
|
+
框架通过 fieldInjection 把表单值递交给 CLI:
|
|
268
|
+
userCode → env 通道 → process.env.DXB_USER_CODE
|
|
269
|
+
defaultShop → arg 通道 → --default-shop
|
|
270
|
+
|
|
271
|
+
连接成功的唯一判定:凭据文件 ~/.dxb-toolkit/config.json 出现
|
|
272
|
+
凭据文件顶层明文 account 字段用于授权卡片标签
|
|
273
|
+
|
|
274
|
+
Verify API:
|
|
275
|
+
POST https://wixtest.eprolo.com//v1/auth/verify-code
|
|
276
|
+
Body: { "userCode": "<用户密文>" }
|
|
277
|
+
200 ← { "account": "...", "accessToken": "...", ... }
|
|
278
|
+
401 ← { "error": "invalid_or_revoked_code" }
|
|
279
|
+
`);
|
|
189
280
|
}
|
|
190
281
|
|
|
282
|
+
// ---------------------------------------------------------------------------
|
|
283
|
+
// 入口
|
|
284
|
+
// ---------------------------------------------------------------------------
|
|
285
|
+
|
|
191
286
|
async function main() {
|
|
192
|
-
const
|
|
193
|
-
const [group, command] =
|
|
194
|
-
const baseUrl = args.baseUrl || BASE_URL;
|
|
287
|
+
const argv = process.argv.slice(2);
|
|
288
|
+
const [group, command] = argv;
|
|
195
289
|
|
|
196
|
-
if (!group ||
|
|
290
|
+
if (!group || group === "--help" || group === "-h") {
|
|
197
291
|
printHelp();
|
|
198
292
|
return;
|
|
199
293
|
}
|
|
200
294
|
|
|
201
295
|
if (group === "auth" && command === "login") {
|
|
202
|
-
|
|
203
|
-
userCode: args.userCode || args.user_code || process.env.DXB_USER_CODE || process.env.userCode || process.env.USER_CODE || "mock-user-code"
|
|
204
|
-
};
|
|
205
|
-
const defaultStoreName = args.defaultStoreName || args.default_store_name || args.storeName || process.env.DXB_DEFAULT_STORE_NAME || process.env.DXB_STORE_NAME || process.env.defaultStoreName || process.env.storeName || process.env.STORE_NAME;
|
|
206
|
-
const account = args.account || process.env.DXB_ACCOUNT || process.env.account || process.env.ACCOUNT || defaultStoreName || "mock-account";
|
|
207
|
-
if (defaultStoreName) config.defaultStoreName = defaultStoreName;
|
|
208
|
-
config.account = account;
|
|
209
|
-
writeConfig(config);
|
|
210
|
-
printResult({
|
|
211
|
-
success: true,
|
|
212
|
-
connected: true,
|
|
213
|
-
account: config.account || null,
|
|
214
|
-
defaultStoreName: config.defaultStoreName || null
|
|
215
|
-
}, args.json);
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (group === "auth" && command === "status") {
|
|
220
|
-
const config = readConfig();
|
|
221
|
-
printResult({
|
|
222
|
-
connected: true,
|
|
223
|
-
account: config.account || "mock-account",
|
|
224
|
-
defaultStoreName: config.defaultStoreName || "mock-store"
|
|
225
|
-
}, args.json);
|
|
296
|
+
await login(argv.slice(2));
|
|
226
297
|
return;
|
|
227
298
|
}
|
|
228
299
|
|
|
229
|
-
if (group === "auth" && command === "
|
|
230
|
-
|
|
231
|
-
printResult({ success: true }, args.json);
|
|
300
|
+
if (group === "auth" && command === "verify") {
|
|
301
|
+
await authVerify(argv.slice(2));
|
|
232
302
|
return;
|
|
233
303
|
}
|
|
234
304
|
|
|
235
|
-
if (group === "
|
|
236
|
-
|
|
237
|
-
// if (args.action !== "ai_release_products") {
|
|
238
|
-
// throw new Error("Only ai_release_products is supported in this simplified version.");
|
|
239
|
-
// }
|
|
240
|
-
const auth = requireAuth(args);
|
|
241
|
-
const target = requireTaskTarget(args);
|
|
242
|
-
const productIds = splitIds(args.productIds);
|
|
243
|
-
const body = {
|
|
244
|
-
action: args.action,
|
|
245
|
-
taskKey: args.taskKey || taskKey(args.action),
|
|
246
|
-
userCode: auth.userCode,
|
|
247
|
-
storeName: target.storeName,
|
|
248
|
-
productIds
|
|
249
|
-
};
|
|
250
|
-
if (target.ptName) body.ptName = target.ptName;
|
|
251
|
-
if (args.payloadJson) body.payload = JSON.parse(args.payloadJson);
|
|
252
|
-
if (args.dataJson) body.data = JSON.parse(args.dataJson);
|
|
253
|
-
if (args.sourceUrlList) body.sourceUrlList = splitIds(args.sourceUrlList);
|
|
254
|
-
printResult(await postJson(baseUrl, "/submit", body), args.json);
|
|
305
|
+
if (group === "auth" && command === "status") {
|
|
306
|
+
authStatus();
|
|
255
307
|
return;
|
|
256
308
|
}
|
|
257
309
|
|
|
258
|
-
if (group === "
|
|
259
|
-
|
|
260
|
-
const auth = requireAuth(args);
|
|
261
|
-
const target = requireTaskTarget(args);
|
|
262
|
-
printResult(await postJson(baseUrl, "/aiReleaseStatus", {
|
|
263
|
-
planId: args.planId,
|
|
264
|
-
userCode: auth.userCode,
|
|
265
|
-
storeName: target.storeName
|
|
266
|
-
}), args.json);
|
|
310
|
+
if (group === "auth" && command === "logout") {
|
|
311
|
+
authLogout();
|
|
267
312
|
return;
|
|
268
313
|
}
|
|
269
314
|
|
|
270
|
-
|
|
315
|
+
console.error(JSON.stringify({
|
|
316
|
+
success: false,
|
|
317
|
+
errorMessage: `Unknown command: ${argv.join(" ")}`
|
|
318
|
+
}, null, 2));
|
|
319
|
+
process.exit(1);
|
|
271
320
|
}
|
|
272
321
|
|
|
273
322
|
main().catch((err) => {
|
|
274
323
|
console.error(JSON.stringify({
|
|
275
324
|
success: false,
|
|
276
|
-
errorMessage: err.message
|
|
277
|
-
response: err.response || null
|
|
325
|
+
errorMessage: err.message
|
|
278
326
|
}, null, 2));
|
|
279
327
|
process.exit(1);
|
|
280
328
|
});
|
|
281
|
-
|
package/package.json
CHANGED