@actual-app/cli 26.5.0 → 26.6.0-nightly.20260504

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.
Files changed (4) hide show
  1. package/README.md +38 -16
  2. package/dist/cli.js +1811 -135
  3. package/dist/stats.json +1721 -1112
  4. package/package.json +7 -3
package/dist/cli.js CHANGED
@@ -1,9 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module";
3
+ import { join } from "node:path";
4
+ import { mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
3
5
  import * as api from "@actual-app/api";
4
- import { mkdirSync, readFileSync } from "fs";
6
+ import { randomBytes } from "node:crypto";
5
7
  import { homedir } from "os";
6
- import { join } from "path";
8
+ import { join as join$1 } from "path";
9
+ import { readFileSync as readFileSync$1 } from "fs";
7
10
  //#region \0rolldown/runtime.js
8
11
  var __create = Object.create;
9
12
  var __defProp = Object.defineProperty;
@@ -1044,8 +1047,8 @@ var require_suggestSimilar = /* @__PURE__ */ __commonJSMin(((exports) => {
1044
1047
  var require_command = /* @__PURE__ */ __commonJSMin(((exports) => {
1045
1048
  var EventEmitter = __require("node:events").EventEmitter;
1046
1049
  var childProcess = __require("node:child_process");
1047
- var path$4 = __require("node:path");
1048
- var fs$1 = __require("node:fs");
1050
+ var path$5 = __require("node:path");
1051
+ var fs$2 = __require("node:fs");
1049
1052
  var process$1 = __require("node:process");
1050
1053
  var { Argument, humanReadableArgName } = require_argument();
1051
1054
  var { CommanderError } = require_error();
@@ -1941,7 +1944,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1941
1944
  * @param {string} subcommandName
1942
1945
  */
1943
1946
  _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
1944
- if (fs$1.existsSync(executableFile)) return;
1947
+ if (fs$2.existsSync(executableFile)) return;
1945
1948
  const executableMissing = `'${executableFile}' does not exist
1946
1949
  - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
1947
1950
  - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
@@ -1964,10 +1967,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
1964
1967
  ".cjs"
1965
1968
  ];
1966
1969
  function findFile(baseDir, baseName) {
1967
- const localBin = path$4.resolve(baseDir, baseName);
1968
- if (fs$1.existsSync(localBin)) return localBin;
1969
- if (sourceExt.includes(path$4.extname(baseName))) return void 0;
1970
- const foundExt = sourceExt.find((ext) => fs$1.existsSync(`${localBin}${ext}`));
1970
+ const localBin = path$5.resolve(baseDir, baseName);
1971
+ if (fs$2.existsSync(localBin)) return localBin;
1972
+ if (sourceExt.includes(path$5.extname(baseName))) return void 0;
1973
+ const foundExt = sourceExt.find((ext) => fs$2.existsSync(`${localBin}${ext}`));
1971
1974
  if (foundExt) return `${localBin}${foundExt}`;
1972
1975
  }
1973
1976
  this._checkForMissingMandatoryOptions();
@@ -1977,21 +1980,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
1977
1980
  if (this._scriptPath) {
1978
1981
  let resolvedScriptPath;
1979
1982
  try {
1980
- resolvedScriptPath = fs$1.realpathSync(this._scriptPath);
1983
+ resolvedScriptPath = fs$2.realpathSync(this._scriptPath);
1981
1984
  } catch {
1982
1985
  resolvedScriptPath = this._scriptPath;
1983
1986
  }
1984
- executableDir = path$4.resolve(path$4.dirname(resolvedScriptPath), executableDir);
1987
+ executableDir = path$5.resolve(path$5.dirname(resolvedScriptPath), executableDir);
1985
1988
  }
1986
1989
  if (executableDir) {
1987
1990
  let localFile = findFile(executableDir, executableFile);
1988
1991
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
1989
- const legacyName = path$4.basename(this._scriptPath, path$4.extname(this._scriptPath));
1992
+ const legacyName = path$5.basename(this._scriptPath, path$5.extname(this._scriptPath));
1990
1993
  if (legacyName !== this._name) localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
1991
1994
  }
1992
1995
  executableFile = localFile || executableFile;
1993
1996
  }
1994
- launchWithNode = sourceExt.includes(path$4.extname(executableFile));
1997
+ launchWithNode = sourceExt.includes(path$5.extname(executableFile));
1995
1998
  let proc;
1996
1999
  if (process$1.platform !== "win32") if (launchWithNode) {
1997
2000
  args.unshift(executableFile);
@@ -2759,7 +2762,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2759
2762
  * @return {Command}
2760
2763
  */
2761
2764
  nameFromFilename(filename) {
2762
- this._name = path$4.basename(filename, path$4.extname(filename));
2765
+ this._name = path$5.basename(filename, path$5.extname(filename));
2763
2766
  return this;
2764
2767
  }
2765
2768
  /**
@@ -3039,22 +3042,108 @@ var { program: program$1, createCommand, createArgument, createOption, Commander
3039
3042
  exports.InvalidOptionArgumentError = InvalidArgumentError;
3040
3043
  })))(), 1)).default;
3041
3044
  //#endregion
3045
+ //#region src/utils.ts
3046
+ function isRecord(value) {
3047
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3048
+ }
3049
+ function parseBoolFlag(value, flagName) {
3050
+ if (value !== "true" && value !== "false") throw new Error(`Invalid ${flagName}: "${value}". Expected "true" or "false".`);
3051
+ return value === "true";
3052
+ }
3053
+ function parseIntFlag(value, flagName) {
3054
+ const parsed = value.trim() === "" ? NaN : Number(value);
3055
+ if (!Number.isInteger(parsed)) throw new Error(`Invalid ${flagName}: "${value}". Expected an integer.`);
3056
+ return parsed;
3057
+ }
3058
+ function parseNonNegativeIntFlag(value, flagName) {
3059
+ const parsed = parseIntFlag(value, flagName);
3060
+ if (parsed < 0) throw new Error(`Invalid ${flagName}: "${value}". Expected a non-negative integer.`);
3061
+ return parsed;
3062
+ }
3063
+ function parseBoolEnv(raw, source) {
3064
+ if (raw === void 0) return void 0;
3065
+ const lower = raw.toLowerCase();
3066
+ if (raw === "1" || lower === "true") return true;
3067
+ if (raw === "0" || lower === "false") return false;
3068
+ throw new Error(`Invalid ${source}: "${raw}". Expected "true", "false", "1", or "0".`);
3069
+ }
3070
+ //#endregion
3071
+ //#region src/cache.ts
3072
+ var CACHE_FILE_NAME = "state.json";
3073
+ var META_ROOT_DIR = ".actual-cli";
3074
+ function getMetaDir(dataDir, syncId) {
3075
+ return join(dataDir, META_ROOT_DIR, syncId);
3076
+ }
3077
+ function cachePath(metaDir) {
3078
+ return join(metaDir, CACHE_FILE_NAME);
3079
+ }
3080
+ function isCacheState(value) {
3081
+ if (!isRecord(value)) return false;
3082
+ return value.version === 1 && typeof value.syncId === "string" && typeof value.budgetId === "string" && typeof value.serverUrl === "string" && typeof value.lastSyncedAt === "number" && typeof value.lastDownloadedAt === "number";
3083
+ }
3084
+ function readCacheState(metaDir) {
3085
+ let raw;
3086
+ try {
3087
+ raw = readFileSync(cachePath(metaDir), "utf-8");
3088
+ } catch {
3089
+ return null;
3090
+ }
3091
+ let parsed;
3092
+ try {
3093
+ parsed = JSON.parse(raw);
3094
+ } catch {
3095
+ return null;
3096
+ }
3097
+ return isCacheState(parsed) ? parsed : null;
3098
+ }
3099
+ function writeCacheState(metaDir, state) {
3100
+ try {
3101
+ mkdirSync(metaDir, { recursive: true });
3102
+ const target = cachePath(metaDir);
3103
+ const tmp = `${target}.${process.pid}-${randomBytes(4).toString("hex")}.tmp`;
3104
+ writeFileSync(tmp, JSON.stringify(state));
3105
+ renameSync(tmp, target);
3106
+ } catch {}
3107
+ }
3108
+ function decideSyncAction({ state, config, now, ttlMs, mutates, refresh, encrypted }) {
3109
+ if (state === null) return { action: "download" };
3110
+ if (state.syncId !== config.syncId) return { action: "download" };
3111
+ if (state.serverUrl !== config.serverUrl) return { action: "download" };
3112
+ if (mutates || refresh || ttlMs === 0 || encrypted) return {
3113
+ action: "sync",
3114
+ state
3115
+ };
3116
+ const age = now - state.lastSyncedAt;
3117
+ if (age < 0) return {
3118
+ action: "sync",
3119
+ state
3120
+ };
3121
+ if (age < ttlMs) return {
3122
+ action: "skip",
3123
+ state
3124
+ };
3125
+ return {
3126
+ action: "sync",
3127
+ state
3128
+ };
3129
+ }
3130
+ //#endregion
3042
3131
  //#region ../../node_modules/resolve-from/index.js
3043
3132
  var require_resolve_from = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3044
- var path$3 = __require("path");
3133
+ var path$4 = __require("path");
3045
3134
  var Module = __require("module");
3046
- var fs = __require("fs");
3135
+ var fs$1 = __require("fs");
3047
3136
  var resolveFrom = (fromDir, moduleId, silent) => {
3048
3137
  if (typeof fromDir !== "string") throw new TypeError(`Expected \`fromDir\` to be of type \`string\`, got \`${typeof fromDir}\``);
3049
3138
  if (typeof moduleId !== "string") throw new TypeError(`Expected \`moduleId\` to be of type \`string\`, got \`${typeof moduleId}\``);
3050
3139
  try {
3051
- fromDir = fs.realpathSync(fromDir);
3140
+ fromDir = fs$1.realpathSync(fromDir);
3052
3141
  } catch (err) {
3053
- if (err.code === "ENOENT") fromDir = path$3.resolve(fromDir);
3142
+ if (err.code === "ENOENT") fromDir = path$4.resolve(fromDir);
3054
3143
  else if (silent) return null;
3055
3144
  else throw err;
3056
3145
  }
3057
- const fromFile = path$3.join(fromDir, "noop.js");
3146
+ const fromFile = path$4.join(fromDir, "noop.js");
3058
3147
  const resolveFileName = () => Module._resolveFilename(moduleId, {
3059
3148
  id: fromFile,
3060
3149
  filename: fromFile,
@@ -3107,13 +3196,13 @@ var require_parent_module = /* @__PURE__ */ __commonJSMin(((exports, module) =>
3107
3196
  //#endregion
3108
3197
  //#region ../../node_modules/import-fresh/index.js
3109
3198
  var require_import_fresh = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3110
- var path$2 = __require("path");
3199
+ var path$3 = __require("path");
3111
3200
  var resolveFrom = require_resolve_from();
3112
3201
  var parentModule = require_parent_module();
3113
3202
  module.exports = (moduleId) => {
3114
3203
  if (typeof moduleId !== "string") throw new TypeError("Expected a string");
3115
3204
  const parentPath = parentModule(__filename);
3116
- const filePath = resolveFrom(parentPath ? path$2.dirname(parentPath) : __dirname, moduleId);
3205
+ const filePath = resolveFrom(parentPath ? path$3.dirname(parentPath) : __dirname, moduleId);
3117
3206
  const oldModule = __require.cache[filePath];
3118
3207
  if (oldModule && oldModule.parent) {
3119
3208
  let i = oldModule.parent.children.length;
@@ -3135,7 +3224,7 @@ var require_is_arrayish = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3135
3224
  //#endregion
3136
3225
  //#region ../../node_modules/error-ex/index.js
3137
3226
  var require_error_ex = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3138
- var util$1 = __require("util");
3227
+ var util$2 = __require("util");
3139
3228
  var isArrayish = require_is_arrayish();
3140
3229
  var errorEx = function errorEx(name, properties) {
3141
3230
  if (!name || name.constructor !== String) {
@@ -3196,7 +3285,7 @@ var require_error_ex = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3196
3285
  if (Object.setPrototypeOf) {
3197
3286
  Object.setPrototypeOf(errorExError.prototype, Error.prototype);
3198
3287
  Object.setPrototypeOf(errorExError, Error);
3199
- } else util$1.inherits(errorExError, Error);
3288
+ } else util$2.inherits(errorExError, Error);
3200
3289
  return errorExError;
3201
3290
  };
3202
3291
  errorEx.append = function(str, def) {
@@ -8960,7 +9049,7 @@ var require_buffer_from = /* @__PURE__ */ __commonJSMin(((exports, module) => {
8960
9049
  //#region ../../node_modules/source-map-support/source-map-support.js
8961
9050
  var require_source_map_support = /* @__PURE__ */ __commonJSMin(((exports, module) => {
8962
9051
  var SourceMapConsumer = require_source_map().SourceMapConsumer;
8963
- var path$1 = __require("path");
9052
+ var path$2 = __require("path");
8964
9053
  var fs;
8965
9054
  try {
8966
9055
  fs = __require("fs");
@@ -9037,15 +9126,15 @@ var require_source_map_support = /* @__PURE__ */ __commonJSMin(((exports, module
9037
9126
  });
9038
9127
  function supportRelativeURL(file, url) {
9039
9128
  if (!file) return url;
9040
- var dir = path$1.dirname(file);
9129
+ var dir = path$2.dirname(file);
9041
9130
  var match = /^\w+:\/\/[^\/]*/.exec(dir);
9042
9131
  var protocol = match ? match[0] : "";
9043
9132
  var startPath = dir.slice(protocol.length);
9044
9133
  if (protocol && /^\/\w\:/.test(startPath)) {
9045
9134
  protocol += "/";
9046
- return protocol + path$1.resolve(dir.slice(protocol.length), url).replace(/\\/g, "/");
9135
+ return protocol + path$2.resolve(dir.slice(protocol.length), url).replace(/\\/g, "/");
9047
9136
  }
9048
- return protocol + path$1.resolve(dir.slice(protocol.length), url);
9137
+ return protocol + path$2.resolve(dir.slice(protocol.length), url);
9049
9138
  }
9050
9139
  function retrieveSourceMapURL(source) {
9051
9140
  var fileData;
@@ -157356,40 +157445,40 @@ var require_defaults = /* @__PURE__ */ __commonJSMin(((exports) => {
157356
157445
  //#endregion
157357
157446
  //#region ../../node_modules/env-paths/index.js
157358
157447
  var require_env_paths = /* @__PURE__ */ __commonJSMin(((exports, module) => {
157359
- var path = __require("path");
157448
+ var path$1 = __require("path");
157360
157449
  var os$1 = __require("os");
157361
157450
  var homedir = os$1.homedir();
157362
157451
  var tmpdir = os$1.tmpdir();
157363
157452
  var { env } = process;
157364
157453
  var macos = (name) => {
157365
- const library = path.join(homedir, "Library");
157454
+ const library = path$1.join(homedir, "Library");
157366
157455
  return {
157367
- data: path.join(library, "Application Support", name),
157368
- config: path.join(library, "Preferences", name),
157369
- cache: path.join(library, "Caches", name),
157370
- log: path.join(library, "Logs", name),
157371
- temp: path.join(tmpdir, name)
157456
+ data: path$1.join(library, "Application Support", name),
157457
+ config: path$1.join(library, "Preferences", name),
157458
+ cache: path$1.join(library, "Caches", name),
157459
+ log: path$1.join(library, "Logs", name),
157460
+ temp: path$1.join(tmpdir, name)
157372
157461
  };
157373
157462
  };
157374
157463
  var windows = (name) => {
157375
- const appData = env.APPDATA || path.join(homedir, "AppData", "Roaming");
157376
- const localAppData = env.LOCALAPPDATA || path.join(homedir, "AppData", "Local");
157464
+ const appData = env.APPDATA || path$1.join(homedir, "AppData", "Roaming");
157465
+ const localAppData = env.LOCALAPPDATA || path$1.join(homedir, "AppData", "Local");
157377
157466
  return {
157378
- data: path.join(localAppData, name, "Data"),
157379
- config: path.join(appData, name, "Config"),
157380
- cache: path.join(localAppData, name, "Cache"),
157381
- log: path.join(localAppData, name, "Log"),
157382
- temp: path.join(tmpdir, name)
157467
+ data: path$1.join(localAppData, name, "Data"),
157468
+ config: path$1.join(appData, name, "Config"),
157469
+ cache: path$1.join(localAppData, name, "Cache"),
157470
+ log: path$1.join(localAppData, name, "Log"),
157471
+ temp: path$1.join(tmpdir, name)
157383
157472
  };
157384
157473
  };
157385
157474
  var linux = (name) => {
157386
- const username = path.basename(homedir);
157475
+ const username = path$1.basename(homedir);
157387
157476
  return {
157388
- data: path.join(env.XDG_DATA_HOME || path.join(homedir, ".local", "share"), name),
157389
- config: path.join(env.XDG_CONFIG_HOME || path.join(homedir, ".config"), name),
157390
- cache: path.join(env.XDG_CACHE_HOME || path.join(homedir, ".cache"), name),
157391
- log: path.join(env.XDG_STATE_HOME || path.join(homedir, ".local", "state"), name),
157392
- temp: path.join(tmpdir, username, name)
157477
+ data: path$1.join(env.XDG_DATA_HOME || path$1.join(homedir, ".local", "share"), name),
157478
+ config: path$1.join(env.XDG_CONFIG_HOME || path$1.join(homedir, ".config"), name),
157479
+ cache: path$1.join(env.XDG_CACHE_HOME || path$1.join(homedir, ".cache"), name),
157480
+ log: path$1.join(env.XDG_STATE_HOME || path$1.join(homedir, ".local", "state"), name),
157481
+ temp: path$1.join(tmpdir, username, name)
157393
157482
  };
157394
157483
  };
157395
157484
  var envPaths = (name, options) => {
@@ -157924,7 +158013,7 @@ var require_ExplorerSync = /* @__PURE__ */ __commonJSMin(((exports) => {
157924
158013
  exports.ExplorerSync = ExplorerSync;
157925
158014
  }));
157926
158015
  //#endregion
157927
- //#region src/utils.ts
158016
+ //#region src/config.ts
157928
158017
  var import_dist = (/* @__PURE__ */ __commonJSMin(((exports) => {
157929
158018
  Object.defineProperty(exports, "__esModule", { value: true });
157930
158019
  exports.defaultLoadersSync = exports.defaultLoaders = exports.globalConfigSearchPlacesSync = exports.globalConfigSearchPlaces = exports.getDefaultSearchPlacesSync = exports.getDefaultSearchPlaces = exports.cosmiconfigSync = exports.cosmiconfig = void 0;
@@ -158085,21 +158174,7 @@ var import_dist = (/* @__PURE__ */ __commonJSMin(((exports) => {
158085
158174
  }
158086
158175
  exports.cosmiconfigSync = cosmiconfigSync;
158087
158176
  })))();
158088
- function isRecord(value) {
158089
- return typeof value === "object" && value !== null && !Array.isArray(value);
158090
- }
158091
- function parseBoolFlag(value, flagName) {
158092
- if (value !== "true" && value !== "false") throw new Error(`Invalid ${flagName}: "${value}". Expected "true" or "false".`);
158093
- return value === "true";
158094
- }
158095
- function parseIntFlag(value, flagName) {
158096
- const parsed = value.trim() === "" ? NaN : Number(value);
158097
- if (!Number.isInteger(parsed)) throw new Error(`Invalid ${flagName}: "${value}". Expected an integer.`);
158098
- return parsed;
158099
- }
158100
- //#endregion
158101
- //#region src/config.ts
158102
- var configFileKeys = [
158177
+ var stringKeys = [
158103
158178
  "serverUrl",
158104
158179
  "password",
158105
158180
  "sessionToken",
@@ -158107,11 +158182,22 @@ var configFileKeys = [
158107
158182
  "dataDir",
158108
158183
  "encryptionPassword"
158109
158184
  ];
158185
+ var numberKeys = ["cacheTtl", "lockTimeout"];
158186
+ var booleanKeys = ["noLock"];
158187
+ var configFileKeys = [
158188
+ ...stringKeys,
158189
+ ...numberKeys,
158190
+ ...booleanKeys
158191
+ ];
158110
158192
  function validateConfigFileContent(value) {
158111
158193
  if (!isRecord(value)) throw new Error("Invalid config file: expected an object with keys: " + configFileKeys.join(", "));
158112
158194
  for (const key of Object.keys(value)) {
158113
158195
  if (!configFileKeys.includes(key)) throw new Error(`Invalid config file: unknown key "${key}"`);
158114
- if (value[key] !== void 0 && typeof value[key] !== "string") throw new Error(`Invalid config file: key "${key}" must be a string, got ${typeof value[key]}`);
158196
+ const v = value[key];
158197
+ if (v === void 0) continue;
158198
+ if (stringKeys.includes(key) && typeof v !== "string") throw new Error(`Invalid config file: key "${key}" must be a string, got ${typeof v}`);
158199
+ if (numberKeys.includes(key) && (typeof v !== "number" || !Number.isInteger(v) || v < 0)) throw new Error(`Invalid config file: key "${key}" must be a non-negative integer`);
158200
+ if (booleanKeys.includes(key) && typeof v !== "boolean") throw new Error(`Invalid config file: key "${key}" must be a boolean, got ${typeof v}`);
158115
158201
  }
158116
158202
  return value;
158117
158203
  }
@@ -158129,13 +158215,20 @@ async function loadConfigFile() {
158129
158215
  if (result && !result.isEmpty) return validateConfigFileContent(result.config);
158130
158216
  return {};
158131
158217
  }
158218
+ function parseNonNegativeIntEnv(raw, source) {
158219
+ return raw === void 0 ? void 0 : parseNonNegativeIntFlag(raw, source);
158220
+ }
158221
+ function validateNonNegativeInt(value, name) {
158222
+ if (!Number.isInteger(value) || value < 0) throw new Error(`Invalid ${name}: expected a non-negative integer, got ${value}`);
158223
+ return value;
158224
+ }
158132
158225
  async function resolveConfig(cliOpts) {
158133
158226
  const fileConfig = await loadConfigFile();
158134
158227
  const serverUrl = cliOpts.serverUrl ?? process.env.ACTUAL_SERVER_URL ?? fileConfig.serverUrl ?? "";
158135
158228
  const password = cliOpts.password ?? process.env.ACTUAL_PASSWORD ?? fileConfig.password;
158136
158229
  const sessionToken = cliOpts.sessionToken ?? process.env.ACTUAL_SESSION_TOKEN ?? fileConfig.sessionToken;
158137
158230
  const syncId = cliOpts.syncId ?? process.env.ACTUAL_SYNC_ID ?? fileConfig.syncId;
158138
- const dataDir = cliOpts.dataDir ?? process.env.ACTUAL_DATA_DIR ?? fileConfig.dataDir ?? join(homedir(), ".actual-cli", "data");
158231
+ const dataDir = cliOpts.dataDir ?? process.env.ACTUAL_DATA_DIR ?? fileConfig.dataDir ?? join$1(homedir(), ".actual-cli", "data");
158139
158232
  const encryptionPassword = cliOpts.encryptionPassword ?? process.env.ACTUAL_ENCRYPTION_PASSWORD ?? fileConfig.encryptionPassword;
158140
158233
  if (!serverUrl) throw new Error("Server URL is required. Set --server-url, ACTUAL_SERVER_URL env var, or serverUrl in config file.");
158141
158234
  if (!password && !sessionToken) throw new Error("Authentication required. Set --password/--session-token, ACTUAL_PASSWORD/ACTUAL_SESSION_TOKEN env var, or password/sessionToken in config file.");
@@ -158145,7 +158238,1465 @@ async function resolveConfig(cliOpts) {
158145
158238
  sessionToken,
158146
158239
  syncId,
158147
158240
  dataDir,
158148
- encryptionPassword
158241
+ encryptionPassword,
158242
+ cacheTtl: validateNonNegativeInt(cliOpts.cacheTtl ?? parseNonNegativeIntEnv(process.env.ACTUAL_CACHE_TTL, "ACTUAL_CACHE_TTL") ?? fileConfig.cacheTtl ?? 60, "cacheTtl"),
158243
+ lockTimeout: validateNonNegativeInt(cliOpts.lockTimeout ?? parseNonNegativeIntEnv(process.env.ACTUAL_LOCK_TIMEOUT, "ACTUAL_LOCK_TIMEOUT") ?? fileConfig.lockTimeout ?? 10, "lockTimeout"),
158244
+ refresh: (cliOpts.refresh ?? false) || cliOpts.cache === false,
158245
+ noLock: (cliOpts.lock === false ? true : void 0) ?? parseBoolEnv(process.env.ACTUAL_NO_LOCK, "ACTUAL_NO_LOCK") ?? fileConfig.noLock ?? false
158246
+ };
158247
+ }
158248
+ //#endregion
158249
+ //#region ../../node_modules/graceful-fs/polyfills.js
158250
+ var require_polyfills = /* @__PURE__ */ __commonJSMin(((exports, module) => {
158251
+ var constants = __require("constants");
158252
+ var origCwd = process.cwd;
158253
+ var cwd = null;
158254
+ var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform;
158255
+ process.cwd = function() {
158256
+ if (!cwd) cwd = origCwd.call(process);
158257
+ return cwd;
158258
+ };
158259
+ try {
158260
+ process.cwd();
158261
+ } catch (er) {}
158262
+ if (typeof process.chdir === "function") {
158263
+ var chdir = process.chdir;
158264
+ process.chdir = function(d) {
158265
+ cwd = null;
158266
+ chdir.call(process, d);
158267
+ };
158268
+ if (Object.setPrototypeOf) Object.setPrototypeOf(process.chdir, chdir);
158269
+ }
158270
+ module.exports = patch;
158271
+ function patch(fs) {
158272
+ if (constants.hasOwnProperty("O_SYMLINK") && process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) patchLchmod(fs);
158273
+ if (!fs.lutimes) patchLutimes(fs);
158274
+ fs.chown = chownFix(fs.chown);
158275
+ fs.fchown = chownFix(fs.fchown);
158276
+ fs.lchown = chownFix(fs.lchown);
158277
+ fs.chmod = chmodFix(fs.chmod);
158278
+ fs.fchmod = chmodFix(fs.fchmod);
158279
+ fs.lchmod = chmodFix(fs.lchmod);
158280
+ fs.chownSync = chownFixSync(fs.chownSync);
158281
+ fs.fchownSync = chownFixSync(fs.fchownSync);
158282
+ fs.lchownSync = chownFixSync(fs.lchownSync);
158283
+ fs.chmodSync = chmodFixSync(fs.chmodSync);
158284
+ fs.fchmodSync = chmodFixSync(fs.fchmodSync);
158285
+ fs.lchmodSync = chmodFixSync(fs.lchmodSync);
158286
+ fs.stat = statFix(fs.stat);
158287
+ fs.fstat = statFix(fs.fstat);
158288
+ fs.lstat = statFix(fs.lstat);
158289
+ fs.statSync = statFixSync(fs.statSync);
158290
+ fs.fstatSync = statFixSync(fs.fstatSync);
158291
+ fs.lstatSync = statFixSync(fs.lstatSync);
158292
+ if (fs.chmod && !fs.lchmod) {
158293
+ fs.lchmod = function(path, mode, cb) {
158294
+ if (cb) process.nextTick(cb);
158295
+ };
158296
+ fs.lchmodSync = function() {};
158297
+ }
158298
+ if (fs.chown && !fs.lchown) {
158299
+ fs.lchown = function(path, uid, gid, cb) {
158300
+ if (cb) process.nextTick(cb);
158301
+ };
158302
+ fs.lchownSync = function() {};
158303
+ }
158304
+ if (platform === "win32") fs.rename = typeof fs.rename !== "function" ? fs.rename : (function(fs$rename) {
158305
+ function rename(from, to, cb) {
158306
+ var start = Date.now();
158307
+ var backoff = 0;
158308
+ fs$rename(from, to, function CB(er) {
158309
+ if (er && (er.code === "EACCES" || er.code === "EPERM" || er.code === "EBUSY") && Date.now() - start < 6e4) {
158310
+ setTimeout(function() {
158311
+ fs.stat(to, function(stater, st) {
158312
+ if (stater && stater.code === "ENOENT") fs$rename(from, to, CB);
158313
+ else cb(er);
158314
+ });
158315
+ }, backoff);
158316
+ if (backoff < 100) backoff += 10;
158317
+ return;
158318
+ }
158319
+ if (cb) cb(er);
158320
+ });
158321
+ }
158322
+ if (Object.setPrototypeOf) Object.setPrototypeOf(rename, fs$rename);
158323
+ return rename;
158324
+ })(fs.rename);
158325
+ fs.read = typeof fs.read !== "function" ? fs.read : (function(fs$read) {
158326
+ function read(fd, buffer, offset, length, position, callback_) {
158327
+ var callback;
158328
+ if (callback_ && typeof callback_ === "function") {
158329
+ var eagCounter = 0;
158330
+ callback = function(er, _, __) {
158331
+ if (er && er.code === "EAGAIN" && eagCounter < 10) {
158332
+ eagCounter++;
158333
+ return fs$read.call(fs, fd, buffer, offset, length, position, callback);
158334
+ }
158335
+ callback_.apply(this, arguments);
158336
+ };
158337
+ }
158338
+ return fs$read.call(fs, fd, buffer, offset, length, position, callback);
158339
+ }
158340
+ if (Object.setPrototypeOf) Object.setPrototypeOf(read, fs$read);
158341
+ return read;
158342
+ })(fs.read);
158343
+ fs.readSync = typeof fs.readSync !== "function" ? fs.readSync : (function(fs$readSync) {
158344
+ return function(fd, buffer, offset, length, position) {
158345
+ var eagCounter = 0;
158346
+ while (true) try {
158347
+ return fs$readSync.call(fs, fd, buffer, offset, length, position);
158348
+ } catch (er) {
158349
+ if (er.code === "EAGAIN" && eagCounter < 10) {
158350
+ eagCounter++;
158351
+ continue;
158352
+ }
158353
+ throw er;
158354
+ }
158355
+ };
158356
+ })(fs.readSync);
158357
+ function patchLchmod(fs) {
158358
+ fs.lchmod = function(path, mode, callback) {
158359
+ fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, mode, function(err, fd) {
158360
+ if (err) {
158361
+ if (callback) callback(err);
158362
+ return;
158363
+ }
158364
+ fs.fchmod(fd, mode, function(err) {
158365
+ fs.close(fd, function(err2) {
158366
+ if (callback) callback(err || err2);
158367
+ });
158368
+ });
158369
+ });
158370
+ };
158371
+ fs.lchmodSync = function(path, mode) {
158372
+ var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode);
158373
+ var threw = true;
158374
+ var ret;
158375
+ try {
158376
+ ret = fs.fchmodSync(fd, mode);
158377
+ threw = false;
158378
+ } finally {
158379
+ if (threw) try {
158380
+ fs.closeSync(fd);
158381
+ } catch (er) {}
158382
+ else fs.closeSync(fd);
158383
+ }
158384
+ return ret;
158385
+ };
158386
+ }
158387
+ function patchLutimes(fs) {
158388
+ if (constants.hasOwnProperty("O_SYMLINK") && fs.futimes) {
158389
+ fs.lutimes = function(path, at, mt, cb) {
158390
+ fs.open(path, constants.O_SYMLINK, function(er, fd) {
158391
+ if (er) {
158392
+ if (cb) cb(er);
158393
+ return;
158394
+ }
158395
+ fs.futimes(fd, at, mt, function(er) {
158396
+ fs.close(fd, function(er2) {
158397
+ if (cb) cb(er || er2);
158398
+ });
158399
+ });
158400
+ });
158401
+ };
158402
+ fs.lutimesSync = function(path, at, mt) {
158403
+ var fd = fs.openSync(path, constants.O_SYMLINK);
158404
+ var ret;
158405
+ var threw = true;
158406
+ try {
158407
+ ret = fs.futimesSync(fd, at, mt);
158408
+ threw = false;
158409
+ } finally {
158410
+ if (threw) try {
158411
+ fs.closeSync(fd);
158412
+ } catch (er) {}
158413
+ else fs.closeSync(fd);
158414
+ }
158415
+ return ret;
158416
+ };
158417
+ } else if (fs.futimes) {
158418
+ fs.lutimes = function(_a, _b, _c, cb) {
158419
+ if (cb) process.nextTick(cb);
158420
+ };
158421
+ fs.lutimesSync = function() {};
158422
+ }
158423
+ }
158424
+ function chmodFix(orig) {
158425
+ if (!orig) return orig;
158426
+ return function(target, mode, cb) {
158427
+ return orig.call(fs, target, mode, function(er) {
158428
+ if (chownErOk(er)) er = null;
158429
+ if (cb) cb.apply(this, arguments);
158430
+ });
158431
+ };
158432
+ }
158433
+ function chmodFixSync(orig) {
158434
+ if (!orig) return orig;
158435
+ return function(target, mode) {
158436
+ try {
158437
+ return orig.call(fs, target, mode);
158438
+ } catch (er) {
158439
+ if (!chownErOk(er)) throw er;
158440
+ }
158441
+ };
158442
+ }
158443
+ function chownFix(orig) {
158444
+ if (!orig) return orig;
158445
+ return function(target, uid, gid, cb) {
158446
+ return orig.call(fs, target, uid, gid, function(er) {
158447
+ if (chownErOk(er)) er = null;
158448
+ if (cb) cb.apply(this, arguments);
158449
+ });
158450
+ };
158451
+ }
158452
+ function chownFixSync(orig) {
158453
+ if (!orig) return orig;
158454
+ return function(target, uid, gid) {
158455
+ try {
158456
+ return orig.call(fs, target, uid, gid);
158457
+ } catch (er) {
158458
+ if (!chownErOk(er)) throw er;
158459
+ }
158460
+ };
158461
+ }
158462
+ function statFix(orig) {
158463
+ if (!orig) return orig;
158464
+ return function(target, options, cb) {
158465
+ if (typeof options === "function") {
158466
+ cb = options;
158467
+ options = null;
158468
+ }
158469
+ function callback(er, stats) {
158470
+ if (stats) {
158471
+ if (stats.uid < 0) stats.uid += 4294967296;
158472
+ if (stats.gid < 0) stats.gid += 4294967296;
158473
+ }
158474
+ if (cb) cb.apply(this, arguments);
158475
+ }
158476
+ return options ? orig.call(fs, target, options, callback) : orig.call(fs, target, callback);
158477
+ };
158478
+ }
158479
+ function statFixSync(orig) {
158480
+ if (!orig) return orig;
158481
+ return function(target, options) {
158482
+ var stats = options ? orig.call(fs, target, options) : orig.call(fs, target);
158483
+ if (stats) {
158484
+ if (stats.uid < 0) stats.uid += 4294967296;
158485
+ if (stats.gid < 0) stats.gid += 4294967296;
158486
+ }
158487
+ return stats;
158488
+ };
158489
+ }
158490
+ function chownErOk(er) {
158491
+ if (!er) return true;
158492
+ if (er.code === "ENOSYS") return true;
158493
+ if (!process.getuid || process.getuid() !== 0) {
158494
+ if (er.code === "EINVAL" || er.code === "EPERM") return true;
158495
+ }
158496
+ return false;
158497
+ }
158498
+ }
158499
+ }));
158500
+ //#endregion
158501
+ //#region ../../node_modules/graceful-fs/legacy-streams.js
158502
+ var require_legacy_streams = /* @__PURE__ */ __commonJSMin(((exports, module) => {
158503
+ var Stream = __require("stream").Stream;
158504
+ module.exports = legacy;
158505
+ function legacy(fs) {
158506
+ return {
158507
+ ReadStream,
158508
+ WriteStream
158509
+ };
158510
+ function ReadStream(path, options) {
158511
+ if (!(this instanceof ReadStream)) return new ReadStream(path, options);
158512
+ Stream.call(this);
158513
+ var self = this;
158514
+ this.path = path;
158515
+ this.fd = null;
158516
+ this.readable = true;
158517
+ this.paused = false;
158518
+ this.flags = "r";
158519
+ this.mode = 438;
158520
+ this.bufferSize = 64 * 1024;
158521
+ options = options || {};
158522
+ var keys = Object.keys(options);
158523
+ for (var index = 0, length = keys.length; index < length; index++) {
158524
+ var key = keys[index];
158525
+ this[key] = options[key];
158526
+ }
158527
+ if (this.encoding) this.setEncoding(this.encoding);
158528
+ if (this.start !== void 0) {
158529
+ if ("number" !== typeof this.start) throw TypeError("start must be a Number");
158530
+ if (this.end === void 0) this.end = Infinity;
158531
+ else if ("number" !== typeof this.end) throw TypeError("end must be a Number");
158532
+ if (this.start > this.end) throw new Error("start must be <= end");
158533
+ this.pos = this.start;
158534
+ }
158535
+ if (this.fd !== null) {
158536
+ process.nextTick(function() {
158537
+ self._read();
158538
+ });
158539
+ return;
158540
+ }
158541
+ fs.open(this.path, this.flags, this.mode, function(err, fd) {
158542
+ if (err) {
158543
+ self.emit("error", err);
158544
+ self.readable = false;
158545
+ return;
158546
+ }
158547
+ self.fd = fd;
158548
+ self.emit("open", fd);
158549
+ self._read();
158550
+ });
158551
+ }
158552
+ function WriteStream(path, options) {
158553
+ if (!(this instanceof WriteStream)) return new WriteStream(path, options);
158554
+ Stream.call(this);
158555
+ this.path = path;
158556
+ this.fd = null;
158557
+ this.writable = true;
158558
+ this.flags = "w";
158559
+ this.encoding = "binary";
158560
+ this.mode = 438;
158561
+ this.bytesWritten = 0;
158562
+ options = options || {};
158563
+ var keys = Object.keys(options);
158564
+ for (var index = 0, length = keys.length; index < length; index++) {
158565
+ var key = keys[index];
158566
+ this[key] = options[key];
158567
+ }
158568
+ if (this.start !== void 0) {
158569
+ if ("number" !== typeof this.start) throw TypeError("start must be a Number");
158570
+ if (this.start < 0) throw new Error("start must be >= zero");
158571
+ this.pos = this.start;
158572
+ }
158573
+ this.busy = false;
158574
+ this._queue = [];
158575
+ if (this.fd === null) {
158576
+ this._open = fs.open;
158577
+ this._queue.push([
158578
+ this._open,
158579
+ this.path,
158580
+ this.flags,
158581
+ this.mode,
158582
+ void 0
158583
+ ]);
158584
+ this.flush();
158585
+ }
158586
+ }
158587
+ }
158588
+ }));
158589
+ //#endregion
158590
+ //#region ../../node_modules/graceful-fs/clone.js
158591
+ var require_clone = /* @__PURE__ */ __commonJSMin(((exports, module) => {
158592
+ module.exports = clone;
158593
+ var getPrototypeOf = Object.getPrototypeOf || function(obj) {
158594
+ return obj.__proto__;
158595
+ };
158596
+ function clone(obj) {
158597
+ if (obj === null || typeof obj !== "object") return obj;
158598
+ if (obj instanceof Object) var copy = { __proto__: getPrototypeOf(obj) };
158599
+ else var copy = Object.create(null);
158600
+ Object.getOwnPropertyNames(obj).forEach(function(key) {
158601
+ Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key));
158602
+ });
158603
+ return copy;
158604
+ }
158605
+ }));
158606
+ //#endregion
158607
+ //#region ../../node_modules/graceful-fs/graceful-fs.js
158608
+ var require_graceful_fs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
158609
+ var fs = __require("fs");
158610
+ var polyfills = require_polyfills();
158611
+ var legacy = require_legacy_streams();
158612
+ var clone = require_clone();
158613
+ var util$1 = __require("util");
158614
+ /* istanbul ignore next - node 0.x polyfill */
158615
+ var gracefulQueue;
158616
+ var previousSymbol;
158617
+ /* istanbul ignore else - node 0.x polyfill */
158618
+ if (typeof Symbol === "function" && typeof Symbol.for === "function") {
158619
+ gracefulQueue = Symbol.for("graceful-fs.queue");
158620
+ previousSymbol = Symbol.for("graceful-fs.previous");
158621
+ } else {
158622
+ gracefulQueue = "___graceful-fs.queue";
158623
+ previousSymbol = "___graceful-fs.previous";
158624
+ }
158625
+ function noop() {}
158626
+ function publishQueue(context, queue) {
158627
+ Object.defineProperty(context, gracefulQueue, { get: function() {
158628
+ return queue;
158629
+ } });
158630
+ }
158631
+ var debug = noop;
158632
+ if (util$1.debuglog) debug = util$1.debuglog("gfs4");
158633
+ else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) debug = function() {
158634
+ var m = util$1.format.apply(util$1, arguments);
158635
+ m = "GFS4: " + m.split(/\n/).join("\nGFS4: ");
158636
+ console.error(m);
158637
+ };
158638
+ if (!fs[gracefulQueue]) {
158639
+ publishQueue(fs, global[gracefulQueue] || []);
158640
+ fs.close = (function(fs$close) {
158641
+ function close(fd, cb) {
158642
+ return fs$close.call(fs, fd, function(err) {
158643
+ if (!err) resetQueue();
158644
+ if (typeof cb === "function") cb.apply(this, arguments);
158645
+ });
158646
+ }
158647
+ Object.defineProperty(close, previousSymbol, { value: fs$close });
158648
+ return close;
158649
+ })(fs.close);
158650
+ fs.closeSync = (function(fs$closeSync) {
158651
+ function closeSync(fd) {
158652
+ fs$closeSync.apply(fs, arguments);
158653
+ resetQueue();
158654
+ }
158655
+ Object.defineProperty(closeSync, previousSymbol, { value: fs$closeSync });
158656
+ return closeSync;
158657
+ })(fs.closeSync);
158658
+ if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || "")) process.on("exit", function() {
158659
+ debug(fs[gracefulQueue]);
158660
+ __require("assert").equal(fs[gracefulQueue].length, 0);
158661
+ });
158662
+ }
158663
+ if (!global[gracefulQueue]) publishQueue(global, fs[gracefulQueue]);
158664
+ module.exports = patch(clone(fs));
158665
+ if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) {
158666
+ module.exports = patch(fs);
158667
+ fs.__patched = true;
158668
+ }
158669
+ function patch(fs) {
158670
+ polyfills(fs);
158671
+ fs.gracefulify = patch;
158672
+ fs.createReadStream = createReadStream;
158673
+ fs.createWriteStream = createWriteStream;
158674
+ var fs$readFile = fs.readFile;
158675
+ fs.readFile = readFile;
158676
+ function readFile(path, options, cb) {
158677
+ if (typeof options === "function") cb = options, options = null;
158678
+ return go$readFile(path, options, cb);
158679
+ function go$readFile(path, options, cb, startTime) {
158680
+ return fs$readFile(path, options, function(err) {
158681
+ if (err && (err.code === "EMFILE" || err.code === "ENFILE")) enqueue([
158682
+ go$readFile,
158683
+ [
158684
+ path,
158685
+ options,
158686
+ cb
158687
+ ],
158688
+ err,
158689
+ startTime || Date.now(),
158690
+ Date.now()
158691
+ ]);
158692
+ else if (typeof cb === "function") cb.apply(this, arguments);
158693
+ });
158694
+ }
158695
+ }
158696
+ var fs$writeFile = fs.writeFile;
158697
+ fs.writeFile = writeFile;
158698
+ function writeFile(path, data, options, cb) {
158699
+ if (typeof options === "function") cb = options, options = null;
158700
+ return go$writeFile(path, data, options, cb);
158701
+ function go$writeFile(path, data, options, cb, startTime) {
158702
+ return fs$writeFile(path, data, options, function(err) {
158703
+ if (err && (err.code === "EMFILE" || err.code === "ENFILE")) enqueue([
158704
+ go$writeFile,
158705
+ [
158706
+ path,
158707
+ data,
158708
+ options,
158709
+ cb
158710
+ ],
158711
+ err,
158712
+ startTime || Date.now(),
158713
+ Date.now()
158714
+ ]);
158715
+ else if (typeof cb === "function") cb.apply(this, arguments);
158716
+ });
158717
+ }
158718
+ }
158719
+ var fs$appendFile = fs.appendFile;
158720
+ if (fs$appendFile) fs.appendFile = appendFile;
158721
+ function appendFile(path, data, options, cb) {
158722
+ if (typeof options === "function") cb = options, options = null;
158723
+ return go$appendFile(path, data, options, cb);
158724
+ function go$appendFile(path, data, options, cb, startTime) {
158725
+ return fs$appendFile(path, data, options, function(err) {
158726
+ if (err && (err.code === "EMFILE" || err.code === "ENFILE")) enqueue([
158727
+ go$appendFile,
158728
+ [
158729
+ path,
158730
+ data,
158731
+ options,
158732
+ cb
158733
+ ],
158734
+ err,
158735
+ startTime || Date.now(),
158736
+ Date.now()
158737
+ ]);
158738
+ else if (typeof cb === "function") cb.apply(this, arguments);
158739
+ });
158740
+ }
158741
+ }
158742
+ var fs$copyFile = fs.copyFile;
158743
+ if (fs$copyFile) fs.copyFile = copyFile;
158744
+ function copyFile(src, dest, flags, cb) {
158745
+ if (typeof flags === "function") {
158746
+ cb = flags;
158747
+ flags = 0;
158748
+ }
158749
+ return go$copyFile(src, dest, flags, cb);
158750
+ function go$copyFile(src, dest, flags, cb, startTime) {
158751
+ return fs$copyFile(src, dest, flags, function(err) {
158752
+ if (err && (err.code === "EMFILE" || err.code === "ENFILE")) enqueue([
158753
+ go$copyFile,
158754
+ [
158755
+ src,
158756
+ dest,
158757
+ flags,
158758
+ cb
158759
+ ],
158760
+ err,
158761
+ startTime || Date.now(),
158762
+ Date.now()
158763
+ ]);
158764
+ else if (typeof cb === "function") cb.apply(this, arguments);
158765
+ });
158766
+ }
158767
+ }
158768
+ var fs$readdir = fs.readdir;
158769
+ fs.readdir = readdir;
158770
+ var noReaddirOptionVersions = /^v[0-5]\./;
158771
+ function readdir(path, options, cb) {
158772
+ if (typeof options === "function") cb = options, options = null;
158773
+ var go$readdir = noReaddirOptionVersions.test(process.version) ? function go$readdir(path, options, cb, startTime) {
158774
+ return fs$readdir(path, fs$readdirCallback(path, options, cb, startTime));
158775
+ } : function go$readdir(path, options, cb, startTime) {
158776
+ return fs$readdir(path, options, fs$readdirCallback(path, options, cb, startTime));
158777
+ };
158778
+ return go$readdir(path, options, cb);
158779
+ function fs$readdirCallback(path, options, cb, startTime) {
158780
+ return function(err, files) {
158781
+ if (err && (err.code === "EMFILE" || err.code === "ENFILE")) enqueue([
158782
+ go$readdir,
158783
+ [
158784
+ path,
158785
+ options,
158786
+ cb
158787
+ ],
158788
+ err,
158789
+ startTime || Date.now(),
158790
+ Date.now()
158791
+ ]);
158792
+ else {
158793
+ if (files && files.sort) files.sort();
158794
+ if (typeof cb === "function") cb.call(this, err, files);
158795
+ }
158796
+ };
158797
+ }
158798
+ }
158799
+ if (process.version.substr(0, 4) === "v0.8") {
158800
+ var legStreams = legacy(fs);
158801
+ ReadStream = legStreams.ReadStream;
158802
+ WriteStream = legStreams.WriteStream;
158803
+ }
158804
+ var fs$ReadStream = fs.ReadStream;
158805
+ if (fs$ReadStream) {
158806
+ ReadStream.prototype = Object.create(fs$ReadStream.prototype);
158807
+ ReadStream.prototype.open = ReadStream$open;
158808
+ }
158809
+ var fs$WriteStream = fs.WriteStream;
158810
+ if (fs$WriteStream) {
158811
+ WriteStream.prototype = Object.create(fs$WriteStream.prototype);
158812
+ WriteStream.prototype.open = WriteStream$open;
158813
+ }
158814
+ Object.defineProperty(fs, "ReadStream", {
158815
+ get: function() {
158816
+ return ReadStream;
158817
+ },
158818
+ set: function(val) {
158819
+ ReadStream = val;
158820
+ },
158821
+ enumerable: true,
158822
+ configurable: true
158823
+ });
158824
+ Object.defineProperty(fs, "WriteStream", {
158825
+ get: function() {
158826
+ return WriteStream;
158827
+ },
158828
+ set: function(val) {
158829
+ WriteStream = val;
158830
+ },
158831
+ enumerable: true,
158832
+ configurable: true
158833
+ });
158834
+ var FileReadStream = ReadStream;
158835
+ Object.defineProperty(fs, "FileReadStream", {
158836
+ get: function() {
158837
+ return FileReadStream;
158838
+ },
158839
+ set: function(val) {
158840
+ FileReadStream = val;
158841
+ },
158842
+ enumerable: true,
158843
+ configurable: true
158844
+ });
158845
+ var FileWriteStream = WriteStream;
158846
+ Object.defineProperty(fs, "FileWriteStream", {
158847
+ get: function() {
158848
+ return FileWriteStream;
158849
+ },
158850
+ set: function(val) {
158851
+ FileWriteStream = val;
158852
+ },
158853
+ enumerable: true,
158854
+ configurable: true
158855
+ });
158856
+ function ReadStream(path, options) {
158857
+ if (this instanceof ReadStream) return fs$ReadStream.apply(this, arguments), this;
158858
+ else return ReadStream.apply(Object.create(ReadStream.prototype), arguments);
158859
+ }
158860
+ function ReadStream$open() {
158861
+ var that = this;
158862
+ open(that.path, that.flags, that.mode, function(err, fd) {
158863
+ if (err) {
158864
+ if (that.autoClose) that.destroy();
158865
+ that.emit("error", err);
158866
+ } else {
158867
+ that.fd = fd;
158868
+ that.emit("open", fd);
158869
+ that.read();
158870
+ }
158871
+ });
158872
+ }
158873
+ function WriteStream(path, options) {
158874
+ if (this instanceof WriteStream) return fs$WriteStream.apply(this, arguments), this;
158875
+ else return WriteStream.apply(Object.create(WriteStream.prototype), arguments);
158876
+ }
158877
+ function WriteStream$open() {
158878
+ var that = this;
158879
+ open(that.path, that.flags, that.mode, function(err, fd) {
158880
+ if (err) {
158881
+ that.destroy();
158882
+ that.emit("error", err);
158883
+ } else {
158884
+ that.fd = fd;
158885
+ that.emit("open", fd);
158886
+ }
158887
+ });
158888
+ }
158889
+ function createReadStream(path, options) {
158890
+ return new fs.ReadStream(path, options);
158891
+ }
158892
+ function createWriteStream(path, options) {
158893
+ return new fs.WriteStream(path, options);
158894
+ }
158895
+ var fs$open = fs.open;
158896
+ fs.open = open;
158897
+ function open(path, flags, mode, cb) {
158898
+ if (typeof mode === "function") cb = mode, mode = null;
158899
+ return go$open(path, flags, mode, cb);
158900
+ function go$open(path, flags, mode, cb, startTime) {
158901
+ return fs$open(path, flags, mode, function(err, fd) {
158902
+ if (err && (err.code === "EMFILE" || err.code === "ENFILE")) enqueue([
158903
+ go$open,
158904
+ [
158905
+ path,
158906
+ flags,
158907
+ mode,
158908
+ cb
158909
+ ],
158910
+ err,
158911
+ startTime || Date.now(),
158912
+ Date.now()
158913
+ ]);
158914
+ else if (typeof cb === "function") cb.apply(this, arguments);
158915
+ });
158916
+ }
158917
+ }
158918
+ return fs;
158919
+ }
158920
+ function enqueue(elem) {
158921
+ debug("ENQUEUE", elem[0].name, elem[1]);
158922
+ fs[gracefulQueue].push(elem);
158923
+ retry();
158924
+ }
158925
+ var retryTimer;
158926
+ function resetQueue() {
158927
+ var now = Date.now();
158928
+ for (var i = 0; i < fs[gracefulQueue].length; ++i) if (fs[gracefulQueue][i].length > 2) {
158929
+ fs[gracefulQueue][i][3] = now;
158930
+ fs[gracefulQueue][i][4] = now;
158931
+ }
158932
+ retry();
158933
+ }
158934
+ function retry() {
158935
+ clearTimeout(retryTimer);
158936
+ retryTimer = void 0;
158937
+ if (fs[gracefulQueue].length === 0) return;
158938
+ var elem = fs[gracefulQueue].shift();
158939
+ var fn = elem[0];
158940
+ var args = elem[1];
158941
+ var err = elem[2];
158942
+ var startTime = elem[3];
158943
+ var lastTime = elem[4];
158944
+ if (startTime === void 0) {
158945
+ debug("RETRY", fn.name, args);
158946
+ fn.apply(null, args);
158947
+ } else if (Date.now() - startTime >= 6e4) {
158948
+ debug("TIMEOUT", fn.name, args);
158949
+ var cb = args.pop();
158950
+ if (typeof cb === "function") cb.call(null, err);
158951
+ } else {
158952
+ var sinceAttempt = Date.now() - lastTime;
158953
+ var sinceStart = Math.max(lastTime - startTime, 1);
158954
+ if (sinceAttempt >= Math.min(sinceStart * 1.2, 100)) {
158955
+ debug("RETRY", fn.name, args);
158956
+ fn.apply(null, args.concat([startTime]));
158957
+ } else fs[gracefulQueue].push(elem);
158958
+ }
158959
+ if (retryTimer === void 0) retryTimer = setTimeout(retry, 0);
158960
+ }
158961
+ }));
158962
+ //#endregion
158963
+ //#region ../../node_modules/retry/lib/retry_operation.js
158964
+ var require_retry_operation = /* @__PURE__ */ __commonJSMin(((exports, module) => {
158965
+ function RetryOperation(timeouts, options) {
158966
+ if (typeof options === "boolean") options = { forever: options };
158967
+ this._originalTimeouts = JSON.parse(JSON.stringify(timeouts));
158968
+ this._timeouts = timeouts;
158969
+ this._options = options || {};
158970
+ this._maxRetryTime = options && options.maxRetryTime || Infinity;
158971
+ this._fn = null;
158972
+ this._errors = [];
158973
+ this._attempts = 1;
158974
+ this._operationTimeout = null;
158975
+ this._operationTimeoutCb = null;
158976
+ this._timeout = null;
158977
+ this._operationStart = null;
158978
+ if (this._options.forever) this._cachedTimeouts = this._timeouts.slice(0);
158979
+ }
158980
+ module.exports = RetryOperation;
158981
+ RetryOperation.prototype.reset = function() {
158982
+ this._attempts = 1;
158983
+ this._timeouts = this._originalTimeouts;
158984
+ };
158985
+ RetryOperation.prototype.stop = function() {
158986
+ if (this._timeout) clearTimeout(this._timeout);
158987
+ this._timeouts = [];
158988
+ this._cachedTimeouts = null;
158989
+ };
158990
+ RetryOperation.prototype.retry = function(err) {
158991
+ if (this._timeout) clearTimeout(this._timeout);
158992
+ if (!err) return false;
158993
+ var currentTime = (/* @__PURE__ */ new Date()).getTime();
158994
+ if (err && currentTime - this._operationStart >= this._maxRetryTime) {
158995
+ this._errors.unshift(/* @__PURE__ */ new Error("RetryOperation timeout occurred"));
158996
+ return false;
158997
+ }
158998
+ this._errors.push(err);
158999
+ var timeout = this._timeouts.shift();
159000
+ if (timeout === void 0) if (this._cachedTimeouts) {
159001
+ this._errors.splice(this._errors.length - 1, this._errors.length);
159002
+ this._timeouts = this._cachedTimeouts.slice(0);
159003
+ timeout = this._timeouts.shift();
159004
+ } else return false;
159005
+ var self = this;
159006
+ var timer = setTimeout(function() {
159007
+ self._attempts++;
159008
+ if (self._operationTimeoutCb) {
159009
+ self._timeout = setTimeout(function() {
159010
+ self._operationTimeoutCb(self._attempts);
159011
+ }, self._operationTimeout);
159012
+ if (self._options.unref) self._timeout.unref();
159013
+ }
159014
+ self._fn(self._attempts);
159015
+ }, timeout);
159016
+ if (this._options.unref) timer.unref();
159017
+ return true;
159018
+ };
159019
+ RetryOperation.prototype.attempt = function(fn, timeoutOps) {
159020
+ this._fn = fn;
159021
+ if (timeoutOps) {
159022
+ if (timeoutOps.timeout) this._operationTimeout = timeoutOps.timeout;
159023
+ if (timeoutOps.cb) this._operationTimeoutCb = timeoutOps.cb;
159024
+ }
159025
+ var self = this;
159026
+ if (this._operationTimeoutCb) this._timeout = setTimeout(function() {
159027
+ self._operationTimeoutCb();
159028
+ }, self._operationTimeout);
159029
+ this._operationStart = (/* @__PURE__ */ new Date()).getTime();
159030
+ this._fn(this._attempts);
159031
+ };
159032
+ RetryOperation.prototype.try = function(fn) {
159033
+ console.log("Using RetryOperation.try() is deprecated");
159034
+ this.attempt(fn);
159035
+ };
159036
+ RetryOperation.prototype.start = function(fn) {
159037
+ console.log("Using RetryOperation.start() is deprecated");
159038
+ this.attempt(fn);
159039
+ };
159040
+ RetryOperation.prototype.start = RetryOperation.prototype.try;
159041
+ RetryOperation.prototype.errors = function() {
159042
+ return this._errors;
159043
+ };
159044
+ RetryOperation.prototype.attempts = function() {
159045
+ return this._attempts;
159046
+ };
159047
+ RetryOperation.prototype.mainError = function() {
159048
+ if (this._errors.length === 0) return null;
159049
+ var counts = {};
159050
+ var mainError = null;
159051
+ var mainErrorCount = 0;
159052
+ for (var i = 0; i < this._errors.length; i++) {
159053
+ var error = this._errors[i];
159054
+ var message = error.message;
159055
+ var count = (counts[message] || 0) + 1;
159056
+ counts[message] = count;
159057
+ if (count >= mainErrorCount) {
159058
+ mainError = error;
159059
+ mainErrorCount = count;
159060
+ }
159061
+ }
159062
+ return mainError;
159063
+ };
159064
+ }));
159065
+ //#endregion
159066
+ //#region ../../node_modules/retry/lib/retry.js
159067
+ var require_retry$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
159068
+ var RetryOperation = require_retry_operation();
159069
+ exports.operation = function(options) {
159070
+ return new RetryOperation(exports.timeouts(options), {
159071
+ forever: options && options.forever,
159072
+ unref: options && options.unref,
159073
+ maxRetryTime: options && options.maxRetryTime
159074
+ });
159075
+ };
159076
+ exports.timeouts = function(options) {
159077
+ if (options instanceof Array) return [].concat(options);
159078
+ var opts = {
159079
+ retries: 10,
159080
+ factor: 2,
159081
+ minTimeout: 1 * 1e3,
159082
+ maxTimeout: Infinity,
159083
+ randomize: false
159084
+ };
159085
+ for (var key in options) opts[key] = options[key];
159086
+ if (opts.minTimeout > opts.maxTimeout) throw new Error("minTimeout is greater than maxTimeout");
159087
+ var timeouts = [];
159088
+ for (var i = 0; i < opts.retries; i++) timeouts.push(this.createTimeout(i, opts));
159089
+ if (options && options.forever && !timeouts.length) timeouts.push(this.createTimeout(i, opts));
159090
+ timeouts.sort(function(a, b) {
159091
+ return a - b;
159092
+ });
159093
+ return timeouts;
159094
+ };
159095
+ exports.createTimeout = function(attempt, opts) {
159096
+ var random = opts.randomize ? Math.random() + 1 : 1;
159097
+ var timeout = Math.round(random * opts.minTimeout * Math.pow(opts.factor, attempt));
159098
+ timeout = Math.min(timeout, opts.maxTimeout);
159099
+ return timeout;
159100
+ };
159101
+ exports.wrap = function(obj, options, methods) {
159102
+ if (options instanceof Array) {
159103
+ methods = options;
159104
+ options = null;
159105
+ }
159106
+ if (!methods) {
159107
+ methods = [];
159108
+ for (var key in obj) if (typeof obj[key] === "function") methods.push(key);
159109
+ }
159110
+ for (var i = 0; i < methods.length; i++) {
159111
+ var method = methods[i];
159112
+ var original = obj[method];
159113
+ obj[method] = function retryWrapper(original) {
159114
+ var op = exports.operation(options);
159115
+ var args = Array.prototype.slice.call(arguments, 1);
159116
+ var callback = args.pop();
159117
+ args.push(function(err) {
159118
+ if (op.retry(err)) return;
159119
+ if (err) arguments[0] = op.mainError();
159120
+ callback.apply(this, arguments);
159121
+ });
159122
+ op.attempt(function() {
159123
+ original.apply(obj, args);
159124
+ });
159125
+ }.bind(obj, original);
159126
+ obj[method].options = options;
159127
+ }
159128
+ };
159129
+ }));
159130
+ //#endregion
159131
+ //#region ../../node_modules/retry/index.js
159132
+ var require_retry = /* @__PURE__ */ __commonJSMin(((exports, module) => {
159133
+ module.exports = require_retry$1();
159134
+ }));
159135
+ //#endregion
159136
+ //#region ../../node_modules/signal-exit/signals.js
159137
+ var require_signals = /* @__PURE__ */ __commonJSMin(((exports, module) => {
159138
+ module.exports = [
159139
+ "SIGABRT",
159140
+ "SIGALRM",
159141
+ "SIGHUP",
159142
+ "SIGINT",
159143
+ "SIGTERM"
159144
+ ];
159145
+ if (process.platform !== "win32") module.exports.push("SIGVTALRM", "SIGXCPU", "SIGXFSZ", "SIGUSR2", "SIGTRAP", "SIGSYS", "SIGQUIT", "SIGIOT");
159146
+ if (process.platform === "linux") module.exports.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT", "SIGUNUSED");
159147
+ }));
159148
+ //#endregion
159149
+ //#region ../../node_modules/signal-exit/index.js
159150
+ var require_signal_exit = /* @__PURE__ */ __commonJSMin(((exports, module) => {
159151
+ var process = global.process;
159152
+ var processOk = function(process) {
159153
+ return process && typeof process === "object" && typeof process.removeListener === "function" && typeof process.emit === "function" && typeof process.reallyExit === "function" && typeof process.listeners === "function" && typeof process.kill === "function" && typeof process.pid === "number" && typeof process.on === "function";
159154
+ };
159155
+ /* istanbul ignore if */
159156
+ if (!processOk(process)) module.exports = function() {
159157
+ return function() {};
159158
+ };
159159
+ else {
159160
+ var assert = __require("assert");
159161
+ var signals = require_signals();
159162
+ var isWin = /^win/i.test(process.platform);
159163
+ var EE = __require("events");
159164
+ /* istanbul ignore if */
159165
+ if (typeof EE !== "function") EE = EE.EventEmitter;
159166
+ var emitter;
159167
+ if (process.__signal_exit_emitter__) emitter = process.__signal_exit_emitter__;
159168
+ else {
159169
+ emitter = process.__signal_exit_emitter__ = new EE();
159170
+ emitter.count = 0;
159171
+ emitter.emitted = {};
159172
+ }
159173
+ if (!emitter.infinite) {
159174
+ emitter.setMaxListeners(Infinity);
159175
+ emitter.infinite = true;
159176
+ }
159177
+ module.exports = function(cb, opts) {
159178
+ /* istanbul ignore if */
159179
+ if (!processOk(global.process)) return function() {};
159180
+ assert.equal(typeof cb, "function", "a callback must be provided for exit handler");
159181
+ if (loaded === false) load();
159182
+ var ev = "exit";
159183
+ if (opts && opts.alwaysLast) ev = "afterexit";
159184
+ var remove = function() {
159185
+ emitter.removeListener(ev, cb);
159186
+ if (emitter.listeners("exit").length === 0 && emitter.listeners("afterexit").length === 0) unload();
159187
+ };
159188
+ emitter.on(ev, cb);
159189
+ return remove;
159190
+ };
159191
+ var unload = function unload() {
159192
+ if (!loaded || !processOk(global.process)) return;
159193
+ loaded = false;
159194
+ signals.forEach(function(sig) {
159195
+ try {
159196
+ process.removeListener(sig, sigListeners[sig]);
159197
+ } catch (er) {}
159198
+ });
159199
+ process.emit = originalProcessEmit;
159200
+ process.reallyExit = originalProcessReallyExit;
159201
+ emitter.count -= 1;
159202
+ };
159203
+ module.exports.unload = unload;
159204
+ var emit = function emit(event, code, signal) {
159205
+ /* istanbul ignore if */
159206
+ if (emitter.emitted[event]) return;
159207
+ emitter.emitted[event] = true;
159208
+ emitter.emit(event, code, signal);
159209
+ };
159210
+ var sigListeners = {};
159211
+ signals.forEach(function(sig) {
159212
+ sigListeners[sig] = function listener() {
159213
+ /* istanbul ignore if */
159214
+ if (!processOk(global.process)) return;
159215
+ if (process.listeners(sig).length === emitter.count) {
159216
+ unload();
159217
+ emit("exit", null, sig);
159218
+ /* istanbul ignore next */
159219
+ emit("afterexit", null, sig);
159220
+ /* istanbul ignore next */
159221
+ if (isWin && sig === "SIGHUP") sig = "SIGINT";
159222
+ /* istanbul ignore next */
159223
+ process.kill(process.pid, sig);
159224
+ }
159225
+ };
159226
+ });
159227
+ module.exports.signals = function() {
159228
+ return signals;
159229
+ };
159230
+ var loaded = false;
159231
+ var load = function load() {
159232
+ if (loaded || !processOk(global.process)) return;
159233
+ loaded = true;
159234
+ emitter.count += 1;
159235
+ signals = signals.filter(function(sig) {
159236
+ try {
159237
+ process.on(sig, sigListeners[sig]);
159238
+ return true;
159239
+ } catch (er) {
159240
+ return false;
159241
+ }
159242
+ });
159243
+ process.emit = processEmit;
159244
+ process.reallyExit = processReallyExit;
159245
+ };
159246
+ module.exports.load = load;
159247
+ var originalProcessReallyExit = process.reallyExit;
159248
+ var processReallyExit = function processReallyExit(code) {
159249
+ /* istanbul ignore if */
159250
+ if (!processOk(global.process)) return;
159251
+ process.exitCode = code || 0;
159252
+ emit("exit", process.exitCode, null);
159253
+ /* istanbul ignore next */
159254
+ emit("afterexit", process.exitCode, null);
159255
+ /* istanbul ignore next */
159256
+ originalProcessReallyExit.call(process, process.exitCode);
159257
+ };
159258
+ var originalProcessEmit = process.emit;
159259
+ var processEmit = function processEmit(ev, arg) {
159260
+ if (ev === "exit" && processOk(global.process)) {
159261
+ /* istanbul ignore else */
159262
+ if (arg !== void 0) process.exitCode = arg;
159263
+ var ret = originalProcessEmit.apply(this, arguments);
159264
+ /* istanbul ignore next */
159265
+ emit("exit", process.exitCode, null);
159266
+ /* istanbul ignore next */
159267
+ emit("afterexit", process.exitCode, null);
159268
+ /* istanbul ignore next */
159269
+ return ret;
159270
+ } else return originalProcessEmit.apply(this, arguments);
159271
+ };
159272
+ }
159273
+ }));
159274
+ //#endregion
159275
+ //#region ../../node_modules/proper-lockfile/lib/mtime-precision.js
159276
+ var require_mtime_precision = /* @__PURE__ */ __commonJSMin(((exports, module) => {
159277
+ var cacheSymbol = Symbol();
159278
+ function probe(file, fs, callback) {
159279
+ const cachedPrecision = fs[cacheSymbol];
159280
+ if (cachedPrecision) return fs.stat(file, (err, stat) => {
159281
+ /* istanbul ignore if */
159282
+ if (err) return callback(err);
159283
+ callback(null, stat.mtime, cachedPrecision);
159284
+ });
159285
+ const mtime = /* @__PURE__ */ new Date(Math.ceil(Date.now() / 1e3) * 1e3 + 5);
159286
+ fs.utimes(file, mtime, mtime, (err) => {
159287
+ /* istanbul ignore if */
159288
+ if (err) return callback(err);
159289
+ fs.stat(file, (err, stat) => {
159290
+ /* istanbul ignore if */
159291
+ if (err) return callback(err);
159292
+ const precision = stat.mtime.getTime() % 1e3 === 0 ? "s" : "ms";
159293
+ Object.defineProperty(fs, cacheSymbol, { value: precision });
159294
+ callback(null, stat.mtime, precision);
159295
+ });
159296
+ });
159297
+ }
159298
+ function getMtime(precision) {
159299
+ let now = Date.now();
159300
+ if (precision === "s") now = Math.ceil(now / 1e3) * 1e3;
159301
+ return new Date(now);
159302
+ }
159303
+ module.exports.probe = probe;
159304
+ module.exports.getMtime = getMtime;
159305
+ }));
159306
+ //#endregion
159307
+ //#region ../../node_modules/proper-lockfile/lib/lockfile.js
159308
+ var require_lockfile = /* @__PURE__ */ __commonJSMin(((exports, module) => {
159309
+ var path = __require("path");
159310
+ var fs = require_graceful_fs();
159311
+ var retry = require_retry();
159312
+ var onExit = require_signal_exit();
159313
+ var mtimePrecision = require_mtime_precision();
159314
+ var locks = {};
159315
+ function getLockFile(file, options) {
159316
+ return options.lockfilePath || `${file}.lock`;
159317
+ }
159318
+ function resolveCanonicalPath(file, options, callback) {
159319
+ if (!options.realpath) return callback(null, path.resolve(file));
159320
+ options.fs.realpath(file, callback);
159321
+ }
159322
+ function acquireLock(file, options, callback) {
159323
+ const lockfilePath = getLockFile(file, options);
159324
+ options.fs.mkdir(lockfilePath, (err) => {
159325
+ if (!err) return mtimePrecision.probe(lockfilePath, options.fs, (err, mtime, mtimePrecision) => {
159326
+ /* istanbul ignore if */
159327
+ if (err) {
159328
+ options.fs.rmdir(lockfilePath, () => {});
159329
+ return callback(err);
159330
+ }
159331
+ callback(null, mtime, mtimePrecision);
159332
+ });
159333
+ if (err.code !== "EEXIST") return callback(err);
159334
+ if (options.stale <= 0) return callback(Object.assign(/* @__PURE__ */ new Error("Lock file is already being held"), {
159335
+ code: "ELOCKED",
159336
+ file
159337
+ }));
159338
+ options.fs.stat(lockfilePath, (err, stat) => {
159339
+ if (err) {
159340
+ if (err.code === "ENOENT") return acquireLock(file, {
159341
+ ...options,
159342
+ stale: 0
159343
+ }, callback);
159344
+ return callback(err);
159345
+ }
159346
+ if (!isLockStale(stat, options)) return callback(Object.assign(/* @__PURE__ */ new Error("Lock file is already being held"), {
159347
+ code: "ELOCKED",
159348
+ file
159349
+ }));
159350
+ removeLock(file, options, (err) => {
159351
+ if (err) return callback(err);
159352
+ acquireLock(file, {
159353
+ ...options,
159354
+ stale: 0
159355
+ }, callback);
159356
+ });
159357
+ });
159358
+ });
159359
+ }
159360
+ function isLockStale(stat, options) {
159361
+ return stat.mtime.getTime() < Date.now() - options.stale;
159362
+ }
159363
+ function removeLock(file, options, callback) {
159364
+ options.fs.rmdir(getLockFile(file, options), (err) => {
159365
+ if (err && err.code !== "ENOENT") return callback(err);
159366
+ callback();
159367
+ });
159368
+ }
159369
+ function updateLock(file, options) {
159370
+ const lock = locks[file];
159371
+ /* istanbul ignore if */
159372
+ if (lock.updateTimeout) return;
159373
+ lock.updateDelay = lock.updateDelay || options.update;
159374
+ lock.updateTimeout = setTimeout(() => {
159375
+ lock.updateTimeout = null;
159376
+ options.fs.stat(lock.lockfilePath, (err, stat) => {
159377
+ const isOverThreshold = lock.lastUpdate + options.stale < Date.now();
159378
+ if (err) {
159379
+ if (err.code === "ENOENT" || isOverThreshold) return setLockAsCompromised(file, lock, Object.assign(err, { code: "ECOMPROMISED" }));
159380
+ lock.updateDelay = 1e3;
159381
+ return updateLock(file, options);
159382
+ }
159383
+ if (!(lock.mtime.getTime() === stat.mtime.getTime())) return setLockAsCompromised(file, lock, Object.assign(/* @__PURE__ */ new Error("Unable to update lock within the stale threshold"), { code: "ECOMPROMISED" }));
159384
+ const mtime = mtimePrecision.getMtime(lock.mtimePrecision);
159385
+ options.fs.utimes(lock.lockfilePath, mtime, mtime, (err) => {
159386
+ const isOverThreshold = lock.lastUpdate + options.stale < Date.now();
159387
+ if (lock.released) return;
159388
+ if (err) {
159389
+ if (err.code === "ENOENT" || isOverThreshold) return setLockAsCompromised(file, lock, Object.assign(err, { code: "ECOMPROMISED" }));
159390
+ lock.updateDelay = 1e3;
159391
+ return updateLock(file, options);
159392
+ }
159393
+ lock.mtime = mtime;
159394
+ lock.lastUpdate = Date.now();
159395
+ lock.updateDelay = null;
159396
+ updateLock(file, options);
159397
+ });
159398
+ });
159399
+ }, lock.updateDelay);
159400
+ /* istanbul ignore else */
159401
+ if (lock.updateTimeout.unref) lock.updateTimeout.unref();
159402
+ }
159403
+ function setLockAsCompromised(file, lock, err) {
159404
+ lock.released = true;
159405
+ /* istanbul ignore if */
159406
+ if (lock.updateTimeout) clearTimeout(lock.updateTimeout);
159407
+ if (locks[file] === lock) delete locks[file];
159408
+ lock.options.onCompromised(err);
159409
+ }
159410
+ function lock(file, options, callback) {
159411
+ /* istanbul ignore next */
159412
+ options = {
159413
+ stale: 1e4,
159414
+ update: null,
159415
+ realpath: true,
159416
+ retries: 0,
159417
+ fs,
159418
+ onCompromised: (err) => {
159419
+ throw err;
159420
+ },
159421
+ ...options
159422
+ };
159423
+ options.retries = options.retries || 0;
159424
+ options.retries = typeof options.retries === "number" ? { retries: options.retries } : options.retries;
159425
+ options.stale = Math.max(options.stale || 0, 2e3);
159426
+ options.update = options.update == null ? options.stale / 2 : options.update || 0;
159427
+ options.update = Math.max(Math.min(options.update, options.stale / 2), 1e3);
159428
+ resolveCanonicalPath(file, options, (err, file) => {
159429
+ if (err) return callback(err);
159430
+ const operation = retry.operation(options.retries);
159431
+ operation.attempt(() => {
159432
+ acquireLock(file, options, (err, mtime, mtimePrecision) => {
159433
+ if (operation.retry(err)) return;
159434
+ if (err) return callback(operation.mainError());
159435
+ const lock = locks[file] = {
159436
+ lockfilePath: getLockFile(file, options),
159437
+ mtime,
159438
+ mtimePrecision,
159439
+ options,
159440
+ lastUpdate: Date.now()
159441
+ };
159442
+ updateLock(file, options);
159443
+ callback(null, (releasedCallback) => {
159444
+ if (lock.released) return releasedCallback && releasedCallback(Object.assign(/* @__PURE__ */ new Error("Lock is already released"), { code: "ERELEASED" }));
159445
+ unlock(file, {
159446
+ ...options,
159447
+ realpath: false
159448
+ }, releasedCallback);
159449
+ });
159450
+ });
159451
+ });
159452
+ });
159453
+ }
159454
+ function unlock(file, options, callback) {
159455
+ options = {
159456
+ fs,
159457
+ realpath: true,
159458
+ ...options
159459
+ };
159460
+ resolveCanonicalPath(file, options, (err, file) => {
159461
+ if (err) return callback(err);
159462
+ const lock = locks[file];
159463
+ if (!lock) return callback(Object.assign(/* @__PURE__ */ new Error("Lock is not acquired/owned by you"), { code: "ENOTACQUIRED" }));
159464
+ lock.updateTimeout && clearTimeout(lock.updateTimeout);
159465
+ lock.released = true;
159466
+ delete locks[file];
159467
+ removeLock(file, options, callback);
159468
+ });
159469
+ }
159470
+ function check(file, options, callback) {
159471
+ options = {
159472
+ stale: 1e4,
159473
+ realpath: true,
159474
+ fs,
159475
+ ...options
159476
+ };
159477
+ options.stale = Math.max(options.stale || 0, 2e3);
159478
+ resolveCanonicalPath(file, options, (err, file) => {
159479
+ if (err) return callback(err);
159480
+ options.fs.stat(getLockFile(file, options), (err, stat) => {
159481
+ if (err) return err.code === "ENOENT" ? callback(null, false) : callback(err);
159482
+ return callback(null, !isLockStale(stat, options));
159483
+ });
159484
+ });
159485
+ }
159486
+ function getLocks() {
159487
+ return locks;
159488
+ }
159489
+ /* istanbul ignore next */
159490
+ onExit(() => {
159491
+ for (const file in locks) {
159492
+ const options = locks[file].options;
159493
+ try {
159494
+ options.fs.rmdirSync(getLockFile(file, options));
159495
+ } catch (e) {}
159496
+ }
159497
+ });
159498
+ module.exports.lock = lock;
159499
+ module.exports.unlock = unlock;
159500
+ module.exports.check = check;
159501
+ module.exports.getLocks = getLocks;
159502
+ }));
159503
+ //#endregion
159504
+ //#region ../../node_modules/proper-lockfile/lib/adapter.js
159505
+ var require_adapter = /* @__PURE__ */ __commonJSMin(((exports, module) => {
159506
+ var fs = require_graceful_fs();
159507
+ function createSyncFs(fs) {
159508
+ const methods = [
159509
+ "mkdir",
159510
+ "realpath",
159511
+ "stat",
159512
+ "rmdir",
159513
+ "utimes"
159514
+ ];
159515
+ const newFs = { ...fs };
159516
+ methods.forEach((method) => {
159517
+ newFs[method] = (...args) => {
159518
+ const callback = args.pop();
159519
+ let ret;
159520
+ try {
159521
+ ret = fs[`${method}Sync`](...args);
159522
+ } catch (err) {
159523
+ return callback(err);
159524
+ }
159525
+ callback(null, ret);
159526
+ };
159527
+ });
159528
+ return newFs;
159529
+ }
159530
+ function toPromise(method) {
159531
+ return (...args) => new Promise((resolve, reject) => {
159532
+ args.push((err, result) => {
159533
+ if (err) reject(err);
159534
+ else resolve(result);
159535
+ });
159536
+ method(...args);
159537
+ });
159538
+ }
159539
+ function toSync(method) {
159540
+ return (...args) => {
159541
+ let err;
159542
+ let result;
159543
+ args.push((_err, _result) => {
159544
+ err = _err;
159545
+ result = _result;
159546
+ });
159547
+ method(...args);
159548
+ if (err) throw err;
159549
+ return result;
159550
+ };
159551
+ }
159552
+ function toSyncOptions(options) {
159553
+ options = { ...options };
159554
+ options.fs = createSyncFs(options.fs || fs);
159555
+ if (typeof options.retries === "number" && options.retries > 0 || options.retries && typeof options.retries.retries === "number" && options.retries.retries > 0) throw Object.assign(/* @__PURE__ */ new Error("Cannot use retries with the sync api"), { code: "ESYNC" });
159556
+ return options;
159557
+ }
159558
+ module.exports = {
159559
+ toPromise,
159560
+ toSync,
159561
+ toSyncOptions
159562
+ };
159563
+ }));
159564
+ //#endregion
159565
+ //#region src/lock.ts
159566
+ var import_proper_lockfile = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
159567
+ var lockfile = require_lockfile();
159568
+ var { toPromise, toSync, toSyncOptions } = require_adapter();
159569
+ async function lock(file, options) {
159570
+ return toPromise(await toPromise(lockfile.lock)(file, options));
159571
+ }
159572
+ function lockSync(file, options) {
159573
+ return toSync(toSync(lockfile.lock)(file, toSyncOptions(options)));
159574
+ }
159575
+ function unlock(file, options) {
159576
+ return toPromise(lockfile.unlock)(file, options);
159577
+ }
159578
+ function unlockSync(file, options) {
159579
+ return toSync(lockfile.unlock)(file, toSyncOptions(options));
159580
+ }
159581
+ function check(file, options) {
159582
+ return toPromise(lockfile.check)(file, options);
159583
+ }
159584
+ function checkSync(file, options) {
159585
+ return toSync(lockfile.check)(file, toSyncOptions(options));
159586
+ }
159587
+ module.exports = lock;
159588
+ module.exports.lock = lock;
159589
+ module.exports.unlock = unlock;
159590
+ module.exports.lockSync = lockSync;
159591
+ module.exports.unlockSync = unlockSync;
159592
+ module.exports.check = check;
159593
+ module.exports.checkSync = checkSync;
159594
+ })))(), 1);
159595
+ var LOCKFILE_NAME = "lock";
159596
+ var READERS_DIR_NAME = "readers";
159597
+ var READER_POLL_INTERVAL_MS = 100;
159598
+ function lockfilePath(dir) {
159599
+ return join(dir, LOCKFILE_NAME);
159600
+ }
159601
+ function readersDir(dir) {
159602
+ return join(dir, READERS_DIR_NAME);
159603
+ }
159604
+ function ensureDir(dir) {
159605
+ mkdirSync(dir, { recursive: true });
159606
+ }
159607
+ function retriesForTimeout(timeoutMs) {
159608
+ return {
159609
+ retries: Math.max(1, Math.floor(timeoutMs / 200)),
159610
+ minTimeout: 100,
159611
+ maxTimeout: 500,
159612
+ factor: 1.5
159613
+ };
159614
+ }
159615
+ function errorCode(err) {
159616
+ if (err instanceof Error && "code" in err) {
159617
+ const { code } = err;
159618
+ if (typeof code === "string") return code;
159619
+ }
159620
+ }
159621
+ function isLockedError(err) {
159622
+ return errorCode(err) === "ELOCKED";
159623
+ }
159624
+ function lockedMessage(timeoutMs) {
159625
+ return `Another CLI process is holding the budget (waited ${Math.round(timeoutMs / 1e3)}s). Retry, or use a different --data-dir.`;
159626
+ }
159627
+ function pidIsAlive(pid) {
159628
+ if (pid <= 0) return false;
159629
+ try {
159630
+ process.kill(pid, 0);
159631
+ return true;
159632
+ } catch (err) {
159633
+ return errorCode(err) === "EPERM";
159634
+ }
159635
+ }
159636
+ function readReaderNames(readers) {
159637
+ try {
159638
+ return readdirSync(readers);
159639
+ } catch (err) {
159640
+ if (errorCode(err) === "ENOENT") return [];
159641
+ throw err;
159642
+ }
159643
+ }
159644
+ function sweepStaleReaders(dir) {
159645
+ const readers = readersDir(dir);
159646
+ for (const name of readReaderNames(readers)) {
159647
+ const pid = Number(name.split("-")[0]);
159648
+ if (!Number.isFinite(pid) || !pidIsAlive(pid)) rmSync(join(readers, name), { force: true });
159649
+ }
159650
+ }
159651
+ async function waitForReadersEmpty(dir, timeoutMs) {
159652
+ const readers = readersDir(dir);
159653
+ const deadline = Date.now() + timeoutMs;
159654
+ while (Date.now() < deadline) {
159655
+ sweepStaleReaders(dir);
159656
+ if (readReaderNames(readers).length === 0) return;
159657
+ await new Promise((resolve) => setTimeout(resolve, READER_POLL_INTERVAL_MS));
159658
+ }
159659
+ throw new Error(lockedMessage(timeoutMs));
159660
+ }
159661
+ async function acquireGate(dir, timeoutMs) {
159662
+ ensureDir(dir);
159663
+ try {
159664
+ return await import_proper_lockfile.default.lock(dir, {
159665
+ lockfilePath: lockfilePath(dir),
159666
+ retries: retriesForTimeout(timeoutMs),
159667
+ stale: 3e4
159668
+ });
159669
+ } catch (err) {
159670
+ if (isLockedError(err)) throw new Error(lockedMessage(timeoutMs));
159671
+ throw err;
159672
+ }
159673
+ }
159674
+ async function acquireExclusive(dir, { timeoutMs }) {
159675
+ const start = Date.now();
159676
+ const release = await acquireGate(dir, timeoutMs);
159677
+ try {
159678
+ await waitForReadersEmpty(dir, Math.max(0, timeoutMs - (Date.now() - start)));
159679
+ } catch (err) {
159680
+ await release();
159681
+ throw err;
159682
+ }
159683
+ return () => release();
159684
+ }
159685
+ async function acquireShared(dir, { timeoutMs }) {
159686
+ const gate = await acquireGate(dir, timeoutMs);
159687
+ let markerPath;
159688
+ try {
159689
+ const readers = readersDir(dir);
159690
+ ensureDir(readers);
159691
+ markerPath = join(readers, `${process.pid}-${randomBytes(6).toString("hex")}`);
159692
+ writeFileSync(markerPath, "");
159693
+ } catch (err) {
159694
+ await gate();
159695
+ throw err;
159696
+ }
159697
+ await gate();
159698
+ return async () => {
159699
+ rmSync(markerPath, { force: true });
158149
159700
  };
158150
159701
  }
158151
159702
  //#endregion
@@ -158153,10 +159704,13 @@ async function resolveConfig(cliOpts) {
158153
159704
  function info(message, verbose) {
158154
159705
  if (verbose) process.stderr.write(message + "\n");
158155
159706
  }
158156
- async function withConnection(globalOpts, fn, options = {}) {
158157
- const { loadBudget = true } = options;
159707
+ async function resolveBudgetIdForSyncId(syncId) {
159708
+ const match = (await api.getBudgets()).find((b) => typeof b.id === "string" && (b.groupId === syncId || b.cloudFileId === syncId));
159709
+ if (!match?.id) throw new Error(`Could not resolve on-disk budget id for syncId ${syncId} after download.`);
159710
+ return match.id;
159711
+ }
159712
+ async function withConnection(globalOpts, fn, { mutates, skipBudget = false }) {
158158
159713
  const config = await resolveConfig(globalOpts);
158159
- mkdirSync(config.dataDir, { recursive: true });
158160
159714
  info(`Connecting to ${config.serverUrl}...`, globalOpts.verbose);
158161
159715
  if (config.sessionToken) await api.init({
158162
159716
  serverURL: config.serverUrl,
@@ -158172,11 +159726,68 @@ async function withConnection(globalOpts, fn, options = {}) {
158172
159726
  });
158173
159727
  else throw new Error("Authentication required. Provide --password or --session-token, or set ACTUAL_PASSWORD / ACTUAL_SESSION_TOKEN.");
158174
159728
  try {
158175
- if (loadBudget && config.syncId) {
158176
- info(`Downloading budget ${config.syncId}...`, globalOpts.verbose);
158177
- await api.downloadBudget(config.syncId, { password: config.encryptionPassword });
158178
- } else if (loadBudget && !config.syncId) throw new Error("Sync ID is required for this command. Set --sync-id or ACTUAL_SYNC_ID.");
158179
- return await fn();
159729
+ if (skipBudget) return await fn(config);
159730
+ if (!config.syncId) throw new Error("Sync ID is required for this command. Set --sync-id or ACTUAL_SYNC_ID.");
159731
+ const meta = getMetaDir(config.dataDir, config.syncId);
159732
+ let release = null;
159733
+ if (!config.noLock) release = mutates ? await acquireExclusive(meta, { timeoutMs: config.lockTimeout * 1e3 }) : await acquireShared(meta, { timeoutMs: config.lockTimeout * 1e3 });
159734
+ try {
159735
+ const cachedState = readCacheState(meta);
159736
+ const decision = decideSyncAction({
159737
+ state: cachedState,
159738
+ config: {
159739
+ syncId: config.syncId,
159740
+ serverUrl: config.serverUrl
159741
+ },
159742
+ now: Date.now(),
159743
+ ttlMs: config.cacheTtl * 1e3,
159744
+ mutates,
159745
+ refresh: config.refresh,
159746
+ encrypted: Boolean(config.encryptionPassword)
159747
+ });
159748
+ let state;
159749
+ if (decision.action === "download") {
159750
+ info(cachedState === null ? `Downloading budget ${config.syncId} for the first time...` : `Re-downloading budget ${config.syncId} (cache invalidated)...`, globalOpts.verbose);
159751
+ await api.downloadBudget(config.syncId, { password: config.encryptionPassword });
159752
+ const budgetId = await resolveBudgetIdForSyncId(config.syncId);
159753
+ const now = Date.now();
159754
+ state = {
159755
+ version: 1,
159756
+ syncId: config.syncId,
159757
+ budgetId,
159758
+ serverUrl: config.serverUrl,
159759
+ lastSyncedAt: now,
159760
+ lastDownloadedAt: now
159761
+ };
159762
+ writeCacheState(meta, state);
159763
+ } else if (decision.action === "skip") {
159764
+ info(`Using cached budget (synced ${Math.round((Date.now() - decision.state.lastSyncedAt) / 1e3)}s ago)...`, globalOpts.verbose);
159765
+ await api.loadBudget(decision.state.budgetId);
159766
+ state = decision.state;
159767
+ } else {
159768
+ info(`Syncing budget ${config.syncId}...`, globalOpts.verbose);
159769
+ await api.loadBudget(decision.state.budgetId);
159770
+ await api.sync();
159771
+ state = {
159772
+ ...decision.state,
159773
+ lastSyncedAt: Date.now()
159774
+ };
159775
+ writeCacheState(meta, state);
159776
+ }
159777
+ const result = await fn(config);
159778
+ if (mutates) {
159779
+ info(`Pushing changes for ${config.syncId}...`, globalOpts.verbose);
159780
+ await api.sync();
159781
+ state = {
159782
+ ...state,
159783
+ lastSyncedAt: Date.now()
159784
+ };
159785
+ writeCacheState(meta, state);
159786
+ }
159787
+ return result;
159788
+ } finally {
159789
+ if (release) await release();
159790
+ }
158180
159791
  } finally {
158181
159792
  await api.shutdown();
158182
159793
  }
@@ -159901,7 +161512,7 @@ function registerAccountsCommand(program) {
159901
161512
  closed: a.closed,
159902
161513
  balance: balances[i]
159903
161514
  })), opts.format);
159904
- });
161515
+ }, { mutates: false });
159905
161516
  });
159906
161517
  accounts.command("create").description("Create a new account").requiredOption("--name <name>", "Account name").option("--offbudget", "Create as off-budget account", false).option("--balance <amount>", "Initial balance in cents (e.g. 50000 = 500.00)", "0").action(async (cmdOpts) => {
159907
161518
  const balance = parseIntFlag(cmdOpts.balance, "--balance");
@@ -159911,7 +161522,7 @@ function registerAccountsCommand(program) {
159911
161522
  name: cmdOpts.name,
159912
161523
  offbudget: cmdOpts.offbudget
159913
161524
  }, balance) }, opts.format);
159914
- });
161525
+ }, { mutates: true });
159915
161526
  });
159916
161527
  accounts.command("update <id>").description("Update an account").option("--name <name>", "New account name").option("--offbudget <bool>", "Set off-budget status").action(async (id, cmdOpts) => {
159917
161528
  const opts = program.opts();
@@ -159929,7 +161540,7 @@ function registerAccountsCommand(program) {
159929
161540
  success: true,
159930
161541
  id
159931
161542
  }, opts.format);
159932
- });
161543
+ }, { mutates: true });
159933
161544
  });
159934
161545
  accounts.command("close <id>").description("Close an account").option("--transfer-account <id>", "Transfer remaining balance to this account").option("--transfer-category <id>", "Transfer remaining balance to this category").action(async (id, cmdOpts) => {
159935
161546
  const opts = program.opts();
@@ -159939,7 +161550,7 @@ function registerAccountsCommand(program) {
159939
161550
  success: true,
159940
161551
  id
159941
161552
  }, opts.format);
159942
- });
161553
+ }, { mutates: true });
159943
161554
  });
159944
161555
  accounts.command("reopen <id>").description("Reopen a closed account").action(async (id) => {
159945
161556
  const opts = program.opts();
@@ -159949,7 +161560,7 @@ function registerAccountsCommand(program) {
159949
161560
  success: true,
159950
161561
  id
159951
161562
  }, opts.format);
159952
- });
161563
+ }, { mutates: true });
159953
161564
  });
159954
161565
  accounts.command("delete <id>").description("Delete an account").action(async (id) => {
159955
161566
  const opts = program.opts();
@@ -159959,7 +161570,7 @@ function registerAccountsCommand(program) {
159959
161570
  success: true,
159960
161571
  id
159961
161572
  }, opts.format);
159962
- });
161573
+ }, { mutates: true });
159963
161574
  });
159964
161575
  accounts.command("balance <id>").description("Get account balance").option("--cutoff <date>", "Cutoff date (YYYY-MM-DD)").action(async (id, cmdOpts) => {
159965
161576
  let cutoff;
@@ -159974,7 +161585,7 @@ function registerAccountsCommand(program) {
159974
161585
  id,
159975
161586
  balance: await api.getAccountBalance(id, cutoff)
159976
161587
  }, opts.format);
159977
- });
161588
+ }, { mutates: false });
159978
161589
  });
159979
161590
  }
159980
161591
  //#endregion
@@ -159985,37 +161596,36 @@ function registerBudgetsCommand(program) {
159985
161596
  const opts = program.opts();
159986
161597
  await withConnection(opts, async () => {
159987
161598
  printOutput(await api.getBudgets(), opts.format);
159988
- }, { loadBudget: false });
161599
+ }, {
161600
+ mutates: false,
161601
+ skipBudget: true
161602
+ });
159989
161603
  });
159990
161604
  budgets.command("download <syncId>").description("Download a budget by sync ID").option("--encryption-password <password>", "Encryption password").action(async (syncId, cmdOpts) => {
159991
161605
  const opts = program.opts();
159992
- const password = (await resolveConfig(opts)).encryptionPassword ?? cmdOpts.encryptionPassword;
159993
- await withConnection(opts, async () => {
161606
+ await withConnection(opts, async (config) => {
161607
+ const password = cmdOpts.encryptionPassword ?? config.encryptionPassword;
159994
161608
  await api.downloadBudget(syncId, { password });
159995
161609
  printOutput({
159996
161610
  success: true,
159997
161611
  syncId
159998
161612
  }, opts.format);
159999
- }, { loadBudget: false });
160000
- });
160001
- budgets.command("sync").description("Sync the current budget").action(async () => {
160002
- const opts = program.opts();
160003
- await withConnection(opts, async () => {
160004
- await api.sync();
160005
- printOutput({ success: true }, opts.format);
161613
+ }, {
161614
+ mutates: false,
161615
+ skipBudget: true
160006
161616
  });
160007
161617
  });
160008
161618
  budgets.command("months").description("List available budget months").action(async () => {
160009
161619
  const opts = program.opts();
160010
161620
  await withConnection(opts, async () => {
160011
161621
  printOutput(await api.getBudgetMonths(), opts.format);
160012
- });
161622
+ }, { mutates: false });
160013
161623
  });
160014
161624
  budgets.command("month <month>").description("Get budget data for a specific month (YYYY-MM)").action(async (month) => {
160015
161625
  const opts = program.opts();
160016
161626
  await withConnection(opts, async () => {
160017
161627
  printOutput(await api.getBudgetMonth(month), opts.format);
160018
- });
161628
+ }, { mutates: false });
160019
161629
  });
160020
161630
  budgets.command("set-amount").description("Set budget amount for a category in a month").requiredOption("--month <month>", "Budget month (YYYY-MM)").requiredOption("--category <id>", "Category ID").requiredOption("--amount <amount>", "Amount in cents (e.g. 50000 = 500.00)").action(async (cmdOpts) => {
160021
161631
  const amount = parseIntFlag(cmdOpts.amount, "--amount");
@@ -160023,7 +161633,7 @@ function registerBudgetsCommand(program) {
160023
161633
  await withConnection(opts, async () => {
160024
161634
  await api.setBudgetAmount(cmdOpts.month, cmdOpts.category, amount);
160025
161635
  printOutput({ success: true }, opts.format);
160026
- });
161636
+ }, { mutates: true });
160027
161637
  });
160028
161638
  budgets.command("set-carryover").description("Enable/disable carryover for a category").requiredOption("--month <month>", "Budget month (YYYY-MM)").requiredOption("--category <id>", "Category ID").requiredOption("--flag <bool>", "Enable (true) or disable (false)").action(async (cmdOpts) => {
160029
161639
  const flag = parseBoolFlag(cmdOpts.flag, "--flag");
@@ -160031,7 +161641,7 @@ function registerBudgetsCommand(program) {
160031
161641
  await withConnection(opts, async () => {
160032
161642
  await api.setBudgetCarryover(cmdOpts.month, cmdOpts.category, flag);
160033
161643
  printOutput({ success: true }, opts.format);
160034
- });
161644
+ }, { mutates: true });
160035
161645
  });
160036
161646
  budgets.command("hold-next-month").description("Hold budget amount for next month").requiredOption("--month <month>", "Budget month (YYYY-MM)").requiredOption("--amount <amount>", "Amount in cents (e.g. 50000 = 500.00)").action(async (cmdOpts) => {
160037
161647
  const parsedAmount = parseIntFlag(cmdOpts.amount, "--amount");
@@ -160039,14 +161649,14 @@ function registerBudgetsCommand(program) {
160039
161649
  await withConnection(opts, async () => {
160040
161650
  await api.holdBudgetForNextMonth(cmdOpts.month, parsedAmount);
160041
161651
  printOutput({ success: true }, opts.format);
160042
- });
161652
+ }, { mutates: true });
160043
161653
  });
160044
161654
  budgets.command("reset-hold").description("Reset budget hold for a month").requiredOption("--month <month>", "Budget month (YYYY-MM)").action(async (cmdOpts) => {
160045
161655
  const opts = program.opts();
160046
161656
  await withConnection(opts, async () => {
160047
161657
  await api.resetBudgetHold(cmdOpts.month);
160048
161658
  printOutput({ success: true }, opts.format);
160049
- });
161659
+ }, { mutates: true });
160050
161660
  });
160051
161661
  }
160052
161662
  //#endregion
@@ -160057,7 +161667,7 @@ function registerCategoriesCommand(program) {
160057
161667
  const opts = program.opts();
160058
161668
  await withConnection(opts, async () => {
160059
161669
  printOutput(await api.getCategories(), opts.format);
160060
- });
161670
+ }, { mutates: false });
160061
161671
  });
160062
161672
  categories.command("create").description("Create a new category").requiredOption("--name <name>", "Category name").requiredOption("--group-id <id>", "Category group ID").option("--is-income", "Mark as income category", false).action(async (cmdOpts) => {
160063
161673
  const opts = program.opts();
@@ -160068,7 +161678,7 @@ function registerCategoriesCommand(program) {
160068
161678
  is_income: cmdOpts.isIncome,
160069
161679
  hidden: false
160070
161680
  }) }, opts.format);
160071
- });
161681
+ }, { mutates: true });
160072
161682
  });
160073
161683
  categories.command("update <id>").description("Update a category").option("--name <name>", "New category name").option("--hidden <bool>", "Set hidden status").action(async (id, cmdOpts) => {
160074
161684
  const fields = {};
@@ -160082,7 +161692,7 @@ function registerCategoriesCommand(program) {
160082
161692
  success: true,
160083
161693
  id
160084
161694
  }, opts.format);
160085
- });
161695
+ }, { mutates: true });
160086
161696
  });
160087
161697
  categories.command("delete <id>").description("Delete a category").option("--transfer-to <id>", "Transfer transactions to this category").action(async (id, cmdOpts) => {
160088
161698
  const opts = program.opts();
@@ -160092,7 +161702,7 @@ function registerCategoriesCommand(program) {
160092
161702
  success: true,
160093
161703
  id
160094
161704
  }, opts.format);
160095
- });
161705
+ }, { mutates: true });
160096
161706
  });
160097
161707
  }
160098
161708
  //#endregion
@@ -160103,7 +161713,7 @@ function registerCategoryGroupsCommand(program) {
160103
161713
  const opts = program.opts();
160104
161714
  await withConnection(opts, async () => {
160105
161715
  printOutput(await api.getCategoryGroups(), opts.format);
160106
- });
161716
+ }, { mutates: false });
160107
161717
  });
160108
161718
  groups.command("create").description("Create a new category group").requiredOption("--name <name>", "Group name").option("--is-income", "Mark as income group", false).action(async (cmdOpts) => {
160109
161719
  const opts = program.opts();
@@ -160113,7 +161723,7 @@ function registerCategoryGroupsCommand(program) {
160113
161723
  is_income: cmdOpts.isIncome,
160114
161724
  hidden: false
160115
161725
  }) }, opts.format);
160116
- });
161726
+ }, { mutates: true });
160117
161727
  });
160118
161728
  groups.command("update <id>").description("Update a category group").option("--name <name>", "New group name").option("--hidden <bool>", "Set hidden status").action(async (id, cmdOpts) => {
160119
161729
  const fields = {};
@@ -160127,7 +161737,7 @@ function registerCategoryGroupsCommand(program) {
160127
161737
  success: true,
160128
161738
  id
160129
161739
  }, opts.format);
160130
- });
161740
+ }, { mutates: true });
160131
161741
  });
160132
161742
  groups.command("delete <id>").description("Delete a category group").option("--transfer-to <id>", "Transfer transactions to this category ID").action(async (id, cmdOpts) => {
160133
161743
  const opts = program.opts();
@@ -160137,7 +161747,7 @@ function registerCategoryGroupsCommand(program) {
160137
161747
  success: true,
160138
161748
  id
160139
161749
  }, opts.format);
160140
- });
161750
+ }, { mutates: true });
160141
161751
  });
160142
161752
  }
160143
161753
  //#endregion
@@ -160148,19 +161758,19 @@ function registerPayeesCommand(program) {
160148
161758
  const opts = program.opts();
160149
161759
  await withConnection(opts, async () => {
160150
161760
  printOutput(await api.getPayees(), opts.format);
160151
- });
161761
+ }, { mutates: false });
160152
161762
  });
160153
161763
  payees.command("common").description("List frequently used payees").action(async () => {
160154
161764
  const opts = program.opts();
160155
161765
  await withConnection(opts, async () => {
160156
161766
  printOutput(await api.getCommonPayees(), opts.format);
160157
- });
161767
+ }, { mutates: false });
160158
161768
  });
160159
161769
  payees.command("create").description("Create a new payee").requiredOption("--name <name>", "Payee name").action(async (cmdOpts) => {
160160
161770
  const opts = program.opts();
160161
161771
  await withConnection(opts, async () => {
160162
161772
  printOutput({ id: await api.createPayee({ name: cmdOpts.name }) }, opts.format);
160163
- });
161773
+ }, { mutates: true });
160164
161774
  });
160165
161775
  payees.command("update <id>").description("Update a payee").option("--name <name>", "New payee name").action(async (id, cmdOpts) => {
160166
161776
  const fields = {};
@@ -160173,7 +161783,7 @@ function registerPayeesCommand(program) {
160173
161783
  success: true,
160174
161784
  id
160175
161785
  }, opts.format);
160176
- });
161786
+ }, { mutates: true });
160177
161787
  });
160178
161788
  payees.command("delete <id>").description("Delete a payee").action(async (id) => {
160179
161789
  const opts = program.opts();
@@ -160183,7 +161793,7 @@ function registerPayeesCommand(program) {
160183
161793
  success: true,
160184
161794
  id
160185
161795
  }, opts.format);
160186
- });
161796
+ }, { mutates: true });
160187
161797
  });
160188
161798
  payees.command("merge").description("Merge payees into a target payee").requiredOption("--target <id>", "Target payee ID").requiredOption("--ids <ids>", "Comma-separated payee IDs to merge").action(async (cmdOpts) => {
160189
161799
  const mergeIds = cmdOpts.ids.split(",").map((id) => id.trim()).filter((id) => id.length > 0);
@@ -160192,7 +161802,7 @@ function registerPayeesCommand(program) {
160192
161802
  await withConnection(opts, async () => {
160193
161803
  await api.mergePayees(cmdOpts.target, mergeIds);
160194
161804
  printOutput({ success: true }, opts.format);
160195
- });
161805
+ }, { mutates: true });
160196
161806
  });
160197
161807
  }
160198
161808
  //#endregion
@@ -160201,7 +161811,7 @@ function readJsonInput(cmdOpts) {
160201
161811
  if (cmdOpts.data && cmdOpts.file) throw new Error("Cannot use both --data and --file");
160202
161812
  if (cmdOpts.data) return JSON.parse(cmdOpts.data);
160203
161813
  if (cmdOpts.file) {
160204
- const content = cmdOpts.file === "-" ? readFileSync(0, "utf-8") : readFileSync(cmdOpts.file, "utf-8");
161814
+ const content = cmdOpts.file === "-" ? readFileSync$1(0, "utf-8") : readFileSync$1(cmdOpts.file, "utf-8");
160205
161815
  return JSON.parse(content);
160206
161816
  }
160207
161817
  throw new Error("Either --data or --file is required");
@@ -160424,7 +162034,7 @@ function registerQueryCommand(program) {
160424
162034
  if (!isRecord(result) || !("data" in result)) throw new Error("Query result missing data");
160425
162035
  if (cmdOpts.count) printOutput({ count: result.data }, opts.format);
160426
162036
  else printOutput(result.data, opts.format);
160427
- });
162037
+ }, { mutates: false });
160428
162038
  });
160429
162039
  query.command("tables").description("List available tables for querying").action(() => {
160430
162040
  const opts = program.opts();
@@ -160449,20 +162059,20 @@ function registerRulesCommand(program) {
160449
162059
  const opts = program.opts();
160450
162060
  await withConnection(opts, async () => {
160451
162061
  printOutput(await api.getRules(), opts.format);
160452
- });
162062
+ }, { mutates: false });
160453
162063
  });
160454
162064
  rules.command("payee-rules <payeeId>").description("List rules for a specific payee").action(async (payeeId) => {
160455
162065
  const opts = program.opts();
160456
162066
  await withConnection(opts, async () => {
160457
162067
  printOutput(await api.getPayeeRules(payeeId), opts.format);
160458
- });
162068
+ }, { mutates: false });
160459
162069
  });
160460
162070
  rules.command("create").description("Create a new rule").option("--data <json>", "Rule definition as JSON").option("--file <path>", "Read rule from JSON file (use - for stdin)").action(async (cmdOpts) => {
160461
162071
  const opts = program.opts();
160462
162072
  await withConnection(opts, async () => {
160463
162073
  const rule = readJsonInput(cmdOpts);
160464
162074
  printOutput({ id: await api.createRule(rule) }, opts.format);
160465
- });
162075
+ }, { mutates: true });
160466
162076
  });
160467
162077
  rules.command("update").description("Update a rule").option("--data <json>", "Rule data as JSON (must include id)").option("--file <path>", "Read rule from JSON file (use - for stdin)").action(async (cmdOpts) => {
160468
162078
  const opts = program.opts();
@@ -160470,7 +162080,7 @@ function registerRulesCommand(program) {
160470
162080
  const rule = readJsonInput(cmdOpts);
160471
162081
  await api.updateRule(rule);
160472
162082
  printOutput({ success: true }, opts.format);
160473
- });
162083
+ }, { mutates: true });
160474
162084
  });
160475
162085
  rules.command("delete <id>").description("Delete a rule").action(async (id) => {
160476
162086
  const opts = program.opts();
@@ -160480,7 +162090,7 @@ function registerRulesCommand(program) {
160480
162090
  success: true,
160481
162091
  id
160482
162092
  }, opts.format);
160483
- });
162093
+ }, { mutates: true });
160484
162094
  });
160485
162095
  }
160486
162096
  //#endregion
@@ -160491,14 +162101,14 @@ function registerSchedulesCommand(program) {
160491
162101
  const opts = program.opts();
160492
162102
  await withConnection(opts, async () => {
160493
162103
  printOutput(await api.getSchedules(), opts.format);
160494
- });
162104
+ }, { mutates: false });
160495
162105
  });
160496
162106
  schedules.command("create").description("Create a new schedule").option("--data <json>", "Schedule definition as JSON").option("--file <path>", "Read schedule from JSON file (use - for stdin)").action(async (cmdOpts) => {
160497
162107
  const opts = program.opts();
160498
162108
  await withConnection(opts, async () => {
160499
162109
  const schedule = readJsonInput(cmdOpts);
160500
162110
  printOutput({ id: await api.createSchedule(schedule) }, opts.format);
160501
- });
162111
+ }, { mutates: true });
160502
162112
  });
160503
162113
  schedules.command("update <id>").description("Update a schedule").option("--data <json>", "Fields to update as JSON").option("--file <path>", "Read fields from JSON file (use - for stdin)").option("--reset-next-date", "Reset next occurrence date", false).action(async (id, cmdOpts) => {
160504
162114
  const opts = program.opts();
@@ -160509,7 +162119,7 @@ function registerSchedulesCommand(program) {
160509
162119
  success: true,
160510
162120
  id
160511
162121
  }, opts.format);
160512
- });
162122
+ }, { mutates: true });
160513
162123
  });
160514
162124
  schedules.command("delete <id>").description("Delete a schedule").action(async (id) => {
160515
162125
  const opts = program.opts();
@@ -160519,7 +162129,7 @@ function registerSchedulesCommand(program) {
160519
162129
  success: true,
160520
162130
  id
160521
162131
  }, opts.format);
160522
- });
162132
+ }, { mutates: true });
160523
162133
  });
160524
162134
  }
160525
162135
  //#endregion
@@ -160530,7 +162140,10 @@ function registerServerCommand(program) {
160530
162140
  const opts = program.opts();
160531
162141
  await withConnection(opts, async () => {
160532
162142
  printOutput({ version: await api.getServerVersion() }, opts.format);
160533
- }, { loadBudget: false });
162143
+ }, {
162144
+ mutates: false,
162145
+ skipBudget: true
162146
+ });
160534
162147
  });
160535
162148
  server.command("get-id").description("Get entity ID by name").addOption(new Option("--type <type>", "Entity type").choices([
160536
162149
  "accounts",
@@ -160545,7 +162158,7 @@ function registerServerCommand(program) {
160545
162158
  type: cmdOpts.type,
160546
162159
  name: cmdOpts.name
160547
162160
  }, opts.format);
160548
- });
162161
+ }, { mutates: false });
160549
162162
  });
160550
162163
  server.command("bank-sync").description("Run bank synchronization").option("--account <id>", "Specific account ID to sync").action(async (cmdOpts) => {
160551
162164
  const opts = program.opts();
@@ -160553,7 +162166,69 @@ function registerServerCommand(program) {
160553
162166
  const args = cmdOpts.account ? { accountId: cmdOpts.account } : void 0;
160554
162167
  await api.runBankSync(args);
160555
162168
  printOutput({ success: true }, opts.format);
160556
- });
162169
+ }, { mutates: true });
162170
+ });
162171
+ }
162172
+ //#endregion
162173
+ //#region src/commands/sync.ts
162174
+ async function requireSyncIdAndMeta(opts, flag) {
162175
+ const config = await resolveConfig(opts);
162176
+ if (!config.syncId) throw new Error(`Sync ID is required for sync ${flag}. Set --sync-id or ACTUAL_SYNC_ID.`);
162177
+ return {
162178
+ config,
162179
+ meta: getMetaDir(config.dataDir, config.syncId)
162180
+ };
162181
+ }
162182
+ function registerSyncCommand(program) {
162183
+ program.command("sync").description("Sync the local cached budget with the server, print cache status, or clear the cache").option("--status", "Print cache status without syncing", false).option("--clear", "Delete the local cache; next command re-downloads", false).action(async (cmdOpts) => {
162184
+ const opts = program.opts();
162185
+ if (cmdOpts.status) {
162186
+ const { config, meta } = await requireSyncIdAndMeta(opts, "--status");
162187
+ const state = readCacheState(meta);
162188
+ if (state === null) {
162189
+ printOutput({
162190
+ neverSynced: true,
162191
+ syncId: config.syncId,
162192
+ ttlSeconds: config.cacheTtl
162193
+ }, opts.format);
162194
+ return;
162195
+ }
162196
+ const rawAgeSeconds = Math.round((Date.now() - state.lastSyncedAt) / 1e3);
162197
+ const ageSeconds = Math.max(0, rawAgeSeconds);
162198
+ printOutput({
162199
+ neverSynced: false,
162200
+ syncId: state.syncId,
162201
+ budgetId: state.budgetId,
162202
+ syncedAt: new Date(state.lastSyncedAt).toISOString(),
162203
+ lastDownloadedAt: new Date(state.lastDownloadedAt).toISOString(),
162204
+ ageSeconds,
162205
+ ttlSeconds: config.cacheTtl,
162206
+ stale: rawAgeSeconds < 0 || rawAgeSeconds > config.cacheTtl
162207
+ }, opts.format);
162208
+ return;
162209
+ }
162210
+ if (cmdOpts.clear) {
162211
+ const { config, meta } = await requireSyncIdAndMeta(opts, "--clear");
162212
+ const release = config.noLock ? null : await acquireExclusive(meta, { timeoutMs: config.lockTimeout * 1e3 });
162213
+ try {
162214
+ rmSync(join(meta, CACHE_FILE_NAME), { force: true });
162215
+ } finally {
162216
+ await release?.();
162217
+ }
162218
+ printOutput({
162219
+ cleared: true,
162220
+ syncId: config.syncId
162221
+ }, opts.format);
162222
+ return;
162223
+ }
162224
+ await withConnection(opts, async (config) => {
162225
+ const state = config.syncId ? readCacheState(getMetaDir(config.dataDir, config.syncId)) : null;
162226
+ printOutput({
162227
+ syncedAt: new Date(state?.lastSyncedAt ?? Date.now()).toISOString(),
162228
+ syncId: config.syncId,
162229
+ budgetId: state?.budgetId ?? config.syncId
162230
+ }, opts.format);
162231
+ }, { mutates: true });
160557
162232
  });
160558
162233
  }
160559
162234
  //#endregion
@@ -160564,7 +162239,7 @@ function registerTagsCommand(program) {
160564
162239
  const opts = program.opts();
160565
162240
  await withConnection(opts, async () => {
160566
162241
  printOutput(await api.getTags(), opts.format);
160567
- });
162242
+ }, { mutates: false });
160568
162243
  });
160569
162244
  tags.command("create").description("Create a new tag").requiredOption("--tag <tag>", "Tag name").option("--color <color>", "Tag color").option("--description <description>", "Tag description").action(async (cmdOpts) => {
160570
162245
  const opts = program.opts();
@@ -160574,7 +162249,7 @@ function registerTagsCommand(program) {
160574
162249
  color: cmdOpts.color,
160575
162250
  description: cmdOpts.description
160576
162251
  }) }, opts.format);
160577
- });
162252
+ }, { mutates: true });
160578
162253
  });
160579
162254
  tags.command("update <id>").description("Update a tag").option("--tag <tag>", "New tag name").option("--color <color>", "New tag color").option("--description <description>", "New tag description").action(async (id, cmdOpts) => {
160580
162255
  const fields = {};
@@ -160589,7 +162264,7 @@ function registerTagsCommand(program) {
160589
162264
  success: true,
160590
162265
  id
160591
162266
  }, opts.format);
160592
- });
162267
+ }, { mutates: true });
160593
162268
  });
160594
162269
  tags.command("delete <id>").description("Delete a tag").action(async (id) => {
160595
162270
  const opts = program.opts();
@@ -160599,7 +162274,7 @@ function registerTagsCommand(program) {
160599
162274
  success: true,
160600
162275
  id
160601
162276
  }, opts.format);
160602
- });
162277
+ }, { mutates: true });
160603
162278
  });
160604
162279
  }
160605
162280
  //#endregion
@@ -160610,7 +162285,7 @@ function registerTransactionsCommand(program) {
160610
162285
  const opts = program.opts();
160611
162286
  await withConnection(opts, async () => {
160612
162287
  printOutput(await api.getTransactions(cmdOpts.account, cmdOpts.start, cmdOpts.end), opts.format);
160613
- });
162288
+ }, { mutates: false });
160614
162289
  });
160615
162290
  transactions.command("add").description("Add transactions to an account").requiredOption("--account <id>", "Account ID").option("--data <json>", "Transaction data as JSON array").option("--file <path>", "Read transaction data from JSON file (use - for stdin)").option("--learn-categories", "Learn category assignments", false).option("--run-transfers", "Process transfers", false).action(async (cmdOpts) => {
160616
162291
  const opts = program.opts();
@@ -160620,7 +162295,7 @@ function registerTransactionsCommand(program) {
160620
162295
  learnCategories: cmdOpts.learnCategories,
160621
162296
  runTransfers: cmdOpts.runTransfers
160622
162297
  }), opts.format);
160623
- });
162298
+ }, { mutates: true });
160624
162299
  });
160625
162300
  transactions.command("import").description("Import transactions to an account").requiredOption("--account <id>", "Account ID").option("--data <json>", "Transaction data as JSON array").option("--file <path>", "Read transaction data from JSON file (use - for stdin)").option("--dry-run", "Preview without importing", false).action(async (cmdOpts) => {
160626
162301
  const opts = program.opts();
@@ -160630,7 +162305,7 @@ function registerTransactionsCommand(program) {
160630
162305
  defaultCleared: true,
160631
162306
  dryRun: cmdOpts.dryRun
160632
162307
  }), opts.format);
160633
- });
162308
+ }, { mutates: true });
160634
162309
  });
160635
162310
  transactions.command("update <id>").description("Update a transaction").option("--data <json>", "Fields to update as JSON").option("--file <path>", "Read fields from JSON file (use - for stdin)").action(async (id, cmdOpts) => {
160636
162311
  const opts = program.opts();
@@ -160641,7 +162316,7 @@ function registerTransactionsCommand(program) {
160641
162316
  success: true,
160642
162317
  id
160643
162318
  }, opts.format);
160644
- });
162319
+ }, { mutates: true });
160645
162320
  });
160646
162321
  transactions.command("delete <id>").description("Delete a transaction").action(async (id) => {
160647
162322
  const opts = program.opts();
@@ -160651,13 +162326,13 @@ function registerTransactionsCommand(program) {
160651
162326
  success: true,
160652
162327
  id
160653
162328
  }, opts.format);
160654
- });
162329
+ }, { mutates: true });
160655
162330
  });
160656
162331
  }
160657
162332
  //#endregion
160658
162333
  //#region src/index.ts
160659
162334
  var program = new Command();
160660
- program.name("actual").description("CLI for Actual Budget").version("26.5.0").option("--server-url <url>", "Actual server URL (env: ACTUAL_SERVER_URL)").option("--password <password>", "Server password (env: ACTUAL_PASSWORD)").option("--session-token <token>", "Session token (env: ACTUAL_SESSION_TOKEN)").option("--sync-id <id>", "Budget sync ID (env: ACTUAL_SYNC_ID)").option("--data-dir <path>", "Data directory (env: ACTUAL_DATA_DIR)").option("--encryption-password <password>", "E2E encryption password (env: ACTUAL_ENCRYPTION_PASSWORD)").addOption(new Option("--format <format>", "Output format: json, table, csv").choices([
162335
+ program.name("actual").description("CLI for Actual Budget").version("26.6.0-nightly.20260504").option("--server-url <url>", "Actual server URL (env: ACTUAL_SERVER_URL)").option("--password <password>", "Server password (env: ACTUAL_PASSWORD)").option("--session-token <token>", "Session token (env: ACTUAL_SESSION_TOKEN)").option("--sync-id <id>", "Budget sync ID (env: ACTUAL_SYNC_ID)").option("--data-dir <path>", "Data directory (env: ACTUAL_DATA_DIR)").option("--encryption-password <password>", "E2E encryption password (env: ACTUAL_ENCRYPTION_PASSWORD)").option("--cache-ttl <seconds>", "Cache TTL in seconds (env: ACTUAL_CACHE_TTL; default: 60)", (value) => parseNonNegativeIntFlag(value, "--cache-ttl")).option("--refresh", "Force a sync on this call, ignoring the cache", false).option("--no-cache", "Alias for --refresh").option("--lock-timeout <seconds>", "How long to wait for another CLI process to release the lock (env: ACTUAL_LOCK_TIMEOUT; default: 10)", (value) => parseNonNegativeIntFlag(value, "--lock-timeout")).option("--no-lock", "Disable the budget directory lock (use with care, env: ACTUAL_NO_LOCK)").addOption(new Option("--format <format>", "Output format: json, table, csv").choices([
160661
162336
  "json",
160662
162337
  "table",
160663
162338
  "csv"
@@ -160673,6 +162348,7 @@ registerRulesCommand(program);
160673
162348
  registerSchedulesCommand(program);
160674
162349
  registerQueryCommand(program);
160675
162350
  registerServerCommand(program);
162351
+ registerSyncCommand(program);
160676
162352
  function normalizeThrownMessage(err) {
160677
162353
  if (err instanceof Error) return err.message;
160678
162354
  if (typeof err === "object" && err !== null) try {