@actual-app/core 26.3.0
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/.swcrc +11 -0
- package/bin/build-browser +40 -0
- package/bin/copy-migrations +9 -0
- package/db.sqlite +0 -0
- package/default-db.sqlite +0 -0
- package/migrations/.force-copy-windows +0 -0
- package/migrations/1548957970627_remove-db-version.sql +5 -0
- package/migrations/1550601598648_payees.sql +23 -0
- package/migrations/1555786194328_remove_category_group_unique.sql +25 -0
- package/migrations/1561751833510_indexes.sql +7 -0
- package/migrations/1567699552727_budget.sql +38 -0
- package/migrations/1582384163573_cleared.sql +6 -0
- package/migrations/1597756566448_rules.sql +10 -0
- package/migrations/1608652596043_parent_field.sql +13 -0
- package/migrations/1608652596044_trans_views.sql +56 -0
- package/migrations/1612625548236_optimize.sql +7 -0
- package/migrations/1614782639336_trans_views2.sql +33 -0
- package/migrations/1615745967948_meta.sql +10 -0
- package/migrations/1616167010796_accounts_order.sql +5 -0
- package/migrations/1618975177358_schedules.sql +28 -0
- package/migrations/1632571489012_remove_cache.js +136 -0
- package/migrations/1679728867040_rules_conditions.sql +5 -0
- package/migrations/1681115033845_add_schedule_name.sql +5 -0
- package/migrations/1682974838138_remove_payee_rules.sql +5 -0
- package/migrations/1685007876842_add_category_hidden.sql +6 -0
- package/migrations/1686139660866_remove_account_type.sql +5 -0
- package/migrations/1688749527273_transaction_filters.sql +10 -0
- package/migrations/1688841238000_add_account_type.sql +5 -0
- package/migrations/1691233396000_add_schedule_next_date_tombstone.sql +5 -0
- package/migrations/1694438752000_add_goal_targets.sql +7 -0
- package/migrations/1697046240000_add_reconciled.sql +5 -0
- package/migrations/1704572023730_add_account_sync_source.sql +5 -0
- package/migrations/1704572023731_add_missing_goCardless_sync_source.sql +9 -0
- package/migrations/1707267033000_reports.sql +28 -0
- package/migrations/1712784523000_unhide_input_group.sql +8 -0
- package/migrations/1716359441000_include_current.sql +5 -0
- package/migrations/1720310586000_link_transfer_schedules.sql +19 -0
- package/migrations/1720664867241_add_payee_favorite.sql +5 -0
- package/migrations/1720665000000_goal_context.sql +6 -0
- package/migrations/1722717601000_reports_move_selected_categories.js +55 -0
- package/migrations/1722804019000_create_dashboard_table.js +69 -0
- package/migrations/1723665565000_prefs.js +59 -0
- package/migrations/1730744182000_fix_dashboard_table.sql +7 -0
- package/migrations/1736640000000_custom_report_sorting.sql +7 -0
- package/migrations/1737158400000_add_learn_categories_to_payees.sql +5 -0
- package/migrations/1738491452000_sorting_rename.sql +13 -0
- package/migrations/1739139550000_bank_sync_page.sql +7 -0
- package/migrations/1740506588539_add_last_reconciled_at.sql +5 -0
- package/migrations/1745425408000_update_budgetType_pref.sql +7 -0
- package/migrations/1749799110000_add_tags.sql +10 -0
- package/migrations/1749799110001_tags_tombstone.sql +5 -0
- package/migrations/1754611200000_add_category_template_settings.sql +5 -0
- package/migrations/1759260219000_add_trim_interval_report_setting.sql +6 -0
- package/migrations/1759842823172_add_isGlobal_to_preferences.sql +1 -0
- package/migrations/1762178745667_rename_csv_skip_lines_pref.sql +8 -0
- package/migrations/1765518577215_multiple_dashboards.js +30 -0
- package/migrations/1768872504000_add_payee_locations.sql +21 -0
- package/package.json +128 -0
- package/src/mocks/arbitrary-schema.ts +162 -0
- package/src/mocks/budget.ts +901 -0
- package/src/mocks/files/8859-1.qfx +63 -0
- package/src/mocks/files/best.data-ever$.QFX +124 -0
- package/src/mocks/files/big.data.QiF +91 -0
- package/src/mocks/files/budgets/.commit-to-git +0 -0
- package/src/mocks/files/camt/camt.053.payee-memo.xml +127 -0
- package/src/mocks/files/camt/camt.053.xml +463 -0
- package/src/mocks/files/credit-card.ofx +11 -0
- package/src/mocks/files/data-multi-decimal.ofx +64 -0
- package/src/mocks/files/data-payee-memo.ofx +75 -0
- package/src/mocks/files/data-payee-memo.qif +17 -0
- package/src/mocks/files/data.ofx +124 -0
- package/src/mocks/files/data.qfx +124 -0
- package/src/mocks/files/data.qif +91 -0
- package/src/mocks/files/default-budget-template/db.sqlite +0 -0
- package/src/mocks/files/default-budget-template/metadata.json +6 -0
- package/src/mocks/files/html-vals.qfx +17 -0
- package/src/mocks/index.ts +221 -0
- package/src/mocks/migrations/1508717984291_up_add-poop.sql +13 -0
- package/src/mocks/migrations/1508718036311_up_modify-poop.sql +2 -0
- package/src/mocks/migrations/1508727787513_remove-is_income.sql +15 -0
- package/src/mocks/random.ts +16 -0
- package/src/mocks/setup.ts +180 -0
- package/src/mocks/spreadsheet.ts +101 -0
- package/src/mocks/util.ts +82 -0
- package/src/platform/client/connection/README.md +3 -0
- package/src/platform/client/connection/__mocks__/index.ts +67 -0
- package/src/platform/client/connection/index-types.ts +95 -0
- package/src/platform/client/connection/index.browser.ts +213 -0
- package/src/platform/client/connection/index.ts +155 -0
- package/src/platform/client/undo/index.ts +59 -0
- package/src/platform/exceptions/__mocks__/index.ts +7 -0
- package/src/platform/exceptions/index.ts +9 -0
- package/src/platform/server/asyncStorage/__mocks__/index.ts +50 -0
- package/src/platform/server/asyncStorage/index-types.ts +35 -0
- package/src/platform/server/asyncStorage/index.api.ts +2 -0
- package/src/platform/server/asyncStorage/index.electron.ts +88 -0
- package/src/platform/server/asyncStorage/index.ts +126 -0
- package/src/platform/server/connection/README.md +3 -0
- package/src/platform/server/connection/__mocks__/index.ts +15 -0
- package/src/platform/server/connection/index-types.ts +20 -0
- package/src/platform/server/connection/index.api.ts +13 -0
- package/src/platform/server/connection/index.electron.ts +102 -0
- package/src/platform/server/connection/index.ts +154 -0
- package/src/platform/server/fetch/__mocks__/index.ts +3 -0
- package/src/platform/server/fetch/index.api.ts +1 -0
- package/src/platform/server/fetch/index.electron.ts +18 -0
- package/src/platform/server/fetch/index.ts +20 -0
- package/src/platform/server/fs/index.api.ts +198 -0
- package/src/platform/server/fs/index.electron.ts +208 -0
- package/src/platform/server/fs/index.test.ts +117 -0
- package/src/platform/server/fs/index.ts +416 -0
- package/src/platform/server/fs/path-join.api.ts +1 -0
- package/src/platform/server/fs/path-join.electron.ts +1 -0
- package/src/platform/server/fs/path-join.ts +97 -0
- package/src/platform/server/fs/shared.ts +33 -0
- package/src/platform/server/indexeddb/index.ts +115 -0
- package/src/platform/server/log/index.ts +43 -0
- package/src/platform/server/sqlite/index.api.ts +2 -0
- package/src/platform/server/sqlite/index.electron.ts +134 -0
- package/src/platform/server/sqlite/index.test.ts +108 -0
- package/src/platform/server/sqlite/index.ts +241 -0
- package/src/platform/server/sqlite/normalise.ts +9 -0
- package/src/platform/server/sqlite/unicodeLike.test.ts +58 -0
- package/src/platform/server/sqlite/unicodeLike.ts +31 -0
- package/src/server/__mocks__/post.ts +9 -0
- package/src/server/__snapshots__/main.test.ts.snap +199 -0
- package/src/server/__snapshots__/sheet.test.ts.snap +9 -0
- package/src/server/accounts/__snapshots__/sync.test.ts.snap +136 -0
- package/src/server/accounts/app-bank-sync.test.ts +136 -0
- package/src/server/accounts/app.ts +1294 -0
- package/src/server/accounts/link.ts +25 -0
- package/src/server/accounts/payees.ts +36 -0
- package/src/server/accounts/sync.test.ts +679 -0
- package/src/server/accounts/sync.ts +1168 -0
- package/src/server/accounts/title/index.ts +60 -0
- package/src/server/accounts/title/lower-case.ts +93 -0
- package/src/server/accounts/title/specials.ts +21 -0
- package/src/server/admin/app.ts +241 -0
- package/src/server/api-models.ts +244 -0
- package/src/server/api.test.ts +36 -0
- package/src/server/api.ts +1030 -0
- package/src/server/app.ts +91 -0
- package/src/server/aql/compiler.test.ts +966 -0
- package/src/server/aql/compiler.ts +1222 -0
- package/src/server/aql/exec.test.ts +289 -0
- package/src/server/aql/exec.ts +128 -0
- package/src/server/aql/index.ts +41 -0
- package/src/server/aql/schema/executors.test.ts +420 -0
- package/src/server/aql/schema/executors.ts +345 -0
- package/src/server/aql/schema/index.test.ts +67 -0
- package/src/server/aql/schema/index.ts +409 -0
- package/src/server/aql/schema-helpers.test.ts +242 -0
- package/src/server/aql/schema-helpers.ts +208 -0
- package/src/server/aql/views.test.ts +62 -0
- package/src/server/aql/views.ts +57 -0
- package/src/server/auth/app.ts +387 -0
- package/src/server/bench.ts +29 -0
- package/src/server/budget/actions.ts +686 -0
- package/src/server/budget/app.ts +469 -0
- package/src/server/budget/base.test.ts +340 -0
- package/src/server/budget/base.ts +339 -0
- package/src/server/budget/category-template-context.test.ts +1658 -0
- package/src/server/budget/category-template-context.ts +862 -0
- package/src/server/budget/cleanup-template.pegjs +27 -0
- package/src/server/budget/cleanup-template.ts +408 -0
- package/src/server/budget/envelope.ts +403 -0
- package/src/server/budget/goal-template.pegjs +110 -0
- package/src/server/budget/goal-template.ts +309 -0
- package/src/server/budget/report.ts +308 -0
- package/src/server/budget/schedule-template.test.ts +184 -0
- package/src/server/budget/schedule-template.ts +351 -0
- package/src/server/budget/statements.ts +60 -0
- package/src/server/budget/template-notes.test.ts +393 -0
- package/src/server/budget/template-notes.ts +323 -0
- package/src/server/budget/util.ts +25 -0
- package/src/server/budgetfiles/__snapshots__/backups.test.ts.snap +101 -0
- package/src/server/budgetfiles/app.ts +672 -0
- package/src/server/budgetfiles/backups.test.ts +79 -0
- package/src/server/budgetfiles/backups.ts +251 -0
- package/src/server/cloud-storage.ts +467 -0
- package/src/server/dashboard/app.ts +373 -0
- package/src/server/db/__snapshots__/index.test.ts.snap +271 -0
- package/src/server/db/index.test.ts +300 -0
- package/src/server/db/index.ts +855 -0
- package/src/server/db/mappings.ts +59 -0
- package/src/server/db/sort.ts +58 -0
- package/src/server/db/types/index.ts +342 -0
- package/src/server/db/util.ts +36 -0
- package/src/server/encryption/app.ts +133 -0
- package/src/server/encryption/encryption-internals.api.ts +2 -0
- package/src/server/encryption/encryption-internals.electron.ts +89 -0
- package/src/server/encryption/encryption-internals.ts +109 -0
- package/src/server/encryption/encryption.test.ts +19 -0
- package/src/server/encryption/index.test.ts +19 -0
- package/src/server/encryption/index.ts +89 -0
- package/src/server/errors.ts +110 -0
- package/src/server/filters/app.ts +191 -0
- package/src/server/importers/actual.ts +49 -0
- package/src/server/importers/index.ts +58 -0
- package/src/server/importers/ynab4-types.ts +163 -0
- package/src/server/importers/ynab4.ts +470 -0
- package/src/server/importers/ynab5-types.ts +290 -0
- package/src/server/importers/ynab5.ts +1193 -0
- package/src/server/main-app.ts +25 -0
- package/src/server/main.test.ts +392 -0
- package/src/server/main.ts +336 -0
- package/src/server/migrate/__snapshots__/migrations.test.ts.snap +17 -0
- package/src/server/migrate/cli.ts +100 -0
- package/src/server/migrate/migrations.test.ts +81 -0
- package/src/server/migrate/migrations.ts +192 -0
- package/src/server/models.ts +184 -0
- package/src/server/mutators.ts +139 -0
- package/src/server/notes/app.ts +18 -0
- package/src/server/payees/app.ts +351 -0
- package/src/server/polyfills.ts +26 -0
- package/src/server/post.ts +219 -0
- package/src/server/preferences/app.ts +249 -0
- package/src/server/prefs.ts +91 -0
- package/src/server/reports/app.ts +187 -0
- package/src/server/rules/action.ts +344 -0
- package/src/server/rules/app.ts +193 -0
- package/src/server/rules/condition.ts +436 -0
- package/src/server/rules/customFunctions.ts +61 -0
- package/src/server/rules/formula-action.test.ts +175 -0
- package/src/server/rules/handlebars-helpers.ts +131 -0
- package/src/server/rules/index.test.ts +1095 -0
- package/src/server/rules/index.ts +22 -0
- package/src/server/rules/rule-indexer.ts +89 -0
- package/src/server/rules/rule-utils.ts +274 -0
- package/src/server/rules/rule.ts +193 -0
- package/src/server/schedules/app.test.ts +502 -0
- package/src/server/schedules/app.ts +644 -0
- package/src/server/schedules/find-schedules.ts +391 -0
- package/src/server/server-config.ts +59 -0
- package/src/server/sheet.test.ts +101 -0
- package/src/server/sheet.ts +280 -0
- package/src/server/spreadsheet/__snapshots__/spreadsheet.test.ts.snap +5 -0
- package/src/server/spreadsheet/app.ts +54 -0
- package/src/server/spreadsheet/globals.ts +13 -0
- package/src/server/spreadsheet/graph-data-structure.ts +165 -0
- package/src/server/spreadsheet/scratch +60 -0
- package/src/server/spreadsheet/spreadsheet.test.ts +191 -0
- package/src/server/spreadsheet/spreadsheet.ts +523 -0
- package/src/server/spreadsheet/util.ts +15 -0
- package/src/server/sql/init.sql +88 -0
- package/src/server/sync/__snapshots__/sync.test.ts.snap +31 -0
- package/src/server/sync/app.ts +29 -0
- package/src/server/sync/encoder.ts +129 -0
- package/src/server/sync/index.ts +820 -0
- package/src/server/sync/make-test-message.ts +19 -0
- package/src/server/sync/migrate.test.ts +169 -0
- package/src/server/sync/migrate.ts +48 -0
- package/src/server/sync/repair.ts +39 -0
- package/src/server/sync/reset.ts +91 -0
- package/src/server/sync/sync.property.test.ts +385 -0
- package/src/server/sync/sync.test.ts +349 -0
- package/src/server/sync/utils.ts +3 -0
- package/src/server/tags/app.ts +101 -0
- package/src/server/tests/mockData.json +9352 -0
- package/src/server/tests/mockSyncServer.ts +119 -0
- package/src/server/tools/app.ts +152 -0
- package/src/server/transactions/__snapshots__/transaction-rules.test.ts.snap +173 -0
- package/src/server/transactions/__snapshots__/transfer.test.ts.snap +655 -0
- package/src/server/transactions/app.ts +136 -0
- package/src/server/transactions/export/export-to-csv.ts +132 -0
- package/src/server/transactions/import/__snapshots__/parse-file.test.ts.snap +1582 -0
- package/src/server/transactions/import/ofx2json.test.ts +33 -0
- package/src/server/transactions/import/ofx2json.ts +157 -0
- package/src/server/transactions/import/parse-file.test.ts +224 -0
- package/src/server/transactions/import/parse-file.ts +286 -0
- package/src/server/transactions/import/qif2json.ts +110 -0
- package/src/server/transactions/import/xmlcamt2json.ts +168 -0
- package/src/server/transactions/index.ts +196 -0
- package/src/server/transactions/merge.test.ts +370 -0
- package/src/server/transactions/merge.ts +139 -0
- package/src/server/transactions/transaction-rules.test.ts +994 -0
- package/src/server/transactions/transaction-rules.ts +1038 -0
- package/src/server/transactions/transfer.test.ts +221 -0
- package/src/server/transactions/transfer.ts +173 -0
- package/src/server/undo.ts +271 -0
- package/src/server/update.ts +37 -0
- package/src/server/util/budget-name.ts +61 -0
- package/src/server/util/custom-sync-mapping.ts +48 -0
- package/src/server/util/rschedule.ts +9 -0
- package/src/shared/__mocks__/platform.ts +7 -0
- package/src/shared/__snapshots__/months.test.ts.snap +21 -0
- package/src/shared/arithmetic.test.ts +112 -0
- package/src/shared/arithmetic.ts +170 -0
- package/src/shared/async.test.ts +135 -0
- package/src/shared/async.ts +76 -0
- package/src/shared/constants.ts +5 -0
- package/src/shared/currencies.ts +70 -0
- package/src/shared/dashboard.ts +260 -0
- package/src/shared/environment.ts +18 -0
- package/src/shared/errors.ts +195 -0
- package/src/shared/locale.ts +27 -0
- package/src/shared/location-utils.test.ts +69 -0
- package/src/shared/location-utils.ts +49 -0
- package/src/shared/months.test.ts +5 -0
- package/src/shared/months.ts +485 -0
- package/src/shared/normalisation.ts +6 -0
- package/src/shared/platform.electron.ts +21 -0
- package/src/shared/platform.ts +20 -0
- package/src/shared/query.ts +176 -0
- package/src/shared/rules.test.ts +56 -0
- package/src/shared/rules.ts +371 -0
- package/src/shared/schedules.test.ts +570 -0
- package/src/shared/schedules.ts +560 -0
- package/src/shared/test-helpers.ts +156 -0
- package/src/shared/transactions.test.ts +275 -0
- package/src/shared/transactions.ts +433 -0
- package/src/shared/transfer.test.ts +75 -0
- package/src/shared/transfer.ts +16 -0
- package/src/shared/user.ts +4 -0
- package/src/shared/util.test.ts +240 -0
- package/src/shared/util.ts +633 -0
- package/src/types/api-handlers.ts +287 -0
- package/src/types/budget.ts +8 -0
- package/src/types/file.ts +47 -0
- package/src/types/handlers.ts +46 -0
- package/src/types/models/account.ts +24 -0
- package/src/types/models/bank-sync.ts +23 -0
- package/src/types/models/bank.ts +6 -0
- package/src/types/models/category-group.ts +11 -0
- package/src/types/models/category.ts +13 -0
- package/src/types/models/dashboard.ts +199 -0
- package/src/types/models/gocardless.ts +84 -0
- package/src/types/models/import-transaction.ts +56 -0
- package/src/types/models/index.ts +23 -0
- package/src/types/models/nearby-payee.ts +7 -0
- package/src/types/models/note.ts +4 -0
- package/src/types/models/openid.ts +8 -0
- package/src/types/models/payee-location.ts +8 -0
- package/src/types/models/payee.ts +10 -0
- package/src/types/models/pluggyai.ts +19 -0
- package/src/types/models/reports.ts +144 -0
- package/src/types/models/rule.ts +174 -0
- package/src/types/models/schedule.ts +49 -0
- package/src/types/models/simplefin.ts +28 -0
- package/src/types/models/tags.ts +6 -0
- package/src/types/models/templates.ts +135 -0
- package/src/types/models/transaction-filter.ts +9 -0
- package/src/types/models/transaction.ts +39 -0
- package/src/types/models/user-access.ts +10 -0
- package/src/types/models/user.ts +25 -0
- package/src/types/prefs.ts +167 -0
- package/src/types/server-events.ts +86 -0
- package/src/types/server-handlers.ts +27 -0
- package/src/types/util.ts +26 -0
- package/tsconfig.json +34 -0
- package/typings/pegjs.ts +1 -0
- package/typings/process-worker.ts +12 -0
- package/typings/vite-plugin-peggy-loader.ts +1 -0
- package/typings/window.ts +62 -0
- package/vite.config.ts +109 -0
- package/vite.desktop.config.ts +59 -0
- package/vitest.config.ts +43 -0
- package/vitest.web.config.ts +38 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// @ts-strict-ignore
|
|
2
|
+
import * as nativeFs from 'fs';
|
|
3
|
+
|
|
4
|
+
import * as fetchClient from '../platform/client/connection';
|
|
5
|
+
import * as sqlite from '../platform/server/sqlite';
|
|
6
|
+
import * as db from '../server/db';
|
|
7
|
+
import type * as MigrationsType from '../server/migrate/migrations';
|
|
8
|
+
import {
|
|
9
|
+
disableGlobalMutations,
|
|
10
|
+
enableGlobalMutations,
|
|
11
|
+
} from '../server/mutators';
|
|
12
|
+
import { setServer } from '../server/server-config';
|
|
13
|
+
import * as sheet from '../server/sheet';
|
|
14
|
+
import { setSyncingMode } from '../server/sync';
|
|
15
|
+
import * as rules from '../server/transactions/transaction-rules';
|
|
16
|
+
import { updateVersion } from '../server/update';
|
|
17
|
+
import { resetTracer, tracer } from '../shared/test-helpers';
|
|
18
|
+
|
|
19
|
+
vi.mock('../platform/client/connection');
|
|
20
|
+
vi.mock('../platform/exceptions');
|
|
21
|
+
vi.mock('../platform/server/asyncStorage');
|
|
22
|
+
vi.mock('../platform/server/connection');
|
|
23
|
+
vi.mock('../server/post');
|
|
24
|
+
|
|
25
|
+
// By default, syncing is disabled
|
|
26
|
+
setSyncingMode('disabled');
|
|
27
|
+
|
|
28
|
+
// Set a mock url for the testing server
|
|
29
|
+
setServer('https://test.env');
|
|
30
|
+
|
|
31
|
+
process.on('unhandledRejection', reason => {
|
|
32
|
+
console.log('REJECTION', reason);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
global.IS_TESTING = true;
|
|
36
|
+
|
|
37
|
+
let _time = 123456789;
|
|
38
|
+
const _oldDateNow = global.Date.now;
|
|
39
|
+
global.Date.now = () => _time;
|
|
40
|
+
|
|
41
|
+
global.restoreDateNow = () => (global.Date.now = _oldDateNow);
|
|
42
|
+
global.restoreFakeDateNow = () => (global.Date.now = () => _time);
|
|
43
|
+
|
|
44
|
+
global.stepForwardInTime = time => {
|
|
45
|
+
if (time) {
|
|
46
|
+
_time = time;
|
|
47
|
+
} else {
|
|
48
|
+
_time += 1000;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
global.resetTime = () => {
|
|
53
|
+
_time = 123456789;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
let _id = 1;
|
|
57
|
+
global.resetRandomId = () => {
|
|
58
|
+
_id = 1;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
vi.mock('uuid', () => ({
|
|
62
|
+
v4: () => {
|
|
63
|
+
return 'id' + _id++;
|
|
64
|
+
},
|
|
65
|
+
}));
|
|
66
|
+
vi.mock('../server/migrate/migrations', async () => {
|
|
67
|
+
const realMigrations = await vi.importActual<typeof MigrationsType>(
|
|
68
|
+
'../server/migrate/migrations',
|
|
69
|
+
);
|
|
70
|
+
return {
|
|
71
|
+
...realMigrations,
|
|
72
|
+
migrate: async db => {
|
|
73
|
+
_id = 100_000_000;
|
|
74
|
+
await realMigrations.migrate(db);
|
|
75
|
+
_id = 1;
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
global.getDatabaseDump = async function (tables) {
|
|
81
|
+
if (!tables) {
|
|
82
|
+
const rows = sqlite.runQuery<{ name }>(
|
|
83
|
+
db.getDatabase(),
|
|
84
|
+
"SELECT name FROM sqlite_master WHERE type='table'",
|
|
85
|
+
[],
|
|
86
|
+
true,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
tables = rows.map(row => row.name);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const data = await Promise.all(
|
|
93
|
+
tables.map(async table => {
|
|
94
|
+
let sortColumn;
|
|
95
|
+
switch (table) {
|
|
96
|
+
case 'spreadsheet_cells':
|
|
97
|
+
sortColumn = 'name';
|
|
98
|
+
break;
|
|
99
|
+
case 'created_budgets':
|
|
100
|
+
sortColumn = 'month';
|
|
101
|
+
break;
|
|
102
|
+
case 'db_version':
|
|
103
|
+
sortColumn = 'version';
|
|
104
|
+
break;
|
|
105
|
+
default:
|
|
106
|
+
sortColumn = 'id';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return [
|
|
110
|
+
table,
|
|
111
|
+
sqlite.runQuery(
|
|
112
|
+
db.getDatabase(),
|
|
113
|
+
'SELECT * FROM ' + table + ' ORDER BY ' + sortColumn,
|
|
114
|
+
[],
|
|
115
|
+
true,
|
|
116
|
+
),
|
|
117
|
+
];
|
|
118
|
+
}),
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const grouped = {};
|
|
122
|
+
data.forEach(table => (grouped[table[0]] = table[1]));
|
|
123
|
+
return grouped;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// If you want to test the sql.js backend, you need this so it knows
|
|
127
|
+
// where to find the webassembly file
|
|
128
|
+
// process.env.PUBLIC_URL =
|
|
129
|
+
// __dirname + '/../../../../node_modules/@jlongster/sql.js/dist/';
|
|
130
|
+
|
|
131
|
+
global.emptyDatabase = function (avoidUpdate) {
|
|
132
|
+
return async () => {
|
|
133
|
+
const path = ':memory:';
|
|
134
|
+
// let path = `/tmp/foo-${Math.random()}.sqlite`;
|
|
135
|
+
// console.log('Using db ' + path);
|
|
136
|
+
|
|
137
|
+
await sqlite.init();
|
|
138
|
+
|
|
139
|
+
const memoryDB = await sqlite.openDatabase(path);
|
|
140
|
+
sqlite.execQuery(
|
|
141
|
+
memoryDB,
|
|
142
|
+
nativeFs.readFileSync(__dirname + '/../server/sql/init.sql', 'utf8'),
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
db.setDatabase(memoryDB);
|
|
146
|
+
db.runQuery('INSERT INTO db_version (version) VALUES (?)', ['0.0.1']);
|
|
147
|
+
|
|
148
|
+
if (!avoidUpdate) {
|
|
149
|
+
await updateVersion();
|
|
150
|
+
await db.loadClock();
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
beforeEach(() => {
|
|
156
|
+
// This is necessary to create a valid rules state
|
|
157
|
+
rules.resetState();
|
|
158
|
+
resetTracer();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
afterEach(() => {
|
|
162
|
+
global.resetRandomId();
|
|
163
|
+
tracer.end();
|
|
164
|
+
void fetchClient.clearServer();
|
|
165
|
+
|
|
166
|
+
return new Promise(resolve => {
|
|
167
|
+
if (sheet.get()) {
|
|
168
|
+
sheet.get().onFinish(() => {
|
|
169
|
+
sheet.unloadSpreadsheet();
|
|
170
|
+
resolve(undefined);
|
|
171
|
+
});
|
|
172
|
+
} else {
|
|
173
|
+
resolve(undefined);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Tests by default are allowed to mutate the db at any time
|
|
179
|
+
beforeEach(() => enableGlobalMutations());
|
|
180
|
+
afterEach(() => disableGlobalMutations());
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// @ts-strict-ignore
|
|
2
|
+
export function makeSpreadsheet() {
|
|
3
|
+
const cells = {};
|
|
4
|
+
return {
|
|
5
|
+
observers: [],
|
|
6
|
+
_getNode(sheetName, name) {
|
|
7
|
+
const resolvedName = `${sheetName}!${name}`;
|
|
8
|
+
|
|
9
|
+
const existing = cells[resolvedName];
|
|
10
|
+
if (existing) {
|
|
11
|
+
return existing;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
cells[resolvedName] = {
|
|
15
|
+
name: resolvedName,
|
|
16
|
+
sheet: sheetName,
|
|
17
|
+
value: null,
|
|
18
|
+
};
|
|
19
|
+
return cells[resolvedName];
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
prewarmCache(sheetName = '__global', name, value) {
|
|
23
|
+
this._getNode(sheetName, name).value = value;
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
bind(sheetName, binding, cb) {
|
|
27
|
+
const { name } = binding;
|
|
28
|
+
const resolvedName = `${sheetName}!${name}`;
|
|
29
|
+
if (!this.observers[resolvedName]) {
|
|
30
|
+
this.observers[resolvedName] = [];
|
|
31
|
+
}
|
|
32
|
+
this.observers[resolvedName].push(cb);
|
|
33
|
+
|
|
34
|
+
const node = this._getNode(sheetName, name);
|
|
35
|
+
cb(node);
|
|
36
|
+
|
|
37
|
+
// bind returns a function which unsubscribes itself. In this mock
|
|
38
|
+
// it's a noop.
|
|
39
|
+
return () => {
|
|
40
|
+
this.observers[resolvedName] = this.observers[resolvedName].filter(
|
|
41
|
+
x => x !== cb,
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
create(sheetName, name, expr) {
|
|
47
|
+
this.set(sheetName, name, expr);
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
get(sheetName, name) {
|
|
51
|
+
return this._getNode(sheetName, name);
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
getValue(sheetName, name) {
|
|
55
|
+
return this._getNode(sheetName, name).value;
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
set(sheetName, name, expr) {
|
|
59
|
+
const node = this._getNode(sheetName, name);
|
|
60
|
+
node.value = expr;
|
|
61
|
+
|
|
62
|
+
const resolvedName = `${sheetName}!${name}`;
|
|
63
|
+
if (this.observers[resolvedName]) {
|
|
64
|
+
this.observers[resolvedName].forEach(cb => cb(node));
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
getCellNames(sheetName) {
|
|
69
|
+
const names = Object.keys(cells);
|
|
70
|
+
if (sheetName) {
|
|
71
|
+
return names.filter(name => name.startsWith(sheetName + '!'));
|
|
72
|
+
}
|
|
73
|
+
return names;
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
getCells() {
|
|
77
|
+
return cells;
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
setCells(cells) {
|
|
81
|
+
Object.keys(cells).forEach(sheet => {
|
|
82
|
+
Object.keys(cells[sheet]).forEach(name => {
|
|
83
|
+
this.set(sheet, name, cells[sheet][name]);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
deleteCells(cells) {
|
|
89
|
+
Object.keys(cells).forEach(sheet => {
|
|
90
|
+
cells[sheet].forEach(name => {
|
|
91
|
+
this.set(sheet, name, '');
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
batchChange(batch) {
|
|
97
|
+
this.setCells(batch.updateCells);
|
|
98
|
+
this.deleteCells(batch.deleteCells);
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// @ts-strict-ignore
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import { basename, dirname, join } from 'path';
|
|
4
|
+
|
|
5
|
+
import { diff } from 'jest-diff';
|
|
6
|
+
|
|
7
|
+
export function expectSnapshotWithDiffer(
|
|
8
|
+
initialValue,
|
|
9
|
+
{ onlyUpdates }: { onlyUpdates? } = {},
|
|
10
|
+
) {
|
|
11
|
+
let currentValue = initialValue;
|
|
12
|
+
if (!onlyUpdates) {
|
|
13
|
+
expect(initialValue).toMatchSnapshot();
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
expectToMatchDiff: value => {
|
|
17
|
+
expect(
|
|
18
|
+
diff(currentValue, value, {
|
|
19
|
+
aAnnotation: 'First value',
|
|
20
|
+
bAnnotation: 'Second value',
|
|
21
|
+
contextLines: 5,
|
|
22
|
+
expand: false,
|
|
23
|
+
}),
|
|
24
|
+
).toMatchSnapshot();
|
|
25
|
+
currentValue = value;
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function getFixtures(filename) {
|
|
31
|
+
join(
|
|
32
|
+
dirname(filename),
|
|
33
|
+
'__fixtures__',
|
|
34
|
+
basename(filename).replace(/\.[^.]+.js/, '.fixtures.js'),
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function debugDOM(node) {
|
|
39
|
+
function debugDOM(node, indent = 0) {
|
|
40
|
+
let str = '';
|
|
41
|
+
if (node) {
|
|
42
|
+
str += ' '.repeat(indent);
|
|
43
|
+
if (node.tagName) {
|
|
44
|
+
str +=
|
|
45
|
+
node.tagName.toLowerCase() +
|
|
46
|
+
' ' +
|
|
47
|
+
(node.tabIndex || '') +
|
|
48
|
+
(node.dataset['testid'] ? ' ' + node.dataset['testid'] : '') +
|
|
49
|
+
'\n';
|
|
50
|
+
} else {
|
|
51
|
+
str += node.textContent + '\n';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
for (const child of node.childNodes) {
|
|
55
|
+
str += debugDOM(child, indent + 2);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return str;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return debugDOM(node);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function patchFetchForSqlJS(baseURL: string) {
|
|
65
|
+
// Patch the global fetch to resolve to a file
|
|
66
|
+
// This is a workaround for the fact that initSqlJS uses fetch to load the wasm file
|
|
67
|
+
// and we can't use the file protocol directly in tests
|
|
68
|
+
vi.spyOn(global, 'fetch').mockImplementation(
|
|
69
|
+
async (url: string | URL | Request) => {
|
|
70
|
+
if (typeof url === 'string' && url.startsWith(baseURL)) {
|
|
71
|
+
return new Response(new Uint8Array(await fs.readFile(url)), {
|
|
72
|
+
status: 200,
|
|
73
|
+
statusText: 'OK',
|
|
74
|
+
headers: {
|
|
75
|
+
'Content-Type': 'application/wasm',
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return Promise.reject(new Error(`fetch not mocked for ${String(url)}`));
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// @ts-strict-ignore
|
|
2
|
+
import type * as T from '../index-types';
|
|
3
|
+
|
|
4
|
+
let listeners = new Map();
|
|
5
|
+
let serverHandler = null;
|
|
6
|
+
|
|
7
|
+
export const initServer: T.InitServer = handlers => {
|
|
8
|
+
serverHandler = msg => {
|
|
9
|
+
const { name, args, catchErrors } = msg;
|
|
10
|
+
if (handlers[name]) {
|
|
11
|
+
return Promise.resolve().then(() => {
|
|
12
|
+
const promise = handlers[name](args);
|
|
13
|
+
|
|
14
|
+
if (catchErrors) {
|
|
15
|
+
return promise.then(
|
|
16
|
+
data => ({ data }),
|
|
17
|
+
error => ({ error }),
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
return promise;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const clearServer: T.ClearServer = async () => {
|
|
27
|
+
serverHandler = null;
|
|
28
|
+
listeners = new Map();
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const serverPush: T.ServerPush = (name, args) => {
|
|
32
|
+
void Promise.resolve().then(() => {
|
|
33
|
+
const listens = listeners.get(name);
|
|
34
|
+
if (listens) {
|
|
35
|
+
listens.forEach(listener => {
|
|
36
|
+
listener(args);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const send = async (name, args, { catchErrors = false } = {}) => {
|
|
43
|
+
if (serverHandler) {
|
|
44
|
+
return serverHandler({ name, args, catchErrors });
|
|
45
|
+
} else {
|
|
46
|
+
throw new Error('`send` called with no mock server installed');
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const sendCatch = (name, args) => {
|
|
51
|
+
return send(name, args, { catchErrors: true });
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const listen = (name, cb) => {
|
|
55
|
+
if (!listeners.get(name)) {
|
|
56
|
+
listeners.set(name, []);
|
|
57
|
+
}
|
|
58
|
+
listeners.get(name).push(cb);
|
|
59
|
+
|
|
60
|
+
return () => {
|
|
61
|
+
const arr = listeners.get(name);
|
|
62
|
+
listeners.set(
|
|
63
|
+
name,
|
|
64
|
+
arr.filter(cb_ => cb_ !== cb),
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { Handlers } from '../../../types/handlers';
|
|
2
|
+
import type { ServerEvents } from '../../../types/server-events';
|
|
3
|
+
|
|
4
|
+
export declare function init(): Promise<unknown>;
|
|
5
|
+
export type Init = typeof init;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Send a command to the browser server.
|
|
9
|
+
*
|
|
10
|
+
* @param name The name of the command to be executed by the browser server.
|
|
11
|
+
* @param args The command arguments.
|
|
12
|
+
* @param options The options for the command. If `catchErrors` is true,
|
|
13
|
+
* and an error occurs, the promise will be resolved with an object that
|
|
14
|
+
* has an `error` property. Otherwise, the promise will be rejected with the error.
|
|
15
|
+
* @returns A promise that resolves with the command result, or rejects with an error if one occurs.
|
|
16
|
+
* If you want to catch errors as part of the resolved value instead of rejecting, use `sendCatch` instead.
|
|
17
|
+
*/
|
|
18
|
+
export declare function send<K extends keyof Handlers>(
|
|
19
|
+
name: K,
|
|
20
|
+
args: Parameters<Handlers[K]>[0],
|
|
21
|
+
options: { catchErrors: true },
|
|
22
|
+
): Promise<
|
|
23
|
+
| { data: Awaited<ReturnType<Handlers[K]>>; error: undefined }
|
|
24
|
+
| {
|
|
25
|
+
data: undefined;
|
|
26
|
+
error: {
|
|
27
|
+
type: 'APIError' | 'ServerError';
|
|
28
|
+
message: string;
|
|
29
|
+
cause?: unknown;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
>;
|
|
33
|
+
export declare function send<K extends keyof Handlers>(
|
|
34
|
+
name: K,
|
|
35
|
+
args?: Parameters<Handlers[K]>[0],
|
|
36
|
+
options?: { catchErrors?: boolean },
|
|
37
|
+
): Promise<Awaited<ReturnType<Handlers[K]>>>;
|
|
38
|
+
export type Send = typeof send;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Send a command to the browser server.
|
|
42
|
+
*
|
|
43
|
+
* @param name The name of the command to be executed by the browser server.
|
|
44
|
+
* @param args The command arguments.
|
|
45
|
+
* @returns A promise that resolves with an object containing either the command result or an error if one occurs.
|
|
46
|
+
* The promise will never reject, as errors are caught and returned as part of the resolved value.
|
|
47
|
+
*/
|
|
48
|
+
export declare function sendCatch<K extends keyof Handlers>(
|
|
49
|
+
name: K,
|
|
50
|
+
args?: Parameters<Handlers[K]>[0],
|
|
51
|
+
): Promise<
|
|
52
|
+
| { data: Awaited<ReturnType<Handlers[K]>>; error: undefined }
|
|
53
|
+
| {
|
|
54
|
+
data: undefined;
|
|
55
|
+
error: {
|
|
56
|
+
type: 'APIError' | 'ServerError';
|
|
57
|
+
message: string;
|
|
58
|
+
cause?: unknown;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
>;
|
|
62
|
+
export type SendCatch = typeof sendCatch;
|
|
63
|
+
|
|
64
|
+
/** Server push listeners */
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Listen to events pushed to the client from the browser server.
|
|
68
|
+
*
|
|
69
|
+
* @param name The name of the event to listen to.
|
|
70
|
+
* @param cb The callback to be called when the event is received.
|
|
71
|
+
* @returns A function that can be called to unregister the listener.
|
|
72
|
+
*/
|
|
73
|
+
export declare function listen<K extends keyof ServerEvents>(
|
|
74
|
+
name: K,
|
|
75
|
+
cb: (arg: ServerEvents[K]) => void,
|
|
76
|
+
): () => void;
|
|
77
|
+
export type Listen = typeof listen;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Stop listening to events pushed to the client from the browser server.
|
|
81
|
+
*
|
|
82
|
+
* @param name The name of the event to stop listening to.
|
|
83
|
+
*/
|
|
84
|
+
export declare function unlisten(name: string): void;
|
|
85
|
+
export type Unlisten = typeof unlisten;
|
|
86
|
+
|
|
87
|
+
/** Mock functions */
|
|
88
|
+
export declare function initServer(handlers: Partial<Handlers>): void;
|
|
89
|
+
export type InitServer = typeof initServer;
|
|
90
|
+
|
|
91
|
+
export declare function serverPush(name: string, args: unknown): void;
|
|
92
|
+
export type ServerPush = typeof serverPush;
|
|
93
|
+
|
|
94
|
+
export declare function clearServer(): Promise<void>;
|
|
95
|
+
export type ClearServer = typeof clearServer;
|