@adep/cli 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +295 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -8472,6 +8472,163 @@ var init_hash = __esm({
|
|
|
8472
8472
|
}
|
|
8473
8473
|
});
|
|
8474
8474
|
|
|
8475
|
+
// packages/cli/src/publish-checks.ts
|
|
8476
|
+
import { posix as posix3 } from "node:path";
|
|
8477
|
+
function formatFindings(findings) {
|
|
8478
|
+
const lines = findings.map(
|
|
8479
|
+
(finding) => `${finding.file}:${finding.line} [${finding.rule}] ${finding.severity === "error" ? "\u5371\u9669" : "\u8B66\u544A"}\uFF1A${finding.message}`
|
|
8480
|
+
);
|
|
8481
|
+
return [`\u53D1\u5E03\u524D\u9759\u6001\u6821\u9A8C\u53D1\u73B0 ${findings.length} \u4E2A\u95EE\u9898\uFF1A`, ...lines, "\u4FEE\u590D\u540E\u91CD\u8BD5\uFF1Bwarn \u7EA7\u53EF\u7528 --force \u653E\u884C\uFF0Cerror \u7EA7\u4E0D\u53EF\u653E\u884C\u3002"].join(
|
|
8482
|
+
"\n"
|
|
8483
|
+
);
|
|
8484
|
+
}
|
|
8485
|
+
function locate(content, index) {
|
|
8486
|
+
const before = content.slice(0, index);
|
|
8487
|
+
const line = before.split("\n").length;
|
|
8488
|
+
const start = before.lastIndexOf("\n") + 1;
|
|
8489
|
+
const end = content.indexOf("\n", index);
|
|
8490
|
+
return { line, text: content.slice(start, end === -1 ? content.length : end) };
|
|
8491
|
+
}
|
|
8492
|
+
function checkFilePath(functionName, file2) {
|
|
8493
|
+
const normalized = file2.split("\\").join("/");
|
|
8494
|
+
const segments = normalized.split("/");
|
|
8495
|
+
const escapes = normalized.startsWith("/") || segments.some((s) => ESCAPE_KEY_SEGMENTS.has(s));
|
|
8496
|
+
if (!escapes) return [];
|
|
8497
|
+
return [
|
|
8498
|
+
{
|
|
8499
|
+
rule: "PATH_ESCAPE",
|
|
8500
|
+
severity: "error",
|
|
8501
|
+
functionName,
|
|
8502
|
+
file: file2,
|
|
8503
|
+
line: 1,
|
|
8504
|
+
message: `bundle \u952E\u4E0D\u80FD\u662F\u7EDD\u5BF9\u8DEF\u5F84\u6216\u5305\u542B ".."\uFF08\u6536\u5230 "${file2}"\uFF09`
|
|
8505
|
+
}
|
|
8506
|
+
];
|
|
8507
|
+
}
|
|
8508
|
+
function checkImportSpecifiers(functionName, file2, content) {
|
|
8509
|
+
const findings = [];
|
|
8510
|
+
for (const matched of content.matchAll(IMPORT_SPECIFIER)) {
|
|
8511
|
+
const specifier = matched[1] ?? "";
|
|
8512
|
+
if (!specifier.startsWith(".")) continue;
|
|
8513
|
+
const resolved = posix3.normalize(posix3.join(posix3.dirname(file2.split("\\").join("/")), specifier));
|
|
8514
|
+
if (!resolved.startsWith("..") && !posix3.isAbsolute(resolved)) continue;
|
|
8515
|
+
const { line } = locate(content, matched.index ?? 0);
|
|
8516
|
+
findings.push({
|
|
8517
|
+
rule: "PATH_ESCAPE",
|
|
8518
|
+
severity: "error",
|
|
8519
|
+
functionName,
|
|
8520
|
+
file: file2,
|
|
8521
|
+
line,
|
|
8522
|
+
message: `import "${specifier}" \u89E3\u6790\u5230 "${resolved}"\uFF0C\u9003\u51FA\u51FD\u6570 bundle \u6839`
|
|
8523
|
+
});
|
|
8524
|
+
}
|
|
8525
|
+
return findings;
|
|
8526
|
+
}
|
|
8527
|
+
function checkSqlConcat(functionName, file2, content) {
|
|
8528
|
+
const findings = [];
|
|
8529
|
+
for (const matched of content.matchAll(SQL_CALL)) {
|
|
8530
|
+
const arg = matched.groups?.["arg"] ?? "";
|
|
8531
|
+
if (!SQL_KEYWORD.test(arg) || !CONCAT_OR_TEMPLATE.test(arg)) continue;
|
|
8532
|
+
const { line } = locate(content, matched.index ?? 0);
|
|
8533
|
+
findings.push({
|
|
8534
|
+
rule: "SQL_CONCAT",
|
|
8535
|
+
severity: "error",
|
|
8536
|
+
functionName,
|
|
8537
|
+
file: file2,
|
|
8538
|
+
line,
|
|
8539
|
+
message: "SQL \u8BED\u53E5\u542B\u5B57\u7B26\u4E32\u62FC\u63A5 / \u6A21\u677F\u63D2\u503C\uFF1B\u6539\u7528\u53C2\u6570\u5316\u5360\u4F4D\u7B26\uFF08? / $1\uFF09"
|
|
8540
|
+
});
|
|
8541
|
+
}
|
|
8542
|
+
return findings;
|
|
8543
|
+
}
|
|
8544
|
+
function checkSecrets(functionName, file2, content) {
|
|
8545
|
+
const findings = [];
|
|
8546
|
+
const lines = content.split("\n");
|
|
8547
|
+
lines.forEach((text, index) => {
|
|
8548
|
+
for (const rule of SECRET_RULES) {
|
|
8549
|
+
if (!rule.pattern.test(text)) continue;
|
|
8550
|
+
findings.push({
|
|
8551
|
+
rule: "SECRET_LITERAL",
|
|
8552
|
+
severity: rule.severity,
|
|
8553
|
+
functionName,
|
|
8554
|
+
file: file2,
|
|
8555
|
+
line: index + 1,
|
|
8556
|
+
message: rule.message
|
|
8557
|
+
});
|
|
8558
|
+
}
|
|
8559
|
+
});
|
|
8560
|
+
return findings;
|
|
8561
|
+
}
|
|
8562
|
+
function collectPrecheckFindings(functions) {
|
|
8563
|
+
const findings = [];
|
|
8564
|
+
for (const [functionName, files] of Object.entries(functions).toSorted(
|
|
8565
|
+
([a], [b]) => a.localeCompare(b)
|
|
8566
|
+
)) {
|
|
8567
|
+
const sortedFiles = Object.entries(files).toSorted(([a], [b]) => a.localeCompare(b));
|
|
8568
|
+
for (const [file2, content] of sortedFiles) {
|
|
8569
|
+
findings.push(...checkFilePath(functionName, file2));
|
|
8570
|
+
findings.push(...checkImportSpecifiers(functionName, file2, content));
|
|
8571
|
+
findings.push(...checkSqlConcat(functionName, file2, content));
|
|
8572
|
+
findings.push(...checkSecrets(functionName, file2, content));
|
|
8573
|
+
}
|
|
8574
|
+
}
|
|
8575
|
+
const seen = /* @__PURE__ */ new Set();
|
|
8576
|
+
return findings.filter((finding) => {
|
|
8577
|
+
const key = `${finding.rule}|${finding.functionName}|${finding.file}|${finding.line}|${finding.message}`;
|
|
8578
|
+
if (seen.has(key)) return false;
|
|
8579
|
+
seen.add(key);
|
|
8580
|
+
return true;
|
|
8581
|
+
}).toSorted(
|
|
8582
|
+
(a, b) => a.file.localeCompare(b.file) || a.line - b.line || a.rule.localeCompare(b.rule)
|
|
8583
|
+
);
|
|
8584
|
+
}
|
|
8585
|
+
function assertPrechecks(functions, options = {}) {
|
|
8586
|
+
const findings = collectPrecheckFindings(functions);
|
|
8587
|
+
const errors = findings.filter((finding) => finding.severity === "error");
|
|
8588
|
+
const warnings = findings.filter((finding) => finding.severity === "warn");
|
|
8589
|
+
if (errors.length > 0) throw new PrecheckError(findings);
|
|
8590
|
+
if (warnings.length > 0 && options.force !== true) throw new PrecheckError(warnings);
|
|
8591
|
+
return warnings;
|
|
8592
|
+
}
|
|
8593
|
+
var PrecheckError, ESCAPE_KEY_SEGMENTS, IMPORT_SPECIFIER, SQL_CALL, SQL_KEYWORD, CONCAT_OR_TEMPLATE, SECRET_RULES;
|
|
8594
|
+
var init_publish_checks = __esm({
|
|
8595
|
+
"packages/cli/src/publish-checks.ts"() {
|
|
8596
|
+
"use strict";
|
|
8597
|
+
init_auth();
|
|
8598
|
+
PrecheckError = class extends CliError {
|
|
8599
|
+
findings;
|
|
8600
|
+
constructor(findings) {
|
|
8601
|
+
super("PRECHECK_FAILED", formatFindings(findings));
|
|
8602
|
+
this.name = "PrecheckError";
|
|
8603
|
+
this.findings = findings;
|
|
8604
|
+
}
|
|
8605
|
+
};
|
|
8606
|
+
ESCAPE_KEY_SEGMENTS = /* @__PURE__ */ new Set([".."]);
|
|
8607
|
+
IMPORT_SPECIFIER = /(?:from\s*|import\s*|require\s*\(\s*)['"]([^'"]+)['"]/g;
|
|
8608
|
+
SQL_CALL = /\.(?:query|execute|run|all|get|prepare)\s*\(\s*(?<arg>[^\n]*)/g;
|
|
8609
|
+
SQL_KEYWORD = /\b(?:SELECT|INSERT|UPDATE|DELETE|REPLACE|WITH|WHERE|FROM)\b/i;
|
|
8610
|
+
CONCAT_OR_TEMPLATE = /(?:\$\{|`\s*\+|\+\s*['"`]|['"`]\s*\+)/;
|
|
8611
|
+
SECRET_RULES = [
|
|
8612
|
+
{
|
|
8613
|
+
pattern: /-----BEGIN (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----/,
|
|
8614
|
+
message: "\u6E90\u7801\u542B PEM \u79C1\u94A5\u660E\u6587",
|
|
8615
|
+
severity: "error"
|
|
8616
|
+
},
|
|
8617
|
+
{ pattern: /AKIA[0-9A-Z]{16}/, message: "\u6E90\u7801\u542B AWS Access Key \u660E\u6587", severity: "error" },
|
|
8618
|
+
{
|
|
8619
|
+
pattern: /(?:sk|pk)_(?:live|test)_[0-9A-Za-z]{16,}/,
|
|
8620
|
+
message: "\u6E90\u7801\u542B\u652F\u4ED8\u6E20\u9053\u5BC6\u94A5\u660E\u6587",
|
|
8621
|
+
severity: "error"
|
|
8622
|
+
},
|
|
8623
|
+
{
|
|
8624
|
+
pattern: /(?:password|passwd|secret|api[_-]?key|access[_-]?token)\s*[:=]\s*['"][^'"]{8,}['"]/i,
|
|
8625
|
+
message: "\u7591\u4F3C\u5BC6\u94A5 / \u53E3\u4EE4\u786C\u7F16\u7801\uFF1B\u6539\u4ECE ctx.env / \u5E73\u53F0\u73AF\u5883\u53D8\u91CF\u8BFB\u53D6",
|
|
8626
|
+
severity: "warn"
|
|
8627
|
+
}
|
|
8628
|
+
];
|
|
8629
|
+
}
|
|
8630
|
+
});
|
|
8631
|
+
|
|
8475
8632
|
// packages/cli/src/deploy.ts
|
|
8476
8633
|
var deploy_exports = {};
|
|
8477
8634
|
__export(deploy_exports, {
|
|
@@ -8577,6 +8734,10 @@ async function deploy(paths, options) {
|
|
|
8577
8734
|
}
|
|
8578
8735
|
const shared = await collectShared(functionsDir);
|
|
8579
8736
|
const filesFor = (name) => local[name] ?? {};
|
|
8737
|
+
const precheckWarnings = assertPrechecks(local, { force: options.force === true });
|
|
8738
|
+
for (const finding of precheckWarnings) {
|
|
8739
|
+
log(`[adep] \u6821\u9A8C\u8B66\u544A ${finding.file}:${finding.line} [${finding.rule}] ${finding.message}`);
|
|
8740
|
+
}
|
|
8580
8741
|
const sharedRows = Object.entries(shared).map(([path, content]) => ({ path, content }));
|
|
8581
8742
|
const hashFiles = (name) => {
|
|
8582
8743
|
const filesAsRuntimeSees = mergeSharedSource(filesFor(name), sharedRows);
|
|
@@ -8677,6 +8838,7 @@ var init_deploy = __esm({
|
|
|
8677
8838
|
init_hash();
|
|
8678
8839
|
init_dev();
|
|
8679
8840
|
init_net();
|
|
8841
|
+
init_publish_checks();
|
|
8680
8842
|
init_shared_source();
|
|
8681
8843
|
init_shared_source();
|
|
8682
8844
|
AmbiguousFunctionError = class extends CliError {
|
|
@@ -10037,7 +10199,9 @@ var init_git = __esm({
|
|
|
10037
10199
|
var functions_exports = {};
|
|
10038
10200
|
__export(functions_exports, {
|
|
10039
10201
|
functionsList: () => functionsList,
|
|
10040
|
-
functionsLogs: () => functionsLogs
|
|
10202
|
+
functionsLogs: () => functionsLogs,
|
|
10203
|
+
logsByTrace: () => logsByTrace,
|
|
10204
|
+
resolveProject: () => resolveProject2
|
|
10041
10205
|
});
|
|
10042
10206
|
import { resolve as resolve20 } from "node:path";
|
|
10043
10207
|
async function functionsList(paths, options) {
|
|
@@ -10080,6 +10244,22 @@ async function functionsLogs(paths, options) {
|
|
|
10080
10244
|
);
|
|
10081
10245
|
return { functionId: target.id, name: target.name, logs: result.logs };
|
|
10082
10246
|
}
|
|
10247
|
+
async function logsByTrace(paths, options) {
|
|
10248
|
+
const trace = options.trace.trim();
|
|
10249
|
+
if (trace.length === 0) {
|
|
10250
|
+
throw new CliError("INVALID_ARGUMENT", "\u7F3A\u5C11 traceId\uFF1Aadep logs --trace <traceId>");
|
|
10251
|
+
}
|
|
10252
|
+
const client = await createClient(paths);
|
|
10253
|
+
const project2 = await resolveProject2(client, options);
|
|
10254
|
+
const params = new URLSearchParams({ trace });
|
|
10255
|
+
if (options.tail !== void 0) params.set("tail", String(options.tail));
|
|
10256
|
+
const result = await client.request(
|
|
10257
|
+
`/api/v1/projects/${project2.id}/logs?${params.toString()}`,
|
|
10258
|
+
{},
|
|
10259
|
+
"FUNCTION_LOGS_FAILED"
|
|
10260
|
+
);
|
|
10261
|
+
return { projectId: project2.id, slug: project2.slug, traceId: result.traceId, logs: result.logs };
|
|
10262
|
+
}
|
|
10083
10263
|
async function resolveProject2(client, options) {
|
|
10084
10264
|
const slug = await resolveSlug(resolve20(options.cwd), options.slug);
|
|
10085
10265
|
const projects = await projectsListFrom(client);
|
|
@@ -10104,6 +10284,65 @@ var init_functions = __esm({
|
|
|
10104
10284
|
}
|
|
10105
10285
|
});
|
|
10106
10286
|
|
|
10287
|
+
// packages/cli/src/rollback.ts
|
|
10288
|
+
var rollback_exports = {};
|
|
10289
|
+
__export(rollback_exports, {
|
|
10290
|
+
parseVersionFlag: () => parseVersionFlag,
|
|
10291
|
+
rollbackFunctionTo: () => rollbackFunctionTo
|
|
10292
|
+
});
|
|
10293
|
+
function parseVersionFlag(raw) {
|
|
10294
|
+
const text = (raw ?? "").trim();
|
|
10295
|
+
const matched = /^v?(\d+)$/.exec(text);
|
|
10296
|
+
const version2 = matched === null ? Number.NaN : Number(matched[1]);
|
|
10297
|
+
if (!Number.isInteger(version2) || version2 <= 0) {
|
|
10298
|
+
throw new CliError("INVALID_ARGUMENT", `--to \u987B\u4E3A\u7248\u672C\u53F7\uFF08\u5982 v2 \u6216 2\uFF09\uFF0C\u6536\u5230 "${raw ?? ""}"`);
|
|
10299
|
+
}
|
|
10300
|
+
return version2;
|
|
10301
|
+
}
|
|
10302
|
+
async function rollbackFunctionTo(paths, options) {
|
|
10303
|
+
if (!Number.isInteger(options.to) || options.to <= 0) {
|
|
10304
|
+
throw new CliError("INVALID_ARGUMENT", `--to \u987B\u4E3A\u6B63\u6574\u6570\uFF0C\u6536\u5230 ${options.to}`);
|
|
10305
|
+
}
|
|
10306
|
+
const client = await createClient(paths);
|
|
10307
|
+
const project2 = await resolveProject2(client, options);
|
|
10308
|
+
const listed = await client.request(
|
|
10309
|
+
`/api/v1/projects/${project2.id}/functions`,
|
|
10310
|
+
{},
|
|
10311
|
+
"FUNCTION_LIST_FAILED"
|
|
10312
|
+
);
|
|
10313
|
+
const target = listed.functions.find((fn) => fn.name === options.name);
|
|
10314
|
+
if (target === void 0) {
|
|
10315
|
+
throw new CliError("FN_NOT_FOUND", `\u51FD\u6570 "${options.name}" \u4E0D\u5B58\u5728\u4E8E\u9879\u76EE "${project2.slug}"`);
|
|
10316
|
+
}
|
|
10317
|
+
const versions = await client.request(`/api/v1/functions/${target.id}/versions`, {}, "FUNCTION_VERSIONS_FAILED");
|
|
10318
|
+
if (!versions.versions.some((version2) => version2.version === options.to)) {
|
|
10319
|
+
const available = versions.versions.map((version2) => `v${version2.version}`).join(", ");
|
|
10320
|
+
throw new CliError(
|
|
10321
|
+
"VERSION_NOT_FOUND",
|
|
10322
|
+
`\u7248\u672C v${options.to} \u4E0D\u5728\u4FDD\u7559\u7A97\u53E3\u5185\uFF08\u5F53\u524D v${versions.current ?? "\u2014"}\uFF1B\u53EF\u7528\uFF1A${available === "" ? "\u65E0" : available}\uFF09`
|
|
10323
|
+
);
|
|
10324
|
+
}
|
|
10325
|
+
const result = await client.request(
|
|
10326
|
+
`/api/v1/functions/${target.id}/rollback`,
|
|
10327
|
+
{ method: "POST", body: { version: options.to } },
|
|
10328
|
+
"ROLLBACK_FAILED"
|
|
10329
|
+
);
|
|
10330
|
+
return {
|
|
10331
|
+
functionId: target.id,
|
|
10332
|
+
name: target.name,
|
|
10333
|
+
from: versions.current,
|
|
10334
|
+
to: result.version
|
|
10335
|
+
};
|
|
10336
|
+
}
|
|
10337
|
+
var init_rollback = __esm({
|
|
10338
|
+
"packages/cli/src/rollback.ts"() {
|
|
10339
|
+
"use strict";
|
|
10340
|
+
init_auth();
|
|
10341
|
+
init_client();
|
|
10342
|
+
init_functions();
|
|
10343
|
+
}
|
|
10344
|
+
});
|
|
10345
|
+
|
|
10107
10346
|
// packages/cli/src/cli.ts
|
|
10108
10347
|
init_config();
|
|
10109
10348
|
import { Command } from "commander";
|
|
@@ -38765,6 +39004,59 @@ function registerHosting(program2, ctx) {
|
|
|
38765
39004
|
});
|
|
38766
39005
|
}
|
|
38767
39006
|
|
|
39007
|
+
// packages/cli/src/commands/logs.ts
|
|
39008
|
+
init_auth();
|
|
39009
|
+
function registerLogs(program2, ctx) {
|
|
39010
|
+
program2.command("logs").description("\u6309 traceId \u67E5\u8BE2\u4E00\u6B21\u8C03\u7528\u94FE\u7684\u65E5\u5FD7\uFF08traceId \u89C1\u9519\u8BEF\u4FE1\u5C01\u6216\u54CD\u5E94\u5934\uFF09").option("--trace <traceId>", "W3C traceId\uFF0832 \u4F4D hex\uFF09").option("--tail <count>", "\u53D6\u6700\u8FD1\u591A\u5C11\u6761\uFF08\u7F3A\u7701 100\uFF0C\u670D\u52A1\u7AEF\u6709\u4E0A\u9650\uFF09").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (flags) => {
|
|
39011
|
+
const command = ctx.io("logs");
|
|
39012
|
+
await command.run(async () => {
|
|
39013
|
+
const trace = flags.trace?.trim() ?? "";
|
|
39014
|
+
if (trace.length === 0) {
|
|
39015
|
+
throw new CliError("INVALID_ARGUMENT", "\u7F3A\u5C11 --trace\uFF1Aadep logs --trace <traceId>");
|
|
39016
|
+
}
|
|
39017
|
+
const tail = flags.tail === void 0 ? void 0 : Number(flags.tail);
|
|
39018
|
+
if (tail !== void 0 && (!Number.isFinite(tail) || tail <= 0)) {
|
|
39019
|
+
throw new CliError("INVALID_TAIL", `--tail \u987B\u4E3A\u6B63\u6574\u6570\uFF0C\u6536\u5230 "${flags.tail}"`);
|
|
39020
|
+
}
|
|
39021
|
+
const { logsByTrace: logsByTrace2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
|
|
39022
|
+
const result = await logsByTrace2(ctx.paths, {
|
|
39023
|
+
cwd: ctx.cwd,
|
|
39024
|
+
trace,
|
|
39025
|
+
...tail === void 0 ? {} : { tail },
|
|
39026
|
+
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
39027
|
+
});
|
|
39028
|
+
command.ok(result, (data) => {
|
|
39029
|
+
const r = data;
|
|
39030
|
+
if (r.logs.length === 0) {
|
|
39031
|
+
return `\uFF08trace ${r.traceId} \u6682\u65E0\u65E5\u5FD7\uFF1A\u786E\u8BA4 traceId \u6B63\u786E\uFF0C\u4E14\u8BE5\u8C03\u7528\u53D1\u751F\u5728\u65E5\u5FD7\u7F13\u51B2\u4FDD\u7559\u7A97\u53E3\u5185\uFF09`;
|
|
39032
|
+
}
|
|
39033
|
+
return r.logs.map((log) => `${log.at} [${log.level}] ${log.message}`);
|
|
39034
|
+
});
|
|
39035
|
+
});
|
|
39036
|
+
});
|
|
39037
|
+
}
|
|
39038
|
+
|
|
39039
|
+
// packages/cli/src/commands/rollback.ts
|
|
39040
|
+
function registerRollback(program2, ctx) {
|
|
39041
|
+
program2.command("rollback <fn>").description("\u628A\u5DF2\u53D1\u5E03\u51FD\u6570\u5207\u56DE\u5386\u53F2\u7248\u672C\uFF08\u7248\u672C\u6765\u81EA adep publish \u751F\u6210\u7684\u81EA\u589E\u53F7\uFF09").option("--to <version>", "\u76EE\u6807\u7248\u672C\u53F7\uFF0C\u5982 v2 \u6216 2").option("-p, --project <slug>", "\u76EE\u6807\u5E73\u53F0\u9879\u76EE slug\uFF08\u7F3A\u7701\u53D6 adep.config.ts \u7684 name\uFF09").action(async (name, flags) => {
|
|
39042
|
+
const command = ctx.io("rollback");
|
|
39043
|
+
await command.run(async () => {
|
|
39044
|
+
const { parseVersionFlag: parseVersionFlag2, rollbackFunctionTo: rollbackFunctionTo2 } = await Promise.resolve().then(() => (init_rollback(), rollback_exports));
|
|
39045
|
+
const to = parseVersionFlag2(flags.to);
|
|
39046
|
+
const result = await rollbackFunctionTo2(ctx.paths, {
|
|
39047
|
+
cwd: ctx.cwd,
|
|
39048
|
+
name,
|
|
39049
|
+
to,
|
|
39050
|
+
...flags.project === void 0 ? {} : { slug: flags.project }
|
|
39051
|
+
});
|
|
39052
|
+
command.ok(result, (data) => {
|
|
39053
|
+
const r = data;
|
|
39054
|
+
return `\u5DF2\u56DE\u6EDA ${r.name}\uFF1Av${r.from ?? "\u2014"} \u2192 v${r.to}`;
|
|
39055
|
+
});
|
|
39056
|
+
});
|
|
39057
|
+
});
|
|
39058
|
+
}
|
|
39059
|
+
|
|
38768
39060
|
// packages/cli/src/cli.ts
|
|
38769
39061
|
var requireJson = createRequire2(import.meta.url);
|
|
38770
39062
|
var APP_VERSION = requireJson("../package.json").version;
|
|
@@ -38800,6 +39092,8 @@ function buildProgram(options = {}) {
|
|
|
38800
39092
|
registerAuth(program2, ctx);
|
|
38801
39093
|
registerMcp(program2, ctx);
|
|
38802
39094
|
registerGit(program2, ctx);
|
|
39095
|
+
registerLogs(program2, ctx);
|
|
39096
|
+
registerRollback(program2, ctx);
|
|
38803
39097
|
registerDeploy(program2, ctx);
|
|
38804
39098
|
registerProjects(program2, ctx);
|
|
38805
39099
|
registerFunctions(program2, ctx);
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"homepage": "https://adep.top",
|
|
9
9
|
"bugs": "https://gitcode.com/yunqiang_wu/ai-yunke/issues",
|
|
10
|
-
"version": "0.5.
|
|
10
|
+
"version": "0.5.1",
|
|
11
11
|
"type": "module",
|
|
12
12
|
"description": "`adep` 命令行工具包位:登录 / 初始化 / 本地调试 / 部署 / 数据库维护 / 云存储 / 静态托管 / 微前端组件(widget),实现见任务单 CLI-001 ~ CLI-003 与 FE-002;子路径 `@adep/cli/vite` 提供云函数 vite 插件(CLI-014)",
|
|
13
13
|
"bin": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@adep/runtime": "0.3.8"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@adep/types": "0.4.
|
|
40
|
+
"@adep/types": "0.4.1"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
43
|
"test": "vitest run",
|