@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.mjs CHANGED
@@ -9,7 +9,7 @@ import fs$1 from "fs/promises";
9
9
  import assert from "assert";
10
10
  import crypto from "crypto";
11
11
  import { Buffer as Buffer$1 } from "buffer";
12
- import N, { execArgv, execPath, hrtime, platform, stdin, stdout } from "node:process";
12
+ import process$1, { execArgv, execPath, hrtime, platform, stdin, stdout } from "node:process";
13
13
  import * as k from "node:readline";
14
14
  import ot from "node:readline";
15
15
  import tty, { ReadStream } from "node:tty";
@@ -24,13 +24,14 @@ import Stream, { Duplex, PassThrough as PassThrough$1, Readable as Readable$1, T
24
24
  import { StringDecoder } from "node:string_decoder";
25
25
  import assert$1 from "node:assert";
26
26
  import { randomBytes } from "node:crypto";
27
- import fsp from "node:fs/promises";
27
+ import fsPromises from "node:fs/promises";
28
28
  import { fileURLToPath } from "node:url";
29
29
  import { ChildProcess, execFile, spawn, spawnSync } from "node:child_process";
30
30
  import { scheduler, setImmediate as setImmediate$1, setTimeout as setTimeout$1 } from "node:timers/promises";
31
31
  import { serialize } from "node:v8";
32
32
  import { finished } from "node:stream/promises";
33
33
  import { Buffer as Buffer$2 } from "node:buffer";
34
+ import ts from "typescript";
34
35
  import { loadConfig as loadConfig$1 } from "unconfig";
35
36
  import { transformSync } from "oxc-transform";
36
37
  //#region ../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js
@@ -19279,7 +19280,7 @@ var dist_exports = /* @__PURE__ */ __exportAll({
19279
19280
  updateSettings: () => It$1
19280
19281
  });
19281
19282
  function me() {
19282
- return N.platform !== "win32" ? N.env.TERM !== "linux" : !!N.env.CI || !!N.env.WT_SESSION || !!N.env.TERMINUS_SUBLIME || N.env.ConEmuTask === "{cmd::Cmder}" || N.env.TERM_PROGRAM === "Terminus-Sublime" || N.env.TERM_PROGRAM === "vscode" || N.env.TERM === "xterm-256color" || N.env.TERM === "alacritty" || N.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
19283
+ return process$1.platform !== "win32" ? process$1.env.TERM !== "linux" : !!process$1.env.CI || !!process$1.env.WT_SESSION || !!process$1.env.TERMINUS_SUBLIME || process$1.env.ConEmuTask === "{cmd::Cmder}" || process$1.env.TERM_PROGRAM === "Terminus-Sublime" || process$1.env.TERM_PROGRAM === "vscode" || process$1.env.TERM === "xterm-256color" || process$1.env.TERM === "alacritty" || process$1.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
19283
19284
  }
19284
19285
  const et = me(), ct = () => process.env.CI === "true", Mt = (t) => t.isTTY === !0, C = (t, r) => et ? t : r, Rt = C("◆", "*"), dt = C("■", "x"), $t = C("▲", "x"), V = C("◇", "o"), ht = C("┌", "T"), d = C("│", "|"), x = C("└", "—"), Ot = C("┐", "T"), Pt = C("┘", "—"), Q = C("●", ">"), H = C("○", " "), st = C("◻", "[•]"), U = C("◼", "[+]"), q = C("◻", "[ ]"), Nt = C("▪", "•"), rt = C("─", "-"), mt = C("╮", "+"), Wt = C("├", "+"), pt = C("╯", "+"), gt = C("╰", "+"), Lt = C("╭", "+"), ft = C("●", "•"), Ft = C("◆", "*"), yt = C("▲", "!"), Et = C("■", "x"), W = (t) => {
19285
19286
  switch (t) {
@@ -19919,7 +19920,7 @@ ${import_picocolors.default.cyan(x)}
19919
19920
  `), o = a.reduce((n, c) => Math.max(M(c), n), 0);
19920
19921
  return J(t, r - (a.map(s).reduce((n, c) => Math.max(M(c), n), 0) - o), i);
19921
19922
  }, Ve = (t = "", r = "", s) => {
19922
- const i = s?.output ?? N.stdout, a = s?.withGuide ?? _.withGuide, o = s?.format ?? Ge, u = [
19923
+ const i = s?.output ?? process$1.stdout, a = s?.withGuide ?? _.withGuide, o = s?.format ?? Ge, u = [
19923
19924
  "",
19924
19925
  ...ke(t, rt$1(i) - 6, o).split(`
19925
19926
  `).map(o),
@@ -20849,13 +20850,13 @@ function assembleStyles$1() {
20849
20850
  const ansiStyles$1 = assembleStyles$1();
20850
20851
  //#endregion
20851
20852
  //#region ../../node_modules/.pnpm/chalk@5.4.1/node_modules/chalk/source/vendor/supports-color/index.js
20852
- function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : N.argv) {
20853
+ function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process$1.argv) {
20853
20854
  const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
20854
20855
  const position = argv.indexOf(prefix + flag);
20855
20856
  const terminatorPosition = argv.indexOf("--");
20856
20857
  return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
20857
20858
  }
20858
- const { env } = N;
20859
+ const { env } = process$1;
20859
20860
  let flagForceColor;
20860
20861
  if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) flagForceColor = 0;
20861
20862
  else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) flagForceColor = 1;
@@ -20888,7 +20889,7 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
20888
20889
  if (haveStream && !streamIsTTY && forceColor === void 0) return 0;
20889
20890
  const min = forceColor || 0;
20890
20891
  if (env.TERM === "dumb") return min;
20891
- if (N.platform === "win32") {
20892
+ if (process$1.platform === "win32") {
20892
20893
  const osRelease = os.release().split(".");
20893
20894
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
20894
20895
  return 1;
@@ -21645,7 +21646,7 @@ const NEWLINE = "\n";
21645
21646
  const PAD = " ";
21646
21647
  const NONE = "none";
21647
21648
  const terminalColumns = () => {
21648
- const { env, stdout, stderr } = N;
21649
+ const { env, stdout, stderr } = process$1;
21649
21650
  if (stdout?.columns) return stdout.columns;
21650
21651
  if (stderr?.columns) return stderr.columns;
21651
21652
  if (env.COLUMNS) return Number.parseInt(env.COLUMNS, 10);
@@ -21788,8 +21789,8 @@ const boxContent = (content, contentWidth, options) => {
21788
21789
  return result;
21789
21790
  };
21790
21791
  const sanitizeOptions = (options) => {
21791
- if (options.fullscreen && N?.stdout) {
21792
- let newDimensions = [N.stdout.columns, N.stdout.rows];
21792
+ if (options.fullscreen && process$1?.stdout) {
21793
+ let newDimensions = [process$1.stdout.columns, process$1.stdout.rows];
21793
21794
  if (typeof options.fullscreen === "function") newDimensions = options.fullscreen(...newDimensions);
21794
21795
  options.width ||= newDimensions[0];
21795
21796
  options.height ||= newDimensions[1];
@@ -21882,6 +21883,53 @@ const printBanner = (version) => {
21882
21883
  };
21883
21884
  //#endregion
21884
21885
  //#region src/ConfigBuilder.ts
21886
+ const normalizeImportInfos = (imports) => {
21887
+ const collectedImports = /* @__PURE__ */ new Map();
21888
+ for (const info of imports) {
21889
+ const existing = collectedImports.get(info.pkg);
21890
+ if (existing) {
21891
+ if (info.named) for (const namedImport of info.named) existing.named.add(namedImport);
21892
+ if (info.defaultOrNamespace && !existing.defaultOrNamespace) existing.defaultOrNamespace = info.defaultOrNamespace;
21893
+ if (info.sideEffect && !existing.sideEffect) existing.sideEffect = true;
21894
+ continue;
21895
+ }
21896
+ collectedImports.set(info.pkg, {
21897
+ named: new Set(info.named ?? []),
21898
+ defaultOrNamespace: info.defaultOrNamespace,
21899
+ sideEffect: info.sideEffect ?? false
21900
+ });
21901
+ }
21902
+ return Array.from(collectedImports.entries()).sort(([a], [b]) => {
21903
+ const isABuild = a.startsWith("@hot-updater/");
21904
+ if (isABuild !== b.startsWith("@hot-updater/")) return isABuild ? -1 : 1;
21905
+ if (a === "dotenv/config") return -1;
21906
+ if (b === "dotenv/config") return 1;
21907
+ const isAdminA = a === "firebase-admin";
21908
+ if (isAdminA !== (b === "firebase-admin")) return isAdminA ? -1 : 1;
21909
+ return a.localeCompare(b);
21910
+ }).map(([pkg, info]) => ({
21911
+ pkg,
21912
+ named: Array.from(info.named).sort(),
21913
+ defaultOrNamespace: info.defaultOrNamespace,
21914
+ sideEffect: info.sideEffect ?? false
21915
+ }));
21916
+ };
21917
+ const renderImportStatements = (imports) => {
21918
+ const importLines = [];
21919
+ for (const info of normalizeImportInfos(imports)) {
21920
+ if (info.sideEffect) {
21921
+ importLines.push(`import "${info.pkg}";`);
21922
+ continue;
21923
+ }
21924
+ if (info.defaultOrNamespace) {
21925
+ if (info.pkg === "firebase-admin" && (info.named?.length ?? 0) > 0) importLines.push(`import ${info.defaultOrNamespace}, { ${info.named.join(", ")} } from "${info.pkg}";`);
21926
+ else importLines.push(`import ${info.defaultOrNamespace} from "${info.pkg}";`);
21927
+ continue;
21928
+ }
21929
+ if ((info.named?.length ?? 0) > 0) importLines.push(`import { ${info.named.join(", ")} } from "${info.pkg}";`);
21930
+ }
21931
+ return importLines.join("\n");
21932
+ };
21885
21933
  var ConfigBuilder = class {
21886
21934
  buildType = null;
21887
21935
  storageInfo = null;
@@ -21915,28 +21963,13 @@ var ConfigBuilder = class {
21915
21963
  addImports(imports) {
21916
21964
  for (const imp of imports) this.addImport(imp);
21917
21965
  }
21918
- generateImportStatements() {
21919
- const importLines = [];
21920
- const sortedPackages = Array.from(this.collectedImports.keys()).sort((a, b) => {
21921
- const isABuild = a.startsWith("@hot-updater/");
21922
- if (isABuild !== b.startsWith("@hot-updater/")) return isABuild ? -1 : 1;
21923
- if (a === "dotenv/config") return -1;
21924
- if (b === "dotenv/config") return 1;
21925
- const isAdminA = a === "firebase-admin";
21926
- if (isAdminA !== (b === "firebase-admin")) return isAdminA ? -1 : 1;
21927
- return a.localeCompare(b);
21928
- });
21929
- for (const pkg of sortedPackages) {
21930
- const info = this.collectedImports.get(pkg);
21931
- if (info.sideEffect) importLines.push(`import "${pkg}";`);
21932
- 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}";`);
21933
- else importLines.push(`import ${info.defaultOrNamespace} from "${pkg}";`);
21934
- else if (info.named.size > 0) {
21935
- const namedPart = Array.from(info.named).sort().join(", ");
21936
- importLines.push(`import { ${namedPart} } from "${pkg}";`);
21937
- }
21938
- }
21939
- return importLines.join("\n");
21966
+ getImportInfos() {
21967
+ return normalizeImportInfos(Array.from(this.collectedImports.entries()).map(([pkg, info]) => ({
21968
+ pkg,
21969
+ named: Array.from(info.named),
21970
+ defaultOrNamespace: info.defaultOrNamespace,
21971
+ sideEffect: info.sideEffect ?? false
21972
+ })));
21940
21973
  }
21941
21974
  generateBuildConfigString() {
21942
21975
  if (!this.buildType) throw new Error("Build type must be set using .setBuildType()");
@@ -21978,13 +22011,14 @@ var ConfigBuilder = class {
21978
22011
  this.intermediateCode = code.trim();
21979
22012
  return this;
21980
22013
  }
21981
- getResult() {
22014
+ getScaffold() {
21982
22015
  if (!this.buildType) throw new Error("Build type must be set using .setBuildType()");
21983
22016
  if (!this.storageInfo) throw new Error("Storage config must be set using .setStorage()");
21984
22017
  if (!this.databaseInfo) throw new Error("Database config must be set using .setDatabase()");
21985
- const importStatements = this.generateImportStatements();
22018
+ const imports = this.getImportInfos();
22019
+ const importStatements = renderImportStatements(imports);
21986
22020
  const buildConfigString = this.generateBuildConfigString();
21987
- return `
22021
+ const text = `
21988
22022
  ${importStatements}
21989
22023
 
21990
22024
  config({ path: ".env.hotupdater" });
@@ -21997,6 +22031,17 @@ export default defineConfig({
21997
22031
  updateStrategy: "appVersion", // or "fingerprint"
21998
22032
  });
21999
22033
  `.trim();
22034
+ return {
22035
+ imports,
22036
+ buildConfigString,
22037
+ storageConfigString: this.storageInfo.configString,
22038
+ databaseConfigString: this.databaseInfo.configString,
22039
+ intermediateCode: this.intermediateCode,
22040
+ text
22041
+ };
22042
+ }
22043
+ getResult() {
22044
+ return this.getScaffold().text;
22000
22045
  }
22001
22046
  };
22002
22047
  //#endregion
@@ -25943,7 +25988,7 @@ const mkdir = (dir, opt, cb) => {
25943
25988
  else cb();
25944
25989
  };
25945
25990
  if (dir === cwd) return checkCwd(dir, done);
25946
- if (preserve) return fsp.mkdir(dir, {
25991
+ if (preserve) return fsPromises.mkdir(dir, {
25947
25992
  mode,
25948
25993
  recursive: true
25949
25994
  }).then((made) => done(null, made ?? void 0), done);
@@ -36006,9 +36051,9 @@ const getSubprocessResult = ({ stdout }) => {
36006
36051
  //#region ../../node_modules/.pnpm/execa@9.5.2/node_modules/execa/lib/utils/standard-stream.js
36007
36052
  const isStandardStream = (stream) => STANDARD_STREAMS.includes(stream);
36008
36053
  const STANDARD_STREAMS = [
36009
- N.stdin,
36010
- N.stdout,
36011
- N.stderr
36054
+ process$1.stdin,
36055
+ process$1.stdout,
36056
+ process$1.stderr
36012
36057
  ];
36013
36058
  const STANDARD_STREAMS_ALIASES = [
36014
36059
  "stdin",
@@ -36129,9 +36174,9 @@ const NO_ESCAPE_REGEXP = /^[\w./-]+$/;
36129
36174
  //#endregion
36130
36175
  //#region ../../node_modules/.pnpm/is-unicode-supported@2.1.0/node_modules/is-unicode-supported/index.js
36131
36176
  function isUnicodeSupported() {
36132
- const { env } = N;
36177
+ const { env } = process$1;
36133
36178
  const { TERM, TERM_PROGRAM } = env;
36134
- if (N.platform !== "win32") return TERM !== "linux";
36179
+ if (process$1.platform !== "win32") return TERM !== "linux";
36135
36180
  return Boolean(env.WT_SESSION) || Boolean(env.TERMINUS_SUBLIME) || env.ConEmuTask === "{cmd::Cmder}" || TERM_PROGRAM === "Terminus-Sublime" || TERM_PROGRAM === "vscode" || TERM === "xterm-256color" || TERM === "alacritty" || TERM === "rxvt-unicode" || TERM === "rxvt-unicode-256color" || env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
36136
36181
  }
36137
36182
  //#endregion
@@ -37024,7 +37069,7 @@ function traversePathUp(startPath) {
37024
37069
  }
37025
37070
  //#endregion
37026
37071
  //#region ../../node_modules/.pnpm/npm-run-path@6.0.0/node_modules/npm-run-path/index.js
37027
- const npmRunPath = ({ cwd = N.cwd(), path: pathOption = N.env[pathKey()], preferLocal = true, execPath = N.execPath, addExecPath = true } = {}) => {
37072
+ const npmRunPath = ({ cwd = process$1.cwd(), path: pathOption = process$1.env[pathKey()], preferLocal = true, execPath = process$1.execPath, addExecPath = true } = {}) => {
37028
37073
  const cwdPath = path$1.resolve(toPath$2(cwd));
37029
37074
  const result = [];
37030
37075
  const pathParts = pathOption.split(path$1.delimiter);
@@ -37042,7 +37087,7 @@ const applyExecPath = (result, pathParts, execPath, cwdPath) => {
37042
37087
  const pathPart = path$1.resolve(cwdPath, toPath$2(execPath), "..");
37043
37088
  if (!pathParts.includes(pathPart)) result.push(pathPart);
37044
37089
  };
37045
- const npmRunPathEnv = ({ env = N.env, ...options } = {}) => {
37090
+ const npmRunPathEnv = ({ env = process$1.env, ...options } = {}) => {
37046
37091
  env = { ...env };
37047
37092
  const pathName = pathKey({ env });
37048
37093
  options.path = env[pathName];
@@ -38149,7 +38194,7 @@ const normalizeCwd = (cwd = getDefaultCwd()) => {
38149
38194
  };
38150
38195
  const getDefaultCwd = () => {
38151
38196
  try {
38152
- return N.cwd();
38197
+ return process$1.cwd();
38153
38198
  } catch (error) {
38154
38199
  error.message = `The current directory does not exist.\n${error.message}`;
38155
38200
  throw error;
@@ -38183,7 +38228,7 @@ const normalizeOptions = (filePath, rawArguments, rawOptions) => {
38183
38228
  options.killSignal = normalizeKillSignal(options.killSignal);
38184
38229
  options.forceKillAfterDelay = normalizeForceKillAfterDelay(options.forceKillAfterDelay);
38185
38230
  options.lines = options.lines.map((lines, fdNumber) => lines && !BINARY_ENCODINGS.has(options.encoding) && options.buffer[fdNumber]);
38186
- if (N.platform === "win32" && path$1.basename(file, ".exe") === "cmd") commandArguments.unshift("/q");
38231
+ if (process$1.platform === "win32" && path$1.basename(file, ".exe") === "cmd") commandArguments.unshift("/q");
38187
38232
  return {
38188
38233
  file,
38189
38234
  commandArguments,
@@ -38210,7 +38255,7 @@ const addDefaultOptions = ({ extendEnv = true, preferLocal = false, cwd, localDi
38210
38255
  });
38211
38256
  const getEnv = ({ env: envOption, extendEnv, preferLocal, node, localDirectory, nodePath }) => {
38212
38257
  const env = extendEnv ? {
38213
- ...N.env,
38258
+ ...process$1.env,
38214
38259
  ...envOption
38215
38260
  } : envOption;
38216
38261
  if (preferLocal || node) return npmRunPathEnv({
@@ -39177,12 +39222,12 @@ const guessStreamDirection = {
39177
39222
  }
39178
39223
  };
39179
39224
  const getStandardStreamDirection = (value) => {
39180
- if ([0, N.stdin].includes(value)) return "input";
39225
+ if ([0, process$1.stdin].includes(value)) return "input";
39181
39226
  if ([
39182
39227
  1,
39183
39228
  2,
39184
- N.stdout,
39185
- N.stderr
39229
+ process$1.stdout,
39230
+ process$1.stderr
39186
39231
  ].includes(value)) return "output";
39187
39232
  };
39188
39233
  const DEFAULT_DIRECTION = "output";
@@ -40222,9 +40267,9 @@ const addIpcMethods = (subprocess, { ipc }) => {
40222
40267
  Object.assign(subprocess, getIpcMethods(subprocess, false, ipc));
40223
40268
  };
40224
40269
  const getIpcExport = () => {
40225
- const anyProcess = N;
40270
+ const anyProcess = process$1;
40226
40271
  const isSubprocess = true;
40227
- const ipc = N.channel !== void 0;
40272
+ const ipc = process$1.channel !== void 0;
40228
40273
  return {
40229
40274
  ...getIpcMethods(anyProcess, isSubprocess, ipc),
40230
40275
  getCancelSignal: getCancelSignal$1.bind(void 0, {
@@ -40694,7 +40739,7 @@ var SignalExitFallback = class extends SignalExitBase {
40694
40739
  };
40695
40740
  var SignalExit = class extends SignalExitBase {
40696
40741
  /* c8 ignore start */
40697
- #hupSig = process$1.platform === "win32" ? "SIGINT" : "SIGHUP";
40742
+ #hupSig = process$2.platform === "win32" ? "SIGINT" : "SIGHUP";
40698
40743
  /* c8 ignore stop */
40699
40744
  #emitter = new Emitter();
40700
40745
  #process;
@@ -40789,8 +40834,8 @@ var SignalExit = class extends SignalExitBase {
40789
40834
  } else return og.call(this.#process, ev, ...args);
40790
40835
  }
40791
40836
  };
40792
- const process$1 = globalThis.process;
40793
- const { onExit, load, unload } = signalExitWrap(processOk(process$1) ? new SignalExit(process$1) : new SignalExitFallback());
40837
+ const process$2 = globalThis.process;
40838
+ const { onExit, load, unload } = signalExitWrap(processOk(process$2) ? new SignalExit(process$2) : new SignalExitFallback());
40794
40839
  //#endregion
40795
40840
  //#region ../../node_modules/.pnpm/execa@9.5.2/node_modules/execa/lib/terminate/cleanup.js
40796
40841
  const cleanupOnExit = (subprocess, { cleanup, detached }, { signal }) => {
@@ -42002,7 +42047,7 @@ const { sendMessage, getOneMessage, getEachMessage, getCancelSignal } = getIpcEx
42002
42047
  //#endregion
42003
42048
  //#region ../../node_modules/.pnpm/find-up-simple@1.0.1/node_modules/find-up-simple/index.js
42004
42049
  const toPath$1 = (urlOrPath) => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;
42005
- async function findUp(name, { cwd = N.cwd(), type = "file", stopAt } = {}) {
42050
+ async function findUp(name, { cwd = process$1.cwd(), type = "file", stopAt } = {}) {
42006
42051
  let directory = path$1.resolve(toPath$1(cwd) ?? "");
42007
42052
  const { root } = path$1.parse(directory);
42008
42053
  stopAt = path$1.resolve(directory, toPath$1(stopAt ?? root));
@@ -42010,7 +42055,7 @@ async function findUp(name, { cwd = N.cwd(), type = "file", stopAt } = {}) {
42010
42055
  while (directory) {
42011
42056
  const filePath = isAbsoluteName ? name : path$1.join(directory, name);
42012
42057
  try {
42013
- const stats = await fsp.stat(filePath);
42058
+ const stats = await fsPromises.stat(filePath);
42014
42059
  if (type === "file" && stats.isFile() || type === "directory" && stats.isDirectory()) return filePath;
42015
42060
  } catch {}
42016
42061
  if (directory === stopAt || directory === root) break;
@@ -47079,7 +47124,7 @@ const _readPackage = (file, normalize) => {
47079
47124
  return json;
47080
47125
  };
47081
47126
  async function readPackage({ cwd, normalize = true } = {}) {
47082
- return _readPackage(await fsp.readFile(getPackagePath(cwd), "utf8"), normalize);
47127
+ return _readPackage(await fsPromises.readFile(getPackagePath(cwd), "utf8"), normalize);
47083
47128
  }
47084
47129
  //#endregion
47085
47130
  //#region ../../node_modules/.pnpm/read-package-up@11.0.0/node_modules/read-package-up/index.js
@@ -47538,6 +47583,363 @@ const getReactNativeMetadatas = (cwd) => {
47538
47583
  }
47539
47584
  };
47540
47585
  //#endregion
47586
+ //#region src/hotUpdaterConfig.ts
47587
+ const HOT_UPDATER_CONFIG_PATH = "hot-updater.config.ts";
47588
+ const WRAP_PREFIX = "const __hotUpdaterValue = ";
47589
+ const WRAP_SUFFIX = ";";
47590
+ const MANAGED_IMPORT_PACKAGES = new Set([
47591
+ "dotenv",
47592
+ "firebase-admin",
47593
+ "hot-updater",
47594
+ "@aws-sdk/credential-provider-sso",
47595
+ "@hot-updater/aws",
47596
+ "@hot-updater/bare",
47597
+ "@hot-updater/cloudflare",
47598
+ "@hot-updater/expo",
47599
+ "@hot-updater/firebase",
47600
+ "@hot-updater/rock",
47601
+ "@hot-updater/supabase"
47602
+ ]);
47603
+ const MANAGED_HELPER_NAMES = new Set(["commonOptions", "credential"]);
47604
+ const KNOWN_BUILD_CALLEES = new Set([
47605
+ "bare",
47606
+ "expo",
47607
+ "rock"
47608
+ ]);
47609
+ const createSnippetSourceFile = (code) => ts.createSourceFile("hot-updater-config-snippet.ts", code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
47610
+ const extractCallIdentifier = (initializer) => {
47611
+ const match = /^\s*([A-Za-z_$][\w$]*)\s*\(/.exec(initializer);
47612
+ if (!match) throw new Error(`Failed to extract call identifier from "${initializer}"`);
47613
+ return match[1];
47614
+ };
47615
+ const wrapExpression = (expression) => `${WRAP_PREFIX}${expression}${WRAP_SUFFIX}`;
47616
+ const getWrappedObjectLiteral = (text) => {
47617
+ const sourceFile = createSnippetSourceFile(wrapExpression(text));
47618
+ const statement = sourceFile.statements[0];
47619
+ if (!statement || !ts.isVariableStatement(statement)) return null;
47620
+ const declaration = statement.declarationList.declarations[0];
47621
+ if (!declaration || !declaration.initializer) return null;
47622
+ if (!ts.isObjectLiteralExpression(declaration.initializer)) return null;
47623
+ return {
47624
+ sourceFile,
47625
+ objectLiteral: declaration.initializer,
47626
+ offset: 26
47627
+ };
47628
+ };
47629
+ const parseVariableStatement = (code) => {
47630
+ const sourceFile = createSnippetSourceFile(code);
47631
+ const statement = sourceFile.statements.find((node) => ts.isVariableStatement(node));
47632
+ if (!statement || !ts.isVariableStatement(statement)) return null;
47633
+ const declaration = statement.declarationList.declarations[0];
47634
+ if (!declaration || !ts.isIdentifier(declaration.name) || !declaration.initializer) return null;
47635
+ return {
47636
+ sourceFile,
47637
+ statement,
47638
+ declaration
47639
+ };
47640
+ };
47641
+ const getPropertyName = (property) => {
47642
+ if (ts.isIdentifier(property) || ts.isStringLiteral(property) || ts.isNumericLiteral(property)) return property.text;
47643
+ if (ts.isSpreadAssignment(property)) return null;
47644
+ if (ts.isShorthandPropertyAssignment(property)) return property.name.text;
47645
+ if (ts.isPropertyAssignment(property) || ts.isMethodDeclaration(property) || ts.isGetAccessorDeclaration(property) || ts.isSetAccessorDeclaration(property)) {
47646
+ const { name } = property;
47647
+ if (ts.isIdentifier(name) || ts.isStringLiteral(name)) return name.text;
47648
+ if (ts.isNumericLiteral(name)) return name.text;
47649
+ }
47650
+ return null;
47651
+ };
47652
+ const trimStatementText = (text) => text.trim();
47653
+ const getStatementText = (sourceText, statement) => trimStatementText(sourceText.slice(statement.getFullStart(), statement.end));
47654
+ const getObjectTrailingComma = (text) => {
47655
+ const closeBraceIndex = text.lastIndexOf("}");
47656
+ if (closeBraceIndex === -1) return false;
47657
+ let index = closeBraceIndex - 1;
47658
+ while (index >= 0 && /\s/.test(text[index] ?? "")) index -= 1;
47659
+ return (text[index] ?? "") === ",";
47660
+ };
47661
+ const dedentBlock = (text) => {
47662
+ const lines = text.replace(/\s+$/, "").split("\n");
47663
+ const indents = lines.filter((line) => line.trim() !== "").map((line) => line.match(/^\s*/)[0].length);
47664
+ const minIndent = indents.length > 0 ? Math.min(...indents) : 0;
47665
+ return lines.map((line) => line.slice(minIndent)).join("\n");
47666
+ };
47667
+ const indentBlock = (text, indent) => dedentBlock(text).split("\n").map((line) => `${indent}${line}`).join("\n");
47668
+ const appendMissingProperties = (objectText, propertyTexts, hasExistingProperties) => {
47669
+ if (propertyTexts.length === 0) return objectText;
47670
+ const closingIndent = /\n([ \t]*)\}$/.exec(objectText)?.[1] ?? "";
47671
+ const childIndent = objectText.match(/\n([ \t]+)[^\s]/)?.[1] ?? `${closingIndent} `;
47672
+ const formattedProperties = propertyTexts.map((propertyText) => indentBlock(propertyText, childIndent)).join(",\n");
47673
+ const closeBraceIndex = objectText.lastIndexOf("}");
47674
+ if (closeBraceIndex === -1) return objectText;
47675
+ const prefix = hasExistingProperties ? getObjectTrailingComma(objectText) ? "\n" : ",\n" : "\n";
47676
+ const suffix = `,\n${closingIndent}`;
47677
+ return `${objectText.slice(0, closeBraceIndex)}${prefix}${formattedProperties}${suffix}${objectText.slice(closeBraceIndex)}`;
47678
+ };
47679
+ const mergeObjectLiteralText = (existingText, newText) => {
47680
+ const existingWrapped = getWrappedObjectLiteral(existingText);
47681
+ const newWrapped = getWrappedObjectLiteral(newText);
47682
+ if (!existingWrapped || !newWrapped) return null;
47683
+ const existingPropertyNames = /* @__PURE__ */ new Set();
47684
+ const existingSpreadTexts = /* @__PURE__ */ new Set();
47685
+ const edits = [];
47686
+ for (const property of existingWrapped.objectLiteral.properties) {
47687
+ if (ts.isSpreadAssignment(property)) {
47688
+ existingSpreadTexts.add(property.expression.getText(existingWrapped.sourceFile).trim());
47689
+ continue;
47690
+ }
47691
+ const propertyName = getPropertyName(property);
47692
+ if (!propertyName) continue;
47693
+ existingPropertyNames.add(propertyName);
47694
+ const nextProperty = newWrapped.objectLiteral.properties.find((candidate) => {
47695
+ if (ts.isSpreadAssignment(candidate)) return false;
47696
+ return getPropertyName(candidate) === propertyName;
47697
+ });
47698
+ if (!nextProperty || !ts.isPropertyAssignment(property) || !ts.isPropertyAssignment(nextProperty)) continue;
47699
+ if (ts.isObjectLiteralExpression(property.initializer) && ts.isObjectLiteralExpression(nextProperty.initializer)) {
47700
+ const mergedInitializer = mergeObjectLiteralText(property.initializer.getText(existingWrapped.sourceFile), nextProperty.initializer.getText(newWrapped.sourceFile));
47701
+ if (!mergedInitializer) return null;
47702
+ edits.push({
47703
+ start: property.initializer.getStart(existingWrapped.sourceFile) - existingWrapped.offset,
47704
+ end: property.initializer.end - existingWrapped.offset,
47705
+ text: mergedInitializer
47706
+ });
47707
+ }
47708
+ }
47709
+ let mergedText = existingText;
47710
+ for (const edit of edits.sort((a, b) => b.start - a.start)) mergedText = mergedText.slice(0, edit.start) + edit.text + mergedText.slice(edit.end);
47711
+ const missingPropertyTexts = newWrapped.objectLiteral.properties.filter((property) => {
47712
+ if (ts.isSpreadAssignment(property)) return !existingSpreadTexts.has(property.expression.getText(newWrapped.sourceFile).trim());
47713
+ const propertyName = getPropertyName(property);
47714
+ return propertyName ? !existingPropertyNames.has(propertyName) : false;
47715
+ }).map((property) => property.getText(newWrapped.sourceFile));
47716
+ return appendMissingProperties(mergedText, missingPropertyTexts, existingWrapped.objectLiteral.properties.length > 0);
47717
+ };
47718
+ const buildMergedCallInitializer = (existingCall, existingSourceFile, newCall, newSourceFile) => {
47719
+ const existingCallee = existingCall.expression.getText(existingSourceFile);
47720
+ const [existingArg] = existingCall.arguments;
47721
+ const [newArg] = newCall.arguments;
47722
+ if (existingCall.arguments.length === 1 && newCall.arguments.length === 1 && existingArg && newArg && ts.isObjectLiteralExpression(existingArg) && ts.isObjectLiteralExpression(newArg)) {
47723
+ const mergedObjectLiteral = mergeObjectLiteralText(existingArg.getText(existingSourceFile), newArg.getText(newSourceFile));
47724
+ if (!mergedObjectLiteral) return null;
47725
+ return `${existingCallee}(${mergedObjectLiteral})`;
47726
+ }
47727
+ return existingCall.getText(existingSourceFile);
47728
+ };
47729
+ const findDefineConfigObject = (sourceFile) => {
47730
+ const exportAssignment = sourceFile.statements.find((statement) => {
47731
+ if (!ts.isExportAssignment(statement)) return false;
47732
+ const expression = statement.expression;
47733
+ if (!ts.isCallExpression(expression)) return false;
47734
+ return ts.isIdentifier(expression.expression) && expression.expression.text === "defineConfig" && expression.arguments.length > 0 && ts.isObjectLiteralExpression(expression.arguments[0]);
47735
+ });
47736
+ if (!exportAssignment || !ts.isExportAssignment(exportAssignment)) return null;
47737
+ const expression = exportAssignment.expression;
47738
+ if (!ts.isCallExpression(expression)) return null;
47739
+ const [argument] = expression.arguments;
47740
+ if (!argument || !ts.isObjectLiteralExpression(argument)) return null;
47741
+ return {
47742
+ exportAssignment,
47743
+ objectLiteral: argument
47744
+ };
47745
+ };
47746
+ const findManagedProperty = (objectLiteral, propertyName) => objectLiteral.properties.find((property) => ts.isPropertyAssignment(property) && getPropertyName(property.name) === propertyName);
47747
+ const getCallCallee = (expression) => {
47748
+ if (!ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression)) return null;
47749
+ return expression.expression.text;
47750
+ };
47751
+ const isConfigCallStatement = (statement) => ts.isExpressionStatement(statement) && ts.isCallExpression(statement.expression) && ts.isIdentifier(statement.expression.expression) && statement.expression.expression.text === "config";
47752
+ const isManagedHelperStatement = (statement) => {
47753
+ if (!ts.isVariableStatement(statement)) return null;
47754
+ const declaration = statement.declarationList.declarations[0];
47755
+ if (!declaration || !ts.isIdentifier(declaration.name)) return null;
47756
+ return MANAGED_HELPER_NAMES.has(declaration.name.text) ? declaration.name.text : null;
47757
+ };
47758
+ const mergeHelperStatement = (existingStatementText, helper) => {
47759
+ if (helper.strategy === "preserve-existing") return existingStatementText;
47760
+ if (helper.strategy === "replace") return helper.code.trim();
47761
+ const existingStatement = parseVariableStatement(existingStatementText);
47762
+ const nextStatement = parseVariableStatement(helper.code);
47763
+ if (!existingStatement || !nextStatement) return null;
47764
+ const existingInitializer = existingStatement.declaration.initializer;
47765
+ const newInitializer = nextStatement.declaration.initializer;
47766
+ if (!existingInitializer || !newInitializer || !ts.isObjectLiteralExpression(existingInitializer) || !ts.isObjectLiteralExpression(newInitializer)) return null;
47767
+ const mergedInitializer = mergeObjectLiteralText(existingInitializer.getText(existingStatement.sourceFile), newInitializer.getText(nextStatement.sourceFile));
47768
+ if (!mergedInitializer) return null;
47769
+ return `${ts.tokenToString(existingStatement.statement.declarationList.flags & ts.NodeFlags.Const ? ts.SyntaxKind.ConstKeyword : existingStatement.statement.declarationList.flags & ts.NodeFlags.Let ? ts.SyntaxKind.LetKeyword : ts.SyntaxKind.VarKeyword) ?? "const"} ${helper.name} = ${mergedInitializer};`;
47770
+ };
47771
+ const updateManagedObject = (existingText, existingObject, newObject, existingSourceFile, newSourceFile) => {
47772
+ const objectStart = existingObject.getStart(existingSourceFile);
47773
+ const objectText = existingText.slice(objectStart, existingObject.end);
47774
+ const propertyEdits = [];
47775
+ const missingPropertyTexts = [];
47776
+ for (const propertyName of [
47777
+ "build",
47778
+ "storage",
47779
+ "database"
47780
+ ]) {
47781
+ const existingProperty = findManagedProperty(existingObject, propertyName);
47782
+ const nextProperty = findManagedProperty(newObject, propertyName);
47783
+ if (!nextProperty) continue;
47784
+ if (!existingProperty) {
47785
+ missingPropertyTexts.push(nextProperty.getText(newSourceFile));
47786
+ continue;
47787
+ }
47788
+ if (!ts.isCallExpression(existingProperty.initializer)) return null;
47789
+ if (!ts.isCallExpression(nextProperty.initializer)) return null;
47790
+ const existingCallee = getCallCallee(existingProperty.initializer);
47791
+ const nextCallee = getCallCallee(nextProperty.initializer);
47792
+ if (!existingCallee || !nextCallee) return null;
47793
+ let nextInitializerText = nextProperty.initializer.getText(newSourceFile);
47794
+ if (propertyName === "build") {
47795
+ if (existingCallee === nextCallee) continue;
47796
+ if (!KNOWN_BUILD_CALLEES.has(existingCallee)) return null;
47797
+ } else if (existingCallee === nextCallee) {
47798
+ const mergedInitializer = buildMergedCallInitializer(existingProperty.initializer, existingSourceFile, nextProperty.initializer, newSourceFile);
47799
+ if (mergedInitializer === null) return null;
47800
+ nextInitializerText = mergedInitializer;
47801
+ }
47802
+ propertyEdits.push({
47803
+ start: existingProperty.initializer.getStart(existingSourceFile) - objectStart,
47804
+ end: existingProperty.initializer.end - objectStart,
47805
+ text: nextInitializerText
47806
+ });
47807
+ }
47808
+ let mergedText = objectText;
47809
+ for (const edit of propertyEdits.sort((a, b) => b.start - a.start)) mergedText = mergedText.slice(0, edit.start) + edit.text + mergedText.slice(edit.end);
47810
+ return appendMissingProperties(mergedText, missingPropertyTexts, existingObject.properties.length > 0);
47811
+ };
47812
+ const rebuildImportBlock = (sourceText, sourceFile, scaffold) => {
47813
+ const importDeclarations = sourceFile.statements.filter(ts.isImportDeclaration);
47814
+ if (importDeclarations.length === 0) return {
47815
+ start: 0,
47816
+ end: 0,
47817
+ text: `${renderImportStatements(scaffold.imports)}\n\n`
47818
+ };
47819
+ const preservedImportTexts = importDeclarations.filter((declaration) => {
47820
+ const moduleSpecifier = declaration.moduleSpecifier;
47821
+ return ts.isStringLiteral(moduleSpecifier) && !MANAGED_IMPORT_PACKAGES.has(moduleSpecifier.text);
47822
+ }).map((declaration) => trimStatementText(sourceText.slice(declaration.getFullStart(), declaration.end)));
47823
+ const managedImportText = renderImportStatements(scaffold.imports);
47824
+ const nextImportBlock = [...preservedImportTexts, managedImportText].filter(Boolean).join("\n");
47825
+ return {
47826
+ start: importDeclarations[0].getFullStart(),
47827
+ end: importDeclarations.at(-1).end,
47828
+ text: `${nextImportBlock}\n\n`
47829
+ };
47830
+ };
47831
+ const rebuildManagedBody = (sourceText, sourceFile, exportAssignment, scaffold) => {
47832
+ const statementsBeforeExport = sourceFile.statements.filter((statement) => !ts.isImportDeclaration(statement) && statement.pos < exportAssignment.pos);
47833
+ const managedHelpers = new Map(scaffold.helperStatements.map((statement) => [statement.name, statement]));
47834
+ const emittedHelpers = /* @__PURE__ */ new Set();
47835
+ const bodyStatements = [];
47836
+ for (const statement of statementsBeforeExport) {
47837
+ if (isConfigCallStatement(statement)) continue;
47838
+ const helperName = isManagedHelperStatement(statement);
47839
+ if (!helperName) {
47840
+ bodyStatements.push(getStatementText(sourceText, statement));
47841
+ continue;
47842
+ }
47843
+ const helper = managedHelpers.get(helperName);
47844
+ if (!helper) continue;
47845
+ const mergedHelperStatement = mergeHelperStatement(getStatementText(sourceText, statement), helper);
47846
+ if (!mergedHelperStatement) return null;
47847
+ emittedHelpers.add(helperName);
47848
+ bodyStatements.push(mergedHelperStatement);
47849
+ }
47850
+ for (const helper of scaffold.helperStatements) if (!emittedHelpers.has(helper.name)) bodyStatements.push(helper.code.trim());
47851
+ const bodyText = bodyStatements.filter(Boolean).join("\n\n");
47852
+ const configStatement = `config({ path: ".env.hotupdater" });`;
47853
+ const managedBody = bodyText ? `\n\n${configStatement}\n\n${bodyText}\n\n` : `\n\n${configStatement}\n\n`;
47854
+ return {
47855
+ start: sourceFile.statements.filter(ts.isImportDeclaration).at(-1)?.end ?? 0,
47856
+ end: exportAssignment.getFullStart(),
47857
+ text: managedBody
47858
+ };
47859
+ };
47860
+ const createHotUpdaterConfigScaffold = ({ build, storage, database, extraImports = [], helperStatements = [], updateStrategy = "appVersion" }) => {
47861
+ const intermediateCode = helperStatements.map((statement) => statement.code.trim()).filter(Boolean).join("\n\n");
47862
+ const builder = new ConfigBuilder().setBuildType(build).setStorage(storage).setDatabase(database);
47863
+ for (const extraImport of extraImports) builder.addImport(extraImport);
47864
+ if (intermediateCode) builder.setIntermediateCode(intermediateCode);
47865
+ return createHotUpdaterConfigScaffoldFromBuilder(builder, {
47866
+ helperStatements,
47867
+ updateStrategy
47868
+ });
47869
+ };
47870
+ const createHotUpdaterConfigScaffoldFromBuilder = (builder, { helperStatements = [], updateStrategy = "appVersion" } = {}) => {
47871
+ const scaffold = builder.getScaffold();
47872
+ return {
47873
+ text: updateStrategy === "appVersion" ? scaffold.text : scaffold.text.replace("updateStrategy: \"appVersion\"", `updateStrategy: "${updateStrategy}"`),
47874
+ imports: scaffold.imports,
47875
+ build: {
47876
+ initializer: scaffold.buildConfigString,
47877
+ callee: extractCallIdentifier(scaffold.buildConfigString)
47878
+ },
47879
+ storage: {
47880
+ initializer: scaffold.storageConfigString,
47881
+ callee: extractCallIdentifier(scaffold.storageConfigString)
47882
+ },
47883
+ database: {
47884
+ initializer: scaffold.databaseConfigString,
47885
+ callee: extractCallIdentifier(scaffold.databaseConfigString)
47886
+ },
47887
+ helperStatements,
47888
+ updateStrategy: `"${updateStrategy}"`
47889
+ };
47890
+ };
47891
+ const writeHotUpdaterConfig = async (scaffold, filePath = HOT_UPDATER_CONFIG_PATH) => {
47892
+ const existingText = await fs$1.readFile(filePath, "utf-8").catch((error) => {
47893
+ if (error.code === "ENOENT") return null;
47894
+ throw error;
47895
+ });
47896
+ if (existingText === null) {
47897
+ await fs$1.writeFile(filePath, `${scaffold.text}\n`, "utf-8");
47898
+ return {
47899
+ status: "created",
47900
+ path: filePath
47901
+ };
47902
+ }
47903
+ const existingSourceFile = createSnippetSourceFile(existingText);
47904
+ const existingConfig = findDefineConfigObject(existingSourceFile);
47905
+ const nextSourceFile = createSnippetSourceFile(scaffold.text);
47906
+ const nextConfig = findDefineConfigObject(nextSourceFile);
47907
+ if (!existingConfig || !nextConfig) return {
47908
+ status: "skipped",
47909
+ path: filePath,
47910
+ reason: "Existing config is not a supported `export default defineConfig({ ... })` shape."
47911
+ };
47912
+ const nextObjectText = updateManagedObject(existingText, existingConfig.objectLiteral, nextConfig.objectLiteral, existingSourceFile, nextSourceFile);
47913
+ if (!nextObjectText) return {
47914
+ status: "skipped",
47915
+ path: filePath,
47916
+ reason: "Existing config uses dynamic build/storage/database expressions that cannot be merged safely."
47917
+ };
47918
+ const objectEdit = {
47919
+ start: existingConfig.objectLiteral.getStart(existingSourceFile),
47920
+ end: existingConfig.objectLiteral.end,
47921
+ text: nextObjectText
47922
+ };
47923
+ const importEdit = rebuildImportBlock(existingText, existingSourceFile, scaffold);
47924
+ const bodyEdit = rebuildManagedBody(existingText, existingSourceFile, existingConfig.exportAssignment, scaffold);
47925
+ if (!bodyEdit) return {
47926
+ status: "skipped",
47927
+ path: filePath,
47928
+ reason: "Existing helper declarations could not be merged safely."
47929
+ };
47930
+ let mergedText = existingText;
47931
+ for (const edit of [
47932
+ objectEdit,
47933
+ bodyEdit,
47934
+ importEdit
47935
+ ].sort((a, b) => b.start - a.start)) mergedText = mergedText.slice(0, edit.start) + edit.text + mergedText.slice(edit.end);
47936
+ await fs$1.writeFile(filePath, mergedText, "utf-8");
47937
+ return {
47938
+ status: "merged",
47939
+ path: filePath
47940
+ };
47941
+ };
47942
+ //#endregion
47541
47943
  //#region ../../node_modules/.pnpm/es-toolkit@1.32.0/node_modules/es-toolkit/dist/predicate/isPlainObject.mjs
47542
47944
  function isPlainObject(value) {
47543
47945
  if (!value || typeof value !== "object") return false;
@@ -47659,8 +48061,9 @@ const log = {
47659
48061
  };
47660
48062
  //#endregion
47661
48063
  //#region src/makeEnv.ts
47662
- const makeEnv = async (newEnvVars, filePath = ".env.hotupdater") => {
48064
+ const makeEnv = async (newEnvVars, filePath = ".env.hotupdater", options) => {
47663
48065
  try {
48066
+ const preserveKeys = new Set(options?.preserveKeys ?? []);
47664
48067
  const existingContent = await fs$1.readFile(filePath, "utf-8").catch(() => "");
47665
48068
  const lines = existingContent ? existingContent.split("\n") : [];
47666
48069
  const processedKeys = /* @__PURE__ */ new Set();
@@ -47677,7 +48080,7 @@ const makeEnv = async (newEnvVars, filePath = ".env.hotupdater") => {
47677
48080
  const nextLine = (lines[i + 1] ?? "").trim();
47678
48081
  if (nextLine && !nextLine.startsWith("#") && nextLine.includes("=")) {
47679
48082
  const [possibleKey = ""] = nextLine.split("=");
47680
- if (Object.hasOwn(newEnvVars, possibleKey.trim())) continue;
48083
+ if (Object.hasOwn(newEnvVars, possibleKey.trim()) && !preserveKeys.has(possibleKey.trim())) continue;
47681
48084
  }
47682
48085
  }
47683
48086
  updatedLines.push(line);
@@ -47688,6 +48091,10 @@ const makeEnv = async (newEnvVars, filePath = ".env.hotupdater") => {
47688
48091
  const key = keyPart?.trim() ?? "";
47689
48092
  if (Object.hasOwn(newEnvVars, key)) {
47690
48093
  processedKeys.add(key);
48094
+ if (preserveKeys.has(key)) {
48095
+ updatedLines.push(line);
48096
+ continue;
48097
+ }
47691
48098
  const newValue = newEnvVars[key];
47692
48099
  if (typeof newValue === "object" && newValue !== null) {
47693
48100
  updatedLines.push(`# ${newValue.comment}`);
@@ -47775,4 +48182,4 @@ function transformTemplate(templateString, values) {
47775
48182
  }
47776
48183
  //#endregion
47777
48184
  var colors = import_picocolors.default;
47778
- export { BuildLogger, ConfigBuilder, HOT_UPDATER_SERVER_PACKAGE_VERSION_ENV, HotUpdateDirUtil, banner, colors, copyDirToTmp, createLogWriter, createTarBr, createTarBrTargetFiles, createTarGz, createTarGzTargetFiles, createZip, createZipTargetFiles, decryptJson, encryptJson, ensureInstallPackages, getAndroidSdkPath, getCwd, getPackageManager, getReactNativeMetadatas, link, loadConfig, log, makeEnv, dist_exports as p, printBanner, resolveHotUpdaterServerVersion, resolvePackageVersion, stripAnsi, transformEnv, transformTemplate };
48185
+ export { BuildLogger, ConfigBuilder, HOT_UPDATER_SERVER_PACKAGE_VERSION_ENV, HotUpdateDirUtil, banner, colors, copyDirToTmp, createHotUpdaterConfigScaffold, createHotUpdaterConfigScaffoldFromBuilder, createLogWriter, createTarBr, createTarBrTargetFiles, createTarGz, createTarGzTargetFiles, createZip, createZipTargetFiles, decryptJson, encryptJson, ensureInstallPackages, getAndroidSdkPath, getCwd, getPackageManager, getReactNativeMetadatas, link, loadConfig, log, makeEnv, dist_exports as p, printBanner, renderImportStatements, resolveHotUpdaterServerVersion, resolvePackageVersion, stripAnsi, transformEnv, transformTemplate, writeHotUpdaterConfig };