@actual-app/api 26.2.0-nightly.20260109 → 26.2.0-nightly.20260111

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.
@@ -82,6 +82,7 @@ declare function getUser(): Promise<{
82
82
  displayName?: undefined;
83
83
  loginMethod?: undefined;
84
84
  tokenExpired?: undefined;
85
+ serverPrefs?: undefined;
85
86
  } | {
86
87
  offline: boolean;
87
88
  userName: any;
@@ -90,6 +91,7 @@ declare function getUser(): Promise<{
90
91
  displayName: any;
91
92
  loginMethod: any;
92
93
  tokenExpired: boolean;
94
+ serverPrefs: any;
93
95
  }>;
94
96
  declare function changePassword({ password }: {
95
97
  password: string;
@@ -9,7 +9,7 @@ export declare const app: {
9
9
  handlers: Handlers;
10
10
  services: (() => () => void)[];
11
11
  unlistenServices: (() => void)[];
12
- method<Name extends "sync" | "load-budget" | "undo" | "redo" | "make-filters-from-conditions" | "query" | "get-server-version" | "get-server-url" | "set-server-url" | "app-focused" | "api/batch-budget-start" | "api/batch-budget-end" | "api/load-budget" | "api/download-budget" | "api/get-budgets" | "api/start-import" | "api/finish-import" | "api/abort-import" | "api/query" | "api/budget-months" | "api/budget-month" | "api/budget-set-amount" | "api/budget-set-carryover" | "api/budget-hold-for-next-month" | "api/budget-reset-hold" | "api/transactions-export" | "api/transactions-import" | "api/transactions-add" | "api/transactions-get" | "api/transaction-update" | "api/transaction-delete" | "api/sync" | "api/bank-sync" | "api/accounts-get" | "api/account-create" | "api/account-update" | "api/account-close" | "api/account-reopen" | "api/account-delete" | "api/account-balance" | "api/categories-get" | "api/category-groups-get" | "api/category-group-create" | "api/category-group-update" | "api/category-group-delete" | "api/category-create" | "api/category-update" | "api/category-delete" | "api/payees-get" | "api/common-payees-get" | "api/payee-create" | "api/payee-update" | "api/payee-delete" | "api/payees-merge" | "api/rules-get" | "api/payee-rules-get" | "api/rule-create" | "api/rule-update" | "api/rule-delete" | "api/schedule-create" | "api/schedule-update" | "api/schedule-delete" | "api/schedules-get" | "api/get-id-by-name" | "api/get-server-version" | "budget/budget-amount" | "budget/copy-previous-month" | "budget/copy-single-month" | "budget/set-zero" | "budget/set-3month-avg" | "budget/set-6month-avg" | "budget/set-12month-avg" | "budget/set-n-month-avg" | "budget/check-templates" | "budget/apply-goal-template" | "budget/apply-multiple-templates" | "budget/overwrite-goal-template" | "budget/apply-single-template" | "budget/cleanup-goal-template" | "budget/hold-for-next-month" | "budget/reset-hold" | "budget/cover-overspending" | "budget/transfer-available" | "budget/cover-overbudgeted" | "budget/transfer-category" | "budget/set-carryover" | "budget/reset-income-carryover" | "get-categories" | "get-budget-bounds" | "envelope-budget-month" | "tracking-budget-month" | "category-create" | "category-update" | "category-move" | "category-delete" | "get-category-groups" | "category-group-create" | "category-group-update" | "category-group-move" | "category-group-delete" | "must-category-transfer" | "budget/get-category-automations" | "budget/set-category-automations" | "budget/store-note-templates" | "budget/render-note-templates" | "dashboard-update" | "dashboard-update-widget" | "dashboard-reset" | "dashboard-add-widget" | "dashboard-remove-widget" | "dashboard-import" | "filter-create" | "filter-update" | "filter-delete" | "notes-save" | "notes-save-undoable" | "preferences/save" | "preferences/get" | "save-global-prefs" | "load-global-prefs" | "save-prefs" | "load-prefs" | "report/create" | "report/update" | "report/delete" | "rule-validate" | "rule-add" | "rule-update" | "rule-delete" | "rule-delete-all" | "rule-apply-actions" | "rule-add-payee-rename" | "rules-get" | "rule-get" | "rules-run" | "schedule/create" | "schedule/update" | "schedule/delete" | "schedule/skip-next-date" | "schedule/post-transaction" | "schedule/force-run-service" | "schedule/discover" | "schedule/get-upcoming-dates" | "transactions-batch-update" | "transaction-add" | "transaction-update" | "transaction-delete" | "transactions-parse-file" | "transactions-export" | "transactions-export-query" | "transactions-merge" | "get-earliest-transaction" | "get-latest-transaction" | "users-get" | "user-delete-all" | "user-add" | "user-update" | "access-add" | "access-delete-all" | "access-get-available-users" | "transfer-ownership" | "owner-created" | "tools/fix-split-transactions" | "account-update" | "accounts-get" | "account-balance" | "account-properties" | "gocardless-accounts-link" | "simplefin-accounts-link" | "pluggyai-accounts-link" | "account-create" | "account-close" | "account-reopen" | "account-move" | "secret-set" | "secret-check" | "gocardless-poll-web-token" | "gocardless-poll-web-token-stop" | "gocardless-status" | "simplefin-status" | "pluggyai-status" | "simplefin-accounts" | "pluggyai-accounts" | "gocardless-get-banks" | "gocardless-create-web-token" | "accounts-bank-sync" | "simplefin-batch-sync" | "transactions-import" | "account-unlink" | "payee-create" | "common-payees-get" | "payees-get" | "payees-get-orphaned" | "payees-get-rule-counts" | "payees-merge" | "payees-batch-change" | "payees-check-orphaned" | "payees-get-rules" | "get-cell" | "get-cell-names" | "create-query" | "sync-reset" | "sync-repair" | "validate-budget-name" | "unique-budget-name" | "get-budgets" | "get-remote-files" | "get-user-file-info" | "reset-budget-cache" | "upload-budget" | "download-budget" | "sync-budget" | "create-demo-budget" | "close-budget" | "delete-budget" | "duplicate-budget" | "create-budget" | "import-budget" | "export-budget" | "upload-file-web" | "backups-get" | "backup-load" | "backup-make" | "get-last-opened-backup" | "key-make" | "key-test" | "tags-get" | "tags-create" | "tags-delete" | "tags-delete-all" | "tags-update" | "tags-find" | "get-did-bootstrap" | "subscribe-needs-bootstrap" | "subscribe-bootstrap" | "subscribe-get-login-methods" | "subscribe-get-user" | "subscribe-change-password" | "subscribe-sign-in" | "subscribe-sign-out" | "subscribe-set-token" | "enable-openid" | "get-openid-config" | "enable-password">(name: Name, func: Handlers[Name]): void;
12
+ method<Name extends "sync" | "load-budget" | "undo" | "redo" | "make-filters-from-conditions" | "query" | "get-server-version" | "get-server-url" | "set-server-url" | "app-focused" | "api/batch-budget-start" | "api/batch-budget-end" | "api/load-budget" | "api/download-budget" | "api/get-budgets" | "api/start-import" | "api/finish-import" | "api/abort-import" | "api/query" | "api/budget-months" | "api/budget-month" | "api/budget-set-amount" | "api/budget-set-carryover" | "api/budget-hold-for-next-month" | "api/budget-reset-hold" | "api/transactions-export" | "api/transactions-import" | "api/transactions-add" | "api/transactions-get" | "api/transaction-update" | "api/transaction-delete" | "api/sync" | "api/bank-sync" | "api/accounts-get" | "api/account-create" | "api/account-update" | "api/account-close" | "api/account-reopen" | "api/account-delete" | "api/account-balance" | "api/categories-get" | "api/category-groups-get" | "api/category-group-create" | "api/category-group-update" | "api/category-group-delete" | "api/category-create" | "api/category-update" | "api/category-delete" | "api/payees-get" | "api/common-payees-get" | "api/payee-create" | "api/payee-update" | "api/payee-delete" | "api/payees-merge" | "api/rules-get" | "api/payee-rules-get" | "api/rule-create" | "api/rule-update" | "api/rule-delete" | "api/schedule-create" | "api/schedule-update" | "api/schedule-delete" | "api/schedules-get" | "api/get-id-by-name" | "api/get-server-version" | "budget/budget-amount" | "budget/copy-previous-month" | "budget/copy-single-month" | "budget/set-zero" | "budget/set-3month-avg" | "budget/set-6month-avg" | "budget/set-12month-avg" | "budget/set-n-month-avg" | "budget/check-templates" | "budget/apply-goal-template" | "budget/apply-multiple-templates" | "budget/overwrite-goal-template" | "budget/apply-single-template" | "budget/cleanup-goal-template" | "budget/hold-for-next-month" | "budget/reset-hold" | "budget/cover-overspending" | "budget/transfer-available" | "budget/cover-overbudgeted" | "budget/transfer-category" | "budget/set-carryover" | "budget/reset-income-carryover" | "get-categories" | "get-budget-bounds" | "envelope-budget-month" | "tracking-budget-month" | "category-create" | "category-update" | "category-move" | "category-delete" | "get-category-groups" | "category-group-create" | "category-group-update" | "category-group-move" | "category-group-delete" | "must-category-transfer" | "budget/get-category-automations" | "budget/set-category-automations" | "budget/store-note-templates" | "budget/render-note-templates" | "dashboard-update" | "dashboard-update-widget" | "dashboard-reset" | "dashboard-add-widget" | "dashboard-remove-widget" | "dashboard-import" | "filter-create" | "filter-update" | "filter-delete" | "notes-save" | "notes-save-undoable" | "preferences/save" | "preferences/get" | "save-global-prefs" | "load-global-prefs" | "save-prefs" | "load-prefs" | "save-server-prefs" | "report/create" | "report/update" | "report/delete" | "rule-validate" | "rule-add" | "rule-update" | "rule-delete" | "rule-delete-all" | "rule-apply-actions" | "rule-add-payee-rename" | "rules-get" | "rule-get" | "rules-run" | "schedule/create" | "schedule/update" | "schedule/delete" | "schedule/skip-next-date" | "schedule/post-transaction" | "schedule/force-run-service" | "schedule/discover" | "schedule/get-upcoming-dates" | "transactions-batch-update" | "transaction-add" | "transaction-update" | "transaction-delete" | "transactions-parse-file" | "transactions-export" | "transactions-export-query" | "transactions-merge" | "get-earliest-transaction" | "get-latest-transaction" | "users-get" | "user-delete-all" | "user-add" | "user-update" | "access-add" | "access-delete-all" | "access-get-available-users" | "transfer-ownership" | "owner-created" | "tools/fix-split-transactions" | "account-update" | "accounts-get" | "account-balance" | "account-properties" | "gocardless-accounts-link" | "simplefin-accounts-link" | "pluggyai-accounts-link" | "account-create" | "account-close" | "account-reopen" | "account-move" | "secret-set" | "secret-check" | "gocardless-poll-web-token" | "gocardless-poll-web-token-stop" | "gocardless-status" | "simplefin-status" | "pluggyai-status" | "simplefin-accounts" | "pluggyai-accounts" | "gocardless-get-banks" | "gocardless-create-web-token" | "accounts-bank-sync" | "simplefin-batch-sync" | "transactions-import" | "account-unlink" | "payee-create" | "common-payees-get" | "payees-get" | "payees-get-orphaned" | "payees-get-rule-counts" | "payees-merge" | "payees-batch-change" | "payees-check-orphaned" | "payees-get-rules" | "get-cell" | "get-cell-names" | "create-query" | "sync-reset" | "sync-repair" | "validate-budget-name" | "unique-budget-name" | "get-budgets" | "get-remote-files" | "get-user-file-info" | "reset-budget-cache" | "upload-budget" | "download-budget" | "sync-budget" | "create-demo-budget" | "close-budget" | "delete-budget" | "duplicate-budget" | "create-budget" | "import-budget" | "export-budget" | "upload-file-web" | "backups-get" | "backup-load" | "backup-make" | "get-last-opened-backup" | "key-make" | "key-test" | "tags-get" | "tags-create" | "tags-delete" | "tags-delete-all" | "tags-update" | "tags-find" | "get-did-bootstrap" | "subscribe-needs-bootstrap" | "subscribe-bootstrap" | "subscribe-get-login-methods" | "subscribe-get-user" | "subscribe-change-password" | "subscribe-sign-in" | "subscribe-sign-out" | "subscribe-set-token" | "enable-openid" | "get-openid-config" | "enable-password">(name: Name, func: Handlers[Name]): void;
13
13
  service(func: () => () => void): void;
14
14
  combine(...apps: any[]): void;
15
15
  startServices(): void;
@@ -6,6 +6,7 @@ export type PreferencesHandlers = {
6
6
  'load-global-prefs': typeof loadGlobalPrefs;
7
7
  'save-prefs': typeof saveMetadataPrefs;
8
8
  'load-prefs': typeof loadMetadataPrefs;
9
+ 'save-server-prefs': typeof saveServerPrefs;
9
10
  };
10
11
  export declare const app: {
11
12
  events: import("mitt").Emitter<{
@@ -17,7 +18,7 @@ export declare const app: {
17
18
  handlers: PreferencesHandlers;
18
19
  services: (() => () => void)[];
19
20
  unlistenServices: (() => void)[];
20
- method<Name extends "preferences/save" | "preferences/get" | "save-global-prefs" | "load-global-prefs" | "save-prefs" | "load-prefs">(name: Name, func: PreferencesHandlers[Name]): void;
21
+ method<Name extends "preferences/save" | "preferences/get" | "save-global-prefs" | "load-global-prefs" | "save-prefs" | "load-prefs" | "save-server-prefs">(name: Name, func: PreferencesHandlers[Name]): void;
21
22
  service(func: () => () => void): void;
22
23
  combine(...apps: any[]): void;
23
24
  startServices(): void;
@@ -32,4 +33,11 @@ declare function saveGlobalPrefs(prefs: GlobalPrefs): Promise<string>;
32
33
  declare function loadGlobalPrefs(): Promise<GlobalPrefs>;
33
34
  declare function saveMetadataPrefs(prefsToSet: MetadataPrefs): Promise<string>;
34
35
  declare function loadMetadataPrefs(): Promise<MetadataPrefs>;
36
+ declare function saveServerPrefs({ prefs }: {
37
+ prefs: Record<string, string>;
38
+ }): Promise<{
39
+ error: string;
40
+ } | {
41
+ error?: undefined;
42
+ }>;
35
43
  export {};
@@ -1,8 +1,8 @@
1
- export type FeatureFlag = 'goalTemplatesEnabled' | 'goalTemplatesUIEnabled' | 'actionTemplating' | 'formulaMode' | 'currency' | 'crossoverReport' | 'plugins' | 'forceReload';
1
+ export type FeatureFlag = 'goalTemplatesEnabled' | 'goalTemplatesUIEnabled' | 'actionTemplating' | 'formulaMode' | 'currency' | 'crossoverReport' | 'forceReload';
2
2
  /**
3
3
  * Cross-device preferences. These sync across devices when they are changed.
4
4
  */
5
- export type SyncedPrefs = Partial<Record<'budgetType' | 'upcomingScheduledTransactionLength' | 'firstDayOfWeekIdx' | 'dateFormat' | 'numberFormat' | 'hideFraction' | 'isPrivacyEnabled' | 'currencySymbolPosition' | 'currencySpaceBetweenAmountAndSymbol' | 'defaultCurrencyCode' | 'plugins' | `show-account-${string}-net-worth-chart` | `side-nav.show-balance-history-${string}` | `show-balances-${string}` | `show-extra-balances-${string}` | `hide-cleared-${string}` | `hide-reconciled-${string}` | `parse-date-${string}-${'csv' | 'qif'}` | `csv-mappings-${string}` | `csv-delimiter-${string}` | `csv-skip-start-lines-${string}` | `csv-skip-end-lines-${string}` | `csv-in-out-mode-${string}` | `csv-out-value-${string}` | `csv-has-header-${string}` | `custom-sync-mappings-${string}` | `sync-import-pending-${string}` | `sync-reimport-deleted-${string}` | `sync-import-notes-${string}` | `sync-import-transactions-${string}` | `ofx-fallback-missing-payee-${string}` | `flip-amount-${string}-${'csv' | 'qif'}` | `flags.${FeatureFlag}` | `learn-categories`, string>>;
5
+ export type SyncedPrefs = Partial<Record<'budgetType' | 'upcomingScheduledTransactionLength' | 'firstDayOfWeekIdx' | 'dateFormat' | 'numberFormat' | 'hideFraction' | 'isPrivacyEnabled' | 'currencySymbolPosition' | 'currencySpaceBetweenAmountAndSymbol' | 'defaultCurrencyCode' | `show-account-${string}-net-worth-chart` | `side-nav.show-balance-history-${string}` | `show-balances-${string}` | `show-extra-balances-${string}` | `hide-cleared-${string}` | `hide-reconciled-${string}` | `parse-date-${string}-${'csv' | 'qif'}` | `csv-mappings-${string}` | `csv-delimiter-${string}` | `csv-skip-start-lines-${string}` | `csv-skip-end-lines-${string}` | `csv-in-out-mode-${string}` | `csv-out-value-${string}` | `csv-has-header-${string}` | `custom-sync-mappings-${string}` | `sync-import-pending-${string}` | `sync-reimport-deleted-${string}` | `sync-import-notes-${string}` | `sync-import-transactions-${string}` | `ofx-fallback-missing-payee-${string}` | `flip-amount-${string}-${'csv' | 'qif'}` | `flags.${FeatureFlag}` | `learn-categories`, string>>;
6
6
  /**
7
7
  * Preferences that are stored in the `metadata.json` file along with the
8
8
  * core database.
@@ -87,3 +87,6 @@ export type GlobalPrefsJson = Partial<{
87
87
  notifyWhenUpdateIsAvailable?: GlobalPrefs['notifyWhenUpdateIsAvailable'];
88
88
  }>;
89
89
  export type AuthMethods = 'password' | 'openid';
90
+ export type ServerPrefs = Partial<{
91
+ 'flags.plugins': 'true' | 'false';
92
+ }>;
@@ -110257,7 +110257,7 @@ async function getUser() {
110257
110257
  }
110258
110258
  });
110259
110259
  let tokenExpired = false;
110260
- const { status, reason, data: { userName = null, permission = "", userId = null, displayName = null, loginMethod = null } = {} } = JSON.parse(res) || {};
110260
+ const { status, reason, data: { userName = null, permission = "", userId = null, displayName = null, loginMethod = null, prefs: serverPrefs } = {} } = JSON.parse(res) || {};
110261
110261
  if (status === "error") {
110262
110262
  if (reason === "unauthorized") {
110263
110263
  return null;
@@ -110276,7 +110276,8 @@ async function getUser() {
110276
110276
  userId,
110277
110277
  displayName,
110278
110278
  loginMethod,
110279
- tokenExpired
110279
+ tokenExpired,
110280
+ serverPrefs
110280
110281
  };
110281
110282
  }
110282
110283
  catch (e) {
@@ -115922,6 +115923,9 @@ function getSinkingBaseContributionTotal(t2) {
115922
115923
  intervalMonths = 1;
115923
115924
  monthlyAmount = schedule.target / intervalMonths;
115924
115925
  break;
115926
+ default:
115927
+ monthlyAmount = schedule.target / schedule.target_interval;
115928
+ break;
115925
115929
  }
115926
115930
  total += monthlyAmount;
115927
115931
  }
@@ -115938,14 +115942,16 @@ async function runSchedule(template_lines, current_month, balance, remainder, la
115938
115942
  const scheduleTemplates = template_lines.filter((t22) => t22.type === "schedule");
115939
115943
  const t2 = await createScheduleList(scheduleTemplates, current_month, category);
115940
115944
  errors2 = errors2.concat(t2.errors);
115941
- const isPayMonthOf = (c) => c.full || c.target_frequency === "monthly" && c.target_interval === 1 && c.num_months === 0 || c.target_frequency === "weekly" && c.target_interval <= 4 || c.target_frequency === "daily" && c.target_interval <= 31 || isReflectBudget();
115945
+ const isPayMonthOf = (c) => c.full || (c.target_frequency === "monthly" || !c.target_frequency) && c.target_interval === 1 && c.num_months === 0 || c.target_frequency === "weekly" && c.target_interval <= 4 || c.target_frequency === "daily" && c.target_interval <= 31 || isReflectBudget();
115946
+ const isSubMonthly = (c) => c.target_frequency === "weekly" || c.target_frequency === "daily";
115942
115947
  const t_payMonthOf = t2.t.filter(isPayMonthOf);
115943
115948
  const t_sinking = t2.t.filter((c) => !isPayMonthOf(c)).sort((a, b) => a.next_date_string.localeCompare(b.next_date_string));
115949
+ const numSubMonthly = t2.t.filter(isSubMonthly).length;
115944
115950
  const totalPayMonthOf = getPayMonthOfTotal(t_payMonthOf);
115945
115951
  const totalSinking = getSinkingTotal(t_sinking);
115946
115952
  const totalSinkingBaseContribution = getSinkingBaseContributionTotal(t_sinking);
115947
115953
  const lastMonthGoal = await getSheetValue(sheetForMonth(subMonths(current_month, 1)), `goal-${category.id}`);
115948
- if (balance >= totalSinking + totalPayMonthOf || lastMonthGoal < totalSinking + totalPayMonthOf && lastMonthGoal !== 0 && balance >= lastMonthGoal) {
115954
+ if (balance >= totalSinking + totalPayMonthOf || lastMonthGoal < totalSinking + totalPayMonthOf && lastMonthGoal !== 0 && balance >= lastMonthGoal && numSubMonthly > 0) {
115949
115955
  to_budget += Math.round(totalPayMonthOf + totalSinkingBaseContribution);
115950
115956
  }
115951
115957
  else {
@@ -124859,6 +124865,7 @@ app$6.method("save-global-prefs", saveGlobalPrefs);
124859
124865
  app$6.method("load-global-prefs", loadGlobalPrefs);
124860
124866
  app$6.method("save-prefs", saveMetadataPrefs);
124861
124867
  app$6.method("load-prefs", loadMetadataPrefs);
124868
+ app$6.method("save-server-prefs", saveServerPrefs);
124862
124869
  async function saveSyncedPrefs({ id: id2, value }) {
124863
124870
  if (!id2) {
124864
124871
  return;
@@ -124963,6 +124970,31 @@ async function saveMetadataPrefs(prefsToSet) {
124963
124970
  async function loadMetadataPrefs() {
124964
124971
  return getPrefs();
124965
124972
  }
124973
+ async function saveServerPrefs({ prefs: prefs2 }) {
124974
+ const userToken = await getItem("user-token");
124975
+ if (!userToken) {
124976
+ return { error: "not-logged-in" };
124977
+ }
124978
+ try {
124979
+ const serverConfig = getServer();
124980
+ if (!serverConfig) {
124981
+ throw new Error("No sync server configured.");
124982
+ }
124983
+ await post(serverConfig.SIGNUP_SERVER + "/server-prefs", {
124984
+ token: userToken,
124985
+ prefs: prefs2
124986
+ });
124987
+ }
124988
+ catch (err) {
124989
+ if (err instanceof PostError) {
124990
+ return {
124991
+ error: err.reason || "network-failure"
124992
+ };
124993
+ }
124994
+ throw err;
124995
+ }
124996
+ return {};
124997
+ }
124966
124998
  function validateRule(rule) {
124967
124999
  function runValidation(array, validate2) {
124968
125000
  const result = array.map((item) => {
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actual-app/api",
3
- "version": "26.2.0-nightly.20260109",
3
+ "version": "26.2.0-nightly.20260111",
4
4
  "description": "An API for Actual",
5
5
  "license": "MIT",
6
6
  "files": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actual-app/api",
3
- "version": "26.2.0-nightly.20260109",
3
+ "version": "26.2.0-nightly.20260111",
4
4
  "description": "An API for Actual",
5
5
  "license": "MIT",
6
6
  "files": [