[AI] Add subpath import wildcard patterns to loot-core (#7429)

* [AI] Add subpath import wildcard patterns and explicit directory entries to loot-core

Extend the package.json imports field with prefix-specific wildcard patterns
(#server/*, #shared/*, #types/*, #mocks/*, #platform/*) and explicit entries
for directory imports (#server/db, #server/sync, etc.) to support the ongoing
migration from relative imports to subpath imports.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* [AI] Add release notes for #7429

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Co-authored-by: Cursor Agent <[email protected]>
Co-authored-by: Matiss Janis Aboltins <[email protected]>
This commit is contained in:
Matiss Janis Aboltins
2026-04-09 08:02:25 +00:00
committed by GitHub
co-authored by Claude Opus 4.6 Cursor Agent Matiss Janis Aboltins
parent e6bd684812
commit f364d5a9d8
156 changed files with 770 additions and 633 deletions
+6
View File
@@ -396,6 +396,12 @@
"actual/no-anchor-tag": "off"
}
},
{
"files": ["packages/loot-core/src/**/*.{ts,tsx}"],
"rules": {
"actual/prefer-subpath-imports": "error"
}
},
{
"files": ["packages/desktop-client/**/*.{js,ts,jsx,tsx}"],
"rules": {
@@ -12,5 +12,6 @@ module.exports = {
'prefer-const': require('./rules/prefer-const'),
'no-anchor-tag': require('./rules/no-anchor-tag'),
'no-react-default-import': require('./rules/no-react-default-import'),
'prefer-subpath-imports': require('./rules/prefer-subpath-imports'),
},
};
@@ -0,0 +1,96 @@
const path = require('path');
/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
meta: {
type: 'suggestion',
docs: {
description:
'Prefer subpath imports (#path/to/module) over relative backtracked imports (../path/to/module) in loot-core',
},
fixable: 'code',
schema: [],
messages: {
preferSubpathImport:
'Use subpath import "{{subpath}}" instead of relative import "{{original}}"',
},
},
create(context) {
const filenameRaw = context.getFilename();
const normalizedFilename = filenameRaw.replace(/\\/g, '/');
// Only apply to files inside packages/loot-core/src/
const lootCoreMatch = normalizedFilename.match(
/packages\/loot-core\/src\//,
);
if (!lootCoreMatch) {
return {};
}
// Get the absolute path to the src/ directory
const srcIndex =
normalizedFilename.indexOf('packages/loot-core/src/') +
'packages/loot-core/src/'.length;
const srcDir = normalizedFilename.slice(0, srcIndex);
function getSubpathImport(importSource) {
// Only transform backtracked imports
if (!importSource.startsWith('../')) {
return null;
}
const fileDir = path.dirname(normalizedFilename);
const resolved = path.posix.join(fileDir, importSource);
// Check that the resolved path is inside src/
if (!resolved.startsWith(srcDir.slice(0, -1))) {
return null;
}
// Get path relative to src/
let subpath = resolved.slice(srcDir.length);
// Strip file extensions
subpath = subpath.replace(/\.(ts|tsx|js|jsx)$/, '');
// Strip trailing /index
subpath = subpath.replace(/\/index$/, '');
return '#' + subpath;
}
function checkAndReport(node, source) {
if (!source || typeof source.value !== 'string') return;
const subpath = getSubpathImport(source.value);
if (!subpath) return;
context.report({
node: source,
messageId: 'preferSubpathImport',
data: {
subpath,
original: source.value,
},
fix(fixer) {
const raw = source.raw;
const quote = raw[0];
return fixer.replaceText(source, `${quote}${subpath}${quote}`);
},
});
}
return {
ImportDeclaration(node) {
checkAndReport(node, node.source);
},
ExportNamedDeclaration(node) {
checkAndReport(node, node.source);
},
ExportAllDeclaration(node) {
checkAndReport(node, node.source);
},
};
},
};
@@ -1,6 +1,6 @@
import { v4 as uuidv4 } from 'uuid';
import { DEFAULT_DASHBOARD_STATE } from '../src/shared/dashboard';
import { DEFAULT_DASHBOARD_STATE } from '#shared/dashboard';
export default async function runMigration(db) {
db.transaction(() => {
+25 -9
View File
@@ -41,9 +41,10 @@
"api": "./src/platform/server/sqlite/index.api.ts",
"default": "./src/platform/server/sqlite/index.ts"
},
"#platform/server/log": "./src/platform/server/log/index.ts",
"#platform/server/indexeddb": "./src/platform/server/indexeddb/index.ts",
"#platform/exceptions": "./src/platform/exceptions/index.ts",
"#platform/client/connection": {
"electron": "./src/platform/client/connection/index.ts",
"default": "./src/platform/client/connection/index.browser.ts"
},
"#server/encryption/encryption-internals": {
"electron": "./src/server/encryption/encryption-internals.electron.ts",
"api": "./src/server/encryption/encryption-internals.api.ts",
@@ -54,12 +55,27 @@
"api": "./src/shared/platform.api.ts",
"default": "./src/shared/platform.ts"
},
"#*": [
"./src/*.ts",
"./src/*.tsx",
"./src/*/index.ts",
"./src/*/index.tsx"
]
"#mocks": "./src/mocks/index.ts",
"#platform/client/undo": "./src/platform/client/undo/index.ts",
"#platform/exceptions": "./src/platform/exceptions/index.ts",
"#platform/server/indexeddb": "./src/platform/server/indexeddb/index.ts",
"#platform/server/log": "./src/platform/server/log/index.ts",
"#server/aql": "./src/server/aql/index.ts",
"#server/db": "./src/server/db/index.ts",
"#server/encryption": "./src/server/encryption/index.ts",
"#server/importers": "./src/server/importers/index.ts",
"#server/rules": "./src/server/rules/index.ts",
"#server/sync": "./src/server/sync/index.ts",
"#server/transactions": "./src/server/transactions/index.ts",
"#types/models": "./src/types/models/index.ts",
"#platform/client/*": "./src/platform/client/*.ts",
"#platform/server/*": "./src/platform/server/*.ts",
"#platform/*": "./src/platform/*.ts",
"#server/*": "./src/server/*.ts",
"#shared/*": "./src/shared/*.ts",
"#types/*": "./src/types/*.ts",
"#mocks/*": "./src/mocks/*.ts",
"#*": "./src/*.ts"
},
"exports": {
"./client/accounts/*": "./src/client/accounts/*.ts",
@@ -2,8 +2,8 @@
import fc from 'fast-check';
import type { Arbitrary } from 'fast-check';
import { schema } from '../server/aql';
import { addDays } from '../shared/months';
import { schema } from '#server/aql';
import { addDays } from '#shared/months';
export function typeArbitrary(typeDesc, name?) {
let arb;
+12 -12
View File
@@ -1,22 +1,22 @@
// @ts-strict-ignore
import { v4 as uuidv4 } from 'uuid';
import { addTransactions } from '../server/accounts/sync';
import { aqlQuery } from '../server/aql';
import * as budgetActions from '../server/budget/actions';
import * as budget from '../server/budget/base';
import * as db from '../server/db';
import { runHandler, runMutator } from '../server/mutators';
import * as sheet from '../server/sheet';
import { batchMessages, setSyncingMode } from '../server/sync';
import * as monthUtils from '../shared/months';
import { q } from '../shared/query';
import type { Handlers } from '../types/handlers';
import { addTransactions } from '#server/accounts/sync';
import { aqlQuery } from '#server/aql';
import * as budgetActions from '#server/budget/actions';
import * as budget from '#server/budget/base';
import * as db from '#server/db';
import { runHandler, runMutator } from '#server/mutators';
import * as sheet from '#server/sheet';
import { batchMessages, setSyncingMode } from '#server/sync';
import * as monthUtils from '#shared/months';
import { q } from '#shared/query';
import type { Handlers } from '#types/handlers';
import type {
CategoryGroupEntity,
PayeeEntity,
TransactionEntity,
} from '../types/models';
} from '#types/models';
import { random } from './random';
+2 -2
View File
@@ -1,12 +1,12 @@
import { v4 as uuidv4 } from 'uuid';
import * as monthUtils from '../shared/months';
import * as monthUtils from '#shared/months';
import type {
AccountEntity,
CategoryEntity,
CategoryGroupEntity,
TransactionEntity,
} from '../types/models';
} from '#types/models';
import { random } from './random';
+15 -15
View File
@@ -1,26 +1,26 @@
// @ts-strict-ignore
import * as nativeFs from 'fs';
import * as fetchClient from '#platform/client/connection';
import * as sqlite from '#platform/server/sqlite';
import * as fetchClient from '../platform/client/connection';
import * as db from '../server/db';
import type * as MigrationsType from '../server/migrate/migrations';
import * as db from '#server/db';
import type * as MigrationsType from '#server/migrate/migrations';
import {
disableGlobalMutations,
enableGlobalMutations,
} from '../server/mutators';
import { setServer } from '../server/server-config';
import * as sheet from '../server/sheet';
import { setSyncingMode } from '../server/sync';
import * as rules from '../server/transactions/transaction-rules';
import { updateVersion } from '../server/update';
import { resetTracer, tracer } from '../shared/test-helpers';
} from '#server/mutators';
import { setServer } from '#server/server-config';
import * as sheet from '#server/sheet';
import { setSyncingMode } from '#server/sync';
import * as rules from '#server/transactions/transaction-rules';
import { updateVersion } from '#server/update';
import { resetTracer, tracer } from '#shared/test-helpers';
vi.mock('../platform/client/connection');
vi.mock('../platform/exceptions');
vi.mock('#platform/client/connection');
vi.mock('#platform/exceptions');
vi.mock('#platform/server/asyncStorage');
vi.mock('#platform/server/connection');
vi.mock('../server/post');
vi.mock('#server/post');
// By default, syncing is disabled
setSyncingMode('disabled');
@@ -63,9 +63,9 @@ vi.mock('uuid', () => ({
return 'id' + _id++;
},
}));
vi.mock('../server/migrate/migrations', async () => {
vi.mock('#server/migrate/migrations', async () => {
const realMigrations = await vi.importActual<typeof MigrationsType>(
'../server/migrate/migrations',
'#server/migrate/migrations',
);
return {
...realMigrations,
@@ -1,5 +1,5 @@
// @ts-strict-ignore
import type * as T from '../index-types';
import type * as T from '#platform/client/connection/index-types';
let listeners = new Map();
let serverHandler = null;
@@ -1,5 +1,5 @@
import type { Handlers } from '../../../types/handlers';
import type { ServerEvents } from '../../../types/server-events';
import type { Handlers } from '#types/handlers';
import type { ServerEvents } from '#types/server-events';
export declare function init(): Promise<unknown>;
export type Init = typeof init;
@@ -2,8 +2,8 @@
import { t } from 'i18next';
import { v4 as uuidv4 } from 'uuid';
import { captureBreadcrumb, captureException } from '../../exceptions';
import * as undo from '../undo';
import * as undo from '#platform/client/undo';
import { captureBreadcrumb, captureException } from '#platform/exceptions';
import type * as T from './index-types';
@@ -1,7 +1,7 @@
// @ts-strict-ignore
import { v4 as uuidv4 } from 'uuid';
import * as undo from '../undo';
import * as undo from '#platform/client/undo';
import type * as T from './index-types';
@@ -1,6 +1,6 @@
import { v4 as uuidv4 } from 'uuid';
import type { UndoState as ServerUndoState } from '../../../server/undo';
import type { UndoState as ServerUndoState } from '#server/undo';
// oxlint-disable-next-line @typescript-eslint/no-explicit-any
type Modal = any; // TODO: fix me
@@ -1,6 +1,6 @@
import type * as T from '#platform/server/asyncStorage/index-types';
// @ts-strict-ignore
import type { GlobalPrefsJson } from '../../../../types/prefs';
import type * as T from '../index-types';
import type { GlobalPrefsJson } from '#types/prefs';
const store: GlobalPrefsJson = {};
@@ -1,4 +1,4 @@
import type { GlobalPrefsJson } from '../../../types/prefs';
import type { GlobalPrefsJson } from '#types/prefs';
export declare function init(opts?: { persist?: boolean }): void;
export type Init = typeof init;
@@ -1,6 +1,6 @@
import { getDatabase } from '#platform/server/indexeddb';
// @ts-strict-ignore
import type { GlobalPrefsJson } from '../../../types/prefs';
import { getDatabase } from '../indexeddb';
import type { GlobalPrefsJson } from '#types/prefs';
import type * as T from './index-types';
@@ -1,4 +1,4 @@
import type * as T from '../index-types';
import type * as T from '#platform/server/connection/index-types';
let events = [];
@@ -1,5 +1,5 @@
import type { Handlers } from '../../../types/handlers';
import type { ServerEvents } from '../../../types/server-events';
import type { Handlers } from '#types/handlers';
import type { ServerEvents } from '#types/server-events';
export declare function init(
channel: Window | number, // in electron the port number, in web the worker
@@ -1,8 +1,8 @@
import { captureException } from '#platform/exceptions';
import { logger } from '#platform/server/log';
// @ts-strict-ignore
import { APIError } from '../../../server/errors';
import { isMutating, runHandler } from '../../../server/mutators';
import { captureException } from '../../exceptions';
import { logger } from '../log';
import { APIError } from '#server/errors';
import { isMutating, runHandler } from '#server/mutators';
import type * as T from './index-types';
@@ -1,4 +1,4 @@
import { logger } from '../log';
import { logger } from '#platform/server/log';
import type * as T from './index';
@@ -4,7 +4,7 @@ import * as path from 'path';
import promiseRetry from 'promise-retry';
import { logger } from '../log';
import { logger } from '#platform/server/log';
import type * as T from './index';
@@ -4,7 +4,7 @@ import * as path from 'path';
import promiseRetry from 'promise-retry';
import { logger } from '../log';
import { logger } from '#platform/server/log';
import type * as T from './index';
@@ -1,9 +1,9 @@
import 'fake-indexeddb/auto';
import { IDBFactory } from 'fake-indexeddb';
import { patchFetchForSqlJS } from '#mocks/util';
import * as idb from '#platform/server/indexeddb';
import * as sqlite from '#platform/server/sqlite';
import { patchFetchForSqlJS } from '../../../mocks/util';
import { exists, init, join, pathToId, readFile, writeFile } from './index';
@@ -1,4 +1,4 @@
import { logger } from '../log';
import { logger } from '#platform/server/log';
let openedDb: null | ReturnType<typeof _openDatabase> = _openDatabase();
@@ -1,5 +1,5 @@
// @ts-strict-ignore
import { patchFetchForSqlJS } from '../../../mocks/util';
import { patchFetchForSqlJS } from '#mocks/util';
import { execQuery, init, openDatabase, runQuery, transaction } from './index';
@@ -2,7 +2,7 @@
import initSqlJS from '@jlongster/sql.js';
import type { Database, SqlJsStatic, Statement } from '@jlongster/sql.js';
import { logger } from '../log';
import { logger } from '#platform/server/log';
import { normalise } from './normalise';
import { unicodeLike } from './unicodeLike';
@@ -1,4 +1,4 @@
import { getNormalisedString } from '../../../shared/normalisation';
import { getNormalisedString } from '#shared/normalisation';
export function normalise(value: string | null): string | null {
if (!value) {
@@ -2,7 +2,7 @@
export {
handleRequest as post,
handleRequestBinary as postBinary,
} from '../tests/mockSyncServer';
} from '#server/tests/mockSyncServer';
export const get = function () {
throw new Error('get unimplemented');
@@ -1,5 +1,5 @@
import * as db from '../db';
import { loadMappings } from '../db/mappings';
import * as db from '#server/db';
import { loadMappings } from '#server/db/mappings';
import { app } from './app';
import * as bankSync from './sync';
+20 -20
View File
@@ -1,15 +1,29 @@
import { t } from 'i18next';
import { v4 as uuidv4 } from 'uuid';
import { captureException } from '#platform/exceptions';
import * as asyncStorage from '#platform/server/asyncStorage';
import * as connection from '#platform/server/connection';
import { logger } from '#platform/server/log';
import { createApp } from '#server/app';
import * as db from '#server/db';
import {
APIError,
BankSyncError,
PostError,
TransactionError,
} from '#server/errors';
import { app as mainApp } from '#server/main-app';
import { mutator } from '#server/mutators';
import { get, post } from '#server/post';
import { getServer } from '#server/server-config';
import { batchMessages } from '#server/sync';
import { undoable, withUndo } from '#server/undo';
import { isNonProductionEnvironment } from '#shared/environment';
import { dayFromDate } from '#shared/months';
import * as monthUtils from '#shared/months';
import { amountToInteger } from '#shared/util';
import type { ImportTransactionsOpts } from '#types/api-handlers';
import { captureException } from '../../platform/exceptions';
import { isNonProductionEnvironment } from '../../shared/environment';
import { dayFromDate } from '../../shared/months';
import * as monthUtils from '../../shared/months';
import { amountToInteger } from '../../shared/util';
import type {
AccountEntity,
CategoryEntity,
@@ -19,21 +33,7 @@ import type {
SyncServerPluggyAiAccount,
SyncServerSimpleFinAccount,
TransactionEntity,
} from '../../types/models';
import { createApp } from '../app';
import * as db from '../db';
import {
APIError,
BankSyncError,
PostError,
TransactionError,
} from '../errors';
import { app as mainApp } from '../main-app';
import { mutator } from '../mutators';
import { get, post } from '../post';
import { getServer } from '../server-config';
import { batchMessages } from '../sync';
import { undoable, withUndo } from '../undo';
} from '#types/models';
import * as link from './link';
import { getStartingBalancePayee } from './payees';
@@ -1,7 +1,7 @@
// @ts-strict-ignore
import { v4 as uuidv4 } from 'uuid';
import * as db from '../db';
import * as db from '#server/db';
export async function findOrCreateBank(institution, requisitionId) {
const bank = await db.first<Pick<db.DbBank, 'id' | 'bank_id'>>(
@@ -1,4 +1,4 @@
import * as db from '../db';
import * as db from '#server/db';
export async function createPayee(description: string) {
// Check to make sure no payee already exists with exactly the same
@@ -1,13 +1,13 @@
// @ts-strict-ignore
import * as asyncStorage from '#platform/server/asyncStorage';
import * as monthUtils from '../../shared/months';
import type { SyncedPrefs } from '../../types/prefs';
import * as db from '../db';
import { loadMappings } from '../db/mappings';
import { post } from '../post';
import { getServer } from '../server-config';
import { handlers } from '../tests/mockSyncServer';
import { insertRule, loadRules } from '../transactions/transaction-rules';
import * as db from '#server/db';
import { loadMappings } from '#server/db/mappings';
import { post } from '#server/post';
import { getServer } from '#server/server-config';
import { handlers } from '#server/tests/mockSyncServer';
import { insertRule, loadRules } from '#server/transactions/transaction-rules';
import * as monthUtils from '#shared/months';
import type { SyncedPrefs } from '#types/prefs';
import {
addTransactions,
@@ -15,8 +15,8 @@ import {
simpleFinBatchSync,
} from './sync';
vi.mock('../../shared/months', async () => ({
...(await vi.importActual('../../shared/months')),
vi.mock('#shared/months', async () => ({
...(await vi.importActual('#shared/months')),
currentDay: vi.fn(),
currentMonth: vi.fn(),
}));
+19 -19
View File
@@ -3,36 +3,36 @@ import * as dateFns from 'date-fns';
import { v4 as uuidv4 } from 'uuid';
import * as asyncStorage from '#platform/server/asyncStorage';
import { logger } from '../../platform/server/log';
import * as monthUtils from '../../shared/months';
import { q } from '../../shared/query';
import { logger } from '#platform/server/log';
import { aqlQuery } from '#server/aql';
import * as db from '#server/db';
import { TRANSACTION_SORT_INCREMENT } from '#server/db/sort';
import { runMutator } from '#server/mutators';
import { post } from '#server/post';
import { getServer } from '#server/server-config';
import { batchMessages } from '#server/sync';
import { batchUpdateTransactions } from '#server/transactions';
import { runRules } from '#server/transactions/transaction-rules';
import {
defaultMappings,
mappingsFromString,
} from '#server/util/custom-sync-mapping';
import * as monthUtils from '#shared/months';
import { q } from '#shared/query';
import {
makeChild as makeChildTransaction,
recalculateSplit,
} from '../../shared/transactions';
} from '#shared/transactions';
import {
amountToInteger,
hasFieldsChanged,
integerToAmount,
} from '../../shared/util';
} from '#shared/util';
import type {
AccountEntity,
BankSyncResponse,
TransactionEntity,
} from '../../types/models';
import { aqlQuery } from '../aql';
import * as db from '../db';
import { TRANSACTION_SORT_INCREMENT } from '../db/sort';
import { runMutator } from '../mutators';
import { post } from '../post';
import { getServer } from '../server-config';
import { batchMessages } from '../sync';
import { batchUpdateTransactions } from '../transactions';
import { runRules } from '../transactions/transaction-rules';
import {
defaultMappings,
mappingsFromString,
} from '../util/custom-sync-mapping';
} from '#types/models';
import { getStartingBalancePayee } from './payees';
import { title } from './title';
+4 -4
View File
@@ -1,13 +1,13 @@
// @ts-strict-ignore
import * as asyncStorage from '#platform/server/asyncStorage';
import { createApp } from '#server/app';
import { del, get, patch, post } from '#server/post';
import { getServer } from '#server/server-config';
import type {
NewUserAccessEntity,
UserAvailable,
UserEntity,
} from '../../types/models';
import { createApp } from '../app';
import { del, get, patch, post } from '../post';
import { getServer } from '../server-config';
} from '#types/models';
export type AdminHandlers = {
'users-get': typeof getUsers;
+2 -2
View File
@@ -1,4 +1,4 @@
import type { Budget } from '../types/budget';
import type { Budget } from '#types/budget';
import type {
AccountEntity,
CategoryEntity,
@@ -6,7 +6,7 @@ import type {
PayeeEntity,
ScheduleEntity,
TagEntity,
} from '../types/models';
} from '#types/models';
import type { RemoteFile } from './cloud-storage';
import * as models from './models';
+3 -3
View File
@@ -1,8 +1,8 @@
import { getBankSyncError } from '../shared/errors';
import type { ServerHandlers } from '../types/server-handlers';
import { getBankSyncError } from '#shared/errors';
import type { ServerHandlers } from '#types/server-handlers';
import { installAPI } from './api';
vi.mock('../shared/errors', () => ({
vi.mock('#shared/errors', () => ({
getBankSyncError: vi.fn(error => `Bank sync error: ${error}`),
}));
+8 -8
View File
@@ -8,22 +8,22 @@ import {
getDownloadError,
getSyncError,
getTestKeyError,
} from '../shared/errors';
import * as monthUtils from '../shared/months';
import { q } from '../shared/query';
} from '#shared/errors';
import * as monthUtils from '#shared/months';
import { q } from '#shared/query';
import {
deleteTransaction,
ungroupTransactions,
updateTransaction,
} from '../shared/transactions';
import { integerToAmount } from '../shared/util';
import type { Handlers } from '../types/handlers';
} from '#shared/transactions';
import { integerToAmount } from '#shared/util';
import type { Handlers } from '#types/handlers';
import type {
AccountEntity,
CategoryGroupEntity,
ScheduleEntity,
} from '../types/models';
import type { ServerHandlers } from '../types/server-handlers';
} from '#types/models';
import type { ServerHandlers } from '#types/server-handlers';
import { addTransactions } from './accounts/sync';
import {
+2 -2
View File
@@ -2,8 +2,8 @@
import mitt from 'mitt';
import type { Emitter } from 'mitt';
import { captureException } from '../platform/exceptions';
import type { ServerEvents } from '../types/server-events';
import { captureException } from '#platform/exceptions';
import type { ServerEvents } from '#types/server-events';
// This is a simple helper abstraction for defining methods exposed to
// the client. It doesn't do much, but checks for naming conflicts and
@@ -1,5 +1,5 @@
// @ts-strict-ignore
import { q } from '../../shared/query';
import { q } from '#shared/query';
import { generateSQLWithState } from './compiler';
@@ -1,5 +1,5 @@
import { getNormalisedString } from '../../shared/normalisation';
import type { QueryState } from '../../shared/query';
import { getNormalisedString } from '#shared/normalisation';
import type { QueryState } from '#shared/query';
// @ts-strict-ignore
let _uid = 0;
@@ -1,9 +1,9 @@
// @ts-strict-ignore
import { v4 as uuidv4 } from 'uuid';
import { q } from '../../shared/query';
import { makeChild } from '../../shared/transactions';
import * as db from '../db';
import * as db from '#server/db';
import { q } from '#shared/query';
import { makeChild } from '#shared/transactions';
import * as aql from './exec';
import { schema, schemaConfig } from './schema';
+2 -2
View File
@@ -1,6 +1,6 @@
import * as db from '#server/db';
// @ts-strict-ignore
import type { QueryState } from '../../shared/query';
import * as db from '../db';
import type { QueryState } from '#shared/query';
import { compileQuery, defaultConstructQuery } from './compiler';
import type {
+2 -2
View File
@@ -1,5 +1,5 @@
import { Query } from '../../shared/query';
import type { QueryState } from '../../shared/query';
import { Query } from '#shared/query';
import type { QueryState } from '#shared/query';
import type { CompilerState, SqlPieces } from './compiler';
import { compileAndRunAqlQuery, runCompiledAqlQuery } from './exec';
@@ -1,6 +1,6 @@
import { fromDateRepr, toDateRepr } from '#server/models';
// @ts-strict-ignore
import { dayFromDate } from '../../shared/months';
import { fromDateRepr, toDateRepr } from '../models';
import { dayFromDate } from '#shared/months';
function isRequired(name, fieldDesc) {
return fieldDesc.required || name === 'id';
@@ -2,12 +2,12 @@
import { setClock } from '@actual-app/crdt';
import fc from 'fast-check';
import * as arbs from '#mocks/arbitrary-schema';
import * as db from '#server/db';
import { batchMessages, setSyncingMode } from '#server/sync';
import { q } from '#shared/query';
import { groupById } from '#shared/util';
import { aqlQuery } from '..';
import * as arbs from '../../../mocks/arbitrary-schema';
import { q } from '../../../shared/query';
import { groupById } from '../../../shared/util';
import * as db from '../../db';
import { batchMessages, setSyncingMode } from '../../sync/index';
import { isHappyPathQuery } from './executors';
@@ -1,16 +1,20 @@
// @ts-strict-ignore
import { isAggregateQuery } from '#server/aql/compiler';
import type {
CompilerState,
OutputTypes,
SqlPieces,
} from '#server/aql/compiler';
import { execQuery } from '#server/aql/exec';
import type { AqlQueryExecutor } from '#server/aql/exec';
import { convertOutputType } from '#server/aql/schema-helpers';
import * as db from '#server/db';
import { whereIn } from '#server/db/util';
import { q } from '#shared/query';
import type { QueryState } from '#shared/query';
import type { CategoryEntity } from '#types/models';
import { aqlQuery } from '..';
import { q } from '../../../shared/query';
import type { QueryState } from '../../../shared/query';
import type { CategoryEntity } from '../../../types/models';
import * as db from '../../db';
import { whereIn } from '../../db/util';
import { isAggregateQuery } from '../compiler';
import type { CompilerState, OutputTypes, SqlPieces } from '../compiler';
import { execQuery } from '../exec';
import type { AqlQueryExecutor } from '../exec';
import { convertOutputType } from '../schema-helpers';
// Transactions executor
@@ -1,5 +1,5 @@
// @ts-strict-ignore
import * as db from '../../db';
import * as db from '#server/db';
// This file doesn't test the schema code directly, it tests that
// views return data as expected and various constraints on the
@@ -1,5 +1,5 @@
// @ts-strict-ignore
import type { SchemaConfig } from '../compiler';
import type { SchemaConfig } from '#server/aql/compiler';
function f(type: string, opts?: Record<string, unknown>) {
return { type, ...opts };
@@ -1,5 +1,5 @@
// @ts-strict-ignore
import * as db from '../db';
import * as db from '#server/db';
import { makeViews } from './views';
+7 -7
View File
@@ -1,11 +1,11 @@
import * as asyncStorage from '#platform/server/asyncStorage';
import { logger } from '../../platform/server/log';
import type { OpenIdConfig } from '../../types/models';
import { createApp } from '../app';
import * as encryption from '../encryption';
import { PostError } from '../errors';
import { get, post } from '../post';
import { getServer, isValidBaseURL } from '../server-config';
import { logger } from '#platform/server/log';
import { createApp } from '#server/app';
import * as encryption from '#server/encryption';
import { PostError } from '#server/errors';
import { get, post } from '#server/post';
import { getServer, isValidBaseURL } from '#server/server-config';
import type { OpenIdConfig } from '#types/models';
export type AuthHandlers = {
'get-did-bootstrap': typeof didBootstrap;
+1 -1
View File
@@ -2,7 +2,7 @@
// @ts-strict-ignore
import * as fs from 'fs';
import { logger } from '../platform/server/log';
import { logger } from '#platform/server/log';
import * as db from './db';
@@ -1,7 +1,7 @@
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import * as db from '../db';
import * as sheet from '../sheet';
import * as db from '#server/db';
import * as sheet from '#server/sheet';
import {
coverOverbudgeted,
@@ -1,15 +1,15 @@
// @ts-strict-ignore
import * as asyncStorage from '#platform/server/asyncStorage';
import * as db from '#server/db';
import * as sheet from '#server/sheet';
import { batchMessages } from '#server/sync';
import { getCurrency } from '#shared/currencies';
import { getLocale } from '../../shared/locale';
import * as monthUtils from '../../shared/months';
import { integerToCurrency, safeNumber } from '../../shared/util';
import type { IntegerAmount } from '../../shared/util';
import type { CategoryEntity } from '../../types/models';
import * as db from '../db';
import * as sheet from '../sheet';
import { batchMessages } from '../sync';
import { getLocale } from '#shared/locale';
import * as monthUtils from '#shared/months';
import { integerToCurrency, safeNumber } from '#shared/util';
import type { IntegerAmount } from '#shared/util';
import type { CategoryEntity } from '#types/models';
export async function getSheetValue(
sheetName: string,
+13 -13
View File
@@ -1,16 +1,16 @@
import * as monthUtils from '../../shared/months';
import { q } from '../../shared/query';
import type { CategoryEntity, CategoryGroupEntity } from '../../types/models';
import { createApp } from '../app';
import { aqlQuery } from '../aql';
import * as db from '../db';
import { APIError } from '../errors';
import { categoryGroupModel, categoryModel } from '../models';
import { mutator } from '../mutators';
import * as sheet from '../sheet';
import { resolveName } from '../spreadsheet/util';
import { batchMessages } from '../sync';
import { undoable } from '../undo';
import { createApp } from '#server/app';
import { aqlQuery } from '#server/aql';
import * as db from '#server/db';
import { APIError } from '#server/errors';
import { categoryGroupModel, categoryModel } from '#server/models';
import { mutator } from '#server/mutators';
import * as sheet from '#server/sheet';
import { resolveName } from '#server/spreadsheet/util';
import { batchMessages } from '#server/sync';
import { undoable } from '#server/undo';
import * as monthUtils from '#shared/months';
import { q } from '#shared/query';
import type { CategoryEntity, CategoryGroupEntity } from '#types/models';
import * as actions from './actions';
import * as budget from './base';
@@ -1,7 +1,7 @@
import * as db from '#server/db';
import * as sheet from '#server/sheet';
// @ts-strict-ignore
import * as monthUtils from '../../shared/months';
import * as db from '../db';
import * as sheet from '../sheet';
import * as monthUtils from '#shared/months';
import { createAllBudgets } from './base';
+8 -8
View File
@@ -1,12 +1,12 @@
import { aqlQuery } from '#server/aql';
import * as db from '#server/db';
import * as sheet from '#server/sheet';
import { resolveName } from '#server/spreadsheet/util';
// @ts-strict-ignore
import * as monthUtils from '../../shared/months';
import { q } from '../../shared/query';
import { getChangedValues } from '../../shared/util';
import type { CategoryGroupEntity } from '../../types/models';
import { aqlQuery } from '../aql';
import * as db from '../db';
import * as sheet from '../sheet';
import { resolveName } from '../spreadsheet/util';
import * as monthUtils from '#shared/months';
import { q } from '#shared/query';
import { getChangedValues } from '#shared/util';
import type { CategoryGroupEntity } from '#types/models';
import * as budgetActions from './actions';
import * as envelopeBudget from './envelope';
@@ -1,10 +1,10 @@
import { vi } from 'vitest';
import { amountToInteger } from '../../shared/util';
import type { CategoryEntity } from '../../types/models';
import type { Template } from '../../types/models/templates';
import * as aql from '../aql';
import * as db from '../db';
import * as aql from '#server/aql';
import * as db from '#server/db';
import { amountToInteger } from '#shared/util';
import type { CategoryEntity } from '#types/models';
import type { Template } from '#types/models/templates';
import * as actions from './actions';
import { CategoryTemplateContext } from './category-template-context';
@@ -16,11 +16,11 @@ vi.mock('./actions', () => ({
isReflectBudget: vi.fn(),
}));
vi.mock('../db', () => ({
vi.mock('#server/db', () => ({
getCategories: vi.fn(),
}));
vi.mock('../aql', () => ({
vi.mock('#server/aql', () => ({
aqlQuery: vi.fn(),
}));
@@ -1,9 +1,11 @@
import { aqlQuery } from '#server/aql';
import * as db from '#server/db';
import { getCurrency } from '#shared/currencies';
import type { Currency } from '#shared/currencies';
import * as monthUtils from '#shared/months';
import { q } from '#shared/query';
import * as monthUtils from '../../shared/months';
import { amountToInteger, integerToAmount } from '../../shared/util';
import type { CategoryEntity } from '../../types/models';
import { amountToInteger, integerToAmount } from '#shared/util';
import type { CategoryEntity } from '#types/models';
import type {
AverageTemplate,
ByTemplate,
@@ -16,9 +18,7 @@ import type {
SimpleTemplate,
SpendTemplate,
Template,
} from '../../types/models/templates';
import { aqlQuery } from '../aql';
import * as db from '../db';
} from '#types/models/templates';
import { getSheetBoolean, getSheetValue, isReflectBudget } from './actions';
import { runSchedule } from './schedule-template';
@@ -1,6 +1,6 @@
import * as db from '#server/db';
// @ts-strict-ignore
import * as monthUtils from '../../shared/months';
import * as db from '../db';
import * as monthUtils from '#shared/months';
import { getSheetValue, setBudget, setGoal } from './actions';
import { parse } from './cleanup-template.pegjs';
@@ -1,9 +1,9 @@
import * as db from '#server/db';
import * as sheet from '#server/sheet';
import { resolveName } from '#server/spreadsheet/util';
// @ts-strict-ignore
import * as monthUtils from '../../shared/months';
import { safeNumber } from '../../shared/util';
import * as db from '../db';
import * as sheet from '../sheet';
import { resolveName } from '../spreadsheet/util';
import * as monthUtils from '#shared/months';
import { safeNumber } from '#shared/util';
import { createCategory as createCategoryFromBase } from './base';
import { flatten2, number, sumAmounts, unflatten2 } from './util';
@@ -1,11 +1,11 @@
import { aqlQuery } from '#server/aql';
import * as db from '#server/db';
import { batchMessages } from '#server/sync';
// @ts-strict-ignore
import * as monthUtils from '../../shared/months';
import { q } from '../../shared/query';
import type { CategoryEntity, CategoryGroupEntity } from '../../types/models';
import type { Template } from '../../types/models/templates';
import { aqlQuery } from '../aql';
import * as db from '../db';
import { batchMessages } from '../sync';
import * as monthUtils from '#shared/months';
import { q } from '#shared/query';
import type { CategoryEntity, CategoryGroupEntity } from '#types/models';
import type { Template } from '#types/models/templates';
import { getSheetValue, isReflectBudget, setBudget, setGoal } from './actions';
import { CategoryTemplateContext } from './category-template-context';
@@ -1,9 +1,9 @@
import * as db from '#server/db';
import * as sheet from '#server/sheet';
import { resolveName } from '#server/spreadsheet/util';
// @ts-strict-ignore
import * as monthUtils from '../../shared/months';
import { safeNumber } from '../../shared/util';
import * as db from '../db';
import * as sheet from '../sheet';
import { resolveName } from '../spreadsheet/util';
import * as monthUtils from '#shared/months';
import { safeNumber } from '#shared/util';
import { createCategory as createCategoryFromBase } from './base';
import { number, sumAmounts } from './util';
@@ -1,16 +1,16 @@
import * as db from '#server/db';
import { Rule } from '#server/rules';
import { getRuleForSchedule } from '#server/schedules/app';
import type { Currency } from '#shared/currencies';
import type { CategoryEntity } from '../../types/models';
import * as db from '../db';
import { Rule } from '../rules';
import { getRuleForSchedule } from '../schedules/app';
import type { CategoryEntity } from '#types/models';
import { isReflectBudget } from './actions';
import { runSchedule } from './schedule-template';
vi.mock('../db');
vi.mock('#server/db');
vi.mock('./actions');
vi.mock('../schedules/app', async () => {
const actualModule = await vi.importActual('../schedules/app');
vi.mock('#server/schedules/app', async () => {
const actualModule = await vi.importActual('#server/schedules/app');
return {
...actualModule,
getRuleForSchedule: vi.fn(),
@@ -1,17 +1,17 @@
// @ts-strict-ignore
import * as db from '#server/db';
import { getRuleForSchedule } from '#server/schedules/app';
import type { Currency } from '#shared/currencies';
import { amountToInteger } from '#shared/util';
import * as monthUtils from '../../shared/months';
import * as monthUtils from '#shared/months';
import {
extractScheduleConds,
getDateWithSkippedWeekend,
getNextDate,
} from '../../shared/schedules';
import type { CategoryEntity } from '../../types/models';
import type { ScheduleTemplate, Template } from '../../types/models/templates';
import * as db from '../db';
import { getRuleForSchedule } from '../schedules/app';
} from '#shared/schedules';
import { amountToInteger } from '#shared/util';
import type { CategoryEntity } from '#types/models';
import type { ScheduleTemplate, Template } from '#types/models/templates';
import { getSheetValue, isReflectBudget } from './actions';
@@ -1,5 +1,5 @@
import * as db from '../db';
import type { DbSchedule } from '../db';
import * as db from '#server/db';
import type { DbSchedule } from '#server/db';
import { GOAL_PREFIX, TEMPLATE_PREFIX } from './template-notes';
@@ -1,5 +1,5 @@
import type { Template } from '../../types/models/templates';
import * as db from '../db';
import * as db from '#server/db';
import type { Template } from '#types/models/templates';
import { parse } from './goal-template.pegjs';
import {
@@ -14,7 +14,7 @@ import {
unparse,
} from './template-notes';
vi.mock('../db');
vi.mock('#server/db');
vi.mock('./statements');
function mockGetTemplateNotesForCategories(
@@ -1,4 +1,4 @@
import type { Template } from '../../types/models/templates';
import type { Template } from '#types/models/templates';
import { storeTemplates } from './goal-template';
import { parse } from './goal-template.pegjs';
+3 -3
View File
@@ -1,8 +1,8 @@
import { number } from '#server/spreadsheet/globals';
// @ts-strict-ignore
import { safeNumber } from '../../shared/util';
import { number } from '../spreadsheet/globals';
import { safeNumber } from '#shared/util';
export { number } from '../spreadsheet/globals';
export { number } from '#server/spreadsheet/globals';
export function sumAmounts(...amounts) {
return safeNumber(
@@ -1,36 +1,40 @@
// @ts-strict-ignore
import * as CRDT from '@actual-app/crdt';
import { createTestBudget } from '#mocks/budget';
import { captureBreadcrumb, captureException } from '#platform/exceptions';
import * as asyncStorage from '#platform/server/asyncStorage';
import * as connection from '#platform/server/connection';
import * as fs from '#platform/server/fs';
import { logger } from '#platform/server/log';
import * as Platform from '#shared/platform';
import { createTestBudget } from '../../mocks/budget';
import { captureBreadcrumb, captureException } from '../../platform/exceptions';
import type { Budget } from '../../types/budget';
import { createApp } from '../app';
import * as budget from '../budget/base';
import * as cloudStorage from '../cloud-storage';
import * as db from '../db';
import * as mappings from '../db/mappings';
import { handleBudgetImport } from '../importers';
import type { ImportableBudgetType } from '../importers';
import { app as mainApp } from '../main-app';
import { mutator } from '../mutators';
import * as prefs from '../prefs';
import { getServer } from '../server-config';
import * as sheet from '../sheet';
import { clearFullSyncTimeout, initialFullSync, setSyncingMode } from '../sync';
import * as syncMigrations from '../sync/migrate';
import * as rules from '../transactions/transaction-rules';
import { clearUndo } from '../undo';
import { updateVersion } from '../update';
import { createApp } from '#server/app';
import * as budget from '#server/budget/base';
import * as cloudStorage from '#server/cloud-storage';
import * as db from '#server/db';
import * as mappings from '#server/db/mappings';
import { handleBudgetImport } from '#server/importers';
import type { ImportableBudgetType } from '#server/importers';
import { app as mainApp } from '#server/main-app';
import { mutator } from '#server/mutators';
import * as prefs from '#server/prefs';
import { getServer } from '#server/server-config';
import * as sheet from '#server/sheet';
import {
clearFullSyncTimeout,
initialFullSync,
setSyncingMode,
} from '#server/sync';
import * as syncMigrations from '#server/sync/migrate';
import * as rules from '#server/transactions/transaction-rules';
import { clearUndo } from '#server/undo';
import { updateVersion } from '#server/update';
import {
idFromBudgetName,
uniqueBudgetName,
validateBudgetName,
} from '../util/budget-name';
} from '#server/util/budget-name';
import * as Platform from '#shared/platform';
import type { Budget } from '#types/budget';
import {
loadBackup as _loadBackup,
@@ -7,9 +7,9 @@ import * as connection from '#platform/server/connection';
import * as fs from '#platform/server/fs';
import { logger } from '#platform/server/log';
import * as sqlite from '#platform/server/sqlite';
import * as monthUtils from '../../shared/months';
import * as cloudStorage from '../cloud-storage';
import * as prefs from '../prefs';
import * as cloudStorage from '#server/cloud-storage';
import * as prefs from '#server/prefs';
import * as monthUtils from '#shared/months';
// A special backup that represents the latest version of the db that
// can be reverted to after loading a backup
@@ -7,7 +7,7 @@ import { fetch } from '#platform/server/fetch';
import * as fs from '#platform/server/fs';
import { logger } from '#platform/server/log';
import * as sqlite from '#platform/server/sqlite';
import * as monthUtils from '../shared/months';
import * as monthUtils from '#shared/months';
import * as encryption from './encryption';
import {
+14 -14
View File
@@ -1,26 +1,26 @@
import isMatch from 'lodash/isMatch';
import { v4 as uuidv4 } from 'uuid';
import { captureException } from '#platform/exceptions';
import * as fs from '#platform/server/fs';
import { captureException } from '../../platform/exceptions';
import { DEFAULT_DASHBOARD_STATE } from '../../shared/dashboard';
import { q } from '../../shared/query';
import { createApp } from '#server/app';
import { aqlQuery } from '#server/aql';
import * as db from '#server/db';
import { ValidationError } from '#server/errors';
import { requiredFields } from '#server/models';
import { mutator } from '#server/mutators';
import { reportModel } from '#server/reports/app';
import { batchMessages } from '#server/sync';
import { undoable } from '#server/undo';
import { DEFAULT_DASHBOARD_STATE } from '#shared/dashboard';
import { q } from '#shared/query';
import type {
DashboardWidgetEntity,
ExportImportCustomReportWidget,
ExportImportDashboard,
ExportImportDashboardWidget,
} from '../../types/models';
import type { EverythingButIdOptional, WithOptional } from '../../types/util';
import { createApp } from '../app';
import { aqlQuery } from '../aql';
import * as db from '../db';
import { ValidationError } from '../errors';
import { requiredFields } from '../models';
import { mutator } from '../mutators';
import { reportModel } from '../reports/app';
import { batchMessages } from '../sync';
import { undoable } from '../undo';
} from '#types/models';
import type { EverythingButIdOptional, WithOptional } from '#types/util';
function isExportedCustomReportWidget(
widget: ExportImportDashboardWidget,
+8 -8
View File
@@ -13,25 +13,25 @@ import { v4 as uuidv4 } from 'uuid';
import * as fs from '#platform/server/fs';
import * as sqlite from '#platform/server/sqlite';
import * as monthUtils from '../../shared/months';
import { groupById } from '../../shared/util';
import type { TransactionEntity } from '../../types/models';
import type { WithRequired } from '../../types/util';
import {
convertForInsert,
convertForUpdate,
convertFromSelect,
schema,
schemaConfig,
} from '../aql';
} from '#server/aql';
import {
accountModel,
categoryGroupModel,
categoryModel,
payeeModel,
toDateRepr,
} from '../models';
import { batchMessages, sendMessages } from '../sync';
} from '#server/models';
import { batchMessages, sendMessages } from '#server/sync';
import * as monthUtils from '#shared/months';
import { groupById } from '#shared/util';
import type { TransactionEntity } from '#types/models';
import type { WithRequired } from '#types/util';
import {
shoveSortOrders,
@@ -56,7 +56,7 @@ import type {
export * from './types';
export { toDateRepr, fromDateRepr } from '../models';
export { toDateRepr, fromDateRepr } from '#server/models';
let dbPath: string | null = null;
let db: Database | null = null;
+1 -1
View File
@@ -1,5 +1,5 @@
// @ts-strict-ignore
import { addSyncListener } from '../sync/index';
import { addSyncListener } from '#server/sync';
import * as db from './index';
@@ -1,13 +1,13 @@
import { v4 as uuidv4 } from 'uuid';
import * as asyncStorage from '#platform/server/asyncStorage';
import { logger } from '../../platform/server/log';
import type { Budget } from '../../types/budget';
import { createApp } from '../app';
import { post } from '../post';
import * as prefs from '../prefs';
import { getServer } from '../server-config';
import { makeTestMessage, resetSync } from '../sync';
import { logger } from '#platform/server/log';
import { createApp } from '#server/app';
import { post } from '#server/post';
import * as prefs from '#server/prefs';
import { getServer } from '#server/server-config';
import { makeTestMessage, resetSync } from '#server/sync';
import type { Budget } from '#types/budget';
import * as encryption from '.';
+7 -7
View File
@@ -1,13 +1,13 @@
// @ts-strict-ignore
import { v4 as uuidv4 } from 'uuid';
import type { TransactionFilterEntity } from '../../types/models';
import { createApp } from '../app';
import * as db from '../db';
import { requiredFields } from '../models';
import { mutator } from '../mutators';
import { parseConditionsOrActions } from '../transactions/transaction-rules';
import { undoable } from '../undo';
import { createApp } from '#server/app';
import * as db from '#server/db';
import { requiredFields } from '#server/models';
import { mutator } from '#server/mutators';
import { parseConditionsOrActions } from '#server/transactions/transaction-rules';
import { undoable } from '#server/undo';
import type { TransactionFilterEntity } from '#types/models';
const filterModel = {
validate(filter, { update }: { update?: boolean } = {}) {
@@ -1,9 +1,9 @@
// @ts-strict-ignore
import * as fs from '#platform/server/fs';
import * as sqlite from '#platform/server/sqlite';
import * as cloudStorage from '../cloud-storage';
import { handlers } from '../main';
import { waitOnSpreadsheet } from '../sheet';
import * as cloudStorage from '#server/cloud-storage';
import { handlers } from '#server/main';
import { waitOnSpreadsheet } from '#server/sheet';
export async function importActual(_filepath: string, buffer: Buffer) {
// Importing Actual files is a special case because we can directly
@@ -1,6 +1,6 @@
// @ts-strict-ignore
import { logger } from '../../platform/server/log';
import { handlers } from '../main';
import { logger } from '#platform/server/log';
import { handlers } from '#server/main';
import { importActual } from './actual';
import * as YNAB4 from './ynab4';
@@ -2,10 +2,10 @@
import AdmZip from 'adm-zip';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '../../platform/server/log';
import * as monthUtils from '../../shared/months';
import { amountToInteger, groupBy, sortByKey } from '../../shared/util';
import { send } from '../main-app';
import { logger } from '#platform/server/log';
import { send } from '#server/main-app';
import * as monthUtils from '#shared/months';
import { amountToInteger, groupBy, sortByKey } from '#shared/util';
import type * as YNAB4 from './ynab4-types';
@@ -1,13 +1,13 @@
// @ts-strict-ignore
import { v4 as uuidv4 } from 'uuid';
import { logger } from '../../platform/server/log';
import * as monthUtils from '../../shared/months';
import { q } from '../../shared/query';
import { groupBy, sortByKey } from '../../shared/util';
import type { RecurConfig, RecurPattern, RuleEntity } from '../../types/models';
import { send } from '../main-app';
import { ruleModel } from '../transactions/transaction-rules';
import { logger } from '#platform/server/log';
import { send } from '#server/main-app';
import { ruleModel } from '#server/transactions/transaction-rules';
import * as monthUtils from '#shared/months';
import { q } from '#shared/query';
import { groupBy, sortByKey } from '#shared/util';
import type { RecurConfig, RecurPattern, RuleEntity } from '#types/models';
import type {
Budget,
+1 -1
View File
@@ -1,5 +1,5 @@
import * as connection from '#platform/server/connection';
import type { Handlers } from '../types/handlers';
import type { Handlers } from '#types/handlers';
import { createApp } from './app';
import { runHandler } from './mutators';
+2 -2
View File
@@ -2,10 +2,10 @@
import { deserializeClock, getClock } from '@actual-app/crdt';
import { v4 as uuidv4 } from 'uuid';
import { expectSnapshotWithDiffer } from '#mocks/util';
import * as connection from '#platform/server/connection';
import * as fs from '#platform/server/fs';
import { expectSnapshotWithDiffer } from '../mocks/util';
import * as monthUtils from '../shared/months';
import * as monthUtils from '#shared/months';
import * as budgetActions from './budget/actions';
import * as budget from './budget/base';
+3 -3
View File
@@ -5,9 +5,9 @@ import * as connection from '#platform/server/connection';
import * as fs from '#platform/server/fs';
import { logger, setVerboseMode } from '#platform/server/log';
import * as sqlite from '#platform/server/sqlite';
import { q } from '../shared/query';
import { amountToInteger, integerToAmount } from '../shared/util';
import type { Handlers } from '../types/handlers';
import { q } from '#shared/query';
import { amountToInteger, integerToAmount } from '#shared/util';
import type { Handlers } from '#types/handlers';
import { app as accountsApp } from './accounts/app';
import { app as adminApp } from './admin/app';
@@ -1,5 +1,5 @@
// @ts-strict-ignore
import * as db from '../db';
import * as db from '#server/db';
import {
getAppliedMigrations,
@@ -7,12 +7,12 @@ import type { Database } from '@jlongster/sql.js';
import * as fs from '#platform/server/fs';
import { logger } from '#platform/server/log';
import * as sqlite from '#platform/server/sqlite';
import * as prefs from '#server/prefs';
import m1632571489012 from '../../../migrations/1632571489012_remove_cache';
import m1722717601000 from '../../../migrations/1722717601000_reports_move_selected_categories';
import m1722804019000 from '../../../migrations/1722804019000_create_dashboard_table';
import m1723665565000 from '../../../migrations/1723665565000_prefs';
import m1765518577215 from '../../../migrations/1765518577215_multiple_dashboards';
import * as prefs from '../prefs';
let MIGRATIONS_DIR = fs.migrationsPath;
+1 -1
View File
@@ -2,7 +2,7 @@ import type {
CategoryEntity,
CategoryGroupEntity,
PayeeEntity,
} from '../types/models';
} from '#types/models';
import {
convertForInsert,
+3 -3
View File
@@ -1,7 +1,7 @@
// @ts-strict-ignore
import { captureBreadcrumb, captureException } from '../platform/exceptions';
import { sequential } from '../shared/async';
import type { HandlerFunctions, Handlers } from '../types/handlers';
import { captureBreadcrumb, captureException } from '#platform/exceptions';
import { sequential } from '#shared/async';
import type { HandlerFunctions, Handlers } from '#types/handlers';
const runningMethods = new Set();
+5 -5
View File
@@ -1,8 +1,8 @@
import type { NoteEntity } from '../../types/models';
import { createApp } from '../app';
import * as db from '../db';
import { mutator } from '../mutators';
import { undoable } from '../undo';
import { createApp } from '#server/app';
import * as db from '#server/db';
import { mutator } from '#server/mutators';
import { undoable } from '#server/undo';
import type { NoteEntity } from '#types/models';
export type NotesHandlers = {
'notes-save': typeof updateNotes;
+9 -9
View File
@@ -1,18 +1,18 @@
import { createApp } from '#server/app';
import * as db from '#server/db';
import { payeeModel } from '#server/models';
import { mutator } from '#server/mutators';
import { batchMessages } from '#server/sync';
import * as rules from '#server/transactions/transaction-rules';
import { undoable } from '#server/undo';
import { DEFAULT_MAX_DISTANCE_METERS } from '#shared/constants';
import type { Diff } from '../../shared/util';
import type { Diff } from '#shared/util';
import type {
NearbyPayeeEntity,
PayeeEntity,
PayeeLocationEntity,
RuleEntity,
} from '../../types/models';
import { createApp } from '../app';
import * as db from '../db';
import { payeeModel } from '../models';
import { mutator } from '../mutators';
import { batchMessages } from '../sync';
import * as rules from '../transactions/transaction-rules';
import { undoable } from '../undo';
} from '#types/models';
export type PayeesHandlers = {
'payee-create': typeof createPayee;
@@ -1,23 +1,19 @@
import * as asyncStorage from '#platform/server/asyncStorage';
import * as fs from '#platform/server/fs';
import { stringToInteger } from '../../shared/util';
import type {
GlobalPrefs,
MetadataPrefs,
SyncedPrefs,
} from '../../types/prefs';
import { createApp } from '../app';
import * as db from '../db';
import { PostError } from '../errors';
import { getDefaultDocumentDir } from '../main';
import { mutator } from '../mutators';
import { post } from '../post';
import { createApp } from '#server/app';
import * as db from '#server/db';
import { PostError } from '#server/errors';
import { getDefaultDocumentDir } from '#server/main';
import { mutator } from '#server/mutators';
import { post } from '#server/post';
import {
getPrefs as _getMetadataPrefs,
savePrefs as _saveMetadataPrefs,
} from '../prefs';
import { getServer } from '../server-config';
import { undoable } from '../undo';
} from '#server/prefs';
import { getServer } from '#server/server-config';
import { undoable } from '#server/undo';
import { stringToInteger } from '#shared/util';
import type { GlobalPrefs, MetadataPrefs, SyncedPrefs } from '#types/prefs';
export type PreferencesHandlers = {
'preferences/save': typeof saveSyncedPrefs;
+1 -1
View File
@@ -2,7 +2,7 @@
import { Timestamp } from '@actual-app/crdt';
import * as fs from '#platform/server/fs';
import type { MetadataPrefs } from '../types/prefs';
import type { MetadataPrefs } from '#types/prefs';
import { sendMessages } from './sync';
import type { Message } from './sync';
+8 -8
View File
@@ -1,14 +1,14 @@
import { v4 as uuidv4 } from 'uuid';
import { createApp } from '#server/app';
import { aqlQuery } from '#server/aql';
import * as db from '#server/db';
import { ValidationError } from '#server/errors';
import { requiredFields } from '#server/models';
import { mutator } from '#server/mutators';
import { undoable } from '#server/undo';
import { q } from '#shared/query';
import type { CustomReportData, CustomReportEntity } from '../../types/models';
import { createApp } from '../app';
import { aqlQuery } from '../aql';
import * as db from '../db';
import { ValidationError } from '../errors';
import { requiredFields } from '../models';
import { mutator } from '../mutators';
import { undoable } from '../undo';
import type { CustomReportData, CustomReportEntity } from '#types/models';
export const reportModel = {
validate(
@@ -4,11 +4,11 @@ import * as Handlebars from 'handlebars';
import { HyperFormula } from 'hyperformula';
import enUS from 'hyperformula/i18n/languages/enUS';
import { logger } from '#platform/server/log';
import type { TransactionForRules } from '#server/transactions/transaction-rules';
import { currentDay, format, parseDate } from '#shared/months';
import { FIELD_TYPES } from '#shared/rules';
import { amountToInteger } from '#shared/util';
import { logger } from '../../platform/server/log';
import { currentDay, format, parseDate } from '../../shared/months';
import { FIELD_TYPES } from '../../shared/rules';
import type { TransactionForRules } from '../transactions/transaction-rules';
import {
CustomFunctionsPlugin,
+8 -8
View File
@@ -1,16 +1,16 @@
// @ts-strict-ignore
import { logger } from '../../platform/server/log';
import { logger } from '#platform/server/log';
import { createApp } from '#server/app';
import { RuleError } from '#server/errors';
import { mutator } from '#server/mutators';
import { batchMessages } from '#server/sync';
import * as rules from '#server/transactions/transaction-rules';
import { undoable } from '#server/undo';
import type {
RuleActionEntity,
RuleEntity,
TransactionEntity,
} from '../../types/models';
import { createApp } from '../app';
import { RuleError } from '../errors';
import { mutator } from '../mutators';
import { batchMessages } from '../sync';
import * as rules from '../transactions/transaction-rules';
import { undoable } from '../undo';
} from '#types/models';
import { Action, Condition, rankRules } from '.';
@@ -1,7 +1,7 @@
// @ts-strict-ignore
import * as dateFns from 'date-fns';
import { logger } from '../../platform/server/log';
import { logger } from '#platform/server/log';
import {
addDays,
isAfter,
@@ -10,13 +10,13 @@ import {
parseDate,
subDays,
yearFromDate,
} from '../../shared/months';
} from '#shared/months';
import {
FIELD_TYPES,
getApproxNumberThreshold,
isValidOp,
sortNumbers,
} from '../../shared/rules';
} from '#shared/rules';
import {
assert,
@@ -2,7 +2,7 @@ import { FunctionArgumentType, FunctionPlugin } from 'hyperformula';
import type { InterpreterState } from 'hyperformula/typings/interpreter/InterpreterState';
import type { ProcedureAst } from 'hyperformula/typings/parser';
import { integerToAmount } from '../../shared/util';
import { integerToAmount } from '#shared/util';
export class CustomFunctionsPlugin extends FunctionPlugin {
integerToAmount(ast: ProcedureAst, state: InterpreterState) {
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
import type { TransactionForRules } from '../transactions/transaction-rules';
import type { TransactionForRules } from '#server/transactions/transaction-rules';
import { Action } from './action';
@@ -8,8 +8,8 @@ import {
} from 'date-fns';
import * as Handlebars from 'handlebars';
import { logger } from '../../platform/server/log';
import { addDays, format, parseDate, subDays } from '../../shared/months';
import { logger } from '#platform/server/log';
import { addDays, format, parseDate, subDays } from '#shared/months';
export function registerHandlebarsHelpers() {
const regexTest = /^\/(.*)\/([gimuy]*)$/;

Some files were not shown because too many files have changed in this diff Show More