@actual-app/sync-server 26.10.0 → 26.11.0-nightly.20261003

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/app.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { t as run } from "./chunks/migrations-7U65Wxd5.js";
2
2
  //#region app.ts
3
3
  run().then(() => {
4
- import("./chunks/app-BgMEdvse.js").then((app) => app.run());
4
+ import("./chunks/app-DllQNg0p.js").then((app) => app.run());
5
5
  }).catch((err) => {
6
6
  console.log("Error starting app:", err);
7
7
  process.exit(1);
@@ -41,7 +41,7 @@ if (values.help) {
41
41
  process.exit();
42
42
  }
43
43
  if (values.version) {
44
- console.log("v26.10.0");
44
+ console.log("v26.11.0-nightly.20261003");
45
45
  process.exit();
46
46
  }
47
47
  var setupDataDir = (dataDir) => {
@@ -1 +1 @@
1
- {"version":3,"file":"actual-server.js","names":[],"sources":["../../bin/actual-server.js"],"sourcesContent":["#!/usr/bin/env node\nimport { existsSync, readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { parseArgs } from 'node:util';\n\nconst args = process.argv;\n\nconst options = {\n help: {\n type: 'boolean',\n short: 'h',\n },\n version: {\n type: 'boolean',\n short: 'v',\n },\n 'reset-password': {\n type: 'boolean',\n },\n config: {\n type: 'string',\n },\n};\n\nconst { values } = parseArgs({\n args,\n options,\n allowPositionals: true,\n});\n\nif (values.help) {\n console.log(\n [\n 'usage: actual-server [options]',\n '',\n 'options:',\n ' --config Path to config file',\n '',\n ' -h --help Print this list and exit.',\n ' -v --version Print the version and exit.',\n '',\n 'Examples:',\n '',\n 'Runs actual-server with default configuration',\n ' actual-server',\n '',\n 'Runs actual-server with custom configuration',\n ' actual-server --config ./config.json',\n ].join('\\n'),\n );\n\n process.exit();\n}\n\nif (values.version) {\n console.log('v' + __APP_VERSION__);\n process.exit();\n}\n\nconst setupDataDir = dataDir => {\n if (process.env.ACTUAL_DATA_DIR) {\n return; // Env variables must not be overwritten\n }\n\n if (dataDir) {\n process.env.ACTUAL_DATA_DIR = dataDir; // Use the dir specified\n } else {\n // Setup defaults\n if (existsSync('./data')) {\n // The default data directory exists - use it\n console.info('Found existing data directory');\n process.env.ACTUAL_DATA_DIR = resolve('./data');\n } else {\n console.info(\n 'Using default data directory. You can specify a custom config with --config',\n );\n process.env.ACTUAL_DATA_DIR = resolve('./');\n }\n\n console.info(`Data directory: ${process.env.ACTUAL_DATA_DIR}`);\n }\n};\n\nif (values.config) {\n const configExists = existsSync(values.config);\n\n if (!configExists) {\n console.log(\n `Please specify a valid config path. The path ${String(values.config)} does not exist.`,\n );\n\n process.exit();\n } else {\n console.log(`Loading config from ${String(values.config)}`);\n const configJson = JSON.parse(readFileSync(values.config, 'utf-8'));\n process.env.ACTUAL_CONFIG_PATH = values.config;\n setupDataDir(configJson.dataDir);\n }\n} else {\n // If no config is specified, check for a default config in the current directory\n const defaultConfigJsonFile = './config.json';\n const configExists = existsSync(defaultConfigJsonFile);\n\n if (configExists) {\n console.info('Found config.json in the current directory');\n const configJson = JSON.parse(readFileSync(defaultConfigJsonFile, 'utf-8'));\n process.env.ACTUAL_CONFIG_PATH = defaultConfigJsonFile;\n setupDataDir(configJson.dataDir);\n } else {\n setupDataDir(); // No default config exists - setup data dir with defaults\n }\n}\n\nif (values['reset-password']) {\n console.info('Running reset password script...');\n await import('../src/scripts/reset-password.js');\n process.exit();\n}\n\n// start the sync server\nvoid import('../app.js');\n"],"mappings":";;;;;AAKA,IAAM,OAAO,QAAQ;AAmBrB,IAAM,EAAE,WAAW,UAAU;CAC3B;CACA,SAAA;EAlBA,MAAM;GACJ,MAAM;GACN,OAAO;EACT;EACA,SAAS;GACP,MAAM;GACN,OAAO;EACT;EACA,kBAAkB,EAChB,MAAM,UACR;EACA,QAAQ,EACN,MAAM,SACR;CAKM;CACN,kBAAkB;AACpB,CAAC;AAED,IAAI,OAAO,MAAM;CACf,QAAQ,IACN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI,CACb;CAEA,QAAQ,KAAK;AACf;AAEA,IAAI,OAAO,SAAS;CAClB,QAAQ,IAAI,UAAqB;CACjC,QAAQ,KAAK;AACf;AAEA,IAAM,gBAAe,YAAW;CAC9B,IAAI,QAAQ,IAAI,iBACd;CAGF,IAAI,SACF,QAAQ,IAAI,kBAAkB;MACzB;EAEL,IAAI,WAAW,QAAQ,GAAG;GAExB,QAAQ,KAAK,+BAA+B;GAC5C,QAAQ,IAAI,kBAAkB,QAAQ,QAAQ;EAChD,OAAO;GACL,QAAQ,KACN,6EACF;GACA,QAAQ,IAAI,kBAAkB,QAAQ,IAAI;EAC5C;EAEA,QAAQ,KAAK,mBAAmB,QAAQ,IAAI,iBAAiB;CAC/D;AACF;AAEA,IAAI,OAAO,QAGT,IAAI,CAFiB,WAAW,OAAO,MAEvB,GAAG;CACjB,QAAQ,IACN,gDAAgD,OAAO,OAAO,MAAM,EAAE,iBACxE;CAEA,QAAQ,KAAK;AACf,OAAO;CACL,QAAQ,IAAI,uBAAuB,OAAO,OAAO,MAAM,GAAG;CAC1D,MAAM,aAAa,KAAK,MAAM,aAAa,OAAO,QAAQ,OAAO,CAAC;CAClE,QAAQ,IAAI,qBAAqB,OAAO;CACxC,aAAa,WAAW,OAAO;AACjC;KACK;CAEL,MAAM,wBAAwB;CAG9B,IAFqB,WAAW,qBAEjB,GAAG;EAChB,QAAQ,KAAK,4CAA4C;EACzD,MAAM,aAAa,KAAK,MAAM,aAAa,uBAAuB,OAAO,CAAC;EAC1E,QAAQ,IAAI,qBAAqB;EACjC,aAAa,WAAW,OAAO;CACjC,OACE,aAAa;AAEjB;AAEA,IAAI,OAAO,mBAAmB;CAC5B,QAAQ,KAAK,kCAAkC;CAC/C,MAAM,OAAO;CACb,QAAQ,KAAK;AACf;AAGK,OAAO"}
1
+ {"version":3,"file":"actual-server.js","names":[],"sources":["../../bin/actual-server.js"],"sourcesContent":["#!/usr/bin/env node\nimport { existsSync, readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { parseArgs } from 'node:util';\n\nconst args = process.argv;\n\nconst options = {\n help: {\n type: 'boolean',\n short: 'h',\n },\n version: {\n type: 'boolean',\n short: 'v',\n },\n 'reset-password': {\n type: 'boolean',\n },\n config: {\n type: 'string',\n },\n};\n\nconst { values } = parseArgs({\n args,\n options,\n allowPositionals: true,\n});\n\nif (values.help) {\n console.log(\n [\n 'usage: actual-server [options]',\n '',\n 'options:',\n ' --config Path to config file',\n '',\n ' -h --help Print this list and exit.',\n ' -v --version Print the version and exit.',\n '',\n 'Examples:',\n '',\n 'Runs actual-server with default configuration',\n ' actual-server',\n '',\n 'Runs actual-server with custom configuration',\n ' actual-server --config ./config.json',\n ].join('\\n'),\n );\n\n process.exit();\n}\n\nif (values.version) {\n console.log('v' + __APP_VERSION__);\n process.exit();\n}\n\nconst setupDataDir = dataDir => {\n if (process.env.ACTUAL_DATA_DIR) {\n return; // Env variables must not be overwritten\n }\n\n if (dataDir) {\n process.env.ACTUAL_DATA_DIR = dataDir; // Use the dir specified\n } else {\n // Setup defaults\n if (existsSync('./data')) {\n // The default data directory exists - use it\n console.info('Found existing data directory');\n process.env.ACTUAL_DATA_DIR = resolve('./data');\n } else {\n console.info(\n 'Using default data directory. You can specify a custom config with --config',\n );\n process.env.ACTUAL_DATA_DIR = resolve('./');\n }\n\n console.info(`Data directory: ${process.env.ACTUAL_DATA_DIR}`);\n }\n};\n\nif (values.config) {\n const configExists = existsSync(values.config);\n\n if (!configExists) {\n console.log(\n `Please specify a valid config path. The path ${String(values.config)} does not exist.`,\n );\n\n process.exit();\n } else {\n console.log(`Loading config from ${String(values.config)}`);\n const configJson = JSON.parse(readFileSync(values.config, 'utf-8'));\n process.env.ACTUAL_CONFIG_PATH = values.config;\n setupDataDir(configJson.dataDir);\n }\n} else {\n // If no config is specified, check for a default config in the current directory\n const defaultConfigJsonFile = './config.json';\n const configExists = existsSync(defaultConfigJsonFile);\n\n if (configExists) {\n console.info('Found config.json in the current directory');\n const configJson = JSON.parse(readFileSync(defaultConfigJsonFile, 'utf-8'));\n process.env.ACTUAL_CONFIG_PATH = defaultConfigJsonFile;\n setupDataDir(configJson.dataDir);\n } else {\n setupDataDir(); // No default config exists - setup data dir with defaults\n }\n}\n\nif (values['reset-password']) {\n console.info('Running reset password script...');\n await import('../src/scripts/reset-password.js');\n process.exit();\n}\n\n// start the sync server\nvoid import('../app.js');\n"],"mappings":";;;;;AAKA,IAAM,OAAO,QAAQ;AAmBrB,IAAM,EAAE,WAAW,UAAU;CAC3B;CACA,SAAA;EAlBA,MAAM;GACJ,MAAM;GACN,OAAO;EACT;EACA,SAAS;GACP,MAAM;GACN,OAAO;EACT;EACA,kBAAkB,EAChB,MAAM,UACR;EACA,QAAQ,EACN,MAAM,SACR;CAKM;CACN,kBAAkB;AACpB,CAAC;AAED,IAAI,OAAO,MAAM;CACf,QAAQ,IACN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI,CACb;CAEA,QAAQ,KAAK;AACf;AAEA,IAAI,OAAO,SAAS;CAClB,QAAQ,IAAI,2BAAqB;CACjC,QAAQ,KAAK;AACf;AAEA,IAAM,gBAAe,YAAW;CAC9B,IAAI,QAAQ,IAAI,iBACd;CAGF,IAAI,SACF,QAAQ,IAAI,kBAAkB;MACzB;EAEL,IAAI,WAAW,QAAQ,GAAG;GAExB,QAAQ,KAAK,+BAA+B;GAC5C,QAAQ,IAAI,kBAAkB,QAAQ,QAAQ;EAChD,OAAO;GACL,QAAQ,KACN,6EACF;GACA,QAAQ,IAAI,kBAAkB,QAAQ,IAAI;EAC5C;EAEA,QAAQ,KAAK,mBAAmB,QAAQ,IAAI,iBAAiB;CAC/D;AACF;AAEA,IAAI,OAAO,QAGT,IAAI,CAFiB,WAAW,OAAO,MAEvB,GAAG;CACjB,QAAQ,IACN,gDAAgD,OAAO,OAAO,MAAM,EAAE,iBACxE;CAEA,QAAQ,KAAK;AACf,OAAO;CACL,QAAQ,IAAI,uBAAuB,OAAO,OAAO,MAAM,GAAG;CAC1D,MAAM,aAAa,KAAK,MAAM,aAAa,OAAO,QAAQ,OAAO,CAAC;CAClE,QAAQ,IAAI,qBAAqB,OAAO;CACxC,aAAa,WAAW,OAAO;AACjC;KACK;CAEL,MAAM,wBAAwB;CAG9B,IAFqB,WAAW,qBAEjB,GAAG;EAChB,QAAQ,KAAK,4CAA4C;EACzD,MAAM,aAAa,KAAK,MAAM,aAAa,uBAAuB,OAAO,CAAC;EAC1E,QAAQ,IAAI,qBAAqB;EACjC,aAAa,WAAW,OAAO;CACjC,OACE,aAAa;AAEjB;AAEA,IAAI,OAAO,mBAAmB;CAC5B,QAAQ,KAAK,kCAAkC;CAC/C,MAAM,OAAO;CACb,QAAQ,KAAK;AACf;AAGK,OAAO"}
@@ -1316,8 +1316,8 @@ var enableBankingService = {
1316
1316
  let iteration = 0;
1317
1317
  do {
1318
1318
  const result = await enableBankingService.getTransactions(accountUid, dateFrom, dateTo, continuationKey, psuHeaders);
1319
- allTransactions.push(...result.transactions);
1320
1319
  if (result.continuation_key && result.continuation_key === continuationKey) break;
1320
+ allTransactions.push(...result.transactions);
1321
1321
  continuationKey = result.continuation_key;
1322
1322
  iteration++;
1323
1323
  } while (continuationKey && iteration < maxIterations);
@@ -4996,14 +4996,16 @@ var SyncRequestSchema = messageDesc(file_sync, 3);
4996
4996
  */
4997
4997
  var SyncResponseSchema = messageDesc(file_sync, 4);
4998
4998
  //#endregion
4999
- //#region src/app-sync/errors.js
4999
+ //#region src/app-sync/errors.ts
5000
5000
  var FileNotFound = class extends Error {
5001
+ details;
5001
5002
  constructor(params = {}) {
5002
5003
  super("File does not exist or you don't have access to it");
5003
5004
  this.details = params;
5004
5005
  }
5005
5006
  };
5006
5007
  var GenericFileError = class extends Error {
5008
+ details;
5007
5009
  constructor(message, params = {}) {
5008
5010
  super(message);
5009
5011
  this.details = params;
@@ -5178,10 +5180,10 @@ var FilesService = class {
5178
5180
  }
5179
5181
  };
5180
5182
  //#endregion
5181
- //#region src/app-sync/validation.js
5183
+ //#region src/app-sync/validation.ts
5182
5184
  var SYNC_FORMAT_VERSION = 2;
5183
5185
  var validateSyncedFile = (groupId, keyId, currentFile) => {
5184
- if (currentFile.syncVersion == null || currentFile.syncVersion < SYNC_FORMAT_VERSION) return "file-old-version";
5186
+ if (currentFile.syncVersion == null || Number(currentFile.syncVersion) < SYNC_FORMAT_VERSION) return "file-old-version";
5185
5187
  if (currentFile.groupId == null) return "file-needs-upload";
5186
5188
  if ((currentFile.encryptMeta ? JSON.parse(currentFile.encryptMeta).keyId : null) !== currentFile.encryptKeyId) return "file-key-mismatch";
5187
5189
  if (groupId !== currentFile.groupId) return "file-has-reset";
@@ -5426,14 +5428,18 @@ app$1.post("/upload-user-file", async (req, res) => {
5426
5428
  res.status(400).send("invalid fileId");
5427
5429
  return;
5428
5430
  }
5429
- let groupId = req.headers["x-actual-group-id"] || null;
5431
+ const groupIdHeader = req.headers["x-actual-group-id"];
5430
5432
  const encryptMeta = extractSingleHeader(req, res, "x-actual-encrypt-meta");
5431
5433
  if (res.headersSent) return;
5432
5434
  const syncFormatVersion = extractSingleHeader(req, res, "x-actual-format");
5433
5435
  if (res.headersSent) return;
5434
- if (!!groupId && (typeof groupId !== "string" || !isValidGroupId(groupId))) {
5435
- res.status(400).send("invalid groupId");
5436
- return;
5436
+ let groupId = null;
5437
+ if (groupIdHeader !== void 0) {
5438
+ if (typeof groupIdHeader !== "string" || !isValidGroupId(groupIdHeader)) {
5439
+ res.status(400).send("invalid groupId");
5440
+ return;
5441
+ }
5442
+ groupId = groupIdHeader;
5437
5443
  }
5438
5444
  const keyId = encryptMeta && typeof encryptMeta === "string" ? JSON.parse(encryptMeta).keyId : null;
5439
5445
  const filesService = new FilesService(getAccountDb());
@@ -5750,4 +5756,4 @@ async function run() {
5750
5756
  //#endregion
5751
5757
  export { run };
5752
5758
 
5753
- //# sourceMappingURL=app-BgMEdvse.js.map
5759
+ //# sourceMappingURL=app-DllQNg0p.js.map