@my-life-buddies/cli 0.25.2 → 0.26.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 +44 -5
- package/dist/bin/core.js +596 -188
- package/dist/bin/core.js.map +4 -4
- package/dist/bin/preview.js +65 -5
- package/dist/bin/preview.js.map +2 -2
- package/dist/web/app.js +7 -4
- package/dist/web/index.html +2 -0
- package/dist/web/products.css +19 -0
- package/dist/web/products.js +104 -0
- package/package.json +3 -3
package/dist/bin/core.js
CHANGED
|
@@ -268,8 +268,8 @@ async function cached(definition3, root, lock) {
|
|
|
268
268
|
}
|
|
269
269
|
const skill = join2(root, "node_modules", definition3.name);
|
|
270
270
|
try {
|
|
271
|
-
const
|
|
272
|
-
const entry2 =
|
|
271
|
+
const record3 = JSON.parse(await readFile3(join2(root, "package-lock.json"), "utf8"));
|
|
272
|
+
const entry2 = record3.packages?.[`node_modules/${definition3.name}`];
|
|
273
273
|
if (entry2?.version !== lock.version || entry2.integrity !== lock.integrity) throw new Error("\u7F13\u5B58\u6821\u9A8C\u8BB0\u5F55\u4E0D\u5339\u914D");
|
|
274
274
|
await installed(definition3, skill, lock.version);
|
|
275
275
|
return skill;
|
|
@@ -1398,7 +1398,7 @@ async function latestRuntimeTemplate(template, options) {
|
|
|
1398
1398
|
"--prefer-online",
|
|
1399
1399
|
"--fetch-retries=0",
|
|
1400
1400
|
"--fetch-timeout=20000"
|
|
1401
|
-
], { cwd: temporaryRoot, signal: options.signal, timeout:
|
|
1401
|
+
], { cwd: temporaryRoot, signal: options.signal, timeout: 18e4 });
|
|
1402
1402
|
const result = {
|
|
1403
1403
|
packageJson: await readFile9(join8(temporaryRoot, "package.json"), "utf8"),
|
|
1404
1404
|
packageLock: await readFile9(join8(temporaryRoot, "package-lock.json"), "utf8")
|
|
@@ -1414,7 +1414,8 @@ async function latestRuntimeTemplate(template, options) {
|
|
|
1414
1414
|
return result;
|
|
1415
1415
|
} catch (cause) {
|
|
1416
1416
|
if (options.signal?.aborted) throw new Error("Runtime \u7248\u672C\u9009\u62E9\u5DF2\u53D6\u6D88");
|
|
1417
|
-
const
|
|
1417
|
+
const interrupted = cause instanceof Error && (cause.code === "ETIMEDOUT" || cause.killed);
|
|
1418
|
+
const reason = interrupted ? "\u4F9D\u8D56\u9501\u6587\u4EF6\u751F\u6210\u8D85\u65F6\u6216\u88AB\u4E2D\u65AD\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5" : cause instanceof Error && !cause.message.includes("Command failed") ? cause.message : "npm \u672A\u5B8C\u6210\u9501\u6587\u4EF6\u751F\u6210";
|
|
1418
1419
|
throw new Error(`\u672A\u80FD\u9501\u5B9A\u6700\u65B0\u6B63\u5F0F\u7248 Runtime\uFF1A${reason}\u3002\u5DF2\u505C\u6B62\u751F\u6210\u5DE5\u7A0B\u4F9D\u8D56\uFF0C\u8BF7\u4FEE\u590D\u540E\u91CD\u8BD5\uFF1B\u4E0D\u4F1A\u4F7F\u7528\u9884\u7F6E\u6216\u7F13\u5B58\u7684\u65E7\u7248\u672C\u3002`, { cause });
|
|
1419
1420
|
} finally {
|
|
1420
1421
|
if (temporaryRoot) await rm3(temporaryRoot, { recursive: true, force: true });
|
|
@@ -1664,8 +1665,8 @@ async function selectInitModel(root, requested, io, options = {}) {
|
|
|
1664
1665
|
throw new ModelSelectionError(`\u65E0\u6CD5\u786E\u8BA4\u6A21\u578B\uFF1A${cause instanceof Error ? cause.message : String(cause)}\u3002\u8BF7\u4FEE\u590D\u540E\u91CD\u8BD5\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u9009\u62E9\u9ED8\u8BA4\u6A21\u578B\u3002`);
|
|
1665
1666
|
}
|
|
1666
1667
|
}
|
|
1667
|
-
function checkModelTemplate(template,
|
|
1668
|
-
if (
|
|
1668
|
+
function checkModelTemplate(template, selection2) {
|
|
1669
|
+
if (selection2 && runtimeDependencyVersion(JSON.parse(template.packageJson)) !== selection2.runtimeVersion) {
|
|
1669
1670
|
throw new ModelSelectionError("Runtime \u7248\u672C\u5728\u9009\u62E9\u6A21\u578B\u540E\u53D1\u751F\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C init \u786E\u8BA4\u8BE5\u7248\u672C\u7684\u6A21\u578B\u3002");
|
|
1670
1671
|
}
|
|
1671
1672
|
return template;
|
|
@@ -2479,7 +2480,7 @@ ${KNOWLEDGE_HELP}`);
|
|
|
2479
2480
|
}
|
|
2480
2481
|
|
|
2481
2482
|
// packages/cli-core/src/index.ts
|
|
2482
|
-
import { join as
|
|
2483
|
+
import { join as join24, resolve as resolve19 } from "node:path";
|
|
2483
2484
|
|
|
2484
2485
|
// packages/cli-core/src/init/creator.ts
|
|
2485
2486
|
import { createHash as createHash3, randomUUID as randomUUID7 } from "node:crypto";
|
|
@@ -3148,10 +3149,10 @@ function browserCommand(url) {
|
|
|
3148
3149
|
}
|
|
3149
3150
|
async function openExternalUrl(url) {
|
|
3150
3151
|
const launch = browserCommand(url);
|
|
3151
|
-
await new Promise((
|
|
3152
|
+
await new Promise((resolve20, reject) => {
|
|
3152
3153
|
const child = spawn(launch.command, launch.args, { shell: false, stdio: "ignore", windowsHide: true });
|
|
3153
3154
|
child.once("error", reject);
|
|
3154
|
-
child.once("exit", (code2) => code2 === 0 ?
|
|
3155
|
+
child.once("exit", (code2) => code2 === 0 ? resolve20() : reject(new Error(`browser launcher exited with ${code2 ?? "unknown"}`)));
|
|
3155
3156
|
});
|
|
3156
3157
|
}
|
|
3157
3158
|
async function write(res, status, title, message, webUrl, tone = "error") {
|
|
@@ -3163,10 +3164,10 @@ async function write(res, status, title, message, webUrl, tone = "error") {
|
|
|
3163
3164
|
"referrer-policy": "no-referrer",
|
|
3164
3165
|
"x-content-type-options": "nosniff"
|
|
3165
3166
|
});
|
|
3166
|
-
await new Promise((
|
|
3167
|
+
await new Promise((resolve20, reject) => {
|
|
3167
3168
|
res.once("error", reject);
|
|
3168
|
-
res.once("close",
|
|
3169
|
-
res.end(renderLoginResult(title, message, webUrl, tone),
|
|
3169
|
+
res.once("close", resolve20);
|
|
3170
|
+
res.end(renderLoginResult(title, message, webUrl, tone), resolve20);
|
|
3170
3171
|
});
|
|
3171
3172
|
}
|
|
3172
3173
|
async function readJson(response) {
|
|
@@ -3202,11 +3203,11 @@ var LoopbackBrowserLoginAdapter = class {
|
|
|
3202
3203
|
let settle;
|
|
3203
3204
|
let reject;
|
|
3204
3205
|
let settled = false;
|
|
3205
|
-
const result = new Promise((
|
|
3206
|
+
const result = new Promise((resolve20, rejectResult) => {
|
|
3206
3207
|
settle = (value) => {
|
|
3207
3208
|
if (!settled) {
|
|
3208
3209
|
settled = true;
|
|
3209
|
-
|
|
3210
|
+
resolve20(value);
|
|
3210
3211
|
}
|
|
3211
3212
|
};
|
|
3212
3213
|
reject = (reason) => {
|
|
@@ -3225,9 +3226,9 @@ var LoopbackBrowserLoginAdapter = class {
|
|
|
3225
3226
|
state: request.state
|
|
3226
3227
|
}).then(settle, reject);
|
|
3227
3228
|
});
|
|
3228
|
-
await new Promise((
|
|
3229
|
+
await new Promise((resolve20, rejectListen) => {
|
|
3229
3230
|
server.once("error", rejectListen);
|
|
3230
|
-
server.listen(0, "127.0.0.1", () =>
|
|
3231
|
+
server.listen(0, "127.0.0.1", () => resolve20());
|
|
3231
3232
|
});
|
|
3232
3233
|
const address = server.address();
|
|
3233
3234
|
if (!address || typeof address === "string") {
|
|
@@ -3260,8 +3261,8 @@ var LoopbackBrowserLoginAdapter = class {
|
|
|
3260
3261
|
} finally {
|
|
3261
3262
|
clearTimeout(timer);
|
|
3262
3263
|
request.signal?.removeEventListener("abort", abort);
|
|
3263
|
-
await new Promise((
|
|
3264
|
-
server.close(() =>
|
|
3264
|
+
await new Promise((resolve20) => {
|
|
3265
|
+
server.close(() => resolve20());
|
|
3265
3266
|
server.closeIdleConnections();
|
|
3266
3267
|
server.closeAllConnections();
|
|
3267
3268
|
});
|
|
@@ -3345,7 +3346,9 @@ var CLI_HELP = `\u642D\u642D Developer Platform CLI
|
|
|
3345
3346
|
knowledge \u5C06\u521B\u4F5C\u8D44\u6599\u540C\u6B65\u4E3A\u672C\u5730\u8FD0\u884C\u77E5\u8BC6
|
|
3346
3347
|
dev \u5728\u7EC8\u7AEF\u542F\u52A8\u5F00\u53D1\u7248\u642D\u5B50\uFF1Bdev stop \u505C\u6B62\u672C\u673A DEV
|
|
3347
3348
|
preview \u8FDE\u63A5\u5DE5\u7A0B\u5E76\u6253\u5F00\u540E\u53F0\u5F00\u53D1\u8C03\u8BD5
|
|
3348
|
-
push \u4E0A\u4F20\u7A0B\u5E8F\u5305\
|
|
3349
|
+
push \u4E0A\u4F20\u7A0B\u5E8F\u5305\uFF0C\u53EF\u7528 --product \u540C\u6B65\u63D0\u4EA4\u5546\u54C1\u5BA1\u6838
|
|
3350
|
+
products \u4E3A\u5DF2\u6709\u7248\u672C\u8865\u63D0\u5546\u54C1\uFF0C\u6216\u6062\u590D\u539F\u63D0\u5BA1\u8BF7\u6C42
|
|
3351
|
+
release \u4ECE\u660E\u786E\u56DE\u6267\u53D1\u5E03\uFF0C\u67E5\u8BE2\u3001\u6062\u590D\u3001\u91CD\u8BD5\u6216\u53D6\u6D88\u53D1\u5E03
|
|
3349
3352
|
status \u67E5\u770B\u4E91\u7AEF\u7248\u672C\u3001\u8FD0\u884C\u3001\u5BA1\u6838\u548C\u6784\u5EFA\u72B6\u6001
|
|
3350
3353
|
meta \u67E5\u770B\u4E91\u7AEF\u8D44\u6599\uFF1Bmeta update \u4FEE\u6539\u8D44\u6599\u6216\u66FF\u6362\u5934\u50CF
|
|
3351
3354
|
avatar \u65E7\u5934\u50CF\u547D\u4EE4\u517C\u5BB9\u5165\u53E3\uFF0C\u63A8\u8350 meta update --avatar
|
|
@@ -3491,16 +3494,16 @@ var NodeAgentProcessLauncher = class {
|
|
|
3491
3494
|
}
|
|
3492
3495
|
let hasExited = false;
|
|
3493
3496
|
let spawned = false;
|
|
3494
|
-
const exit = new Promise((
|
|
3497
|
+
const exit = new Promise((resolve20) => {
|
|
3495
3498
|
child.once("error", (error2) => {
|
|
3496
3499
|
if (!spawned) {
|
|
3497
3500
|
hasExited = true;
|
|
3498
|
-
|
|
3501
|
+
resolve20({ code: null, signal: null, error: error2 });
|
|
3499
3502
|
}
|
|
3500
3503
|
});
|
|
3501
3504
|
child.once("exit", (code2, signal) => {
|
|
3502
3505
|
hasExited = true;
|
|
3503
|
-
|
|
3506
|
+
resolve20({ code: code2, signal });
|
|
3504
3507
|
});
|
|
3505
3508
|
});
|
|
3506
3509
|
child.stdout?.setEncoding("utf8");
|
|
@@ -3518,11 +3521,11 @@ var NodeAgentProcessLauncher = class {
|
|
|
3518
3521
|
}
|
|
3519
3522
|
});
|
|
3520
3523
|
try {
|
|
3521
|
-
await new Promise((
|
|
3524
|
+
await new Promise((resolve20, reject) => {
|
|
3522
3525
|
const onSpawn = () => {
|
|
3523
3526
|
spawned = true;
|
|
3524
3527
|
child.off("error", onError);
|
|
3525
|
-
|
|
3528
|
+
resolve20();
|
|
3526
3529
|
};
|
|
3527
3530
|
const onError = (error2) => {
|
|
3528
3531
|
child.off("spawn", onSpawn);
|
|
@@ -3561,11 +3564,11 @@ var NodeAgentProcessLauncher = class {
|
|
|
3561
3564
|
};
|
|
3562
3565
|
function waitForExit(process2, timeoutMs) {
|
|
3563
3566
|
if (process2.hasExited()) return Promise.resolve(true);
|
|
3564
|
-
return new Promise((
|
|
3565
|
-
const timeout = setTimeout(() =>
|
|
3567
|
+
return new Promise((resolve20) => {
|
|
3568
|
+
const timeout = setTimeout(() => resolve20(false), timeoutMs);
|
|
3566
3569
|
process2.exit.then(() => {
|
|
3567
3570
|
clearTimeout(timeout);
|
|
3568
|
-
|
|
3571
|
+
resolve20(true);
|
|
3569
3572
|
});
|
|
3570
3573
|
});
|
|
3571
3574
|
}
|
|
@@ -3648,7 +3651,7 @@ async function waitForGroupExit(pid, isGroupAlive, timeoutMs) {
|
|
|
3648
3651
|
while (isGroupAlive(pid)) {
|
|
3649
3652
|
const remaining = deadline - Date.now();
|
|
3650
3653
|
if (remaining <= 0) return false;
|
|
3651
|
-
await new Promise((
|
|
3654
|
+
await new Promise((resolve20) => setTimeout(resolve20, Math.min(25, remaining)));
|
|
3652
3655
|
}
|
|
3653
3656
|
return true;
|
|
3654
3657
|
}
|
|
@@ -3703,11 +3706,11 @@ async function acquireDevInstanceLock(options) {
|
|
|
3703
3706
|
}
|
|
3704
3707
|
}) : void 0;
|
|
3705
3708
|
try {
|
|
3706
|
-
if (server) await new Promise((
|
|
3709
|
+
if (server) await new Promise((resolve20, reject) => {
|
|
3707
3710
|
server.once("error", reject);
|
|
3708
3711
|
server.listen(0, "127.0.0.1", () => {
|
|
3709
3712
|
server.off("error", reject);
|
|
3710
|
-
|
|
3713
|
+
resolve20();
|
|
3711
3714
|
});
|
|
3712
3715
|
});
|
|
3713
3716
|
const address = server?.address();
|
|
@@ -4437,25 +4440,25 @@ import { join as join18 } from "node:path";
|
|
|
4437
4440
|
var DATA_ACCESS_FILENAME = "data-access.json";
|
|
4438
4441
|
function parseDataAccessRequirements(source) {
|
|
4439
4442
|
if (source === void 0) return [];
|
|
4440
|
-
const
|
|
4443
|
+
const invalid4 = (reason) => {
|
|
4441
4444
|
throw new Error(`${DATA_ACCESS_FILENAME}\uFF1A${reason}`);
|
|
4442
4445
|
};
|
|
4443
4446
|
let value;
|
|
4444
4447
|
try {
|
|
4445
4448
|
value = JSON.parse(source);
|
|
4446
4449
|
} catch {
|
|
4447
|
-
return
|
|
4450
|
+
return invalid4("\u4E0D\u662F\u6709\u6548 JSON");
|
|
4448
4451
|
}
|
|
4449
4452
|
if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).some((key) => key !== "requirements") || !Array.isArray(value.requirements) || value.requirements.length > 32) {
|
|
4450
|
-
return
|
|
4453
|
+
return invalid4("\u5FC5\u987B\u662F\u4EC5\u5305\u542B requirements \u6570\u7EC4\u7684\u5BF9\u8C61\uFF0C\u6700\u591A\u58F0\u660E 32 \u9879");
|
|
4451
4454
|
}
|
|
4452
4455
|
const seen = /* @__PURE__ */ new Set();
|
|
4453
4456
|
return value.requirements.map((item, index) => {
|
|
4454
4457
|
if (!item || typeof item !== "object" || Array.isArray(item) || Object.keys(item).some((key) => key !== "id" && key !== "purpose") || !("id" in item) || typeof item.id !== "string" || !item.id.trim() || !("purpose" in item) || typeof item.purpose !== "string" || !item.purpose.trim() || item.purpose.trim().length > 200) {
|
|
4455
|
-
return
|
|
4458
|
+
return invalid4(`requirements[${index}] \u5FC5\u987B\u5305\u542B\u975E\u7A7A id \u548C 1\u2013200 \u5B57\u7684 purpose`);
|
|
4456
4459
|
}
|
|
4457
4460
|
const id = item.id.trim(), purpose = item.purpose.trim();
|
|
4458
|
-
if (seen.has(id)) return
|
|
4461
|
+
if (seen.has(id)) return invalid4(`\u6570\u636E\u96C6\u4E0D\u80FD\u91CD\u590D\u58F0\u660E\uFF1A${id}`);
|
|
4459
4462
|
seen.add(id);
|
|
4460
4463
|
return { id, purpose };
|
|
4461
4464
|
});
|
|
@@ -4987,18 +4990,18 @@ function parse(source) {
|
|
|
4987
4990
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
4988
4991
|
throw new CloudLifecycleError("AUTH_CREDENTIAL_CORRUPT", "\u7CFB\u7EDF\u51ED\u636E\u683C\u5F0F\u65E0\u6548");
|
|
4989
4992
|
}
|
|
4990
|
-
const
|
|
4991
|
-
if (Object.keys(
|
|
4993
|
+
const record3 = value;
|
|
4994
|
+
if (Object.keys(record3).length !== 3 || typeof record3.accessToken !== "string" || typeof record3.subject !== "string" || !Number.isSafeInteger(record3.expiresAt)) {
|
|
4992
4995
|
throw new CloudLifecycleError("AUTH_CREDENTIAL_CORRUPT", "\u7CFB\u7EDF\u51ED\u636E\u683C\u5F0F\u65E0\u6548");
|
|
4993
4996
|
}
|
|
4994
4997
|
return Object.freeze({
|
|
4995
|
-
accessToken:
|
|
4996
|
-
subject:
|
|
4997
|
-
expiresAt:
|
|
4998
|
+
accessToken: record3.accessToken,
|
|
4999
|
+
subject: record3.subject,
|
|
5000
|
+
expiresAt: record3.expiresAt
|
|
4998
5001
|
});
|
|
4999
5002
|
}
|
|
5000
5003
|
async function runCredentialCommand(input) {
|
|
5001
|
-
return await new Promise((
|
|
5004
|
+
return await new Promise((resolve20, reject) => {
|
|
5002
5005
|
const child = spawn2(input.command, [...input.args], {
|
|
5003
5006
|
shell: false,
|
|
5004
5007
|
windowsHide: true,
|
|
@@ -5014,7 +5017,7 @@ async function runCredentialCommand(input) {
|
|
|
5014
5017
|
child.stdout.on("data", (chunk) => collect(stdout, chunk));
|
|
5015
5018
|
child.stderr.on("data", (chunk) => collect(stderr, chunk));
|
|
5016
5019
|
child.once("error", reject);
|
|
5017
|
-
child.once("close", (code2) =>
|
|
5020
|
+
child.once("close", (code2) => resolve20({
|
|
5018
5021
|
code: code2 ?? 1,
|
|
5019
5022
|
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
5020
5023
|
stderr: Buffer.concat(stderr).toString("utf8")
|
|
@@ -5303,9 +5306,424 @@ async function runDevCommand(args, io, options = {}) {
|
|
|
5303
5306
|
}
|
|
5304
5307
|
}
|
|
5305
5308
|
|
|
5306
|
-
// packages/cli-core/src/commands/cloud.ts
|
|
5309
|
+
// packages/cli-core/src/commands/cloud-errors.ts
|
|
5310
|
+
var CloudCommandUsageError = class extends Error {
|
|
5311
|
+
constructor(message) {
|
|
5312
|
+
super(message);
|
|
5313
|
+
this.name = "CloudCommandUsageError";
|
|
5314
|
+
}
|
|
5315
|
+
};
|
|
5316
|
+
|
|
5317
|
+
// packages/cli-core/src/commands/product-lifecycle.ts
|
|
5318
|
+
import { createHash as createHash10, randomUUID as randomUUID9 } from "node:crypto";
|
|
5319
|
+
import { resolve as resolve15 } from "node:path";
|
|
5307
5320
|
import { setTimeout as delay3 } from "node:timers/promises";
|
|
5308
5321
|
|
|
5322
|
+
// packages/cli-core/src/cloud/product-protocol.ts
|
|
5323
|
+
function invalid2(message) {
|
|
5324
|
+
throw new CloudLifecycleError("PLATFORM_RESPONSE_INVALID", message);
|
|
5325
|
+
}
|
|
5326
|
+
function record(value) {
|
|
5327
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) invalid2("\u64CD\u4F5C\u56DE\u6267\u5FC5\u987B\u4E3A\u5BF9\u8C61");
|
|
5328
|
+
return value;
|
|
5329
|
+
}
|
|
5330
|
+
function isProductId(value) {
|
|
5331
|
+
return typeof value === "string" && /^(?:prd_[0-9]{8}|ps_[A-Za-z0-9_-]{1,61})$/u.exec(value)?.[0] === value;
|
|
5332
|
+
}
|
|
5333
|
+
function operationId(value) {
|
|
5334
|
+
if (typeof value !== "string" || !/^[A-Za-z0-9_-]{1,128}$/.test(value)) invalid2("\u64CD\u4F5C\u56DE\u6267\u6807\u8BC6\u65E0\u6548");
|
|
5335
|
+
return value;
|
|
5336
|
+
}
|
|
5337
|
+
function selectedReviewIds(value) {
|
|
5338
|
+
if (!Array.isArray(value) || value.length > 10 || value.some((id) => typeof id !== "string" || !/^pr_[A-Za-z0-9_-]{1,61}$/.test(id)) || new Set(value).size !== value.length) invalid2("\u5546\u54C1\u5BA1\u6838\u56DE\u6267\u96C6\u5408\u65E0\u6548");
|
|
5339
|
+
return value;
|
|
5340
|
+
}
|
|
5341
|
+
function parsePushMetadata(value) {
|
|
5342
|
+
const m = record(value);
|
|
5343
|
+
if (typeof m.commit !== "string" || !m.commit.trim() || m.commit.length > 2e3 || /[\u0000-\u001f\u007f]/u.test(m.commit) || typeof m.sourceSha256 !== "string" || !/^[a-f0-9]{64}$/.test(m.sourceSha256) || !Array.isArray(m.productReviews) || m.productReviews.length > 10) invalid2("\u4E0A\u4F20\u5143\u6570\u636E\u56DE\u6267\u65E0\u6548");
|
|
5344
|
+
const productReviews = m.productReviews.map((value2) => {
|
|
5345
|
+
const r = record(value2);
|
|
5346
|
+
if (!isProductId(r.productId) || !Number.isSafeInteger(r.expectedDraftVersion) || Number(r.expectedDraftVersion) < 1) invalid2("\u5546\u54C1\u8349\u7A3F\u7248\u672C\u56DE\u6267\u65E0\u6548");
|
|
5347
|
+
return { productId: r.productId, reviewId: selectedReviewIds([r.reviewId])[0], expectedDraftVersion: Number(r.expectedDraftVersion) };
|
|
5348
|
+
});
|
|
5349
|
+
if (new Set(productReviews.map((r) => r.productId)).size !== productReviews.length || new Set(productReviews.map((r) => r.reviewId)).size !== productReviews.length) invalid2("\u56DE\u6267\u5305\u542B\u91CD\u590D\u5546\u54C1\u6216\u5BA1\u6838 ID");
|
|
5350
|
+
return { pushId: operationId(m.pushId), commit: m.commit, sourceSha256: m.sourceSha256, productReviews };
|
|
5351
|
+
}
|
|
5352
|
+
function parsePackagePush(value) {
|
|
5353
|
+
const p = record(value);
|
|
5354
|
+
const metadata = parsePushMetadata(p.metadata);
|
|
5355
|
+
if (!["receiving", "stored", "completed", "product_reviews_failed", "failed"].includes(String(p.status))) invalid2("\u4E0A\u4F20\u64CD\u4F5C\u72B6\u6001\u65E0\u6548");
|
|
5356
|
+
if (p.uploadVersion !== null && (typeof p.uploadVersion !== "string" || !p.uploadVersion.trim() || /[\u0000-\u001f\u007f]/u.test(p.uploadVersion))) invalid2("\u4E0A\u4F20\u7248\u672C\u56DE\u6267\u65E0\u6548");
|
|
5357
|
+
if (operationId(p.pushId) !== metadata.pushId) invalid2("\u4E0A\u4F20\u56DE\u6267 ID \u4E0E\u5143\u6570\u636E\u4E0D\u5339\u914D");
|
|
5358
|
+
return { pushId: metadata.pushId, uploadVersion: p.uploadVersion, status: p.status, metadata, reviewIds: selectedReviewIds(p.reviewIds), failure: p.failure ?? null };
|
|
5359
|
+
}
|
|
5360
|
+
function parseProductRelease(value) {
|
|
5361
|
+
const r = record(value);
|
|
5362
|
+
if (r.mode !== "with_buddy" && r.mode !== "products_only") invalid2("\u53D1\u5E03\u6A21\u5F0F\u65E0\u6548");
|
|
5363
|
+
if (!["accepted", "activating", "active", "failed", "cancelled"].includes(String(r.status))) invalid2("\u53D1\u5E03\u64CD\u4F5C\u72B6\u6001\u65E0\u6548");
|
|
5364
|
+
if (typeof r.buddyVersion !== "string" || !r.buddyVersion.trim() || /[\u0000-\u001f\u007f]/u.test(r.buddyVersion)) invalid2("\u53D1\u5E03\u7248\u672C\u65E0\u6548");
|
|
5365
|
+
return { releaseId: operationId(r.releaseId), mode: r.mode, buddyVersion: r.buddyVersion, reviewIds: selectedReviewIds(r.reviewIds), status: r.status, ...r.failure === void 0 ? {} : { failure: r.failure } };
|
|
5366
|
+
}
|
|
5367
|
+
var CloudOperationError = class extends CloudLifecycleError {
|
|
5368
|
+
constructor(code2, message, details, push, release) {
|
|
5369
|
+
super(code2, message, details);
|
|
5370
|
+
this.push = push;
|
|
5371
|
+
this.release = release;
|
|
5372
|
+
}
|
|
5373
|
+
push;
|
|
5374
|
+
release;
|
|
5375
|
+
};
|
|
5376
|
+
function sameReviewIds(a, b) {
|
|
5377
|
+
return [...a].sort().join("\0") === [...b].sort().join("\0");
|
|
5378
|
+
}
|
|
5379
|
+
function samePushMetadata(a, b) {
|
|
5380
|
+
return a.pushId === b.pushId && a.commit === b.commit && a.sourceSha256 === b.sourceSha256 && JSON.stringify([...a.productReviews].sort((x, y) => x.productId.localeCompare(y.productId))) === JSON.stringify([...b.productReviews].sort((x, y) => x.productId.localeCompare(y.productId)));
|
|
5381
|
+
}
|
|
5382
|
+
|
|
5383
|
+
// packages/cli-core/src/cloud/operation-store.ts
|
|
5384
|
+
import { createHash as createHash9, randomUUID as randomUUID8 } from "node:crypto";
|
|
5385
|
+
import { mkdir as mkdir9, readFile as readFile19, rename as rename10, writeFile as writeFile8, chmod } from "node:fs/promises";
|
|
5386
|
+
import { homedir as homedir4 } from "node:os";
|
|
5387
|
+
import { join as join20 } from "node:path";
|
|
5388
|
+
var OperationStore = class {
|
|
5389
|
+
constructor(identity, base = join20(homedir4(), ".cache", "buddy-cli", "operations")) {
|
|
5390
|
+
this.identity = identity;
|
|
5391
|
+
this.directory = join20(base, createHash9("sha256").update(JSON.stringify(identity)).digest("hex"));
|
|
5392
|
+
}
|
|
5393
|
+
identity;
|
|
5394
|
+
directory;
|
|
5395
|
+
async ready() {
|
|
5396
|
+
await mkdir9(this.directory, { recursive: true, mode: 448 });
|
|
5397
|
+
await chmod(this.directory, 448);
|
|
5398
|
+
}
|
|
5399
|
+
path(id, suffix = "json") {
|
|
5400
|
+
return join20(this.directory, `${operationId(id)}.${suffix}`);
|
|
5401
|
+
}
|
|
5402
|
+
async create(record3, bytes) {
|
|
5403
|
+
await this.ready();
|
|
5404
|
+
if (record3.kind === "push") {
|
|
5405
|
+
if (!bytes || createHash9("sha256").update(bytes).digest("hex") !== record3.metadata.sourceSha256) throw new CloudLifecycleError("INVALID_REQUEST", "\u4FDD\u5B58\u4E0A\u4F20\u8BB0\u5F55\u65F6\u5305\u5185\u5BB9\u6821\u9A8C\u5931\u8D25");
|
|
5406
|
+
await writeFile8(this.path(record3.id, "tar.gz"), bytes, { flag: "wx", mode: 384 });
|
|
5407
|
+
}
|
|
5408
|
+
await writeFile8(this.path(record3.id), JSON.stringify({ identity: this.identity, operation: record3 }), { flag: "wx", mode: 384 });
|
|
5409
|
+
}
|
|
5410
|
+
async save(record3) {
|
|
5411
|
+
const prior = await this.read(record3.id, record3.kind);
|
|
5412
|
+
const input = (r) => r.kind === "push" ? r.metadata : r.kind === "release" ? r.request : { version: r.version, reviews: r.reviews };
|
|
5413
|
+
if (JSON.stringify(input(prior)) !== JSON.stringify(input(record3))) throw new CloudLifecycleError("INVALID_REQUEST", "\u6062\u590D\u8BB0\u5F55\u7684\u539F\u59CB\u8BF7\u6C42\u4E0D\u80FD\u66F4\u6539");
|
|
5414
|
+
const temporary = this.path(`${record3.id}_${randomUUID8()}`);
|
|
5415
|
+
await writeFile8(temporary, JSON.stringify({ identity: this.identity, operation: record3 }), { flag: "wx", mode: 384 });
|
|
5416
|
+
await rename10(temporary, this.path(record3.id));
|
|
5417
|
+
}
|
|
5418
|
+
async read(id, kind) {
|
|
5419
|
+
try {
|
|
5420
|
+
const value = JSON.parse(await readFile19(this.path(id), "utf8"));
|
|
5421
|
+
const r = value.operation;
|
|
5422
|
+
if (JSON.stringify(value.identity) !== JSON.stringify(this.identity) || r.kind !== kind || r.id !== id) throw new Error("identity mismatch");
|
|
5423
|
+
if (r.kind === "push") {
|
|
5424
|
+
parsePushMetadata(r.metadata);
|
|
5425
|
+
if (r.metadata.pushId !== id) throw new Error("push mismatch");
|
|
5426
|
+
if (r.receipt) parsePackagePush(r.receipt);
|
|
5427
|
+
}
|
|
5428
|
+
if (r.kind === "release") {
|
|
5429
|
+
parseProductRelease({ ...r.request, status: "accepted" });
|
|
5430
|
+
if (r.request.releaseId !== id) throw new Error("release mismatch");
|
|
5431
|
+
if (r.receipt) parseProductRelease(r.receipt);
|
|
5432
|
+
}
|
|
5433
|
+
if (r.kind === "submission") {
|
|
5434
|
+
if (typeof r.version !== "string" || !r.version.trim() || typeof r.confirmed !== "boolean" || r.reviews.length === 0) throw new Error("submission invalid");
|
|
5435
|
+
parsePushMetadata({ pushId: id, commit: "validate", sourceSha256: "0".repeat(64), productReviews: r.reviews });
|
|
5436
|
+
}
|
|
5437
|
+
return r;
|
|
5438
|
+
} catch {
|
|
5439
|
+
throw new CloudLifecycleError("INVALID_REQUEST", `\u627E\u4E0D\u5230\u5F53\u524D\u5E73\u53F0\u3001\u8D26\u53F7\u548C\u642D\u5B50\u7684\u6709\u6548 ${kind} \u6062\u590D\u8BB0\u5F55\uFF1A${id}\uFF1B\u4E0D\u80FD\u66F4\u6362\u5185\u5BB9\u540E\u91CD\u7528\u6B64 ID`);
|
|
5440
|
+
}
|
|
5441
|
+
}
|
|
5442
|
+
async archive(record3) {
|
|
5443
|
+
try {
|
|
5444
|
+
const bytes = await readFile19(this.path(record3.id, "tar.gz"));
|
|
5445
|
+
if (createHash9("sha256").update(bytes).digest("hex") !== record3.metadata.sourceSha256) throw new Error("hash mismatch");
|
|
5446
|
+
return { ...record3.bundle, mediaType: "application/gzip", bytes };
|
|
5447
|
+
} catch {
|
|
5448
|
+
throw new CloudLifecycleError("INVALID_REQUEST", "\u6062\u590D\u7528\u7684\u539F\u59CB\u4EE3\u7801\u5305\u7F3A\u5931\u6216\u88AB\u4FEE\u6539\uFF1B\u4E3A\u907F\u514D\u5185\u5BB9\u6F02\u79FB\uFF0C\u5DF2\u505C\u6B62\u91CD\u8BD5");
|
|
5449
|
+
}
|
|
5450
|
+
}
|
|
5451
|
+
};
|
|
5452
|
+
|
|
5453
|
+
// packages/cli-core/src/commands/product-lifecycle.ts
|
|
5454
|
+
var PRODUCT_HELP = {
|
|
5455
|
+
push: `\u7528\u6CD5: buddy-cli push --commit <\u6539\u52A8\u8BF4\u660E> [--product <\u5546\u54C1 ID> ...] [--directory <\u76EE\u5F55>]
|
|
5456
|
+
buddy-cli push --resume <pushId> | --status <pushId> [--directory <\u76EE\u5F55>]
|
|
5457
|
+
\u4E0A\u4F20\u4EE3\u7801\u5E76\u63D0\u4EA4\u660E\u786E\u9009\u4E2D\u7684\u5546\u54C1\uFF1B\u4E0D\u6307\u5B9A --product \u53EA\u4E0A\u4F20\u4EE3\u7801\u3002\u4E0D\u4F1A\u81EA\u52A8\u53D1\u5E03\u3002
|
|
5458
|
+
\u5546\u54C1 ID \u793A\u4F8B\uFF1Aprd_12345678\uFF1B\u5DF2\u6709 ps_ \u5546\u54C1 ID \u7EE7\u7EED\u517C\u5BB9\u3002
|
|
5459
|
+
\u9996\u6B21\u4E0A\u4F20\u5FC5\u987B\u5B89\u88C5 npm latest \u6700\u65B0\u7A33\u5B9A Runtime \u7684\u51C6\u786E\u7248\u672C\uFF1B\u91CD\u8BD5\u56FA\u5B9A\u4F7F\u7528\u539F\u59CB\u5305\u3001\u8349\u7A3F\u7248\u672C\u548C\u5BA1\u6838 ID\u3002
|
|
5460
|
+
\u7F51\u7EDC\u7ED3\u679C\u672A\u77E5\u65F6\u8BF7\u4F7F\u7528\u8F93\u51FA\u7684 --resume\uFF1B--status \u53EA\u67E5\u8BE2\u3002\u4E0D\u8981\u91CD\u65B0\u4E0A\u4F20\u3002`,
|
|
5461
|
+
products: `\u7528\u6CD5: buddy-cli products submit --version <\u5DF2\u4E0A\u4F20\u6216\u5F53\u524D\u53D1\u5E03\u7248\u672C> --product <\u5546\u54C1 ID> [--product <\u5546\u54C1 ID> ...] [--directory <\u76EE\u5F55>]
|
|
5462
|
+
buddy-cli products submit --resume <submissionId> [--directory <\u76EE\u5F55>]
|
|
5463
|
+
\u7528\u4E8E\u5DF2\u4E0A\u4F20\u7248\u672C\u8865\u63D0\u5546\u54C1\uFF1B\u6B63\u5E38 push --product \u5DF2\u81EA\u52A8\u63D0\u5BA1\uFF0C\u65E0\u9700\u91CD\u590D\u6267\u884C\u3002
|
|
5464
|
+
\u5546\u54C1 ID \u793A\u4F8B\uFF1Aprd_12345678\uFF1B\u5DF2\u6709 ps_ \u5546\u54C1 ID \u7EE7\u7EED\u517C\u5BB9\u3002
|
|
5465
|
+
\u6062\u590D\u4F7F\u7528\u9996\u6B21\u6301\u4E45\u4FDD\u5B58\u7684\u5546\u54C1\u96C6\u5408\u3001\u5BA1\u6838 ID \u548C\u8349\u7A3F\u7248\u672C\u3002`,
|
|
5466
|
+
release: `\u7528\u6CD5: buddy-cli release (--from-push <pushId> | --from-submission <submissionId>) [--products-only] [--directory <\u76EE\u5F55>]
|
|
5467
|
+
buddy-cli release --version <\u7248\u672C> --code-only [--directory <\u76EE\u5F55>]
|
|
5468
|
+
buddy-cli release (--resume | --status | --retry | --cancel) <releaseId> [--directory <\u76EE\u5F55>]
|
|
5469
|
+
\u53D1\u5E03\u53EA\u91C7\u7528\u6307\u5B9A\u6210\u529F\u56DE\u6267\u4E2D\u7684\u5BA1\u6838\u96C6\u5408\uFF1B\u5546\u54C1\u5931\u8D25\u4E0D\u4F1A\u81EA\u52A8\u964D\u7EA7\u4E3A\u7EAF\u4EE3\u7801\u53D1\u5E03\u3002
|
|
5470
|
+
\u9ED8\u8BA4\u968F\u642D\u5B50\u7248\u672C\u4E00\u8D77\u53D1\u5E03\uFF1B--products-only \u53EA\u6FC0\u6D3B\u5546\u54C1\u5E76\u6838\u5BF9\u5F53\u524D\u7EBF\u4E0A\u7248\u672C\u3002
|
|
5471
|
+
\u4EC5 active \u8868\u793A\u5DF2\u751F\u6548\uFF1Baccepted/activating \u8BF7\u7528 --status \u67E5\u8BE2\u3002`
|
|
5472
|
+
};
|
|
5473
|
+
function parse2(command, args) {
|
|
5474
|
+
if (command === "products") {
|
|
5475
|
+
if (args[0] !== "submit") throw new CloudCommandUsageError(PRODUCT_HELP.products);
|
|
5476
|
+
args = args.slice(1);
|
|
5477
|
+
}
|
|
5478
|
+
const values = /* @__PURE__ */ new Map();
|
|
5479
|
+
const products = [];
|
|
5480
|
+
const allowed = command === "push" ? ["--commit", "--resume", "--status", "--product"] : command === "products" ? ["--version", "--resume", "--product"] : ["--from-push", "--from-submission", "--version", "--code-only", "--products-only", "--resume", "--status", "--retry", "--cancel"];
|
|
5481
|
+
for (let i = 0; i < args.length; i++) {
|
|
5482
|
+
const flag2 = args[i];
|
|
5483
|
+
if (flag2 !== "--directory" && !allowed.includes(flag2)) throw new CloudCommandUsageError(`\u672A\u77E5\u53C2\u6570 ${flag2}`);
|
|
5484
|
+
if (flag2 !== "--product" && values.has(flag2)) throw new CloudCommandUsageError(`${flag2} \u4E0D\u80FD\u91CD\u590D`);
|
|
5485
|
+
if (["--code-only", "--products-only"].includes(flag2)) {
|
|
5486
|
+
values.set(flag2, "true");
|
|
5487
|
+
continue;
|
|
5488
|
+
}
|
|
5489
|
+
const value = args[++i];
|
|
5490
|
+
if (!value?.trim() || value.startsWith("--") || /[\u0000-\u001f\u007f]/u.test(value)) throw new CloudCommandUsageError(`${flag2} \u7F3A\u5C11\u6709\u6548\u503C`);
|
|
5491
|
+
if (flag2 === "--product") {
|
|
5492
|
+
if (!isProductId(value) || products.includes(value)) throw new CloudCommandUsageError("\u5546\u54C1 ID \u65E0\u6548\u6216\u91CD\u590D");
|
|
5493
|
+
products.push(value);
|
|
5494
|
+
} else values.set(flag2, value.trim());
|
|
5495
|
+
}
|
|
5496
|
+
if (products.length > 10) throw new CloudCommandUsageError("\u4E00\u6B21\u6700\u591A\u9009\u62E9 10 \u4E2A\u5546\u54C1");
|
|
5497
|
+
const recovery = ["--resume", "--status", "--retry", "--cancel"].filter((f) => values.has(f));
|
|
5498
|
+
if (recovery.length && (recovery.length !== 1 || products.length || [...values.keys()].some((f) => f !== "--directory" && !recovery.includes(f)))) throw new CloudCommandUsageError("\u6062\u590D\u6216\u67E5\u8BE2\u547D\u4EE4\u4E0D\u80FD\u540C\u65F6\u66F4\u6539\u539F\u59CB\u8BF7\u6C42");
|
|
5499
|
+
return { values, products };
|
|
5500
|
+
}
|
|
5501
|
+
function required(value) {
|
|
5502
|
+
if (!value) throw new CloudCommandUsageError("\u5E73\u53F0 Adapter \u5C1A\u672A\u652F\u6301\u5546\u54C1\u4E0A\u4F20\u548C\u53D1\u5E03\u534F\u8BAE\uFF0C\u8BF7\u5347\u7EA7 Adapter");
|
|
5503
|
+
return value;
|
|
5504
|
+
}
|
|
5505
|
+
function responseError(message) {
|
|
5506
|
+
throw new CloudLifecycleError("PLATFORM_RESPONSE_INVALID", message);
|
|
5507
|
+
}
|
|
5508
|
+
async function selection(client, id, products, io) {
|
|
5509
|
+
const reviews = [];
|
|
5510
|
+
const labels = [];
|
|
5511
|
+
for (const productId of products) {
|
|
5512
|
+
const product = await required(client.getProductForSubmission).call(client, { id, productId });
|
|
5513
|
+
if (product.productId !== productId || product.buddyId !== id || !Number.isSafeInteger(product.draftVersion) || product.draftVersion < 1) responseError("\u5546\u54C1\u8EAB\u4EFD\u6216\u8349\u7A3F\u7248\u672C\u65E0\u6548");
|
|
5514
|
+
reviews.push({ productId, reviewId: `pr_${randomUUID9()}`, expectedDraftVersion: product.draftVersion });
|
|
5515
|
+
labels.push({ productId, name: product.name });
|
|
5516
|
+
io.write(`\u9009\u62E9\u5546\u54C1\uFF1A${product.name ?? productId}\uFF08${productId}\uFF09\uFF0C\u8349\u7A3F\u7248\u672C ${product.draftVersion}`);
|
|
5517
|
+
}
|
|
5518
|
+
return { reviews, labels };
|
|
5519
|
+
}
|
|
5520
|
+
function confirmPush(record3, push) {
|
|
5521
|
+
if (!samePushMetadata(record3.metadata, push.metadata) || push.pushId !== record3.id) responseError("\u670D\u52A1\u5668\u4E0A\u4F20\u56DE\u6267\u4E0E\u539F\u59CB\u8BF7\u6C42\u4E0D\u4E00\u81F4");
|
|
5522
|
+
if (push.status === "completed" && (!push.uploadVersion || !sameReviewIds(push.reviewIds, record3.metadata.productReviews.map((r) => r.reviewId)))) responseError("\u670D\u52A1\u5668\u672A\u786E\u8BA4\u5B8C\u6574\u5546\u54C1\u5BA1\u6838\u96C6\u5408");
|
|
5523
|
+
}
|
|
5524
|
+
function failureMessage(value) {
|
|
5525
|
+
if (!value || typeof value !== "object") return void 0;
|
|
5526
|
+
const detail = value;
|
|
5527
|
+
const code2 = typeof detail.code === "string" ? detail.code : void 0;
|
|
5528
|
+
const message = typeof detail.message === "string" ? detail.message : void 0;
|
|
5529
|
+
return [code2, message].filter(Boolean).join(" \xB7 ") || void 0;
|
|
5530
|
+
}
|
|
5531
|
+
function showPush(io, push) {
|
|
5532
|
+
io.write(`\u4E0A\u4F20\u7F16\u53F7\uFF1A${push.pushId}`);
|
|
5533
|
+
if (push.uploadVersion) io.write(`\u4E0A\u4F20\u7248\u672C\uFF1A${push.uploadVersion}`);
|
|
5534
|
+
io.write(`\u4E0A\u4F20\u72B6\u6001\uFF1A${push.status}`);
|
|
5535
|
+
if (failureMessage(push.failure)) io.writeError(`\u539F\u56E0\uFF1A${failureMessage(push.failure)}`);
|
|
5536
|
+
if (push.reviewIds.length) io.write(`\u5546\u54C1\u5BA1\u6838\u7F16\u53F7\uFF1A${push.reviewIds.join(", ")}`);
|
|
5537
|
+
if (push.status === "completed") {
|
|
5538
|
+
io.write(`\u672C\u6B21 push \u4E0D\u4F1A\u53D1\u5E03\u642D\u5B50\uFF1B\u786E\u8BA4\u4EE3\u7801\u53CA\u6240\u9009\u5546\u54C1\u5BA1\u6838\u7ED3\u679C\u540E\u4F7F\u7528 buddy-cli release --from-push ${push.pushId}\u3002`);
|
|
5539
|
+
return 0;
|
|
5540
|
+
}
|
|
5541
|
+
if (push.status === "product_reviews_failed") io.writeError(`\u4EE3\u7801\u5305\u5DF2\u4FDD\u5B58\uFF0C\u5546\u54C1\u672A\u5B8C\u6574\u63D0\u5BA1\u3002\u4FEE\u6B63\u5546\u54C1\u540E\u4F7F\u7528 products submit --version ${push.uploadVersion} --product <\u5546\u54C1 ID> \u8865\u63D0\uFF1B\u7EAF\u4EE3\u7801\u53D1\u5E03\u987B\u660E\u786E --code-only\u3002`);
|
|
5542
|
+
else io.writeError(`\u4E0A\u4F20\u672A\u5B8C\u6210\uFF0C\u4F7F\u7528 buddy-cli push --resume ${push.pushId} \u6062\u590D\u539F\u8BF7\u6C42\u3002`);
|
|
5543
|
+
return 1;
|
|
5544
|
+
}
|
|
5545
|
+
async function executePush(record3, sourceBundle, store, client, id, io, options) {
|
|
5546
|
+
try {
|
|
5547
|
+
const receipt = await client.pushPackage({ id, commit: record3.metadata.commit, metadata: record3.metadata, sourceBundle });
|
|
5548
|
+
const push = required(receipt.push);
|
|
5549
|
+
confirmPush(record3, push);
|
|
5550
|
+
await store.save({ ...record3, receipt: push });
|
|
5551
|
+
let exitCode = showPush(io, push);
|
|
5552
|
+
io.write(`commit\uFF1A${receipt.commit}`);
|
|
5553
|
+
io.write(`\u5BA1\u6838\u72B6\u6001\uFF1A${{ auditing: "\u5BA1\u6838\u4E2D", approved: "\u5DF2\u901A\u8FC7", rejected: "\u672A\u901A\u8FC7" }[receipt.auditStatus]}`);
|
|
5554
|
+
if (receipt.buildStatus && client.getPackageBuild && exitCode === 0) {
|
|
5555
|
+
let build = { buildStatus: receipt.buildStatus, buildError: receipt.buildError ?? null };
|
|
5556
|
+
const deadline = Date.now() + (options.buildWaitMs ?? 6e4);
|
|
5557
|
+
try {
|
|
5558
|
+
while (build.buildStatus === "building" && Date.now() < deadline) {
|
|
5559
|
+
await delay3(Math.min(options.buildPollMs ?? 2e3, Math.max(1, deadline - Date.now())), void 0, { signal: options.signal });
|
|
5560
|
+
build = await client.getPackageBuild({ id, version: receipt.version });
|
|
5561
|
+
}
|
|
5562
|
+
io.write(`\u6784\u5EFA\uFF1A${{ building: "\u6784\u5EFA\u4E2D", ready: "\u6784\u5EFA\u5B8C\u6210", failed: "\u6784\u5EFA\u5931\u8D25" }[build.buildStatus]}${build.buildError ? ` \xB7 ${build.buildError}` : ""}`);
|
|
5563
|
+
if (build.buildStatus === "failed") exitCode = 1;
|
|
5564
|
+
if (build.buildStatus === "building") io.write("\u6784\u5EFA\u4ECD\u5728\u8FDB\u884C\uFF0C\u7A0D\u540E\u8FD0\u884C buddy-cli status \u67E5\u8BE2\uFF1B\u4E0D\u8981\u91CD\u590D\u4E0A\u4F20\u3002");
|
|
5565
|
+
} catch (cause) {
|
|
5566
|
+
io.writeError(`\u4EE3\u7801\u5DF2\u4E0A\u4F20\uFF0C\u4F46\u6784\u5EFA\u72B6\u6001\u5C1A\u672A\u786E\u8BA4\uFF1A${cause instanceof Error ? cause.message : "\u7F51\u7EDC\u9519\u8BEF"}\u3002\u7528 buddy-cli status \u91CD\u67E5\uFF0C\u4E0D\u8981\u91CD\u590D\u4E0A\u4F20\u3002`);
|
|
5567
|
+
return { exitCode: 1, buddyId: id, version: receipt.version };
|
|
5568
|
+
}
|
|
5569
|
+
}
|
|
5570
|
+
return { exitCode, buddyId: id, version: receipt.version };
|
|
5571
|
+
} catch (cause) {
|
|
5572
|
+
if (cause instanceof CloudOperationError && cause.push) {
|
|
5573
|
+
confirmPush(record3, cause.push);
|
|
5574
|
+
await store.save({ ...record3, receipt: cause.push });
|
|
5575
|
+
showPush(io, cause.push);
|
|
5576
|
+
}
|
|
5577
|
+
io.writeError(`\u4E0A\u4F20\u7ED3\u679C\u9700\u786E\u8BA4\u3002\u6062\u590D\u547D\u4EE4\uFF1Abuddy-cli push --resume ${record3.id}`);
|
|
5578
|
+
throw cause;
|
|
5579
|
+
}
|
|
5580
|
+
}
|
|
5581
|
+
function matchRelease(request, release) {
|
|
5582
|
+
if (request.releaseId !== release.releaseId || request.mode !== release.mode || request.buddyVersion !== release.buddyVersion || !sameReviewIds(request.reviewIds, release.reviewIds)) responseError("\u53D1\u5E03\u56DE\u6267\u4E0E\u56FA\u5B9A\u8BF7\u6C42\u4E0D\u4E00\u81F4");
|
|
5583
|
+
}
|
|
5584
|
+
function showRelease(io, release) {
|
|
5585
|
+
io.write(`\u53D1\u5E03\u7F16\u53F7\uFF1A${release.releaseId}`);
|
|
5586
|
+
io.write(`\u53D1\u5E03\u72B6\u6001\uFF1A${release.status}`);
|
|
5587
|
+
io.write(`\u76EE\u6807\u7248\u672C\uFF1A${release.buddyVersion}`);
|
|
5588
|
+
if (failureMessage(release.failure)) io.writeError(`\u539F\u56E0\uFF1A${failureMessage(release.failure)}`);
|
|
5589
|
+
if (release.status === "active") {
|
|
5590
|
+
io.write("\u53D1\u5E03\u5DF2\u751F\u6548\u3002");
|
|
5591
|
+
return 0;
|
|
5592
|
+
}
|
|
5593
|
+
if (release.status === "failed") io.writeError(`\u53D1\u5E03\u672A\u751F\u6548\u3002\u4FEE\u6B63\u539F\u56E0\u540E buddy-cli release --retry ${release.releaseId}\uFF1B\u653E\u5F03\u5219 --cancel ${release.releaseId}\u3002`);
|
|
5594
|
+
else if (release.status === "cancelled") io.write("\u8BE5\u53D1\u5E03\u5DF2\u53D6\u6D88\u3002");
|
|
5595
|
+
else io.write(`\u53D1\u5E03\u4ECD\u5728\u5904\u7406\uFF0C\u8BF7\u8FD0\u884C buddy-cli release --status ${release.releaseId} \u786E\u8BA4\u662F\u5426\u751F\u6548\u3002`);
|
|
5596
|
+
return 1;
|
|
5597
|
+
}
|
|
5598
|
+
async function runProductLifecycle(command, args, io, options) {
|
|
5599
|
+
if (args.length === 1 && ["--help", "-h"].includes(args[0]) || command === "products" && args.length === 2 && args[0] === "submit" && args[1] === "--help") {
|
|
5600
|
+
io.write(PRODUCT_HELP[command]);
|
|
5601
|
+
return { exitCode: 0 };
|
|
5602
|
+
}
|
|
5603
|
+
const p = parse2(command, args);
|
|
5604
|
+
const v = p.values;
|
|
5605
|
+
if (options.mode === "local-mock") throw new CloudCommandUsageError("\u672C\u5730\u6A21\u62DF\u6A21\u5F0F\u4E0D\u4F1A\u4F2A\u9020\u6B63\u5F0F push \u6216\u53D1\u5E03\uFF0C\u8BF7\u8FDE\u63A5\u771F\u5B9E MLB Server");
|
|
5606
|
+
const freshPush = command === "push" && !v.has("--resume") && !v.has("--status");
|
|
5607
|
+
const root = await (options.resolveProjectRoot ?? (freshPush ? requireBuddyAgentProjectRoot : requireBuddyProjectRoot))(resolve15(options.cwd ?? process.cwd(), v.get("--directory") ?? "."));
|
|
5608
|
+
const platform = resolvePlatformUrl({ env: options.runtimeUpdate?.env });
|
|
5609
|
+
await checkProjectGateway(root, platform);
|
|
5610
|
+
const config = freshPush ? await (options.readConfig ?? readBuddyConfig)(root) : await (options.readManifest ?? readBuddyProjectManifest)(root);
|
|
5611
|
+
const id = config.buddyId;
|
|
5612
|
+
if (!id) throw new CloudCommandUsageError("\u5F53\u524D\u9879\u76EE\u7F3A\u5C11\u5E73\u53F0\u751F\u6210\u7684 buddyId\uFF0C\u8BF7\u5148\u8FD0\u884C buddy-cli init");
|
|
5613
|
+
const client = required(options.client);
|
|
5614
|
+
const session = required(options.session);
|
|
5615
|
+
let commit = v.get("--commit");
|
|
5616
|
+
if (freshPush && !commit) {
|
|
5617
|
+
if (!io.canPrompt || !io.input) throw new CloudCommandUsageError("\u7F3A\u5C11 --commit\uFF1B\u8BF7\u8BF4\u660E\u672C\u6B21\u63D0\u4EA4\u5BA1\u6838\u7684\u6539\u52A8\u5185\u5BB9");
|
|
5618
|
+
while (!commit) commit = (await io.input("\u8BF7\u8BF4\u660E\u672C\u6B21\u63D0\u4EA4\u5BA1\u6838\u7684\u6539\u52A8\u5185\u5BB9")).trim();
|
|
5619
|
+
}
|
|
5620
|
+
if (commit && (commit.length > 2e3 || /[\u0000-\u001f\u007f]/u.test(commit))) throw new CloudCommandUsageError("--commit \u987B\u4E0D\u8D85\u8FC7 2000 \u5B57\u4E14\u4E0D\u80FD\u5305\u542B\u63A7\u5236\u5B57\u7B26");
|
|
5621
|
+
const runtime = freshPush ? await requireProjectRuntime(root, { ...options.runtimeUpdate, signal: options.signal }) : void 0;
|
|
5622
|
+
const token = await session.token({ signal: options.signal });
|
|
5623
|
+
const store = new OperationStore({ platform: platform.toString(), subject: token.subject, buddyId: id }, options.operationCacheDirectory);
|
|
5624
|
+
if (command === "push") {
|
|
5625
|
+
const statusId = v.get("--status");
|
|
5626
|
+
if (statusId) {
|
|
5627
|
+
const push = await required(client.getPackagePush).call(client, { id, pushId: statusId });
|
|
5628
|
+
if (push.pushId !== statusId) responseError("\u4E0A\u4F20\u7F16\u53F7\u4E0D\u5339\u914D");
|
|
5629
|
+
return { exitCode: showPush(io, push), buddyId: id, ...push.uploadVersion ? { version: push.uploadVersion } : {} };
|
|
5630
|
+
}
|
|
5631
|
+
const resume = v.get("--resume");
|
|
5632
|
+
if (resume) {
|
|
5633
|
+
const record5 = await store.read(resume, "push");
|
|
5634
|
+
return executePush(record5, await store.archive(record5), store, client, id, io, options);
|
|
5635
|
+
}
|
|
5636
|
+
const bundle = await required(options.preparePush)(root, config, runtime);
|
|
5637
|
+
for (const warning2 of bundle.warnings ?? []) io.writeError(`\u6253\u5305\u63D0\u793A [${warning2.code}]\uFF1A${warning2.message}`);
|
|
5638
|
+
const chosen = await selection(client, id, p.products, io);
|
|
5639
|
+
const pushId = `pu_${randomUUID9()}`;
|
|
5640
|
+
const { bytes, ...bundleInfo } = bundle;
|
|
5641
|
+
const record4 = { kind: "push", id: pushId, metadata: { pushId, commit, sourceSha256: createHash10("sha256").update(bytes).digest("hex"), productReviews: chosen.reviews }, bundle: bundleInfo, products: chosen.labels };
|
|
5642
|
+
await store.create(record4, bytes);
|
|
5643
|
+
io.write(`\u6062\u590D\u7F16\u53F7\uFF1A${pushId}`);
|
|
5644
|
+
return executePush(record4, bundle, store, client, id, io, options);
|
|
5645
|
+
}
|
|
5646
|
+
if (command === "products") {
|
|
5647
|
+
let record4;
|
|
5648
|
+
if (v.has("--resume")) record4 = await store.read(v.get("--resume"), "submission");
|
|
5649
|
+
else {
|
|
5650
|
+
const version = v.get("--version");
|
|
5651
|
+
if (!version || !p.products.length) throw new CloudCommandUsageError(PRODUCT_HELP.products);
|
|
5652
|
+
const chosen = await selection(client, id, p.products, io);
|
|
5653
|
+
record4 = { kind: "submission", id: `sub_${randomUUID9()}`, version, reviews: chosen.reviews, confirmed: false };
|
|
5654
|
+
await store.create(record4);
|
|
5655
|
+
}
|
|
5656
|
+
io.write(`\u5546\u54C1\u63D0\u4EA4\u7F16\u53F7\uFF1A${record4.id}`);
|
|
5657
|
+
try {
|
|
5658
|
+
const receipt = await required(client.submitPackageProducts).call(client, { id, version: record4.version, reviews: record4.reviews });
|
|
5659
|
+
if (!sameReviewIds(receipt.reviewIds, record4.reviews.map((r) => r.reviewId))) responseError("\u5E73\u53F0\u672A\u786E\u8BA4\u5B8C\u6574\u5546\u54C1\u5BA1\u6838\u96C6\u5408");
|
|
5660
|
+
await store.save({ ...record4, confirmed: true });
|
|
5661
|
+
io.write(`\u5546\u54C1\u5DF2\u63D0\u4EA4\u5BA1\u6838\uFF1A${receipt.reviewIds.join(", ")}`);
|
|
5662
|
+
io.write(`\u5BA1\u6838\u901A\u8FC7\u540E\uFF1Abuddy-cli release --from-submission ${record4.id}`);
|
|
5663
|
+
return { exitCode: 0, buddyId: id, version: record4.version };
|
|
5664
|
+
} catch (cause) {
|
|
5665
|
+
io.writeError(`\u4FDD\u7559\u539F\u8BF7\u6C42\u91CD\u8BD5\uFF1Abuddy-cli products submit --resume ${record4.id}`);
|
|
5666
|
+
throw cause;
|
|
5667
|
+
}
|
|
5668
|
+
}
|
|
5669
|
+
const action = ["--resume", "--status", "--retry", "--cancel"].find((f) => v.has(f));
|
|
5670
|
+
let record3;
|
|
5671
|
+
if (action) {
|
|
5672
|
+
const releaseId = v.get(action);
|
|
5673
|
+
if (action === "--status") {
|
|
5674
|
+
const release = await required(client.getProductRelease).call(client, { id, releaseId });
|
|
5675
|
+
if (release.releaseId !== releaseId) responseError("\u53D1\u5E03\u7F16\u53F7\u4E0D\u5339\u914D");
|
|
5676
|
+
return { exitCode: showRelease(io, release), buddyId: id, version: release.buddyVersion };
|
|
5677
|
+
}
|
|
5678
|
+
record3 = await store.read(releaseId, "release");
|
|
5679
|
+
} else {
|
|
5680
|
+
const sources = ["--from-push", "--from-submission", "--version"].filter((f) => v.has(f));
|
|
5681
|
+
if (sources.length !== 1 || v.has("--code-only") !== v.has("--version") || v.has("--code-only") && v.has("--products-only")) throw new CloudCommandUsageError(PRODUCT_HELP.release);
|
|
5682
|
+
let version;
|
|
5683
|
+
let reviewIds;
|
|
5684
|
+
if (v.has("--from-push")) {
|
|
5685
|
+
const pushRecord = await store.read(v.get("--from-push"), "push");
|
|
5686
|
+
const receipt = await required(client.getPackagePush).call(client, { id, pushId: pushRecord.id });
|
|
5687
|
+
confirmPush(pushRecord, receipt);
|
|
5688
|
+
await store.save({ ...pushRecord, receipt });
|
|
5689
|
+
if (receipt.status !== "completed" || !receipt.uploadVersion) throw new CloudCommandUsageError("\u6307\u5B9A\u4E0A\u4F20\u5C1A\u672A\u5B8C\u6574\u63D0\u5BA1\uFF0C\u4E0D\u80FD\u81EA\u52A8\u7701\u7565\u5931\u8D25\u5546\u54C1\uFF1B\u8BF7\u8865\u63D0\u6216\u660E\u786E --version <\u7248\u672C> --code-only");
|
|
5690
|
+
version = receipt.uploadVersion;
|
|
5691
|
+
reviewIds = receipt.reviewIds;
|
|
5692
|
+
} else if (v.has("--from-submission")) {
|
|
5693
|
+
const submission = await store.read(v.get("--from-submission"), "submission");
|
|
5694
|
+
if (!submission.confirmed) throw new CloudCommandUsageError(`\u8865\u63D0\u7ED3\u679C\u5C1A\u672A\u786E\u8BA4\uFF0C\u8BF7\u5148 products submit --resume ${submission.id}`);
|
|
5695
|
+
version = submission.version;
|
|
5696
|
+
reviewIds = submission.reviews.map((r) => r.reviewId);
|
|
5697
|
+
} else {
|
|
5698
|
+
version = v.get("--version");
|
|
5699
|
+
reviewIds = [];
|
|
5700
|
+
}
|
|
5701
|
+
if (v.has("--products-only")) {
|
|
5702
|
+
if (!reviewIds.length) throw new CloudCommandUsageError("--products-only \u9700\u8981\u660E\u786E\u7684\u5546\u54C1\u5BA1\u6838\u96C6\u5408");
|
|
5703
|
+
const buddy2 = await client.getBuddy({ id });
|
|
5704
|
+
if (buddy2.id !== id || !buddy2.released || buddy2.version !== version) throw new CloudCommandUsageError("\u4EC5\u5546\u54C1\u53D1\u5E03\u8981\u6C42\u56DE\u6267\u7248\u672C\u4E0E\u5F53\u524D\u5DF2\u53D1\u5E03\u642D\u5B50\u7248\u672C\u4E00\u81F4");
|
|
5705
|
+
}
|
|
5706
|
+
const releaseId = `rel_${randomUUID9()}`;
|
|
5707
|
+
record3 = { kind: "release", id: releaseId, request: { releaseId, mode: v.has("--products-only") ? "products_only" : "with_buddy", buddyVersion: version, reviewIds } };
|
|
5708
|
+
await store.create(record3);
|
|
5709
|
+
}
|
|
5710
|
+
io.write(`\u6062\u590D\u7F16\u53F7\uFF1A${record3.id}`);
|
|
5711
|
+
try {
|
|
5712
|
+
const receipt = action === "--retry" ? await required(client.retryProductRelease).call(client, { id, releaseId: record3.id }) : action === "--cancel" ? await required(client.cancelProductRelease).call(client, { id, releaseId: record3.id }) : await required(client.createProductRelease).call(client, { id, release: record3.request });
|
|
5713
|
+
matchRelease(record3.request, receipt);
|
|
5714
|
+
await store.save({ ...record3, receipt });
|
|
5715
|
+
return { exitCode: showRelease(io, receipt), buddyId: id, version: receipt.buddyVersion };
|
|
5716
|
+
} catch (cause) {
|
|
5717
|
+
if (cause instanceof CloudOperationError && cause.release) {
|
|
5718
|
+
matchRelease(record3.request, cause.release);
|
|
5719
|
+
await store.save({ ...record3, receipt: cause.release });
|
|
5720
|
+
showRelease(io, cause.release);
|
|
5721
|
+
}
|
|
5722
|
+
io.writeError(`\u53D1\u5E03\u7ED3\u679C\u9700\u786E\u8BA4\uFF1Abuddy-cli release --status ${record3.id}\uFF1B\u539F\u8BF7\u6C42\u6062\u590D\uFF1Abuddy-cli release --resume ${record3.id}`);
|
|
5723
|
+
throw cause;
|
|
5724
|
+
}
|
|
5725
|
+
}
|
|
5726
|
+
|
|
5309
5727
|
// packages/cli-core/src/push/errors.ts
|
|
5310
5728
|
var PushPreflightError = class extends Error {
|
|
5311
5729
|
code;
|
|
@@ -5319,13 +5737,13 @@ var PushPreflightError = class extends Error {
|
|
|
5319
5737
|
};
|
|
5320
5738
|
|
|
5321
5739
|
// packages/cli-core/src/commands/cloud.ts
|
|
5322
|
-
import { resolve as
|
|
5740
|
+
import { resolve as resolve16 } from "node:path";
|
|
5323
5741
|
|
|
5324
5742
|
// packages/cli-core/src/cloud/auth.ts
|
|
5325
|
-
import { randomUUID as
|
|
5743
|
+
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
5326
5744
|
|
|
5327
5745
|
// packages/cli-core/src/cloud/validation.ts
|
|
5328
|
-
function
|
|
5746
|
+
function record2(value, path = "request") {
|
|
5329
5747
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
5330
5748
|
return invalidRequest(`${path} \u5FC5\u987B\u662F\u5BF9\u8C61`);
|
|
5331
5749
|
}
|
|
@@ -5335,12 +5753,12 @@ function record(value, path = "request") {
|
|
|
5335
5753
|
}
|
|
5336
5754
|
return value;
|
|
5337
5755
|
}
|
|
5338
|
-
function exactKeys(value,
|
|
5339
|
-
const allowed = /* @__PURE__ */ new Set([...
|
|
5756
|
+
function exactKeys(value, required2, optional = [], path = "request") {
|
|
5757
|
+
const allowed = /* @__PURE__ */ new Set([...required2, ...optional]);
|
|
5340
5758
|
for (const key of Object.keys(value)) {
|
|
5341
5759
|
if (!allowed.has(key)) invalidRequest(`${path} \u5305\u542B\u672A\u77E5\u5B57\u6BB5 ${key}`);
|
|
5342
5760
|
}
|
|
5343
|
-
for (const key of
|
|
5761
|
+
for (const key of required2) {
|
|
5344
5762
|
if (!Object.hasOwn(value, key)) invalidRequest(`${path} \u7F3A\u5C11\u5B57\u6BB5 ${key}`);
|
|
5345
5763
|
}
|
|
5346
5764
|
}
|
|
@@ -5390,7 +5808,7 @@ var CloudAuthenticator = class {
|
|
|
5390
5808
|
this.#adapter = adapter;
|
|
5391
5809
|
this.#store = store;
|
|
5392
5810
|
this.#now = options.now ?? Date.now;
|
|
5393
|
-
this.#createState = options.createState ??
|
|
5811
|
+
this.#createState = options.createState ?? randomUUID10;
|
|
5394
5812
|
this.#minimumValidityMs = options.minimumValidityMs ?? 3e4;
|
|
5395
5813
|
if (!Number.isSafeInteger(this.#minimumValidityMs) || this.#minimumValidityMs < 0) {
|
|
5396
5814
|
throw new TypeError("minimumValidityMs must be a non-negative safe integer");
|
|
@@ -5442,7 +5860,7 @@ var CloudAuthenticator = class {
|
|
|
5442
5860
|
state: state2,
|
|
5443
5861
|
...signal === void 0 ? {} : { signal }
|
|
5444
5862
|
}));
|
|
5445
|
-
const resultRecord =
|
|
5863
|
+
const resultRecord = record2(result, "browser login result");
|
|
5446
5864
|
exactKeys(resultRecord, ["state", "token"], [], "browser login result");
|
|
5447
5865
|
if (resultRecord.state !== state2) {
|
|
5448
5866
|
throw new CloudLifecycleError(
|
|
@@ -5460,7 +5878,7 @@ var CloudAuthenticator = class {
|
|
|
5460
5878
|
};
|
|
5461
5879
|
function validateToken2(value) {
|
|
5462
5880
|
try {
|
|
5463
|
-
const input =
|
|
5881
|
+
const input = record2(value, "cloud token");
|
|
5464
5882
|
exactKeys(input, ["accessToken", "subject", "expiresAt"], [], "cloud token");
|
|
5465
5883
|
const accessToken = safeString(input.accessToken, "cloud token accessToken", {
|
|
5466
5884
|
min: 16,
|
|
@@ -5538,6 +5956,7 @@ var EcsSessionMigrationStore = class {
|
|
|
5538
5956
|
};
|
|
5539
5957
|
|
|
5540
5958
|
// packages/cli-core/src/cloud/http-client.ts
|
|
5959
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
5541
5960
|
var MAX_RESPONSE_BYTES = 1024 * 1024;
|
|
5542
5961
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
5543
5962
|
var DEFAULT_UPLOAD_TIMEOUT_MS = 5 * 6e4;
|
|
@@ -5548,17 +5967,17 @@ function positiveTimeout(value, fallback, name) {
|
|
|
5548
5967
|
}
|
|
5549
5968
|
function object3(value, path) {
|
|
5550
5969
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
5551
|
-
throw
|
|
5970
|
+
throw invalid3(`${path} \u5FC5\u987B\u662F\u5BF9\u8C61`);
|
|
5552
5971
|
}
|
|
5553
5972
|
return value;
|
|
5554
5973
|
}
|
|
5555
|
-
function
|
|
5974
|
+
function invalid3(message) {
|
|
5556
5975
|
return new CloudLifecycleError("PLATFORM_RESPONSE_INVALID", message);
|
|
5557
5976
|
}
|
|
5558
5977
|
function safeText(value, path, allowNewlines = false, allowEmpty = false) {
|
|
5559
|
-
if (typeof value !== "string" || !allowEmpty && !value.trim()) throw
|
|
5978
|
+
if (typeof value !== "string" || !allowEmpty && !value.trim()) throw invalid3(`${path} \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`);
|
|
5560
5979
|
const invalidControl = allowNewlines ? /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/u : /[\u0000-\u001f\u007f]/u;
|
|
5561
|
-
if (invalidControl.test(value)) throw
|
|
5980
|
+
if (invalidControl.test(value)) throw invalid3(`${path} \u5305\u542B\u975E\u6CD5\u63A7\u5236\u5B57\u7B26`);
|
|
5562
5981
|
return value;
|
|
5563
5982
|
}
|
|
5564
5983
|
function optionalText(value, path, allowNewlines = false) {
|
|
@@ -5580,29 +5999,29 @@ function meta(value, path) {
|
|
|
5580
5999
|
});
|
|
5581
6000
|
}
|
|
5582
6001
|
function flag(value, path) {
|
|
5583
|
-
if (typeof value !== "boolean") throw
|
|
6002
|
+
if (typeof value !== "boolean") throw invalid3(`${path} \u5FC5\u987B\u662F boolean`);
|
|
5584
6003
|
return value;
|
|
5585
6004
|
}
|
|
5586
6005
|
function timestamp(value, path) {
|
|
5587
|
-
if (!Number.isSafeInteger(value) || value < 0) throw
|
|
6006
|
+
if (!Number.isSafeInteger(value) || value < 0) throw invalid3(`${path} \u5FC5\u987B\u662F\u975E\u8D1F\u6BEB\u79D2\u65F6\u95F4\u6233`);
|
|
5588
6007
|
return value;
|
|
5589
6008
|
}
|
|
5590
6009
|
function nullableText(value, path) {
|
|
5591
6010
|
return value === null ? null : safeText(value, path);
|
|
5592
6011
|
}
|
|
5593
6012
|
function nonNegativeInteger(value, path) {
|
|
5594
|
-
if (!Number.isSafeInteger(value) || value < 0) throw
|
|
6013
|
+
if (!Number.isSafeInteger(value) || value < 0) throw invalid3(`${path} \u5FC5\u987B\u662F\u975E\u8D1F\u6574\u6570`);
|
|
5595
6014
|
return value;
|
|
5596
6015
|
}
|
|
5597
6016
|
function auditStatus(value, path) {
|
|
5598
6017
|
if (value !== "auditing" && value !== "approved" && value !== "rejected") {
|
|
5599
|
-
throw
|
|
6018
|
+
throw invalid3(`${path} \u5FC5\u987B\u662F auditing\u3001approved \u6216 rejected`);
|
|
5600
6019
|
}
|
|
5601
6020
|
return value;
|
|
5602
6021
|
}
|
|
5603
6022
|
function parseBuild(value) {
|
|
5604
6023
|
const source = object3(value, "build");
|
|
5605
|
-
if (!["building", "ready", "failed"].includes(String(source.buildStatus))) throw
|
|
6024
|
+
if (!["building", "ready", "failed"].includes(String(source.buildStatus))) throw invalid3("\u6784\u5EFA\u72B6\u6001\u65E0\u6548");
|
|
5606
6025
|
return {
|
|
5607
6026
|
buildStatus: source.buildStatus,
|
|
5608
6027
|
buildError: source.buildError == null ? null : safeText(source.buildError, "build.buildError")
|
|
@@ -5652,7 +6071,7 @@ async function boundedJson(response) {
|
|
|
5652
6071
|
total += item.value.byteLength;
|
|
5653
6072
|
if (total > MAX_RESPONSE_BYTES) {
|
|
5654
6073
|
void reader.cancel().catch(() => void 0);
|
|
5655
|
-
throw
|
|
6074
|
+
throw invalid3("\u5E73\u53F0\u54CD\u5E94\u8D85\u8FC7 1 MiB");
|
|
5656
6075
|
}
|
|
5657
6076
|
chunks.push(item.value);
|
|
5658
6077
|
}
|
|
@@ -5668,17 +6087,17 @@ async function boundedJson(response) {
|
|
|
5668
6087
|
try {
|
|
5669
6088
|
return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
5670
6089
|
} catch {
|
|
5671
|
-
throw
|
|
6090
|
+
throw invalid3("\u5E73\u53F0\u54CD\u5E94\u4E0D\u662F\u6709\u6548 JSON");
|
|
5672
6091
|
}
|
|
5673
6092
|
}
|
|
5674
6093
|
function serverError(response, body) {
|
|
5675
6094
|
const source = typeof body === "object" && body !== null && !Array.isArray(body) ? body : void 0;
|
|
5676
6095
|
const message = typeof source?.error === "string" && source.error.trim() ? source.error.slice(0, 8 * 1024) : `\u5E73\u53F0\u8BF7\u6C42\u5931\u8D25\uFF08HTTP ${response.status}\uFF09`;
|
|
5677
6096
|
const code2 = response.status === 401 ? "AUTH_TOKEN_EXPIRED" : response.status === 404 ? "APP_NOT_FOUND" : response.status >= 500 ? "PLATFORM_UNAVAILABLE" : "INVALID_REQUEST";
|
|
5678
|
-
return new
|
|
6097
|
+
return new CloudOperationError(code2, message, {
|
|
5679
6098
|
httpStatus: response.status,
|
|
5680
6099
|
retryable: response.status === 408 || response.status === 429 || response.status >= 500
|
|
5681
|
-
});
|
|
6100
|
+
}, source?.push === void 0 ? void 0 : parsePackagePush(source.push), source?.release === void 0 ? void 0 : parseProductRelease(source.release));
|
|
5682
6101
|
}
|
|
5683
6102
|
var HttpDeveloperPlatformClient = class {
|
|
5684
6103
|
#baseUrl;
|
|
@@ -5739,7 +6158,7 @@ var HttpDeveloperPlatformClient = class {
|
|
|
5739
6158
|
const mediaType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
|
|
5740
6159
|
if (mediaType !== "application/json") {
|
|
5741
6160
|
await response.body?.cancel().catch(() => void 0);
|
|
5742
|
-
throw
|
|
6161
|
+
throw invalid3(`\u5E73\u53F0\u54CD\u5E94 Content-Type \u65E0\u6548\uFF08HTTP ${response.status}\uFF09`);
|
|
5743
6162
|
}
|
|
5744
6163
|
const payload = await boundedJson(response);
|
|
5745
6164
|
if (!response.ok) throw serverError(response, payload);
|
|
@@ -5764,7 +6183,7 @@ var HttpDeveloperPlatformClient = class {
|
|
|
5764
6183
|
}
|
|
5765
6184
|
async listBuddies() {
|
|
5766
6185
|
const source = object3(await this.#request("/cli/buddies", "GET"), "response");
|
|
5767
|
-
if (!Array.isArray(source.buddies)) throw
|
|
6186
|
+
if (!Array.isArray(source.buddies)) throw invalid3("response.buddies \u5FC5\u987B\u662F\u6570\u7EC4");
|
|
5768
6187
|
return Object.freeze({
|
|
5769
6188
|
buddies: Object.freeze(source.buddies.map((item) => buddy(item, false)))
|
|
5770
6189
|
});
|
|
@@ -5784,7 +6203,7 @@ var HttpDeveloperPlatformClient = class {
|
|
|
5784
6203
|
`/cli/buddies/${encodeURIComponent(request.id)}/packages${suffix}`,
|
|
5785
6204
|
"GET"
|
|
5786
6205
|
), "response");
|
|
5787
|
-
if (!Array.isArray(source.items)) throw
|
|
6206
|
+
if (!Array.isArray(source.items)) throw invalid3("response.items \u5FC5\u987B\u662F\u6570\u7EC4");
|
|
5788
6207
|
return Object.freeze({
|
|
5789
6208
|
total: nonNegativeInteger(source.total, "response.total"),
|
|
5790
6209
|
page: nonNegativeInteger(source.page, "response.page"),
|
|
@@ -5802,37 +6221,82 @@ var HttpDeveloperPlatformClient = class {
|
|
|
5802
6221
|
throw new CloudLifecycleError("INVALID_REQUEST", "\u63D0\u4EA4\u5305\u4E0D\u80FD\u4E3A\u7A7A");
|
|
5803
6222
|
}
|
|
5804
6223
|
const query = new URLSearchParams({ commit });
|
|
6224
|
+
const form = request.metadata ? new FormData() : void 0;
|
|
6225
|
+
if (form && request.metadata) {
|
|
6226
|
+
if (request.metadata.commit !== commit || request.metadata.sourceSha256 !== createHash11("sha256").update(request.sourceBundle.bytes).digest("hex")) throw new CloudLifecycleError("INVALID_REQUEST", "\u4FDD\u5B58\u7684\u4E0A\u4F20\u5143\u6570\u636E\u4E0E\u7A0B\u5E8F\u5305\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u52FF\u66F4\u6362\u6062\u590D\u5305");
|
|
6227
|
+
form.set("metadata", JSON.stringify(request.metadata));
|
|
6228
|
+
form.set("archive", new Blob([new Uint8Array(request.sourceBundle.bytes)], { type: "application/gzip" }), "archive.tar.gz");
|
|
6229
|
+
}
|
|
5805
6230
|
const source = object3(await this.#request(
|
|
5806
|
-
`/cli/buddies/${encodeURIComponent(request.id)}/packages/push
|
|
6231
|
+
`/cli/buddies/${encodeURIComponent(request.id)}/packages/push${form ? "" : `?${query.toString()}`}`,
|
|
5807
6232
|
"POST",
|
|
5808
6233
|
{
|
|
5809
|
-
binary: request.sourceBundle.bytes,
|
|
5810
|
-
mediaType: request.sourceBundle.mediaType,
|
|
6234
|
+
...form ? { form } : { binary: request.sourceBundle.bytes, mediaType: request.sourceBundle.mediaType },
|
|
5811
6235
|
timeoutMs: this.#uploadTimeoutMs
|
|
5812
6236
|
}
|
|
5813
6237
|
), "response");
|
|
6238
|
+
const push = request.metadata ? parsePackagePush(source.push) : void 0;
|
|
6239
|
+
if (push && request.metadata && !samePushMetadata(push.metadata, request.metadata)) throw invalid3("\u5E73\u53F0\u4E0A\u4F20\u56DE\u6267\u4E0E\u56FA\u5B9A\u8BF7\u6C42\u4E0D\u5339\u914D");
|
|
5814
6240
|
return Object.freeze({
|
|
5815
6241
|
version: safeText(source.version, "response.version"),
|
|
5816
6242
|
commit: safeText(source.commit, "response.commit"),
|
|
5817
6243
|
size: nonNegativeInteger(source.size, "response.size"),
|
|
5818
6244
|
auditStatus: auditStatus(source.auditStatus, "response.auditStatus"),
|
|
5819
|
-
...source.buildStatus === void 0 ? {} : parseBuild(source)
|
|
6245
|
+
...source.buildStatus === void 0 ? {} : parseBuild(source),
|
|
6246
|
+
...push ? { push, reviewIds: selectedReviewIds(source.reviewIds) } : {}
|
|
5820
6247
|
});
|
|
5821
6248
|
}
|
|
6249
|
+
async getProductForSubmission(request) {
|
|
6250
|
+
const response = object3(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/products/${encodeURIComponent(request.productId)}`, "GET"), "response");
|
|
6251
|
+
const p = object3(response.product, "product"), draft = object3(p.draft, "product.draft"), declaration = object3(draft.declaration, "product.draft.declaration");
|
|
6252
|
+
if (p.productId !== request.productId || p.buddyId !== request.id) throw invalid3("\u5546\u54C1\u5F52\u5C5E\u4E0E\u8BF7\u6C42\u4E0D\u5339\u914D");
|
|
6253
|
+
const draftVersion = nonNegativeInteger(p.draftVersion, "product.draftVersion");
|
|
6254
|
+
if (draftVersion < 1) throw invalid3("\u5546\u54C1\u8349\u7A3F\u7248\u672C\u65E0\u6548");
|
|
6255
|
+
return { productId: request.productId, buddyId: request.id, draftVersion, name: declaration.name == null ? null : safeText(declaration.name, "product.name", false, true) };
|
|
6256
|
+
}
|
|
6257
|
+
async getPackagePush(request) {
|
|
6258
|
+
const source = object3(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/packages/pushes/${encodeURIComponent(request.pushId)}`, "GET"), "response");
|
|
6259
|
+
const push = parsePackagePush(source.push);
|
|
6260
|
+
if (push.pushId !== request.pushId) throw invalid3("\u4E0A\u4F20\u56DE\u6267 ID \u4E0D\u5339\u914D");
|
|
6261
|
+
return push;
|
|
6262
|
+
}
|
|
6263
|
+
async submitPackageProducts(request) {
|
|
6264
|
+
const source = object3(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/packages/${encodeURIComponent(request.version)}/product-reviews`, "POST", { json: { reviews: request.reviews } }), "response");
|
|
6265
|
+
return { reviewIds: selectedReviewIds(source.reviewIds) };
|
|
6266
|
+
}
|
|
6267
|
+
async createProductRelease(request) {
|
|
6268
|
+
const source = object3(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/product-releases`, "POST", { json: request.release }), "response");
|
|
6269
|
+
return parseProductRelease(source.release);
|
|
6270
|
+
}
|
|
6271
|
+
async getProductRelease(request) {
|
|
6272
|
+
const source = object3(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/product-releases/${encodeURIComponent(request.releaseId)}`, "GET"), "response");
|
|
6273
|
+
const release = parseProductRelease(source.release);
|
|
6274
|
+
if (release.releaseId !== request.releaseId) throw invalid3("\u53D1\u5E03\u56DE\u6267 ID \u4E0D\u5339\u914D");
|
|
6275
|
+
return release;
|
|
6276
|
+
}
|
|
6277
|
+
async retryProductRelease(request) {
|
|
6278
|
+
const source = object3(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/product-releases/${encodeURIComponent(request.releaseId)}/retry`, "POST"), "response");
|
|
6279
|
+
return parseProductRelease(source.release);
|
|
6280
|
+
}
|
|
6281
|
+
async cancelProductRelease(request) {
|
|
6282
|
+
const source = object3(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/product-releases/${encodeURIComponent(request.releaseId)}/cancel`, "POST"), "response");
|
|
6283
|
+
return parseProductRelease(source.release);
|
|
6284
|
+
}
|
|
5822
6285
|
async getPackageBuild(request) {
|
|
5823
6286
|
return parseBuild(await this.#request(`/cli/buddies/${encodeURIComponent(request.id)}/packages/${encodeURIComponent(request.version)}/build`, "GET"));
|
|
5824
6287
|
}
|
|
5825
6288
|
async logout(accessToken) {
|
|
5826
6289
|
const source = object3(await this.#request("/cli/auth/logout", "POST", { accessToken }), "response");
|
|
5827
|
-
if (source.ok !== true) throw
|
|
6290
|
+
if (source.ok !== true) throw invalid3("response.ok \u5FC5\u987B\u662F true");
|
|
5828
6291
|
}
|
|
5829
6292
|
};
|
|
5830
6293
|
|
|
5831
6294
|
// packages/cli-core/src/cloud/mock-client.ts
|
|
5832
|
-
import { createHash as
|
|
6295
|
+
import { createHash as createHash12, randomBytes as randomBytes3 } from "node:crypto";
|
|
5833
6296
|
var MockDeveloperPlatformClient = class {
|
|
5834
6297
|
#now;
|
|
5835
6298
|
#buddies = /* @__PURE__ */ new Map();
|
|
6299
|
+
#pushes = /* @__PURE__ */ new Map();
|
|
5836
6300
|
#packages = /* @__PURE__ */ new Map();
|
|
5837
6301
|
constructor(options = {}) {
|
|
5838
6302
|
this.#now = options.now ?? Date.now;
|
|
@@ -5857,7 +6321,7 @@ var MockDeveloperPlatformClient = class {
|
|
|
5857
6321
|
const current = this.#require(request.id);
|
|
5858
6322
|
validateBuddyMetaUpdate(request.meta);
|
|
5859
6323
|
const onlyAvatar = Object.keys(request.meta).every((key) => key === "avatar");
|
|
5860
|
-
const avatar = request.avatar ? `/media/avatar-${request.id}.webp?v=${
|
|
6324
|
+
const avatar = request.avatar ? `/media/avatar-${request.id}.webp?v=${createHash12("sha256").update(request.avatar.bytes).digest("hex").slice(0, 16)}` : request.meta.avatar === null ? null : current.meta?.avatar ?? null;
|
|
5861
6325
|
const next = this.#value({ ...current, meta: { ...onlyAvatar ? current.meta : request.meta, avatar }, updatedAt: this.#now() });
|
|
5862
6326
|
this.#buddies.set(request.id, next);
|
|
5863
6327
|
return structuredClone(next);
|
|
@@ -5894,6 +6358,8 @@ var MockDeveloperPlatformClient = class {
|
|
|
5894
6358
|
throw new CloudLifecycleError("INVALID_REQUEST", "commit \u4E0D\u80FD\u4E3A\u7A7A");
|
|
5895
6359
|
}
|
|
5896
6360
|
const current = this.#require(request.id);
|
|
6361
|
+
const existing = request.metadata && this.#pushes.get(request.metadata.pushId);
|
|
6362
|
+
if (existing) return { version: existing.uploadVersion, commit: existing.metadata.commit, size: request.sourceBundle.bytes.byteLength, auditStatus: "auditing", push: structuredClone(existing), reviewIds: existing.reviewIds };
|
|
5897
6363
|
const pushedAt = this.#now();
|
|
5898
6364
|
const version = mockVersion(pushedAt);
|
|
5899
6365
|
const versions = this.#packages.get(request.id) ?? [];
|
|
@@ -5906,12 +6372,20 @@ var MockDeveloperPlatformClient = class {
|
|
|
5906
6372
|
version,
|
|
5907
6373
|
commit: request.commit,
|
|
5908
6374
|
size: request.sourceBundle.bytes.byteLength,
|
|
5909
|
-
auditStatus: "auditing"
|
|
6375
|
+
auditStatus: "auditing",
|
|
6376
|
+
...request.metadata ? { push: { pushId: request.metadata.pushId, uploadVersion: version, status: "completed", metadata: request.metadata, reviewIds: request.metadata.productReviews.map((r) => r.reviewId), failure: null }, reviewIds: request.metadata.productReviews.map((r) => r.reviewId) } : {}
|
|
5910
6377
|
});
|
|
6378
|
+
if (receipt.push) this.#pushes.set(receipt.push.pushId, receipt.push);
|
|
5911
6379
|
versions.unshift(Object.freeze({ ...receipt, auditNote: null }));
|
|
5912
6380
|
this.#packages.set(request.id, versions);
|
|
5913
6381
|
return receipt;
|
|
5914
6382
|
}
|
|
6383
|
+
async getPackagePush(request) {
|
|
6384
|
+
this.#require(request.id);
|
|
6385
|
+
const push = this.#pushes.get(request.pushId);
|
|
6386
|
+
if (!push) throw new CloudLifecycleError("APP_NOT_FOUND", "\u4E0A\u4F20\u8BB0\u5F55\u4E0D\u5B58\u5728");
|
|
6387
|
+
return structuredClone(push);
|
|
6388
|
+
}
|
|
5915
6389
|
async logout(_accessToken) {
|
|
5916
6390
|
}
|
|
5917
6391
|
#require(id) {
|
|
@@ -5933,20 +6407,12 @@ function mockVersion(now) {
|
|
|
5933
6407
|
}
|
|
5934
6408
|
|
|
5935
6409
|
// packages/cli-core/src/commands/cloud.ts
|
|
5936
|
-
var CloudCommandUsageError = class extends Error {
|
|
5937
|
-
constructor(message) {
|
|
5938
|
-
super(message);
|
|
5939
|
-
this.name = "CloudCommandUsageError";
|
|
5940
|
-
}
|
|
5941
|
-
};
|
|
5942
6410
|
var HELP = Object.freeze({
|
|
5943
6411
|
login: "\u7528\u6CD5: buddy-cli login",
|
|
5944
6412
|
logout: "\u7528\u6CD5: buddy-cli logout",
|
|
5945
|
-
push:
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
\u4E0A\u4F20\u540E\u663E\u793A\u5BA1\u6838\u53CA\u6784\u5EFA\u72B6\u6001\uFF1B\u6784\u5EFA\u672A\u5B8C\u6210\u7528 status \u91CD\u67E5\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u53D1\u5E03\u3002
|
|
5949
|
-
\u793A\u4F8B: buddy-cli push --commit "\u8C03\u6574\u56DE\u590D\u65B9\u5F0F"`,
|
|
6413
|
+
push: PRODUCT_HELP.push,
|
|
6414
|
+
products: PRODUCT_HELP.products,
|
|
6415
|
+
release: PRODUCT_HELP.release,
|
|
5950
6416
|
status: "\u7528\u6CD5: buddy-cli status [--directory <\u9879\u76EE\u76EE\u5F55>]",
|
|
5951
6417
|
meta: `\u7528\u6CD5: buddy-cli meta [--directory <\u9879\u76EE\u76EE\u5F55> | --buddy-id <\u642D\u5B50 ID>]
|
|
5952
6418
|
buddy-cli meta update [--name <\u540D\u79F0>] [--tagline <\u4E00\u53E5\u8BDD\u4ECB\u7ECD>] [--intro <\u5B8C\u6574\u4ECB\u7ECD>] [--avatar <\u56FE\u7247\u6587\u4EF6>] [--directory <\u9879\u76EE\u76EE\u5F55> | --buddy-id <\u642D\u5B50 ID>]
|
|
@@ -5962,7 +6428,7 @@ meta \u53EA\u67E5\u770B\u4E91\u7AEF\u8D44\u6599\uFF1Bmeta update \u81F3\u5C11\u6
|
|
|
5962
6428
|
--file \u63A5\u53D7\u672C\u5730\u9759\u6001 PNG\u3001JPEG\u3001WebP \u56FE\u7247\uFF0C\u6700\u5927 5 MiB\uFF1BServer \u81EA\u52A8\u5904\u7406\u5E76\u751F\u6210\u5730\u5740\u3002
|
|
5963
6429
|
\u9700\u8981\u5F53\u524D\u8D26\u53F7\u62E5\u6709\u8BE5\u642D\u5B50\uFF0C\u547D\u4EE4\u6267\u884C\u540E\u7ACB\u5373\u66F4\u65B0\u4E91\u7AEF\u8D44\u6599\u3002`
|
|
5964
6430
|
});
|
|
5965
|
-
function
|
|
6431
|
+
function parse3(args, command) {
|
|
5966
6432
|
const values = /* @__PURE__ */ new Map();
|
|
5967
6433
|
let help = false;
|
|
5968
6434
|
const update = command === "meta" && args[0] === "update";
|
|
@@ -5993,26 +6459,6 @@ function parse2(args, command) {
|
|
|
5993
6459
|
}
|
|
5994
6460
|
return { values, help, update };
|
|
5995
6461
|
}
|
|
5996
|
-
function validCommit(value) {
|
|
5997
|
-
const commit = value.trim();
|
|
5998
|
-
if (!commit) throw new CloudCommandUsageError("--commit \u4E0D\u80FD\u4E3A\u7A7A");
|
|
5999
|
-
if (/[\u0000-\u001f\u007f]/u.test(commit)) {
|
|
6000
|
-
throw new CloudCommandUsageError("--commit \u4E0D\u80FD\u5305\u542B\u975E\u6CD5\u63A7\u5236\u5B57\u7B26");
|
|
6001
|
-
}
|
|
6002
|
-
return commit;
|
|
6003
|
-
}
|
|
6004
|
-
async function pushCommit(parsed, io) {
|
|
6005
|
-
const provided = parsed.values.get("--commit");
|
|
6006
|
-
if (provided !== void 0) return validCommit(provided);
|
|
6007
|
-
if (!io.canPrompt || io.input === void 0) {
|
|
6008
|
-
throw new CloudCommandUsageError("\u7F3A\u5C11 --commit\uFF1B\u8BF7\u8BF4\u660E\u672C\u6B21\u63D0\u4EA4\u5BA1\u6838\u7684\u6539\u52A8\u5185\u5BB9");
|
|
6009
|
-
}
|
|
6010
|
-
while (true) {
|
|
6011
|
-
const answer = await io.input("\u8BF7\u8BF4\u660E\u672C\u6B21\u63D0\u4EA4\u5BA1\u6838\u7684\u6539\u52A8\u5185\u5BB9");
|
|
6012
|
-
if (answer.trim()) return validCommit(answer);
|
|
6013
|
-
io.writeError("\u8BF7\u8F93\u5165\u975E\u7A7A\u7684 commit\u3002");
|
|
6014
|
-
}
|
|
6015
|
-
}
|
|
6016
6462
|
function dependencies(options) {
|
|
6017
6463
|
if (!options.session || !options.client) {
|
|
6018
6464
|
throw new CloudCommandUsageError("\u5F53\u524D CLI Host \u5C1A\u672A\u914D\u7F6E\u642D\u642D\u8D26\u53F7\u548C\u5F00\u53D1\u8005\u5E73\u53F0 Adapter");
|
|
@@ -6020,7 +6466,7 @@ function dependencies(options) {
|
|
|
6020
6466
|
return { session: options.session, client: options.client };
|
|
6021
6467
|
}
|
|
6022
6468
|
function requestedDirectory(options, parsed) {
|
|
6023
|
-
return
|
|
6469
|
+
return resolve16(options.cwd ?? process.cwd(), parsed.values.get("--directory") ?? ".");
|
|
6024
6470
|
}
|
|
6025
6471
|
function auditLabel(status) {
|
|
6026
6472
|
if (status === "auditing") return "\u5BA1\u6838\u4E2D";
|
|
@@ -6074,49 +6520,6 @@ async function runLogout(io, options) {
|
|
|
6074
6520
|
io.write("\u5DF2\u9000\u51FA\u642D\u642D\u5F00\u53D1\u8005\u8D26\u53F7\uFF0C\u5E76\u6E05\u9664\u672C\u673A\u767B\u5F55\u72B6\u6001\u3002");
|
|
6075
6521
|
return { exitCode: 0 };
|
|
6076
6522
|
}
|
|
6077
|
-
async function runPush(parsed, io, options) {
|
|
6078
|
-
const root = await (options.resolveProjectRoot ?? requireBuddyAgentProjectRoot)(requestedDirectory(options, parsed));
|
|
6079
|
-
await checkProjectGateway(root, resolvePlatformUrl({ env: options.runtimeUpdate?.env }));
|
|
6080
|
-
const config = await (options.readConfig ?? readBuddyConfig)(root);
|
|
6081
|
-
const commit = await pushCommit(parsed, io);
|
|
6082
|
-
if (!config.buddyId) throw new CloudCommandUsageError("\u5F53\u524D\u9879\u76EE\u7F3A\u5C11\u5E73\u53F0\u751F\u6210\u7684 buddyId\uFF0C\u8BF7\u5148\u8FD0\u884C buddy-cli init");
|
|
6083
|
-
if (options.mode === "local-mock") {
|
|
6084
|
-
throw new CloudCommandUsageError("\u672C\u5730\u6A21\u62DF\u6A21\u5F0F\u4E0D\u4F1A\u4F2A\u9020\u6B63\u5F0F push\uFF0C\u8BF7\u8FDE\u63A5\u771F\u5B9E MLB Server");
|
|
6085
|
-
}
|
|
6086
|
-
if (!options.preparePush) throw new CloudCommandUsageError("push \u6253\u5305 Adapter \u5C1A\u672A\u914D\u7F6E");
|
|
6087
|
-
const { session, client } = dependencies(options);
|
|
6088
|
-
const expectedRuntime = await requireProjectRuntime(root, { ...options.runtimeUpdate, signal: options.signal });
|
|
6089
|
-
await session.token({ signal: options.signal });
|
|
6090
|
-
const sourceBundle = await options.preparePush(root, config, expectedRuntime);
|
|
6091
|
-
for (const warning2 of sourceBundle.warnings ?? []) {
|
|
6092
|
-
io.writeError(`\u6253\u5305\u63D0\u793A [${warning2.code}]\uFF1A${warning2.message}`);
|
|
6093
|
-
}
|
|
6094
|
-
const receipt = await client.pushPackage({ id: config.buddyId, commit, sourceBundle });
|
|
6095
|
-
io.write(`\u5DF2\u63D0\u4EA4\u5BA1\u6838\uFF1A${config.buddyId}`);
|
|
6096
|
-
io.write(`\u5F85\u5BA1\u6838\u7248\u672C\uFF1A${receipt.version}`);
|
|
6097
|
-
io.write(`commit\uFF1A${receipt.commit}`);
|
|
6098
|
-
io.write(`\u5BA1\u6838\u72B6\u6001\uFF1A${auditLabel(receipt.auditStatus)}`);
|
|
6099
|
-
io.write(`\u4E0A\u4F20\u5927\u5C0F\uFF1A${receipt.size} bytes`);
|
|
6100
|
-
io.write("\u672C\u6B21 push \u63D0\u4EA4\u4EE3\u7801\u5E76\u89E6\u53D1\u5E73\u53F0\u6784\u5EFA\uFF0C\u4E0D\u4F1A\u53D1\u5E03 Agent\uFF1B\u6784\u5EFA\u5B8C\u6210\u540E\u4ECD\u9700\u5728\u540E\u53F0\u624B\u52A8\u53D1\u5E03\u3002");
|
|
6101
|
-
if (receipt.buildStatus && client.getPackageBuild) {
|
|
6102
|
-
io.write(`\u6784\u5EFA\uFF1A${buildLabel(receipt.buildStatus)}`);
|
|
6103
|
-
const deadline = Date.now() + (options.buildWaitMs ?? 6e4);
|
|
6104
|
-
let build = { buildStatus: receipt.buildStatus, buildError: receipt.buildError ?? null };
|
|
6105
|
-
try {
|
|
6106
|
-
while (build.buildStatus === "building" && Date.now() < deadline) {
|
|
6107
|
-
await delay3(Math.min(options.buildPollMs ?? 2e3, Math.max(1, deadline - Date.now())), void 0, { signal: options.signal });
|
|
6108
|
-
build = await client.getPackageBuild({ id: config.buddyId, version: receipt.version });
|
|
6109
|
-
}
|
|
6110
|
-
io.write(`\u6784\u5EFA\uFF1A${buildLabel(build.buildStatus)}${build.buildError ? ` \xB7 ${build.buildError}` : ""}`);
|
|
6111
|
-
if (build.buildStatus === "failed") return { exitCode: 1, buddyId: config.buddyId, version: receipt.version };
|
|
6112
|
-
if (build.buildStatus === "building") io.write("\u6784\u5EFA\u4ECD\u5728\u8FDB\u884C\uFF0C\u7A0D\u540E\u8FD0\u884C buddy-cli status \u67E5\u8BE2\uFF1B\u4E0D\u8981\u91CD\u590D\u4E0A\u4F20\u3002");
|
|
6113
|
-
} catch (cause) {
|
|
6114
|
-
io.writeError(`\u4EE3\u7801\u5DF2\u4E0A\u4F20\uFF0C\u4F46\u6784\u5EFA\u72B6\u6001\u5C1A\u672A\u786E\u8BA4\uFF1A${cause instanceof Error ? cause.message : String(cause)}\u3002\u7528 buddy-cli status \u91CD\u67E5\uFF0C\u4E0D\u8981\u91CD\u590D\u4E0A\u4F20\u3002`);
|
|
6115
|
-
return { exitCode: 1, buddyId: config.buddyId, version: receipt.version };
|
|
6116
|
-
}
|
|
6117
|
-
}
|
|
6118
|
-
return { exitCode: 0, buddyId: config.buddyId, version: receipt.version };
|
|
6119
|
-
}
|
|
6120
6523
|
function printMeta(io, buddy2) {
|
|
6121
6524
|
io.write(`\u642D\u5B50\uFF1A${buddy2.meta?.name ?? "\u672A\u586B\u5199\u540D\u79F0"}\uFF08${buddy2.id}\uFF09`);
|
|
6122
6525
|
io.write(`\u4E00\u53E5\u8BDD\u4ECB\u7ECD\uFF1A${buddy2.meta?.tagline || "\u672A\u586B\u5199"}`);
|
|
@@ -6151,7 +6554,7 @@ async function runMeta(parsed, io, options, legacyAvatar = false) {
|
|
|
6151
6554
|
}
|
|
6152
6555
|
let upload;
|
|
6153
6556
|
try {
|
|
6154
|
-
upload = file ? await readBuddyAvatarFile(
|
|
6557
|
+
upload = file ? await readBuddyAvatarFile(resolve16(options.cwd ?? process.cwd(), file)) : void 0;
|
|
6155
6558
|
} catch (error2) {
|
|
6156
6559
|
throw new CloudCommandUsageError(error2 instanceof Error ? error2.message : "\u65E0\u6CD5\u8BFB\u53D6\u5934\u50CF\u56FE\u7247");
|
|
6157
6560
|
}
|
|
@@ -6193,7 +6596,8 @@ async function runMeta(parsed, io, options, legacyAvatar = false) {
|
|
|
6193
6596
|
}
|
|
6194
6597
|
async function runCloudCommand(command, args, io, options = {}) {
|
|
6195
6598
|
try {
|
|
6196
|
-
|
|
6599
|
+
if (command === "push" || command === "products" || command === "release") return await runProductLifecycle(command, args, io, options);
|
|
6600
|
+
const parsed = parse3(args, command);
|
|
6197
6601
|
if (parsed.help) {
|
|
6198
6602
|
io.write(HELP[command]);
|
|
6199
6603
|
return { exitCode: 0 };
|
|
@@ -6206,7 +6610,6 @@ async function runCloudCommand(command, args, io, options = {}) {
|
|
|
6206
6610
|
return { exitCode: 0 };
|
|
6207
6611
|
}
|
|
6208
6612
|
if (command === "logout") return await runLogout(io, options);
|
|
6209
|
-
if (command === "push") return await runPush(parsed, io, options);
|
|
6210
6613
|
if (command === "meta" || command === "avatar") return await runMeta(parsed, io, options, command === "avatar");
|
|
6211
6614
|
const root = await (options.resolveProjectRoot ?? requireBuddyProjectRoot)(requestedDirectory(options, parsed));
|
|
6212
6615
|
await checkProjectGateway(root, resolvePlatformUrl({ env: options.runtimeUpdate?.env }));
|
|
@@ -6238,6 +6641,10 @@ async function runCloudCommand(command, args, io, options = {}) {
|
|
|
6238
6641
|
exitCode: cause instanceof CloudCommandUsageError || cause instanceof BuddyProjectContextError ? 2 : 1
|
|
6239
6642
|
};
|
|
6240
6643
|
}
|
|
6644
|
+
if (["push", "products", "release"].includes(command)) {
|
|
6645
|
+
io.writeError(`buddy-cli: ${cause instanceof Error ? cause.message : "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u6309\u8F93\u51FA\u7F16\u53F7\u67E5\u8BE2\u6216\u6062\u590D"}`);
|
|
6646
|
+
return { exitCode: 1 };
|
|
6647
|
+
}
|
|
6241
6648
|
throw cause;
|
|
6242
6649
|
}
|
|
6243
6650
|
}
|
|
@@ -6245,7 +6652,7 @@ var CLOUD_COMMAND_HELP = HELP;
|
|
|
6245
6652
|
|
|
6246
6653
|
// packages/cli-core/src/migration/index.ts
|
|
6247
6654
|
import { lstat as lstat12, open as open5, readdir as readdir6, realpath as realpath7, stat } from "node:fs/promises";
|
|
6248
|
-
import { extname, isAbsolute as isAbsolute3, join as
|
|
6655
|
+
import { extname, isAbsolute as isAbsolute3, join as join21, relative, resolve as resolve17, sep, win32 as win322 } from "node:path";
|
|
6249
6656
|
var DEFAULT_SKILL_SCAN_LIMITS = Object.freeze({
|
|
6250
6657
|
maxFiles: 128,
|
|
6251
6658
|
maxFileBytes: 256 * 1024,
|
|
@@ -6398,7 +6805,7 @@ async function existingProjectRoot(value) {
|
|
|
6398
6805
|
return rejectScan("SKILL_PROJECT_ROOT_INVALID", ".", "projectRoot \u5FC5\u987B\u6307\u5411\u4E00\u4E2A\u5DF2\u6709\u9879\u76EE\u76EE\u5F55\u3002");
|
|
6399
6806
|
}
|
|
6400
6807
|
try {
|
|
6401
|
-
const root = await realpath7(
|
|
6808
|
+
const root = await realpath7(resolve17(value));
|
|
6402
6809
|
if (!(await stat(root)).isDirectory()) {
|
|
6403
6810
|
return rejectScan("SKILL_PROJECT_ROOT_INVALID", ".", "projectRoot \u5FC5\u987B\u6307\u5411\u4E00\u4E2A\u5DF2\u6709\u9879\u76EE\u76EE\u5F55\u3002");
|
|
6404
6811
|
}
|
|
@@ -6414,7 +6821,7 @@ async function existingProjectRoot(value) {
|
|
|
6414
6821
|
}
|
|
6415
6822
|
}
|
|
6416
6823
|
async function existingSkillRoot(projectRoot, skillPath) {
|
|
6417
|
-
const candidate = skillPath === "." ? projectRoot :
|
|
6824
|
+
const candidate = skillPath === "." ? projectRoot : join21(projectRoot, ...skillPath.split("/"));
|
|
6418
6825
|
try {
|
|
6419
6826
|
await lstat12(candidate);
|
|
6420
6827
|
} catch (cause) {
|
|
@@ -6451,7 +6858,7 @@ async function existingSkillRoot(projectRoot, skillPath) {
|
|
|
6451
6858
|
}
|
|
6452
6859
|
async function assertEntrypoint(context) {
|
|
6453
6860
|
const entryPath = reportChild(context.skillPath, "SKILL.md");
|
|
6454
|
-
const candidate =
|
|
6861
|
+
const candidate = join21(context.skillRoot, "SKILL.md");
|
|
6455
6862
|
try {
|
|
6456
6863
|
await lstat12(candidate);
|
|
6457
6864
|
const target = await realpath7(candidate);
|
|
@@ -6555,7 +6962,7 @@ async function walkDirectory(actualDirectory, reportDirectory, ancestors, contex
|
|
|
6555
6962
|
}
|
|
6556
6963
|
for (const entry2 of entries) {
|
|
6557
6964
|
const childReportPath = reportChild(reportDirectory, entry2.name);
|
|
6558
|
-
const childPath =
|
|
6965
|
+
const childPath = join21(directory, entry2.name);
|
|
6559
6966
|
let target;
|
|
6560
6967
|
try {
|
|
6561
6968
|
target = await realpath7(childPath);
|
|
@@ -7009,9 +7416,9 @@ async function scanExternalSkillPortability(options) {
|
|
|
7009
7416
|
}
|
|
7010
7417
|
|
|
7011
7418
|
// packages/cli-core/src/push/preflight.ts
|
|
7012
|
-
import { createHash as
|
|
7419
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
7013
7420
|
import { lstat as lstat13, open as open6, readdir as readdir7, realpath as realpath8 } from "node:fs/promises";
|
|
7014
|
-
import { isAbsolute as isAbsolute4, join as
|
|
7421
|
+
import { isAbsolute as isAbsolute4, join as join22, relative as relative2, resolve as resolve18, sep as sep2, win32 as win323 } from "node:path";
|
|
7015
7422
|
var MEBIBYTE = 1024 * 1024;
|
|
7016
7423
|
var DEFAULT_PUSH_MANIFEST_LIMITS = Object.freeze({
|
|
7017
7424
|
maxFiles: 1e4,
|
|
@@ -7095,7 +7502,7 @@ function error(options) {
|
|
|
7095
7502
|
throw new PushPreflightError(options);
|
|
7096
7503
|
}
|
|
7097
7504
|
function sha256(value) {
|
|
7098
|
-
return `sha256:${
|
|
7505
|
+
return `sha256:${createHash13("sha256").update(value).digest("hex")}`;
|
|
7099
7506
|
}
|
|
7100
7507
|
function positiveLimit(value, name, hardMaximum) {
|
|
7101
7508
|
if (!Number.isSafeInteger(value) || value < 1 || value > hardMaximum) {
|
|
@@ -7185,7 +7592,7 @@ function normalizeBookletPath(value) {
|
|
|
7185
7592
|
return normalized;
|
|
7186
7593
|
}
|
|
7187
7594
|
async function canonicalProjectRoot(projectRoot) {
|
|
7188
|
-
const absolute =
|
|
7595
|
+
const absolute = resolve18(projectRoot);
|
|
7189
7596
|
let entry2;
|
|
7190
7597
|
try {
|
|
7191
7598
|
entry2 = await lstat13(absolute);
|
|
@@ -7216,7 +7623,7 @@ async function canonicalProjectRoot(projectRoot) {
|
|
|
7216
7623
|
}
|
|
7217
7624
|
}
|
|
7218
7625
|
async function captureConfigWithinLimit(projectRoot, maxFileBytes, filename) {
|
|
7219
|
-
const path =
|
|
7626
|
+
const path = join22(projectRoot, filename);
|
|
7220
7627
|
let entry2;
|
|
7221
7628
|
try {
|
|
7222
7629
|
entry2 = await lstat13(path);
|
|
@@ -7341,7 +7748,7 @@ async function hashRegularFile(options) {
|
|
|
7341
7748
|
message: `\u751F\u6210\u6E05\u5355\u65F6\u6587\u4EF6\u53D1\u751F\u53D8\u5316\uFF1A${options.portablePath}`
|
|
7342
7749
|
});
|
|
7343
7750
|
}
|
|
7344
|
-
const hash3 =
|
|
7751
|
+
const hash3 = createHash13("sha256");
|
|
7345
7752
|
const captured = [];
|
|
7346
7753
|
const buffer = Buffer.allocUnsafe(READ_BUFFER_BYTES);
|
|
7347
7754
|
let bytes = 0;
|
|
@@ -7419,7 +7826,7 @@ async function createManifest(options) {
|
|
|
7419
7826
|
sensitiveEntriesExcluded += 1;
|
|
7420
7827
|
continue;
|
|
7421
7828
|
}
|
|
7422
|
-
const absolutePath =
|
|
7829
|
+
const absolutePath = join22(directory, name);
|
|
7423
7830
|
let entry2;
|
|
7424
7831
|
try {
|
|
7425
7832
|
entry2 = await lstat13(absolutePath);
|
|
@@ -7673,7 +8080,7 @@ async function assertCapturedConfigStable(options) {
|
|
|
7673
8080
|
}
|
|
7674
8081
|
let current;
|
|
7675
8082
|
try {
|
|
7676
|
-
const path =
|
|
8083
|
+
const path = join22(options.projectRoot, options.filename);
|
|
7677
8084
|
const entry2 = await lstat13(path);
|
|
7678
8085
|
if (!entry2.isFile() || entry2.isSymbolicLink()) {
|
|
7679
8086
|
error({
|
|
@@ -7719,7 +8126,7 @@ async function createPushPreflight(options) {
|
|
|
7719
8126
|
parseCapturedProject(initialAgentEntry);
|
|
7720
8127
|
let initialDataEntry;
|
|
7721
8128
|
try {
|
|
7722
|
-
await lstat13(
|
|
8129
|
+
await lstat13(join22(projectRoot, DATA_ACCESS_FILENAME));
|
|
7723
8130
|
initialDataEntry = await captureConfigWithinLimit(projectRoot, limits.maxFileBytes, DATA_ACCESS_FILENAME);
|
|
7724
8131
|
} catch (cause) {
|
|
7725
8132
|
if (cause.code !== "ENOENT") throw cause;
|
|
@@ -7820,16 +8227,16 @@ async function createPushPreflight(options) {
|
|
|
7820
8227
|
}
|
|
7821
8228
|
|
|
7822
8229
|
// packages/cli-core/src/push/bundle.ts
|
|
7823
|
-
import { createHash as
|
|
7824
|
-
import { lstat as lstat14, readFile as
|
|
7825
|
-
import { join as
|
|
8230
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
8231
|
+
import { lstat as lstat14, readFile as readFile20, realpath as realpath9 } from "node:fs/promises";
|
|
8232
|
+
import { join as join23, relative as relative3, sep as sep3, win32 as win324 } from "node:path";
|
|
7826
8233
|
import { Writable } from "node:stream";
|
|
7827
8234
|
import { pipeline } from "node:stream/promises";
|
|
7828
8235
|
import { createGzip } from "node:zlib";
|
|
7829
8236
|
import { pack } from "tar-stream";
|
|
7830
8237
|
var MEDIA_TYPE = "application/gzip";
|
|
7831
8238
|
function digest3(bytes) {
|
|
7832
|
-
return `sha256:${
|
|
8239
|
+
return `sha256:${createHash14("sha256").update(bytes).digest("hex")}`;
|
|
7833
8240
|
}
|
|
7834
8241
|
function changed(path, message, cause) {
|
|
7835
8242
|
throw new PushPreflightError({
|
|
@@ -7844,7 +8251,7 @@ function inside(root, target) {
|
|
|
7844
8251
|
return path === "" || path !== ".." && !path.startsWith(`..${sep3}`) && !path.startsWith("/") && !win324.isAbsolute(path);
|
|
7845
8252
|
}
|
|
7846
8253
|
async function capture(root, file) {
|
|
7847
|
-
const absolute =
|
|
8254
|
+
const absolute = join23(root, ...file.path.split("/"));
|
|
7848
8255
|
try {
|
|
7849
8256
|
const entry2 = await lstat14(absolute);
|
|
7850
8257
|
if (!entry2.isFile() || entry2.isSymbolicLink() || entry2.size !== file.bytes) {
|
|
@@ -7852,7 +8259,7 @@ async function capture(root, file) {
|
|
|
7852
8259
|
}
|
|
7853
8260
|
const canonical = await realpath9(absolute);
|
|
7854
8261
|
if (!inside(root, canonical)) changed(file.path, `\u63D0\u4EA4\u6587\u4EF6\u8D8A\u8FC7\u9879\u76EE\u6839\u76EE\u5F55\uFF1A${file.path}`);
|
|
7855
|
-
const contents = await
|
|
8262
|
+
const contents = await readFile20(absolute);
|
|
7856
8263
|
if (contents.byteLength !== file.bytes || digest3(contents) !== file.digest) {
|
|
7857
8264
|
changed(file.path, `\u63D0\u4EA4\u524D\u6587\u4EF6\u5185\u5BB9\u53D1\u751F\u53D8\u5316\uFF1A${file.path}`);
|
|
7858
8265
|
}
|
|
@@ -7878,7 +8285,7 @@ async function createPushSourceBundle(plan) {
|
|
|
7878
8285
|
schemaVersion: "1",
|
|
7879
8286
|
files: files.map((file) => ({ path: file.path, bytes: file.bytes, digest: file.digest }))
|
|
7880
8287
|
});
|
|
7881
|
-
const calculatedBundleDigest = `sha256:${
|
|
8288
|
+
const calculatedBundleDigest = `sha256:${createHash14("sha256").update(`buddy-push-bundle-v1\0${descriptor}`).digest("hex")}`;
|
|
7882
8289
|
if (calculatedBundleDigest !== plan.bundleDigest) {
|
|
7883
8290
|
changed(plan.projectRoot, "\u63D0\u4EA4\u6E05\u5355\u8EAB\u4EFD\u5728\u6253\u5305\u524D\u53D1\u751F\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C push");
|
|
7884
8291
|
}
|
|
@@ -7979,7 +8386,7 @@ async function resolveApplicationDraft(name, tagline, intro, requestedBuddyId, o
|
|
|
7979
8386
|
confirmMeta: args.confirmMeta,
|
|
7980
8387
|
avatarSkill: { version: args.avatarSkillVersion, signal: options.cloud?.signal },
|
|
7981
8388
|
requestedBuddyId,
|
|
7982
|
-
cwd:
|
|
8389
|
+
cwd: resolve19(options.cwd ?? process.cwd()),
|
|
7983
8390
|
client: platformDependencies(options).client,
|
|
7984
8391
|
io
|
|
7985
8392
|
});
|
|
@@ -8143,7 +8550,7 @@ function defaultProjectDirectory(name) {
|
|
|
8143
8550
|
return `./${folder2}`;
|
|
8144
8551
|
}
|
|
8145
8552
|
async function initializeProjectRoute(route, args, io, options, application) {
|
|
8146
|
-
const cwd =
|
|
8553
|
+
const cwd = resolve19(options.cwd ?? process.cwd());
|
|
8147
8554
|
const { name, tagline, intro } = application;
|
|
8148
8555
|
const directoryInput = await textAnswer(
|
|
8149
8556
|
io,
|
|
@@ -8152,7 +8559,7 @@ async function initializeProjectRoute(route, args, io, options, application) {
|
|
|
8152
8559
|
"\u9879\u76EE\u76EE\u5F55\uFF08\u7A7A\u76EE\u5F55\u6216\u5DF2\u6709\u642D\u642D\u5DE5\u7A0B\uFF09",
|
|
8153
8560
|
defaultProjectDirectory(name)
|
|
8154
8561
|
);
|
|
8155
|
-
const rootDirectory =
|
|
8562
|
+
const rootDirectory = resolve19(cwd, directoryInput);
|
|
8156
8563
|
await assertInitializableBuddyTarget(rootDirectory);
|
|
8157
8564
|
const initializationTarget = { directory: rootDirectory, kind: "new" };
|
|
8158
8565
|
let initializationPlan = options.initializeProject ? void 0 : await planBuddyProjectInitialization(initializationTarget);
|
|
@@ -8198,7 +8605,7 @@ async function initializeProjectRoute(route, args, io, options, application) {
|
|
|
8198
8605
|
}
|
|
8199
8606
|
async function runRoute(route, args, io, options) {
|
|
8200
8607
|
if (!io.canPrompt) assertNonInteractiveProjectArguments(route, args);
|
|
8201
|
-
const cwd =
|
|
8608
|
+
const cwd = resolve19(options.cwd ?? process.cwd());
|
|
8202
8609
|
const name = await textAnswer(io, args.name, "--name", "\u642D\u5B50\u540D\u79F0", void 0, BUDDY_PROFILE_TEXT_LIMITS.name);
|
|
8203
8610
|
const tagline = await textAnswer(
|
|
8204
8611
|
io,
|
|
@@ -8226,7 +8633,7 @@ async function runRoute(route, args, io, options) {
|
|
|
8226
8633
|
"\u9879\u76EE\u76EE\u5F55",
|
|
8227
8634
|
defaultProjectDirectory(name)
|
|
8228
8635
|
);
|
|
8229
|
-
const rootDirectory =
|
|
8636
|
+
const rootDirectory = resolve19(cwd, directoryInput);
|
|
8230
8637
|
await assertInitializableBuddyTarget(rootDirectory);
|
|
8231
8638
|
let plan = await planBuddyDraftInitialization(rootDirectory);
|
|
8232
8639
|
const existingBuddyId = plan.existingManifest?.buddyId;
|
|
@@ -8262,11 +8669,11 @@ async function runRoute(route, args, io, options) {
|
|
|
8262
8669
|
return { ...result, route: "create", draft, buddyId };
|
|
8263
8670
|
}
|
|
8264
8671
|
async function resumeProjectArguments(args, cwd, options, io) {
|
|
8265
|
-
const root =
|
|
8672
|
+
const root = resolve19(cwd, args.directory?.trim() || ".");
|
|
8266
8673
|
await assertInitializableBuddyTarget(root);
|
|
8267
8674
|
let entry2;
|
|
8268
8675
|
try {
|
|
8269
|
-
entry2 = await lstat15(
|
|
8676
|
+
entry2 = await lstat15(join24(root, "package.json"));
|
|
8270
8677
|
} catch (cause) {
|
|
8271
8678
|
if (cause.code === "ENOENT") {
|
|
8272
8679
|
const draft = await readMetaDraft(root);
|
|
@@ -8307,7 +8714,7 @@ async function runBuddyCli(args, io, options = {}) {
|
|
|
8307
8714
|
try {
|
|
8308
8715
|
const [command, ...rest] = args;
|
|
8309
8716
|
if (!command) {
|
|
8310
|
-
const cwd =
|
|
8717
|
+
const cwd = resolve19(options.cwd ?? process.cwd());
|
|
8311
8718
|
let projectRoot;
|
|
8312
8719
|
try {
|
|
8313
8720
|
projectRoot = await findBuddyProjectRoot(cwd);
|
|
@@ -8357,7 +8764,7 @@ async function runBuddyCli(args, io, options = {}) {
|
|
|
8357
8764
|
...options.dev
|
|
8358
8765
|
});
|
|
8359
8766
|
}
|
|
8360
|
-
if (command === "login" || command === "logout" || command === "push" || command === "status" || command === "meta" || command === "avatar") {
|
|
8767
|
+
if (command === "login" || command === "logout" || command === "push" || command === "products" || command === "release" || command === "status" || command === "meta" || command === "avatar") {
|
|
8361
8768
|
return await runCloudCommand(command, rest, io, {
|
|
8362
8769
|
cwd: options.cwd,
|
|
8363
8770
|
runtimeUpdate: options.runtimeCatalog,
|
|
@@ -8372,13 +8779,13 @@ async function runBuddyCli(args, io, options = {}) {
|
|
|
8372
8779
|
}
|
|
8373
8780
|
let route = routeFromMode(parsed.mode);
|
|
8374
8781
|
if (route === void 0 && !io.canPrompt) requireModeForNonInteractive();
|
|
8375
|
-
const cwd =
|
|
8782
|
+
const cwd = resolve19(options.cwd ?? process.cwd());
|
|
8376
8783
|
await assertInitializableBuddyTarget(cwd);
|
|
8377
8784
|
if (parsed.directory !== void 0) {
|
|
8378
8785
|
if (!parsed.directory.trim()) throw new CliUsageError("--directory \u4E0D\u80FD\u4E3A\u7A7A");
|
|
8379
|
-
await assertInitializableBuddyTarget(
|
|
8786
|
+
await assertInitializableBuddyTarget(resolve19(cwd, parsed.directory));
|
|
8380
8787
|
}
|
|
8381
|
-
await checkProjectGateway(
|
|
8788
|
+
await checkProjectGateway(resolve19(cwd, parsed.directory ?? "."), resolvePlatformUrl({ env: options.runtimeCatalog?.env }));
|
|
8382
8789
|
await authenticate(options);
|
|
8383
8790
|
await resumeProjectArguments(parsed, cwd, options, io);
|
|
8384
8791
|
route ??= routeFromMode(parsed.mode);
|
|
@@ -8492,6 +8899,7 @@ export {
|
|
|
8492
8899
|
CloudAuthenticator,
|
|
8493
8900
|
CloudCommandUsageError,
|
|
8494
8901
|
CloudLifecycleError,
|
|
8902
|
+
CloudOperationError,
|
|
8495
8903
|
DEFAULT_DEVELOPER_WEB_URL,
|
|
8496
8904
|
DEFAULT_MLB_TEST_URL,
|
|
8497
8905
|
DEFAULT_PUSH_MANIFEST_LIMITS,
|