@freelog-cli/cli2 0.5.3 → 0.5.5
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/bin/index.js +1578 -640
- package/dist/bin/index.js.map +1 -1
- package/dist/docs/01-/345/277/253/351/200/237/344/270/212/346/211/213.md +9 -5
- package/dist/docs/02-/346/227/245/345/270/270/350/267/257/345/276/204.md +1 -1
- package/dist/docs/03-/344/270/273/351/242/230/344/270/216/346/217/222/344/273/266.md +15 -6
- package/dist/docs/04-/347/211/210/346/234/254/345/267/245/344/275/234/347/250/277.md +18 -5
- package/dist/docs/05-/350/265/204/346/272/220/347/256/241/347/220/206.md +23 -7
- package/dist/docs/06-/345/270/270/350/247/201/346/203/205/345/206/265/344/270/216/346/212/245/351/224/231.md +2 -2
- package/dist/docs/08-/346/234/254/345/234/260/346/226/207/344/273/266/345/217/202/350/200/203.md +20 -17
- package/dist/docs/09-/346/214/211/345/234/272/346/231/257/346/223/215/344/275/234.md +3 -3
- package/dist/docs/10-/345/221/275/344/273/244/345/217/202/350/200/203.md +21 -18
- package/dist/docs/README.md +4 -4
- package/package.json +1 -1
package/dist/bin/index.js
CHANGED
|
@@ -9168,11 +9168,11 @@ var require_mime_types = __commonJS({
|
|
|
9168
9168
|
}
|
|
9169
9169
|
return exts[0];
|
|
9170
9170
|
}
|
|
9171
|
-
function lookup(
|
|
9172
|
-
if (!
|
|
9171
|
+
function lookup(path20) {
|
|
9172
|
+
if (!path20 || typeof path20 !== "string") {
|
|
9173
9173
|
return false;
|
|
9174
9174
|
}
|
|
9175
|
-
var extension2 = extname("x." +
|
|
9175
|
+
var extension2 = extname("x." + path20).toLowerCase().substr(1);
|
|
9176
9176
|
if (!extension2) {
|
|
9177
9177
|
return false;
|
|
9178
9178
|
}
|
|
@@ -10287,7 +10287,7 @@ var require_form_data = __commonJS({
|
|
|
10287
10287
|
"use strict";
|
|
10288
10288
|
var CombinedStream = require_combined_stream();
|
|
10289
10289
|
var util4 = __require("util");
|
|
10290
|
-
var
|
|
10290
|
+
var path20 = __require("path");
|
|
10291
10291
|
var http3 = __require("http");
|
|
10292
10292
|
var https2 = __require("https");
|
|
10293
10293
|
var parseUrl2 = __require("url").parse;
|
|
@@ -10418,11 +10418,11 @@ var require_form_data = __commonJS({
|
|
|
10418
10418
|
FormData3.prototype._getContentDisposition = function(value, options) {
|
|
10419
10419
|
var filename;
|
|
10420
10420
|
if (typeof options.filepath === "string") {
|
|
10421
|
-
filename =
|
|
10421
|
+
filename = path20.normalize(options.filepath).replace(/\\/g, "/");
|
|
10422
10422
|
} else if (options.filename || value && (value.name || value.path)) {
|
|
10423
|
-
filename =
|
|
10423
|
+
filename = path20.basename(options.filename || value && (value.name || value.path));
|
|
10424
10424
|
} else if (value && value.readable && hasOwn(value, "httpVersion")) {
|
|
10425
|
-
filename =
|
|
10425
|
+
filename = path20.basename(value.client._httpMessage.path || "");
|
|
10426
10426
|
}
|
|
10427
10427
|
if (filename) {
|
|
10428
10428
|
return 'filename="' + escapeHeaderParam(filename) + '"';
|
|
@@ -13339,9 +13339,9 @@ function isVisitable(thing) {
|
|
|
13339
13339
|
function removeBrackets(key) {
|
|
13340
13340
|
return utils_default.endsWith(key, "[]") ? key.slice(0, -2) : key;
|
|
13341
13341
|
}
|
|
13342
|
-
function renderKey(
|
|
13343
|
-
if (!
|
|
13344
|
-
return
|
|
13342
|
+
function renderKey(path20, key, dots) {
|
|
13343
|
+
if (!path20) return key;
|
|
13344
|
+
return path20.concat(key).map(function each(token, i) {
|
|
13345
13345
|
token = removeBrackets(token);
|
|
13346
13346
|
return !dots && i ? "[" + token + "]" : token;
|
|
13347
13347
|
}).join(dots ? "." : "");
|
|
@@ -13427,13 +13427,13 @@ function toFormData(obj, formData, options) {
|
|
|
13427
13427
|
return currentValue;
|
|
13428
13428
|
});
|
|
13429
13429
|
}
|
|
13430
|
-
function defaultVisitor(value, key,
|
|
13430
|
+
function defaultVisitor(value, key, path20) {
|
|
13431
13431
|
let arr = value;
|
|
13432
13432
|
if (utils_default.isReactNative(formData) && utils_default.isReactNativeBlob(value)) {
|
|
13433
|
-
formData.append(renderKey(
|
|
13433
|
+
formData.append(renderKey(path20, key, dots), convertValue(value));
|
|
13434
13434
|
return false;
|
|
13435
13435
|
}
|
|
13436
|
-
if (value && !
|
|
13436
|
+
if (value && !path20 && typeof value === "object") {
|
|
13437
13437
|
if (utils_default.endsWith(key, "{}")) {
|
|
13438
13438
|
key = metaTokens ? key : key.slice(0, -2);
|
|
13439
13439
|
value = stringifyWithDepthLimit(value, 1);
|
|
@@ -13452,7 +13452,7 @@ function toFormData(obj, formData, options) {
|
|
|
13452
13452
|
if (isVisitable(value)) {
|
|
13453
13453
|
return true;
|
|
13454
13454
|
}
|
|
13455
|
-
formData.append(renderKey(
|
|
13455
|
+
formData.append(renderKey(path20, key, dots), convertValue(value));
|
|
13456
13456
|
return false;
|
|
13457
13457
|
}
|
|
13458
13458
|
const exposedHelpers = Object.assign(predicates, {
|
|
@@ -13460,17 +13460,17 @@ function toFormData(obj, formData, options) {
|
|
|
13460
13460
|
convertValue,
|
|
13461
13461
|
isVisitable
|
|
13462
13462
|
});
|
|
13463
|
-
function build(value,
|
|
13463
|
+
function build(value, path20, depth = 0) {
|
|
13464
13464
|
if (utils_default.isUndefined(value)) return;
|
|
13465
13465
|
throwIfMaxDepthExceeded(depth);
|
|
13466
13466
|
if (stack.indexOf(value) !== -1) {
|
|
13467
|
-
throw new Error("Circular reference detected in " +
|
|
13467
|
+
throw new Error("Circular reference detected in " + path20.join("."));
|
|
13468
13468
|
}
|
|
13469
13469
|
stack.push(value);
|
|
13470
13470
|
utils_default.forEach(value, function each(el, key) {
|
|
13471
|
-
const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key) ? key.trim() : key,
|
|
13471
|
+
const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key) ? key.trim() : key, path20, exposedHelpers);
|
|
13472
13472
|
if (result === true) {
|
|
13473
|
-
build(el,
|
|
13473
|
+
build(el, path20 ? path20.concat(key) : [key], depth + 1);
|
|
13474
13474
|
}
|
|
13475
13475
|
});
|
|
13476
13476
|
stack.pop();
|
|
@@ -13682,7 +13682,7 @@ var platform_default = {
|
|
|
13682
13682
|
// ../../node_modules/.pnpm/axios@1.19.0/node_modules/axios/lib/helpers/toURLEncodedForm.js
|
|
13683
13683
|
function toURLEncodedForm(data, options) {
|
|
13684
13684
|
return toFormData_default(data, new platform_default.classes.URLSearchParams(), {
|
|
13685
|
-
visitor: function(value, key,
|
|
13685
|
+
visitor: function(value, key, path20, helpers) {
|
|
13686
13686
|
if (platform_default.isNode && utils_default.isBuffer(value)) {
|
|
13687
13687
|
this.append(key, value.toString("base64"));
|
|
13688
13688
|
return false;
|
|
@@ -13704,14 +13704,14 @@ function throwIfDepthExceeded(index) {
|
|
|
13704
13704
|
}
|
|
13705
13705
|
}
|
|
13706
13706
|
function parsePropPath(name) {
|
|
13707
|
-
const
|
|
13707
|
+
const path20 = [];
|
|
13708
13708
|
const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
|
|
13709
13709
|
let match;
|
|
13710
13710
|
while ((match = pattern.exec(name)) !== null) {
|
|
13711
|
-
throwIfDepthExceeded(
|
|
13712
|
-
|
|
13711
|
+
throwIfDepthExceeded(path20.length);
|
|
13712
|
+
path20.push(match[0] === "[]" ? "" : match[1] || match[0]);
|
|
13713
13713
|
}
|
|
13714
|
-
return
|
|
13714
|
+
return path20;
|
|
13715
13715
|
}
|
|
13716
13716
|
function arrayToObject(arr) {
|
|
13717
13717
|
const obj = {};
|
|
@@ -13726,12 +13726,12 @@ function arrayToObject(arr) {
|
|
|
13726
13726
|
return obj;
|
|
13727
13727
|
}
|
|
13728
13728
|
function formDataToJSON(formData) {
|
|
13729
|
-
function buildPath(
|
|
13729
|
+
function buildPath(path20, value, target, index) {
|
|
13730
13730
|
throwIfDepthExceeded(index);
|
|
13731
|
-
let name =
|
|
13731
|
+
let name = path20[index++];
|
|
13732
13732
|
if (name === "__proto__") return true;
|
|
13733
13733
|
const isNumericKey = Number.isFinite(+name);
|
|
13734
|
-
const isLast = index >=
|
|
13734
|
+
const isLast = index >= path20.length;
|
|
13735
13735
|
name = !name && utils_default.isArray(target) ? target.length : name;
|
|
13736
13736
|
if (isLast) {
|
|
13737
13737
|
if (utils_default.hasOwnProp(target, name)) {
|
|
@@ -13744,7 +13744,7 @@ function formDataToJSON(formData) {
|
|
|
13744
13744
|
if (!utils_default.hasOwnProp(target, name) || !utils_default.isObject(target[name])) {
|
|
13745
13745
|
target[name] = [];
|
|
13746
13746
|
}
|
|
13747
|
-
const result = buildPath(
|
|
13747
|
+
const result = buildPath(path20, value, target[name], index);
|
|
13748
13748
|
if (result && utils_default.isArray(target[name])) {
|
|
13749
13749
|
target[name] = arrayToObject(target[name]);
|
|
13750
13750
|
}
|
|
@@ -15462,9 +15462,9 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
15462
15462
|
auth = urlUsername + ":" + urlPassword;
|
|
15463
15463
|
}
|
|
15464
15464
|
auth && headers.delete("authorization");
|
|
15465
|
-
let
|
|
15465
|
+
let path20;
|
|
15466
15466
|
try {
|
|
15467
|
-
|
|
15467
|
+
path20 = buildURL(
|
|
15468
15468
|
parsed.pathname + parsed.search,
|
|
15469
15469
|
own2("params"),
|
|
15470
15470
|
own2("paramsSerializer")
|
|
@@ -15483,7 +15483,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
15483
15483
|
false
|
|
15484
15484
|
);
|
|
15485
15485
|
const options = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
15486
|
-
path:
|
|
15486
|
+
path: path20,
|
|
15487
15487
|
method,
|
|
15488
15488
|
headers: toByteStringHeaderObject(headers),
|
|
15489
15489
|
agents: { http: httpAgent, https: httpsAgent },
|
|
@@ -15885,14 +15885,14 @@ var isURLSameOrigin_default = platform_default.hasStandardBrowserEnv ? /* @__PUR
|
|
|
15885
15885
|
var cookies_default = platform_default.hasStandardBrowserEnv ? (
|
|
15886
15886
|
// Standard browser envs support document.cookie
|
|
15887
15887
|
{
|
|
15888
|
-
write(name, value, expires,
|
|
15888
|
+
write(name, value, expires, path20, domain, secure, sameSite) {
|
|
15889
15889
|
if (typeof document === "undefined") return;
|
|
15890
15890
|
const cookie = [`${name}=${encodeURIComponent(value)}`];
|
|
15891
15891
|
if (utils_default.isNumber(expires)) {
|
|
15892
15892
|
cookie.push(`expires=${new Date(expires).toUTCString()}`);
|
|
15893
15893
|
}
|
|
15894
|
-
if (utils_default.isString(
|
|
15895
|
-
cookie.push(`path=${
|
|
15894
|
+
if (utils_default.isString(path20)) {
|
|
15895
|
+
cookie.push(`path=${path20}`);
|
|
15896
15896
|
}
|
|
15897
15897
|
if (utils_default.isString(domain)) {
|
|
15898
15898
|
cookie.push(`domain=${domain}`);
|
|
@@ -17786,14 +17786,14 @@ function copy(a, s, t2) {
|
|
|
17786
17786
|
if (s[m]) t2[m] = s[m];
|
|
17787
17787
|
});
|
|
17788
17788
|
}
|
|
17789
|
-
function getLastOfPath(object,
|
|
17789
|
+
function getLastOfPath(object, path20, Empty) {
|
|
17790
17790
|
function cleanKey(key2) {
|
|
17791
17791
|
return key2 && key2.indexOf("###") > -1 ? key2.replace(/###/g, ".") : key2;
|
|
17792
17792
|
}
|
|
17793
17793
|
function canNotTraverseDeeper() {
|
|
17794
17794
|
return !object || typeof object === "string";
|
|
17795
17795
|
}
|
|
17796
|
-
var stack = typeof
|
|
17796
|
+
var stack = typeof path20 !== "string" ? [].concat(path20) : path20.split(".");
|
|
17797
17797
|
while (stack.length > 1) {
|
|
17798
17798
|
if (canNotTraverseDeeper()) return {};
|
|
17799
17799
|
var key = cleanKey(stack.shift());
|
|
@@ -17810,18 +17810,18 @@ function getLastOfPath(object, path19, Empty) {
|
|
|
17810
17810
|
k: cleanKey(stack.shift())
|
|
17811
17811
|
};
|
|
17812
17812
|
}
|
|
17813
|
-
function setPath(object,
|
|
17814
|
-
var _getLastOfPath = getLastOfPath(object,
|
|
17813
|
+
function setPath(object, path20, newValue) {
|
|
17814
|
+
var _getLastOfPath = getLastOfPath(object, path20, Object), obj = _getLastOfPath.obj, k = _getLastOfPath.k;
|
|
17815
17815
|
obj[k] = newValue;
|
|
17816
17816
|
}
|
|
17817
|
-
function pushPath(object,
|
|
17818
|
-
var _getLastOfPath2 = getLastOfPath(object,
|
|
17817
|
+
function pushPath(object, path20, newValue, concat) {
|
|
17818
|
+
var _getLastOfPath2 = getLastOfPath(object, path20, Object), obj = _getLastOfPath2.obj, k = _getLastOfPath2.k;
|
|
17819
17819
|
obj[k] = obj[k] || [];
|
|
17820
17820
|
if (concat) obj[k] = obj[k].concat(newValue);
|
|
17821
17821
|
if (!concat) obj[k].push(newValue);
|
|
17822
17822
|
}
|
|
17823
|
-
function getPath(object,
|
|
17824
|
-
var _getLastOfPath3 = getLastOfPath(object,
|
|
17823
|
+
function getPath(object, path20) {
|
|
17824
|
+
var _getLastOfPath3 = getLastOfPath(object, path20), obj = _getLastOfPath3.obj, k = _getLastOfPath3.k;
|
|
17825
17825
|
if (!obj) return void 0;
|
|
17826
17826
|
return obj[k];
|
|
17827
17827
|
}
|
|
@@ -17943,11 +17943,11 @@ function _isNativeReflectConstruct() {
|
|
|
17943
17943
|
return false;
|
|
17944
17944
|
}
|
|
17945
17945
|
}
|
|
17946
|
-
function deepFind(obj,
|
|
17946
|
+
function deepFind(obj, path20) {
|
|
17947
17947
|
var keySeparator = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : ".";
|
|
17948
17948
|
if (!obj) return void 0;
|
|
17949
|
-
if (obj[
|
|
17950
|
-
var paths =
|
|
17949
|
+
if (obj[path20]) return obj[path20];
|
|
17950
|
+
var paths = path20.split(keySeparator);
|
|
17951
17951
|
var current = obj;
|
|
17952
17952
|
for (var i = 0; i < paths.length; ++i) {
|
|
17953
17953
|
if (!current) return void 0;
|
|
@@ -17965,7 +17965,7 @@ function deepFind(obj, path19) {
|
|
|
17965
17965
|
}
|
|
17966
17966
|
if (mix === void 0) return void 0;
|
|
17967
17967
|
if (mix === null) return null;
|
|
17968
|
-
if (
|
|
17968
|
+
if (path20.endsWith(p)) {
|
|
17969
17969
|
if (typeof mix === "string") return mix;
|
|
17970
17970
|
if (p && typeof mix[p] === "string") return mix[p];
|
|
17971
17971
|
}
|
|
@@ -18022,13 +18022,13 @@ var ResourceStore = (function(_EventEmitter) {
|
|
|
18022
18022
|
var options = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : {};
|
|
18023
18023
|
var keySeparator = options.keySeparator !== void 0 ? options.keySeparator : this.options.keySeparator;
|
|
18024
18024
|
var ignoreJSONStructure = options.ignoreJSONStructure !== void 0 ? options.ignoreJSONStructure : this.options.ignoreJSONStructure;
|
|
18025
|
-
var
|
|
18026
|
-
if (key && typeof key !== "string")
|
|
18027
|
-
if (key && typeof key === "string")
|
|
18025
|
+
var path20 = [lng, ns];
|
|
18026
|
+
if (key && typeof key !== "string") path20 = path20.concat(key);
|
|
18027
|
+
if (key && typeof key === "string") path20 = path20.concat(keySeparator ? key.split(keySeparator) : key);
|
|
18028
18028
|
if (lng.indexOf(".") > -1) {
|
|
18029
|
-
|
|
18029
|
+
path20 = lng.split(".");
|
|
18030
18030
|
}
|
|
18031
|
-
var result = getPath(this.data,
|
|
18031
|
+
var result = getPath(this.data, path20);
|
|
18032
18032
|
if (result || !ignoreJSONStructure || typeof key !== "string") return result;
|
|
18033
18033
|
return deepFind(this.data && this.data[lng] && this.data[lng][ns], key, keySeparator);
|
|
18034
18034
|
}
|
|
@@ -18040,15 +18040,15 @@ var ResourceStore = (function(_EventEmitter) {
|
|
|
18040
18040
|
};
|
|
18041
18041
|
var keySeparator = this.options.keySeparator;
|
|
18042
18042
|
if (keySeparator === void 0) keySeparator = ".";
|
|
18043
|
-
var
|
|
18044
|
-
if (key)
|
|
18043
|
+
var path20 = [lng, ns];
|
|
18044
|
+
if (key) path20 = path20.concat(keySeparator ? key.split(keySeparator) : key);
|
|
18045
18045
|
if (lng.indexOf(".") > -1) {
|
|
18046
|
-
|
|
18046
|
+
path20 = lng.split(".");
|
|
18047
18047
|
value = ns;
|
|
18048
|
-
ns =
|
|
18048
|
+
ns = path20[1];
|
|
18049
18049
|
}
|
|
18050
18050
|
this.addNamespaces(ns);
|
|
18051
|
-
setPath(this.data,
|
|
18051
|
+
setPath(this.data, path20, value);
|
|
18052
18052
|
if (!options.silent) this.emit("added", lng, ns, key, value);
|
|
18053
18053
|
}
|
|
18054
18054
|
}, {
|
|
@@ -18070,21 +18070,21 @@ var ResourceStore = (function(_EventEmitter) {
|
|
|
18070
18070
|
var options = arguments.length > 5 && arguments[5] !== void 0 ? arguments[5] : {
|
|
18071
18071
|
silent: false
|
|
18072
18072
|
};
|
|
18073
|
-
var
|
|
18073
|
+
var path20 = [lng, ns];
|
|
18074
18074
|
if (lng.indexOf(".") > -1) {
|
|
18075
|
-
|
|
18075
|
+
path20 = lng.split(".");
|
|
18076
18076
|
deep = resources;
|
|
18077
18077
|
resources = ns;
|
|
18078
|
-
ns =
|
|
18078
|
+
ns = path20[1];
|
|
18079
18079
|
}
|
|
18080
18080
|
this.addNamespaces(ns);
|
|
18081
|
-
var pack = getPath(this.data,
|
|
18081
|
+
var pack = getPath(this.data, path20) || {};
|
|
18082
18082
|
if (deep) {
|
|
18083
18083
|
deepExtend(pack, resources, overwrite);
|
|
18084
18084
|
} else {
|
|
18085
18085
|
pack = _objectSpread$1(_objectSpread$1({}, pack), resources);
|
|
18086
18086
|
}
|
|
18087
|
-
setPath(this.data,
|
|
18087
|
+
setPath(this.data, path20, pack);
|
|
18088
18088
|
if (!options.silent) this.emit("added", lng, ns, resources);
|
|
18089
18089
|
}
|
|
18090
18090
|
}, {
|
|
@@ -19078,10 +19078,10 @@ var Interpolator = (function() {
|
|
|
19078
19078
|
}
|
|
19079
19079
|
var handleFormat = function handleFormat2(key) {
|
|
19080
19080
|
if (key.indexOf(_this.formatSeparator) < 0) {
|
|
19081
|
-
var
|
|
19082
|
-
return _this.alwaysFormat ? _this.format(
|
|
19081
|
+
var path20 = getPathWithDefaults(data, defaultData, key);
|
|
19082
|
+
return _this.alwaysFormat ? _this.format(path20, void 0, lng, _objectSpread$3(_objectSpread$3(_objectSpread$3({}, options), data), {}, {
|
|
19083
19083
|
interpolationkey: key
|
|
19084
|
-
})) :
|
|
19084
|
+
})) : path20;
|
|
19085
19085
|
}
|
|
19086
19086
|
var p = key.split(_this.formatSeparator);
|
|
19087
19087
|
var k = p.shift().trim();
|
|
@@ -23985,7 +23985,7 @@ function addSharedOptions(command) {
|
|
|
23985
23985
|
"--json",
|
|
23986
23986
|
// i18n: cli.flag.json
|
|
23987
23987
|
"\u4EE5 JSON \u8F93\u51FA"
|
|
23988
|
-
).option("--resource <selector>", "\u9009\u62E9\u672C\u5730\u8D44\u6E90\uFF08id:\u3001name:\
|
|
23988
|
+
).option("--resource <selector>", "\u9009\u62E9\u672C\u5730\u8D44\u6E90\uFF08id:\u3001name:\u3001artifact: \u6216 file:N.json\uFF09");
|
|
23989
23989
|
}
|
|
23990
23990
|
function readSharedOptions(command) {
|
|
23991
23991
|
const raw = command.optsWithGlobals();
|
|
@@ -24273,28 +24273,47 @@ function sha256(content) {
|
|
|
24273
24273
|
function readText(filePath) {
|
|
24274
24274
|
return existsSync3(filePath) ? readFileSync2(filePath, "utf8") : null;
|
|
24275
24275
|
}
|
|
24276
|
-
function
|
|
24276
|
+
function resolveTransactionTarget(cwd, entryPath, allowLegacyIndex = false) {
|
|
24277
|
+
const root = path4.resolve(freelogDir(cwd));
|
|
24278
|
+
const allowed = allowLegacyIndex && entryPath === "index.json" || entryPath === ".sequence" || entryPath === ".pending-operation.json" || /^[1-9]\d*(?:\.version)?\.json$/.test(entryPath);
|
|
24279
|
+
if (!allowed || path4.isAbsolute(entryPath) || entryPath.includes("/") || entryPath.includes("\\")) {
|
|
24280
|
+
throw new CliError("\u672C\u5730\u4E8B\u52A1\u65E5\u5FD7\u5305\u542B\u4E0D\u5141\u8BB8\u7684\u76EE\u6807", "LOCAL_TXN_INVALID");
|
|
24281
|
+
}
|
|
24282
|
+
const target = path4.resolve(root, entryPath);
|
|
24283
|
+
if (path4.dirname(target) !== root) {
|
|
24284
|
+
throw new CliError("\u672C\u5730\u4E8B\u52A1\u65E5\u5FD7\u5305\u542B\u8D8A\u754C\u76EE\u6807", "LOCAL_TXN_INVALID");
|
|
24285
|
+
}
|
|
24286
|
+
return target;
|
|
24287
|
+
}
|
|
24288
|
+
function validateTransaction(cwd, raw) {
|
|
24277
24289
|
const value = raw;
|
|
24278
24290
|
if (value?.schemaVersion !== 1 || !Array.isArray(value.entries) || value.entries.length === 0) {
|
|
24279
24291
|
throw new CliError("\u672C\u5730\u4E8B\u52A1\u65E5\u5FD7\u65E0\u6548\uFF0C\u8BF7\u5148\u5907\u4EFD .freelog \u540E\u5904\u7406", "LOCAL_TXN_INVALID");
|
|
24280
24292
|
}
|
|
24293
|
+
const targets = /* @__PURE__ */ new Set();
|
|
24281
24294
|
for (const entry2 of value.entries) {
|
|
24282
24295
|
if (!entry2 || typeof entry2.path !== "string" || entry2.before !== null && typeof entry2.before !== "string" || entry2.after !== null && typeof entry2.after !== "string" || entry2.beforeSha256 !== sha256(entry2.before) || entry2.afterSha256 !== sha256(entry2.after)) {
|
|
24283
24296
|
throw new CliError("\u672C\u5730\u4E8B\u52A1\u65E5\u5FD7\u6821\u9A8C\u5931\u8D25\uFF0C\u8BF7\u5148\u5907\u4EFD .freelog \u540E\u5904\u7406", "LOCAL_TXN_INVALID");
|
|
24284
24297
|
}
|
|
24298
|
+
const target = resolveTransactionTarget(cwd, entry2.path, true);
|
|
24299
|
+
if (targets.has(target)) {
|
|
24300
|
+
throw new CliError("\u672C\u5730\u4E8B\u52A1\u65E5\u5FD7\u5305\u542B\u91CD\u590D\u76EE\u6807", "LOCAL_TXN_INVALID");
|
|
24301
|
+
}
|
|
24302
|
+
targets.add(target);
|
|
24285
24303
|
}
|
|
24286
24304
|
return value;
|
|
24287
24305
|
}
|
|
24288
|
-
function applyEntry(entry2) {
|
|
24289
|
-
const
|
|
24306
|
+
function applyEntry(cwd, entry2) {
|
|
24307
|
+
const target = resolveTransactionTarget(cwd, entry2.path, true);
|
|
24308
|
+
const current = readText(target);
|
|
24290
24309
|
if (current === entry2.after) return;
|
|
24291
24310
|
if (current !== entry2.before) {
|
|
24292
|
-
throw new CliError(`\u672C\u5730\u4E8B\u52A1\u4E0E ${
|
|
24311
|
+
throw new CliError(`\u672C\u5730\u4E8B\u52A1\u4E0E ${entry2.path} \u51B2\u7A81\uFF0C\u62D2\u7EDD\u731C\u6D4B\u8986\u76D6`, "LOCAL_TXN_CONFLICT");
|
|
24293
24312
|
}
|
|
24294
24313
|
if (entry2.after === null) {
|
|
24295
|
-
if (existsSync3(
|
|
24314
|
+
if (existsSync3(target)) unlinkSync2(target);
|
|
24296
24315
|
} else {
|
|
24297
|
-
atomicWriteFile(
|
|
24316
|
+
atomicWriteFile(target, entry2.after);
|
|
24298
24317
|
}
|
|
24299
24318
|
}
|
|
24300
24319
|
function recoverPendingTransaction(cwd) {
|
|
@@ -24306,23 +24325,25 @@ function recoverPendingTransaction(cwd) {
|
|
|
24306
24325
|
} catch {
|
|
24307
24326
|
throw new CliError("\u672C\u5730\u4E8B\u52A1\u65E5\u5FD7\u65E0\u6CD5\u89E3\u6790\uFF0C\u8BF7\u5148\u5907\u4EFD .freelog \u540E\u5904\u7406", "LOCAL_TXN_INVALID");
|
|
24308
24327
|
}
|
|
24309
|
-
const transaction2 = validateTransaction(raw);
|
|
24310
|
-
for (const entry2 of transaction2.entries) applyEntry(entry2);
|
|
24328
|
+
const transaction2 = validateTransaction(cwd, raw);
|
|
24329
|
+
for (const entry2 of transaction2.entries) applyEntry(cwd, entry2);
|
|
24311
24330
|
unlinkSync2(txnPath);
|
|
24312
24331
|
}
|
|
24313
24332
|
function commitLocalTransaction(cwd, changes) {
|
|
24314
24333
|
if (changes.length === 0) return;
|
|
24315
|
-
const root =
|
|
24334
|
+
const root = path4.resolve(freelogDir(cwd));
|
|
24316
24335
|
const paths = /* @__PURE__ */ new Set();
|
|
24317
24336
|
const entries = changes.map((change) => {
|
|
24318
24337
|
const target = path4.resolve(change.path);
|
|
24319
|
-
if (
|
|
24338
|
+
if (path4.dirname(target) !== root || paths.has(target)) {
|
|
24320
24339
|
throw new CliError("\u672C\u5730\u4E8B\u52A1\u76EE\u6807\u65E0\u6548", "LOCAL_TXN_INVALID");
|
|
24321
24340
|
}
|
|
24341
|
+
const relativePath = path4.basename(target);
|
|
24342
|
+
resolveTransactionTarget(cwd, relativePath);
|
|
24322
24343
|
paths.add(target);
|
|
24323
24344
|
const before = readText(target);
|
|
24324
24345
|
return {
|
|
24325
|
-
path:
|
|
24346
|
+
path: relativePath,
|
|
24326
24347
|
before,
|
|
24327
24348
|
beforeSha256: sha256(before),
|
|
24328
24349
|
after: change.content,
|
|
@@ -24332,7 +24353,7 @@ function commitLocalTransaction(cwd, changes) {
|
|
|
24332
24353
|
if (entries.length === 0) return;
|
|
24333
24354
|
atomicWriteFile(transactionFilePath(cwd), `${JSON.stringify({ schemaVersion: 1, entries }, null, 2)}
|
|
24334
24355
|
`);
|
|
24335
|
-
for (const entry2 of entries) applyEntry(entry2);
|
|
24356
|
+
for (const entry2 of entries) applyEntry(cwd, entry2);
|
|
24336
24357
|
unlinkSync2(transactionFilePath(cwd));
|
|
24337
24358
|
}
|
|
24338
24359
|
|
|
@@ -24456,6 +24477,7 @@ var IDENTITY_FILE_RE = /^([1-9]\d*)\.json$/;
|
|
|
24456
24477
|
var inputFields = {
|
|
24457
24478
|
subject: z2.literal("resource"),
|
|
24458
24479
|
resourceId: z2.string().min(1).optional(),
|
|
24480
|
+
resourceName: z2.string().min(1).optional(),
|
|
24459
24481
|
name: z2.string().min(1).optional(),
|
|
24460
24482
|
title: z2.string().min(1).optional(),
|
|
24461
24483
|
typeCode: z2.string().min(1),
|
|
@@ -24469,9 +24491,10 @@ var storedSchema = z2.object({
|
|
|
24469
24491
|
...inputFields
|
|
24470
24492
|
}).strict().superRefine((identity, ctx) => {
|
|
24471
24493
|
const hasResourceId = identity.resourceId !== void 0;
|
|
24494
|
+
const hasResourceName = identity.resourceName !== void 0;
|
|
24472
24495
|
const hasName = identity.name !== void 0;
|
|
24473
24496
|
const hasTitle = identity.title !== void 0;
|
|
24474
|
-
const bound = hasResourceId || hasName || hasTitle;
|
|
24497
|
+
const bound = hasResourceId || hasResourceName || hasName || hasTitle;
|
|
24475
24498
|
if (hasResourceId !== hasName) {
|
|
24476
24499
|
ctx.addIssue({
|
|
24477
24500
|
code: ZodIssueCode.custom,
|
|
@@ -24479,8 +24502,11 @@ var storedSchema = z2.object({
|
|
|
24479
24502
|
message: "\u7ED1\u5B9A\u8EAB\u4EFD\u5FC5\u987B\u540C\u65F6\u5305\u542B resourceId \u548C name"
|
|
24480
24503
|
});
|
|
24481
24504
|
}
|
|
24482
|
-
if (!hasResourceId
|
|
24483
|
-
ctx.addIssue({ code: ZodIssueCode.custom, path: ["
|
|
24505
|
+
if (hasResourceName && (!hasResourceId || !hasName)) {
|
|
24506
|
+
ctx.addIssue({ code: ZodIssueCode.custom, path: ["resourceName"], message: "\u5B8C\u6574\u8D44\u6E90\u6807\u8BC6\u53EA\u80FD\u5C5E\u4E8E\u5DF2\u7ED1\u5B9A\u8EAB\u4EFD" });
|
|
24507
|
+
}
|
|
24508
|
+
if (!hasResourceId && !hasName && (hasTitle || hasResourceName)) {
|
|
24509
|
+
ctx.addIssue({ code: ZodIssueCode.custom, path: [hasTitle ? "title" : "resourceName"], message: "\u672A\u7ED1\u5B9A\u8EAB\u4EFD\u4E0D\u80FD\u5199\u5165\u7ED1\u5B9A\u7F13\u5B58" });
|
|
24484
24510
|
}
|
|
24485
24511
|
if (!bound && identity.env !== void 0) {
|
|
24486
24512
|
ctx.addIssue({
|
|
@@ -24496,6 +24522,9 @@ function freelogDir(cwd) {
|
|
|
24496
24522
|
function identityFilePath(cwd, n) {
|
|
24497
24523
|
return path6.join(freelogDir(cwd), `${n}.json`);
|
|
24498
24524
|
}
|
|
24525
|
+
function identitySequenceFilePath(cwd) {
|
|
24526
|
+
return path6.join(freelogDir(cwd), ".sequence");
|
|
24527
|
+
}
|
|
24499
24528
|
function assertIdentityNumber(n) {
|
|
24500
24529
|
if (!Number.isInteger(n) || n < 1) {
|
|
24501
24530
|
throw new CliError("\u8EAB\u4EFD\u7F16\u53F7\u65E0\u6548", "IDENTITY_INVALID");
|
|
@@ -24516,7 +24545,7 @@ function throwZodAsCliError(error2) {
|
|
|
24516
24545
|
if (field === "subject") {
|
|
24517
24546
|
throw new CliError("\u672C\u671F\u53EA\u652F\u6301\u5355\u8D44\u6E90", "IDENTITY_SUBJECT_UNSUPPORTED");
|
|
24518
24547
|
}
|
|
24519
|
-
if (field === "name" || field === "resourceId" || field === "title") {
|
|
24548
|
+
if (field === "name" || field === "resourceName" || field === "resourceId" || field === "title") {
|
|
24520
24549
|
throw new CliError("\u7ED1\u5B9A\u8EAB\u4EFD\u5B57\u6BB5\u4E0D\u5B8C\u6574", "IDENTITY_BINDING_INVALID");
|
|
24521
24550
|
}
|
|
24522
24551
|
if (field === "filePath") {
|
|
@@ -24529,6 +24558,7 @@ function toStored(data) {
|
|
|
24529
24558
|
schemaVersion: 1,
|
|
24530
24559
|
subject: data.subject,
|
|
24531
24560
|
...data.resourceId ? { resourceId: data.resourceId } : {},
|
|
24561
|
+
...data.resourceName ? { resourceName: data.resourceName } : {},
|
|
24532
24562
|
...data.name ? { name: data.name } : {},
|
|
24533
24563
|
...data.title ? { title: data.title } : {},
|
|
24534
24564
|
typeCode: data.typeCode,
|
|
@@ -24548,6 +24578,7 @@ function toDiskObject(identity) {
|
|
|
24548
24578
|
schemaVersion: 1,
|
|
24549
24579
|
subject: identity.subject,
|
|
24550
24580
|
...identity.resourceId ? { resourceId: identity.resourceId } : {},
|
|
24581
|
+
...identity.resourceName ? { resourceName: identity.resourceName } : {},
|
|
24551
24582
|
...identity.name ? { name: identity.name } : {},
|
|
24552
24583
|
...identity.title ? { title: identity.title } : {},
|
|
24553
24584
|
typeCode: identity.typeCode,
|
|
@@ -24575,6 +24606,7 @@ function prepareIdentityUpdate(cwd, n, patch) {
|
|
|
24575
24606
|
const identity = normalize({
|
|
24576
24607
|
subject: parsed.subject ?? current.subject,
|
|
24577
24608
|
resourceId: parsed.resourceId ?? current.resourceId,
|
|
24609
|
+
resourceName: parsed.resourceName ?? current.resourceName,
|
|
24578
24610
|
name: parsed.name ?? current.name,
|
|
24579
24611
|
title: parsed.title ?? current.title,
|
|
24580
24612
|
typeCode: parsed.typeCode ?? current.typeCode,
|
|
@@ -24585,7 +24617,23 @@ function prepareIdentityUpdate(cwd, n, patch) {
|
|
|
24585
24617
|
}
|
|
24586
24618
|
function prepareIdentityCreate(cwd, input2) {
|
|
24587
24619
|
const numbers = listIdentityNumbers(cwd);
|
|
24588
|
-
|
|
24620
|
+
const highestOnDisk = numbers.length === 0 ? 0 : Math.max(...numbers);
|
|
24621
|
+
const sequencePath = identitySequenceFilePath(cwd);
|
|
24622
|
+
let highestAllocated = 0;
|
|
24623
|
+
if (existsSync5(sequencePath)) {
|
|
24624
|
+
const raw = readFileSync4(sequencePath, "utf8").trim();
|
|
24625
|
+
const parsed = Number(raw);
|
|
24626
|
+
if (!/^[1-9]\d*$/.test(raw) || !Number.isSafeInteger(parsed)) {
|
|
24627
|
+
throw new CliError(".freelog/.sequence \u65E0\u6548\uFF0C\u8BF7\u5148\u5907\u4EFD\u540E\u6062\u590D", "IDENTITY_SEQUENCE_INVALID");
|
|
24628
|
+
}
|
|
24629
|
+
highestAllocated = parsed;
|
|
24630
|
+
}
|
|
24631
|
+
return { n: Math.max(highestOnDisk, highestAllocated) + 1, ...parseCreateInput(input2) };
|
|
24632
|
+
}
|
|
24633
|
+
function serializeIdentitySequence(n) {
|
|
24634
|
+
assertIdentityNumber(n);
|
|
24635
|
+
return `${n}
|
|
24636
|
+
`;
|
|
24589
24637
|
}
|
|
24590
24638
|
function parsePatchInput(input2) {
|
|
24591
24639
|
const parsed = patchSchema.safeParse(input2);
|
|
@@ -24631,7 +24679,10 @@ function listIdentities(cwd) {
|
|
|
24631
24679
|
function createIdentity(cwd, input2) {
|
|
24632
24680
|
return withProjectLock(cwd, () => {
|
|
24633
24681
|
const identity = prepareIdentityCreate(cwd, input2);
|
|
24634
|
-
|
|
24682
|
+
commitLocalTransaction(cwd, [
|
|
24683
|
+
{ path: identityFilePath(cwd, identity.n), content: serializeIdentity(identity) },
|
|
24684
|
+
{ path: identitySequenceFilePath(cwd), content: serializeIdentitySequence(identity.n) }
|
|
24685
|
+
]);
|
|
24635
24686
|
return identity;
|
|
24636
24687
|
}, "create-identity");
|
|
24637
24688
|
}
|
|
@@ -24644,7 +24695,7 @@ function updateIdentity(cwd, n, patch) {
|
|
|
24644
24695
|
}
|
|
24645
24696
|
|
|
24646
24697
|
// src/local/resolve.ts
|
|
24647
|
-
import { existsSync as
|
|
24698
|
+
import { existsSync as existsSync8, readdirSync as readdirSync2 } from "fs";
|
|
24648
24699
|
|
|
24649
24700
|
// src/local/draft.ts
|
|
24650
24701
|
import { existsSync as existsSync6, readFileSync as readFileSync5, unlinkSync as unlinkSync4 } from "fs";
|
|
@@ -24765,6 +24816,7 @@ function draftSummary(draft) {
|
|
|
24765
24816
|
|
|
24766
24817
|
// src/local/projectPath.ts
|
|
24767
24818
|
import path8 from "path";
|
|
24819
|
+
import { existsSync as existsSync7, realpathSync } from "fs";
|
|
24768
24820
|
var defaultError = {
|
|
24769
24821
|
code: "FILE_PATH_OUTSIDE_PROJECT",
|
|
24770
24822
|
message: "\u8DEF\u5F84\u5FC5\u987B\u843D\u5728\u5F53\u524D\u5DE5\u7A0B\u91CC"
|
|
@@ -24776,10 +24828,29 @@ function normalizeProjectPath(cwd, rawPath, error2 = defaultError) {
|
|
|
24776
24828
|
const root = path8.resolve(cwd);
|
|
24777
24829
|
const resolved = path8.resolve(root, rawPath);
|
|
24778
24830
|
const relative = path8.relative(root, resolved);
|
|
24779
|
-
|
|
24831
|
+
const normalized = relative.replaceAll("\\", "/");
|
|
24832
|
+
if (!relative || relative.startsWith("..") || path8.isAbsolute(relative) || normalized === ".freelog" || normalized.startsWith(".freelog/")) {
|
|
24833
|
+
throw new CliError(error2.message, error2.code);
|
|
24834
|
+
}
|
|
24835
|
+
return normalized;
|
|
24836
|
+
}
|
|
24837
|
+
function isInside(root, target) {
|
|
24838
|
+
const relative = path8.relative(root, target);
|
|
24839
|
+
return relative !== "" && relative !== ".." && !relative.startsWith(`..${path8.sep}`) && !path8.isAbsolute(relative);
|
|
24840
|
+
}
|
|
24841
|
+
function resolveExistingProjectPath(cwd, filePath, error2 = defaultError) {
|
|
24842
|
+
const root = path8.resolve(cwd);
|
|
24843
|
+
const absolute = path8.resolve(root, filePath);
|
|
24844
|
+
if (!existsSync7(absolute)) {
|
|
24845
|
+
if (!isInside(root, absolute)) throw new CliError(error2.message, error2.code);
|
|
24846
|
+
return absolute;
|
|
24847
|
+
}
|
|
24848
|
+
const realRoot = realpathSync(root);
|
|
24849
|
+
const realTarget = realpathSync(absolute);
|
|
24850
|
+
if (!isInside(realRoot, realTarget)) {
|
|
24780
24851
|
throw new CliError(error2.message, error2.code);
|
|
24781
24852
|
}
|
|
24782
|
-
return
|
|
24853
|
+
return realTarget;
|
|
24783
24854
|
}
|
|
24784
24855
|
|
|
24785
24856
|
// src/local/resolve.ts
|
|
@@ -24799,25 +24870,24 @@ function assertNoDuplicate(cwd, identities, key) {
|
|
|
24799
24870
|
function matches(cwd, identity, selector) {
|
|
24800
24871
|
if (selector.startsWith("file:")) return `${identity.n}.json` === selector.slice(5);
|
|
24801
24872
|
if (selector.startsWith("id:")) return identity.resourceId === selector.slice(3);
|
|
24802
|
-
if (selector.startsWith("name:")) return identity.
|
|
24803
|
-
if (selector.startsWith("title:")) return identity.title === selector.slice(6);
|
|
24873
|
+
if (selector.startsWith("name:")) return identity.resourceName === selector.slice(5);
|
|
24804
24874
|
if (selector.startsWith("artifact:")) {
|
|
24805
24875
|
return normalizeProjectPath(cwd, identity.filePath) === normalizeProjectPath(
|
|
24806
24876
|
cwd,
|
|
24807
24877
|
selector.slice("artifact:".length)
|
|
24808
24878
|
);
|
|
24809
24879
|
}
|
|
24810
|
-
return `${identity.n}.json` === selector || identity.resourceId === selector || identity.
|
|
24880
|
+
return `${identity.n}.json` === selector || identity.resourceId === selector || identity.resourceName === selector;
|
|
24811
24881
|
}
|
|
24812
24882
|
var DRAFT_FILE_RE = /^([1-9]\d*)\.version\.json$/;
|
|
24813
24883
|
function validateLocalState(cwd) {
|
|
24814
24884
|
const identities = listIdentities(cwd);
|
|
24815
24885
|
assertNoDuplicate(cwd, identities, "resourceId");
|
|
24816
|
-
assertNoDuplicate(cwd, identities, "
|
|
24886
|
+
assertNoDuplicate(cwd, identities, "resourceName");
|
|
24817
24887
|
assertNoDuplicate(cwd, identities, "filePath");
|
|
24818
24888
|
const numbers = new Set(identities.map((identity) => identity.n));
|
|
24819
24889
|
const dir = freelogDir(cwd);
|
|
24820
|
-
if (!
|
|
24890
|
+
if (!existsSync8(dir)) return identities;
|
|
24821
24891
|
for (const fileName of readdirSync2(dir)) {
|
|
24822
24892
|
const match = DRAFT_FILE_RE.exec(fileName);
|
|
24823
24893
|
if (!match) continue;
|
|
@@ -24914,6 +24984,15 @@ function unwrapOne(result) {
|
|
|
24914
24984
|
const data = envelope.data ?? result;
|
|
24915
24985
|
return data && typeof data === "object" && !Array.isArray(data) ? data : void 0;
|
|
24916
24986
|
}
|
|
24987
|
+
function normalizeTypeInfo(node) {
|
|
24988
|
+
const support = node.resourceConfig?.supportOptionalConfig ?? node.supportOptionalConfig;
|
|
24989
|
+
if (support === void 0 || support === null || support === "") return node;
|
|
24990
|
+
const numeric = Number(support);
|
|
24991
|
+
return Number.isFinite(numeric) ? { ...node, supportOptionalConfig: numeric } : node;
|
|
24992
|
+
}
|
|
24993
|
+
function supportsOptionalConfig(node) {
|
|
24994
|
+
return Number(node.resourceConfig?.supportOptionalConfig ?? node.supportOptionalConfig) === 2;
|
|
24995
|
+
}
|
|
24917
24996
|
function isEnabledResourceLeaf(node) {
|
|
24918
24997
|
return node.isTerminate === true && node.status === 1 && supportsResourceSubject(node.subjectType);
|
|
24919
24998
|
}
|
|
@@ -24927,13 +25006,18 @@ function supportsResourceSubject(subjectType) {
|
|
|
24927
25006
|
function hasChildren(node) {
|
|
24928
25007
|
return Array.isArray(node.children) && node.children.length > 0;
|
|
24929
25008
|
}
|
|
24930
|
-
function flattenLeaves(nodes2, acc = []) {
|
|
25009
|
+
function flattenLeaves(nodes2, ancestors = [], acc = []) {
|
|
24931
25010
|
for (const node of nodes2) {
|
|
25011
|
+
const path20 = [...ancestors, node];
|
|
24932
25012
|
if (hasChildren(node)) {
|
|
24933
|
-
flattenLeaves(node.children, acc);
|
|
25013
|
+
flattenLeaves(node.children, path20, acc);
|
|
24934
25014
|
}
|
|
24935
25015
|
if (isEnabledResourceLeafCandidate(node)) {
|
|
24936
|
-
|
|
25016
|
+
const names = path20.map((item) => item.name.trim());
|
|
25017
|
+
if (names.some((name) => !name)) {
|
|
25018
|
+
throw new CliError("\u5E73\u53F0\u7C7B\u578B\u94FE\u5B58\u5728\u7F3A\u5931\u540D\u79F0\uFF0C\u65E0\u6CD5\u5C55\u793A\u5B8C\u6574\u5C42\u7EA7", "TYPE_HIERARCHY_INVALID");
|
|
25019
|
+
}
|
|
25020
|
+
acc.push({ ...node, nameChain: names.join(" / ") });
|
|
24937
25021
|
}
|
|
24938
25022
|
}
|
|
24939
25023
|
return acc;
|
|
@@ -24943,18 +25027,58 @@ async function resourceTypeTree(apis) {
|
|
|
24943
25027
|
const request2 = apis.resourceTypes ?? ((params) => service_API_default.Resource.resourceTypes(params));
|
|
24944
25028
|
return unwrapList(await request2({ category: 1, status: 1, subjectType: 1 }));
|
|
24945
25029
|
}
|
|
25030
|
+
function findTypePath(nodes2, code, ancestors = []) {
|
|
25031
|
+
for (const node of nodes2) {
|
|
25032
|
+
const path20 = [...ancestors, node];
|
|
25033
|
+
if (node.code === code) return path20;
|
|
25034
|
+
if (hasChildren(node)) {
|
|
25035
|
+
const found = findTypePath(node.children, code, path20);
|
|
25036
|
+
if (found) return found;
|
|
25037
|
+
}
|
|
25038
|
+
}
|
|
25039
|
+
return void 0;
|
|
25040
|
+
}
|
|
25041
|
+
async function getTypeHierarchy(code, apis = {}) {
|
|
25042
|
+
const normalized = code.trim();
|
|
25043
|
+
if (!normalized) throw new CliError("\u8BF7\u63D0\u4F9B\u8D44\u6E90\u7C7B\u578B\u7F16\u53F7", "TYPE_CODE_REQUIRED");
|
|
25044
|
+
const path20 = findTypePath(await resourceTypeTree(apis), normalized);
|
|
25045
|
+
if (!path20) throw new CliError(`\u5E73\u53F0\u7C7B\u578B\u6811\u4E0D\u5305\u542B\u5F53\u524D\u7C7B\u578B ${normalized}`, "TYPE_HIERARCHY_NOT_FOUND");
|
|
25046
|
+
const names = path20.map((node) => node.name.trim());
|
|
25047
|
+
if (names.some((name) => !name)) {
|
|
25048
|
+
throw new CliError("\u5E73\u53F0\u7C7B\u578B\u94FE\u5B58\u5728\u7F3A\u5931\u540D\u79F0\uFF0C\u65E0\u6CD5\u5C55\u793A\u5B8C\u6574\u5C42\u7EA7", "TYPE_HIERARCHY_INVALID");
|
|
25049
|
+
}
|
|
25050
|
+
return names;
|
|
25051
|
+
}
|
|
24946
25052
|
async function listLeafTypes(apis = {}) {
|
|
24947
25053
|
return flattenLeaves(await resourceTypeTree(apis));
|
|
24948
25054
|
}
|
|
24949
25055
|
async function searchLeafTypes(keyword, apis = {}) {
|
|
24950
25056
|
assertPlatformAllowed();
|
|
24951
25057
|
const request2 = apis.searchLeaves ?? ((params) => service_API_default.Resource.ListSimpleByParentCode(params));
|
|
24952
|
-
|
|
24953
|
-
|
|
24954
|
-
|
|
24955
|
-
|
|
24956
|
-
|
|
24957
|
-
|
|
25058
|
+
const [tree, response] = await Promise.all([
|
|
25059
|
+
resourceTypeTree(apis),
|
|
25060
|
+
request2({
|
|
25061
|
+
category: 1,
|
|
25062
|
+
nameChain: keyword,
|
|
25063
|
+
isTerminate: true,
|
|
25064
|
+
status: 1,
|
|
25065
|
+
subjectType: 1
|
|
25066
|
+
})
|
|
25067
|
+
]);
|
|
25068
|
+
const codes = /* @__PURE__ */ new Set();
|
|
25069
|
+
return unwrapList(response).flatMap((item) => {
|
|
25070
|
+
if (!item.code || codes.has(item.code)) return [];
|
|
25071
|
+
codes.add(item.code);
|
|
25072
|
+
const path20 = findTypePath(tree, item.code);
|
|
25073
|
+
if (!path20) return [];
|
|
25074
|
+
const leaf = path20[path20.length - 1];
|
|
25075
|
+
if (!isEnabledResourceLeafCandidate(leaf)) return [];
|
|
25076
|
+
const names = path20.map((node) => node.name.trim());
|
|
25077
|
+
if (names.some((name) => !name)) {
|
|
25078
|
+
throw new CliError("\u5E73\u53F0\u7C7B\u578B\u94FE\u5B58\u5728\u7F3A\u5931\u540D\u79F0\uFF0C\u65E0\u6CD5\u5C55\u793A\u5B8C\u6574\u5C42\u7EA7", "TYPE_HIERARCHY_INVALID");
|
|
25079
|
+
}
|
|
25080
|
+
return [{ ...leaf, nameChain: names.join(" / ") }];
|
|
25081
|
+
});
|
|
24958
25082
|
}
|
|
24959
25083
|
async function getTypeInfo(code, apis = {}) {
|
|
24960
25084
|
const normalized = code.trim();
|
|
@@ -24963,7 +25087,8 @@ async function getTypeInfo(code, apis = {}) {
|
|
|
24963
25087
|
}
|
|
24964
25088
|
assertPlatformAllowed();
|
|
24965
25089
|
const request2 = apis.getByCode ?? ((params) => service_API_default.Resource.getResourceTypeInfoByCode(params));
|
|
24966
|
-
const
|
|
25090
|
+
const rawInfo = unwrapOne(await request2({ code: normalized }));
|
|
25091
|
+
const info2 = rawInfo ? normalizeTypeInfo(rawInfo) : void 0;
|
|
24967
25092
|
if (!info2?.code) {
|
|
24968
25093
|
throw new CliError(`\u627E\u4E0D\u5230\u7C7B\u578B ${normalized}`, "TYPE_NOT_FOUND");
|
|
24969
25094
|
}
|
|
@@ -25027,13 +25152,41 @@ async function chooseLeafType(apis = {}) {
|
|
|
25027
25152
|
}
|
|
25028
25153
|
throw new CliError("\u5DF2\u53D6\u6D88\u8D44\u6E90\u7C7B\u578B\u9009\u62E9", "TYPE_PICK_CANCELLED");
|
|
25029
25154
|
}
|
|
25155
|
+
var TYPE_LIST_PAGE_SIZE = 50;
|
|
25156
|
+
function typeListPage(items, page) {
|
|
25157
|
+
const pageCount = Math.max(1, Math.ceil(items.length / TYPE_LIST_PAGE_SIZE));
|
|
25158
|
+
if (!Number.isInteger(page) || page < 1 || page > pageCount) {
|
|
25159
|
+
throw new CliError(`\u7C7B\u578B\u9875\u7801\u8D85\u51FA\u8303\u56F4\uFF0C\u5F53\u524D\u5171 ${pageCount} \u9875`, "TYPE_LIST_PAGE");
|
|
25160
|
+
}
|
|
25161
|
+
return {
|
|
25162
|
+
page,
|
|
25163
|
+
pageCount,
|
|
25164
|
+
total: items.length,
|
|
25165
|
+
hasPrevious: page > 1,
|
|
25166
|
+
hasNext: page < pageCount,
|
|
25167
|
+
items: items.slice((page - 1) * TYPE_LIST_PAGE_SIZE, page * TYPE_LIST_PAGE_SIZE)
|
|
25168
|
+
};
|
|
25169
|
+
}
|
|
25030
25170
|
function formatTypeList(items) {
|
|
25031
25171
|
return items.map((item) => `${item.code} ${item.nameChain ?? item.name}`).join("\n");
|
|
25032
25172
|
}
|
|
25173
|
+
function formatTypeListPage(page) {
|
|
25174
|
+
const header = `\u7B2C ${page.page}/${page.pageCount} \u9875\uFF0C\u5171 ${page.total} \u4E2A\u53EF\u7528\u6700\u7EC8\u53F6\u5B50\u7C7B\u578B`;
|
|
25175
|
+
const rows = formatTypeList(page.items);
|
|
25176
|
+
return rows ? `${header}
|
|
25177
|
+
${rows}` : `${header}
|
|
25178
|
+
\u6CA1\u6709\u5339\u914D\u7684\u542F\u7528\u6700\u7EC8\u53F6\u5B50\u7C7B\u578B`;
|
|
25179
|
+
}
|
|
25180
|
+
function formatTypeInfo(item, hierarchy) {
|
|
25181
|
+
const optionalConfig = supportsOptionalConfig(item) ? "\u652F\u6301" : "\u4E0D\u652F\u6301";
|
|
25182
|
+
const label = hierarchy?.join(" / ") || item.nameChain || item.name;
|
|
25183
|
+
return `${item.code} ${label} \u53EF\u9009\u914D\u7F6E\uFF1A${optionalConfig}`;
|
|
25184
|
+
}
|
|
25033
25185
|
|
|
25034
25186
|
// src/domain/version/zip.ts
|
|
25035
|
-
import { createWriteStream, existsSync as
|
|
25187
|
+
import { createWriteStream, existsSync as existsSync9, lstatSync, readFileSync as readFileSync6, readdirSync as readdirSync3, statSync, unlinkSync as unlinkSync5 } from "fs";
|
|
25036
25188
|
import { tmpdir } from "os";
|
|
25189
|
+
import { randomUUID } from "crypto";
|
|
25037
25190
|
import path9 from "path";
|
|
25038
25191
|
import { finished } from "stream/promises";
|
|
25039
25192
|
import archiver from "archiver";
|
|
@@ -25041,56 +25194,83 @@ function isThemeOrWidget(typeCode) {
|
|
|
25041
25194
|
return typeCode === "RT001" || typeCode === "RT002";
|
|
25042
25195
|
}
|
|
25043
25196
|
function assertArtifactPath(typeCode, filePath) {
|
|
25044
|
-
const stats =
|
|
25197
|
+
const stats = existsSync9(filePath) ? statSync(filePath) : void 0;
|
|
25045
25198
|
const themeOrWidget = isThemeOrWidget(typeCode);
|
|
25046
25199
|
if (stats?.isDirectory() && !themeOrWidget) {
|
|
25047
25200
|
throw new CliError("\u4E0D\u652F\u6301\u6587\u4EF6\u5939\uFF0C\u8BF7\u6307\u5B9A\u4E00\u4E2A\u6587\u4EF6\u3002", "FILE_DIRECTORY_UNSUPPORTED");
|
|
25048
25201
|
}
|
|
25049
25202
|
}
|
|
25050
|
-
function assertArtifactAnchor(typeCode, filePath) {
|
|
25051
|
-
if (!
|
|
25203
|
+
function assertArtifactAnchor(typeCode, filePath, cwd) {
|
|
25204
|
+
if (!existsSync9(filePath)) {
|
|
25052
25205
|
throw new CliError(`\u672C\u5730\u4EA7\u7269\u4E0D\u5B58\u5728\uFF1A${filePath}`, "ARTIFACT_ANCHOR_MISSING");
|
|
25053
25206
|
}
|
|
25207
|
+
if (cwd) resolveExistingProjectPath(cwd, filePath);
|
|
25054
25208
|
const stats = statSync(filePath);
|
|
25055
25209
|
assertArtifactPath(typeCode, filePath);
|
|
25056
25210
|
if (!isThemeOrWidget(typeCode) && !stats.isFile()) {
|
|
25057
25211
|
throw new CliError("\u4E0D\u652F\u6301\u6587\u4EF6\u5939\uFF0C\u8BF7\u6307\u5B9A\u4E00\u4E2A\u6587\u4EF6\u3002", "FILE_DIRECTORY_UNSUPPORTED");
|
|
25058
25212
|
}
|
|
25059
25213
|
}
|
|
25060
|
-
|
|
25061
|
-
if (
|
|
25214
|
+
function assertUploadArtifactReady(typeCode, filePath, cwd) {
|
|
25215
|
+
if (cwd) resolveExistingProjectPath(cwd, filePath);
|
|
25216
|
+
assertArtifactPath(typeCode, filePath);
|
|
25217
|
+
const stats = existsSync9(filePath) ? statSync(filePath) : void 0;
|
|
25218
|
+
if (!stats) {
|
|
25219
|
+
throw new CliError(`\u672C\u5730\u4EA7\u7269\u4E0D\u5B58\u5728\uFF1A${filePath}`, "ARTIFACT_ANCHOR_MISSING");
|
|
25220
|
+
}
|
|
25221
|
+
if (stats.isDirectory() && isThemeOrWidget(typeCode)) {
|
|
25222
|
+
assertZipDirectoryReady(filePath);
|
|
25223
|
+
return;
|
|
25224
|
+
}
|
|
25225
|
+
if (!stats.isFile()) {
|
|
25226
|
+
throw new CliError("\u4EA7\u7269\u5FC5\u987B\u662F\u6587\u4EF6\uFF0C\u6216\u4E3B\u9898/\u63D2\u4EF6\u7684\u975E\u7A7A\u6784\u5EFA\u76EE\u5F55\u3002", "FILE_ARTIFACT_UNSUPPORTED");
|
|
25227
|
+
}
|
|
25228
|
+
}
|
|
25229
|
+
function assertZipDirectoryReady(dir) {
|
|
25230
|
+
if (!existsSync9(dir) || !statSync(dir).isDirectory()) {
|
|
25062
25231
|
throw new CliError(`\u6CA1\u6709\u6784\u5EFA\u4EA7\u7269 ${dir}\uFF0C\u8BF7\u5148\u6784\u5EFA`, "ZIP_MISSING");
|
|
25063
25232
|
}
|
|
25064
|
-
if (
|
|
25233
|
+
if (existsSync9(path9.join(dir, ".freelog"))) {
|
|
25065
25234
|
throw new CliError("\u4E0D\u8981\u628A\u5DE5\u7A0B\u6839\u5F53\u4EA7\u7269\u76EE\u5F55\uFF0C\u8BF7\u6307\u5B9A dist \u6216 build\u3002", "ZIP_PROJECT_ROOT");
|
|
25066
25235
|
}
|
|
25067
|
-
|
|
25068
|
-
if (entries.length === 0) {
|
|
25236
|
+
if (readdirSync3(dir).length === 0) {
|
|
25069
25237
|
throw new CliError("\u6784\u5EFA\u4EA7\u7269\u662F\u7A7A\u7684\uFF0C\u8BF7\u5148\u6784\u5EFA", "ZIP_EMPTY");
|
|
25070
25238
|
}
|
|
25239
|
+
}
|
|
25240
|
+
async function zipDirectoryContents(dir) {
|
|
25241
|
+
assertZipDirectoryReady(dir);
|
|
25071
25242
|
const outPath = path9.join(
|
|
25072
25243
|
tmpdir(),
|
|
25073
|
-
`freelog-zip-${process.pid}-${
|
|
25244
|
+
`freelog-zip-${process.pid}-${randomUUID()}.zip`
|
|
25074
25245
|
);
|
|
25075
25246
|
const output2 = createWriteStream(outPath);
|
|
25076
25247
|
const archive = archiver("zip", { zlib: { level: 9 } });
|
|
25077
25248
|
try {
|
|
25078
25249
|
archive.on("error", (error2) => output2.destroy(error2));
|
|
25079
25250
|
archive.pipe(output2);
|
|
25080
|
-
|
|
25081
|
-
const
|
|
25082
|
-
|
|
25083
|
-
|
|
25084
|
-
|
|
25085
|
-
|
|
25086
|
-
|
|
25251
|
+
const appendEntries = (currentDir, prefix = "") => {
|
|
25252
|
+
for (const entry2 of readdirSync3(currentDir).sort((left, right) => left < right ? -1 : left > right ? 1 : 0)) {
|
|
25253
|
+
const full = path9.join(currentDir, entry2);
|
|
25254
|
+
const stats = lstatSync(full);
|
|
25255
|
+
const entryName = prefix ? `${prefix}/${entry2}` : entry2;
|
|
25256
|
+
if (stats.isSymbolicLink()) {
|
|
25257
|
+
throw new CliError(`\u6784\u5EFA\u76EE\u5F55\u4E0D\u80FD\u5305\u542B\u8F6F\u94FE\u63A5\uFF1A${entryName}`, "ZIP_SYMLINK_UNSUPPORTED");
|
|
25258
|
+
}
|
|
25259
|
+
if (stats.isDirectory()) {
|
|
25260
|
+
appendEntries(full, entryName);
|
|
25261
|
+
} else if (stats.isFile()) {
|
|
25262
|
+
archive.append(readFileSync6(full), { name: entryName });
|
|
25263
|
+
} else {
|
|
25264
|
+
throw new CliError(`\u6784\u5EFA\u76EE\u5F55\u5305\u542B\u4E0D\u652F\u6301\u7684\u6761\u76EE\uFF1A${entryName}`, "ZIP_ENTRY_UNSUPPORTED");
|
|
25265
|
+
}
|
|
25087
25266
|
}
|
|
25088
|
-
}
|
|
25267
|
+
};
|
|
25268
|
+
appendEntries(dir);
|
|
25089
25269
|
await archive.finalize();
|
|
25090
25270
|
await finished(output2);
|
|
25091
25271
|
return outPath;
|
|
25092
25272
|
} catch (error2) {
|
|
25093
|
-
if (
|
|
25273
|
+
if (existsSync9(outPath)) {
|
|
25094
25274
|
try {
|
|
25095
25275
|
unlinkSync5(outPath);
|
|
25096
25276
|
} catch {
|
|
@@ -25099,9 +25279,9 @@ async function zipDirectoryContents(dir) {
|
|
|
25099
25279
|
throw error2;
|
|
25100
25280
|
}
|
|
25101
25281
|
}
|
|
25102
|
-
async function prepareUploadPath(typeCode, filePath) {
|
|
25103
|
-
|
|
25104
|
-
if (isThemeOrWidget(typeCode) &&
|
|
25282
|
+
async function prepareUploadPath(typeCode, filePath, cwd) {
|
|
25283
|
+
assertUploadArtifactReady(typeCode, filePath, cwd);
|
|
25284
|
+
if (isThemeOrWidget(typeCode) && existsSync9(filePath) && statSync(filePath).isDirectory()) {
|
|
25105
25285
|
return zipDirectoryContents(filePath);
|
|
25106
25286
|
}
|
|
25107
25287
|
return filePath;
|
|
@@ -25164,6 +25344,9 @@ function validateCreateFlags(input2) {
|
|
|
25164
25344
|
function resolveTargetIdentity(input2) {
|
|
25165
25345
|
if (input2.selector) return resolveIdentity(input2.cwd, input2.selector);
|
|
25166
25346
|
const unbound = input2.identities.filter((identity) => !identity.resourceId);
|
|
25347
|
+
if (input2.artifact !== void 0) {
|
|
25348
|
+
return unbound.find((identity) => identity.filePath === input2.artifact);
|
|
25349
|
+
}
|
|
25167
25350
|
if (unbound.length === 1) return unbound[0];
|
|
25168
25351
|
if (unbound.length > 1) throw new CliError("\u5F53\u524D\u5DE5\u7A0B\u6709\u591A\u4EFD\u672A\u7ED1\u5B9A\u8D44\u6E90\u72B6\u6001\uFF1B\u8BF7\u4F7F\u7528 --resource \u6307\u5B9A\u8D44\u6E90", "IDENTITY_RESOURCE_REQUIRED");
|
|
25169
25352
|
return void 0;
|
|
@@ -25177,7 +25360,8 @@ async function assertOwnShellAvailable(input2) {
|
|
|
25177
25360
|
if (!existing.resourceId) {
|
|
25178
25361
|
return;
|
|
25179
25362
|
}
|
|
25180
|
-
|
|
25363
|
+
const ownerId = existing.userId ?? existing.ownerId ?? existing.creatorId;
|
|
25364
|
+
if (ownerId !== input2.authUserId) {
|
|
25181
25365
|
throw new CliError(
|
|
25182
25366
|
`\u8D44\u6E90\u6388\u6743\u6807\u8BC6 ${input2.name} \u5DF2\u88AB\u4F7F\u7528\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165\u3002`,
|
|
25183
25367
|
"CREATE_NAME_TAKEN"
|
|
@@ -25193,6 +25377,7 @@ function writeCreatedIdentity(input2) {
|
|
|
25193
25377
|
if (!filePath) throw new CliError("\u65B0\u8D44\u6E90\u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "CREATE_ARTIFACT_REQUIRED");
|
|
25194
25378
|
const patch = {
|
|
25195
25379
|
resourceId: input2.resourceId,
|
|
25380
|
+
resourceName: input2.resourceName,
|
|
25196
25381
|
name: input2.name,
|
|
25197
25382
|
title: input2.title,
|
|
25198
25383
|
typeCode: input2.typeCode,
|
|
@@ -25202,6 +25387,7 @@ function writeCreatedIdentity(input2) {
|
|
|
25202
25387
|
return input2.target ? updateIdentity(input2.cwd, input2.target.n, patch) : createIdentity(input2.cwd, {
|
|
25203
25388
|
subject: "resource",
|
|
25204
25389
|
resourceId: input2.resourceId,
|
|
25390
|
+
resourceName: input2.resourceName,
|
|
25205
25391
|
name: input2.name,
|
|
25206
25392
|
title: input2.title,
|
|
25207
25393
|
typeCode: input2.typeCode,
|
|
@@ -25212,7 +25398,6 @@ function writeCreatedIdentity(input2) {
|
|
|
25212
25398
|
async function createResource(input2) {
|
|
25213
25399
|
assertPlatformAllowed();
|
|
25214
25400
|
const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
25215
|
-
validateLocalState(input2.cwd);
|
|
25216
25401
|
const { title, name } = validateCreateFlags(input2);
|
|
25217
25402
|
const file = input2.file !== void 0 ? normalizeProjectPath(input2.cwd, input2.file, {
|
|
25218
25403
|
code: "CREATE_FILE_OUTSIDE",
|
|
@@ -25223,6 +25408,7 @@ async function createResource(input2) {
|
|
|
25223
25408
|
const target = resolveTargetIdentity({
|
|
25224
25409
|
cwd: input2.cwd,
|
|
25225
25410
|
selector: input2.selector,
|
|
25411
|
+
artifact: file,
|
|
25226
25412
|
identities
|
|
25227
25413
|
});
|
|
25228
25414
|
const occupant = file ? identities.find((identity) => identity.filePath === file && identity.n !== target?.n) : void 0;
|
|
@@ -25248,7 +25434,7 @@ async function createResource(input2) {
|
|
|
25248
25434
|
}
|
|
25249
25435
|
const typeCode = resolveTypeCode(input2.type, target);
|
|
25250
25436
|
await getTypeInfo(typeCode, input2.apis);
|
|
25251
|
-
assertArtifactAnchor(typeCode, path10.resolve(input2.cwd, artifact));
|
|
25437
|
+
assertArtifactAnchor(typeCode, path10.resolve(input2.cwd, artifact), input2.cwd);
|
|
25252
25438
|
await assertOwnShellAvailable({
|
|
25253
25439
|
authLoginName: auth.loginName,
|
|
25254
25440
|
authUserId: auth.userId,
|
|
@@ -25271,6 +25457,7 @@ async function createResource(input2) {
|
|
|
25271
25457
|
cwd: input2.cwd,
|
|
25272
25458
|
env: getEnv2(),
|
|
25273
25459
|
name,
|
|
25460
|
+
resourceName: typeof created.resourceName === "string" && created.resourceName ? created.resourceName : `${auth.loginName}/${name}`,
|
|
25274
25461
|
typeCode,
|
|
25275
25462
|
resourceId,
|
|
25276
25463
|
title,
|
|
@@ -25318,6 +25505,10 @@ function createCreateCommand() {
|
|
|
25318
25505
|
// src/commands/listing/update.ts
|
|
25319
25506
|
import { Command as Command5 } from "commander";
|
|
25320
25507
|
|
|
25508
|
+
// src/domain/listing/update.ts
|
|
25509
|
+
import { existsSync as existsSync10, readFileSync as readFileSync7, statSync as statSync2 } from "fs";
|
|
25510
|
+
import path11 from "path";
|
|
25511
|
+
|
|
25321
25512
|
// src/domain/version/gates.ts
|
|
25322
25513
|
function evaluateGates(input2, intent) {
|
|
25323
25514
|
const latest = input2.latestVersion;
|
|
@@ -25359,19 +25550,170 @@ function resolveBoundIdentity(cwd, file) {
|
|
|
25359
25550
|
if (!identity.resourceId) {
|
|
25360
25551
|
throw new CliError("\u8BF7\u5148 create \u6216 bind", "GATE_NO_RESOURCE");
|
|
25361
25552
|
}
|
|
25553
|
+
const identityEnv = identity.env ?? "prod";
|
|
25554
|
+
const activeEnv2 = getEnv2();
|
|
25555
|
+
if (identityEnv !== activeEnv2) {
|
|
25556
|
+
throw new CliError(
|
|
25557
|
+
`\u8D44\u6E90 ${identity.n}.json \u5C5E\u4E8E ${identityEnv} \u73AF\u5883\uFF0C\u672C\u6B21\u662F ${activeEnv2}\uFF1B\u8BF7\u5207\u6362 --env \u6216\u9009\u62E9\u8BE5\u73AF\u5883\u7684\u8D44\u6E90\u72B6\u6001`,
|
|
25558
|
+
"RESOURCE_ENV_MISMATCH"
|
|
25559
|
+
);
|
|
25560
|
+
}
|
|
25362
25561
|
return identity;
|
|
25363
25562
|
}
|
|
25563
|
+
function assertRemoteResourceWritable(input2) {
|
|
25564
|
+
const codes = {
|
|
25565
|
+
invalid: input2.codes?.invalid ?? "RESOURCE_WRITE_INFO_INVALID",
|
|
25566
|
+
notOwner: input2.codes?.notOwner ?? "RESOURCE_NOT_OWNER",
|
|
25567
|
+
frozen: input2.codes?.frozen ?? "RESOURCE_FROZEN"
|
|
25568
|
+
};
|
|
25569
|
+
assertRemoteResourceOwned({
|
|
25570
|
+
info: input2.info,
|
|
25571
|
+
resourceId: input2.resourceId,
|
|
25572
|
+
authUserId: input2.authUserId,
|
|
25573
|
+
codes
|
|
25574
|
+
});
|
|
25575
|
+
if (input2.info.status === 2 || input2.info.isFrozen === true) {
|
|
25576
|
+
throw new CliError("\u8D44\u6E90\u5DF2\u88AB\u51BB\u7ED3\uFF0C\u4E0D\u80FD\u4FEE\u6539", codes.frozen);
|
|
25577
|
+
}
|
|
25578
|
+
}
|
|
25579
|
+
function assertRemoteResourceOwned(input2) {
|
|
25580
|
+
const codes = {
|
|
25581
|
+
invalid: input2.codes?.invalid ?? "RESOURCE_WRITE_INFO_INVALID",
|
|
25582
|
+
notOwner: input2.codes?.notOwner ?? "RESOURCE_NOT_OWNER"
|
|
25583
|
+
};
|
|
25584
|
+
if (input2.info.resourceId !== input2.resourceId) {
|
|
25585
|
+
throw new CliError("\u5E73\u53F0\u8BE6\u60C5\u7F3A\u5C11\u6216\u4E0D\u5339\u914D resourceId\uFF0C\u62D2\u7EDD\u5199\u5165", codes.invalid);
|
|
25586
|
+
}
|
|
25587
|
+
const ownerId = input2.info.userId ?? input2.info.ownerId ?? input2.info.creatorId;
|
|
25588
|
+
if (typeof ownerId !== "number" || !Number.isSafeInteger(ownerId)) {
|
|
25589
|
+
throw new CliError("\u5E73\u53F0\u8BE6\u60C5\u7F3A\u5C11\u8D44\u6E90 owner\uFF0C\u62D2\u7EDD\u5199\u5165", codes.invalid);
|
|
25590
|
+
}
|
|
25591
|
+
if (ownerId !== input2.authUserId) {
|
|
25592
|
+
throw new CliError("\u53EA\u80FD\u4FEE\u6539\u81EA\u5DF1\u7684\u8D44\u6E90", codes.notOwner);
|
|
25593
|
+
}
|
|
25594
|
+
}
|
|
25595
|
+
|
|
25596
|
+
// src/platform/unwrap.ts
|
|
25597
|
+
function unwrapData2(result) {
|
|
25598
|
+
const envelope = result;
|
|
25599
|
+
const data = envelope.data ?? result;
|
|
25600
|
+
return data ?? {};
|
|
25601
|
+
}
|
|
25602
|
+
function unwrapFirst(result) {
|
|
25603
|
+
const envelope = result;
|
|
25604
|
+
const data = envelope.data ?? result;
|
|
25605
|
+
if (Array.isArray(data)) {
|
|
25606
|
+
return data[0] ?? {};
|
|
25607
|
+
}
|
|
25608
|
+
return data ?? {};
|
|
25609
|
+
}
|
|
25610
|
+
function unwrapList2(result, fields = ["dataList", "list"]) {
|
|
25611
|
+
const envelope = result;
|
|
25612
|
+
const data = envelope.data ?? result;
|
|
25613
|
+
if (Array.isArray(data)) {
|
|
25614
|
+
return data;
|
|
25615
|
+
}
|
|
25616
|
+
if (data && typeof data === "object") {
|
|
25617
|
+
for (const field of fields) {
|
|
25618
|
+
const list2 = data[field];
|
|
25619
|
+
if (Array.isArray(list2)) {
|
|
25620
|
+
return list2;
|
|
25621
|
+
}
|
|
25622
|
+
}
|
|
25623
|
+
}
|
|
25624
|
+
return [];
|
|
25625
|
+
}
|
|
25364
25626
|
|
|
25365
25627
|
// src/domain/listing/update.ts
|
|
25366
25628
|
var MAX_TITLE = 100;
|
|
25367
25629
|
var MAX_INTRO = 200;
|
|
25368
25630
|
var MAX_TAGS = 20;
|
|
25369
25631
|
var MAX_TAG_LENGTH = 20;
|
|
25632
|
+
var MAX_COVER_BYTES = 5 * 1024 * 1024;
|
|
25633
|
+
var COVER_EXTENSIONS = /* @__PURE__ */ new Set([".jpg", ".jpeg", ".png", ".gif"]);
|
|
25370
25634
|
function assertTitle(title) {
|
|
25635
|
+
if (!title) {
|
|
25636
|
+
throw new CliError("\u8BF7\u8F93\u5165\u8D44\u6E90\u6807\u9898", "UPDATE_TITLE_REQUIRED");
|
|
25637
|
+
}
|
|
25371
25638
|
if (title.length > MAX_TITLE) {
|
|
25372
25639
|
throw new CliError("\u6807\u9898\u4E0D\u80FD\u8D85\u8FC7100\u4E2A\u5B57\u7B26", "UPDATE_TITLE_LONG");
|
|
25373
25640
|
}
|
|
25374
25641
|
}
|
|
25642
|
+
function isAnimatedGif(content) {
|
|
25643
|
+
if (content.subarray(0, 6).toString("ascii") !== "GIF87a" && content.subarray(0, 6).toString("ascii") !== "GIF89a" || content.length < 13) {
|
|
25644
|
+
return true;
|
|
25645
|
+
}
|
|
25646
|
+
let offset = 13;
|
|
25647
|
+
if ((content[10] & 128) !== 0) {
|
|
25648
|
+
offset += 3 * 2 ** ((content[10] & 7) + 1);
|
|
25649
|
+
}
|
|
25650
|
+
let frames = 0;
|
|
25651
|
+
while (offset < content.length) {
|
|
25652
|
+
const marker = content[offset++];
|
|
25653
|
+
if (marker === 59) return frames > 1;
|
|
25654
|
+
if (marker === 44) {
|
|
25655
|
+
frames += 1;
|
|
25656
|
+
if (frames > 1) return true;
|
|
25657
|
+
if (offset + 9 > content.length) return true;
|
|
25658
|
+
const packed = content[offset + 8];
|
|
25659
|
+
offset += 9;
|
|
25660
|
+
if ((packed & 128) !== 0) offset += 3 * 2 ** ((packed & 7) + 1);
|
|
25661
|
+
offset += 1;
|
|
25662
|
+
} else if (marker === 33) {
|
|
25663
|
+
offset += 1;
|
|
25664
|
+
} else {
|
|
25665
|
+
return true;
|
|
25666
|
+
}
|
|
25667
|
+
while (offset < content.length) {
|
|
25668
|
+
const size = content[offset++];
|
|
25669
|
+
if (size === 0) break;
|
|
25670
|
+
offset += size;
|
|
25671
|
+
}
|
|
25672
|
+
}
|
|
25673
|
+
return true;
|
|
25674
|
+
}
|
|
25675
|
+
function assertCoverContent(extension, content) {
|
|
25676
|
+
const isJpeg = content.length >= 3 && content[0] === 255 && content[1] === 216 && content[2] === 255;
|
|
25677
|
+
const isPng = content.length >= 8 && content.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]));
|
|
25678
|
+
const isGif = content.subarray(0, 6).toString("ascii") === "GIF87a" || content.subarray(0, 6).toString("ascii") === "GIF89a";
|
|
25679
|
+
if ((extension === ".jpg" || extension === ".jpeg") && isJpeg) return;
|
|
25680
|
+
if (extension === ".png" && isPng) return;
|
|
25681
|
+
if (extension === ".gif" && isGif && !isAnimatedGif(content)) return;
|
|
25682
|
+
throw new CliError("\u5C01\u9762\u5FC5\u987B\u662F JPG\u3001PNG \u6216\u9759\u6001 GIF \u56FE\u7247", "UPDATE_COVER_INVALID");
|
|
25683
|
+
}
|
|
25684
|
+
async function uploadCover(cwd, cover, apis) {
|
|
25685
|
+
const normalized = normalizeProjectPath(cwd, cover, {
|
|
25686
|
+
code: "UPDATE_COVER_OUTSIDE",
|
|
25687
|
+
message: "\u5C01\u9762\u5FC5\u987B\u4F4D\u4E8E\u5F53\u524D\u5DE5\u7A0B\u5185"
|
|
25688
|
+
});
|
|
25689
|
+
const localPath = resolveExistingProjectPath(cwd, path11.resolve(cwd, normalized), {
|
|
25690
|
+
code: "UPDATE_COVER_OUTSIDE",
|
|
25691
|
+
message: "\u5C01\u9762\u5FC5\u987B\u4F4D\u4E8E\u5F53\u524D\u5DE5\u7A0B\u5185"
|
|
25692
|
+
});
|
|
25693
|
+
if (!existsSync10(localPath)) {
|
|
25694
|
+
throw new CliError(`\u5C01\u9762\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${normalized}`, "UPDATE_COVER_MISSING");
|
|
25695
|
+
}
|
|
25696
|
+
const stats = statSync2(localPath);
|
|
25697
|
+
if (!stats.isFile()) {
|
|
25698
|
+
throw new CliError("\u5C01\u9762\u5FC5\u987B\u662F\u4E00\u4E2A\u56FE\u7247\u6587\u4EF6", "UPDATE_COVER_INVALID");
|
|
25699
|
+
}
|
|
25700
|
+
if (stats.size > MAX_COVER_BYTES) {
|
|
25701
|
+
throw new CliError("\u5C01\u9762\u4E0D\u80FD\u8D85\u8FC7 5MB", "UPDATE_COVER_TOO_LARGE");
|
|
25702
|
+
}
|
|
25703
|
+
const extension = path11.extname(normalized).toLowerCase();
|
|
25704
|
+
if (!COVER_EXTENSIONS.has(extension)) {
|
|
25705
|
+
throw new CliError("\u5C01\u9762\u53EA\u652F\u6301 JPG\u3001PNG \u6216\u9759\u6001 GIF", "UPDATE_COVER_INVALID");
|
|
25706
|
+
}
|
|
25707
|
+
const content = readFileSync7(localPath);
|
|
25708
|
+
assertCoverContent(extension, content);
|
|
25709
|
+
const upload = apis?.uploadImage ?? ((params) => service_API_default.Storage.uploadImage(params));
|
|
25710
|
+
const result = unwrapData2(await upload({ file: content }));
|
|
25711
|
+
const url2 = result.url ?? result.fileUrl ?? result.fileURL;
|
|
25712
|
+
if (typeof url2 !== "string" || !url2.trim()) {
|
|
25713
|
+
throw new CliError("\u5C01\u9762\u4E0A\u4F20\u6210\u529F\u4F46\u5E73\u53F0\u672A\u8FD4\u56DE\u56FE\u7247 URL", "UPDATE_COVER_UPLOAD_INVALID");
|
|
25714
|
+
}
|
|
25715
|
+
return url2;
|
|
25716
|
+
}
|
|
25375
25717
|
function assertIntro(intro) {
|
|
25376
25718
|
if (intro.length > MAX_INTRO) {
|
|
25377
25719
|
throw new CliError("\u7B80\u4ECB\u4E0D\u80FD\u8D85\u8FC7200\u4E2A\u5B57\u7B26", "UPDATE_INTRO_LONG");
|
|
@@ -25385,9 +25727,6 @@ function assertTags(tags) {
|
|
|
25385
25727
|
if (tag.length > MAX_TAG_LENGTH) {
|
|
25386
25728
|
throw new CliError("\u5355\u4E2A\u6807\u7B7E\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC720\u4E2A\u5B57\u7B26", "UPDATE_TAG_LONG");
|
|
25387
25729
|
}
|
|
25388
|
-
if (tag.includes("#")) {
|
|
25389
|
-
throw new CliError(`\u6807\u7B7E\u4E0D\u80FD\u5305\u542B #\uFF1A${tag}`, "UPDATE_TAG_INVALID");
|
|
25390
|
-
}
|
|
25391
25730
|
}
|
|
25392
25731
|
if (tags.some((tag, i) => tags.indexOf(tag) !== i)) {
|
|
25393
25732
|
throw new CliError("\u8BE5\u6807\u7B7E\u5DF2\u6DFB\u52A0", "UPDATE_TAG_DUPLICATE");
|
|
@@ -25395,34 +25734,47 @@ function assertTags(tags) {
|
|
|
25395
25734
|
}
|
|
25396
25735
|
async function updateListing(input2) {
|
|
25397
25736
|
assertPlatformAllowed();
|
|
25398
|
-
requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
25399
|
-
if (input2.yes &&
|
|
25737
|
+
const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
25738
|
+
if (input2.yes && input2.title === void 0 && input2.intro === void 0 && input2.cover === void 0 && input2.tags === void 0) {
|
|
25400
25739
|
throw new CliError("--yes \u4E14\u65E0\u4FEE\u6539\u9879\uFF0C\u62D2\u7EDD\u7A7A\u66F4\u65B0", "UPDATE_NO_FLAGS");
|
|
25401
25740
|
}
|
|
25402
25741
|
const identity = resolveBoundIdentity(input2.cwd, input2.file);
|
|
25742
|
+
const info2 = input2.apis?.info ?? ((params) => service_API_default.Resource.info(params));
|
|
25743
|
+
const remote = unwrapData2(await info2({ resourceIdOrName: identity.resourceId }));
|
|
25744
|
+
assertRemoteResourceWritable({ info: remote, resourceId: identity.resourceId, authUserId: auth.userId });
|
|
25403
25745
|
const payload = {
|
|
25404
25746
|
resourceId: identity.resourceId
|
|
25405
25747
|
};
|
|
25406
|
-
|
|
25407
|
-
|
|
25408
|
-
|
|
25748
|
+
const title = input2.title?.trim();
|
|
25749
|
+
if (input2.title !== void 0) {
|
|
25750
|
+
assertTitle(title ?? "");
|
|
25751
|
+
payload.resourceTitle = title;
|
|
25409
25752
|
}
|
|
25410
|
-
if (input2.intro) {
|
|
25411
|
-
|
|
25412
|
-
|
|
25753
|
+
if (input2.intro !== void 0) {
|
|
25754
|
+
const intro = input2.intro.trim();
|
|
25755
|
+
assertIntro(intro);
|
|
25756
|
+
payload.intro = intro;
|
|
25757
|
+
}
|
|
25758
|
+
if (input2.cover !== void 0) {
|
|
25759
|
+
if (!input2.cover.trim()) {
|
|
25760
|
+
throw new CliError("\u8BF7\u63D0\u4F9B\u5C01\u9762\u56FE\u7247\u8DEF\u5F84\uFF1B\u672C\u671F\u4E0D\u652F\u6301\u6E05\u7A7A\u5C01\u9762", "UPDATE_COVER_REQUIRED");
|
|
25761
|
+
}
|
|
25762
|
+
payload.coverImages = [await uploadCover(input2.cwd, input2.cover, input2.apis)];
|
|
25413
25763
|
}
|
|
25414
|
-
if (input2.
|
|
25415
|
-
|
|
25416
|
-
|
|
25417
|
-
|
|
25418
|
-
|
|
25764
|
+
if (input2.tags !== void 0) {
|
|
25765
|
+
const rawTags = input2.tags === "" ? [] : input2.tags.split(",").map((item) => item.trim().replaceAll("#", ""));
|
|
25766
|
+
if (rawTags.some((tag) => !tag)) {
|
|
25767
|
+
throw new CliError("\u6807\u7B7E\u4E0D\u80FD\u5305\u542B\u7A7A\u9879", "UPDATE_TAG_EMPTY");
|
|
25768
|
+
}
|
|
25769
|
+
assertTags(rawTags);
|
|
25770
|
+
payload.tags = rawTags;
|
|
25419
25771
|
}
|
|
25420
25772
|
if ("status" in payload) {
|
|
25421
25773
|
delete payload.status;
|
|
25422
25774
|
}
|
|
25423
25775
|
const update2 = input2.apis?.update ?? ((params) => service_API_default.Resource.update(params));
|
|
25424
25776
|
await update2(payload);
|
|
25425
|
-
if (
|
|
25777
|
+
if (title !== void 0) updateIdentity(input2.cwd, identity.n, { title });
|
|
25426
25778
|
return payload;
|
|
25427
25779
|
}
|
|
25428
25780
|
|
|
@@ -25448,27 +25800,13 @@ function createUpdateCommand() {
|
|
|
25448
25800
|
}
|
|
25449
25801
|
|
|
25450
25802
|
// src/commands/policy/apply.ts
|
|
25451
|
-
import { readFileSync as
|
|
25452
|
-
import
|
|
25803
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
25804
|
+
import path12 from "path";
|
|
25453
25805
|
import { confirm, input } from "@inquirer/prompts";
|
|
25454
25806
|
import { Command as Command6 } from "commander";
|
|
25455
25807
|
|
|
25456
|
-
// src/platform/unwrap.ts
|
|
25457
|
-
function unwrapData2(result) {
|
|
25458
|
-
const envelope = result;
|
|
25459
|
-
const data = envelope.data ?? result;
|
|
25460
|
-
return data ?? {};
|
|
25461
|
-
}
|
|
25462
|
-
function unwrapFirst(result) {
|
|
25463
|
-
const envelope = result;
|
|
25464
|
-
const data = envelope.data ?? result;
|
|
25465
|
-
if (Array.isArray(data)) {
|
|
25466
|
-
return data[0] ?? {};
|
|
25467
|
-
}
|
|
25468
|
-
return data ?? {};
|
|
25469
|
-
}
|
|
25470
|
-
|
|
25471
25808
|
// src/domain/policy/list.ts
|
|
25809
|
+
var POLICY_TEMPLATE_PAGE_SIZE = 20;
|
|
25472
25810
|
function infoApi(apis) {
|
|
25473
25811
|
return apis?.info ?? ((params) => service_API_default.Resource.info(params));
|
|
25474
25812
|
}
|
|
@@ -25497,14 +25835,17 @@ function decoded(value) {
|
|
|
25497
25835
|
return value;
|
|
25498
25836
|
}
|
|
25499
25837
|
}
|
|
25500
|
-
function assertEditable(info2, authUserId) {
|
|
25501
|
-
|
|
25502
|
-
|
|
25503
|
-
|
|
25504
|
-
|
|
25505
|
-
|
|
25506
|
-
|
|
25507
|
-
|
|
25838
|
+
function assertEditable(info2, authUserId, resourceId) {
|
|
25839
|
+
assertRemoteResourceWritable({
|
|
25840
|
+
info: info2,
|
|
25841
|
+
resourceId,
|
|
25842
|
+
authUserId,
|
|
25843
|
+
codes: {
|
|
25844
|
+
invalid: "POLICY_INFO_INVALID",
|
|
25845
|
+
notOwner: "POLICY_NOT_OWNER",
|
|
25846
|
+
frozen: "POLICY_RESOURCE_FROZEN"
|
|
25847
|
+
}
|
|
25848
|
+
});
|
|
25508
25849
|
}
|
|
25509
25850
|
async function loadPolicyContext(input2) {
|
|
25510
25851
|
assertPlatformAllowed();
|
|
@@ -25523,7 +25864,7 @@ async function loadPolicyContext(input2) {
|
|
|
25523
25864
|
isLoadPolicyInfo: 1,
|
|
25524
25865
|
isTranslate: 1
|
|
25525
25866
|
}));
|
|
25526
|
-
if (input2.editable) assertEditable(info2, auth.userId);
|
|
25867
|
+
if (input2.editable) assertEditable(info2, auth.userId, resourceId);
|
|
25527
25868
|
return {
|
|
25528
25869
|
resourceId,
|
|
25529
25870
|
typeCode,
|
|
@@ -25534,55 +25875,97 @@ async function loadPolicyContext(input2) {
|
|
|
25534
25875
|
function templateFrom(value) {
|
|
25535
25876
|
if (!value || typeof value !== "object") return void 0;
|
|
25536
25877
|
const raw = value;
|
|
25537
|
-
const id = raw.id ?? raw.templateId ?? raw.policyTemplateId;
|
|
25538
|
-
const name = raw.name ?? raw.templateName ?? raw.policyName;
|
|
25539
|
-
const defaultValue = raw.defaultValue ?? raw.policyText ?? raw.value;
|
|
25878
|
+
const id = raw.id ?? raw.templateId ?? raw.policyTemplateId ?? raw._id;
|
|
25879
|
+
const name = raw.name ?? raw.templateName ?? raw.policyName ?? raw.title;
|
|
25880
|
+
const defaultValue = raw.defaultValue ?? raw.policyText ?? raw.value ?? raw.template;
|
|
25540
25881
|
if (typeof id !== "string" || !id || typeof name !== "string" || !name || typeof defaultValue !== "string" || !defaultValue.trim()) {
|
|
25541
25882
|
return void 0;
|
|
25542
25883
|
}
|
|
25543
25884
|
const summaryValue = raw.summary ?? raw.description ?? raw.eventSummary;
|
|
25885
|
+
const fillArgs = Array.isArray(raw.reportUiTemplate) ? raw.reportUiTemplate.flatMap((item) => {
|
|
25886
|
+
if (!item || typeof item !== "object") return [];
|
|
25887
|
+
const field = item;
|
|
25888
|
+
const name2 = field.id;
|
|
25889
|
+
const value2 = field.uiSectionDefaultValue;
|
|
25890
|
+
return typeof name2 === "string" && name2 && (typeof value2 === "string" || typeof value2 === "number") ? [{ name: name2, value: value2 }] : [];
|
|
25891
|
+
}) : [];
|
|
25544
25892
|
return {
|
|
25545
25893
|
id,
|
|
25546
25894
|
name,
|
|
25547
25895
|
defaultValue,
|
|
25896
|
+
fillArgs,
|
|
25548
25897
|
...typeof summaryValue === "string" && summaryValue.trim() ? { summary: summaryValue.trim() } : {}
|
|
25549
25898
|
};
|
|
25550
25899
|
}
|
|
25900
|
+
function normalizeCompiledTemplateDsl(contract2) {
|
|
25901
|
+
return contract2.replace(/\bfor\s+public\b/gi, "FOR PUBLIC").replace(/\binitial\b/gi, "Initial");
|
|
25902
|
+
}
|
|
25903
|
+
function compiledContract(result) {
|
|
25904
|
+
const envelope = result;
|
|
25905
|
+
const data = envelope.data ?? result;
|
|
25906
|
+
const contract2 = data && typeof data === "object" ? data.contractNew ?? data.contract : data;
|
|
25907
|
+
if (typeof contract2 !== "string" || !contract2.trim()) {
|
|
25908
|
+
throw new CliError("\u7B56\u7565\u6A21\u677F\u7F16\u8BD1\u7ED3\u679C\u7F3A\u5C11 contractNew", "POLICY_TEMPLATE_COMPILE_INVALID");
|
|
25909
|
+
}
|
|
25910
|
+
return normalizeCompiledTemplateDsl(contract2).trim();
|
|
25911
|
+
}
|
|
25551
25912
|
async function getPolicyTemplates(input2) {
|
|
25552
|
-
|
|
25913
|
+
await loadPolicyContext(input2);
|
|
25553
25914
|
const request2 = input2.apis?.policyTemplates ?? ((params) => service_API_default.Policy.policyTemplates(params));
|
|
25554
|
-
const
|
|
25555
|
-
const rawList = Array.isArray(result.list) ? result.list : Array.isArray(result.dataList) ? result.dataList : Array.isArray(result.templates) ? result.templates : [];
|
|
25915
|
+
const rawList = unwrapList2(await request2({}), ["list", "dataList", "templates"]);
|
|
25556
25916
|
return rawList.flatMap((item) => {
|
|
25557
25917
|
const template = templateFrom(item);
|
|
25558
25918
|
return template ? [template] : [];
|
|
25559
25919
|
});
|
|
25560
25920
|
}
|
|
25561
|
-
function
|
|
25562
|
-
const
|
|
25563
|
-
if (!
|
|
25564
|
-
|
|
25565
|
-
}
|
|
25566
|
-
|
|
25921
|
+
async function applyPolicyTemplate(input2) {
|
|
25922
|
+
const template = (await getPolicyTemplates(input2)).find((item) => item.id === input2.templateId);
|
|
25923
|
+
if (!template) throw new CliError("\u6307\u5B9A\u6A21\u677F\u4E0D\u5728\u5F53\u524D\u6A21\u677F\u5217\u8868\u4E2D", "POLICY_TEMPLATE_INVALID");
|
|
25924
|
+
const request2 = input2.apis?.policyReCompile ?? ((params) => service_API_default.Policy.policyReCompile(params));
|
|
25925
|
+
const policyText = compiledContract(await request2({ _id: template.id, fillArgs: template.fillArgs }));
|
|
25926
|
+
await applyPolicy({ ...input2, policyText });
|
|
25567
25927
|
}
|
|
25568
|
-
async function
|
|
25928
|
+
async function getPolicyList(input2) {
|
|
25569
25929
|
const context = await loadPolicyContext(input2);
|
|
25570
|
-
|
|
25571
|
-
return
|
|
25572
|
-
|
|
25573
|
-
|
|
25574
|
-
|
|
25575
|
-
|
|
25576
|
-
|
|
25577
|
-
const
|
|
25578
|
-
|
|
25579
|
-
|
|
25580
|
-
|
|
25581
|
-
|
|
25582
|
-
|
|
25583
|
-
|
|
25584
|
-
|
|
25585
|
-
|
|
25930
|
+
const typeHierarchy = await getTypeHierarchy(context.typeCode, input2.apis);
|
|
25931
|
+
return {
|
|
25932
|
+
typeHierarchy,
|
|
25933
|
+
policies: [...context.policies].sort((a, b) => b.status - a.status || a.policyName.localeCompare(b.policyName))
|
|
25934
|
+
};
|
|
25935
|
+
}
|
|
25936
|
+
function formatPolicyList(list2) {
|
|
25937
|
+
const header = [
|
|
25938
|
+
`\u8D44\u6E90\u7C7B\u578B\uFF1A${list2.typeHierarchy.join(" / ")}`,
|
|
25939
|
+
`\u5171 ${list2.policies.length} \u6761\u6388\u6743\u7B56\u7565`
|
|
25940
|
+
];
|
|
25941
|
+
if (list2.policies.length === 0) return [...header, "\u8FD8\u6CA1\u6709\u6388\u6743\u7B56\u7565"].join("\n");
|
|
25942
|
+
return [
|
|
25943
|
+
...header,
|
|
25944
|
+
...list2.policies.map((item) => `${item.policyId} ${item.policyName} ${item.status === 1 ? "on" : "off"}`)
|
|
25945
|
+
].join("\n");
|
|
25946
|
+
}
|
|
25947
|
+
function policyTemplatePage(templates, page) {
|
|
25948
|
+
const pageCount = Math.max(1, Math.ceil(templates.length / POLICY_TEMPLATE_PAGE_SIZE));
|
|
25949
|
+
if (!Number.isInteger(page) || page < 1 || page > pageCount) {
|
|
25950
|
+
throw new CliError(`\u7B56\u7565\u6A21\u677F\u9875\u7801\u8D85\u51FA\u8303\u56F4\uFF0C\u5F53\u524D\u5171 ${pageCount} \u9875`, "POLICY_TEMPLATE_PAGE");
|
|
25951
|
+
}
|
|
25952
|
+
return {
|
|
25953
|
+
page,
|
|
25954
|
+
pageCount,
|
|
25955
|
+
total: templates.length,
|
|
25956
|
+
hasPrevious: page > 1,
|
|
25957
|
+
hasNext: page < pageCount,
|
|
25958
|
+
items: templates.slice((page - 1) * POLICY_TEMPLATE_PAGE_SIZE, page * POLICY_TEMPLATE_PAGE_SIZE)
|
|
25959
|
+
};
|
|
25960
|
+
}
|
|
25961
|
+
function formatPolicyTemplatePage(page) {
|
|
25962
|
+
const header = `\u7B2C ${page.page}/${page.pageCount} \u9875\uFF0C\u5171 ${page.total} \u4E2A\u6388\u6743\u7B56\u7565\u6A21\u677F`;
|
|
25963
|
+
if (page.items.length === 0) return `${header}
|
|
25964
|
+
\u6CA1\u6709\u53EF\u7528\u6388\u6743\u7B56\u7565\u6A21\u677F`;
|
|
25965
|
+
return [
|
|
25966
|
+
header,
|
|
25967
|
+
...page.items.map((item) => [item.id, item.name, item.summary].filter(Boolean).join(" "))
|
|
25968
|
+
].join("\n");
|
|
25586
25969
|
}
|
|
25587
25970
|
function assertPolicyInput(context, policyName, policyText) {
|
|
25588
25971
|
const name = policyName.trim();
|
|
@@ -25627,8 +26010,8 @@ async function setPolicy(input2) {
|
|
|
25627
26010
|
|
|
25628
26011
|
// src/commands/policy/apply.ts
|
|
25629
26012
|
function parsePolicy(file) {
|
|
25630
|
-
const text =
|
|
25631
|
-
if (
|
|
26013
|
+
const text = readFileSync8(file, "utf8");
|
|
26014
|
+
if (path12.extname(file).toLowerCase() !== ".json") return { policyText: text };
|
|
25632
26015
|
let parsed;
|
|
25633
26016
|
try {
|
|
25634
26017
|
parsed = JSON.parse(text);
|
|
@@ -25667,13 +26050,14 @@ function createPolicyListCommand() {
|
|
|
25667
26050
|
const command = addSharedOptions(new Command7("list"));
|
|
25668
26051
|
command.description(
|
|
25669
26052
|
// i18n: cli.command.policy.list.description
|
|
25670
|
-
"\u770B\
|
|
26053
|
+
"\u67E5\u770B\u5F53\u524D\u8D44\u6E90\u7684\u5168\u90E8\u6388\u6743\u7B56\u7565\u53CA\u8D44\u6E90\u7C7B\u578B\u5C42\u7EA7"
|
|
25671
26054
|
).action(async function() {
|
|
25672
26055
|
const shared = readSharedOptions(this);
|
|
25673
|
-
|
|
26056
|
+
const list2 = await getPolicyList({
|
|
25674
26057
|
cwd: resolveCwd(shared.cwd),
|
|
25675
26058
|
file: shared.file
|
|
25676
|
-
})
|
|
26059
|
+
});
|
|
26060
|
+
console.log(formatPolicyList(list2));
|
|
25677
26061
|
});
|
|
25678
26062
|
return command;
|
|
25679
26063
|
}
|
|
@@ -25695,22 +26079,39 @@ function createPolicySetCommand() {
|
|
|
25695
26079
|
}
|
|
25696
26080
|
|
|
25697
26081
|
// src/commands/policy/template.ts
|
|
25698
|
-
import { confirm as confirm3
|
|
26082
|
+
import { confirm as confirm3 } from "@inquirer/prompts";
|
|
25699
26083
|
import { Command as Command9 } from "commander";
|
|
26084
|
+
async function showTemplatePages(templates) {
|
|
26085
|
+
let page = 1;
|
|
26086
|
+
while (true) {
|
|
26087
|
+
const current = policyTemplatePage(templates, page);
|
|
26088
|
+
console.log(formatPolicyTemplatePage(current));
|
|
26089
|
+
if (!current.hasPrevious && !current.hasNext) return;
|
|
26090
|
+
if (!isInteractive()) {
|
|
26091
|
+
if (current.hasNext) {
|
|
26092
|
+
console.log(`\u8FD8\u6709 ${current.total - current.page * POLICY_TEMPLATE_PAGE_SIZE} \u4E2A\u6388\u6743\u7B56\u7565\u6A21\u677F\uFF1B\u8BF7\u5728\u4EA4\u4E92\u7EC8\u7AEF\u8FD0\u884C policy template list \u67E5\u770B\u540E\u7EED\u9875`);
|
|
26093
|
+
}
|
|
26094
|
+
return;
|
|
26095
|
+
}
|
|
26096
|
+
const action = await selectQuestion("\u6388\u6743\u7B56\u7565\u6A21\u677F\u5217\u8868", [
|
|
26097
|
+
...current.hasPrevious ? [{ name: "\u4E0A\u4E00\u9875", value: "__previous__" }] : [],
|
|
26098
|
+
...current.hasNext ? [{ name: "\u4E0B\u4E00\u9875", value: "__next__" }] : [],
|
|
26099
|
+
{ name: "\u9000\u51FA", value: "__exit__" }
|
|
26100
|
+
]);
|
|
26101
|
+
if (action === "__exit__") return;
|
|
26102
|
+
page += action === "__next__" ? 1 : -1;
|
|
26103
|
+
}
|
|
26104
|
+
}
|
|
25700
26105
|
async function chooseTemplate(templates) {
|
|
25701
|
-
let page =
|
|
25702
|
-
const pageSize2 = 20;
|
|
26106
|
+
let page = 1;
|
|
25703
26107
|
while (true) {
|
|
25704
|
-
const
|
|
25705
|
-
const value = await
|
|
25706
|
-
|
|
25707
|
-
|
|
25708
|
-
|
|
25709
|
-
|
|
25710
|
-
|
|
25711
|
-
{ name: "\u53D6\u6D88", value: "__cancel__" }
|
|
25712
|
-
]
|
|
25713
|
-
});
|
|
26108
|
+
const current = policyTemplatePage(templates, page);
|
|
26109
|
+
const value = await selectQuestion(`\u8BF7\u9009\u62E9\u6388\u6743\u7B56\u7565\u6A21\u677F\uFF08\u7B2C ${current.page}/${current.pageCount} \u9875\uFF09`, [
|
|
26110
|
+
...current.items.map((item) => ({ name: `${item.name} (${item.id})${item.summary ? ` \u2014 ${item.summary}` : ""}`, value: item.id })),
|
|
26111
|
+
...current.hasPrevious ? [{ name: "\u4E0A\u4E00\u9875", value: "__previous__" }] : [],
|
|
26112
|
+
...current.hasNext ? [{ name: "\u4E0B\u4E00\u9875", value: "__next__" }] : [],
|
|
26113
|
+
{ name: "\u53D6\u6D88", value: "__cancel__" }
|
|
26114
|
+
]);
|
|
25714
26115
|
if (value === "__previous__") {
|
|
25715
26116
|
page -= 1;
|
|
25716
26117
|
continue;
|
|
@@ -25725,9 +26126,9 @@ async function chooseTemplate(templates) {
|
|
|
25725
26126
|
}
|
|
25726
26127
|
function createPolicyTemplateCommand() {
|
|
25727
26128
|
const template = addSharedOptions(new Command9("template")).description("\u6388\u6743\u7B56\u7565\u6A21\u677F");
|
|
25728
|
-
addSharedOptions(template.command("list")).description("\
|
|
26129
|
+
addSharedOptions(template.command("list")).description("\u5217\u5F53\u524D\u6A21\u677F\u5217\u8868\uFF08\u6BCF\u9875 20 \u6761\uFF09").action(async function() {
|
|
25729
26130
|
const shared = readSharedOptions(this);
|
|
25730
|
-
|
|
26131
|
+
await showTemplatePages(await getPolicyTemplates({ cwd: resolveCwd(shared.cwd), file: shared.file }));
|
|
25731
26132
|
});
|
|
25732
26133
|
addSharedOptions(template.command("apply")).description("\u5E94\u7528\u5F53\u524D\u7C7B\u578B\u7684\u4E00\u6761\u6A21\u677F\u5E76\u542F\u7528").argument("[templateId]", "\u6A21\u677F\u7F16\u53F7").option("--name <name>", "\u7B56\u7565\u540D").action(async function(templateId, options) {
|
|
25733
26134
|
const shared = readSharedOptions(this);
|
|
@@ -25735,7 +26136,7 @@ function createPolicyTemplateCommand() {
|
|
|
25735
26136
|
const yes = shared.yes === true;
|
|
25736
26137
|
const templates = await getPolicyTemplates({ cwd, file: shared.file });
|
|
25737
26138
|
let item = templateId ? templates.find((candidate) => candidate.id === templateId) : void 0;
|
|
25738
|
-
if (!item && templateId) throw new CliError("\u6307\u5B9A\u6A21\u677F\u4E0D\
|
|
26139
|
+
if (!item && templateId) throw new CliError("\u6307\u5B9A\u6A21\u677F\u4E0D\u5728\u5F53\u524D\u6A21\u677F\u5217\u8868\u4E2D", "POLICY_TEMPLATE_INVALID");
|
|
25739
26140
|
if (!item) {
|
|
25740
26141
|
if (yes || !process.stdin.isTTY) throw new CliError("--yes \u6216\u975E\u4EA4\u4E92\u6A21\u5F0F\u5FC5\u987B\u63D0\u4F9B templateId", "POLICY_TEMPLATE_ID");
|
|
25741
26142
|
item = await chooseTemplate(templates);
|
|
@@ -25743,7 +26144,7 @@ function createPolicyTemplateCommand() {
|
|
|
25743
26144
|
}
|
|
25744
26145
|
const policyName = options.name ?? item.name;
|
|
25745
26146
|
if (!yes && !await confirm3({ message: `\u6DFB\u52A0\u5E76\u542F\u7528\u7B56\u7565\u300C${policyName}\u300D\uFF1F`, default: true })) return;
|
|
25746
|
-
await
|
|
26147
|
+
await applyPolicyTemplate({ cwd, file: shared.file, templateId: item.id, policyName });
|
|
25747
26148
|
console.log("\u5DF2\u6DFB\u52A0\u5E76\u542F\u7528\u6388\u6743\u7B56\u7565");
|
|
25748
26149
|
});
|
|
25749
26150
|
return template;
|
|
@@ -25753,28 +26154,18 @@ function createPolicyTemplateCommand() {
|
|
|
25753
26154
|
import { Command as Command10 } from "commander";
|
|
25754
26155
|
|
|
25755
26156
|
// src/domain/bind/bind.ts
|
|
25756
|
-
import { existsSync as
|
|
25757
|
-
|
|
25758
|
-
// src/local/indexFile.ts
|
|
25759
|
-
import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
|
|
25760
|
-
import path12 from "path";
|
|
25761
|
-
function normalizeFileKey(filePath) {
|
|
25762
|
-
return path12.posix.normalize(filePath.replaceAll("\\", "/")).replace(/^\.\//, "");
|
|
25763
|
-
}
|
|
25764
|
-
|
|
25765
|
-
// src/domain/bind/bind.ts
|
|
26157
|
+
import { existsSync as existsSync11 } from "fs";
|
|
25766
26158
|
import path13 from "path";
|
|
25767
26159
|
async function bindResource(input2) {
|
|
25768
26160
|
assertPlatformAllowed();
|
|
25769
26161
|
const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
25770
|
-
validateLocalState(input2.cwd);
|
|
25771
26162
|
const filePath = input2.file !== void 0 ? normalizeProjectPath(input2.cwd, input2.file, {
|
|
25772
26163
|
code: "BIND_FILE_OUTSIDE",
|
|
25773
26164
|
message: "--artifact \u5FC5\u987B\u843D\u5728\u5F53\u524D\u5DE5\u7A0B\u91CC"
|
|
25774
26165
|
}) : void 0;
|
|
25775
26166
|
if (filePath) {
|
|
25776
26167
|
const absolute = path13.resolve(input2.cwd, filePath);
|
|
25777
|
-
if (!
|
|
26168
|
+
if (!existsSync11(absolute)) {
|
|
25778
26169
|
throw new CliError(`\u672C\u5730\u4EA7\u7269\u4E0D\u5B58\u5728\uFF1A${absolute}`, "ARTIFACT_ANCHOR_MISSING");
|
|
25779
26170
|
}
|
|
25780
26171
|
}
|
|
@@ -25791,23 +26182,34 @@ async function bindResource(input2) {
|
|
|
25791
26182
|
if (!isResourceSubject(info2.subjectType)) {
|
|
25792
26183
|
throw new CliError("\u53EA\u80FD bind \u5355\u8D44\u6E90", "BIND_SUBJECT_INVALID");
|
|
25793
26184
|
}
|
|
25794
|
-
if (info2.userId !== auth.userId) {
|
|
25795
|
-
throw new CliError("\u53EA\u80FD bind \u81EA\u5DF1\u7684\u8D44\u6E90", "BIND_NOT_OWNER");
|
|
25796
|
-
}
|
|
25797
26185
|
const resourceId = String(info2.resourceId ?? "");
|
|
25798
|
-
|
|
26186
|
+
if (!resourceId) {
|
|
26187
|
+
throw new CliError("\u5E73\u53F0\u8BE6\u60C5\u7F3A\u5C11\u8EAB\u4EFD\u5B57\u6BB5", "BIND_INFO_INVALID");
|
|
26188
|
+
}
|
|
26189
|
+
assertRemoteResourceOwned({
|
|
26190
|
+
info: info2,
|
|
26191
|
+
resourceId,
|
|
26192
|
+
authUserId: auth.userId,
|
|
26193
|
+
codes: {
|
|
26194
|
+
invalid: "BIND_INFO_INVALID",
|
|
26195
|
+
notOwner: "BIND_NOT_OWNER"
|
|
26196
|
+
}
|
|
26197
|
+
});
|
|
26198
|
+
const resourceName = String(info2.resourceName ?? "");
|
|
26199
|
+
const name = (resourceName || String(info2.name ?? "")).split("/").pop() ?? "";
|
|
25799
26200
|
const title = String(info2.resourceTitle ?? info2.title ?? name);
|
|
25800
26201
|
const resourceType = info2.resourceType;
|
|
25801
26202
|
const typeFromArray = Array.isArray(resourceType) ? String(resourceType[0] ?? "") : "";
|
|
25802
26203
|
const typeCode = String(info2.resourceTypeCode ?? typeFromArray);
|
|
25803
|
-
if (!
|
|
26204
|
+
if (!name || !typeCode || !title) {
|
|
25804
26205
|
throw new CliError("\u5E73\u53F0\u8BE6\u60C5\u7F3A\u5C11\u8EAB\u4EFD\u5B57\u6BB5", "BIND_INFO_INVALID");
|
|
25805
26206
|
}
|
|
26207
|
+
const stableResourceName = resourceName || `${auth.loginName}/${name}`;
|
|
25806
26208
|
return withProjectLock(input2.cwd, () => {
|
|
25807
26209
|
const identities = validateLocalState(input2.cwd);
|
|
25808
26210
|
const byId = identities.find((item) => item.resourceId === resourceId);
|
|
25809
26211
|
const byFile = filePath ? identities.find(
|
|
25810
|
-
(item) =>
|
|
26212
|
+
(item) => normalizeProjectPath(input2.cwd, item.filePath) === filePath
|
|
25811
26213
|
) : void 0;
|
|
25812
26214
|
const unbound = identities.filter((item) => !item.resourceId);
|
|
25813
26215
|
if (byFile && byId && byFile.n !== byId.n) {
|
|
@@ -25817,7 +26219,10 @@ async function bindResource(input2) {
|
|
|
25817
26219
|
if (input2.selector && byId && target && target.n !== byId.n) {
|
|
25818
26220
|
throw new CliError(`\u8D44\u6E90\u5DF2\u7ED1\u5B9A\u5230 ${byId.n}.json`, "BIND_ID_TAKEN");
|
|
25819
26221
|
}
|
|
25820
|
-
if (!target &&
|
|
26222
|
+
if (!target && filePath) {
|
|
26223
|
+
target = unbound.find((item) => item.filePath === filePath);
|
|
26224
|
+
}
|
|
26225
|
+
if (!target && filePath === void 0 && unbound.length === 1) {
|
|
25821
26226
|
target = unbound[0];
|
|
25822
26227
|
}
|
|
25823
26228
|
if (!target && unbound.length > 1) throw new CliError("\u5F53\u524D\u5DE5\u7A0B\u6709\u591A\u4EFD\u672A\u7ED1\u5B9A\u8D44\u6E90\u72B6\u6001\uFF1B\u8BF7\u4F7F\u7528 --resource \u6307\u5B9A\u8D44\u6E90", "IDENTITY_RESOURCE_REQUIRED");
|
|
@@ -25828,9 +26233,15 @@ async function bindResource(input2) {
|
|
|
25828
26233
|
if (!resolvedFilePath) {
|
|
25829
26234
|
throw new CliError("\u65B0\u589E\u672C\u5730\u72B6\u6001\u65F6\u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "BIND_ARTIFACT_REQUIRED");
|
|
25830
26235
|
}
|
|
25831
|
-
assertArtifactAnchor(typeCode, path13.resolve(input2.cwd, resolvedFilePath));
|
|
26236
|
+
assertArtifactAnchor(typeCode, path13.resolve(input2.cwd, resolvedFilePath), input2.cwd);
|
|
25832
26237
|
const env = getEnv2();
|
|
25833
26238
|
if (target) {
|
|
26239
|
+
if (target.resourceId && (target.env ?? "prod") !== env) {
|
|
26240
|
+
throw new CliError(
|
|
26241
|
+
`\u4E0D\u80FD\u628A ${target.n}.json\uFF08${target.env ?? "prod"}\uFF09\u6539\u7ED1\u5230 ${env} \u73AF\u5883\uFF1B\u8BF7\u65B0\u5EFA\u6216\u9009\u62E9\u8BE5\u73AF\u5883\u7684\u672C\u5730\u8D44\u6E90\u72B6\u6001`,
|
|
26242
|
+
"BIND_ENV_MISMATCH"
|
|
26243
|
+
);
|
|
26244
|
+
}
|
|
25834
26245
|
const resourceChanged = target.resourceId !== resourceId;
|
|
25835
26246
|
const typeChanged = target.typeCode !== typeCode;
|
|
25836
26247
|
if (target.resourceId && resourceChanged) {
|
|
@@ -25841,6 +26252,7 @@ async function bindResource(input2) {
|
|
|
25841
26252
|
const discardDraft = target.resourceId && resourceChanged || typeChanged;
|
|
25842
26253
|
const updated = prepareIdentityUpdate(input2.cwd, target.n, {
|
|
25843
26254
|
resourceId,
|
|
26255
|
+
resourceName: stableResourceName,
|
|
25844
26256
|
name,
|
|
25845
26257
|
title,
|
|
25846
26258
|
typeCode,
|
|
@@ -25856,6 +26268,7 @@ async function bindResource(input2) {
|
|
|
25856
26268
|
const created = prepareIdentityCreate(input2.cwd, {
|
|
25857
26269
|
subject: "resource",
|
|
25858
26270
|
resourceId,
|
|
26271
|
+
resourceName: stableResourceName,
|
|
25859
26272
|
name,
|
|
25860
26273
|
title,
|
|
25861
26274
|
typeCode,
|
|
@@ -25863,7 +26276,8 @@ async function bindResource(input2) {
|
|
|
25863
26276
|
env
|
|
25864
26277
|
});
|
|
25865
26278
|
commitLocalTransaction(input2.cwd, [
|
|
25866
|
-
{ path: identityFilePath(input2.cwd, created.n), content: serializeIdentity(created) }
|
|
26279
|
+
{ path: identityFilePath(input2.cwd, created.n), content: serializeIdentity(created) },
|
|
26280
|
+
{ path: identitySequenceFilePath(input2.cwd), content: serializeIdentitySequence(created.n) }
|
|
25867
26281
|
]);
|
|
25868
26282
|
return created;
|
|
25869
26283
|
});
|
|
@@ -25911,7 +26325,7 @@ import { Command as Command11 } from "commander";
|
|
|
25911
26325
|
|
|
25912
26326
|
// src/domain/init/scaffold.ts
|
|
25913
26327
|
import { execFile as execFileCallback } from "child_process";
|
|
25914
|
-
import { cpSync, existsSync as
|
|
26328
|
+
import { cpSync, existsSync as existsSync12, lstatSync as lstatSync2, mkdirSync as mkdirSync2, mkdtempSync, readdirSync as readdirSync4, readFileSync as readFileSync9, renameSync, rmSync } from "fs";
|
|
25915
26329
|
import os4 from "os";
|
|
25916
26330
|
import path14 from "path";
|
|
25917
26331
|
import { promisify } from "util";
|
|
@@ -25943,7 +26357,7 @@ function resolveTargetDir(input2) {
|
|
|
25943
26357
|
return input2.dir ? path14.isAbsolute(input2.dir) ? input2.dir : path14.resolve(input2.cwd, input2.dir) : path14.resolve(input2.cwd);
|
|
25944
26358
|
}
|
|
25945
26359
|
function targetHasOnlyAuthSelector(targetDir) {
|
|
25946
|
-
if (!
|
|
26360
|
+
if (!existsSync12(targetDir)) return false;
|
|
25947
26361
|
let entries;
|
|
25948
26362
|
try {
|
|
25949
26363
|
entries = readdirSync4(targetDir);
|
|
@@ -25956,20 +26370,20 @@ function targetHasOnlyAuthSelector(targetDir) {
|
|
|
25956
26370
|
return stateDirHasOnlyAuthSelector(stateDir);
|
|
25957
26371
|
}
|
|
25958
26372
|
function stateDirHasOnlyAuthSelector(stateDir) {
|
|
25959
|
-
if (!
|
|
26373
|
+
if (!existsSync12(stateDir) || !lstatSync2(stateDir).isDirectory() || lstatSync2(stateDir).isSymbolicLink()) return false;
|
|
25960
26374
|
const stateEntries = readdirSync4(stateDir);
|
|
25961
26375
|
if (stateEntries.length !== 1 || stateEntries[0] !== "auth") return false;
|
|
25962
|
-
const auth =
|
|
26376
|
+
const auth = lstatSync2(path14.join(stateDir, "auth"));
|
|
25963
26377
|
return auth.isFile() && !auth.isSymbolicLink();
|
|
25964
26378
|
}
|
|
25965
26379
|
function assertInitialTarget(targetDir, adoptExistingProject) {
|
|
25966
|
-
if (!
|
|
26380
|
+
if (!existsSync12(targetDir)) return { targetExisted: false, preserveAuth: false, adoptExistingProject };
|
|
25967
26381
|
const entries = readdirSync4(targetDir);
|
|
25968
26382
|
if (entries.length === 0) return { targetExisted: true, preserveAuth: false, adoptExistingProject };
|
|
25969
26383
|
if (targetHasOnlyAuthSelector(targetDir)) return { targetExisted: true, preserveAuth: true, adoptExistingProject };
|
|
25970
26384
|
if (adoptExistingProject) {
|
|
25971
26385
|
const stateDir = path14.join(targetDir, ".freelog");
|
|
25972
|
-
if (!
|
|
26386
|
+
if (!existsSync12(stateDir)) return { targetExisted: true, preserveAuth: false, adoptExistingProject: true };
|
|
25973
26387
|
if (stateDirHasOnlyAuthSelector(stateDir)) return { targetExisted: true, preserveAuth: true, adoptExistingProject: true };
|
|
25974
26388
|
}
|
|
25975
26389
|
throw new CliError("\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u7A7A\u76EE\u5F55\uFF0C\u62D2\u7EDD\u8986\u76D6", "INIT_TARGET_NOT_EMPTY");
|
|
@@ -25997,12 +26411,12 @@ function validateRemoteTemplate(packageDir, template) {
|
|
|
25997
26411
|
const templateDir = path14.join(packageDir, "template");
|
|
25998
26412
|
let manifest;
|
|
25999
26413
|
try {
|
|
26000
|
-
manifest = JSON.parse(
|
|
26414
|
+
manifest = JSON.parse(readFileSync9(manifestPath, "utf8"));
|
|
26001
26415
|
} catch {
|
|
26002
26416
|
throw new CliError("\u6A21\u677F\u6821\u9A8C\u5931\u8D25\uFF1A\u7F3A\u5C11\u6216\u65E0\u6CD5\u8BFB\u53D6 template.manifest.json", "TEMPLATE_INVALID");
|
|
26003
26417
|
}
|
|
26004
26418
|
const tags = Array.isArray(manifest.tags) ? manifest.tags : [];
|
|
26005
|
-
if (manifest.id !== template.id || manifest.npmName !== template.npmName || manifest.version !== template.version || !tags.includes("runtime") || !template.targets.every((target) => tags.includes(target)) || !
|
|
26419
|
+
if (manifest.id !== template.id || manifest.npmName !== template.npmName || manifest.version !== template.version || !tags.includes("runtime") || !template.targets.every((target) => tags.includes(target)) || !existsSync12(templateDir)) {
|
|
26006
26420
|
throw new CliError("\u6A21\u677F\u6821\u9A8C\u5931\u8D25\uFF1A\u7EBF\u4E0A\u6A21\u677F\u4E0E\u53D7\u63A7\u6E05\u5355\u4E0D\u4E00\u81F4", "TEMPLATE_INVALID");
|
|
26007
26421
|
}
|
|
26008
26422
|
return templateDir;
|
|
@@ -26040,7 +26454,7 @@ function commitStaging(stagingDir, targetDir, targetExisted, preserveAuth, adopt
|
|
|
26040
26454
|
if (preserveAuth) {
|
|
26041
26455
|
assertOnlyAuthSelectorStillThere(targetDir);
|
|
26042
26456
|
} else if (adoptExistingProject) {
|
|
26043
|
-
if (
|
|
26457
|
+
if (existsSync12(path14.join(targetDir, ".freelog"))) {
|
|
26044
26458
|
throw new CliError("\u76EE\u6807\u76EE\u5F55\u5728\u521D\u59CB\u5316\u671F\u95F4\u88AB\u4FEE\u6539\uFF0C\u672A\u8986\u76D6\u672A\u77E5\u6587\u4EF6", "INIT_TARGET_CHANGED");
|
|
26045
26459
|
}
|
|
26046
26460
|
renameSync(path14.join(stagingDir, ".freelog"), path14.join(targetDir, ".freelog"));
|
|
@@ -26054,7 +26468,7 @@ function commitStaging(stagingDir, targetDir, targetExisted, preserveAuth, adopt
|
|
|
26054
26468
|
if (preserveAuth && entry2 === ".freelog") {
|
|
26055
26469
|
for (const stateEntry of readdirSync4(path14.join(stagingDir, entry2))) {
|
|
26056
26470
|
const stateDestination = path14.join(destination, stateEntry);
|
|
26057
|
-
if (
|
|
26471
|
+
if (existsSync12(stateDestination)) {
|
|
26058
26472
|
throw new CliError("\u76EE\u6807\u76EE\u5F55\u5728\u521D\u59CB\u5316\u671F\u95F4\u88AB\u4FEE\u6539\uFF0C\u672A\u8986\u76D6\u672A\u77E5\u6587\u4EF6", "INIT_TARGET_CHANGED");
|
|
26059
26473
|
}
|
|
26060
26474
|
renameSync(path14.join(stagingDir, entry2, stateEntry), stateDestination);
|
|
@@ -26062,7 +26476,7 @@ function commitStaging(stagingDir, targetDir, targetExisted, preserveAuth, adopt
|
|
|
26062
26476
|
rmSync(path14.join(stagingDir, entry2), { recursive: true, force: true });
|
|
26063
26477
|
continue;
|
|
26064
26478
|
}
|
|
26065
|
-
if (
|
|
26479
|
+
if (existsSync12(destination)) {
|
|
26066
26480
|
throw new CliError("\u76EE\u6807\u76EE\u5F55\u5728\u521D\u59CB\u5316\u671F\u95F4\u88AB\u4FEE\u6539\uFF0C\u672A\u8986\u76D6\u672A\u77E5\u6587\u4EF6", "INIT_TARGET_CHANGED");
|
|
26067
26481
|
}
|
|
26068
26482
|
renameSync(path14.join(stagingDir, entry2), destination);
|
|
@@ -26086,7 +26500,7 @@ async function initProject(input2) {
|
|
|
26086
26500
|
}
|
|
26087
26501
|
const typeCode = shortcut === "theme" ? "RT001" : shortcut === "widget" ? "RT002" : (await (input2.typeValidator ?? ((code) => getTypeInfo(code, input2.typeApis)))(input2.typeCode)).code;
|
|
26088
26502
|
const artifact = shortcut ? "dist" : normalizeProjectPath(targetDir, input2.artifact);
|
|
26089
|
-
if (!shortcut) assertArtifactAnchor(typeCode, path14.resolve(targetDir, artifact));
|
|
26503
|
+
if (!shortcut) assertArtifactAnchor(typeCode, path14.resolve(targetDir, artifact), targetDir);
|
|
26090
26504
|
const template = shortcut && input2.template ? getTemplate(input2.template, shortcut) : void 0;
|
|
26091
26505
|
if (shortcut && !template) throw new CliError("\u8BF7\u9009\u62E9\u6A21\u677F", "INIT_TEMPLATE_REQUIRED");
|
|
26092
26506
|
const parent = path14.dirname(targetDir);
|
|
@@ -26188,6 +26602,7 @@ async function statusProject(input2) {
|
|
|
26188
26602
|
if (local?.resourceId) {
|
|
26189
26603
|
assertPlatformAllowed();
|
|
26190
26604
|
requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
26605
|
+
resolveBoundIdentity(input2.cwd, input2.file);
|
|
26191
26606
|
const infoApi2 = input2.apis?.info ?? ((params) => service_API_default.Resource.info(params));
|
|
26192
26607
|
const result = await infoApi2({
|
|
26193
26608
|
resourceIdOrName: local.resourceId,
|
|
@@ -26248,22 +26663,40 @@ function requireTypeAuth(command) {
|
|
|
26248
26663
|
const shared = readSharedOptions(command);
|
|
26249
26664
|
requireAuth({ cwd: resolveCwd(shared.cwd) });
|
|
26250
26665
|
}
|
|
26666
|
+
async function showTypePages(items, commandText) {
|
|
26667
|
+
let page = 1;
|
|
26668
|
+
while (true) {
|
|
26669
|
+
const current = typeListPage(items, page);
|
|
26670
|
+
console.log(formatTypeListPage(current));
|
|
26671
|
+
if (!current.hasPrevious && !current.hasNext) return;
|
|
26672
|
+
if (!isInteractive()) {
|
|
26673
|
+
if (current.hasNext) {
|
|
26674
|
+
console.log(`\u8FD8\u6709 ${current.total - current.page * TYPE_LIST_PAGE_SIZE} \u4E2A\u8D44\u6E90\u7C7B\u578B\uFF1B\u8BF7\u5728\u4EA4\u4E92\u7EC8\u7AEF\u8FD0\u884C ${commandText} \u67E5\u770B\u540E\u7EED\u9875`);
|
|
26675
|
+
}
|
|
26676
|
+
return;
|
|
26677
|
+
}
|
|
26678
|
+
const action = await selectQuestion("\u8D44\u6E90\u7C7B\u578B\u5217\u8868", [
|
|
26679
|
+
...current.hasPrevious ? [{ name: "\u4E0A\u4E00\u9875", value: "__previous__" }] : [],
|
|
26680
|
+
...current.hasNext ? [{ name: "\u4E0B\u4E00\u9875", value: "__next__" }] : [],
|
|
26681
|
+
{ name: "\u9000\u51FA", value: "__exit__" }
|
|
26682
|
+
]);
|
|
26683
|
+
if (action === "__exit__") return;
|
|
26684
|
+
page += action === "__next__" ? 1 : -1;
|
|
26685
|
+
}
|
|
26686
|
+
}
|
|
26251
26687
|
function createTypeCommand() {
|
|
26252
26688
|
const type = addSharedOptions(new Command14("type"));
|
|
26253
26689
|
type.description(
|
|
26254
26690
|
// i18n: cli.command.type.description
|
|
26255
|
-
"\u67E5\u8BE2\u53F6\u5B50\u7C7B\u578B"
|
|
26691
|
+
"\u67E5\u8BE2\u53EF\u9009\u6700\u7EC8\u53F6\u5B50\u7C7B\u578B"
|
|
26256
26692
|
);
|
|
26257
26693
|
addSharedOptions(type.command("list")).description(
|
|
26258
26694
|
// i18n: cli.command.type.list.description
|
|
26259
|
-
"\u5217\u51FA\u53F6\u5B50\u7C7B\u578B"
|
|
26695
|
+
"\u5217\u51FA\u6700\u7EC8\u53F6\u5B50\u7C7B\u578B\u7684\u5B8C\u6574\u5C42\u7EA7\u8DEF\u5F84"
|
|
26260
26696
|
).action(async function() {
|
|
26261
26697
|
requireTypeAuth(this);
|
|
26262
26698
|
const items = await listLeafTypes();
|
|
26263
|
-
|
|
26264
|
-
if (text) {
|
|
26265
|
-
console.log(text);
|
|
26266
|
-
}
|
|
26699
|
+
await showTypePages(items, "type list");
|
|
26267
26700
|
});
|
|
26268
26701
|
addSharedOptions(type.command("search")).description(
|
|
26269
26702
|
// i18n: cli.command.type.search.description
|
|
@@ -26275,10 +26708,7 @@ function createTypeCommand() {
|
|
|
26275
26708
|
).action(async function(keyword) {
|
|
26276
26709
|
requireTypeAuth(this);
|
|
26277
26710
|
const items = await searchLeafTypes(keyword ?? "");
|
|
26278
|
-
|
|
26279
|
-
if (text) {
|
|
26280
|
-
console.log(text);
|
|
26281
|
-
}
|
|
26711
|
+
await showTypePages(items, `type search ${keyword ?? ""}`.trim());
|
|
26282
26712
|
});
|
|
26283
26713
|
addSharedOptions(type.command("pick")).description(
|
|
26284
26714
|
// i18n: cli.command.type.pick.description
|
|
@@ -26291,14 +26721,11 @@ function createTypeCommand() {
|
|
|
26291
26721
|
requireTypeAuth(this);
|
|
26292
26722
|
if (!options.type) {
|
|
26293
26723
|
const items = await listLeafTypes();
|
|
26294
|
-
|
|
26295
|
-
if (text) {
|
|
26296
|
-
console.log(text);
|
|
26297
|
-
}
|
|
26724
|
+
await showTypePages(items, "type pick");
|
|
26298
26725
|
return;
|
|
26299
26726
|
}
|
|
26300
26727
|
const info2 = await getTypeInfo(options.type);
|
|
26301
|
-
console.log(
|
|
26728
|
+
console.log(formatTypeInfo(info2, await getTypeHierarchy(info2.code)));
|
|
26302
26729
|
});
|
|
26303
26730
|
addSharedOptions(type.command("info")).description(
|
|
26304
26731
|
// i18n: cli.command.type.info.description
|
|
@@ -26313,7 +26740,7 @@ function createTypeCommand() {
|
|
|
26313
26740
|
throw new CliError("\u8BF7\u63D0\u4F9B\u7C7B\u578B\u7F16\u53F7", "TYPE_CODE_REQUIRED");
|
|
26314
26741
|
}
|
|
26315
26742
|
const info2 = await getTypeInfo(code);
|
|
26316
|
-
console.log(
|
|
26743
|
+
console.log(formatTypeInfo(info2, await getTypeHierarchy(info2.code)));
|
|
26317
26744
|
});
|
|
26318
26745
|
return type;
|
|
26319
26746
|
}
|
|
@@ -26340,6 +26767,9 @@ async function syncResourceTitles(input2) {
|
|
|
26340
26767
|
if (!identity.resourceId) return { identity, error: "\u8D44\u6E90\u5C1A\u672A\u7ED1\u5B9A" };
|
|
26341
26768
|
try {
|
|
26342
26769
|
const data = unwrapData2(await info2({ resourceIdOrName: identity.resourceId, isLoadLatestVersionInfo: 1 }));
|
|
26770
|
+
if (data.resourceId !== identity.resourceId) {
|
|
26771
|
+
return { identity, error: "\u5E73\u53F0\u8BE6\u60C5\u7F3A\u5C11\u6216\u4E0D\u5339\u914D resourceId" };
|
|
26772
|
+
}
|
|
26343
26773
|
const title = String(data.resourceTitle ?? data.title ?? "");
|
|
26344
26774
|
if (!title) return { identity, error: "\u5E73\u53F0\u8BE6\u60C5\u7F3A\u5C11\u6807\u9898" };
|
|
26345
26775
|
return { identity, title };
|
|
@@ -26363,55 +26793,346 @@ async function syncResourceTitles(input2) {
|
|
|
26363
26793
|
}, "sync-resource-titles");
|
|
26364
26794
|
}
|
|
26365
26795
|
|
|
26366
|
-
// src/
|
|
26367
|
-
|
|
26368
|
-
|
|
26369
|
-
|
|
26370
|
-
|
|
26371
|
-
|
|
26372
|
-
|
|
26373
|
-
|
|
26796
|
+
// src/local/pendingOperation.ts
|
|
26797
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
26798
|
+
import { existsSync as existsSync13, readFileSync as readFileSync10, unlinkSync as unlinkSync6 } from "fs";
|
|
26799
|
+
import path15 from "path";
|
|
26800
|
+
import { z as z4 } from "zod";
|
|
26801
|
+
var pendingVersionSubmitV1Schema = z4.object({
|
|
26802
|
+
schemaVersion: z4.literal(1),
|
|
26803
|
+
operationId: z4.string().uuid(),
|
|
26804
|
+
kind: z4.literal("version-submit"),
|
|
26805
|
+
resourceN: z4.number().int().positive(),
|
|
26806
|
+
resourceId: z4.string().min(1),
|
|
26807
|
+
env: z4.enum(["prod", "test", "dev"]),
|
|
26808
|
+
version: z4.string().min(1),
|
|
26809
|
+
fileSha1: z4.string().min(1),
|
|
26810
|
+
createdAt: z4.string().min(1)
|
|
26811
|
+
}).strict();
|
|
26812
|
+
var pendingVersionSubmitV2Schema = pendingVersionSubmitV1Schema.omit({ schemaVersion: true }).extend({
|
|
26813
|
+
schemaVersion: z4.literal(2),
|
|
26814
|
+
state: z4.enum(["prepared", "sending"])
|
|
26815
|
+
}).strict();
|
|
26816
|
+
function pendingOperationFilePath(cwd) {
|
|
26817
|
+
return path15.join(freelogDir(cwd), ".pending-operation.json");
|
|
26374
26818
|
}
|
|
26375
|
-
|
|
26376
|
-
|
|
26377
|
-
import { Command as Command16 } from "commander";
|
|
26378
|
-
|
|
26379
|
-
// src/domain/online/online.ts
|
|
26380
|
-
async function loadInfo(resourceId, apis) {
|
|
26381
|
-
const infoApi2 = apis?.info ?? ((params) => service_API_default.Resource.info(params));
|
|
26382
|
-
return unwrapData2(
|
|
26383
|
-
await infoApi2({
|
|
26384
|
-
resourceIdOrName: resourceId,
|
|
26385
|
-
isLoadLatestVersionInfo: 1,
|
|
26386
|
-
isLoadPolicyInfo: 1
|
|
26387
|
-
})
|
|
26388
|
-
);
|
|
26819
|
+
function invalidPending() {
|
|
26820
|
+
throw new CliError("\u672A\u51B3\u8FDC\u7AEF\u64CD\u4F5C\u8BB0\u5F55\u65E0\u6548\uFF0C\u8BF7\u5148\u5907\u4EFD .freelog \u540E\u5904\u7406", "PENDING_OPERATION_INVALID");
|
|
26389
26821
|
}
|
|
26390
|
-
function
|
|
26391
|
-
|
|
26392
|
-
|
|
26822
|
+
function readPendingOperation(cwd) {
|
|
26823
|
+
const filePath = pendingOperationFilePath(cwd);
|
|
26824
|
+
if (!existsSync13(filePath)) return void 0;
|
|
26825
|
+
let raw;
|
|
26826
|
+
try {
|
|
26827
|
+
raw = JSON.parse(readFileSync10(filePath, "utf8"));
|
|
26828
|
+
} catch {
|
|
26829
|
+
return invalidPending();
|
|
26393
26830
|
}
|
|
26394
|
-
const
|
|
26395
|
-
if (
|
|
26396
|
-
|
|
26831
|
+
const v2 = pendingVersionSubmitV2Schema.safeParse(raw);
|
|
26832
|
+
if (v2.success) return v2.data;
|
|
26833
|
+
const v1 = pendingVersionSubmitV1Schema.safeParse(raw);
|
|
26834
|
+
if (v1.success) {
|
|
26835
|
+
return { ...v1.data, state: "sending" };
|
|
26397
26836
|
}
|
|
26837
|
+
return invalidPending();
|
|
26398
26838
|
}
|
|
26399
|
-
|
|
26400
|
-
|
|
26401
|
-
|
|
26402
|
-
|
|
26403
|
-
const
|
|
26404
|
-
|
|
26405
|
-
|
|
26406
|
-
|
|
26407
|
-
|
|
26408
|
-
|
|
26409
|
-
|
|
26410
|
-
|
|
26411
|
-
|
|
26412
|
-
|
|
26413
|
-
|
|
26839
|
+
function createPendingVersionSubmit(input2) {
|
|
26840
|
+
if (readPendingOperation(input2.cwd)) {
|
|
26841
|
+
throw new CliError("\u5B58\u5728\u7ED3\u679C\u672A\u77E5\u7684\u8FDC\u7AEF\u64CD\u4F5C\uFF1B\u8BF7\u5148 resource recover", "PENDING_OPERATION_EXISTS");
|
|
26842
|
+
}
|
|
26843
|
+
const pending = {
|
|
26844
|
+
schemaVersion: 2,
|
|
26845
|
+
operationId: randomUUID2(),
|
|
26846
|
+
kind: "version-submit",
|
|
26847
|
+
resourceN: input2.resourceN,
|
|
26848
|
+
resourceId: input2.resourceId,
|
|
26849
|
+
env: input2.env,
|
|
26850
|
+
version: input2.version,
|
|
26851
|
+
fileSha1: input2.fileSha1,
|
|
26852
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
26853
|
+
state: "prepared"
|
|
26854
|
+
};
|
|
26855
|
+
atomicWriteFile(pendingOperationFilePath(input2.cwd), `${JSON.stringify(pending, null, 2)}
|
|
26856
|
+
`);
|
|
26857
|
+
return pending;
|
|
26858
|
+
}
|
|
26859
|
+
function markPendingVersionSubmitSending(cwd) {
|
|
26860
|
+
const pending = readPendingOperation(cwd);
|
|
26861
|
+
if (!pending || pending.state !== "prepared") {
|
|
26862
|
+
throw new CliError("\u672A\u51B3\u7248\u672C\u63D0\u4EA4\u4E0D\u5904\u4E8E\u53EF\u53D1\u9001\u72B6\u6001\uFF0C\u62D2\u7EDD\u8C03\u7528\u5E73\u53F0", "PENDING_OPERATION_STATE_INVALID");
|
|
26863
|
+
}
|
|
26864
|
+
const sending = {
|
|
26865
|
+
...pending,
|
|
26866
|
+
schemaVersion: 2,
|
|
26867
|
+
state: "sending"
|
|
26868
|
+
};
|
|
26869
|
+
atomicWriteFile(pendingOperationFilePath(cwd), `${JSON.stringify(sending, null, 2)}
|
|
26870
|
+
`);
|
|
26871
|
+
return sending;
|
|
26872
|
+
}
|
|
26873
|
+
function clearPendingOperation(cwd) {
|
|
26874
|
+
const filePath = pendingOperationFilePath(cwd);
|
|
26875
|
+
if (!existsSync13(filePath)) return false;
|
|
26876
|
+
unlinkSync6(filePath);
|
|
26877
|
+
return true;
|
|
26878
|
+
}
|
|
26879
|
+
function assertNoPendingOperation(cwd) {
|
|
26880
|
+
const pending = readPendingOperation(cwd);
|
|
26881
|
+
if (pending) {
|
|
26882
|
+
throw new CliError(
|
|
26883
|
+
`\u5B58\u5728\u672A\u5B8C\u6210\u6536\u5C3E\u7684\u7248\u672C\u63D0\u4EA4\uFF08${pending.resourceId} ${pending.version}\uFF0C${pending.state}\uFF09\uFF1B\u8BF7\u5148 resource recover`,
|
|
26884
|
+
"PENDING_OPERATION_EXISTS"
|
|
26885
|
+
);
|
|
26886
|
+
}
|
|
26887
|
+
}
|
|
26888
|
+
|
|
26889
|
+
// src/domain/resource/recover.ts
|
|
26890
|
+
async function recoverPendingOperation(input2) {
|
|
26891
|
+
return withProjectLock(input2.cwd, () => recoverPendingOperationLocked(input2), "resource-recover");
|
|
26892
|
+
}
|
|
26893
|
+
async function recoverPendingOperationLocked(input2) {
|
|
26894
|
+
assertPlatformAllowed();
|
|
26895
|
+
const pending = readPendingOperation(input2.cwd);
|
|
26896
|
+
if (!pending) return "\u6CA1\u6709\u7ED3\u679C\u672A\u77E5\u7684\u8FDC\u7AEF\u64CD\u4F5C";
|
|
26897
|
+
const activeEnv2 = getEnv2();
|
|
26898
|
+
if (pending.env !== activeEnv2) {
|
|
26899
|
+
throw new CliError(
|
|
26900
|
+
`\u672A\u51B3\u64CD\u4F5C\u5C5E\u4E8E ${pending.env} \u73AF\u5883\uFF0C\u672C\u6B21\u662F ${activeEnv2}\uFF1B\u8BF7\u5207\u6362 --env \u540E\u6062\u590D`,
|
|
26901
|
+
"PENDING_OPERATION_ENV_MISMATCH"
|
|
26902
|
+
);
|
|
26903
|
+
}
|
|
26904
|
+
const identity = readIdentity(input2.cwd, pending.resourceN);
|
|
26905
|
+
if (identity.resourceId !== pending.resourceId || (identity.env ?? "prod") !== pending.env) {
|
|
26906
|
+
throw new CliError("\u672A\u51B3\u64CD\u4F5C\u4E0E\u5F53\u524D N.json \u8EAB\u4EFD\u6216\u73AF\u5883\u4E0D\u4E00\u81F4\uFF0C\u62D2\u7EDD\u731C\u6D4B\u6E05\u7406", "PENDING_OPERATION_LOCAL_MISMATCH");
|
|
26907
|
+
}
|
|
26908
|
+
const draft = readDraft(input2.cwd, identity.n);
|
|
26909
|
+
if (draft?.resourceId && draft.resourceId !== pending.resourceId) {
|
|
26910
|
+
throw new CliError("\u672A\u51B3\u64CD\u4F5C\u4E0E\u5F53\u524D\u5DE5\u4F5C\u7A3F\u4E0D\u4E00\u81F4\uFF0C\u62D2\u7EDD\u731C\u6D4B\u6E05\u7406", "PENDING_OPERATION_LOCAL_MISMATCH");
|
|
26911
|
+
}
|
|
26912
|
+
if (pending.state === "prepared") {
|
|
26913
|
+
if (!input2.apply) {
|
|
26914
|
+
return `\u5C1A\u672A\u53D1\u9001\uFF1A${pending.resourceId} ${pending.version} \u7684\u63D0\u4EA4\u8BF7\u6C42\u5C1A\u672A\u5141\u8BB8\u53D1\u51FA\uFF1B\u5DE5\u4F5C\u7A3F\u5DF2\u4FDD\u7559\u3002\u8FD0\u884C resource recover --apply --yes \u4EC5\u6E05\u7406\u672A\u51B3\u8BB0\u5F55\u540E\u53EF\u91CD\u65B0\u63D0\u4EA4`;
|
|
26915
|
+
}
|
|
26916
|
+
if (!input2.yes) {
|
|
26917
|
+
throw new CliError("\u5E94\u7528\u6062\u590D\u4F1A\u6E05\u7406\u672A\u51B3\u8BB0\u5F55\uFF1B\u8BF7\u4F7F\u7528 resource recover --apply --yes", "RECOVER_APPLY_NEED_YES");
|
|
26918
|
+
}
|
|
26919
|
+
commitLocalTransaction(input2.cwd, [
|
|
26920
|
+
{ path: pendingOperationFilePath(input2.cwd), content: null }
|
|
26921
|
+
]);
|
|
26922
|
+
return `\u5DF2\u5B8C\u6210\u6062\u590D\uFF1A${pending.resourceId} ${pending.version} \u7684\u672A\u51B3\u8BB0\u5F55\u5DF2\u6E05\u7406\uFF0C\u5DE5\u4F5C\u7A3F\u5DF2\u4FDD\u7559`;
|
|
26923
|
+
}
|
|
26924
|
+
const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
26925
|
+
const infoApi2 = input2.apis?.info ?? ((params) => service_API_default.Resource.info(params));
|
|
26926
|
+
const info2 = unwrapData2(await infoApi2({ resourceIdOrName: pending.resourceId }));
|
|
26927
|
+
assertRemoteResourceOwned({
|
|
26928
|
+
info: info2,
|
|
26929
|
+
resourceId: pending.resourceId,
|
|
26930
|
+
authUserId: auth.userId,
|
|
26931
|
+
codes: {
|
|
26932
|
+
invalid: "RECOVER_RESOURCE_INFO_INVALID",
|
|
26933
|
+
notOwner: "RECOVER_NOT_OWNER"
|
|
26934
|
+
}
|
|
26935
|
+
});
|
|
26936
|
+
const versionInfoApi = input2.apis?.resourceVersionInfo1 ?? ((params) => service_API_default.Resource.resourceVersionInfo1(params));
|
|
26937
|
+
const versionInfo = unwrapData2(await versionInfoApi({
|
|
26938
|
+
resourceId: pending.resourceId,
|
|
26939
|
+
version: pending.version
|
|
26940
|
+
}));
|
|
26941
|
+
const remoteSha = typeof versionInfo.fileSha1 === "string" ? versionInfo.fileSha1 : "";
|
|
26942
|
+
if (!remoteSha) {
|
|
26943
|
+
if (input2.apply) {
|
|
26944
|
+
throw new CliError("\u7EBF\u4E0A\u5C1A\u672A\u8BC1\u660E\u76EE\u6807\u7248\u672C\u5B58\u5728\uFF0C\u4E0D\u80FD\u5E94\u7528\u6062\u590D", "RECOVER_NOT_CONFIRMED");
|
|
26945
|
+
}
|
|
26946
|
+
return `\u672A\u786E\u8BA4\uFF1A\u7EBF\u4E0A\u4E0D\u5B58\u5728 ${pending.resourceId} \u7684\u7248\u672C ${pending.version}\uFF1B\u5DF2\u4FDD\u7559\u5DE5\u4F5C\u7A3F\u548C\u672A\u51B3\u8BB0\u5F55\uFF0C\u5207\u52FF\u91CD\u590D\u63D0\u4EA4`;
|
|
26947
|
+
}
|
|
26948
|
+
if (remoteSha !== pending.fileSha1) {
|
|
26949
|
+
if (input2.apply) {
|
|
26950
|
+
throw new CliError("\u7EBF\u4E0A\u76EE\u6807\u7248\u672C\u7684\u6587\u4EF6 SHA \u4E0D\u5339\u914D\uFF0C\u4E0D\u80FD\u5E94\u7528\u6062\u590D", "RECOVER_NOT_CONFIRMED");
|
|
26951
|
+
}
|
|
26952
|
+
return `\u51B2\u7A81\uFF1A\u7EBF\u4E0A ${pending.version} \u7684\u6587\u4EF6 SHA \u4E0E\u672A\u51B3\u8BB0\u5F55\u4E0D\u540C\uFF1B\u5DF2\u4FDD\u7559\u5DE5\u4F5C\u7A3F\u548C\u672A\u51B3\u8BB0\u5F55\uFF0C\u5207\u52FF\u91CD\u590D\u63D0\u4EA4`;
|
|
26953
|
+
}
|
|
26954
|
+
if (!input2.apply) {
|
|
26955
|
+
return `\u5DF2\u786E\u8BA4\uFF1A${pending.resourceId} ${pending.version} \u5DF2\u4EE5\u76F8\u540C SHA \u63D0\u4EA4\u3002\u8FD0\u884C resource recover --apply --yes \u6E05\u7406\u672C\u5730\u5DE5\u4F5C\u7A3F\u548C\u672A\u51B3\u8BB0\u5F55`;
|
|
26956
|
+
}
|
|
26957
|
+
if (!input2.yes) {
|
|
26958
|
+
throw new CliError("\u5E94\u7528\u6062\u590D\u4F1A\u5220\u9664\u672C\u5730\u5DE5\u4F5C\u7A3F\uFF1B\u8BF7\u4F7F\u7528 resource recover --apply --yes", "RECOVER_APPLY_NEED_YES");
|
|
26959
|
+
}
|
|
26960
|
+
commitLocalTransaction(input2.cwd, [
|
|
26961
|
+
{ path: pendingOperationFilePath(input2.cwd), content: null },
|
|
26962
|
+
{ path: draftFilePath(input2.cwd, identity.n), content: null }
|
|
26963
|
+
]);
|
|
26964
|
+
return `\u5DF2\u5B8C\u6210\u6062\u590D\uFF1A${pending.resourceId} ${pending.version} \u7684\u672C\u5730\u5DE5\u4F5C\u7A3F\u548C\u672A\u51B3\u8BB0\u5F55\u5DF2\u6E05\u7406`;
|
|
26965
|
+
}
|
|
26966
|
+
|
|
26967
|
+
// src/local/diagnostics.ts
|
|
26968
|
+
import { existsSync as existsSync14, readdirSync as readdirSync5 } from "fs";
|
|
26969
|
+
var IDENTITY_FILE_RE2 = /^([1-9]\d*)\.json$/;
|
|
26970
|
+
var DRAFT_FILE_RE2 = /^([1-9]\d*)\.version\.json$/;
|
|
26971
|
+
function errorMessage(error2) {
|
|
26972
|
+
return error2 instanceof Error ? error2.message : "\u672A\u77E5\u9519\u8BEF";
|
|
26973
|
+
}
|
|
26974
|
+
function duplicateDiagnostics(cwd, identities) {
|
|
26975
|
+
const result = [];
|
|
26976
|
+
for (const key of ["resourceId", "resourceName", "filePath"]) {
|
|
26977
|
+
const seen = /* @__PURE__ */ new Map();
|
|
26978
|
+
for (const identity of identities) {
|
|
26979
|
+
const raw = identity[key];
|
|
26980
|
+
if (!raw) continue;
|
|
26981
|
+
let value;
|
|
26982
|
+
try {
|
|
26983
|
+
value = key === "filePath" ? normalizeProjectPath(cwd, raw) : raw;
|
|
26984
|
+
} catch (error2) {
|
|
26985
|
+
result.push({ file: `${identity.n}.json`, code: "IDENTITY_PATH_INVALID", message: errorMessage(error2) });
|
|
26986
|
+
continue;
|
|
26987
|
+
}
|
|
26988
|
+
const previous = seen.get(value);
|
|
26989
|
+
if (previous !== void 0) {
|
|
26990
|
+
result.push({
|
|
26991
|
+
file: `${identity.n}.json`,
|
|
26992
|
+
code: "IDENTITY_CONFLICT",
|
|
26993
|
+
message: `\u4E0E ${previous}.json \u4F7F\u7528\u76F8\u540C ${key}`
|
|
26994
|
+
});
|
|
26995
|
+
} else {
|
|
26996
|
+
seen.set(value, identity.n);
|
|
26997
|
+
}
|
|
26998
|
+
}
|
|
26999
|
+
}
|
|
27000
|
+
return result;
|
|
27001
|
+
}
|
|
27002
|
+
function diagnoseLocalState(cwd) {
|
|
27003
|
+
const dir = freelogDir(cwd);
|
|
27004
|
+
if (!existsSync14(dir)) return "\u6CA1\u6709 .freelog \u672C\u5730\u72B6\u6001";
|
|
27005
|
+
let entries;
|
|
27006
|
+
try {
|
|
27007
|
+
entries = readdirSync5(dir).sort((left, right) => left.localeCompare(right, "en"));
|
|
27008
|
+
} catch (error2) {
|
|
27009
|
+
return `\u65E0\u6CD5\u8BFB\u53D6 .freelog\uFF1A${errorMessage(error2)}`;
|
|
27010
|
+
}
|
|
27011
|
+
const lines = [];
|
|
27012
|
+
const diagnostics = [];
|
|
27013
|
+
const identityNumbers = /* @__PURE__ */ new Set();
|
|
27014
|
+
const validIdentities = [];
|
|
27015
|
+
for (const file of entries) {
|
|
27016
|
+
const match = IDENTITY_FILE_RE2.exec(file);
|
|
27017
|
+
if (!match) continue;
|
|
27018
|
+
const n = Number(match[1]);
|
|
27019
|
+
identityNumbers.add(n);
|
|
27020
|
+
try {
|
|
27021
|
+
const identity = readIdentity(cwd, n);
|
|
27022
|
+
validIdentities.push(identity);
|
|
27023
|
+
lines.push(`${file}\uFF1A\u6709\u6548\uFF08${identity.resourceId ?? "\u672A\u7ED1\u5B9A"}\uFF0C${identity.typeCode}\uFF0C${identity.filePath}\uFF09`);
|
|
27024
|
+
} catch (error2) {
|
|
27025
|
+
diagnostics.push({ file, code: "IDENTITY_INVALID", message: errorMessage(error2) });
|
|
27026
|
+
}
|
|
27027
|
+
}
|
|
27028
|
+
for (const file of entries) {
|
|
27029
|
+
const match = DRAFT_FILE_RE2.exec(file);
|
|
27030
|
+
if (!match) continue;
|
|
27031
|
+
const n = Number(match[1]);
|
|
27032
|
+
if (!identityNumbers.has(n)) {
|
|
27033
|
+
diagnostics.push({ file, code: "DRAFT_ORPHAN", message: `\u6CA1\u6709\u540C\u53F7 ${n}.json` });
|
|
27034
|
+
continue;
|
|
27035
|
+
}
|
|
27036
|
+
if (!validIdentities.some((identity) => identity.n === n)) {
|
|
27037
|
+
diagnostics.push({ file, code: "DRAFT_IDENTITY_INVALID", message: `\u540C\u53F7 ${n}.json \u5DF2\u635F\u574F\uFF0C\u65E0\u6CD5\u6838\u9A8C\u5DE5\u4F5C\u7A3F` });
|
|
27038
|
+
continue;
|
|
27039
|
+
}
|
|
27040
|
+
try {
|
|
27041
|
+
const draft = readDraft(cwd, n);
|
|
27042
|
+
lines.push(`${file}\uFF1A\u6709\u6548\uFF08${draft?.draftKind ?? "\u65E0"} \u5DE5\u4F5C\u7A3F\uFF09`);
|
|
27043
|
+
} catch (error2) {
|
|
27044
|
+
diagnostics.push({ file, code: "DRAFT_INVALID", message: errorMessage(error2) });
|
|
27045
|
+
}
|
|
27046
|
+
}
|
|
27047
|
+
diagnostics.push(...duplicateDiagnostics(cwd, validIdentities));
|
|
27048
|
+
if (entries.includes("index.json")) {
|
|
27049
|
+
lines.push("index.json\uFF1A\u5386\u53F2\u9057\u7559\u6587\u4EF6\uFF0C\u5F53\u524D CLI \u4E0D\u8BFB\u53D6\u3001\u4E0D\u91CD\u5EFA\u4E5F\u4E0D\u81EA\u52A8\u5220\u9664");
|
|
27050
|
+
}
|
|
27051
|
+
try {
|
|
27052
|
+
const pending = readPendingOperation(cwd);
|
|
27053
|
+
if (pending) lines.push(`.pending-operation.json\uFF1A\u672A\u51B3 ${pending.kind}\uFF08${pending.resourceId} ${pending.version}\uFF09`);
|
|
27054
|
+
} catch (error2) {
|
|
27055
|
+
diagnostics.push({ file: ".pending-operation.json", code: "PENDING_OPERATION_INVALID", message: errorMessage(error2) });
|
|
27056
|
+
}
|
|
27057
|
+
if (entries.includes(".txn.json")) {
|
|
27058
|
+
lines.push(".txn.json\uFF1A\u5B58\u5728\uFF1B\u4E0B\u4E00\u6B21\u6301\u9501\u4E1A\u52A1\u547D\u4EE4\u4F1A\u5C1D\u8BD5\u6062\u590D\uFF0C\u8BCA\u65AD\u547D\u4EE4\u4E0D\u4F1A\u56DE\u653E");
|
|
27059
|
+
}
|
|
27060
|
+
if (lines.length === 0) lines.push("\u6CA1\u6709\u53EF\u8BC6\u522B\u7684\u8D44\u6E90\u8EAB\u4EFD\u6216\u5DE5\u4F5C\u7A3F");
|
|
27061
|
+
if (diagnostics.length === 0) return `\u672C\u5730\u72B6\u6001\u6B63\u5E38\uFF1A
|
|
27062
|
+
${lines.map((line) => `- ${line}`).join("\n")}`;
|
|
27063
|
+
return [
|
|
27064
|
+
"\u672C\u5730\u72B6\u6001\u5B58\u5728\u95EE\u9898\uFF08\u672A\u4FEE\u6539\u4EFB\u4F55\u6587\u4EF6\uFF09\uFF1A",
|
|
27065
|
+
...lines.map((line) => `- ${line}`),
|
|
27066
|
+
...diagnostics.map((item) => `- ${item.file} [${item.code}]\uFF1A${item.message}`),
|
|
27067
|
+
"\u8BF7\u5148\u5907\u4EFD .freelog\uFF1B\u4FEE\u590D\u6216\u5220\u9664\u660E\u786E\u65E0\u7528\u7684\u5B8C\u6574\u72B6\u6001\u5355\u5143\u540E\u518D\u6267\u884C\u4E1A\u52A1\u547D\u4EE4\u3002"
|
|
27068
|
+
].join("\n");
|
|
27069
|
+
}
|
|
27070
|
+
|
|
27071
|
+
// src/commands/project/resource.ts
|
|
27072
|
+
function createResourceCommand() {
|
|
27073
|
+
const resource = addSharedOptions(new Command15("resource")).description("\u8D44\u6E90\u672C\u5730\u72B6\u6001\u7EF4\u62A4");
|
|
27074
|
+
resource.command("list").description("\u53EA\u8BFB\u8BCA\u65AD\u672C\u5730\u8D44\u6E90\u72B6\u6001\uFF08\u635F\u574F\u65F6\u4E5F\u53EF\u8FD0\u884C\uFF09").action(function() {
|
|
27075
|
+
const shared = readSharedOptions(this);
|
|
27076
|
+
console.log(diagnoseLocalState(resolveCwd(shared.cwd)));
|
|
27077
|
+
});
|
|
27078
|
+
resource.command("sync").description("\u4ECE\u5E73\u53F0\u540C\u6B65\u672C\u5730\u8D44\u6E90\u6807\u9898").action(async function() {
|
|
27079
|
+
const shared = readSharedOptions(this);
|
|
27080
|
+
console.log(await syncResourceTitles({ cwd: resolveCwd(shared.cwd), selector: shared.file }));
|
|
27081
|
+
});
|
|
27082
|
+
resource.command("recover").description("\u5904\u7406\u672A\u51B3\u7248\u672C\u63D0\u4EA4\uFF0C\u7EDD\u4E0D\u91CD\u53D1").option("--apply", "prepared \u4EC5\u6E05 marker\uFF1Bsending \u987B\u8FDC\u7AEF\u7248\u672C\u548C SHA \u5DF2\u8BC1\u660E\u6210\u529F\u624D\u6E05\u7406\u7A3F").action(async function() {
|
|
27083
|
+
const shared = readSharedOptions(this);
|
|
27084
|
+
const options = this.opts();
|
|
27085
|
+
console.log(await recoverPendingOperation({
|
|
27086
|
+
cwd: resolveCwd(shared.cwd),
|
|
27087
|
+
apply: options.apply === true,
|
|
27088
|
+
yes: shared.yes
|
|
27089
|
+
}));
|
|
27090
|
+
});
|
|
27091
|
+
return resource;
|
|
27092
|
+
}
|
|
27093
|
+
|
|
27094
|
+
// src/commands/shelf/offline.ts
|
|
27095
|
+
import { Command as Command16 } from "commander";
|
|
27096
|
+
|
|
27097
|
+
// src/domain/online/online.ts
|
|
27098
|
+
async function loadInfo(resourceId, apis) {
|
|
27099
|
+
const infoApi2 = apis?.info ?? ((params) => service_API_default.Resource.info(params));
|
|
27100
|
+
return unwrapData2(
|
|
27101
|
+
await infoApi2({
|
|
27102
|
+
resourceIdOrName: resourceId,
|
|
27103
|
+
isLoadLatestVersionInfo: 1,
|
|
27104
|
+
isLoadPolicyInfo: 1
|
|
27105
|
+
})
|
|
27106
|
+
);
|
|
27107
|
+
}
|
|
27108
|
+
function validateForOnline(info2) {
|
|
27109
|
+
if (!info2.latestVersion) {
|
|
27110
|
+
throw new CliError("\u4E0A\u67B6\u987B\u5DF2\u6709\u7248\u672C", "ONLINE_NO_VERSION");
|
|
27111
|
+
}
|
|
27112
|
+
const policies2 = info2.policies ?? [];
|
|
27113
|
+
if (!policies2.some((item) => item.status === 1)) {
|
|
27114
|
+
throw new CliError("\u4E0A\u67B6\u987B\u81F3\u5C11\u4E00\u6761\u542F\u7528\u7B56\u7565", "ONLINE_NO_POLICY");
|
|
27115
|
+
}
|
|
27116
|
+
}
|
|
27117
|
+
async function onlineResource(input2) {
|
|
27118
|
+
assertPlatformAllowed();
|
|
27119
|
+
const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
26414
27120
|
const identity = resolveBoundIdentity(input2.cwd, input2.file);
|
|
27121
|
+
const info2 = await loadInfo(identity.resourceId, input2.apis);
|
|
27122
|
+
assertRemoteResourceWritable({ info: info2, resourceId: identity.resourceId, authUserId: auth.userId });
|
|
27123
|
+
validateForOnline(info2);
|
|
27124
|
+
const update2 = input2.apis?.update ?? ((params) => service_API_default.Resource.update(params));
|
|
27125
|
+
await update2({
|
|
27126
|
+
resourceId: identity.resourceId,
|
|
27127
|
+
status: 1
|
|
27128
|
+
});
|
|
27129
|
+
}
|
|
27130
|
+
async function offlineResource(input2) {
|
|
27131
|
+
assertPlatformAllowed();
|
|
27132
|
+
const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
27133
|
+
const identity = resolveBoundIdentity(input2.cwd, input2.file);
|
|
27134
|
+
const info2 = await loadInfo(identity.resourceId, input2.apis);
|
|
27135
|
+
assertRemoteResourceWritable({ info: info2, resourceId: identity.resourceId, authUserId: auth.userId });
|
|
26415
27136
|
const update2 = input2.apis?.update ?? ((params) => service_API_default.Resource.update(params));
|
|
26416
27137
|
await update2({
|
|
26417
27138
|
resourceId: identity.resourceId,
|
|
@@ -26461,7 +27182,7 @@ async function validateOnline(input2) {
|
|
|
26461
27182
|
throw new CliError("\u76EE\u524D\u53EA\u652F\u6301 --for online", "VALIDATE_FOR");
|
|
26462
27183
|
}
|
|
26463
27184
|
assertPlatformAllowed();
|
|
26464
|
-
requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
27185
|
+
const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
26465
27186
|
const identity = resolveBoundIdentity(input2.cwd, input2.file);
|
|
26466
27187
|
const infoApi2 = input2.apis?.info ?? ((params) => service_API_default.Resource.info(params));
|
|
26467
27188
|
const result = await infoApi2({
|
|
@@ -26470,6 +27191,11 @@ async function validateOnline(input2) {
|
|
|
26470
27191
|
isLoadPolicyInfo: 1
|
|
26471
27192
|
});
|
|
26472
27193
|
const data = result.data ?? result;
|
|
27194
|
+
assertRemoteResourceWritable({
|
|
27195
|
+
info: data,
|
|
27196
|
+
resourceId: identity.resourceId,
|
|
27197
|
+
authUserId: auth.userId
|
|
27198
|
+
});
|
|
26473
27199
|
validateForOnline(data);
|
|
26474
27200
|
return "\u53EF\u4EE5\u4E0A\u67B6";
|
|
26475
27201
|
}
|
|
@@ -26753,6 +27479,42 @@ function attrList(cwd, file) {
|
|
|
26753
27479
|
);
|
|
26754
27480
|
return list2.map((item) => `${item.key}=${item.defaultValue ?? ""} ${item.name ?? ""}`).join("\n");
|
|
26755
27481
|
}
|
|
27482
|
+
function attrReview(cwd, file) {
|
|
27483
|
+
const identity = resolveIdentity(cwd, file);
|
|
27484
|
+
const draft = readDraft(cwd, identity.n);
|
|
27485
|
+
if (!draft) {
|
|
27486
|
+
throw new CliError("\u6CA1\u6709\u5DE5\u4F5C\u7A3F\uFF0C\u8BF7\u5148 version draft pull", "DRAFT_MISSING");
|
|
27487
|
+
}
|
|
27488
|
+
const items = draft.orphanedInputAttrs ?? [];
|
|
27489
|
+
if (items.length === 0) return "\u6CA1\u6709\u5F85\u590D\u6838\u7684\u9644\u52A0\u5C5E\u6027";
|
|
27490
|
+
return [
|
|
27491
|
+
"\u4EE5\u4E0B\u9644\u52A0\u5C5E\u6027\u5DF2\u4E0D\u5728\u5F53\u524D\u6587\u4EF6\u5206\u6790\u7ED3\u679C\u4E2D\uFF0C\u4E0D\u80FD\u63D0\u4EA4\uFF1A",
|
|
27492
|
+
...items.map((item) => ` ${String(item.key ?? "\uFF08\u65E0\u952E\uFF09")}=${String(item.value ?? "")}`),
|
|
27493
|
+
"\u91CD\u65B0\u4E0A\u4F20\u5305\u542B\u8BE5 key \u7684\u6587\u4EF6\u4F1A\u81EA\u52A8\u6062\u590D\uFF1B\u786E\u8BA4\u4E0D\u518D\u9700\u8981\u53EF\u6267\u884C version attr review discard <key>\u3002"
|
|
27494
|
+
].join("\n");
|
|
27495
|
+
}
|
|
27496
|
+
async function attrReviewDiscard(cwd, input2) {
|
|
27497
|
+
return withProjectLock(cwd, () => attrReviewDiscardLocked(cwd, input2), "version-attr-review-discard");
|
|
27498
|
+
}
|
|
27499
|
+
async function attrReviewDiscardLocked(cwd, input2) {
|
|
27500
|
+
const identity = resolveIdentity(cwd, input2.file);
|
|
27501
|
+
const draft = readDraft(cwd, identity.n);
|
|
27502
|
+
if (!draft) {
|
|
27503
|
+
throw new CliError("\u6CA1\u6709\u5DE5\u4F5C\u7A3F\uFF0C\u8BF7\u5148 version draft pull", "DRAFT_MISSING");
|
|
27504
|
+
}
|
|
27505
|
+
const key = input2.key.trim();
|
|
27506
|
+
const items = draft.orphanedInputAttrs ?? [];
|
|
27507
|
+
if (!key || !items.some((item) => item.key === key)) {
|
|
27508
|
+
throw new CliError("\u627E\u4E0D\u5230\u5F85\u590D\u6838\u9644\u52A0\u5C5E\u6027", "ATTR_REVIEW_NOT_FOUND");
|
|
27509
|
+
}
|
|
27510
|
+
const preview = `\u5373\u5C06\u4E22\u5F03\u5F85\u590D\u6838\u9644\u52A0\u5C5E\u6027\uFF1A${key}`;
|
|
27511
|
+
if (!await confirmDestructive(preview, "\u4E22\u5F03\u5F85\u590D\u6838\u9644\u52A0\u5C5E\u6027", input2.yes)) {
|
|
27512
|
+
return "\u5DF2\u53D6\u6D88";
|
|
27513
|
+
}
|
|
27514
|
+
draft.orphanedInputAttrs = items.filter((item) => item.key !== key);
|
|
27515
|
+
writeDraft(cwd, identity.n, draft);
|
|
27516
|
+
return preview;
|
|
27517
|
+
}
|
|
26756
27518
|
|
|
26757
27519
|
// src/commands/version/attr.ts
|
|
26758
27520
|
function createVersionAttrCommand() {
|
|
@@ -26774,12 +27536,232 @@ function createVersionAttrCommand() {
|
|
|
26774
27536
|
const shared = readSharedOptions(this);
|
|
26775
27537
|
console.log(attrList(resolveCwd(shared.cwd), shared.file));
|
|
26776
27538
|
});
|
|
27539
|
+
const review = addSharedOptions(attr.command("review")).description("\u67E5\u770B\u6216\u5904\u7406\u6587\u4EF6\u5206\u6790\u53D8\u5316\u540E\u7684\u9644\u52A0\u5C5E\u6027");
|
|
27540
|
+
review.action(function() {
|
|
27541
|
+
const shared = readSharedOptions(this);
|
|
27542
|
+
console.log(attrReview(resolveCwd(shared.cwd), shared.file));
|
|
27543
|
+
});
|
|
27544
|
+
addSharedOptions(review.command("discard")).description("\u786E\u8BA4\u4E22\u5F03\u4E00\u9879\u5F85\u590D\u6838\u9644\u52A0\u5C5E\u6027").argument("<key>", "\u9644\u52A0\u5C5E\u6027\u952E").action(async function(key) {
|
|
27545
|
+
const shared = readSharedOptions(this);
|
|
27546
|
+
console.log(await attrReviewDiscard(resolveCwd(shared.cwd), {
|
|
27547
|
+
key,
|
|
27548
|
+
file: shared.file,
|
|
27549
|
+
yes: shared.yes
|
|
27550
|
+
}));
|
|
27551
|
+
});
|
|
26777
27552
|
return attr;
|
|
26778
27553
|
}
|
|
26779
27554
|
|
|
26780
27555
|
// src/commands/version/create-version.ts
|
|
26781
27556
|
import { Command as Command20 } from "commander";
|
|
26782
27557
|
|
|
27558
|
+
// src/domain/version/form/option.ts
|
|
27559
|
+
var MAX_OPTION = 30;
|
|
27560
|
+
var MAX_OPTION_ITEM = 30;
|
|
27561
|
+
var MAX_TEXT_DEFAULT = 140;
|
|
27562
|
+
var MAX_NAME2 = 50;
|
|
27563
|
+
var MAX_REMARK2 = 50;
|
|
27564
|
+
function assertValidName2(name) {
|
|
27565
|
+
if (name.length > MAX_NAME2) {
|
|
27566
|
+
throw new CliError("\u540D\u79F0\u4E0D\u80FD\u8D85\u8FC750\u4E2A\u5B57\u7B26", "OPTION_NAME_LONG");
|
|
27567
|
+
}
|
|
27568
|
+
}
|
|
27569
|
+
function assertValidRemark2(remark) {
|
|
27570
|
+
if (remark.length > MAX_REMARK2) {
|
|
27571
|
+
throw new CliError("\u4E0D\u80FD\u8D85\u8FC750\u4E2A\u5B57\u7B26\u3002", "OPTION_REMARK_LONG");
|
|
27572
|
+
}
|
|
27573
|
+
}
|
|
27574
|
+
function assertOptionValueLength(value) {
|
|
27575
|
+
if (value.length > MAX_TEXT_DEFAULT) {
|
|
27576
|
+
throw new CliError("\u4E0D\u8D85\u8FC7140\u4E2A\u5B57\u7B26", "OPTION_VALUE_LONG");
|
|
27577
|
+
}
|
|
27578
|
+
}
|
|
27579
|
+
function isOption(item) {
|
|
27580
|
+
return item.type === "editableText" || item.type === "select";
|
|
27581
|
+
}
|
|
27582
|
+
async function assertTypeAllowsOption(input2) {
|
|
27583
|
+
if (input2.supportOptionalConfig === true) return;
|
|
27584
|
+
if (input2.supportOptionalConfig === false) {
|
|
27585
|
+
throw new CliError("\u5F53\u524D\u7C7B\u578B\u4E0D\u652F\u6301\u53EF\u9009\u914D\u7F6E", "OPTION_UNSUPPORTED");
|
|
27586
|
+
}
|
|
27587
|
+
requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
27588
|
+
const type = await getTypeInfo(input2.typeCode, input2.apis);
|
|
27589
|
+
if (type.supportOptionalConfig !== 2) {
|
|
27590
|
+
throw new CliError("\u5F53\u524D\u7C7B\u578B\u4E0D\u652F\u6301\u53EF\u9009\u914D\u7F6E", "OPTION_UNSUPPORTED");
|
|
27591
|
+
}
|
|
27592
|
+
}
|
|
27593
|
+
async function assertDraftOptionsAllowed(input2) {
|
|
27594
|
+
if (!(input2.customPropertyDescriptors ?? []).some((item) => isOption(item))) return;
|
|
27595
|
+
await assertTypeAllowsOption(input2);
|
|
27596
|
+
}
|
|
27597
|
+
function optionListFromDraft(draft) {
|
|
27598
|
+
return (draft.customPropertyDescriptors ?? []).filter((item) => isOption(item));
|
|
27599
|
+
}
|
|
27600
|
+
function normalizeMode(mode) {
|
|
27601
|
+
if (mode === void 0) return void 0;
|
|
27602
|
+
if (mode === "\u4E0B\u62C9" || mode === "\u4E0B\u62C9\u5217\u8868" || mode === "select") return "select";
|
|
27603
|
+
if (mode === "\u6587\u672C" || mode === "\u6587\u672C\u8F93\u5165\u6846" || mode === "input") return "editableText";
|
|
27604
|
+
throw new CliError("\u65B9\u5F0F\u53EA\u80FD\u662F\u6587\u672C\u6216\u4E0B\u62C9", "OPTION_MODE");
|
|
27605
|
+
}
|
|
27606
|
+
function parseCandidates(raw) {
|
|
27607
|
+
const items = (raw ?? "").split("|").map((item) => item.trim()).filter(Boolean);
|
|
27608
|
+
if (items.length === 0) throw new CliError("\u4E0B\u62C9\u81F3\u5C11\u9700\u8981 1 \u4E2A\u9009\u9879", "OPTION_OPTIONS");
|
|
27609
|
+
if (items.length > MAX_OPTION_ITEM) throw new CliError("\u9009\u9879\u4E2A\u6570\u4E0D\u80FD\u8D85\u8FC730\u9879", "OPTION_OPTIONS");
|
|
27610
|
+
for (const item of items) assertOptionValueLength(item);
|
|
27611
|
+
if (items.some((item, index) => items.indexOf(item) !== index)) {
|
|
27612
|
+
throw new CliError("\u8BE5\u9009\u9879\u5DF2\u5B58\u5728", "OPTION_DUPLICATE_OPTION");
|
|
27613
|
+
}
|
|
27614
|
+
return items;
|
|
27615
|
+
}
|
|
27616
|
+
async function optionAdd(cwd, input2) {
|
|
27617
|
+
return withProjectLock(cwd, () => optionAddLocked(cwd, input2), "version-option-add");
|
|
27618
|
+
}
|
|
27619
|
+
async function optionAddLocked(cwd, input2) {
|
|
27620
|
+
const identity = resolveIdentity(cwd, input2.file);
|
|
27621
|
+
await assertTypeAllowsOption({ cwd, typeCode: identity.typeCode, ...input2 });
|
|
27622
|
+
const draft = readDraft(cwd, identity.n) ?? {
|
|
27623
|
+
baseUpcastResources: [],
|
|
27624
|
+
authExcludedItems: []
|
|
27625
|
+
};
|
|
27626
|
+
const parsed = parseLine(input2.line ?? "");
|
|
27627
|
+
if (!parsed.name || !parsed.key) {
|
|
27628
|
+
throw new CliError("\u53EF\u9009\u914D\u7F6E\u9700\u8981\u540D\u79F0\u548C\u952E", "OPTION_FIELDS");
|
|
27629
|
+
}
|
|
27630
|
+
assertValidKey(parsed.key);
|
|
27631
|
+
const list2 = draft.customPropertyDescriptors ?? [];
|
|
27632
|
+
if (optionListFromDraft(draft).length >= MAX_OPTION) {
|
|
27633
|
+
throw new CliError("\u6700\u591A\u53EF\u6DFB\u52A030\u4E2A\u53EF\u9009\u914D\u7F6E", "OPTION_FULL");
|
|
27634
|
+
}
|
|
27635
|
+
if (list2.some((item) => item.key === parsed.key)) {
|
|
27636
|
+
throw new CliError(`\u952E ${parsed.key} \u5DF2\u5B58\u5728`, "OPTION_DUPLICATE");
|
|
27637
|
+
}
|
|
27638
|
+
if (list2.some((item) => item.name === parsed.name)) {
|
|
27639
|
+
throw new CliError("\u540D\u79F0\u5DF2\u5B58\u5728", "OPTION_NAME_DUPLICATE");
|
|
27640
|
+
}
|
|
27641
|
+
const normalizedMode = normalizeMode(parsed.mode);
|
|
27642
|
+
if (!normalizedMode) {
|
|
27643
|
+
throw new CliError("\u65B9\u5F0F\u53EA\u80FD\u662F\u6587\u672C\u6216\u4E0B\u62C9", "OPTION_MODE");
|
|
27644
|
+
}
|
|
27645
|
+
const isSelect = normalizedMode === "select";
|
|
27646
|
+
const isText = normalizedMode === "editableText";
|
|
27647
|
+
if (isSelect && parsed.defaultValue) {
|
|
27648
|
+
throw new CliError("\u4E0B\u62C9\u9ED8\u8BA4\u503C\u56FA\u5B9A\u4E3A\u7B2C\u4E00\u9879\uFF0C\u8BF7\u628A\u8981\u9ED8\u8BA4\u7684\u9009\u9879\u653E\u5728\u7B2C\u4E00\u4F4D", "OPTION_SELECT_DEFAULT");
|
|
27649
|
+
}
|
|
27650
|
+
if (isText && parsed.options) {
|
|
27651
|
+
throw new CliError("\u6587\u672C\u65B9\u5F0F\u4E0D\u8981\u5199\u9009\u9879", "OPTION_TEXT_OPTIONS");
|
|
27652
|
+
}
|
|
27653
|
+
if (!isSelect && !isText) {
|
|
27654
|
+
throw new CliError("\u65B9\u5F0F\u53EA\u80FD\u662F\u6587\u672C\u6216\u4E0B\u62C9", "OPTION_MODE");
|
|
27655
|
+
}
|
|
27656
|
+
let type = "editableText";
|
|
27657
|
+
let defaultValue = parsed.defaultValue ?? parsed.value ?? "";
|
|
27658
|
+
let candidateItems;
|
|
27659
|
+
assertValidName2(parsed.name);
|
|
27660
|
+
assertValidRemark2(parsed.remark ?? "");
|
|
27661
|
+
if (isSelect) {
|
|
27662
|
+
const options = parseCandidates(parsed.options);
|
|
27663
|
+
type = "select";
|
|
27664
|
+
defaultValue = options[0] ?? "";
|
|
27665
|
+
candidateItems = options;
|
|
27666
|
+
} else {
|
|
27667
|
+
assertOptionValueLength(defaultValue);
|
|
27668
|
+
}
|
|
27669
|
+
const preview = await confirmWrite(previewLine(parsed), input2.yes);
|
|
27670
|
+
list2.push({
|
|
27671
|
+
name: parsed.name,
|
|
27672
|
+
key: parsed.key,
|
|
27673
|
+
remark: parsed.remark ?? "",
|
|
27674
|
+
defaultValue,
|
|
27675
|
+
type,
|
|
27676
|
+
...candidateItems ? { candidateItems } : {}
|
|
27677
|
+
});
|
|
27678
|
+
draft.customPropertyDescriptors = list2;
|
|
27679
|
+
writeDraft(cwd, identity.n, draft);
|
|
27680
|
+
return preview;
|
|
27681
|
+
}
|
|
27682
|
+
async function optionSet(cwd, input2) {
|
|
27683
|
+
return withProjectLock(cwd, () => optionSetLocked(cwd, input2), "version-option-set");
|
|
27684
|
+
}
|
|
27685
|
+
async function optionSetLocked(cwd, input2) {
|
|
27686
|
+
const identity = resolveIdentity(cwd, input2.file);
|
|
27687
|
+
const draft = readDraft(cwd, identity.n);
|
|
27688
|
+
if (!draft) {
|
|
27689
|
+
throw new CliError("\u6CA1\u6709\u5DE5\u4F5C\u7A3F\uFF0C\u8BF7\u5148 version draft pull", "DRAFT_MISSING");
|
|
27690
|
+
}
|
|
27691
|
+
const parsed = parseLine(input2.line ?? "");
|
|
27692
|
+
const found = (draft.customPropertyDescriptors ?? []).find(
|
|
27693
|
+
(item) => isOption(item) && (item.key === parsed.key || item.name === parsed.name)
|
|
27694
|
+
);
|
|
27695
|
+
if (!found) {
|
|
27696
|
+
throw new CliError("\u627E\u4E0D\u5230\u8FD9\u6761\u53EF\u9009\u914D\u7F6E", "OPTION_NOT_FOUND");
|
|
27697
|
+
}
|
|
27698
|
+
await assertTypeAllowsOption({ cwd, typeCode: identity.typeCode, ...input2 });
|
|
27699
|
+
assertKeyUnchanged(String(found.key), parsed.key);
|
|
27700
|
+
assertValidName2(parsed.name ?? String(found.name ?? ""));
|
|
27701
|
+
assertValidRemark2(parsed.remark ?? String(found.remark ?? ""));
|
|
27702
|
+
const nextType = normalizeMode(parsed.mode) ?? (String(found.type) === "select" ? "select" : "editableText");
|
|
27703
|
+
const nextDefault = parsed.defaultValue ?? parsed.value;
|
|
27704
|
+
if (nextType === "select" && nextDefault !== void 0) {
|
|
27705
|
+
throw new CliError("\u4E0B\u62C9\u9ED8\u8BA4\u503C\u56FA\u5B9A\u4E3A\u7B2C\u4E00\u9879\uFF0C\u8BF7\u628A\u8981\u9ED8\u8BA4\u7684\u9009\u9879\u653E\u5728\u7B2C\u4E00\u4F4D", "OPTION_SELECT_DEFAULT");
|
|
27706
|
+
}
|
|
27707
|
+
if (nextType === "editableText") {
|
|
27708
|
+
if (parsed.options !== void 0) {
|
|
27709
|
+
throw new CliError("\u6587\u672C\u65B9\u5F0F\u4E0D\u8981\u5199\u9009\u9879", "OPTION_TEXT_OPTIONS");
|
|
27710
|
+
}
|
|
27711
|
+
if (nextDefault !== void 0) assertOptionValueLength(nextDefault);
|
|
27712
|
+
}
|
|
27713
|
+
if (parsed.name && (draft.customPropertyDescriptors ?? []).some((item) => item.name === parsed.name && item.key !== found.key)) {
|
|
27714
|
+
throw new CliError("\u540D\u79F0\u5DF2\u5B58\u5728", "OPTION_NAME_DUPLICATE");
|
|
27715
|
+
}
|
|
27716
|
+
if (parsed.name) {
|
|
27717
|
+
found.name = parsed.name;
|
|
27718
|
+
}
|
|
27719
|
+
if (parsed.remark !== void 0) {
|
|
27720
|
+
found.remark = parsed.remark;
|
|
27721
|
+
}
|
|
27722
|
+
if (nextType === "select") {
|
|
27723
|
+
const candidates = parsed.options !== void 0 ? parseCandidates(parsed.options) : Array.isArray(found.candidateItems) ? found.candidateItems.map(String) : [];
|
|
27724
|
+
if (candidates.length === 0) {
|
|
27725
|
+
throw new CliError("\u4E0B\u62C9\u81F3\u5C11\u9700\u8981 1 \u4E2A\u9009\u9879", "OPTION_OPTIONS");
|
|
27726
|
+
}
|
|
27727
|
+
found.type = "select";
|
|
27728
|
+
found.candidateItems = candidates;
|
|
27729
|
+
found.defaultValue = candidates[0];
|
|
27730
|
+
} else {
|
|
27731
|
+
found.type = "editableText";
|
|
27732
|
+
delete found.candidateItems;
|
|
27733
|
+
if (nextDefault !== void 0) {
|
|
27734
|
+
found.defaultValue = nextDefault;
|
|
27735
|
+
}
|
|
27736
|
+
}
|
|
27737
|
+
const preview = await confirmWrite(previewLine(parsed), input2.yes);
|
|
27738
|
+
writeDraft(cwd, identity.n, draft);
|
|
27739
|
+
return preview;
|
|
27740
|
+
}
|
|
27741
|
+
function optionRm(cwd, key, file) {
|
|
27742
|
+
return withProjectLock(cwd, () => optionRmLocked(cwd, key, file), "version-option-rm");
|
|
27743
|
+
}
|
|
27744
|
+
function optionRmLocked(cwd, key, file) {
|
|
27745
|
+
const identity = resolveIdentity(cwd, file);
|
|
27746
|
+
const draft = readDraft(cwd, identity.n);
|
|
27747
|
+
if (!draft) {
|
|
27748
|
+
throw new CliError("\u6CA1\u6709\u5DE5\u4F5C\u7A3F\uFF0C\u8BF7\u5148 version draft pull", "DRAFT_MISSING");
|
|
27749
|
+
}
|
|
27750
|
+
const list2 = draft.customPropertyDescriptors ?? [];
|
|
27751
|
+
const next = list2.filter((item) => !(isOption(item) && item.key === key));
|
|
27752
|
+
if (next.length === list2.length) {
|
|
27753
|
+
throw new CliError("\u627E\u4E0D\u5230\u8FD9\u6761\u53EF\u9009\u914D\u7F6E", "OPTION_NOT_FOUND");
|
|
27754
|
+
}
|
|
27755
|
+
draft.customPropertyDescriptors = next;
|
|
27756
|
+
writeDraft(cwd, identity.n, draft);
|
|
27757
|
+
return key;
|
|
27758
|
+
}
|
|
27759
|
+
function optionList(cwd, file) {
|
|
27760
|
+
const identity = resolveIdentity(cwd, file);
|
|
27761
|
+
const draft = readDraft(cwd, identity.n);
|
|
27762
|
+
return optionListFromDraft(draft ?? {}).map((item) => `${item.key}=${item.defaultValue ?? ""} ${item.name ?? ""}`).join("\n");
|
|
27763
|
+
}
|
|
27764
|
+
|
|
26783
27765
|
// src/domain/version/submit.ts
|
|
26784
27766
|
function fieldName(error2) {
|
|
26785
27767
|
const rec = error2;
|
|
@@ -26804,6 +27786,9 @@ function buildVersionPayload(input2) {
|
|
|
26804
27786
|
};
|
|
26805
27787
|
}
|
|
26806
27788
|
async function submitVersion(input2) {
|
|
27789
|
+
return withProjectLock(input2.cwd, () => submitVersionLocked(input2), "submit-version");
|
|
27790
|
+
}
|
|
27791
|
+
async function submitVersionLocked(input2) {
|
|
26807
27792
|
assertPlatformAllowed();
|
|
26808
27793
|
if (!input2.identity.resourceId) {
|
|
26809
27794
|
throw new CliError("\u8BF7\u5148 create \u6216 bind", "SUBMIT_NO_RESOURCE");
|
|
@@ -26818,15 +27803,39 @@ async function submitVersion(input2) {
|
|
|
26818
27803
|
if ((draft.orphanedInputAttrs ?? []).length > 0) {
|
|
26819
27804
|
throw new CliError("\u6587\u4EF6\u5206\u6790\u53D8\u5316\u5F85\u5904\u7406\uFF0C\u8BF7\u5148\u4EBA\u5DE5\u590D\u6838\u9644\u52A0\u5C5E\u6027", "SUBMIT_ORPHANED_INPUT_ATTRS");
|
|
26820
27805
|
}
|
|
27806
|
+
await assertDraftOptionsAllowed({
|
|
27807
|
+
cwd: input2.cwd,
|
|
27808
|
+
typeCode: input2.identity.typeCode,
|
|
27809
|
+
customPropertyDescriptors: draft.customPropertyDescriptors,
|
|
27810
|
+
homeDir: input2.homeDir,
|
|
27811
|
+
apis: input2.apis
|
|
27812
|
+
});
|
|
26821
27813
|
const payload = buildVersionPayload({
|
|
26822
27814
|
resourceId: input2.identity.resourceId,
|
|
26823
27815
|
version: input2.version,
|
|
26824
27816
|
draft
|
|
26825
27817
|
});
|
|
26826
27818
|
const createVersion2 = input2.apis?.createVersion ?? ((params) => service_API_default.Resource.createVersion(params));
|
|
27819
|
+
assertNoPendingOperation(input2.cwd);
|
|
27820
|
+
createPendingVersionSubmit({
|
|
27821
|
+
cwd: input2.cwd,
|
|
27822
|
+
resourceN: input2.identity.n,
|
|
27823
|
+
resourceId: input2.identity.resourceId,
|
|
27824
|
+
env: getEnv2(),
|
|
27825
|
+
version: input2.version,
|
|
27826
|
+
fileSha1: draft.fileSha1
|
|
27827
|
+
});
|
|
27828
|
+
markPendingVersionSubmitSending(input2.cwd);
|
|
26827
27829
|
try {
|
|
26828
27830
|
await createVersion2(payload);
|
|
26829
27831
|
} catch (error2) {
|
|
27832
|
+
if (!isDefinitivePlatformRejection(error2)) {
|
|
27833
|
+
throw new CliError(
|
|
27834
|
+
"\u7248\u672C\u63D0\u4EA4\u8BF7\u6C42\u7ED3\u679C\u672A\u77E5\uFF1B\u8BF7\u8FD0\u884C resource recover \u6838\u9A8C\uFF0C\u5207\u52FF\u91CD\u590D\u63D0\u4EA4\u6216\u91CD\u65B0 bump",
|
|
27835
|
+
"SUBMIT_RESULT_UNKNOWN"
|
|
27836
|
+
);
|
|
27837
|
+
}
|
|
27838
|
+
clearPendingOperation(input2.cwd);
|
|
26830
27839
|
const field = fieldName(error2);
|
|
26831
27840
|
const detail = errorDetail(error2);
|
|
26832
27841
|
throw new CliError(
|
|
@@ -26834,21 +27843,30 @@ async function submitVersion(input2) {
|
|
|
26834
27843
|
"SUBMIT_FAILED"
|
|
26835
27844
|
);
|
|
26836
27845
|
}
|
|
26837
|
-
|
|
27846
|
+
commitLocalTransaction(input2.cwd, [
|
|
27847
|
+
{ path: draftFilePath(input2.cwd, input2.identity.n), content: null },
|
|
27848
|
+
{ path: pendingOperationFilePath(input2.cwd), content: null }
|
|
27849
|
+
]);
|
|
27850
|
+
}
|
|
27851
|
+
function isDefinitivePlatformRejection(error2) {
|
|
27852
|
+
if (error2 instanceof CliError) return true;
|
|
27853
|
+
const rec = error2;
|
|
27854
|
+
if (typeof rec.field === "string" || typeof rec.msg === "string" || typeof rec.result?.msg === "string") {
|
|
27855
|
+
return true;
|
|
27856
|
+
}
|
|
27857
|
+
const status = rec.status ?? rec.statusCode ?? rec.response?.status;
|
|
27858
|
+
return typeof status === "number" && status >= 400 && status < 500;
|
|
26838
27859
|
}
|
|
26839
27860
|
|
|
26840
27861
|
// src/domain/version/file.ts
|
|
26841
27862
|
import { createHash as createHash3 } from "crypto";
|
|
26842
|
-
import { existsSync as
|
|
26843
|
-
import
|
|
27863
|
+
import { createReadStream, existsSync as existsSync15, openAsBlob, statSync as statSync3, unlinkSync as unlinkSync7 } from "fs";
|
|
27864
|
+
import path16 from "path";
|
|
26844
27865
|
var ANALYZE_TIMEOUT_MS = 12e4;
|
|
26845
27866
|
var ANALYZE_POLL_INTERVAL_MS = 200;
|
|
26846
27867
|
function resolveExistingPath(cwd, raw) {
|
|
26847
|
-
|
|
26848
|
-
|
|
26849
|
-
}
|
|
26850
|
-
const joined = path15.resolve(cwd, raw);
|
|
26851
|
-
if (existsSync12(joined)) {
|
|
27868
|
+
const joined = path16.resolve(cwd, raw);
|
|
27869
|
+
if (existsSync15(joined)) {
|
|
26852
27870
|
return joined;
|
|
26853
27871
|
}
|
|
26854
27872
|
return void 0;
|
|
@@ -26860,11 +27878,13 @@ function confirmLocalPath(identity, file, yes, cwd) {
|
|
|
26860
27878
|
if (!resolved) {
|
|
26861
27879
|
throw new CliError(`\u672C\u5730\u6587\u4EF6\u4E0D\u5728\uFF1A${normalizedFile}\u3002\u4E0D\u51C6\u7EED\u7528 sha1`, "FILE_MISSING");
|
|
26862
27880
|
}
|
|
27881
|
+
resolveExistingProjectPath(cwd, resolved);
|
|
26863
27882
|
return resolved;
|
|
26864
27883
|
}
|
|
26865
27884
|
const recorded = identity.filePath ? normalizeProjectPath(cwd, identity.filePath) : void 0;
|
|
26866
27885
|
const recordedExists = recorded ? resolveExistingPath(cwd, recorded) : void 0;
|
|
26867
27886
|
if (recordedExists) {
|
|
27887
|
+
resolveExistingProjectPath(cwd, recordedExists);
|
|
26868
27888
|
return recordedExists;
|
|
26869
27889
|
}
|
|
26870
27890
|
if (yes) {
|
|
@@ -26894,24 +27914,55 @@ async function waitAnalyze(sha1, typeCode, apis, now = Date.now, sleep = (ms) =>
|
|
|
26894
27914
|
}
|
|
26895
27915
|
throw new CliError("\u5C5E\u6027\u89E3\u6790\u8D85\u65F6", "FILE_ANALYZE_TIMEOUT");
|
|
26896
27916
|
}
|
|
26897
|
-
function
|
|
26898
|
-
|
|
27917
|
+
function fingerprintFile(uploadPath) {
|
|
27918
|
+
const stats = statSync3(uploadPath);
|
|
27919
|
+
if (!stats.isFile()) {
|
|
27920
|
+
throw new CliError("\u4EA7\u7269\u5FC5\u987B\u662F\u53EF\u8BFB\u53D6\u7684\u6587\u4EF6", "FILE_ARTIFACT_UNSUPPORTED");
|
|
27921
|
+
}
|
|
27922
|
+
return { size: stats.size, mtimeMs: stats.mtimeMs, ctimeMs: stats.ctimeMs };
|
|
27923
|
+
}
|
|
27924
|
+
function assertFileUnchanged(uploadPath, expected) {
|
|
27925
|
+
const actual = fingerprintFile(uploadPath);
|
|
27926
|
+
if (actual.size !== expected.size || actual.mtimeMs !== expected.mtimeMs || actual.ctimeMs !== expected.ctimeMs) {
|
|
27927
|
+
throw new CliError(
|
|
27928
|
+
"\u53D1\u5E03\u671F\u95F4\u672C\u5730\u4EA7\u7269\u53D1\u751F\u53D8\u5316\uFF1B\u8BF7\u4FDD\u6301\u4EA7\u7269\u7A33\u5B9A\u540E\u91CD\u8BD5",
|
|
27929
|
+
"FILE_CHANGED_DURING_PUBLISH"
|
|
27930
|
+
);
|
|
27931
|
+
}
|
|
27932
|
+
}
|
|
27933
|
+
async function sha1OfFile(uploadPath) {
|
|
27934
|
+
const fingerprint = fingerprintFile(uploadPath);
|
|
27935
|
+
const hash = createHash3("sha1");
|
|
27936
|
+
await new Promise((resolve, reject) => {
|
|
27937
|
+
const stream4 = createReadStream(uploadPath);
|
|
27938
|
+
stream4.on("data", (chunk) => {
|
|
27939
|
+
hash.update(chunk);
|
|
27940
|
+
});
|
|
27941
|
+
stream4.once("error", reject);
|
|
27942
|
+
stream4.once("end", resolve);
|
|
27943
|
+
});
|
|
27944
|
+
assertFileUnchanged(uploadPath, fingerprint);
|
|
27945
|
+
return { sha1: hash.digest("hex"), fingerprint };
|
|
26899
27946
|
}
|
|
26900
|
-
async function uploadIfNew(uploadPath, sha1, typeCode, apis) {
|
|
27947
|
+
async function uploadIfNew(uploadPath, sha1, fingerprint, typeCode, apis) {
|
|
26901
27948
|
const fileIsExist2 = apis.fileIsExist ?? ((params) => service_API_default.Storage.fileIsExist(params));
|
|
26902
27949
|
const exists2 = unwrapFirst(await fileIsExist2({ sha1 }));
|
|
26903
27950
|
if (exists2.isExisting || exists2.exist || exists2.data === true) {
|
|
27951
|
+
assertFileUnchanged(uploadPath, fingerprint);
|
|
26904
27952
|
return;
|
|
26905
27953
|
}
|
|
26906
27954
|
const upload = apis.uploadFile ?? ((params) => service_API_default.Storage.uploadFile(params));
|
|
26907
|
-
|
|
27955
|
+
assertFileUnchanged(uploadPath, fingerprint);
|
|
27956
|
+
const file = await openAsBlob(uploadPath);
|
|
27957
|
+
await upload({ file, resourceType: typeCode });
|
|
27958
|
+
assertFileUnchanged(uploadPath, fingerprint);
|
|
26908
27959
|
}
|
|
26909
27960
|
function removeTempZip(uploadPath, localPath) {
|
|
26910
|
-
if (uploadPath === localPath || !
|
|
27961
|
+
if (uploadPath === localPath || !existsSync15(uploadPath)) {
|
|
26911
27962
|
return;
|
|
26912
27963
|
}
|
|
26913
27964
|
try {
|
|
26914
|
-
|
|
27965
|
+
unlinkSync7(uploadPath);
|
|
26915
27966
|
} catch {
|
|
26916
27967
|
}
|
|
26917
27968
|
}
|
|
@@ -26926,16 +27977,22 @@ function writeSha1ToDraft(input2, uploaded, analysis) {
|
|
|
26926
27977
|
metadata.filter((item) => Boolean(item) && typeof item === "object").filter((item) => Number(item.insertMode) === 2).map((item) => String(item.key ?? "")).filter(Boolean)
|
|
26927
27978
|
);
|
|
26928
27979
|
const previousAttrs = draft.inputAttrs ?? [];
|
|
27980
|
+
const previousOrphans = draft.orphanedInputAttrs ?? [];
|
|
26929
27981
|
const reuseCurrentAnalysis = !hasMetadata && draft.fileSha1 === uploaded.fileSha1 && draft.analyzedSha1 === uploaded.fileSha1;
|
|
26930
|
-
const retainedAttrs = reuseCurrentAnalysis ? previousAttrs :
|
|
27982
|
+
const retainedAttrs = reuseCurrentAnalysis ? previousAttrs : [
|
|
27983
|
+
...previousAttrs.filter((item) => additionalKeys.has(String(item.key ?? ""))),
|
|
27984
|
+
// 新分析重新出现同 key 时,恢复用户上次保留的值;它不应永远卡在待复核队列。
|
|
27985
|
+
...previousOrphans.filter((item) => additionalKeys.has(String(item.key ?? "")) && !previousAttrs.some((current) => additionalKeys.has(String(current.key ?? "")) && current.key === item.key))
|
|
27986
|
+
];
|
|
26931
27987
|
const newlyOrphaned = reuseCurrentAnalysis ? [] : previousAttrs.filter((item) => !additionalKeys.has(String(item.key ?? "")));
|
|
27988
|
+
const unresolvedOrphans = reuseCurrentAnalysis ? previousOrphans : previousOrphans.filter((item) => !additionalKeys.has(String(item.key ?? "")));
|
|
26932
27989
|
draft.fileSha1 = uploaded.fileSha1;
|
|
26933
27990
|
draft.filename = uploaded.filename;
|
|
26934
27991
|
draft.analyzedSha1 = uploaded.fileSha1;
|
|
26935
27992
|
draft.inputAttrs = retainedAttrs;
|
|
26936
27993
|
draft.orphanedInputAttrs = [
|
|
26937
|
-
...
|
|
26938
|
-
...newlyOrphaned.filter((item) => !
|
|
27994
|
+
...unresolvedOrphans,
|
|
27995
|
+
...newlyOrphaned.filter((item) => !unresolvedOrphans.some((old) => old.key === item.key))
|
|
26939
27996
|
];
|
|
26940
27997
|
const nextDraft = prepareDraft(input2.cwd, input2.identity.n, draft);
|
|
26941
27998
|
const changes = [{
|
|
@@ -26959,10 +28016,11 @@ async function uploadAndAnalyzeLocked(input2) {
|
|
|
26959
28016
|
const recordedFile = normalizeProjectPath(input2.cwd, input2.identity.filePath);
|
|
26960
28017
|
const identity = recordedFile === input2.identity.filePath ? input2.identity : { ...input2.identity, filePath: recordedFile };
|
|
26961
28018
|
const localPath = confirmLocalPath(identity, file, input2.yes, input2.cwd);
|
|
26962
|
-
const uploadPath = await prepareUploadPath(identity.typeCode, localPath);
|
|
28019
|
+
const uploadPath = await prepareUploadPath(identity.typeCode, localPath, input2.cwd);
|
|
26963
28020
|
try {
|
|
26964
|
-
const
|
|
26965
|
-
|
|
28021
|
+
const hashed = await sha1OfFile(uploadPath);
|
|
28022
|
+
const uploaded = { fileSha1: hashed.sha1, filename: path16.basename(uploadPath) };
|
|
28023
|
+
await uploadIfNew(uploadPath, uploaded.fileSha1, hashed.fingerprint, identity.typeCode, input2.apis ?? {});
|
|
26966
28024
|
const analysis = await waitAnalyze(
|
|
26967
28025
|
uploaded.fileSha1,
|
|
26968
28026
|
identity.typeCode,
|
|
@@ -26970,6 +28028,7 @@ async function uploadAndAnalyzeLocked(input2) {
|
|
|
26970
28028
|
input2.now,
|
|
26971
28029
|
input2.sleep
|
|
26972
28030
|
);
|
|
28031
|
+
assertFileUnchanged(uploadPath, hashed.fingerprint);
|
|
26973
28032
|
writeSha1ToDraft(
|
|
26974
28033
|
{
|
|
26975
28034
|
...input2,
|
|
@@ -27004,7 +28063,7 @@ async function runCreateVersion(input2) {
|
|
|
27004
28063
|
}
|
|
27005
28064
|
async function runCreateVersionLocked(input2) {
|
|
27006
28065
|
assertPlatformAllowed();
|
|
27007
|
-
requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
28066
|
+
const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
27008
28067
|
const identity = resolveBoundIdentity(input2.cwd, input2.file);
|
|
27009
28068
|
const infoApi2 = input2.apis?.info ?? ((params) => service_API_default.Resource.info(params));
|
|
27010
28069
|
const info2 = unwrapData2(
|
|
@@ -27021,8 +28080,10 @@ async function runCreateVersionLocked(input2) {
|
|
|
27021
28080
|
throw new CliError("\u63D0\u4EA4\u8BF7\u52A0 --yes", "CREATE_VERSION_NEED_YES");
|
|
27022
28081
|
}
|
|
27023
28082
|
if (input2.reset) {
|
|
27024
|
-
confirmLocalPath(identity, artifact, input2.yes, input2.cwd);
|
|
28083
|
+
const localPath = confirmLocalPath(identity, artifact, input2.yes, input2.cwd);
|
|
28084
|
+
assertUploadArtifactReady(identity.typeCode, localPath, input2.cwd);
|
|
27025
28085
|
}
|
|
28086
|
+
assertRemoteResourceWritable({ info: info2, resourceId: identity.resourceId, authUserId: auth.userId });
|
|
27026
28087
|
let draft = existingDraft;
|
|
27027
28088
|
if (input2.reset && existingDraft) {
|
|
27028
28089
|
if (!input2.confirmReset) {
|
|
@@ -27060,6 +28121,7 @@ async function runCreateVersionLocked(input2) {
|
|
|
27060
28121
|
isLoadLatestVersionInfo: 1
|
|
27061
28122
|
})
|
|
27062
28123
|
);
|
|
28124
|
+
assertRemoteResourceWritable({ info: again, resourceId: identity.resourceId, authUserId: auth.userId });
|
|
27063
28125
|
if (again.latestVersion) {
|
|
27064
28126
|
throw new CliError(
|
|
27065
28127
|
`\u8FD9\u4E2A\u8D44\u6E90\u5DF2\u7ECF\u6709\u53D1\u884C\u7248\u672C\u3002\u7EBF\u4E0A latest \u662F ${again.latestVersion}\uFF0C\u8BF7\u7528 update-version\u3002`,
|
|
@@ -27070,6 +28132,7 @@ async function runCreateVersionLocked(input2) {
|
|
|
27070
28132
|
cwd: input2.cwd,
|
|
27071
28133
|
identity,
|
|
27072
28134
|
version: "1.0.0",
|
|
28135
|
+
homeDir: input2.homeDir,
|
|
27073
28136
|
apis: input2.apis
|
|
27074
28137
|
});
|
|
27075
28138
|
return "1.0.0";
|
|
@@ -27120,6 +28183,26 @@ import { Command as Command21 } from "commander";
|
|
|
27120
28183
|
|
|
27121
28184
|
// src/domain/version/form/dep.ts
|
|
27122
28185
|
import semver from "semver";
|
|
28186
|
+
async function assertCurrentResourceWritable(input2) {
|
|
28187
|
+
const auth = requireAuth({ cwd: input2.cwd });
|
|
28188
|
+
const resourceId = input2.identity.resourceId;
|
|
28189
|
+
if (!resourceId) {
|
|
28190
|
+
throw new CliError("\u8BF7\u5148 create \u6216 bind", "DEP_NEED_SHELL");
|
|
28191
|
+
}
|
|
28192
|
+
const infoApi2 = input2.apis?.ownInfo ?? ((params) => service_API_default.Resource.info(params));
|
|
28193
|
+
const info2 = unwrapData3(await infoApi2({ resourceIdOrName: resourceId }));
|
|
28194
|
+
assertRemoteResourceWritable({
|
|
28195
|
+
info: info2,
|
|
28196
|
+
resourceId,
|
|
28197
|
+
authUserId: auth.userId,
|
|
28198
|
+
codes: {
|
|
28199
|
+
invalid: "DEP_CURRENT_INFO_INVALID",
|
|
28200
|
+
notOwner: "DEP_CURRENT_NOT_OWNER",
|
|
28201
|
+
frozen: "DEP_CURRENT_RESOURCE_FROZEN"
|
|
28202
|
+
}
|
|
28203
|
+
});
|
|
28204
|
+
return resourceId;
|
|
28205
|
+
}
|
|
27123
28206
|
function unwrapData3(result) {
|
|
27124
28207
|
const envelope = result;
|
|
27125
28208
|
const data = envelope.data ?? result;
|
|
@@ -27157,6 +28240,64 @@ function statusLabel(status) {
|
|
|
27157
28240
|
}
|
|
27158
28241
|
return void 0;
|
|
27159
28242
|
}
|
|
28243
|
+
async function loadDependencyTarget(input2) {
|
|
28244
|
+
const infoApi2 = input2.apis?.info ?? ((params) => service_API_default.Resource.info(params));
|
|
28245
|
+
const info2 = unwrapData3(
|
|
28246
|
+
await infoApi2({
|
|
28247
|
+
resourceIdOrName: input2.resourceIdOrName,
|
|
28248
|
+
isLoadLatestVersionInfo: 1,
|
|
28249
|
+
isLoadPolicyInfo: 1
|
|
28250
|
+
})
|
|
28251
|
+
);
|
|
28252
|
+
const resourceId = typeof info2.resourceId === "string" ? info2.resourceId.trim() : "";
|
|
28253
|
+
if (!resourceId || input2.expectedResourceId && resourceId !== input2.expectedResourceId) {
|
|
28254
|
+
throw new CliError("\u5BF9\u65B9\u8D44\u6E90\u4FE1\u606F\u4E0D\u5B8C\u6574\u6216\u4E0E\u8981\u4FEE\u6539\u7684\u4F9D\u8D56\u4E0D\u4E00\u81F4", "DEP_TARGET_INVALID");
|
|
28255
|
+
}
|
|
28256
|
+
const resourceName = typeof info2.resourceName === "string" ? info2.resourceName : typeof info2.name === "string" ? info2.name : "";
|
|
28257
|
+
if (input2.identity.resourceId === resourceId || input2.identity.name && resourceName === input2.identity.name) {
|
|
28258
|
+
throw new CliError("\u4E0D\u80FD\u4F9D\u8D56\u81EA\u5DF1", "DEP_SELF");
|
|
28259
|
+
}
|
|
28260
|
+
if (Number(info2.subjectType) !== 1) {
|
|
28261
|
+
throw new CliError("\u5BF9\u65B9\u4E0D\u662F\u666E\u901A\u5355\u8D44\u6E90\uFF0C\u4E0D\u52A0", "DEP_NOT_RESOURCE");
|
|
28262
|
+
}
|
|
28263
|
+
const latestVersion = typeof info2.latestVersion === "string" ? info2.latestVersion.trim() : "";
|
|
28264
|
+
if (!latestVersion || !semver.valid(latestVersion)) {
|
|
28265
|
+
throw new CliError("\u5BF9\u65B9\u8FD8\u6CA1\u6709\u53D1\u884C\u7248\u672C", "DEP_NO_VERSION");
|
|
28266
|
+
}
|
|
28267
|
+
if (info2.status === void 0 || !Number.isFinite(Number(info2.status))) {
|
|
28268
|
+
throw new CliError("\u5BF9\u65B9\u8D44\u6E90\u4FE1\u606F\u4E0D\u5B8C\u6574\u6216\u72B6\u6001\u4E0D\u53EF\u7528", "DEP_TARGET_INVALID");
|
|
28269
|
+
}
|
|
28270
|
+
const blocked = statusLabel(Number(info2.status));
|
|
28271
|
+
if (blocked) {
|
|
28272
|
+
throw new CliError(blocked, "DEP_TARGET_STATUS");
|
|
28273
|
+
}
|
|
28274
|
+
if (Array.isArray(info2.baseUpcastResources) && info2.baseUpcastResources.length > 0) {
|
|
28275
|
+
throw new CliError("\u5BF9\u65B9\u5B58\u5728\u57FA\u7840\u4E0A\u629B\uFF0C\u672C\u671F\u4E0D\u652F\u6301\u3002", "DEP_UPCAST");
|
|
28276
|
+
}
|
|
28277
|
+
return { info: info2, resourceId, latestVersion };
|
|
28278
|
+
}
|
|
28279
|
+
async function assertDependencyVersionRange(input2) {
|
|
28280
|
+
const listApi = input2.apis?.getVersionListByResourceID ?? ((params) => service_API_default.Resource.getVersionListByResourceID(params));
|
|
28281
|
+
const list2 = unwrapData3(await listApi({ resourceId: input2.resourceId }));
|
|
28282
|
+
const rawVersions = list2.dataList ?? list2.list;
|
|
28283
|
+
if (!Array.isArray(rawVersions) || rawVersions.length === 0) {
|
|
28284
|
+
throw new CliError("\u5BF9\u65B9\u7248\u672C\u5217\u8868\u4E0D\u53EF\u7528\uFF0C\u4E0D\u80FD\u786E\u8BA4\u4F9D\u8D56\u8303\u56F4", "DEP_VERSION_LIST_INVALID");
|
|
28285
|
+
}
|
|
28286
|
+
const versions = [];
|
|
28287
|
+
for (const item of rawVersions) {
|
|
28288
|
+
const version = typeof item === "object" && item !== null && typeof item.version === "string" ? item.version : "";
|
|
28289
|
+
if (!version || !semver.valid(version)) {
|
|
28290
|
+
throw new CliError("\u5BF9\u65B9\u7248\u672C\u5217\u8868\u4E0D\u53EF\u7528\uFF0C\u4E0D\u80FD\u786E\u8BA4\u4F9D\u8D56\u8303\u56F4", "DEP_VERSION_LIST_INVALID");
|
|
28291
|
+
}
|
|
28292
|
+
versions.push(version);
|
|
28293
|
+
}
|
|
28294
|
+
if (!versions.some((version) => semver.eq(version, input2.latestVersion))) {
|
|
28295
|
+
throw new CliError("\u5BF9\u65B9\u7248\u672C\u5217\u8868\u4E0D\u53EF\u7528\uFF0C\u4E0D\u80FD\u786E\u8BA4\u4F9D\u8D56\u8303\u56F4", "DEP_VERSION_LIST_INVALID");
|
|
28296
|
+
}
|
|
28297
|
+
if (!semver.validRange(input2.versionRange) || !semver.maxSatisfying(versions, input2.versionRange)) {
|
|
28298
|
+
throw new CliError("\u8FD9\u4E2A\u8303\u56F4\u5BF9\u4E0D\u4E0A\u5BF9\u65B9\u5DF2\u53D1\u884C\u7684\u7248\u672C", "DEP_RANGE");
|
|
28299
|
+
}
|
|
28300
|
+
}
|
|
27160
28301
|
function signablePolicies(info2) {
|
|
27161
28302
|
const policies2 = info2.policies ?? [];
|
|
27162
28303
|
return policies2.filter((item) => item.status === 1 && item.policyId).map((item) => ({ policyId: item.policyId, policyName: item.policyName }));
|
|
@@ -27197,49 +28338,26 @@ async function depAdd(input2) {
|
|
|
27197
28338
|
}
|
|
27198
28339
|
async function depAddLocked(input2) {
|
|
27199
28340
|
assertPlatformAllowed();
|
|
27200
|
-
const identity =
|
|
28341
|
+
const identity = resolveBoundIdentity(input2.cwd, input2.file);
|
|
27201
28342
|
const draft = readDraft(input2.cwd, identity.n) ?? {
|
|
27202
28343
|
baseUpcastResources: [],
|
|
27203
28344
|
authExcludedItems: []
|
|
27204
28345
|
};
|
|
27205
|
-
const
|
|
27206
|
-
const
|
|
27207
|
-
|
|
27208
|
-
|
|
27209
|
-
|
|
27210
|
-
|
|
27211
|
-
|
|
27212
|
-
|
|
27213
|
-
const
|
|
27214
|
-
|
|
27215
|
-
|
|
27216
|
-
|
|
27217
|
-
|
|
27218
|
-
|
|
27219
|
-
|
|
27220
|
-
}
|
|
27221
|
-
const latestVersion = info2.latestVersion ? String(info2.latestVersion) : void 0;
|
|
27222
|
-
if (!latestVersion) {
|
|
27223
|
-
throw new CliError("\u5BF9\u65B9\u8FD8\u6CA1\u6709\u53D1\u884C\u7248\u672C", "DEP_NO_VERSION");
|
|
27224
|
-
}
|
|
27225
|
-
const status = Number(info2.status ?? 1);
|
|
27226
|
-
const blocked = statusLabel(status);
|
|
27227
|
-
if (blocked) {
|
|
27228
|
-
throw new CliError(blocked, "DEP_TARGET_STATUS");
|
|
27229
|
-
}
|
|
27230
|
-
const upcast = info2.baseUpcastResources;
|
|
27231
|
-
if (Array.isArray(upcast) && upcast.length > 0) {
|
|
27232
|
-
throw new CliError("\u5BF9\u65B9\u5B58\u5728\u57FA\u7840\u4E0A\u629B\uFF0C\u672C\u671F\u4E0D\u652F\u6301\u3002", "DEP_UPCAST");
|
|
27233
|
-
}
|
|
27234
|
-
let versionRange = input2.versionRange ?? `^${latestVersion}`;
|
|
27235
|
-
const listApi = input2.apis?.getVersionListByResourceID ?? ((params) => service_API_default.Resource.getVersionListByResourceID(params));
|
|
27236
|
-
const list2 = unwrapData3(await listApi({ resourceId: targetId }));
|
|
27237
|
-
const versions = (list2.dataList ?? list2.list ?? []).map((item) => item.version).filter((item) => Boolean(item));
|
|
27238
|
-
if (versions.length > 0) {
|
|
27239
|
-
if (!semver.validRange(versionRange) || !semver.maxSatisfying(versions, versionRange)) {
|
|
27240
|
-
throw new CliError("\u8FD9\u4E2A\u8303\u56F4\u5BF9\u4E0D\u4E0A\u5BF9\u65B9\u5DF2\u53D1\u884C\u7684\u7248\u672C", "DEP_RANGE");
|
|
27241
|
-
}
|
|
27242
|
-
}
|
|
28346
|
+
const licenseeId = await assertCurrentResourceWritable({ cwd: input2.cwd, identity, apis: input2.apis });
|
|
28347
|
+
const target = await loadDependencyTarget({
|
|
28348
|
+
resourceIdOrName: input2.resourceId,
|
|
28349
|
+
identity,
|
|
28350
|
+
apis: input2.apis
|
|
28351
|
+
});
|
|
28352
|
+
const targetId = target.resourceId;
|
|
28353
|
+
const info2 = target.info;
|
|
28354
|
+
const versionRange = input2.versionRange ?? `^${target.latestVersion}`;
|
|
28355
|
+
await assertDependencyVersionRange({
|
|
28356
|
+
resourceId: targetId,
|
|
28357
|
+
latestVersion: target.latestVersion,
|
|
28358
|
+
versionRange,
|
|
28359
|
+
apis: input2.apis
|
|
28360
|
+
});
|
|
27243
28361
|
if (identity.resourceId) {
|
|
27244
28362
|
const cycleApi = input2.apis?.cycleDependencyCheck ?? ((params) => service_API_default.Resource.cycleDependencyCheck(params));
|
|
27245
28363
|
const existing2 = (draft.dependencies ?? []).filter((item) => item.resourceId !== targetId).map((item) => ({ resourceId: String(item.resourceId), versionRange: String(item.versionRange ?? "*") }));
|
|
@@ -27262,16 +28380,13 @@ async function depAddLocked(input2) {
|
|
|
27262
28380
|
);
|
|
27263
28381
|
if (!extractIsAuth(firstAuth, targetId)) {
|
|
27264
28382
|
const policies2 = signablePolicies(info2);
|
|
27265
|
-
if (!identity.resourceId) {
|
|
27266
|
-
throw new CliError("\u8BF7\u5148 create \u6216 bind", "DEP_NEED_SHELL");
|
|
27267
|
-
}
|
|
27268
28383
|
const sign = input2.apis?.sign ?? ((params) => service_API_default.Contract.batchCreateContracts(params));
|
|
27269
28384
|
await signWithSelectedPolicy({
|
|
27270
28385
|
policies: policies2,
|
|
27271
28386
|
policyId: input2.policyId,
|
|
27272
28387
|
yes: input2.yes,
|
|
27273
28388
|
targetId,
|
|
27274
|
-
licenseeId
|
|
28389
|
+
licenseeId,
|
|
27275
28390
|
sign
|
|
27276
28391
|
});
|
|
27277
28392
|
}
|
|
@@ -27317,7 +28432,8 @@ async function depRange(cwd, resourceId, versionRange, file, apis, options) {
|
|
|
27317
28432
|
return withProjectLock(cwd, () => depRangeLocked(cwd, resourceId, versionRange, file, apis, options), "version-dep-range");
|
|
27318
28433
|
}
|
|
27319
28434
|
async function depRangeLocked(cwd, resourceId, versionRange, file, apis, options) {
|
|
27320
|
-
|
|
28435
|
+
assertPlatformAllowed();
|
|
28436
|
+
const identity = resolveBoundIdentity(cwd, file);
|
|
27321
28437
|
const draft = readDraft(cwd, identity.n);
|
|
27322
28438
|
if (!draft) {
|
|
27323
28439
|
throw new CliError("\u6CA1\u6709\u5DE5\u4F5C\u7A3F\uFF0C\u8BF7\u5148 version draft pull", "DRAFT_MISSING");
|
|
@@ -27326,39 +28442,27 @@ async function depRangeLocked(cwd, resourceId, versionRange, file, apis, options
|
|
|
27326
28442
|
if (!found) {
|
|
27327
28443
|
throw new CliError(`\u7A3F\u4E0A\u6CA1\u6709\u4F9D\u8D56 ${resourceId}`, "DEP_NOT_FOUND");
|
|
27328
28444
|
}
|
|
27329
|
-
const
|
|
27330
|
-
const
|
|
27331
|
-
|
|
27332
|
-
|
|
27333
|
-
|
|
27334
|
-
|
|
27335
|
-
|
|
27336
|
-
|
|
27337
|
-
|
|
27338
|
-
|
|
27339
|
-
|
|
27340
|
-
|
|
27341
|
-
|
|
27342
|
-
|
|
27343
|
-
const upcast = info2.baseUpcastResources;
|
|
27344
|
-
if (Array.isArray(upcast) && upcast.length > 0) {
|
|
27345
|
-
throw new CliError("\u5BF9\u65B9\u5B58\u5728\u57FA\u7840\u4E0A\u629B\uFF0C\u672C\u671F\u4E0D\u652F\u6301\u3002", "DEP_UPCAST");
|
|
27346
|
-
}
|
|
27347
|
-
const listApi = apis?.getVersionListByResourceID ?? ((params) => service_API_default.Resource.getVersionListByResourceID(params));
|
|
27348
|
-
const list2 = unwrapData3(await listApi({ resourceId }));
|
|
27349
|
-
const versions = (list2.dataList ?? list2.list ?? []).map((item) => item.version).filter((item) => Boolean(item));
|
|
27350
|
-
if (versions.length > 0 && latestVersion) {
|
|
27351
|
-
if (!semver.validRange(versionRange) || !semver.maxSatisfying(versions, versionRange)) {
|
|
27352
|
-
throw new CliError("\u8FD9\u4E2A\u8303\u56F4\u5BF9\u4E0D\u4E0A\u5BF9\u65B9\u5DF2\u53D1\u884C\u7684\u7248\u672C", "DEP_RANGE");
|
|
27353
|
-
}
|
|
27354
|
-
}
|
|
28445
|
+
const licenseeId = await assertCurrentResourceWritable({ cwd, identity, apis });
|
|
28446
|
+
const target = await loadDependencyTarget({
|
|
28447
|
+
resourceIdOrName: resourceId,
|
|
28448
|
+
expectedResourceId: resourceId,
|
|
28449
|
+
identity,
|
|
28450
|
+
apis
|
|
28451
|
+
});
|
|
28452
|
+
await assertDependencyVersionRange({
|
|
28453
|
+
resourceId: target.resourceId,
|
|
28454
|
+
latestVersion: target.latestVersion,
|
|
28455
|
+
versionRange,
|
|
28456
|
+
apis
|
|
28457
|
+
});
|
|
28458
|
+
const info2 = target.info;
|
|
27355
28459
|
if (identity.resourceId) {
|
|
27356
28460
|
const cycleApi = apis?.cycleDependencyCheck ?? ((params) => service_API_default.Resource.cycleDependencyCheck(params));
|
|
27357
28461
|
const existing = (draft.dependencies ?? []).filter((item) => item.resourceId !== resourceId).map((item) => ({ resourceId: String(item.resourceId), versionRange: String(item.versionRange ?? "*") }));
|
|
27358
28462
|
const cycle = unwrapData3(
|
|
27359
28463
|
await cycleApi({
|
|
27360
28464
|
resourceId: identity.resourceId,
|
|
27361
|
-
dependencies: [...existing, { resourceId, versionRange }]
|
|
28465
|
+
dependencies: [...existing, { resourceId: target.resourceId, versionRange }]
|
|
27362
28466
|
})
|
|
27363
28467
|
);
|
|
27364
28468
|
if (cycle.ok === false || cycle.data === false) {
|
|
@@ -27366,22 +28470,22 @@ async function depRangeLocked(cwd, resourceId, versionRange, file, apis, options
|
|
|
27366
28470
|
}
|
|
27367
28471
|
}
|
|
27368
28472
|
const batchAuth3 = apis?.batchAuth ?? ((params) => service_API_default.Resource.batchAuth(params));
|
|
27369
|
-
const firstAuth = unwrapData3(await batchAuth3({ resourceIds: resourceId, versionRanges: versionRange }));
|
|
27370
|
-
if (!extractIsAuth(firstAuth, resourceId) && identity.resourceId) {
|
|
28473
|
+
const firstAuth = unwrapData3(await batchAuth3({ resourceIds: target.resourceId, versionRanges: versionRange }));
|
|
28474
|
+
if (!extractIsAuth(firstAuth, target.resourceId) && identity.resourceId) {
|
|
27371
28475
|
const policies2 = signablePolicies(info2);
|
|
27372
28476
|
const sign = apis?.sign ?? ((params) => service_API_default.Contract.batchCreateContracts(params));
|
|
27373
28477
|
await signWithSelectedPolicy({
|
|
27374
28478
|
policies: policies2,
|
|
27375
28479
|
policyId: options?.policyId,
|
|
27376
28480
|
yes: options?.yes,
|
|
27377
|
-
targetId: resourceId,
|
|
27378
|
-
licenseeId
|
|
28481
|
+
targetId: target.resourceId,
|
|
28482
|
+
licenseeId,
|
|
27379
28483
|
sign
|
|
27380
28484
|
});
|
|
27381
28485
|
}
|
|
27382
28486
|
found.versionRange = versionRange;
|
|
27383
28487
|
writeDraft(cwd, identity.n, draft);
|
|
27384
|
-
return `${resourceId}@${versionRange}`;
|
|
28488
|
+
return `${target.resourceId}@${versionRange}`;
|
|
27385
28489
|
}
|
|
27386
28490
|
|
|
27387
28491
|
// src/commands/version/dep.ts
|
|
@@ -27424,7 +28528,7 @@ import { Command as Command22 } from "commander";
|
|
|
27424
28528
|
// src/domain/version/description.ts
|
|
27425
28529
|
async function updateOnlineDescription(input2) {
|
|
27426
28530
|
assertPlatformAllowed();
|
|
27427
|
-
requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
28531
|
+
const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
27428
28532
|
const identity = resolveBoundIdentity(input2.cwd, input2.file);
|
|
27429
28533
|
const infoApi2 = input2.apis?.info ?? ((params) => service_API_default.Resource.info(params));
|
|
27430
28534
|
const info2 = unwrapData2(
|
|
@@ -27433,6 +28537,7 @@ async function updateOnlineDescription(input2) {
|
|
|
27433
28537
|
isLoadLatestVersionInfo: 1
|
|
27434
28538
|
})
|
|
27435
28539
|
);
|
|
28540
|
+
assertRemoteResourceWritable({ info: info2, resourceId: identity.resourceId, authUserId: auth.userId });
|
|
27436
28541
|
if (!info2.latestVersion) {
|
|
27437
28542
|
throw new CliError(
|
|
27438
28543
|
"\u8FD8\u6CA1\u6709\u53D1\u884C\u7248\u672C\u3002\u8BF7\u5148\u6309\u53D1\u884C\u7248\u672C create-version \u63D0\u4EA4\u8D44\u6E90\u6587\u4EF6\u3002",
|
|
@@ -27655,210 +28760,6 @@ function createVersionDraftCommand() {
|
|
|
27655
28760
|
|
|
27656
28761
|
// src/commands/version/option.ts
|
|
27657
28762
|
import { Command as Command24 } from "commander";
|
|
27658
|
-
|
|
27659
|
-
// src/domain/version/form/option.ts
|
|
27660
|
-
var MAX_OPTION = 30;
|
|
27661
|
-
var MAX_OPTION_ITEM = 30;
|
|
27662
|
-
var MAX_TEXT_DEFAULT = 140;
|
|
27663
|
-
var MAX_NAME2 = 50;
|
|
27664
|
-
var MAX_REMARK2 = 50;
|
|
27665
|
-
function assertValidName2(name) {
|
|
27666
|
-
if (name.length > MAX_NAME2) {
|
|
27667
|
-
throw new CliError("\u540D\u79F0\u4E0D\u80FD\u8D85\u8FC750\u4E2A\u5B57\u7B26", "OPTION_NAME_LONG");
|
|
27668
|
-
}
|
|
27669
|
-
}
|
|
27670
|
-
function assertValidRemark2(remark) {
|
|
27671
|
-
if (remark.length > MAX_REMARK2) {
|
|
27672
|
-
throw new CliError("\u4E0D\u80FD\u8D85\u8FC750\u4E2A\u5B57\u7B26\u3002", "OPTION_REMARK_LONG");
|
|
27673
|
-
}
|
|
27674
|
-
}
|
|
27675
|
-
function assertOptionValueLength(value) {
|
|
27676
|
-
if (value.length > MAX_TEXT_DEFAULT) {
|
|
27677
|
-
throw new CliError("\u4E0D\u8D85\u8FC7140\u4E2A\u5B57\u7B26", "OPTION_VALUE_LONG");
|
|
27678
|
-
}
|
|
27679
|
-
}
|
|
27680
|
-
function isOption(item) {
|
|
27681
|
-
return item.type === "editableText" || item.type === "select";
|
|
27682
|
-
}
|
|
27683
|
-
async function assertTypeAllowsOption(input2) {
|
|
27684
|
-
if (input2.supportOptionalConfig === true) return;
|
|
27685
|
-
if (input2.supportOptionalConfig === false) {
|
|
27686
|
-
throw new CliError("\u5F53\u524D\u7C7B\u578B\u4E0D\u652F\u6301\u53EF\u9009\u914D\u7F6E", "OPTION_UNSUPPORTED");
|
|
27687
|
-
}
|
|
27688
|
-
requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
27689
|
-
const type = await getTypeInfo(input2.typeCode, input2.apis);
|
|
27690
|
-
if (type.supportOptionalConfig !== 2) {
|
|
27691
|
-
throw new CliError("\u5F53\u524D\u7C7B\u578B\u4E0D\u652F\u6301\u53EF\u9009\u914D\u7F6E", "OPTION_UNSUPPORTED");
|
|
27692
|
-
}
|
|
27693
|
-
}
|
|
27694
|
-
function optionListFromDraft(draft) {
|
|
27695
|
-
return (draft.customPropertyDescriptors ?? []).filter((item) => isOption(item));
|
|
27696
|
-
}
|
|
27697
|
-
function normalizeMode(mode) {
|
|
27698
|
-
if (mode === void 0) return void 0;
|
|
27699
|
-
if (mode === "\u4E0B\u62C9" || mode === "\u4E0B\u62C9\u5217\u8868" || mode === "select") return "select";
|
|
27700
|
-
if (mode === "\u6587\u672C" || mode === "\u6587\u672C\u8F93\u5165\u6846" || mode === "input") return "editableText";
|
|
27701
|
-
throw new CliError("\u65B9\u5F0F\u53EA\u80FD\u662F\u6587\u672C\u6216\u4E0B\u62C9", "OPTION_MODE");
|
|
27702
|
-
}
|
|
27703
|
-
function parseCandidates(raw) {
|
|
27704
|
-
const items = (raw ?? "").split("|").map((item) => item.trim()).filter(Boolean);
|
|
27705
|
-
if (items.length === 0) throw new CliError("\u4E0B\u62C9\u81F3\u5C11\u9700\u8981 1 \u4E2A\u9009\u9879", "OPTION_OPTIONS");
|
|
27706
|
-
if (items.length > MAX_OPTION_ITEM) throw new CliError("\u9009\u9879\u4E2A\u6570\u4E0D\u80FD\u8D85\u8FC730\u9879", "OPTION_OPTIONS");
|
|
27707
|
-
for (const item of items) assertOptionValueLength(item);
|
|
27708
|
-
if (items.some((item, index) => items.indexOf(item) !== index)) {
|
|
27709
|
-
throw new CliError("\u8BE5\u9009\u9879\u5DF2\u5B58\u5728", "OPTION_DUPLICATE_OPTION");
|
|
27710
|
-
}
|
|
27711
|
-
return items;
|
|
27712
|
-
}
|
|
27713
|
-
async function optionAdd(cwd, input2) {
|
|
27714
|
-
return withProjectLock(cwd, () => optionAddLocked(cwd, input2), "version-option-add");
|
|
27715
|
-
}
|
|
27716
|
-
async function optionAddLocked(cwd, input2) {
|
|
27717
|
-
const identity = resolveIdentity(cwd, input2.file);
|
|
27718
|
-
await assertTypeAllowsOption({ cwd, typeCode: identity.typeCode, ...input2 });
|
|
27719
|
-
const draft = readDraft(cwd, identity.n) ?? {
|
|
27720
|
-
baseUpcastResources: [],
|
|
27721
|
-
authExcludedItems: []
|
|
27722
|
-
};
|
|
27723
|
-
const parsed = parseLine(input2.line ?? "");
|
|
27724
|
-
if (!parsed.name || !parsed.key) {
|
|
27725
|
-
throw new CliError("\u53EF\u9009\u914D\u7F6E\u9700\u8981\u540D\u79F0\u548C\u952E", "OPTION_FIELDS");
|
|
27726
|
-
}
|
|
27727
|
-
assertValidKey(parsed.key);
|
|
27728
|
-
const list2 = draft.customPropertyDescriptors ?? [];
|
|
27729
|
-
if (optionListFromDraft(draft).length >= MAX_OPTION) {
|
|
27730
|
-
throw new CliError("\u6700\u591A\u53EF\u6DFB\u52A030\u4E2A\u53EF\u9009\u914D\u7F6E", "OPTION_FULL");
|
|
27731
|
-
}
|
|
27732
|
-
if (list2.some((item) => item.key === parsed.key)) {
|
|
27733
|
-
throw new CliError(`\u952E ${parsed.key} \u5DF2\u5B58\u5728`, "OPTION_DUPLICATE");
|
|
27734
|
-
}
|
|
27735
|
-
if (list2.some((item) => item.name === parsed.name)) {
|
|
27736
|
-
throw new CliError("\u540D\u79F0\u5DF2\u5B58\u5728", "OPTION_NAME_DUPLICATE");
|
|
27737
|
-
}
|
|
27738
|
-
const normalizedMode = normalizeMode(parsed.mode);
|
|
27739
|
-
if (!normalizedMode) {
|
|
27740
|
-
throw new CliError("\u65B9\u5F0F\u53EA\u80FD\u662F\u6587\u672C\u6216\u4E0B\u62C9", "OPTION_MODE");
|
|
27741
|
-
}
|
|
27742
|
-
const isSelect = normalizedMode === "select";
|
|
27743
|
-
const isText = normalizedMode === "editableText";
|
|
27744
|
-
if (isSelect && parsed.defaultValue) {
|
|
27745
|
-
throw new CliError("\u4E0B\u62C9\u9ED8\u8BA4\u503C\u56FA\u5B9A\u4E3A\u7B2C\u4E00\u9879\uFF0C\u8BF7\u628A\u8981\u9ED8\u8BA4\u7684\u9009\u9879\u653E\u5728\u7B2C\u4E00\u4F4D", "OPTION_SELECT_DEFAULT");
|
|
27746
|
-
}
|
|
27747
|
-
if (isText && parsed.options) {
|
|
27748
|
-
throw new CliError("\u6587\u672C\u65B9\u5F0F\u4E0D\u8981\u5199\u9009\u9879", "OPTION_TEXT_OPTIONS");
|
|
27749
|
-
}
|
|
27750
|
-
if (!isSelect && !isText) {
|
|
27751
|
-
throw new CliError("\u65B9\u5F0F\u53EA\u80FD\u662F\u6587\u672C\u6216\u4E0B\u62C9", "OPTION_MODE");
|
|
27752
|
-
}
|
|
27753
|
-
let type = "editableText";
|
|
27754
|
-
let defaultValue = parsed.defaultValue ?? parsed.value ?? "";
|
|
27755
|
-
let candidateItems;
|
|
27756
|
-
assertValidName2(parsed.name);
|
|
27757
|
-
assertValidRemark2(parsed.remark ?? "");
|
|
27758
|
-
if (isSelect) {
|
|
27759
|
-
const options = parseCandidates(parsed.options);
|
|
27760
|
-
type = "select";
|
|
27761
|
-
defaultValue = options[0] ?? "";
|
|
27762
|
-
candidateItems = options;
|
|
27763
|
-
} else {
|
|
27764
|
-
assertOptionValueLength(defaultValue);
|
|
27765
|
-
}
|
|
27766
|
-
const preview = await confirmWrite(previewLine(parsed), input2.yes);
|
|
27767
|
-
list2.push({
|
|
27768
|
-
name: parsed.name,
|
|
27769
|
-
key: parsed.key,
|
|
27770
|
-
remark: parsed.remark ?? "",
|
|
27771
|
-
defaultValue,
|
|
27772
|
-
type,
|
|
27773
|
-
...candidateItems ? { candidateItems } : {}
|
|
27774
|
-
});
|
|
27775
|
-
draft.customPropertyDescriptors = list2;
|
|
27776
|
-
writeDraft(cwd, identity.n, draft);
|
|
27777
|
-
return preview;
|
|
27778
|
-
}
|
|
27779
|
-
async function optionSet(cwd, input2) {
|
|
27780
|
-
return withProjectLock(cwd, () => optionSetLocked(cwd, input2), "version-option-set");
|
|
27781
|
-
}
|
|
27782
|
-
async function optionSetLocked(cwd, input2) {
|
|
27783
|
-
const identity = resolveIdentity(cwd, input2.file);
|
|
27784
|
-
const draft = readDraft(cwd, identity.n);
|
|
27785
|
-
if (!draft) {
|
|
27786
|
-
throw new CliError("\u6CA1\u6709\u5DE5\u4F5C\u7A3F\uFF0C\u8BF7\u5148 version draft pull", "DRAFT_MISSING");
|
|
27787
|
-
}
|
|
27788
|
-
const parsed = parseLine(input2.line ?? "");
|
|
27789
|
-
const found = (draft.customPropertyDescriptors ?? []).find(
|
|
27790
|
-
(item) => isOption(item) && (item.key === parsed.key || item.name === parsed.name)
|
|
27791
|
-
);
|
|
27792
|
-
if (!found) {
|
|
27793
|
-
throw new CliError("\u627E\u4E0D\u5230\u8FD9\u6761\u53EF\u9009\u914D\u7F6E", "OPTION_NOT_FOUND");
|
|
27794
|
-
}
|
|
27795
|
-
assertKeyUnchanged(String(found.key), parsed.key);
|
|
27796
|
-
assertValidName2(parsed.name ?? String(found.name ?? ""));
|
|
27797
|
-
assertValidRemark2(parsed.remark ?? String(found.remark ?? ""));
|
|
27798
|
-
const nextType = normalizeMode(parsed.mode) ?? (String(found.type) === "select" ? "select" : "editableText");
|
|
27799
|
-
const nextDefault = parsed.defaultValue ?? parsed.value;
|
|
27800
|
-
if (nextType === "select" && nextDefault !== void 0) {
|
|
27801
|
-
throw new CliError("\u4E0B\u62C9\u9ED8\u8BA4\u503C\u56FA\u5B9A\u4E3A\u7B2C\u4E00\u9879\uFF0C\u8BF7\u628A\u8981\u9ED8\u8BA4\u7684\u9009\u9879\u653E\u5728\u7B2C\u4E00\u4F4D", "OPTION_SELECT_DEFAULT");
|
|
27802
|
-
}
|
|
27803
|
-
if (nextType === "editableText") {
|
|
27804
|
-
if (parsed.options !== void 0) {
|
|
27805
|
-
throw new CliError("\u6587\u672C\u65B9\u5F0F\u4E0D\u8981\u5199\u9009\u9879", "OPTION_TEXT_OPTIONS");
|
|
27806
|
-
}
|
|
27807
|
-
if (nextDefault !== void 0) assertOptionValueLength(nextDefault);
|
|
27808
|
-
}
|
|
27809
|
-
if (parsed.name && (draft.customPropertyDescriptors ?? []).some((item) => item.name === parsed.name && item.key !== found.key)) {
|
|
27810
|
-
throw new CliError("\u540D\u79F0\u5DF2\u5B58\u5728", "OPTION_NAME_DUPLICATE");
|
|
27811
|
-
}
|
|
27812
|
-
if (parsed.name) {
|
|
27813
|
-
found.name = parsed.name;
|
|
27814
|
-
}
|
|
27815
|
-
if (parsed.remark !== void 0) {
|
|
27816
|
-
found.remark = parsed.remark;
|
|
27817
|
-
}
|
|
27818
|
-
if (nextType === "select") {
|
|
27819
|
-
const candidates = parsed.options !== void 0 ? parseCandidates(parsed.options) : Array.isArray(found.candidateItems) ? found.candidateItems.map(String) : [];
|
|
27820
|
-
if (candidates.length === 0) {
|
|
27821
|
-
throw new CliError("\u4E0B\u62C9\u81F3\u5C11\u9700\u8981 1 \u4E2A\u9009\u9879", "OPTION_OPTIONS");
|
|
27822
|
-
}
|
|
27823
|
-
found.type = "select";
|
|
27824
|
-
found.candidateItems = candidates;
|
|
27825
|
-
found.defaultValue = candidates[0];
|
|
27826
|
-
} else {
|
|
27827
|
-
found.type = "editableText";
|
|
27828
|
-
delete found.candidateItems;
|
|
27829
|
-
if (nextDefault !== void 0) {
|
|
27830
|
-
found.defaultValue = nextDefault;
|
|
27831
|
-
}
|
|
27832
|
-
}
|
|
27833
|
-
const preview = await confirmWrite(previewLine(parsed), input2.yes);
|
|
27834
|
-
writeDraft(cwd, identity.n, draft);
|
|
27835
|
-
return preview;
|
|
27836
|
-
}
|
|
27837
|
-
function optionRm(cwd, key, file) {
|
|
27838
|
-
return withProjectLock(cwd, () => optionRmLocked(cwd, key, file), "version-option-rm");
|
|
27839
|
-
}
|
|
27840
|
-
function optionRmLocked(cwd, key, file) {
|
|
27841
|
-
const identity = resolveIdentity(cwd, file);
|
|
27842
|
-
const draft = readDraft(cwd, identity.n);
|
|
27843
|
-
if (!draft) {
|
|
27844
|
-
throw new CliError("\u6CA1\u6709\u5DE5\u4F5C\u7A3F\uFF0C\u8BF7\u5148 version draft pull", "DRAFT_MISSING");
|
|
27845
|
-
}
|
|
27846
|
-
const list2 = draft.customPropertyDescriptors ?? [];
|
|
27847
|
-
const next = list2.filter((item) => !(isOption(item) && item.key === key));
|
|
27848
|
-
if (next.length === list2.length) {
|
|
27849
|
-
throw new CliError("\u627E\u4E0D\u5230\u8FD9\u6761\u53EF\u9009\u914D\u7F6E", "OPTION_NOT_FOUND");
|
|
27850
|
-
}
|
|
27851
|
-
draft.customPropertyDescriptors = next;
|
|
27852
|
-
writeDraft(cwd, identity.n, draft);
|
|
27853
|
-
return key;
|
|
27854
|
-
}
|
|
27855
|
-
function optionList(cwd, file) {
|
|
27856
|
-
const identity = resolveIdentity(cwd, file);
|
|
27857
|
-
const draft = readDraft(cwd, identity.n);
|
|
27858
|
-
return optionListFromDraft(draft ?? {}).map((item) => `${item.key}=${item.defaultValue ?? ""} ${item.name ?? ""}`).join("\n");
|
|
27859
|
-
}
|
|
27860
|
-
|
|
27861
|
-
// src/commands/version/option.ts
|
|
27862
28763
|
function createVersionOptionCommand() {
|
|
27863
28764
|
const option = addSharedOptions(new Command24("option"));
|
|
27864
28765
|
option.description("\u6539\u7A3F\u4E0A\u7684\u53EF\u9009\u914D\u7F6E");
|
|
@@ -27893,7 +28794,16 @@ function createVersionOptionCommand() {
|
|
|
27893
28794
|
import { Command as Command25 } from "commander";
|
|
27894
28795
|
|
|
27895
28796
|
// src/domain/version/setPath.ts
|
|
27896
|
-
import
|
|
28797
|
+
import { existsSync as existsSync16, statSync as statSync4 } from "fs";
|
|
28798
|
+
import path17 from "path";
|
|
28799
|
+
function sameOrNestedPath(parent, candidate) {
|
|
28800
|
+
const relative = path17.relative(parent, candidate);
|
|
28801
|
+
return relative === "" || relative !== ".." && !relative.startsWith(`..${path17.sep}`) && !path17.isAbsolute(relative);
|
|
28802
|
+
}
|
|
28803
|
+
function artifactsOverlap(first, second) {
|
|
28804
|
+
if (first.path === second.path) return true;
|
|
28805
|
+
return (first.isDirectory || second.isDirectory) && (sameOrNestedPath(first.path, second.path) || sameOrNestedPath(second.path, first.path));
|
|
28806
|
+
}
|
|
27897
28807
|
function setIdentityFilePath(cwd, input2) {
|
|
27898
28808
|
return withProjectLock(cwd, () => {
|
|
27899
28809
|
const artifact = input2.artifact !== void 0 ? normalizeProjectPath(cwd, input2.artifact) : void 0;
|
|
@@ -27901,7 +28811,24 @@ function setIdentityFilePath(cwd, input2) {
|
|
|
27901
28811
|
throw new CliError("\u8BF7\u63D0\u4F9B --artifact", "SET_ARTIFACT_REQUIRED");
|
|
27902
28812
|
}
|
|
27903
28813
|
const identity = resolveIdentity(cwd, input2.file);
|
|
27904
|
-
|
|
28814
|
+
const absoluteArtifact = path17.resolve(cwd, artifact);
|
|
28815
|
+
assertArtifactAnchor(identity.typeCode, absoluteArtifact, cwd);
|
|
28816
|
+
const nextArtifact = {
|
|
28817
|
+
path: resolveExistingProjectPath(cwd, absoluteArtifact),
|
|
28818
|
+
isDirectory: statSync4(absoluteArtifact).isDirectory()
|
|
28819
|
+
};
|
|
28820
|
+
const occupant = validateLocalState(cwd).find((candidate) => {
|
|
28821
|
+
if (candidate.n === identity.n) return false;
|
|
28822
|
+
const candidatePath = path17.resolve(cwd, normalizeProjectPath(cwd, candidate.filePath));
|
|
28823
|
+
if (!existsSync16(candidatePath)) return false;
|
|
28824
|
+
return artifactsOverlap(nextArtifact, {
|
|
28825
|
+
path: resolveExistingProjectPath(cwd, candidatePath),
|
|
28826
|
+
isDirectory: statSync4(candidatePath).isDirectory()
|
|
28827
|
+
});
|
|
28828
|
+
});
|
|
28829
|
+
if (occupant) {
|
|
28830
|
+
throw new CliError(`\u4EA7\u7269\u8DEF\u5F84 ${artifact} \u5DF2\u88AB ${occupant.n}.json \u5360\u7528`, "SET_ARTIFACT_OCCUPIED");
|
|
28831
|
+
}
|
|
27905
28832
|
const updated = prepareIdentityUpdate(cwd, identity.n, { filePath: artifact });
|
|
27906
28833
|
commitLocalTransaction(cwd, [
|
|
27907
28834
|
{ path: identityFilePath(cwd, updated.n), content: serializeIdentity(updated) }
|
|
@@ -27950,10 +28877,11 @@ function showLocal(cwd, file) {
|
|
|
27950
28877
|
async function showOnline(input2) {
|
|
27951
28878
|
assertPlatformAllowed();
|
|
27952
28879
|
requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
27953
|
-
const
|
|
27954
|
-
if (!
|
|
28880
|
+
const local = resolveIdentity(input2.cwd, input2.file);
|
|
28881
|
+
if (!local.resourceId) {
|
|
27955
28882
|
return "\u672C\u5730\u8FD8\u6CA1\u6709 resourceId";
|
|
27956
28883
|
}
|
|
28884
|
+
const identity = resolveBoundIdentity(input2.cwd, input2.file);
|
|
27957
28885
|
const draft = readDraft(input2.cwd, identity.n);
|
|
27958
28886
|
const hint = draft ? "\u672C\u5730\u6709\u672A\u63D0\u4EA4\u7684\u7248\u672C\u5DE5\u4F5C\u7A3F\uFF0C\u67E5\u770B\u8BF7 version show --local\n" : "";
|
|
27959
28887
|
const infoApi2 = input2.apis?.info ?? ((params) => service_API_default.Resource.info(params));
|
|
@@ -28026,7 +28954,7 @@ async function runUpdateVersion(input2) {
|
|
|
28026
28954
|
}
|
|
28027
28955
|
async function runUpdateVersionLocked(input2) {
|
|
28028
28956
|
assertPlatformAllowed();
|
|
28029
|
-
requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
28957
|
+
const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
|
|
28030
28958
|
const identity = resolveBoundIdentity(input2.cwd, input2.file);
|
|
28031
28959
|
const infoApi2 = input2.apis?.info ?? ((params) => service_API_default.Resource.info(params));
|
|
28032
28960
|
const info2 = unwrapData2(
|
|
@@ -28057,8 +28985,10 @@ async function runUpdateVersionLocked(input2) {
|
|
|
28057
28985
|
throw new CliError("\u63D0\u4EA4\u8BF7\u52A0 --yes", "UPDATE_VERSION_NEED_YES");
|
|
28058
28986
|
}
|
|
28059
28987
|
if (input2.reset) {
|
|
28060
|
-
confirmLocalPath(identity, artifact, input2.yes, input2.cwd);
|
|
28988
|
+
const localPath = confirmLocalPath(identity, artifact, input2.yes, input2.cwd);
|
|
28989
|
+
assertUploadArtifactReady(identity.typeCode, localPath, input2.cwd);
|
|
28061
28990
|
}
|
|
28991
|
+
assertRemoteResourceWritable({ info: info2, resourceId: identity.resourceId, authUserId: auth.userId });
|
|
28062
28992
|
let draft = existingDraft;
|
|
28063
28993
|
if (input2.reset && existingDraft) {
|
|
28064
28994
|
if (!input2.confirmReset) {
|
|
@@ -28103,6 +29033,7 @@ async function runUpdateVersionLocked(input2) {
|
|
|
28103
29033
|
isLoadLatestVersionInfo: 1
|
|
28104
29034
|
})
|
|
28105
29035
|
);
|
|
29036
|
+
assertRemoteResourceWritable({ info: again, resourceId: identity.resourceId, authUserId: auth.userId });
|
|
28106
29037
|
const currentLatest = String(again.latestVersion ?? latestVersion);
|
|
28107
29038
|
if (!semver2.gt(next, currentLatest)) {
|
|
28108
29039
|
throw new CliError(
|
|
@@ -28114,6 +29045,7 @@ async function runUpdateVersionLocked(input2) {
|
|
|
28114
29045
|
cwd: input2.cwd,
|
|
28115
29046
|
identity,
|
|
28116
29047
|
version: next,
|
|
29048
|
+
homeDir: input2.homeDir,
|
|
28117
29049
|
apis: input2.apis
|
|
28118
29050
|
});
|
|
28119
29051
|
return next;
|
|
@@ -28235,26 +29167,26 @@ function createSubCommands() {
|
|
|
28235
29167
|
}
|
|
28236
29168
|
|
|
28237
29169
|
// src/core/usageDocs.ts
|
|
28238
|
-
import { existsSync as
|
|
28239
|
-
import
|
|
29170
|
+
import { existsSync as existsSync17 } from "fs";
|
|
29171
|
+
import path18 from "path";
|
|
28240
29172
|
import { fileURLToPath } from "url";
|
|
28241
29173
|
function usageDocsPath() {
|
|
28242
|
-
const moduleDir =
|
|
28243
|
-
const bundledPath =
|
|
28244
|
-
if (
|
|
29174
|
+
const moduleDir = path18.dirname(fileURLToPath(import.meta.url));
|
|
29175
|
+
const bundledPath = path18.resolve(moduleDir, "../docs/README.md");
|
|
29176
|
+
if (existsSync17(bundledPath)) {
|
|
28245
29177
|
return bundledPath;
|
|
28246
29178
|
}
|
|
28247
|
-
return
|
|
29179
|
+
return path18.resolve(moduleDir, "../../../../docs/\u4E00\u671F/\u4EA7\u54C1\u65B9\u6848/\u4F7F\u7528/README.md");
|
|
28248
29180
|
}
|
|
28249
29181
|
|
|
28250
29182
|
// src/core/packageVersion.ts
|
|
28251
|
-
import { readFileSync as
|
|
28252
|
-
import
|
|
29183
|
+
import { readFileSync as readFileSync11 } from "fs";
|
|
29184
|
+
import path19 from "path";
|
|
28253
29185
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
28254
29186
|
function packageVersion() {
|
|
28255
|
-
const moduleDir =
|
|
28256
|
-
const packageJson =
|
|
28257
|
-
const value = JSON.parse(
|
|
29187
|
+
const moduleDir = path19.dirname(fileURLToPath2(import.meta.url));
|
|
29188
|
+
const packageJson = path19.resolve(moduleDir, "../..", "package.json");
|
|
29189
|
+
const value = JSON.parse(readFileSync11(packageJson, "utf8"));
|
|
28258
29190
|
return typeof value.version === "string" ? value.version : "unknown";
|
|
28259
29191
|
}
|
|
28260
29192
|
|
|
@@ -28279,7 +29211,14 @@ function createProgram() {
|
|
|
28279
29211
|
const cwdFlag = findOptionValue(actionCommand ?? thisCommand, "cwd");
|
|
28280
29212
|
const cwd = resolveCwd(typeof cwdFlag === "string" ? cwdFlag : void 0);
|
|
28281
29213
|
setAuthSearchCwd(cwd);
|
|
28282
|
-
|
|
29214
|
+
const command = actionCommand ?? thisCommand;
|
|
29215
|
+
if (!isResourceFreeCommand(command)) {
|
|
29216
|
+
withProjectLock(cwd, () => void 0, "preselect-resource");
|
|
29217
|
+
}
|
|
29218
|
+
if (!isPendingOperationReadAllowed(command)) {
|
|
29219
|
+
withProjectLock(cwd, () => assertNoPendingOperation(cwd), "pending-operation-gate");
|
|
29220
|
+
}
|
|
29221
|
+
await chooseResourceWhenNeeded(command, cwd);
|
|
28283
29222
|
});
|
|
28284
29223
|
for (const command of Object.values(createSubCommands())) {
|
|
28285
29224
|
program.addCommand(command);
|
|
@@ -28287,6 +29226,10 @@ function createProgram() {
|
|
|
28287
29226
|
return program;
|
|
28288
29227
|
}
|
|
28289
29228
|
var RESOURCE_FREE_COMMANDS = /* @__PURE__ */ new Set(["login", "logout", "init", "template", "type", "resource", "create", "bind"]);
|
|
29229
|
+
var PENDING_OPERATION_READ_COMMANDS = /* @__PURE__ */ new Set(["login", "logout", "template", "type", "status", "show", "validate", "list", "recover"]);
|
|
29230
|
+
function isPendingOperationReadAllowed(command) {
|
|
29231
|
+
return PENDING_OPERATION_READ_COMMANDS.has(command.name());
|
|
29232
|
+
}
|
|
28290
29233
|
async function chooseResourceWhenNeeded(command, cwd) {
|
|
28291
29234
|
if (isResourceFreeCommand(command)) return;
|
|
28292
29235
|
const selector = findOptionValue(command, "resource");
|
|
@@ -28317,7 +29260,7 @@ function resourceChoiceLabel(cwd, identity) {
|
|
|
28317
29260
|
return [
|
|
28318
29261
|
`${identity.n}.json`,
|
|
28319
29262
|
`\u6807\u9898=${identity.title ?? "\uFF08\u672A\u540C\u6B65\u6807\u9898\uFF09"}`,
|
|
28320
|
-
`\u6807\u8BC6=${identity.name ?? "\u672A\u7ED1\u5B9A"}`,
|
|
29263
|
+
`\u6807\u8BC6=${identity.resourceName ?? identity.name ?? "\u672A\u7ED1\u5B9A"}`,
|
|
28321
29264
|
`ID=${identity.resourceId ?? "\u672A\u7ED1\u5B9A"}`,
|
|
28322
29265
|
`\u7C7B\u578B=${identity.typeCode}`,
|
|
28323
29266
|
`\u4EA7\u7269=${identity.filePath ?? "\u672A\u8BBE\u7F6E"}`,
|
|
@@ -28325,15 +29268,10 @@ function resourceChoiceLabel(cwd, identity) {
|
|
|
28325
29268
|
].join(" ");
|
|
28326
29269
|
}
|
|
28327
29270
|
function resourceSelectorExamples(identities) {
|
|
28328
|
-
const titleCounts = /* @__PURE__ */ new Map();
|
|
28329
|
-
for (const identity of identities) {
|
|
28330
|
-
if (identity.title) titleCounts.set(identity.title, (titleCounts.get(identity.title) ?? 0) + 1);
|
|
28331
|
-
}
|
|
28332
29271
|
return identities.map((identity) => {
|
|
28333
29272
|
const selectors = [
|
|
28334
29273
|
...identity.resourceId ? [`id:${identity.resourceId}`] : [],
|
|
28335
|
-
...identity.
|
|
28336
|
-
...identity.title && titleCounts.get(identity.title) === 1 ? [`title:${identity.title}`] : [],
|
|
29274
|
+
...identity.resourceName ? [`name:${identity.resourceName}`] : [],
|
|
28337
29275
|
`artifact:${identity.filePath}`,
|
|
28338
29276
|
`file:${identity.n}.json`
|
|
28339
29277
|
];
|