@hot-updater/cli-tools 0.29.5 → 0.29.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -77,6 +77,8 @@ let node_v8 = require("node:v8");
77
77
  let node_stream_promises = require("node:stream/promises");
78
78
  let node_buffer = require("node:buffer");
79
79
  let node_module = require("node:module");
80
+ let typescript = require("typescript");
81
+ typescript = __toESM(typescript);
80
82
  let unconfig = require("unconfig");
81
83
  let oxc_transform = require("oxc-transform");
82
84
  //#region ../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js
@@ -5453,12 +5455,12 @@ var require_sync$5 = /* @__PURE__ */ __commonJSMin(((exports) => {
5453
5455
  var require_fs$2 = /* @__PURE__ */ __commonJSMin(((exports) => {
5454
5456
  Object.defineProperty(exports, "__esModule", { value: true });
5455
5457
  exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0;
5456
- const fs$27 = require("fs");
5458
+ const fs$28 = require("fs");
5457
5459
  exports.FILE_SYSTEM_ADAPTER = {
5458
- lstat: fs$27.lstat,
5459
- stat: fs$27.stat,
5460
- lstatSync: fs$27.lstatSync,
5461
- statSync: fs$27.statSync
5460
+ lstat: fs$28.lstat,
5461
+ stat: fs$28.stat,
5462
+ lstatSync: fs$28.lstatSync,
5463
+ statSync: fs$28.statSync
5462
5464
  };
5463
5465
  function createFileSystemAdapter(fsMethods) {
5464
5466
  if (fsMethods === void 0) return exports.FILE_SYSTEM_ADAPTER;
@@ -5776,14 +5778,14 @@ var require_sync$4 = /* @__PURE__ */ __commonJSMin(((exports) => {
5776
5778
  var require_fs = /* @__PURE__ */ __commonJSMin(((exports) => {
5777
5779
  Object.defineProperty(exports, "__esModule", { value: true });
5778
5780
  exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0;
5779
- const fs$26 = require("fs");
5781
+ const fs$27 = require("fs");
5780
5782
  exports.FILE_SYSTEM_ADAPTER = {
5781
- lstat: fs$26.lstat,
5782
- stat: fs$26.stat,
5783
- lstatSync: fs$26.lstatSync,
5784
- statSync: fs$26.statSync,
5785
- readdir: fs$26.readdir,
5786
- readdirSync: fs$26.readdirSync
5783
+ lstat: fs$27.lstat,
5784
+ stat: fs$27.stat,
5785
+ lstatSync: fs$27.lstatSync,
5786
+ statSync: fs$27.statSync,
5787
+ readdir: fs$27.readdir,
5788
+ readdirSync: fs$27.readdirSync
5787
5789
  };
5788
5790
  function createFileSystemAdapter(fsMethods) {
5789
5791
  if (fsMethods === void 0) return exports.FILE_SYSTEM_ADAPTER;
@@ -6953,7 +6955,7 @@ var require_sync = /* @__PURE__ */ __commonJSMin(((exports) => {
6953
6955
  var require_settings = /* @__PURE__ */ __commonJSMin(((exports) => {
6954
6956
  Object.defineProperty(exports, "__esModule", { value: true });
6955
6957
  exports.DEFAULT_FILE_SYSTEM_ADAPTER = void 0;
6956
- const fs$25 = require("fs");
6958
+ const fs$26 = require("fs");
6957
6959
  const os$1 = require("os");
6958
6960
  /**
6959
6961
  * The `os.cpus` method can return zero. We expect the number of cores to be greater than zero.
@@ -6961,12 +6963,12 @@ var require_settings = /* @__PURE__ */ __commonJSMin(((exports) => {
6961
6963
  */
6962
6964
  const CPU_COUNT = Math.max(os$1.cpus().length, 1);
6963
6965
  exports.DEFAULT_FILE_SYSTEM_ADAPTER = {
6964
- lstat: fs$25.lstat,
6965
- lstatSync: fs$25.lstatSync,
6966
- stat: fs$25.stat,
6967
- statSync: fs$25.statSync,
6968
- readdir: fs$25.readdir,
6969
- readdirSync: fs$25.readdirSync
6966
+ lstat: fs$26.lstat,
6967
+ lstatSync: fs$26.lstatSync,
6968
+ stat: fs$26.stat,
6969
+ statSync: fs$26.statSync,
6970
+ readdir: fs$26.readdir,
6971
+ readdirSync: fs$26.readdirSync
6970
6972
  };
6971
6973
  var Settings = class {
6972
6974
  constructor(_options = {}) {
@@ -13777,7 +13779,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
13777
13779
  }),
13778
13780
  (function(module$50, exports$52, __webpack_require__) {
13779
13781
  module$50.exports = glob;
13780
- var fs$28 = __webpack_require__(3);
13782
+ var fs$29 = __webpack_require__(3);
13781
13783
  var rp = __webpack_require__(114);
13782
13784
  var minimatch = __webpack_require__(60);
13783
13785
  minimatch.Minimatch;
@@ -14054,7 +14056,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
14054
14056
  var lstatkey = "lstat\0" + abs;
14055
14057
  var self = this;
14056
14058
  var lstatcb = inflight(lstatkey, lstatcb_);
14057
- if (lstatcb) fs$28.lstat(abs, lstatcb);
14059
+ if (lstatcb) fs$29.lstat(abs, lstatcb);
14058
14060
  function lstatcb_(er, lstat) {
14059
14061
  if (er && er.code === "ENOENT") return cb();
14060
14062
  var isSym = lstat && lstat.isSymbolicLink();
@@ -14075,7 +14077,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
14075
14077
  if (!c || c === "FILE") return cb();
14076
14078
  if (Array.isArray(c)) return cb(null, c);
14077
14079
  }
14078
- fs$28.readdir(abs, readdirCb(this, abs, cb));
14080
+ fs$29.readdir(abs, readdirCb(this, abs, cb));
14079
14081
  };
14080
14082
  function readdirCb(self, abs, cb) {
14081
14083
  return function(er, entries) {
@@ -14190,9 +14192,9 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
14190
14192
  }
14191
14193
  var self = this;
14192
14194
  var statcb = inflight("stat\0" + abs, lstatcb_);
14193
- if (statcb) fs$28.lstat(abs, statcb);
14195
+ if (statcb) fs$29.lstat(abs, statcb);
14194
14196
  function lstatcb_(er, lstat) {
14195
- if (lstat && lstat.isSymbolicLink()) return fs$28.stat(abs, function(er, stat) {
14197
+ if (lstat && lstat.isSymbolicLink()) return fs$29.stat(abs, function(er, stat) {
14196
14198
  if (er) self._stat2(f, abs, null, lstat, cb);
14197
14199
  else self._stat2(f, abs, er, stat, cb);
14198
14200
  });
@@ -15079,9 +15081,9 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
15079
15081
  realpath.realpathSync = realpathSync;
15080
15082
  realpath.monkeypatch = monkeypatch;
15081
15083
  realpath.unmonkeypatch = unmonkeypatch;
15082
- var fs$29 = __webpack_require__(3);
15083
- var origRealpath = fs$29.realpath;
15084
- var origRealpathSync = fs$29.realpathSync;
15084
+ var fs$30 = __webpack_require__(3);
15085
+ var origRealpath = fs$30.realpath;
15086
+ var origRealpathSync = fs$30.realpathSync;
15085
15087
  var version = process.version;
15086
15088
  var ok = /^v[0-5]\./.test(version);
15087
15089
  var old = __webpack_require__(217);
@@ -15109,12 +15111,12 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
15109
15111
  }
15110
15112
  }
15111
15113
  function monkeypatch() {
15112
- fs$29.realpath = realpath;
15113
- fs$29.realpathSync = realpathSync;
15114
+ fs$30.realpath = realpath;
15115
+ fs$30.realpathSync = realpathSync;
15114
15116
  }
15115
15117
  function unmonkeypatch() {
15116
- fs$29.realpath = origRealpath;
15117
- fs$29.realpathSync = origRealpathSync;
15118
+ fs$30.realpath = origRealpath;
15119
+ fs$30.realpathSync = origRealpathSync;
15118
15120
  }
15119
15121
  }),
15120
15122
  (function(module$70, exports$72, __webpack_require__) {
@@ -15276,7 +15278,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
15276
15278
  }),
15277
15279
  (function(module$71, exports$73, __webpack_require__) {
15278
15280
  var path$58 = __webpack_require__(0);
15279
- var fs$30 = __webpack_require__(3);
15281
+ var fs$31 = __webpack_require__(3);
15280
15282
  var _0777 = parseInt("0777", 8);
15281
15283
  module$71.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
15282
15284
  function mkdirP(p, opts, f, made) {
@@ -15285,7 +15287,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
15285
15287
  opts = {};
15286
15288
  } else if (!opts || typeof opts !== "object") opts = { mode: opts };
15287
15289
  var mode = opts.mode;
15288
- var xfs = opts.fs || fs$30;
15290
+ var xfs = opts.fs || fs$31;
15289
15291
  if (mode === void 0) mode = _0777 & ~process.umask();
15290
15292
  if (!made) made = null;
15291
15293
  var cb = f || function() {};
@@ -15314,7 +15316,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
15314
15316
  mkdirP.sync = function sync(p, opts, made) {
15315
15317
  if (!opts || typeof opts !== "object") opts = { mode: opts };
15316
15318
  var mode = opts.mode;
15317
- var xfs = opts.fs || fs$30;
15319
+ var xfs = opts.fs || fs$31;
15318
15320
  if (mode === void 0) mode = _0777 & ~process.umask();
15319
15321
  if (!made) made = null;
15320
15322
  p = path$58.resolve(p);
@@ -17181,7 +17183,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17181
17183
  (function(module$122, exports$124, __webpack_require__) {
17182
17184
  var pathModule = __webpack_require__(0);
17183
17185
  var isWindows = process.platform === "win32";
17184
- var fs$31 = __webpack_require__(3);
17186
+ var fs$32 = __webpack_require__(3);
17185
17187
  var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
17186
17188
  function rethrow() {
17187
17189
  var callback;
@@ -17232,7 +17234,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17232
17234
  base = m[0];
17233
17235
  previous = "";
17234
17236
  if (isWindows && !knownHard[base]) {
17235
- fs$31.lstatSync(base);
17237
+ fs$32.lstatSync(base);
17236
17238
  knownHard[base] = true;
17237
17239
  }
17238
17240
  }
@@ -17247,7 +17249,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17247
17249
  var resolvedLink;
17248
17250
  if (cache && Object.prototype.hasOwnProperty.call(cache, base)) resolvedLink = cache[base];
17249
17251
  else {
17250
- var stat = fs$31.lstatSync(base);
17252
+ var stat = fs$32.lstatSync(base);
17251
17253
  if (!stat.isSymbolicLink()) {
17252
17254
  knownHard[base] = true;
17253
17255
  if (cache) cache[base] = base;
@@ -17259,8 +17261,8 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17259
17261
  if (seenLinks.hasOwnProperty(id)) linkTarget = seenLinks[id];
17260
17262
  }
17261
17263
  if (linkTarget === null) {
17262
- fs$31.statSync(base);
17263
- linkTarget = fs$31.readlinkSync(base);
17264
+ fs$32.statSync(base);
17265
+ linkTarget = fs$32.readlinkSync(base);
17264
17266
  }
17265
17267
  resolvedLink = pathModule.resolve(previous, linkTarget);
17266
17268
  if (cache) cache[base] = resolvedLink;
@@ -17291,7 +17293,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17291
17293
  current = m[0];
17292
17294
  base = m[0];
17293
17295
  previous = "";
17294
- if (isWindows && !knownHard[base]) fs$31.lstat(base, function(err) {
17296
+ if (isWindows && !knownHard[base]) fs$32.lstat(base, function(err) {
17295
17297
  if (err) return cb(err);
17296
17298
  knownHard[base] = true;
17297
17299
  LOOP();
@@ -17311,7 +17313,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17311
17313
  pos = nextPartRe.lastIndex;
17312
17314
  if (knownHard[base] || cache && cache[base] === base) return process.nextTick(LOOP);
17313
17315
  if (cache && Object.prototype.hasOwnProperty.call(cache, base)) return gotResolvedLink(cache[base]);
17314
- return fs$31.lstat(base, gotStat);
17316
+ return fs$32.lstat(base, gotStat);
17315
17317
  }
17316
17318
  function gotStat(err, stat) {
17317
17319
  if (err) return cb(err);
@@ -17324,9 +17326,9 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17324
17326
  var id = stat.dev.toString(32) + ":" + stat.ino.toString(32);
17325
17327
  if (seenLinks.hasOwnProperty(id)) return gotTarget(null, seenLinks[id], base);
17326
17328
  }
17327
- fs$31.stat(base, function(err) {
17329
+ fs$32.stat(base, function(err) {
17328
17330
  if (err) return cb(err);
17329
- fs$31.readlink(base, function(err, target) {
17331
+ fs$32.readlink(base, function(err, target) {
17330
17332
  if (!isWindows) seenLinks[id] = target;
17331
17333
  gotTarget(err, target);
17332
17334
  });
@@ -17347,7 +17349,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17347
17349
  (function(module$123, exports$125, __webpack_require__) {
17348
17350
  module$123.exports = globSync;
17349
17351
  globSync.GlobSync = GlobSync;
17350
- var fs$32 = __webpack_require__(3);
17352
+ var fs$33 = __webpack_require__(3);
17351
17353
  var rp = __webpack_require__(114);
17352
17354
  var minimatch = __webpack_require__(60);
17353
17355
  minimatch.Minimatch;
@@ -17481,7 +17483,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17481
17483
  var entries;
17482
17484
  var lstat;
17483
17485
  try {
17484
- lstat = fs$32.lstatSync(abs);
17486
+ lstat = fs$33.lstatSync(abs);
17485
17487
  } catch (er) {
17486
17488
  if (er.code === "ENOENT") return null;
17487
17489
  }
@@ -17499,7 +17501,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17499
17501
  if (Array.isArray(c)) return c;
17500
17502
  }
17501
17503
  try {
17502
- return this._readdirEntries(abs, fs$32.readdirSync(abs));
17504
+ return this._readdirEntries(abs, fs$33.readdirSync(abs));
17503
17505
  } catch (er) {
17504
17506
  this._readdirError(abs, er);
17505
17507
  return null;
@@ -17587,7 +17589,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17587
17589
  if (!stat) {
17588
17590
  var lstat;
17589
17591
  try {
17590
- lstat = fs$32.lstatSync(abs);
17592
+ lstat = fs$33.lstatSync(abs);
17591
17593
  } catch (er) {
17592
17594
  if (er && (er.code === "ENOENT" || er.code === "ENOTDIR")) {
17593
17595
  this.statCache[abs] = false;
@@ -17595,7 +17597,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17595
17597
  }
17596
17598
  }
17597
17599
  if (lstat && lstat.isSymbolicLink()) try {
17598
- stat = fs$32.statSync(abs);
17600
+ stat = fs$33.statSync(abs);
17599
17601
  } catch (er) {
17600
17602
  stat = lstat;
17601
17603
  }
@@ -17805,7 +17807,7 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17805
17807
  rimraf.sync = rimrafSync;
17806
17808
  var assert$6 = __webpack_require__(22);
17807
17809
  var path$61 = __webpack_require__(0);
17808
- var fs$33 = __webpack_require__(3);
17810
+ var fs$34 = __webpack_require__(3);
17809
17811
  var glob = __webpack_require__(75);
17810
17812
  var _0666 = parseInt("666", 8);
17811
17813
  var defaultGlobOpts = {
@@ -17823,9 +17825,9 @@ var require_lockfile$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
17823
17825
  "rmdir",
17824
17826
  "readdir"
17825
17827
  ].forEach(function(m) {
17826
- options[m] = options[m] || fs$33[m];
17828
+ options[m] = options[m] || fs$34[m];
17827
17829
  m = m + "Sync";
17828
- options[m] = options[m] || fs$33[m];
17830
+ options[m] = options[m] || fs$34[m];
17829
17831
  });
17830
17832
  options.maxBusyTries = options.maxBusyTries || 3;
17831
17833
  options.emfileWait = options.emfileWait || 1e3;
@@ -21928,6 +21930,53 @@ const printBanner = (version) => {
21928
21930
  };
21929
21931
  //#endregion
21930
21932
  //#region src/ConfigBuilder.ts
21933
+ const normalizeImportInfos = (imports) => {
21934
+ const collectedImports = /* @__PURE__ */ new Map();
21935
+ for (const info of imports) {
21936
+ const existing = collectedImports.get(info.pkg);
21937
+ if (existing) {
21938
+ if (info.named) for (const namedImport of info.named) existing.named.add(namedImport);
21939
+ if (info.defaultOrNamespace && !existing.defaultOrNamespace) existing.defaultOrNamespace = info.defaultOrNamespace;
21940
+ if (info.sideEffect && !existing.sideEffect) existing.sideEffect = true;
21941
+ continue;
21942
+ }
21943
+ collectedImports.set(info.pkg, {
21944
+ named: new Set(info.named ?? []),
21945
+ defaultOrNamespace: info.defaultOrNamespace,
21946
+ sideEffect: info.sideEffect ?? false
21947
+ });
21948
+ }
21949
+ return Array.from(collectedImports.entries()).sort(([a], [b]) => {
21950
+ const isABuild = a.startsWith("@hot-updater/");
21951
+ if (isABuild !== b.startsWith("@hot-updater/")) return isABuild ? -1 : 1;
21952
+ if (a === "dotenv/config") return -1;
21953
+ if (b === "dotenv/config") return 1;
21954
+ const isAdminA = a === "firebase-admin";
21955
+ if (isAdminA !== (b === "firebase-admin")) return isAdminA ? -1 : 1;
21956
+ return a.localeCompare(b);
21957
+ }).map(([pkg, info]) => ({
21958
+ pkg,
21959
+ named: Array.from(info.named).sort(),
21960
+ defaultOrNamespace: info.defaultOrNamespace,
21961
+ sideEffect: info.sideEffect ?? false
21962
+ }));
21963
+ };
21964
+ const renderImportStatements = (imports) => {
21965
+ const importLines = [];
21966
+ for (const info of normalizeImportInfos(imports)) {
21967
+ if (info.sideEffect) {
21968
+ importLines.push(`import "${info.pkg}";`);
21969
+ continue;
21970
+ }
21971
+ if (info.defaultOrNamespace) {
21972
+ if (info.pkg === "firebase-admin" && (info.named?.length ?? 0) > 0) importLines.push(`import ${info.defaultOrNamespace}, { ${info.named.join(", ")} } from "${info.pkg}";`);
21973
+ else importLines.push(`import ${info.defaultOrNamespace} from "${info.pkg}";`);
21974
+ continue;
21975
+ }
21976
+ if ((info.named?.length ?? 0) > 0) importLines.push(`import { ${info.named.join(", ")} } from "${info.pkg}";`);
21977
+ }
21978
+ return importLines.join("\n");
21979
+ };
21931
21980
  var ConfigBuilder = class {
21932
21981
  buildType = null;
21933
21982
  storageInfo = null;
@@ -21961,28 +22010,13 @@ var ConfigBuilder = class {
21961
22010
  addImports(imports) {
21962
22011
  for (const imp of imports) this.addImport(imp);
21963
22012
  }
21964
- generateImportStatements() {
21965
- const importLines = [];
21966
- const sortedPackages = Array.from(this.collectedImports.keys()).sort((a, b) => {
21967
- const isABuild = a.startsWith("@hot-updater/");
21968
- if (isABuild !== b.startsWith("@hot-updater/")) return isABuild ? -1 : 1;
21969
- if (a === "dotenv/config") return -1;
21970
- if (b === "dotenv/config") return 1;
21971
- const isAdminA = a === "firebase-admin";
21972
- if (isAdminA !== (b === "firebase-admin")) return isAdminA ? -1 : 1;
21973
- return a.localeCompare(b);
21974
- });
21975
- for (const pkg of sortedPackages) {
21976
- const info = this.collectedImports.get(pkg);
21977
- if (info.sideEffect) importLines.push(`import "${pkg}";`);
21978
- else if (info.defaultOrNamespace) if (pkg === "firebase-admin" && info.named.size > 0) importLines.push(`import ${info.defaultOrNamespace}, { ${Array.from(info.named).sort().join(", ")} } from "${pkg}";`);
21979
- else importLines.push(`import ${info.defaultOrNamespace} from "${pkg}";`);
21980
- else if (info.named.size > 0) {
21981
- const namedPart = Array.from(info.named).sort().join(", ");
21982
- importLines.push(`import { ${namedPart} } from "${pkg}";`);
21983
- }
21984
- }
21985
- return importLines.join("\n");
22013
+ getImportInfos() {
22014
+ return normalizeImportInfos(Array.from(this.collectedImports.entries()).map(([pkg, info]) => ({
22015
+ pkg,
22016
+ named: Array.from(info.named),
22017
+ defaultOrNamespace: info.defaultOrNamespace,
22018
+ sideEffect: info.sideEffect ?? false
22019
+ })));
21986
22020
  }
21987
22021
  generateBuildConfigString() {
21988
22022
  if (!this.buildType) throw new Error("Build type must be set using .setBuildType()");
@@ -22024,13 +22058,14 @@ var ConfigBuilder = class {
22024
22058
  this.intermediateCode = code.trim();
22025
22059
  return this;
22026
22060
  }
22027
- getResult() {
22061
+ getScaffold() {
22028
22062
  if (!this.buildType) throw new Error("Build type must be set using .setBuildType()");
22029
22063
  if (!this.storageInfo) throw new Error("Storage config must be set using .setStorage()");
22030
22064
  if (!this.databaseInfo) throw new Error("Database config must be set using .setDatabase()");
22031
- const importStatements = this.generateImportStatements();
22065
+ const imports = this.getImportInfos();
22066
+ const importStatements = renderImportStatements(imports);
22032
22067
  const buildConfigString = this.generateBuildConfigString();
22033
- return `
22068
+ const text = `
22034
22069
  ${importStatements}
22035
22070
 
22036
22071
  config({ path: ".env.hotupdater" });
@@ -22043,6 +22078,17 @@ export default defineConfig({
22043
22078
  updateStrategy: "appVersion", // or "fingerprint"
22044
22079
  });
22045
22080
  `.trim();
22081
+ return {
22082
+ imports,
22083
+ buildConfigString,
22084
+ storageConfigString: this.storageInfo.configString,
22085
+ databaseConfigString: this.databaseInfo.configString,
22086
+ intermediateCode: this.intermediateCode,
22087
+ text
22088
+ };
22089
+ }
22090
+ getResult() {
22091
+ return this.getScaffold().text;
22046
22092
  }
22047
22093
  };
22048
22094
  //#endregion
@@ -36657,7 +36703,7 @@ const handleCommand = (filePath, rawArguments, rawOptions) => {
36657
36703
  var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
36658
36704
  module.exports = isexe;
36659
36705
  isexe.sync = sync;
36660
- var fs$9 = require("fs");
36706
+ var fs$10 = require("fs");
36661
36707
  function checkPathExt(path, options) {
36662
36708
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
36663
36709
  if (!pathext) return true;
@@ -36674,12 +36720,12 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
36674
36720
  return checkPathExt(path, options);
36675
36721
  }
36676
36722
  function isexe(path, options, cb) {
36677
- fs$9.stat(path, function(er, stat) {
36723
+ fs$10.stat(path, function(er, stat) {
36678
36724
  cb(er, er ? false : checkStat(stat, path, options));
36679
36725
  });
36680
36726
  }
36681
36727
  function sync(path, options) {
36682
- return checkStat(fs$9.statSync(path), path, options);
36728
+ return checkStat(fs$10.statSync(path), path, options);
36683
36729
  }
36684
36730
  }));
36685
36731
  //#endregion
@@ -36687,14 +36733,14 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
36687
36733
  var require_mode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
36688
36734
  module.exports = isexe;
36689
36735
  isexe.sync = sync;
36690
- var fs$8 = require("fs");
36736
+ var fs$9 = require("fs");
36691
36737
  function isexe(path, options, cb) {
36692
- fs$8.stat(path, function(er, stat) {
36738
+ fs$9.stat(path, function(er, stat) {
36693
36739
  cb(er, er ? false : checkStat(stat, options));
36694
36740
  });
36695
36741
  }
36696
36742
  function sync(path, options) {
36697
- return checkStat(fs$8.statSync(path), options);
36743
+ return checkStat(fs$9.statSync(path), options);
36698
36744
  }
36699
36745
  function checkStat(stat, options) {
36700
36746
  return stat.isFile() && checkMode(stat, options);
@@ -36909,16 +36955,16 @@ var require_shebang_command = /* @__PURE__ */ __commonJSMin(((exports, module) =
36909
36955
  //#endregion
36910
36956
  //#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js
36911
36957
  var require_readShebang = /* @__PURE__ */ __commonJSMin(((exports, module) => {
36912
- const fs$7 = require("fs");
36958
+ const fs$8 = require("fs");
36913
36959
  const shebangCommand = require_shebang_command();
36914
36960
  function readShebang(command) {
36915
36961
  const size = 150;
36916
36962
  const buffer = Buffer.alloc(size);
36917
36963
  let fd;
36918
36964
  try {
36919
- fd = fs$7.openSync(command, "r");
36920
- fs$7.readSync(fd, buffer, 0, size, 0);
36921
- fs$7.closeSync(fd);
36965
+ fd = fs$8.openSync(command, "r");
36966
+ fs$8.readSync(fd, buffer, 0, size, 0);
36967
+ fs$8.closeSync(fd);
36922
36968
  } catch (e) {}
36923
36969
  return shebangCommand(buffer.toString());
36924
36970
  }
@@ -47584,6 +47630,363 @@ const getReactNativeMetadatas = (cwd) => {
47584
47630
  }
47585
47631
  };
47586
47632
  //#endregion
47633
+ //#region src/hotUpdaterConfig.ts
47634
+ const HOT_UPDATER_CONFIG_PATH = "hot-updater.config.ts";
47635
+ const WRAP_PREFIX = "const __hotUpdaterValue = ";
47636
+ const WRAP_SUFFIX = ";";
47637
+ const MANAGED_IMPORT_PACKAGES = new Set([
47638
+ "dotenv",
47639
+ "firebase-admin",
47640
+ "hot-updater",
47641
+ "@aws-sdk/credential-provider-sso",
47642
+ "@hot-updater/aws",
47643
+ "@hot-updater/bare",
47644
+ "@hot-updater/cloudflare",
47645
+ "@hot-updater/expo",
47646
+ "@hot-updater/firebase",
47647
+ "@hot-updater/rock",
47648
+ "@hot-updater/supabase"
47649
+ ]);
47650
+ const MANAGED_HELPER_NAMES = new Set(["commonOptions", "credential"]);
47651
+ const KNOWN_BUILD_CALLEES = new Set([
47652
+ "bare",
47653
+ "expo",
47654
+ "rock"
47655
+ ]);
47656
+ const createSnippetSourceFile = (code) => typescript.default.createSourceFile("hot-updater-config-snippet.ts", code, typescript.default.ScriptTarget.Latest, true, typescript.default.ScriptKind.TS);
47657
+ const extractCallIdentifier = (initializer) => {
47658
+ const match = /^\s*([A-Za-z_$][\w$]*)\s*\(/.exec(initializer);
47659
+ if (!match) throw new Error(`Failed to extract call identifier from "${initializer}"`);
47660
+ return match[1];
47661
+ };
47662
+ const wrapExpression = (expression) => `${WRAP_PREFIX}${expression}${WRAP_SUFFIX}`;
47663
+ const getWrappedObjectLiteral = (text) => {
47664
+ const sourceFile = createSnippetSourceFile(wrapExpression(text));
47665
+ const statement = sourceFile.statements[0];
47666
+ if (!statement || !typescript.default.isVariableStatement(statement)) return null;
47667
+ const declaration = statement.declarationList.declarations[0];
47668
+ if (!declaration || !declaration.initializer) return null;
47669
+ if (!typescript.default.isObjectLiteralExpression(declaration.initializer)) return null;
47670
+ return {
47671
+ sourceFile,
47672
+ objectLiteral: declaration.initializer,
47673
+ offset: 26
47674
+ };
47675
+ };
47676
+ const parseVariableStatement = (code) => {
47677
+ const sourceFile = createSnippetSourceFile(code);
47678
+ const statement = sourceFile.statements.find((node) => typescript.default.isVariableStatement(node));
47679
+ if (!statement || !typescript.default.isVariableStatement(statement)) return null;
47680
+ const declaration = statement.declarationList.declarations[0];
47681
+ if (!declaration || !typescript.default.isIdentifier(declaration.name) || !declaration.initializer) return null;
47682
+ return {
47683
+ sourceFile,
47684
+ statement,
47685
+ declaration
47686
+ };
47687
+ };
47688
+ const getPropertyName = (property) => {
47689
+ if (typescript.default.isIdentifier(property) || typescript.default.isStringLiteral(property) || typescript.default.isNumericLiteral(property)) return property.text;
47690
+ if (typescript.default.isSpreadAssignment(property)) return null;
47691
+ if (typescript.default.isShorthandPropertyAssignment(property)) return property.name.text;
47692
+ if (typescript.default.isPropertyAssignment(property) || typescript.default.isMethodDeclaration(property) || typescript.default.isGetAccessorDeclaration(property) || typescript.default.isSetAccessorDeclaration(property)) {
47693
+ const { name } = property;
47694
+ if (typescript.default.isIdentifier(name) || typescript.default.isStringLiteral(name)) return name.text;
47695
+ if (typescript.default.isNumericLiteral(name)) return name.text;
47696
+ }
47697
+ return null;
47698
+ };
47699
+ const trimStatementText = (text) => text.trim();
47700
+ const getStatementText = (sourceText, statement) => trimStatementText(sourceText.slice(statement.getFullStart(), statement.end));
47701
+ const getObjectTrailingComma = (text) => {
47702
+ const closeBraceIndex = text.lastIndexOf("}");
47703
+ if (closeBraceIndex === -1) return false;
47704
+ let index = closeBraceIndex - 1;
47705
+ while (index >= 0 && /\s/.test(text[index] ?? "")) index -= 1;
47706
+ return (text[index] ?? "") === ",";
47707
+ };
47708
+ const dedentBlock = (text) => {
47709
+ const lines = text.replace(/\s+$/, "").split("\n");
47710
+ const indents = lines.filter((line) => line.trim() !== "").map((line) => line.match(/^\s*/)[0].length);
47711
+ const minIndent = indents.length > 0 ? Math.min(...indents) : 0;
47712
+ return lines.map((line) => line.slice(minIndent)).join("\n");
47713
+ };
47714
+ const indentBlock = (text, indent) => dedentBlock(text).split("\n").map((line) => `${indent}${line}`).join("\n");
47715
+ const appendMissingProperties = (objectText, propertyTexts, hasExistingProperties) => {
47716
+ if (propertyTexts.length === 0) return objectText;
47717
+ const closingIndent = /\n([ \t]*)\}$/.exec(objectText)?.[1] ?? "";
47718
+ const childIndent = objectText.match(/\n([ \t]+)[^\s]/)?.[1] ?? `${closingIndent} `;
47719
+ const formattedProperties = propertyTexts.map((propertyText) => indentBlock(propertyText, childIndent)).join(",\n");
47720
+ const closeBraceIndex = objectText.lastIndexOf("}");
47721
+ if (closeBraceIndex === -1) return objectText;
47722
+ const prefix = hasExistingProperties ? getObjectTrailingComma(objectText) ? "\n" : ",\n" : "\n";
47723
+ const suffix = `,\n${closingIndent}`;
47724
+ return `${objectText.slice(0, closeBraceIndex)}${prefix}${formattedProperties}${suffix}${objectText.slice(closeBraceIndex)}`;
47725
+ };
47726
+ const mergeObjectLiteralText = (existingText, newText) => {
47727
+ const existingWrapped = getWrappedObjectLiteral(existingText);
47728
+ const newWrapped = getWrappedObjectLiteral(newText);
47729
+ if (!existingWrapped || !newWrapped) return null;
47730
+ const existingPropertyNames = /* @__PURE__ */ new Set();
47731
+ const existingSpreadTexts = /* @__PURE__ */ new Set();
47732
+ const edits = [];
47733
+ for (const property of existingWrapped.objectLiteral.properties) {
47734
+ if (typescript.default.isSpreadAssignment(property)) {
47735
+ existingSpreadTexts.add(property.expression.getText(existingWrapped.sourceFile).trim());
47736
+ continue;
47737
+ }
47738
+ const propertyName = getPropertyName(property);
47739
+ if (!propertyName) continue;
47740
+ existingPropertyNames.add(propertyName);
47741
+ const nextProperty = newWrapped.objectLiteral.properties.find((candidate) => {
47742
+ if (typescript.default.isSpreadAssignment(candidate)) return false;
47743
+ return getPropertyName(candidate) === propertyName;
47744
+ });
47745
+ if (!nextProperty || !typescript.default.isPropertyAssignment(property) || !typescript.default.isPropertyAssignment(nextProperty)) continue;
47746
+ if (typescript.default.isObjectLiteralExpression(property.initializer) && typescript.default.isObjectLiteralExpression(nextProperty.initializer)) {
47747
+ const mergedInitializer = mergeObjectLiteralText(property.initializer.getText(existingWrapped.sourceFile), nextProperty.initializer.getText(newWrapped.sourceFile));
47748
+ if (!mergedInitializer) return null;
47749
+ edits.push({
47750
+ start: property.initializer.getStart(existingWrapped.sourceFile) - existingWrapped.offset,
47751
+ end: property.initializer.end - existingWrapped.offset,
47752
+ text: mergedInitializer
47753
+ });
47754
+ }
47755
+ }
47756
+ let mergedText = existingText;
47757
+ for (const edit of edits.sort((a, b) => b.start - a.start)) mergedText = mergedText.slice(0, edit.start) + edit.text + mergedText.slice(edit.end);
47758
+ const missingPropertyTexts = newWrapped.objectLiteral.properties.filter((property) => {
47759
+ if (typescript.default.isSpreadAssignment(property)) return !existingSpreadTexts.has(property.expression.getText(newWrapped.sourceFile).trim());
47760
+ const propertyName = getPropertyName(property);
47761
+ return propertyName ? !existingPropertyNames.has(propertyName) : false;
47762
+ }).map((property) => property.getText(newWrapped.sourceFile));
47763
+ return appendMissingProperties(mergedText, missingPropertyTexts, existingWrapped.objectLiteral.properties.length > 0);
47764
+ };
47765
+ const buildMergedCallInitializer = (existingCall, existingSourceFile, newCall, newSourceFile) => {
47766
+ const existingCallee = existingCall.expression.getText(existingSourceFile);
47767
+ const [existingArg] = existingCall.arguments;
47768
+ const [newArg] = newCall.arguments;
47769
+ if (existingCall.arguments.length === 1 && newCall.arguments.length === 1 && existingArg && newArg && typescript.default.isObjectLiteralExpression(existingArg) && typescript.default.isObjectLiteralExpression(newArg)) {
47770
+ const mergedObjectLiteral = mergeObjectLiteralText(existingArg.getText(existingSourceFile), newArg.getText(newSourceFile));
47771
+ if (!mergedObjectLiteral) return null;
47772
+ return `${existingCallee}(${mergedObjectLiteral})`;
47773
+ }
47774
+ return existingCall.getText(existingSourceFile);
47775
+ };
47776
+ const findDefineConfigObject = (sourceFile) => {
47777
+ const exportAssignment = sourceFile.statements.find((statement) => {
47778
+ if (!typescript.default.isExportAssignment(statement)) return false;
47779
+ const expression = statement.expression;
47780
+ if (!typescript.default.isCallExpression(expression)) return false;
47781
+ return typescript.default.isIdentifier(expression.expression) && expression.expression.text === "defineConfig" && expression.arguments.length > 0 && typescript.default.isObjectLiteralExpression(expression.arguments[0]);
47782
+ });
47783
+ if (!exportAssignment || !typescript.default.isExportAssignment(exportAssignment)) return null;
47784
+ const expression = exportAssignment.expression;
47785
+ if (!typescript.default.isCallExpression(expression)) return null;
47786
+ const [argument] = expression.arguments;
47787
+ if (!argument || !typescript.default.isObjectLiteralExpression(argument)) return null;
47788
+ return {
47789
+ exportAssignment,
47790
+ objectLiteral: argument
47791
+ };
47792
+ };
47793
+ const findManagedProperty = (objectLiteral, propertyName) => objectLiteral.properties.find((property) => typescript.default.isPropertyAssignment(property) && getPropertyName(property.name) === propertyName);
47794
+ const getCallCallee = (expression) => {
47795
+ if (!typescript.default.isCallExpression(expression) || !typescript.default.isIdentifier(expression.expression)) return null;
47796
+ return expression.expression.text;
47797
+ };
47798
+ const isConfigCallStatement = (statement) => typescript.default.isExpressionStatement(statement) && typescript.default.isCallExpression(statement.expression) && typescript.default.isIdentifier(statement.expression.expression) && statement.expression.expression.text === "config";
47799
+ const isManagedHelperStatement = (statement) => {
47800
+ if (!typescript.default.isVariableStatement(statement)) return null;
47801
+ const declaration = statement.declarationList.declarations[0];
47802
+ if (!declaration || !typescript.default.isIdentifier(declaration.name)) return null;
47803
+ return MANAGED_HELPER_NAMES.has(declaration.name.text) ? declaration.name.text : null;
47804
+ };
47805
+ const mergeHelperStatement = (existingStatementText, helper) => {
47806
+ if (helper.strategy === "preserve-existing") return existingStatementText;
47807
+ if (helper.strategy === "replace") return helper.code.trim();
47808
+ const existingStatement = parseVariableStatement(existingStatementText);
47809
+ const nextStatement = parseVariableStatement(helper.code);
47810
+ if (!existingStatement || !nextStatement) return null;
47811
+ const existingInitializer = existingStatement.declaration.initializer;
47812
+ const newInitializer = nextStatement.declaration.initializer;
47813
+ if (!existingInitializer || !newInitializer || !typescript.default.isObjectLiteralExpression(existingInitializer) || !typescript.default.isObjectLiteralExpression(newInitializer)) return null;
47814
+ const mergedInitializer = mergeObjectLiteralText(existingInitializer.getText(existingStatement.sourceFile), newInitializer.getText(nextStatement.sourceFile));
47815
+ if (!mergedInitializer) return null;
47816
+ return `${typescript.default.tokenToString(existingStatement.statement.declarationList.flags & typescript.default.NodeFlags.Const ? typescript.default.SyntaxKind.ConstKeyword : existingStatement.statement.declarationList.flags & typescript.default.NodeFlags.Let ? typescript.default.SyntaxKind.LetKeyword : typescript.default.SyntaxKind.VarKeyword) ?? "const"} ${helper.name} = ${mergedInitializer};`;
47817
+ };
47818
+ const updateManagedObject = (existingText, existingObject, newObject, existingSourceFile, newSourceFile) => {
47819
+ const objectStart = existingObject.getStart(existingSourceFile);
47820
+ const objectText = existingText.slice(objectStart, existingObject.end);
47821
+ const propertyEdits = [];
47822
+ const missingPropertyTexts = [];
47823
+ for (const propertyName of [
47824
+ "build",
47825
+ "storage",
47826
+ "database"
47827
+ ]) {
47828
+ const existingProperty = findManagedProperty(existingObject, propertyName);
47829
+ const nextProperty = findManagedProperty(newObject, propertyName);
47830
+ if (!nextProperty) continue;
47831
+ if (!existingProperty) {
47832
+ missingPropertyTexts.push(nextProperty.getText(newSourceFile));
47833
+ continue;
47834
+ }
47835
+ if (!typescript.default.isCallExpression(existingProperty.initializer)) return null;
47836
+ if (!typescript.default.isCallExpression(nextProperty.initializer)) return null;
47837
+ const existingCallee = getCallCallee(existingProperty.initializer);
47838
+ const nextCallee = getCallCallee(nextProperty.initializer);
47839
+ if (!existingCallee || !nextCallee) return null;
47840
+ let nextInitializerText = nextProperty.initializer.getText(newSourceFile);
47841
+ if (propertyName === "build") {
47842
+ if (existingCallee === nextCallee) continue;
47843
+ if (!KNOWN_BUILD_CALLEES.has(existingCallee)) return null;
47844
+ } else if (existingCallee === nextCallee) {
47845
+ const mergedInitializer = buildMergedCallInitializer(existingProperty.initializer, existingSourceFile, nextProperty.initializer, newSourceFile);
47846
+ if (mergedInitializer === null) return null;
47847
+ nextInitializerText = mergedInitializer;
47848
+ }
47849
+ propertyEdits.push({
47850
+ start: existingProperty.initializer.getStart(existingSourceFile) - objectStart,
47851
+ end: existingProperty.initializer.end - objectStart,
47852
+ text: nextInitializerText
47853
+ });
47854
+ }
47855
+ let mergedText = objectText;
47856
+ for (const edit of propertyEdits.sort((a, b) => b.start - a.start)) mergedText = mergedText.slice(0, edit.start) + edit.text + mergedText.slice(edit.end);
47857
+ return appendMissingProperties(mergedText, missingPropertyTexts, existingObject.properties.length > 0);
47858
+ };
47859
+ const rebuildImportBlock = (sourceText, sourceFile, scaffold) => {
47860
+ const importDeclarations = sourceFile.statements.filter(typescript.default.isImportDeclaration);
47861
+ if (importDeclarations.length === 0) return {
47862
+ start: 0,
47863
+ end: 0,
47864
+ text: `${renderImportStatements(scaffold.imports)}\n\n`
47865
+ };
47866
+ const preservedImportTexts = importDeclarations.filter((declaration) => {
47867
+ const moduleSpecifier = declaration.moduleSpecifier;
47868
+ return typescript.default.isStringLiteral(moduleSpecifier) && !MANAGED_IMPORT_PACKAGES.has(moduleSpecifier.text);
47869
+ }).map((declaration) => trimStatementText(sourceText.slice(declaration.getFullStart(), declaration.end)));
47870
+ const managedImportText = renderImportStatements(scaffold.imports);
47871
+ const nextImportBlock = [...preservedImportTexts, managedImportText].filter(Boolean).join("\n");
47872
+ return {
47873
+ start: importDeclarations[0].getFullStart(),
47874
+ end: importDeclarations.at(-1).end,
47875
+ text: `${nextImportBlock}\n\n`
47876
+ };
47877
+ };
47878
+ const rebuildManagedBody = (sourceText, sourceFile, exportAssignment, scaffold) => {
47879
+ const statementsBeforeExport = sourceFile.statements.filter((statement) => !typescript.default.isImportDeclaration(statement) && statement.pos < exportAssignment.pos);
47880
+ const managedHelpers = new Map(scaffold.helperStatements.map((statement) => [statement.name, statement]));
47881
+ const emittedHelpers = /* @__PURE__ */ new Set();
47882
+ const bodyStatements = [];
47883
+ for (const statement of statementsBeforeExport) {
47884
+ if (isConfigCallStatement(statement)) continue;
47885
+ const helperName = isManagedHelperStatement(statement);
47886
+ if (!helperName) {
47887
+ bodyStatements.push(getStatementText(sourceText, statement));
47888
+ continue;
47889
+ }
47890
+ const helper = managedHelpers.get(helperName);
47891
+ if (!helper) continue;
47892
+ const mergedHelperStatement = mergeHelperStatement(getStatementText(sourceText, statement), helper);
47893
+ if (!mergedHelperStatement) return null;
47894
+ emittedHelpers.add(helperName);
47895
+ bodyStatements.push(mergedHelperStatement);
47896
+ }
47897
+ for (const helper of scaffold.helperStatements) if (!emittedHelpers.has(helper.name)) bodyStatements.push(helper.code.trim());
47898
+ const bodyText = bodyStatements.filter(Boolean).join("\n\n");
47899
+ const configStatement = `config({ path: ".env.hotupdater" });`;
47900
+ const managedBody = bodyText ? `\n\n${configStatement}\n\n${bodyText}\n\n` : `\n\n${configStatement}\n\n`;
47901
+ return {
47902
+ start: sourceFile.statements.filter(typescript.default.isImportDeclaration).at(-1)?.end ?? 0,
47903
+ end: exportAssignment.getFullStart(),
47904
+ text: managedBody
47905
+ };
47906
+ };
47907
+ const createHotUpdaterConfigScaffold = ({ build, storage, database, extraImports = [], helperStatements = [], updateStrategy = "appVersion" }) => {
47908
+ const intermediateCode = helperStatements.map((statement) => statement.code.trim()).filter(Boolean).join("\n\n");
47909
+ const builder = new ConfigBuilder().setBuildType(build).setStorage(storage).setDatabase(database);
47910
+ for (const extraImport of extraImports) builder.addImport(extraImport);
47911
+ if (intermediateCode) builder.setIntermediateCode(intermediateCode);
47912
+ return createHotUpdaterConfigScaffoldFromBuilder(builder, {
47913
+ helperStatements,
47914
+ updateStrategy
47915
+ });
47916
+ };
47917
+ const createHotUpdaterConfigScaffoldFromBuilder = (builder, { helperStatements = [], updateStrategy = "appVersion" } = {}) => {
47918
+ const scaffold = builder.getScaffold();
47919
+ return {
47920
+ text: updateStrategy === "appVersion" ? scaffold.text : scaffold.text.replace("updateStrategy: \"appVersion\"", `updateStrategy: "${updateStrategy}"`),
47921
+ imports: scaffold.imports,
47922
+ build: {
47923
+ initializer: scaffold.buildConfigString,
47924
+ callee: extractCallIdentifier(scaffold.buildConfigString)
47925
+ },
47926
+ storage: {
47927
+ initializer: scaffold.storageConfigString,
47928
+ callee: extractCallIdentifier(scaffold.storageConfigString)
47929
+ },
47930
+ database: {
47931
+ initializer: scaffold.databaseConfigString,
47932
+ callee: extractCallIdentifier(scaffold.databaseConfigString)
47933
+ },
47934
+ helperStatements,
47935
+ updateStrategy: `"${updateStrategy}"`
47936
+ };
47937
+ };
47938
+ const writeHotUpdaterConfig = async (scaffold, filePath = HOT_UPDATER_CONFIG_PATH) => {
47939
+ const existingText = await fs_promises.default.readFile(filePath, "utf-8").catch((error) => {
47940
+ if (error.code === "ENOENT") return null;
47941
+ throw error;
47942
+ });
47943
+ if (existingText === null) {
47944
+ await fs_promises.default.writeFile(filePath, `${scaffold.text}\n`, "utf-8");
47945
+ return {
47946
+ status: "created",
47947
+ path: filePath
47948
+ };
47949
+ }
47950
+ const existingSourceFile = createSnippetSourceFile(existingText);
47951
+ const existingConfig = findDefineConfigObject(existingSourceFile);
47952
+ const nextSourceFile = createSnippetSourceFile(scaffold.text);
47953
+ const nextConfig = findDefineConfigObject(nextSourceFile);
47954
+ if (!existingConfig || !nextConfig) return {
47955
+ status: "skipped",
47956
+ path: filePath,
47957
+ reason: "Existing config is not a supported `export default defineConfig({ ... })` shape."
47958
+ };
47959
+ const nextObjectText = updateManagedObject(existingText, existingConfig.objectLiteral, nextConfig.objectLiteral, existingSourceFile, nextSourceFile);
47960
+ if (!nextObjectText) return {
47961
+ status: "skipped",
47962
+ path: filePath,
47963
+ reason: "Existing config uses dynamic build/storage/database expressions that cannot be merged safely."
47964
+ };
47965
+ const objectEdit = {
47966
+ start: existingConfig.objectLiteral.getStart(existingSourceFile),
47967
+ end: existingConfig.objectLiteral.end,
47968
+ text: nextObjectText
47969
+ };
47970
+ const importEdit = rebuildImportBlock(existingText, existingSourceFile, scaffold);
47971
+ const bodyEdit = rebuildManagedBody(existingText, existingSourceFile, existingConfig.exportAssignment, scaffold);
47972
+ if (!bodyEdit) return {
47973
+ status: "skipped",
47974
+ path: filePath,
47975
+ reason: "Existing helper declarations could not be merged safely."
47976
+ };
47977
+ let mergedText = existingText;
47978
+ for (const edit of [
47979
+ objectEdit,
47980
+ bodyEdit,
47981
+ importEdit
47982
+ ].sort((a, b) => b.start - a.start)) mergedText = mergedText.slice(0, edit.start) + edit.text + mergedText.slice(edit.end);
47983
+ await fs_promises.default.writeFile(filePath, mergedText, "utf-8");
47984
+ return {
47985
+ status: "merged",
47986
+ path: filePath
47987
+ };
47988
+ };
47989
+ //#endregion
47587
47990
  //#region ../../node_modules/.pnpm/es-toolkit@1.32.0/node_modules/es-toolkit/dist/predicate/isPlainObject.mjs
47588
47991
  function isPlainObject(value) {
47589
47992
  if (!value || typeof value !== "object") return false;
@@ -47705,8 +48108,9 @@ const log = {
47705
48108
  };
47706
48109
  //#endregion
47707
48110
  //#region src/makeEnv.ts
47708
- const makeEnv = async (newEnvVars, filePath = ".env.hotupdater") => {
48111
+ const makeEnv = async (newEnvVars, filePath = ".env.hotupdater", options) => {
47709
48112
  try {
48113
+ const preserveKeys = new Set(options?.preserveKeys ?? []);
47710
48114
  const existingContent = await fs_promises.default.readFile(filePath, "utf-8").catch(() => "");
47711
48115
  const lines = existingContent ? existingContent.split("\n") : [];
47712
48116
  const processedKeys = /* @__PURE__ */ new Set();
@@ -47723,7 +48127,7 @@ const makeEnv = async (newEnvVars, filePath = ".env.hotupdater") => {
47723
48127
  const nextLine = (lines[i + 1] ?? "").trim();
47724
48128
  if (nextLine && !nextLine.startsWith("#") && nextLine.includes("=")) {
47725
48129
  const [possibleKey = ""] = nextLine.split("=");
47726
- if (Object.hasOwn(newEnvVars, possibleKey.trim())) continue;
48130
+ if (Object.hasOwn(newEnvVars, possibleKey.trim()) && !preserveKeys.has(possibleKey.trim())) continue;
47727
48131
  }
47728
48132
  }
47729
48133
  updatedLines.push(line);
@@ -47734,6 +48138,10 @@ const makeEnv = async (newEnvVars, filePath = ".env.hotupdater") => {
47734
48138
  const key = keyPart?.trim() ?? "";
47735
48139
  if (Object.hasOwn(newEnvVars, key)) {
47736
48140
  processedKeys.add(key);
48141
+ if (preserveKeys.has(key)) {
48142
+ updatedLines.push(line);
48143
+ continue;
48144
+ }
47737
48145
  const newValue = newEnvVars[key];
47738
48146
  if (typeof newValue === "object" && newValue !== null) {
47739
48147
  updatedLines.push(`# ${newValue.comment}`);
@@ -47827,6 +48235,8 @@ exports.HotUpdateDirUtil = HotUpdateDirUtil;
47827
48235
  exports.banner = banner;
47828
48236
  exports.colors = import_picocolors.default;
47829
48237
  exports.copyDirToTmp = copyDirToTmp;
48238
+ exports.createHotUpdaterConfigScaffold = createHotUpdaterConfigScaffold;
48239
+ exports.createHotUpdaterConfigScaffoldFromBuilder = createHotUpdaterConfigScaffoldFromBuilder;
47830
48240
  exports.createLogWriter = createLogWriter;
47831
48241
  exports.createTarBr = createTarBr;
47832
48242
  exports.createTarBrTargetFiles = createTarBrTargetFiles;
@@ -47852,8 +48262,10 @@ Object.defineProperty(exports, "p", {
47852
48262
  }
47853
48263
  });
47854
48264
  exports.printBanner = printBanner;
48265
+ exports.renderImportStatements = renderImportStatements;
47855
48266
  exports.resolveHotUpdaterServerVersion = resolveHotUpdaterServerVersion;
47856
48267
  exports.resolvePackageVersion = resolvePackageVersion;
47857
48268
  exports.stripAnsi = stripAnsi;
47858
48269
  exports.transformEnv = transformEnv;
47859
48270
  exports.transformTemplate = transformTemplate;
48271
+ exports.writeHotUpdaterConfig = writeHotUpdaterConfig;