@freelog-cli/cli2 0.5.2 → 0.5.3

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 CHANGED
@@ -9168,11 +9168,11 @@ var require_mime_types = __commonJS({
9168
9168
  }
9169
9169
  return exts[0];
9170
9170
  }
9171
- function lookup(path16) {
9172
- if (!path16 || typeof path16 !== "string") {
9171
+ function lookup(path19) {
9172
+ if (!path19 || typeof path19 !== "string") {
9173
9173
  return false;
9174
9174
  }
9175
- var extension2 = extname("x." + path16).toLowerCase().substr(1);
9175
+ var extension2 = extname("x." + path19).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 path16 = __require("path");
10290
+ var path19 = __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 = path16.normalize(options.filepath).replace(/\\/g, "/");
10421
+ filename = path19.normalize(options.filepath).replace(/\\/g, "/");
10422
10422
  } else if (options.filename || value && (value.name || value.path)) {
10423
- filename = path16.basename(options.filename || value && (value.name || value.path));
10423
+ filename = path19.basename(options.filename || value && (value.name || value.path));
10424
10424
  } else if (value && value.readable && hasOwn(value, "httpVersion")) {
10425
- filename = path16.basename(value.client._httpMessage.path || "");
10425
+ filename = path19.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(path16, key, dots) {
13343
- if (!path16) return key;
13344
- return path16.concat(key).map(function each(token, i) {
13342
+ function renderKey(path19, key, dots) {
13343
+ if (!path19) return key;
13344
+ return path19.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, path16) {
13430
+ function defaultVisitor(value, key, path19) {
13431
13431
  let arr = value;
13432
13432
  if (utils_default.isReactNative(formData) && utils_default.isReactNativeBlob(value)) {
13433
- formData.append(renderKey(path16, key, dots), convertValue(value));
13433
+ formData.append(renderKey(path19, key, dots), convertValue(value));
13434
13434
  return false;
13435
13435
  }
13436
- if (value && !path16 && typeof value === "object") {
13436
+ if (value && !path19 && 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(path16, key, dots), convertValue(value));
13455
+ formData.append(renderKey(path19, 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, path16, depth = 0) {
13463
+ function build(value, path19, 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 " + path16.join("."));
13467
+ throw new Error("Circular reference detected in " + path19.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, path16, exposedHelpers);
13471
+ const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key) ? key.trim() : key, path19, exposedHelpers);
13472
13472
  if (result === true) {
13473
- build(el, path16 ? path16.concat(key) : [key], depth + 1);
13473
+ build(el, path19 ? path19.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, path16, helpers) {
13685
+ visitor: function(value, key, path19, 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 path16 = [];
13707
+ const path19 = [];
13708
13708
  const pattern = /[^.[\]]+|\[([^.[\]]*)]/g;
13709
13709
  let match;
13710
13710
  while ((match = pattern.exec(name)) !== null) {
13711
- throwIfDepthExceeded(path16.length);
13712
- path16.push(match[0] === "[]" ? "" : match[1] || match[0]);
13711
+ throwIfDepthExceeded(path19.length);
13712
+ path19.push(match[0] === "[]" ? "" : match[1] || match[0]);
13713
13713
  }
13714
- return path16;
13714
+ return path19;
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(path16, value, target, index) {
13729
+ function buildPath(path19, value, target, index) {
13730
13730
  throwIfDepthExceeded(index);
13731
- let name = path16[index++];
13731
+ let name = path19[index++];
13732
13732
  if (name === "__proto__") return true;
13733
13733
  const isNumericKey = Number.isFinite(+name);
13734
- const isLast = index >= path16.length;
13734
+ const isLast = index >= path19.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(path16, value, target[name], index);
13747
+ const result = buildPath(path19, 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 path16;
15465
+ let path19;
15466
15466
  try {
15467
- path16 = buildURL(
15467
+ path19 = 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: path16,
15486
+ path: path19,
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, path16, domain, secure, sameSite) {
15888
+ write(name, value, expires, path19, 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(path16)) {
15895
- cookie.push(`path=${path16}`);
15894
+ if (utils_default.isString(path19)) {
15895
+ cookie.push(`path=${path19}`);
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, path16, Empty) {
17789
+ function getLastOfPath(object, path19, 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 path16 !== "string" ? [].concat(path16) : path16.split(".");
17796
+ var stack = typeof path19 !== "string" ? [].concat(path19) : path19.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, path16, Empty) {
17810
17810
  k: cleanKey(stack.shift())
17811
17811
  };
17812
17812
  }
17813
- function setPath(object, path16, newValue) {
17814
- var _getLastOfPath = getLastOfPath(object, path16, Object), obj = _getLastOfPath.obj, k = _getLastOfPath.k;
17813
+ function setPath(object, path19, newValue) {
17814
+ var _getLastOfPath = getLastOfPath(object, path19, Object), obj = _getLastOfPath.obj, k = _getLastOfPath.k;
17815
17815
  obj[k] = newValue;
17816
17816
  }
17817
- function pushPath(object, path16, newValue, concat) {
17818
- var _getLastOfPath2 = getLastOfPath(object, path16, Object), obj = _getLastOfPath2.obj, k = _getLastOfPath2.k;
17817
+ function pushPath(object, path19, newValue, concat) {
17818
+ var _getLastOfPath2 = getLastOfPath(object, path19, 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, path16) {
17824
- var _getLastOfPath3 = getLastOfPath(object, path16), obj = _getLastOfPath3.obj, k = _getLastOfPath3.k;
17823
+ function getPath(object, path19) {
17824
+ var _getLastOfPath3 = getLastOfPath(object, path19), 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, path16) {
17946
+ function deepFind(obj, path19) {
17947
17947
  var keySeparator = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : ".";
17948
17948
  if (!obj) return void 0;
17949
- if (obj[path16]) return obj[path16];
17950
- var paths = path16.split(keySeparator);
17949
+ if (obj[path19]) return obj[path19];
17950
+ var paths = path19.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, path16) {
17965
17965
  }
17966
17966
  if (mix === void 0) return void 0;
17967
17967
  if (mix === null) return null;
17968
- if (path16.endsWith(p)) {
17968
+ if (path19.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 path16 = [lng, ns];
18026
- if (key && typeof key !== "string") path16 = path16.concat(key);
18027
- if (key && typeof key === "string") path16 = path16.concat(keySeparator ? key.split(keySeparator) : key);
18025
+ var path19 = [lng, ns];
18026
+ if (key && typeof key !== "string") path19 = path19.concat(key);
18027
+ if (key && typeof key === "string") path19 = path19.concat(keySeparator ? key.split(keySeparator) : key);
18028
18028
  if (lng.indexOf(".") > -1) {
18029
- path16 = lng.split(".");
18029
+ path19 = lng.split(".");
18030
18030
  }
18031
- var result = getPath(this.data, path16);
18031
+ var result = getPath(this.data, path19);
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 path16 = [lng, ns];
18044
- if (key) path16 = path16.concat(keySeparator ? key.split(keySeparator) : key);
18043
+ var path19 = [lng, ns];
18044
+ if (key) path19 = path19.concat(keySeparator ? key.split(keySeparator) : key);
18045
18045
  if (lng.indexOf(".") > -1) {
18046
- path16 = lng.split(".");
18046
+ path19 = lng.split(".");
18047
18047
  value = ns;
18048
- ns = path16[1];
18048
+ ns = path19[1];
18049
18049
  }
18050
18050
  this.addNamespaces(ns);
18051
- setPath(this.data, path16, value);
18051
+ setPath(this.data, path19, 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 path16 = [lng, ns];
18073
+ var path19 = [lng, ns];
18074
18074
  if (lng.indexOf(".") > -1) {
18075
- path16 = lng.split(".");
18075
+ path19 = lng.split(".");
18076
18076
  deep = resources;
18077
18077
  resources = ns;
18078
- ns = path16[1];
18078
+ ns = path19[1];
18079
18079
  }
18080
18080
  this.addNamespaces(ns);
18081
- var pack = getPath(this.data, path16) || {};
18081
+ var pack = getPath(this.data, path19) || {};
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, path16, pack);
18087
+ setPath(this.data, path19, 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 path16 = getPathWithDefaults(data, defaultData, key);
19082
- return _this.alwaysFormat ? _this.format(path16, void 0, lng, _objectSpread$3(_objectSpread$3(_objectSpread$3({}, options), data), {}, {
19081
+ var path19 = getPathWithDefaults(data, defaultData, key);
19082
+ return _this.alwaysFormat ? _this.format(path19, void 0, lng, _objectSpread$3(_objectSpread$3(_objectSpread$3({}, options), data), {}, {
19083
19083
  interpolationkey: key
19084
- })) : path16;
19084
+ })) : path19;
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\u72B6\u6001\uFF08N.json\u3001\u8D44\u6E90 ID\u3001\u6807\u8BC6\u7B26\u6216\u6807\u9898\uFF09");
23988
+ ).option("--resource <selector>", "\u9009\u62E9\u672C\u5730\u8D44\u6E90\uFF08id:\u3001name:\u3001title:\u3001artifact: \u6216 file:N.json\uFF09");
23989
23989
  }
23990
23990
  function readSharedOptions(command) {
23991
23991
  const raw = command.optsWithGlobals();
@@ -24247,6 +24247,9 @@ function createLogoutCommand() {
24247
24247
  // src/commands/create/create.ts
24248
24248
  import { Command as Command4 } from "commander";
24249
24249
 
24250
+ // src/domain/create/create.ts
24251
+ import path10 from "path";
24252
+
24250
24253
  // src/local/identity.ts
24251
24254
  import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync4 } from "fs";
24252
24255
  import path6 from "path";
@@ -24456,7 +24459,7 @@ var inputFields = {
24456
24459
  name: z2.string().min(1).optional(),
24457
24460
  title: z2.string().min(1).optional(),
24458
24461
  typeCode: z2.string().min(1),
24459
- filePath: z2.string().min(1).optional(),
24462
+ filePath: z2.string().min(1),
24460
24463
  env: z2.enum(["prod", "test", "dev"]).optional()
24461
24464
  };
24462
24465
  var createSchema = z2.object(inputFields).strict();
@@ -24516,6 +24519,9 @@ function throwZodAsCliError(error2) {
24516
24519
  if (field === "name" || field === "resourceId" || field === "title") {
24517
24520
  throw new CliError("\u7ED1\u5B9A\u8EAB\u4EFD\u5B57\u6BB5\u4E0D\u5B8C\u6574", "IDENTITY_BINDING_INVALID");
24518
24521
  }
24522
+ if (field === "filePath") {
24523
+ throw new CliError("\u6BCF\u4EFD\u8D44\u6E90\u72B6\u6001\u5FC5\u987B\u5173\u8054\u672C\u5730\u4EA7\u7269\u8DEF\u5F84", "IDENTITY_ARTIFACT_REQUIRED");
24524
+ }
24519
24525
  throw new CliError("\u8EAB\u4EFD\u5B57\u6BB5\u65E0\u6548", "IDENTITY_INVALID");
24520
24526
  }
24521
24527
  function toStored(data) {
@@ -24526,7 +24532,7 @@ function toStored(data) {
24526
24532
  ...data.name ? { name: data.name } : {},
24527
24533
  ...data.title ? { title: data.title } : {},
24528
24534
  typeCode: data.typeCode,
24529
- ...data.filePath ? { filePath: data.filePath } : {},
24535
+ filePath: data.filePath,
24530
24536
  ...data.env === "test" || data.env === "dev" ? { env: data.env } : {}
24531
24537
  };
24532
24538
  }
@@ -24545,7 +24551,7 @@ function toDiskObject(identity) {
24545
24551
  ...identity.name ? { name: identity.name } : {},
24546
24552
  ...identity.title ? { title: identity.title } : {},
24547
24553
  typeCode: identity.typeCode,
24548
- ...identity.filePath ? { filePath: identity.filePath } : {},
24554
+ filePath: identity.filePath,
24549
24555
  ...identity.env ? { env: identity.env } : {}
24550
24556
  };
24551
24557
  }
@@ -24757,32 +24763,58 @@ function draftSummary(draft) {
24757
24763
  return ["\u5C06\u8986\u76D6\u672C\u5730\u5DE5\u4F5C\u7A3F\uFF1A", ` \u6765\u6E90\uFF1A${source}`, ` \u6587\u4EF6\uFF1A${draft.filename ?? "\u65E0"} sha1=${sha1}`, ` \u5C5E\u6027 ${(draft.customPropertyDescriptors ?? []).length} / \u4F9D\u8D56 ${(draft.dependencies ?? []).length}`].join("\n");
24758
24764
  }
24759
24765
 
24766
+ // src/local/projectPath.ts
24767
+ import path8 from "path";
24768
+ var defaultError = {
24769
+ code: "FILE_PATH_OUTSIDE_PROJECT",
24770
+ message: "\u8DEF\u5F84\u5FC5\u987B\u843D\u5728\u5F53\u524D\u5DE5\u7A0B\u91CC"
24771
+ };
24772
+ function normalizeProjectPath(cwd, rawPath, error2 = defaultError) {
24773
+ if (!rawPath.trim() || path8.isAbsolute(rawPath) || path8.win32.isAbsolute(rawPath) || path8.posix.isAbsolute(rawPath)) {
24774
+ throw new CliError(error2.message, error2.code);
24775
+ }
24776
+ const root = path8.resolve(cwd);
24777
+ const resolved = path8.resolve(root, rawPath);
24778
+ const relative = path8.relative(root, resolved);
24779
+ if (!relative || relative.startsWith("..") || path8.isAbsolute(relative)) {
24780
+ throw new CliError(error2.message, error2.code);
24781
+ }
24782
+ return relative.replaceAll("\\", "/");
24783
+ }
24784
+
24760
24785
  // src/local/resolve.ts
24761
- function assertNoDuplicate(identities, key) {
24786
+ function assertNoDuplicate(cwd, identities, key) {
24762
24787
  const seen = /* @__PURE__ */ new Map();
24763
24788
  for (const identity of identities) {
24764
24789
  const value = identity[key];
24765
24790
  if (!value) continue;
24766
- const previous = seen.get(value);
24791
+ const comparable = key === "filePath" ? normalizeProjectPath(cwd, value) : value;
24792
+ const previous = seen.get(comparable);
24767
24793
  if (previous !== void 0) {
24768
24794
  throw new CliError(`\u672C\u5730\u72B6\u6001\u51B2\u7A81\uFF1A${previous}.json \u4E0E ${identity.n}.json \u4F7F\u7528\u540C\u4E00 ${key}`, "IDENTITY_CONFLICT");
24769
24795
  }
24770
- seen.set(value, identity.n);
24796
+ seen.set(comparable, identity.n);
24771
24797
  }
24772
24798
  }
24773
- function matches(identity, selector) {
24799
+ function matches(cwd, identity, selector) {
24774
24800
  if (selector.startsWith("file:")) return `${identity.n}.json` === selector.slice(5);
24775
24801
  if (selector.startsWith("id:")) return identity.resourceId === selector.slice(3);
24776
24802
  if (selector.startsWith("name:")) return identity.name === selector.slice(5) || identity.name === selector.slice(5).split("/").pop();
24777
24803
  if (selector.startsWith("title:")) return identity.title === selector.slice(6);
24804
+ if (selector.startsWith("artifact:")) {
24805
+ return normalizeProjectPath(cwd, identity.filePath) === normalizeProjectPath(
24806
+ cwd,
24807
+ selector.slice("artifact:".length)
24808
+ );
24809
+ }
24778
24810
  return `${identity.n}.json` === selector || identity.resourceId === selector || identity.name === selector || identity.title === selector;
24779
24811
  }
24780
24812
  var DRAFT_FILE_RE = /^([1-9]\d*)\.version\.json$/;
24781
24813
  function validateLocalState(cwd) {
24782
24814
  const identities = listIdentities(cwd);
24783
- assertNoDuplicate(identities, "resourceId");
24784
- assertNoDuplicate(identities, "name");
24785
- assertNoDuplicate(identities, "filePath");
24815
+ assertNoDuplicate(cwd, identities, "resourceId");
24816
+ assertNoDuplicate(cwd, identities, "name");
24817
+ assertNoDuplicate(cwd, identities, "filePath");
24786
24818
  const numbers = new Set(identities.map((identity) => identity.n));
24787
24819
  const dir = freelogDir(cwd);
24788
24820
  if (!existsSync7(dir)) return identities;
@@ -24801,7 +24833,7 @@ function resolveIdentity(cwd, selector) {
24801
24833
  const identities = validateLocalState(cwd);
24802
24834
  if (identities.length === 0) {
24803
24835
  throw new CliError(
24804
- "\u5F53\u524D\u76EE\u5F55\u6CA1\u6709\u8D44\u6E90\u72B6\u6001\u3002\u65B0\u8D44\u6E90\u8BF7\u5148 init \u540E create\uFF1B\u5DF2\u6709\u8D44\u6E90\u8BF7 bind <\u8D44\u6E90 ID|\u6807\u8BC6\u7B26> --artifact <\u8DEF\u5F84>\u3002",
24836
+ "\u5F53\u524D\u76EE\u5F55\u6CA1\u6709\u8D44\u6E90\u72B6\u6001\u3002\u65B0\u8D44\u6E90\u53EF\u76F4\u63A5 create --type <\u53F6\u5B50\u7C7B\u578B> --artifact <\u8DEF\u5F84>\uFF0C\u4E5F\u53EF\u5148 init \u518D create\uFF1B\u5DF2\u6709\u8D44\u6E90\u8BF7 bind <\u8D44\u6E90 ID|\u6807\u8BC6\u7B26> --artifact <\u8DEF\u5F84>\u3002",
24805
24837
  "IDENTITY_NOT_FOUND"
24806
24838
  );
24807
24839
  }
@@ -24809,12 +24841,12 @@ function resolveIdentity(cwd, selector) {
24809
24841
  if (identities.length === 1) return identities[0];
24810
24842
  throw new CliError("\u5F53\u524D\u5DE5\u7A0B\u6709\u591A\u4EFD\u8D44\u6E90\u72B6\u6001\uFF1B\u8BF7\u4F7F\u7528 --resource \u6307\u5B9A\u8D44\u6E90", "IDENTITY_RESOURCE_REQUIRED");
24811
24843
  }
24812
- const matched = identities.filter((identity) => matches(identity, selector));
24844
+ const matched = identities.filter((identity) => matches(cwd, identity, selector));
24813
24845
  if (matched.length === 1) return matched[0];
24814
24846
  if (matched.length === 0) {
24815
24847
  throw new CliError(`\u627E\u4E0D\u5230\u8D44\u6E90\u9009\u62E9\u5668 ${selector}`, "IDENTITY_RESOURCE_NOT_FOUND");
24816
24848
  }
24817
- throw new CliError(`\u8D44\u6E90\u9009\u62E9\u5668 ${selector} \u5339\u914D\u591A\u4EFD\u72B6\u6001\uFF1B\u8BF7\u4F7F\u7528 file:\u3001id: \u6216 name:`, "IDENTITY_RESOURCE_AMBIGUOUS");
24849
+ throw new CliError(`\u8D44\u6E90\u9009\u62E9\u5668 ${selector} \u5339\u914D\u591A\u4EFD\u72B6\u6001\uFF1B\u8BF7\u4F7F\u7528 id:\u3001name:\u3001artifact: \u6216 file:`, "IDENTITY_RESOURCE_AMBIGUOUS");
24818
24850
  }
24819
24851
 
24820
24852
  // src/core/tty.ts
@@ -24854,6 +24886,16 @@ async function confirmWrite(preview, yes) {
24854
24886
  }
24855
24887
  return preview;
24856
24888
  }
24889
+ async function confirmDestructive(preview, action, yes, interactive = isInteractive(), ask = confirmQuestion) {
24890
+ if (yes) {
24891
+ return true;
24892
+ }
24893
+ if (!interactive) {
24894
+ throw new CliError(`\u6709\u672A\u63D0\u4EA4\u5DE5\u4F5C\u7A3F\uFF1B\u8BF7\u52A0 --yes \u786E\u8BA4${action}`, "DRAFT_DESTRUCTIVE_NEED_YES");
24895
+ }
24896
+ return ask(`${preview}
24897
+ \u786E\u8BA4${action}\uFF1F`, false);
24898
+ }
24857
24899
 
24858
24900
  // src/domain/create/typePick.ts
24859
24901
  function unwrapList(result) {
@@ -24989,29 +25031,83 @@ function formatTypeList(items) {
24989
25031
  return items.map((item) => `${item.code} ${item.nameChain ?? item.name}`).join("\n");
24990
25032
  }
24991
25033
 
24992
- // src/local/projectPath.ts
24993
- import path8 from "path";
24994
- var defaultError = {
24995
- code: "FILE_PATH_OUTSIDE_PROJECT",
24996
- message: "\u8DEF\u5F84\u5FC5\u987B\u843D\u5728\u5F53\u524D\u5DE5\u7A0B\u91CC"
24997
- };
24998
- function normalizeProjectPath(cwd, rawPath, error2 = defaultError) {
24999
- if (!rawPath.trim() || path8.isAbsolute(rawPath) || path8.win32.isAbsolute(rawPath) || path8.posix.isAbsolute(rawPath)) {
25000
- throw new CliError(error2.message, error2.code);
25034
+ // src/domain/version/zip.ts
25035
+ import { createWriteStream, existsSync as existsSync8, readdirSync as readdirSync3, statSync, unlinkSync as unlinkSync5 } from "fs";
25036
+ import { tmpdir } from "os";
25037
+ import path9 from "path";
25038
+ import { finished } from "stream/promises";
25039
+ import archiver from "archiver";
25040
+ function isThemeOrWidget(typeCode) {
25041
+ return typeCode === "RT001" || typeCode === "RT002";
25042
+ }
25043
+ function assertArtifactPath(typeCode, filePath) {
25044
+ const stats = existsSync8(filePath) ? statSync(filePath) : void 0;
25045
+ const themeOrWidget = isThemeOrWidget(typeCode);
25046
+ if (stats?.isDirectory() && !themeOrWidget) {
25047
+ throw new CliError("\u4E0D\u652F\u6301\u6587\u4EF6\u5939\uFF0C\u8BF7\u6307\u5B9A\u4E00\u4E2A\u6587\u4EF6\u3002", "FILE_DIRECTORY_UNSUPPORTED");
25001
25048
  }
25002
- const root = path8.resolve(cwd);
25003
- const resolved = path8.resolve(root, rawPath);
25004
- const relative = path8.relative(root, resolved);
25005
- if (!relative || relative.startsWith("..") || path8.isAbsolute(relative)) {
25006
- throw new CliError(error2.message, error2.code);
25049
+ }
25050
+ function assertArtifactAnchor(typeCode, filePath) {
25051
+ if (!existsSync8(filePath)) {
25052
+ throw new CliError(`\u672C\u5730\u4EA7\u7269\u4E0D\u5B58\u5728\uFF1A${filePath}`, "ARTIFACT_ANCHOR_MISSING");
25053
+ }
25054
+ const stats = statSync(filePath);
25055
+ assertArtifactPath(typeCode, filePath);
25056
+ if (!isThemeOrWidget(typeCode) && !stats.isFile()) {
25057
+ throw new CliError("\u4E0D\u652F\u6301\u6587\u4EF6\u5939\uFF0C\u8BF7\u6307\u5B9A\u4E00\u4E2A\u6587\u4EF6\u3002", "FILE_DIRECTORY_UNSUPPORTED");
25007
25058
  }
25008
- return relative.replaceAll("\\", "/");
25059
+ }
25060
+ async function zipDirectoryContents(dir) {
25061
+ if (!existsSync8(dir) || !statSync(dir).isDirectory()) {
25062
+ throw new CliError(`\u6CA1\u6709\u6784\u5EFA\u4EA7\u7269 ${dir}\uFF0C\u8BF7\u5148\u6784\u5EFA`, "ZIP_MISSING");
25063
+ }
25064
+ if (existsSync8(path9.join(dir, ".freelog"))) {
25065
+ 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
+ }
25067
+ const entries = readdirSync3(dir);
25068
+ if (entries.length === 0) {
25069
+ throw new CliError("\u6784\u5EFA\u4EA7\u7269\u662F\u7A7A\u7684\uFF0C\u8BF7\u5148\u6784\u5EFA", "ZIP_EMPTY");
25070
+ }
25071
+ const outPath = path9.join(
25072
+ tmpdir(),
25073
+ `freelog-zip-${process.pid}-${Date.now()}.zip`
25074
+ );
25075
+ const output2 = createWriteStream(outPath);
25076
+ const archive = archiver("zip", { zlib: { level: 9 } });
25077
+ try {
25078
+ archive.on("error", (error2) => output2.destroy(error2));
25079
+ archive.pipe(output2);
25080
+ for (const entry2 of entries) {
25081
+ const full = path9.join(dir, entry2);
25082
+ const stats = statSync(full);
25083
+ if (stats.isDirectory()) {
25084
+ archive.directory(full, entry2);
25085
+ } else {
25086
+ archive.file(full, { name: entry2 });
25087
+ }
25088
+ }
25089
+ await archive.finalize();
25090
+ await finished(output2);
25091
+ return outPath;
25092
+ } catch (error2) {
25093
+ if (existsSync8(outPath)) {
25094
+ try {
25095
+ unlinkSync5(outPath);
25096
+ } catch {
25097
+ }
25098
+ }
25099
+ throw error2;
25100
+ }
25101
+ }
25102
+ async function prepareUploadPath(typeCode, filePath) {
25103
+ assertArtifactPath(typeCode, filePath);
25104
+ if (isThemeOrWidget(typeCode) && existsSync8(filePath) && statSync(filePath).isDirectory()) {
25105
+ return zipDirectoryContents(filePath);
25106
+ }
25107
+ return filePath;
25009
25108
  }
25010
25109
 
25011
25110
  // src/domain/create/create.ts
25012
- function isFixedTemplateType(typeCode) {
25013
- return typeCode === "RT001" || typeCode === "RT002";
25014
- }
25015
25111
  function unwrapData(result) {
25016
25112
  const envelope = result;
25017
25113
  return envelope.data ?? result;
@@ -25093,13 +25189,14 @@ async function assertOwnShellAvailable(input2) {
25093
25189
  );
25094
25190
  }
25095
25191
  function writeCreatedIdentity(input2) {
25096
- const filePath = input2.file;
25192
+ const filePath = input2.file ?? input2.target?.filePath;
25193
+ if (!filePath) throw new CliError("\u65B0\u8D44\u6E90\u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "CREATE_ARTIFACT_REQUIRED");
25097
25194
  const patch = {
25098
25195
  resourceId: input2.resourceId,
25099
25196
  name: input2.name,
25100
25197
  title: input2.title,
25101
25198
  typeCode: input2.typeCode,
25102
- ...filePath ? { filePath } : {},
25199
+ filePath,
25103
25200
  env: input2.env
25104
25201
  };
25105
25202
  return input2.target ? updateIdentity(input2.cwd, input2.target.n, patch) : createIdentity(input2.cwd, {
@@ -25108,7 +25205,7 @@ function writeCreatedIdentity(input2) {
25108
25205
  name: input2.name,
25109
25206
  title: input2.title,
25110
25207
  typeCode: input2.typeCode,
25111
- ...filePath ? { filePath } : {},
25208
+ filePath,
25112
25209
  env: input2.env
25113
25210
  });
25114
25211
  }
@@ -25141,18 +25238,17 @@ async function createResource(input2) {
25141
25238
  if (input2.yes && !input2.type && !target?.typeCode) {
25142
25239
  throw new CliError("--yes \u5728\u6CA1\u6709\u5DE5\u7A0B\u7C7B\u578B\u65F6\u5FC5\u987B\u63D0\u4F9B --type", "CREATE_YES_FLAGS");
25143
25240
  }
25144
- const targetTypeCode = target?.typeCode;
25145
- if (!target && isFixedTemplateType(input2.type) && !file) {
25146
- throw new CliError(
25147
- input2.type === "RT001" ? "\u5DF2\u6709\u4E3B\u9898\u5DE5\u7A0B\u8BF7\u901A\u8FC7 --artifact \u6307\u5B9A\u6784\u5EFA\u76EE\u5F55" : "\u5DF2\u6709\u63D2\u4EF6\u5DE5\u7A0B\u8BF7\u901A\u8FC7 --artifact \u6307\u5B9A\u6784\u5EFA\u76EE\u5F55",
25148
- "CREATE_FIXED_TYPE_FILE_REQUIRED"
25149
- );
25241
+ const artifact = file ?? target?.filePath;
25242
+ if (!artifact) {
25243
+ throw new CliError("\u65B0\u8D44\u6E90\u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "CREATE_ARTIFACT_REQUIRED");
25150
25244
  }
25151
- if (isFixedTemplateType(targetTypeCode) && input2.type && input2.type !== targetTypeCode) {
25245
+ const targetTypeCode = target?.typeCode;
25246
+ if ((targetTypeCode === "RT001" || targetTypeCode === "RT002") && input2.type && input2.type !== targetTypeCode) {
25152
25247
  throw new CliError("\u4E3B\u9898/\u63D2\u4EF6\u5DE5\u7A0B\u7684\u8D44\u6E90\u7C7B\u578B\u56FA\u5B9A\uFF0C\u4E0D\u80FD\u7528 --type \u6539\u5199", "CREATE_FIXED_TYPE");
25153
25248
  }
25154
25249
  const typeCode = resolveTypeCode(input2.type, target);
25155
25250
  await getTypeInfo(typeCode, input2.apis);
25251
+ assertArtifactAnchor(typeCode, path10.resolve(input2.cwd, artifact));
25156
25252
  await assertOwnShellAvailable({
25157
25253
  authLoginName: auth.loginName,
25158
25254
  authUserId: auth.userId,
@@ -25353,7 +25449,7 @@ function createUpdateCommand() {
25353
25449
 
25354
25450
  // src/commands/policy/apply.ts
25355
25451
  import { readFileSync as readFileSync6 } from "fs";
25356
- import path9 from "path";
25452
+ import path11 from "path";
25357
25453
  import { confirm, input } from "@inquirer/prompts";
25358
25454
  import { Command as Command6 } from "commander";
25359
25455
 
@@ -25532,7 +25628,7 @@ async function setPolicy(input2) {
25532
25628
  // src/commands/policy/apply.ts
25533
25629
  function parsePolicy(file) {
25534
25630
  const text = readFileSync6(file, "utf8");
25535
- if (path9.extname(file).toLowerCase() !== ".json") return { policyText: text };
25631
+ if (path11.extname(file).toLowerCase() !== ".json") return { policyText: text };
25536
25632
  let parsed;
25537
25633
  try {
25538
25634
  parsed = JSON.parse(text);
@@ -25656,14 +25752,18 @@ function createPolicyTemplateCommand() {
25656
25752
  // src/commands/project/bind.ts
25657
25753
  import { Command as Command10 } from "commander";
25658
25754
 
25755
+ // src/domain/bind/bind.ts
25756
+ import { existsSync as existsSync10 } from "fs";
25757
+
25659
25758
  // src/local/indexFile.ts
25660
- import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
25661
- import path10 from "path";
25759
+ import { existsSync as existsSync9, readFileSync as readFileSync7 } from "fs";
25760
+ import path12 from "path";
25662
25761
  function normalizeFileKey(filePath) {
25663
- return filePath.replaceAll("\\", "/").replace(/^\.\//, "");
25762
+ return path12.posix.normalize(filePath.replaceAll("\\", "/")).replace(/^\.\//, "");
25664
25763
  }
25665
25764
 
25666
25765
  // src/domain/bind/bind.ts
25766
+ import path13 from "path";
25667
25767
  async function bindResource(input2) {
25668
25768
  assertPlatformAllowed();
25669
25769
  const auth = requireAuth({ cwd: input2.cwd, homeDir: input2.homeDir });
@@ -25672,6 +25772,12 @@ async function bindResource(input2) {
25672
25772
  code: "BIND_FILE_OUTSIDE",
25673
25773
  message: "--artifact \u5FC5\u987B\u843D\u5728\u5F53\u524D\u5DE5\u7A0B\u91CC"
25674
25774
  }) : void 0;
25775
+ if (filePath) {
25776
+ const absolute = path13.resolve(input2.cwd, filePath);
25777
+ if (!existsSync10(absolute)) {
25778
+ throw new CliError(`\u672C\u5730\u4EA7\u7269\u4E0D\u5B58\u5728\uFF1A${absolute}`, "ARTIFACT_ANCHOR_MISSING");
25779
+ }
25780
+ }
25675
25781
  const infoApi2 = input2.apis?.info ?? ((params) => service_API_default.Resource.info(params));
25676
25782
  const info2 = unwrapData2(
25677
25783
  await infoApi2({
@@ -25718,9 +25824,11 @@ async function bindResource(input2) {
25718
25824
  if (byFile && target?.n !== byFile.n) {
25719
25825
  throw new CliError("\u8DEF\u5F84\u5DF2\u88AB\u5360\u7528", "BIND_PATH_TAKEN");
25720
25826
  }
25721
- if (isThemeOrWidget(typeCode) && !filePath && !target?.filePath) {
25722
- throw new CliError("\u4E3B\u9898/\u63D2\u4EF6 bind \u65F6\u8BF7\u901A\u8FC7 --artifact \u6307\u5B9A\u6784\u5EFA\u76EE\u5F55", "BIND_FIXED_TYPE_FILE_REQUIRED");
25827
+ const resolvedFilePath = filePath ?? target?.filePath;
25828
+ if (!resolvedFilePath) {
25829
+ throw new CliError("\u65B0\u589E\u672C\u5730\u72B6\u6001\u65F6\u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "BIND_ARTIFACT_REQUIRED");
25723
25830
  }
25831
+ assertArtifactAnchor(typeCode, path13.resolve(input2.cwd, resolvedFilePath));
25724
25832
  const env = getEnv2();
25725
25833
  if (target) {
25726
25834
  const resourceChanged = target.resourceId !== resourceId;
@@ -25736,7 +25844,7 @@ async function bindResource(input2) {
25736
25844
  name,
25737
25845
  title,
25738
25846
  typeCode,
25739
- filePath: filePath ?? target.filePath,
25847
+ filePath: resolvedFilePath,
25740
25848
  env
25741
25849
  });
25742
25850
  commitLocalTransaction(input2.cwd, [
@@ -25751,7 +25859,7 @@ async function bindResource(input2) {
25751
25859
  name,
25752
25860
  title,
25753
25861
  typeCode,
25754
- filePath,
25862
+ filePath: resolvedFilePath,
25755
25863
  env
25756
25864
  });
25757
25865
  commitLocalTransaction(input2.cwd, [
@@ -25768,9 +25876,6 @@ function isCollectionSubject(subjectType) {
25768
25876
  const values = Array.isArray(subjectType) ? subjectType : [subjectType];
25769
25877
  return values.some((value) => Number(value) === 4);
25770
25878
  }
25771
- function isThemeOrWidget(typeCode) {
25772
- return typeCode === "RT001" || typeCode === "RT002";
25773
- }
25774
25879
 
25775
25880
  // src/commands/project/bind.ts
25776
25881
  function createBindCommand() {
@@ -25806,9 +25911,9 @@ import { Command as Command11 } from "commander";
25806
25911
 
25807
25912
  // src/domain/init/scaffold.ts
25808
25913
  import { execFile as execFileCallback } from "child_process";
25809
- import { cpSync, existsSync as existsSync9, lstatSync, mkdirSync as mkdirSync2, mkdtempSync, readdirSync as readdirSync3, readFileSync as readFileSync8, renameSync, rmSync } from "fs";
25914
+ import { cpSync, existsSync as existsSync11, lstatSync, mkdirSync as mkdirSync2, mkdtempSync, readdirSync as readdirSync4, readFileSync as readFileSync8, renameSync, rmSync } from "fs";
25810
25915
  import os4 from "os";
25811
- import path11 from "path";
25916
+ import path14 from "path";
25812
25917
  import { promisify } from "util";
25813
25918
 
25814
25919
  // src/domain/init/templates.ts
@@ -25834,44 +25939,49 @@ function formatTemplateList(items) {
25834
25939
 
25835
25940
  // src/domain/init/scaffold.ts
25836
25941
  var execFile = promisify(execFileCallback);
25837
- function isFixedTemplateType2(typeCode) {
25838
- return typeCode === "RT001" || typeCode === "RT002";
25839
- }
25840
25942
  function resolveTargetDir(input2) {
25841
- return input2.dir ? path11.isAbsolute(input2.dir) ? input2.dir : path11.resolve(input2.cwd, input2.dir) : path11.resolve(input2.cwd);
25943
+ return input2.dir ? path14.isAbsolute(input2.dir) ? input2.dir : path14.resolve(input2.cwd, input2.dir) : path14.resolve(input2.cwd);
25842
25944
  }
25843
25945
  function targetHasOnlyAuthSelector(targetDir) {
25844
- if (!existsSync9(targetDir)) return false;
25946
+ if (!existsSync11(targetDir)) return false;
25845
25947
  let entries;
25846
25948
  try {
25847
- entries = readdirSync3(targetDir);
25949
+ entries = readdirSync4(targetDir);
25848
25950
  } catch {
25849
25951
  throw new CliError("\u76EE\u6807\u76EE\u5F55\u4E0D\u53EF\u8BFB\u53D6\uFF0C\u62D2\u7EDD\u8986\u76D6", "INIT_TARGET_NOT_EMPTY");
25850
25952
  }
25851
25953
  if (entries.length === 0) return false;
25852
25954
  if (entries.length !== 1 || entries[0] !== ".freelog") return false;
25853
- const stateDir = path11.join(targetDir, ".freelog");
25854
- if (!lstatSync(stateDir).isDirectory() || lstatSync(stateDir).isSymbolicLink()) return false;
25855
- const stateEntries = readdirSync3(stateDir);
25955
+ const stateDir = path14.join(targetDir, ".freelog");
25956
+ return stateDirHasOnlyAuthSelector(stateDir);
25957
+ }
25958
+ function stateDirHasOnlyAuthSelector(stateDir) {
25959
+ if (!existsSync11(stateDir) || !lstatSync(stateDir).isDirectory() || lstatSync(stateDir).isSymbolicLink()) return false;
25960
+ const stateEntries = readdirSync4(stateDir);
25856
25961
  if (stateEntries.length !== 1 || stateEntries[0] !== "auth") return false;
25857
- const auth = lstatSync(path11.join(stateDir, "auth"));
25962
+ const auth = lstatSync(path14.join(stateDir, "auth"));
25858
25963
  return auth.isFile() && !auth.isSymbolicLink();
25859
25964
  }
25860
- function assertInitialTarget(targetDir) {
25861
- if (!existsSync9(targetDir)) return { targetExisted: false, preserveAuth: false };
25862
- const entries = readdirSync3(targetDir);
25863
- if (entries.length === 0) return { targetExisted: true, preserveAuth: false };
25864
- if (targetHasOnlyAuthSelector(targetDir)) return { targetExisted: true, preserveAuth: true };
25965
+ function assertInitialTarget(targetDir, adoptExistingProject) {
25966
+ if (!existsSync11(targetDir)) return { targetExisted: false, preserveAuth: false, adoptExistingProject };
25967
+ const entries = readdirSync4(targetDir);
25968
+ if (entries.length === 0) return { targetExisted: true, preserveAuth: false, adoptExistingProject };
25969
+ if (targetHasOnlyAuthSelector(targetDir)) return { targetExisted: true, preserveAuth: true, adoptExistingProject };
25970
+ if (adoptExistingProject) {
25971
+ const stateDir = path14.join(targetDir, ".freelog");
25972
+ if (!existsSync11(stateDir)) return { targetExisted: true, preserveAuth: false, adoptExistingProject: true };
25973
+ if (stateDirHasOnlyAuthSelector(stateDir)) return { targetExisted: true, preserveAuth: true, adoptExistingProject: true };
25974
+ }
25865
25975
  throw new CliError("\u76EE\u6807\u76EE\u5F55\u4E0D\u662F\u7A7A\u76EE\u5F55\uFF0C\u62D2\u7EDD\u8986\u76D6", "INIT_TARGET_NOT_EMPTY");
25866
25976
  }
25867
25977
  function assertOnlyAuthSelectorStillThere(targetDir) {
25868
- if (!targetHasOnlyAuthSelector(targetDir)) {
25978
+ if (!stateDirHasOnlyAuthSelector(path14.join(targetDir, ".freelog"))) {
25869
25979
  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");
25870
25980
  }
25871
25981
  }
25872
25982
  function copyDirectoryContents(sourceDir, targetDir) {
25873
- for (const entry2 of readdirSync3(sourceDir)) {
25874
- cpSync(path11.join(sourceDir, entry2), path11.join(targetDir, entry2), { recursive: true, errorOnExist: true, force: false });
25983
+ for (const entry2 of readdirSync4(sourceDir)) {
25984
+ cpSync(path14.join(sourceDir, entry2), path14.join(targetDir, entry2), { recursive: true, errorOnExist: true, force: false });
25875
25985
  }
25876
25986
  }
25877
25987
  function parsePackFilename(stdout) {
@@ -25883,8 +25993,8 @@ function parsePackFilename(stdout) {
25883
25993
  throw new CliError("\u6A21\u677F\u4E0B\u8F7D\u5931\u8D25\uFF1Anpm \u672A\u8FD4\u56DE\u5B89\u88C5\u5305", "TEMPLATE_DOWNLOAD_FAILED");
25884
25994
  }
25885
25995
  function validateRemoteTemplate(packageDir, template) {
25886
- const manifestPath = path11.join(packageDir, "template.manifest.json");
25887
- const templateDir = path11.join(packageDir, "template");
25996
+ const manifestPath = path14.join(packageDir, "template.manifest.json");
25997
+ const templateDir = path14.join(packageDir, "template");
25888
25998
  let manifest;
25889
25999
  try {
25890
26000
  manifest = JSON.parse(readFileSync8(manifestPath, "utf8"));
@@ -25892,15 +26002,15 @@ function validateRemoteTemplate(packageDir, template) {
25892
26002
  throw new CliError("\u6A21\u677F\u6821\u9A8C\u5931\u8D25\uFF1A\u7F3A\u5C11\u6216\u65E0\u6CD5\u8BFB\u53D6 template.manifest.json", "TEMPLATE_INVALID");
25893
26003
  }
25894
26004
  const tags = Array.isArray(manifest.tags) ? manifest.tags : [];
25895
- if (manifest.id !== template.id || manifest.npmName !== template.npmName || manifest.version !== template.version || !tags.includes("runtime") || !template.targets.every((target) => tags.includes(target)) || !existsSync9(templateDir)) {
26005
+ if (manifest.id !== template.id || manifest.npmName !== template.npmName || manifest.version !== template.version || !tags.includes("runtime") || !template.targets.every((target) => tags.includes(target)) || !existsSync11(templateDir)) {
25896
26006
  throw new CliError("\u6A21\u677F\u6821\u9A8C\u5931\u8D25\uFF1A\u7EBF\u4E0A\u6A21\u677F\u4E0E\u53D7\u63A7\u6E05\u5355\u4E0D\u4E00\u81F4", "TEMPLATE_INVALID");
25897
26007
  }
25898
26008
  return templateDir;
25899
26009
  }
25900
26010
  async function installRemoteTemplate(input2) {
25901
- const tempDir = mkdtempSync(path11.join(os4.tmpdir(), "freelog-template-"));
25902
- const downloadDir = path11.join(tempDir, "download");
25903
- const extractDir = path11.join(tempDir, "extract");
26011
+ const tempDir = mkdtempSync(path14.join(os4.tmpdir(), "freelog-template-"));
26012
+ const downloadDir = path14.join(tempDir, "download");
26013
+ const extractDir = path14.join(tempDir, "extract");
25904
26014
  mkdirSync2(downloadDir);
25905
26015
  mkdirSync2(extractDir);
25906
26016
  const npm = process.platform === "win32" ? "npm.cmd" : "npm";
@@ -25911,78 +26021,86 @@ async function installRemoteTemplate(input2) {
25911
26021
  } catch {
25912
26022
  throw new CliError(`\u6A21\u677F\u4E0B\u8F7D\u5931\u8D25\uFF1A${input2.template.id}`, "TEMPLATE_DOWNLOAD_FAILED");
25913
26023
  }
25914
- const archivePath = path11.join(downloadDir, parsePackFilename(stdout));
26024
+ const archivePath = path14.join(downloadDir, parsePackFilename(stdout));
25915
26025
  try {
25916
26026
  await execFile("tar", ["-xzf", archivePath, "-C", extractDir]);
25917
26027
  } catch {
25918
26028
  throw new CliError(`\u6A21\u677F\u89E3\u5305\u5931\u8D25\uFF1A${input2.template.id}`, "TEMPLATE_EXTRACT_FAILED");
25919
26029
  }
25920
- copyDirectoryContents(validateRemoteTemplate(path11.join(extractDir, "package"), input2.template), input2.targetDir);
26030
+ copyDirectoryContents(validateRemoteTemplate(path14.join(extractDir, "package"), input2.template), input2.targetDir);
25921
26031
  } finally {
25922
26032
  rmSync(tempDir, { recursive: true, force: true });
25923
26033
  }
25924
26034
  }
25925
- function commitStaging(stagingDir, targetDir, targetExisted, preserveAuth) {
26035
+ function commitStaging(stagingDir, targetDir, targetExisted, preserveAuth, adoptExistingProject) {
25926
26036
  if (!targetExisted) {
25927
26037
  renameSync(stagingDir, targetDir);
25928
26038
  return;
25929
26039
  }
25930
26040
  if (preserveAuth) {
25931
26041
  assertOnlyAuthSelectorStillThere(targetDir);
26042
+ } else if (adoptExistingProject) {
26043
+ if (existsSync11(path14.join(targetDir, ".freelog"))) {
26044
+ 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
+ }
26046
+ renameSync(path14.join(stagingDir, ".freelog"), path14.join(targetDir, ".freelog"));
26047
+ rmSync(stagingDir, { recursive: true, force: true });
26048
+ return;
25932
26049
  } else {
25933
- assertInitialTarget(targetDir);
26050
+ assertInitialTarget(targetDir, false);
25934
26051
  }
25935
- for (const entry2 of readdirSync3(stagingDir)) {
25936
- const destination = path11.join(targetDir, entry2);
26052
+ for (const entry2 of readdirSync4(stagingDir)) {
26053
+ const destination = path14.join(targetDir, entry2);
25937
26054
  if (preserveAuth && entry2 === ".freelog") {
25938
- for (const stateEntry of readdirSync3(path11.join(stagingDir, entry2))) {
25939
- const stateDestination = path11.join(destination, stateEntry);
25940
- if (existsSync9(stateDestination)) {
26055
+ for (const stateEntry of readdirSync4(path14.join(stagingDir, entry2))) {
26056
+ const stateDestination = path14.join(destination, stateEntry);
26057
+ if (existsSync11(stateDestination)) {
25941
26058
  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");
25942
26059
  }
25943
- renameSync(path11.join(stagingDir, entry2, stateEntry), stateDestination);
26060
+ renameSync(path14.join(stagingDir, entry2, stateEntry), stateDestination);
25944
26061
  }
25945
- rmSync(path11.join(stagingDir, entry2), { recursive: true, force: true });
26062
+ rmSync(path14.join(stagingDir, entry2), { recursive: true, force: true });
25946
26063
  continue;
25947
26064
  }
25948
- if (existsSync9(destination)) {
26065
+ if (existsSync11(destination)) {
25949
26066
  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");
25950
26067
  }
25951
- renameSync(path11.join(stagingDir, entry2), destination);
26068
+ renameSync(path14.join(stagingDir, entry2), destination);
25952
26069
  }
25953
26070
  rmSync(stagingDir, { recursive: true, force: true });
25954
26071
  }
25955
26072
  async function initProject(input2) {
25956
26073
  const targetDir = resolveTargetDir(input2);
25957
26074
  return withInitLock(targetDir, async () => {
25958
- const initialTarget = assertInitialTarget(targetDir);
25959
26075
  const shortcut = input2.shortcut;
26076
+ const adoptExistingProject = !shortcut;
26077
+ const initialTarget = assertInitialTarget(targetDir, adoptExistingProject);
25960
26078
  if (shortcut && input2.yes && !input2.template) {
25961
26079
  throw new CliError("init theme / widget \u4F7F\u7528 --yes \u65F6\u5FC5\u987B\u5E26 --template", "INIT_TEMPLATE_REQUIRED");
25962
26080
  }
25963
26081
  if (!shortcut && !input2.typeCode?.trim()) {
25964
26082
  throw new CliError("\u8BF7\u9009\u62E9\u8D44\u6E90\u7C7B\u578B", "INIT_TYPE_REQUIRED");
25965
26083
  }
25966
- const typeCode = shortcut === "theme" ? "RT001" : shortcut === "widget" ? "RT002" : (await (input2.typeValidator ?? ((code) => getTypeInfo(code, input2.typeApis)))(input2.typeCode)).code;
25967
- if (!shortcut && isFixedTemplateType2(typeCode)) {
25968
- throw new CliError(
25969
- typeCode === "RT001" ? "\u4E3B\u9898\u8BF7\u4F7F\u7528 init theme \u521B\u5EFA\u6A21\u677F\u5DE5\u7A0B" : "\u63D2\u4EF6\u8BF7\u4F7F\u7528 init widget \u521B\u5EFA\u6A21\u677F\u5DE5\u7A0B",
25970
- "INIT_TEMPLATE_SHORTCUT_REQUIRED"
25971
- );
26084
+ if (!shortcut && !input2.artifact?.trim()) {
26085
+ throw new CliError("init \u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "INIT_ARTIFACT_REQUIRED");
25972
26086
  }
26087
+ const typeCode = shortcut === "theme" ? "RT001" : shortcut === "widget" ? "RT002" : (await (input2.typeValidator ?? ((code) => getTypeInfo(code, input2.typeApis)))(input2.typeCode)).code;
26088
+ const artifact = shortcut ? "dist" : normalizeProjectPath(targetDir, input2.artifact);
26089
+ if (!shortcut) assertArtifactAnchor(typeCode, path14.resolve(targetDir, artifact));
25973
26090
  const template = shortcut && input2.template ? getTemplate(input2.template, shortcut) : void 0;
25974
26091
  if (shortcut && !template) throw new CliError("\u8BF7\u9009\u62E9\u6A21\u677F", "INIT_TEMPLATE_REQUIRED");
25975
- const parent = path11.dirname(targetDir);
26092
+ const parent = path14.dirname(targetDir);
25976
26093
  mkdirSync2(parent, { recursive: true });
25977
- const stagingDir = mkdtempSync(path11.join(parent, `.${path11.basename(targetDir)}.freelog-init-`));
26094
+ const stagingDir = mkdtempSync(path14.join(parent, `.${path14.basename(targetDir)}.freelog-init-`));
25978
26095
  try {
25979
26096
  if (template) await (input2.templateSource ?? installRemoteTemplate)({ template, targetDir: stagingDir });
26097
+ if (shortcut) mkdirSync2(path14.join(stagingDir, artifact), { recursive: true });
25980
26098
  const created = createIdentity(stagingDir, {
25981
26099
  subject: "resource",
25982
26100
  typeCode,
25983
- ...shortcut ? { filePath: "dist" } : {}
26101
+ filePath: artifact
25984
26102
  });
25985
- commitStaging(stagingDir, targetDir, initialTarget.targetExisted, initialTarget.preserveAuth);
26103
+ commitStaging(stagingDir, targetDir, initialTarget.targetExisted, initialTarget.preserveAuth, adoptExistingProject);
25986
26104
  return { ...created, n: created.n };
25987
26105
  } catch (error2) {
25988
26106
  rmSync(stagingDir, { recursive: true, force: true });
@@ -26012,9 +26130,18 @@ async function chooseProjectDir(dir) {
26012
26130
  }
26013
26131
  return selected;
26014
26132
  }
26133
+ async function chooseArtifact(artifact, yes) {
26134
+ if (artifact?.trim()) return artifact;
26135
+ if (yes || !isInteractive()) {
26136
+ throw new CliError("init \u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "INIT_ARTIFACT_REQUIRED");
26137
+ }
26138
+ const selected = (await askInput2("\u672C\u5730\u4EA7\u7269\u6587\u4EF6\u6216\u6784\u5EFA\u76EE\u5F55")).trim();
26139
+ if (!selected) throw new CliError("init \u5FC5\u987B\u901A\u8FC7 --artifact \u5173\u8054\u672C\u5730\u4EA7\u7269", "INIT_ARTIFACT_REQUIRED");
26140
+ return selected;
26141
+ }
26015
26142
  function createInitCommand() {
26016
26143
  const init2 = addSharedOptions(new Command11("init"));
26017
- init2.description("\u53EA\u5EFA\u672C\u5730\u5355\u8D44\u6E90\u5DE5\u7A0B").argument("[dir]", "\u76EE\u6807\u76EE\u5F55").option("--type <leaf-code>", "\u666E\u901A\u8D44\u6E90\u6700\u7EC8\u53F6\u5B50\u7C7B\u578B").option("--resource-type <leaf-code>", "\u5DF2\u5F03\u7528\uFF1A\u8BF7\u6539\u7528 --type").action(async function(dir, options) {
26144
+ init2.description("\u5EFA\u7ACB\u9996\u4EFD\u672C\u5730\u8D44\u6E90\u72B6\u6001").argument("[dir]", "\u76EE\u6807\u76EE\u5F55").option("--type <leaf-code>", "\u666E\u901A\u8D44\u6E90\u6700\u7EC8\u53F6\u5B50\u7C7B\u578B").option("--artifact <path>", "\u8981\u5173\u8054\u7684\u672C\u5730\u4EA7\u7269\u6587\u4EF6\u6216\u6784\u5EFA\u76EE\u5F55").option("--resource-type <leaf-code>", "\u5DF2\u5F03\u7528\uFF1A\u8BF7\u6539\u7528 --type").action(async function(dir, options) {
26018
26145
  if (options.type && options.resourceType) throw new CliError("--type \u4E0E --resource-type \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528", "INIT_TYPE_CONFLICT");
26019
26146
  if (options.resourceType) console.warn("\u8B66\u544A\uFF1A--resource-type \u5DF2\u5F03\u7528\uFF0C\u8BF7\u6539\u7528 --type");
26020
26147
  const shared = sharedOptions(this);
@@ -26023,7 +26150,14 @@ function createInitCommand() {
26023
26150
  requireAuth({ cwd });
26024
26151
  const selected = options.type ?? options.resourceType;
26025
26152
  const type = selected ? await getTypeInfo(selected) : await chooseLeafType();
26026
- const created = await initProject({ cwd, dir: targetDir, typeCode: type.code, typeValidator: async () => type, yes: shared.yes });
26153
+ const created = await initProject({
26154
+ cwd,
26155
+ dir: targetDir,
26156
+ typeCode: type.code,
26157
+ typeValidator: async () => type,
26158
+ artifact: await chooseArtifact(options.artifact, shared.yes),
26159
+ yes: shared.yes
26160
+ });
26027
26161
  console.log(`\u5DF2\u521B\u5EFA\u672C\u5730\u8EAB\u4EFD ${created.n}.json`);
26028
26162
  });
26029
26163
  for (const shortcut of ["theme", "widget"]) {
@@ -26705,90 +26839,16 @@ async function submitVersion(input2) {
26705
26839
 
26706
26840
  // src/domain/version/file.ts
26707
26841
  import { createHash as createHash3 } from "crypto";
26708
- import { existsSync as existsSync11, readFileSync as readFileSync9, statSync as statSync2, unlinkSync as unlinkSync6 } from "fs";
26709
- import path13 from "path";
26710
-
26711
- // src/domain/version/zip.ts
26712
- import { createWriteStream, existsSync as existsSync10, readdirSync as readdirSync4, statSync, unlinkSync as unlinkSync5 } from "fs";
26713
- import { tmpdir } from "os";
26714
- import path12 from "path";
26715
- import { finished } from "stream/promises";
26716
- import archiver from "archiver";
26717
- function isThemeOrWidget2(typeCode) {
26718
- return typeCode === "RT001" || typeCode === "RT002";
26719
- }
26720
- function assertArtifactPath(typeCode, filePath) {
26721
- const stats = existsSync10(filePath) ? statSync(filePath) : void 0;
26722
- const themeOrWidget = isThemeOrWidget2(typeCode);
26723
- if (stats?.isDirectory() && !themeOrWidget) {
26724
- throw new CliError("\u4E0D\u652F\u6301\u6587\u4EF6\u5939\uFF0C\u8BF7\u6307\u5B9A\u4E00\u4E2A\u6587\u4EF6\u3002", "FILE_DIRECTORY_UNSUPPORTED");
26725
- }
26726
- if (themeOrWidget && stats?.isFile() && filePath.toLowerCase().endsWith(".zip")) {
26727
- throw new CliError("\u4E3B\u9898/\u63D2\u4EF6\u8BF7\u6307\u5B9A\u6784\u5EFA\u4EA7\u7269\u76EE\u5F55\uFF0C\u4E0D\u8981\u81EA\u5DF1\u6253 zip\u3002", "FILE_THEME_ZIP");
26728
- }
26729
- if (themeOrWidget && stats?.isFile()) {
26730
- throw new CliError("\u4E3B\u9898/\u63D2\u4EF6\u8BF7\u6307\u5B9A\u6784\u5EFA\u4EA7\u7269\u76EE\u5F55\uFF0C\u4E0D\u8981\u81EA\u5DF1\u6253 zip\u3002", "FILE_THEME_ZIP");
26731
- }
26732
- }
26733
- async function zipDirectoryContents(dir) {
26734
- if (!existsSync10(dir) || !statSync(dir).isDirectory()) {
26735
- throw new CliError(`\u6CA1\u6709\u6784\u5EFA\u4EA7\u7269 ${dir}\uFF0C\u8BF7\u5148\u6784\u5EFA`, "ZIP_MISSING");
26736
- }
26737
- if (existsSync10(path12.join(dir, ".freelog"))) {
26738
- 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");
26739
- }
26740
- const entries = readdirSync4(dir);
26741
- if (entries.length === 0) {
26742
- throw new CliError("\u6784\u5EFA\u4EA7\u7269\u662F\u7A7A\u7684\uFF0C\u8BF7\u5148\u6784\u5EFA", "ZIP_EMPTY");
26743
- }
26744
- const outPath = path12.join(
26745
- tmpdir(),
26746
- `freelog-zip-${process.pid}-${Date.now()}.zip`
26747
- );
26748
- const output2 = createWriteStream(outPath);
26749
- const archive = archiver("zip", { zlib: { level: 9 } });
26750
- try {
26751
- archive.on("error", (error2) => output2.destroy(error2));
26752
- archive.pipe(output2);
26753
- for (const entry2 of entries) {
26754
- const full = path12.join(dir, entry2);
26755
- const stats = statSync(full);
26756
- if (stats.isDirectory()) {
26757
- archive.directory(full, entry2);
26758
- } else {
26759
- archive.file(full, { name: entry2 });
26760
- }
26761
- }
26762
- await archive.finalize();
26763
- await finished(output2);
26764
- return outPath;
26765
- } catch (error2) {
26766
- if (existsSync10(outPath)) {
26767
- try {
26768
- unlinkSync5(outPath);
26769
- } catch {
26770
- }
26771
- }
26772
- throw error2;
26773
- }
26774
- }
26775
- async function prepareUploadPath(typeCode, filePath) {
26776
- assertArtifactPath(typeCode, filePath);
26777
- if (isThemeOrWidget2(typeCode) && existsSync10(filePath) && statSync(filePath).isDirectory()) {
26778
- return zipDirectoryContents(filePath);
26779
- }
26780
- return filePath;
26781
- }
26782
-
26783
- // src/domain/version/file.ts
26842
+ import { existsSync as existsSync12, readFileSync as readFileSync9, statSync as statSync2, unlinkSync as unlinkSync6 } from "fs";
26843
+ import path15 from "path";
26784
26844
  var ANALYZE_TIMEOUT_MS = 12e4;
26785
26845
  var ANALYZE_POLL_INTERVAL_MS = 200;
26786
26846
  function resolveExistingPath(cwd, raw) {
26787
- if (existsSync11(raw)) {
26788
- return path13.resolve(raw);
26847
+ if (existsSync12(raw)) {
26848
+ return path15.resolve(raw);
26789
26849
  }
26790
- const joined = path13.resolve(cwd, raw);
26791
- if (existsSync11(joined)) {
26850
+ const joined = path15.resolve(cwd, raw);
26851
+ if (existsSync12(joined)) {
26792
26852
  return joined;
26793
26853
  }
26794
26854
  return void 0;
@@ -26847,7 +26907,7 @@ async function uploadIfNew(uploadPath, sha1, typeCode, apis) {
26847
26907
  await upload({ file: readFileSync9(uploadPath), resourceType: typeCode });
26848
26908
  }
26849
26909
  function removeTempZip(uploadPath, localPath) {
26850
- if (uploadPath === localPath || !existsSync11(uploadPath)) {
26910
+ if (uploadPath === localPath || !existsSync12(uploadPath)) {
26851
26911
  return;
26852
26912
  }
26853
26913
  try {
@@ -26896,12 +26956,12 @@ async function uploadAndAnalyze(input2) {
26896
26956
  async function uploadAndAnalyzeLocked(input2) {
26897
26957
  assertPlatformAllowed();
26898
26958
  const file = input2.file !== void 0 ? normalizeProjectPath(input2.cwd, input2.file) : void 0;
26899
- const recordedFile = input2.identity.filePath ? normalizeProjectPath(input2.cwd, input2.identity.filePath) : void 0;
26959
+ const recordedFile = normalizeProjectPath(input2.cwd, input2.identity.filePath);
26900
26960
  const identity = recordedFile === input2.identity.filePath ? input2.identity : { ...input2.identity, filePath: recordedFile };
26901
26961
  const localPath = confirmLocalPath(identity, file, input2.yes, input2.cwd);
26902
26962
  const uploadPath = await prepareUploadPath(identity.typeCode, localPath);
26903
26963
  try {
26904
- const uploaded = { fileSha1: sha1OfFile(uploadPath), filename: path13.basename(uploadPath) };
26964
+ const uploaded = { fileSha1: sha1OfFile(uploadPath), filename: path15.basename(uploadPath) };
26905
26965
  await uploadIfNew(uploadPath, uploaded.fileSha1, identity.typeCode, input2.apis ?? {});
26906
26966
  const analysis = await waitAnalyze(
26907
26967
  uploaded.fileSha1,
@@ -26954,12 +27014,26 @@ async function runCreateVersionLocked(input2) {
26954
27014
  })
26955
27015
  );
26956
27016
  const latestVersion = info2.latestVersion ? String(info2.latestVersion) : void 0;
27017
+ const existingDraft = readDraft(input2.cwd, identity.n);
27018
+ evaluateGates({ latestVersion, draft: input2.reset ? void 0 : existingDraft }, "create-version");
27019
+ const artifact = resolveArtifactPath(input2.cwd, identity, input2.file, input2.artifact);
27020
+ if (!input2.prepare && !input2.yes) {
27021
+ throw new CliError("\u63D0\u4EA4\u8BF7\u52A0 --yes", "CREATE_VERSION_NEED_YES");
27022
+ }
26957
27023
  if (input2.reset) {
27024
+ confirmLocalPath(identity, artifact, input2.yes, input2.cwd);
27025
+ }
27026
+ let draft = existingDraft;
27027
+ if (input2.reset && existingDraft) {
27028
+ if (!input2.confirmReset) {
27029
+ throw new CliError("\u8BF7\u5148\u786E\u8BA4\u4E22\u5F03\u5DE5\u4F5C\u7A3F", "RESET_CONFIRMATION_REQUIRED");
27030
+ }
27031
+ if (!await input2.confirmReset(draftSummary(existingDraft))) {
27032
+ return "\u5DF2\u53D6\u6D88";
27033
+ }
26958
27034
  deleteDraft(input2.cwd, identity.n);
27035
+ draft = void 0;
26959
27036
  }
26960
- const draft = readDraft(input2.cwd, identity.n);
26961
- evaluateGates({ latestVersion, draft }, "create-version");
26962
- const artifact = resolveArtifactPath(input2.cwd, identity, input2.file, input2.artifact);
26963
27037
  if (!draft || input2.prepare || artifact) {
26964
27038
  writeDraft(input2.cwd, identity.n, draft ?? emptyDraft());
26965
27039
  }
@@ -26973,9 +27047,6 @@ async function runCreateVersionLocked(input2) {
26973
27047
  });
26974
27048
  return "\u5DF2\u5907\u7A3F\uFF0C\u672A\u63D0\u4EA4";
26975
27049
  }
26976
- if (!input2.yes) {
26977
- throw new CliError("\u63D0\u4EA4\u8BF7\u52A0 --yes", "CREATE_VERSION_NEED_YES");
26978
- }
26979
27050
  await uploadAndAnalyze({
26980
27051
  cwd: input2.cwd,
26981
27052
  identity,
@@ -27004,6 +27075,11 @@ async function runCreateVersionLocked(input2) {
27004
27075
  return "1.0.0";
27005
27076
  }
27006
27077
 
27078
+ // src/commands/version/draftConfirmation.ts
27079
+ async function confirmDraftDestruction(input2) {
27080
+ return confirmDestructive(input2.summary, input2.action, input2.yes, isInteractive(), confirmQuestion);
27081
+ }
27082
+
27007
27083
  // src/commands/version/create-version.ts
27008
27084
  function createCreateVersionCommand() {
27009
27085
  const command = addSharedOptions(new Command20("create-version"));
@@ -27024,12 +27100,14 @@ function createCreateVersionCommand() {
27024
27100
  "\u672C\u6B21\u4E0A\u4F20\u5E76\u8BB0\u5F55\u7684\u672C\u5730\u6587\u4EF6\u6216\u76EE\u5F55"
27025
27101
  ).action(async function(options) {
27026
27102
  const shared = readSharedOptions(this);
27103
+ const cwd = resolveCwd(shared.cwd);
27027
27104
  const result = await runCreateVersion({
27028
- cwd: resolveCwd(shared.cwd),
27105
+ cwd,
27029
27106
  file: shared.file,
27030
27107
  artifact: options.artifact,
27031
27108
  prepare: options.prepare,
27032
27109
  reset: options.reset,
27110
+ confirmReset: options.reset ? (summary) => confirmDraftDestruction({ summary, yes: shared.yes, action: "\u4E22\u5F03\u5DE5\u4F5C\u7A3F\u5E76\u91CD\u7F6E\u9996\u7248" }) : void 0,
27033
27111
  yes: shared.yes
27034
27112
  });
27035
27113
  console.log(result);
@@ -27442,15 +27520,23 @@ function registerDraftDescription(draft) {
27442
27520
  import { Command as Command23 } from "commander";
27443
27521
 
27444
27522
  // src/domain/version/draftDiscard.ts
27445
- function draftDiscard(cwd, file) {
27446
- return withProjectLock(cwd, () => draftDiscardLocked(cwd, file), "version-draft-discard");
27523
+ async function draftDiscard(cwd, file, confirmed = false, confirm4) {
27524
+ return withProjectLock(cwd, () => draftDiscardLocked(cwd, file, confirmed, confirm4), "version-draft-discard");
27447
27525
  }
27448
- function draftDiscardLocked(cwd, file) {
27526
+ async function draftDiscardLocked(cwd, file, confirmed, confirm4) {
27449
27527
  const identity = resolveIdentity(cwd, file);
27450
27528
  const draft = readDraft(cwd, identity.n);
27451
27529
  if (!draft) {
27452
27530
  return "\u6CA1\u6709\u5DE5\u4F5C\u7A3F";
27453
27531
  }
27532
+ if (!confirmed) {
27533
+ if (!confirm4) {
27534
+ throw new CliError("\u8BF7\u5148\u786E\u8BA4\u4E22\u5F03\u5DE5\u4F5C\u7A3F", "DRAFT_DISCARD_CONFIRMATION_REQUIRED");
27535
+ }
27536
+ if (!await confirm4(draftSummary(draft))) {
27537
+ return "\u5DF2\u53D6\u6D88";
27538
+ }
27539
+ }
27454
27540
  deleteDraft(cwd, identity.n);
27455
27541
  return "\u5DF2\u4E22\u6389\u5DE5\u4F5C\u7A3F";
27456
27542
  }
@@ -27477,17 +27563,6 @@ async function draftPullLocked(input2) {
27477
27563
  if (!want) {
27478
27564
  throw new CliError("\u8FD8\u6CA1\u6709\u53D1\u884C\u7248\u672C\uFF0C\u8BF7\u5148 create-version", "GATE_USE_CREATE");
27479
27565
  }
27480
- if (existing) {
27481
- const summary = draftSummary(existing);
27482
- if (!input2.yes && existing.fromVersion === want) {
27483
- return `${summary}
27484
- \u7A3F\u5DF2\u6765\u81EA ${want}\uFF0C\u672A\u8986\u76D6`;
27485
- }
27486
- if (!input2.yes) {
27487
- return `${summary}
27488
- \u672A\u8986\u76D6`;
27489
- }
27490
- }
27491
27566
  const versionInfoApi = input2.apis?.resourceVersionInfo1 ?? ((params) => service_API_default.Resource.resourceVersionInfo1(params));
27492
27567
  const versionInfo = unwrapData2(
27493
27568
  await versionInfoApi({
@@ -27499,6 +27574,17 @@ async function draftPullLocked(input2) {
27499
27574
  if (!pulledSha) {
27500
27575
  throw new CliError("\u6CA1\u6709\u8FD9\u4E2A\u7248\u672C", "DRAFT_VERSION_MISSING");
27501
27576
  }
27577
+ if (existing && !input2.yes) {
27578
+ const summary = draftSummary(existing);
27579
+ if (!input2.confirmOverwrite) {
27580
+ return existing.fromVersion === want ? `${summary}
27581
+ \u7A3F\u5DF2\u6765\u81EA ${want}\uFF0C\u672A\u8986\u76D6` : `${summary}
27582
+ \u672A\u8986\u76D6`;
27583
+ }
27584
+ if (!await input2.confirmOverwrite(summary, want)) {
27585
+ return "\u5DF2\u53D6\u6D88";
27586
+ }
27587
+ }
27502
27588
  writeDraft(input2.cwd, identity.n, {
27503
27589
  fromVersion: want,
27504
27590
  fileSha1: pulledSha,
@@ -27533,20 +27619,36 @@ function createVersionDraftCommand() {
27533
27619
  "\u5DF2\u53D1\u53F7"
27534
27620
  ).action(async function(options) {
27535
27621
  const shared = readSharedOptions(this);
27622
+ const cwd = resolveCwd(shared.cwd);
27536
27623
  const text = await draftPull({
27537
- cwd: resolveCwd(shared.cwd),
27624
+ cwd,
27538
27625
  file: shared.file,
27539
27626
  version: options.version,
27540
- yes: shared.yes
27627
+ yes: shared.yes,
27628
+ confirmOverwrite: (summary, version) => confirmDraftDestruction({
27629
+ summary,
27630
+ yes: shared.yes,
27631
+ action: `\u7528\u7EBF\u4E0A\u7248\u672C ${version} \u8986\u76D6\u672C\u5730\u5DE5\u4F5C\u7A3F`
27632
+ })
27541
27633
  });
27542
27634
  console.log(text);
27543
27635
  });
27544
27636
  addSharedOptions(draft.command("discard")).description(
27545
27637
  // i18n: cli.command.version.draft.discard.description
27546
27638
  "\u4E22\u6389\u5DE5\u4F5C\u7A3F"
27547
- ).action(function() {
27639
+ ).action(async function() {
27548
27640
  const shared = readSharedOptions(this);
27549
- console.log(draftDiscard(resolveCwd(shared.cwd), shared.file));
27641
+ const cwd = resolveCwd(shared.cwd);
27642
+ console.log(await draftDiscard(
27643
+ cwd,
27644
+ shared.file,
27645
+ shared.yes,
27646
+ (summary) => confirmDraftDestruction({
27647
+ summary,
27648
+ yes: shared.yes,
27649
+ action: "\u4E22\u5F03\u5DE5\u4F5C\u7A3F"
27650
+ })
27651
+ ));
27550
27652
  });
27551
27653
  return draft;
27552
27654
  }
@@ -27791,6 +27893,7 @@ function createVersionOptionCommand() {
27791
27893
  import { Command as Command25 } from "commander";
27792
27894
 
27793
27895
  // src/domain/version/setPath.ts
27896
+ import path16 from "path";
27794
27897
  function setIdentityFilePath(cwd, input2) {
27795
27898
  return withProjectLock(cwd, () => {
27796
27899
  const artifact = input2.artifact !== void 0 ? normalizeProjectPath(cwd, input2.artifact) : void 0;
@@ -27798,6 +27901,7 @@ function setIdentityFilePath(cwd, input2) {
27798
27901
  throw new CliError("\u8BF7\u63D0\u4F9B --artifact", "SET_ARTIFACT_REQUIRED");
27799
27902
  }
27800
27903
  const identity = resolveIdentity(cwd, input2.file);
27904
+ assertArtifactAnchor(identity.typeCode, path16.resolve(cwd, artifact));
27801
27905
  const updated = prepareIdentityUpdate(cwd, identity.n, { filePath: artifact });
27802
27906
  commitLocalTransaction(cwd, [
27803
27907
  { path: identityFilePath(cwd, updated.n), content: serializeIdentity(updated) }
@@ -27932,13 +28036,40 @@ async function runUpdateVersionLocked(input2) {
27932
28036
  })
27933
28037
  );
27934
28038
  const latestVersion = info2.latestVersion ? String(info2.latestVersion) : void 0;
28039
+ const existingDraft = readDraft(input2.cwd, identity.n);
28040
+ const source = input2.reuseVersion ?? latestVersion;
28041
+ evaluateGates({ latestVersion, draft: input2.reset ? void 0 : existingDraft, reuseVersion: input2.reuseVersion }, "update-version");
28042
+ const artifact = resolveArtifactPath(input2.cwd, identity, input2.file, input2.artifact);
28043
+ if (!input2.reset && input2.yes && existingDraft?.fromVersion && source && existingDraft.fromVersion !== source) {
28044
+ throw new CliError(
28045
+ `\u7A3F\u6765\u81EA ${existingDraft.fromVersion}\u3001\u5E95\u662F ${source}\u3002\u8BF7 version draft pull \u6216 --reuse-version`,
28046
+ "UPDATE_VERSION_MISMATCH"
28047
+ );
28048
+ }
28049
+ const next = resolveNextVersion(latestVersion, input2.version, input2.bump);
28050
+ if (!semver2.gt(next, latestVersion)) {
28051
+ throw new CliError(
28052
+ `\u7EBF\u4E0A\u5DF2\u7ECF\u662F ${latestVersion}\uFF0C\u4E0D\u80FD\u53D1 ${next}`,
28053
+ "UPDATE_VERSION_NOT_GREATER"
28054
+ );
28055
+ }
28056
+ if (!input2.yes) {
28057
+ throw new CliError("\u63D0\u4EA4\u8BF7\u52A0 --yes", "UPDATE_VERSION_NEED_YES");
28058
+ }
27935
28059
  if (input2.reset) {
28060
+ confirmLocalPath(identity, artifact, input2.yes, input2.cwd);
28061
+ }
28062
+ let draft = existingDraft;
28063
+ if (input2.reset && existingDraft) {
28064
+ if (!input2.confirmReset) {
28065
+ throw new CliError("\u8BF7\u5148\u786E\u8BA4\u4E22\u5F03\u5DE5\u4F5C\u7A3F", "RESET_CONFIRMATION_REQUIRED");
28066
+ }
28067
+ if (!await input2.confirmReset(draftSummary(existingDraft))) {
28068
+ return "\u5DF2\u53D6\u6D88";
28069
+ }
27936
28070
  deleteDraft(input2.cwd, identity.n);
28071
+ draft = void 0;
27937
28072
  }
27938
- let draft = readDraft(input2.cwd, identity.n);
27939
- const source = input2.reuseVersion ?? latestVersion;
27940
- evaluateGates({ latestVersion, draft, reuseVersion: input2.reuseVersion }, "update-version");
27941
- const artifact = resolveArtifactPath(input2.cwd, identity, input2.file, input2.artifact);
27942
28073
  if (input2.yes && draft && !draft.fromVersion && input2.reuseVersion === void 0) {
27943
28074
  throw new CliError("\u8BF7\u5148 version draft pull --yes", "UPDATE_VERSION_FIRST_DRAFT");
27944
28075
  }
@@ -27958,16 +28089,6 @@ async function runUpdateVersionLocked(input2) {
27958
28089
  "UPDATE_VERSION_MISMATCH"
27959
28090
  );
27960
28091
  }
27961
- const next = resolveNextVersion(latestVersion, input2.version, input2.bump);
27962
- if (!semver2.gt(next, latestVersion)) {
27963
- throw new CliError(
27964
- `\u7EBF\u4E0A\u5DF2\u7ECF\u662F ${latestVersion}\uFF0C\u4E0D\u80FD\u53D1 ${next}`,
27965
- "UPDATE_VERSION_NOT_GREATER"
27966
- );
27967
- }
27968
- if (!input2.yes) {
27969
- throw new CliError("\u63D0\u4EA4\u8BF7\u52A0 --yes", "UPDATE_VERSION_NEED_YES");
27970
- }
27971
28092
  await uploadAndAnalyze({
27972
28093
  cwd: input2.cwd,
27973
28094
  identity,
@@ -28044,14 +28165,16 @@ function createUpdateVersionCommand() {
28044
28165
  "\u672C\u6B21\u4E0A\u4F20\u5E76\u8BB0\u5F55\u7684\u672C\u5730\u6587\u4EF6\u6216\u76EE\u5F55"
28045
28166
  ).action(async function(options) {
28046
28167
  const shared = readSharedOptions(this);
28168
+ const cwd = resolveCwd(shared.cwd);
28047
28169
  const result = await runUpdateVersion({
28048
- cwd: resolveCwd(shared.cwd),
28170
+ cwd,
28049
28171
  file: shared.file,
28050
28172
  artifact: options.artifact,
28051
28173
  version: options.version,
28052
28174
  bump: options.bump,
28053
28175
  reuseVersion: options.reuseVersion,
28054
28176
  reset: options.reset,
28177
+ confirmReset: options.reset ? (summary) => confirmDraftDestruction({ summary, yes: shared.yes, action: "\u4E22\u5F03\u5DE5\u4F5C\u7A3F\u5E76\u91CD\u7F6E\u66F4\u65B0\u7248\u672C" }) : void 0,
28055
28178
  yes: shared.yes
28056
28179
  });
28057
28180
  console.log(result);
@@ -28112,25 +28235,25 @@ function createSubCommands() {
28112
28235
  }
28113
28236
 
28114
28237
  // src/core/usageDocs.ts
28115
- import { existsSync as existsSync12 } from "fs";
28116
- import path14 from "path";
28238
+ import { existsSync as existsSync13 } from "fs";
28239
+ import path17 from "path";
28117
28240
  import { fileURLToPath } from "url";
28118
28241
  function usageDocsPath() {
28119
- const moduleDir = path14.dirname(fileURLToPath(import.meta.url));
28120
- const bundledPath = path14.resolve(moduleDir, "../docs/README.md");
28121
- if (existsSync12(bundledPath)) {
28242
+ const moduleDir = path17.dirname(fileURLToPath(import.meta.url));
28243
+ const bundledPath = path17.resolve(moduleDir, "../docs/README.md");
28244
+ if (existsSync13(bundledPath)) {
28122
28245
  return bundledPath;
28123
28246
  }
28124
- return path14.resolve(moduleDir, "../../../../docs/\u4E00\u671F/\u4EA7\u54C1\u65B9\u6848/\u4F7F\u7528/README.md");
28247
+ return path17.resolve(moduleDir, "../../../../docs/\u4E00\u671F/\u4EA7\u54C1\u65B9\u6848/\u4F7F\u7528/README.md");
28125
28248
  }
28126
28249
 
28127
28250
  // src/core/packageVersion.ts
28128
28251
  import { readFileSync as readFileSync10 } from "fs";
28129
- import path15 from "path";
28252
+ import path18 from "path";
28130
28253
  import { fileURLToPath as fileURLToPath2 } from "url";
28131
28254
  function packageVersion() {
28132
- const moduleDir = path15.dirname(fileURLToPath2(import.meta.url));
28133
- const packageJson = path15.resolve(moduleDir, "../..", "package.json");
28255
+ const moduleDir = path18.dirname(fileURLToPath2(import.meta.url));
28256
+ const packageJson = path18.resolve(moduleDir, "../..", "package.json");
28134
28257
  const value = JSON.parse(readFileSync10(packageJson, "utf8"));
28135
28258
  return typeof value.version === "string" ? value.version : "unknown";
28136
28259
  }
@@ -28202,7 +28325,20 @@ function resourceChoiceLabel(cwd, identity) {
28202
28325
  ].join(" ");
28203
28326
  }
28204
28327
  function resourceSelectorExamples(identities) {
28205
- return identities.map((identity) => `file:${identity.n}.json\uFF08${identity.title ?? "\u672A\u540C\u6B65\u6807\u9898"}\uFF1B${identity.name ?? "\u672A\u7ED1\u5B9A"}\uFF1B${identity.resourceId ?? "\u672A\u7ED1\u5B9A"}\uFF09`).join("\u3001");
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
+ return identities.map((identity) => {
28333
+ const selectors = [
28334
+ ...identity.resourceId ? [`id:${identity.resourceId}`] : [],
28335
+ ...identity.name ? [`name:${identity.name}`] : [],
28336
+ ...identity.title && titleCounts.get(identity.title) === 1 ? [`title:${identity.title}`] : [],
28337
+ `artifact:${identity.filePath}`,
28338
+ `file:${identity.n}.json`
28339
+ ];
28340
+ return selectors.join(" | ");
28341
+ }).join("\uFF1B");
28206
28342
  }
28207
28343
  function isResourceFreeCommand(command) {
28208
28344
  let current = command;