Compare commits

...

36 Commits

Author SHA1 Message Date
Matiss Janis Aboltins
f70a216d06 Feedback: API changes for "internal" 2026-03-10 21:57:05 +00:00
Matiss Janis Aboltins
591da6b3c1 Refactor build script order in package.json for improved execution flow 2026-03-10 21:51:00 +00:00
Matiss Janis Aboltins
c307a07867 Fix lint 2026-03-10 21:47:19 +00:00
Matiss Janis Aboltins
271ef6fbb3 Merge branch 'master' into matiss/fix-6804 2026-03-10 21:45:58 +00:00
Matiss Janis Aboltins
7c3b5dabf3 Add promise-retry dependency to loot-core package and update yarn.lock 2026-03-05 22:08:03 +00:00
Matiss Janis Aboltins
47f3f41f7d Update API tests to mock file system paths for migration handling and change Vite configuration to target Node 20 for improved compatibility. 2026-03-05 22:07:03 +00:00
Matiss Janis Aboltins
2b3d8ef8c2 Refactor rootPath determination in Electron file system module by removing legacy case for 'bundle.api.js'. This simplifies the path management for the Electron app. 2026-03-05 21:55:49 +00:00
Matiss Janis Aboltins
e9d9226a81 Enhance migration handling by allowing both .sql and .js files to be copied during the migration process. Refactor file system operations in loot-core to improve error handling and streamline file management, including new methods for reading, writing, and removing files and directories. 2026-03-05 21:52:23 +00:00
Matiss Janis Aboltins
0d9d45e6fe Enhance inline-loot-core-types script to improve TypeScript declaration handling by separating source and typings directories. Update the copy process to include emitted typings, ensuring no declarations are dropped and maintaining better organization of loot-core types. 2026-03-05 21:13:12 +00:00
Matiss Janis Aboltins
6f91c4cede Update Vite configuration in API package to target Node 18, enhancing compatibility with the latest Node features. 2026-03-04 23:37:20 +00:00
Matiss Janis Aboltins
6a042b0c62 Add internal export to API and enhance Vite configuration for migration handling 2026-03-04 23:33:07 +00:00
Matiss Janis Aboltins
da1ab9e85d Refactor inline-loot-core-types script to streamline TypeScript declaration handling and improve output organization. Remove legacy code and directly copy loot-core declaration tree, updating index.d.ts to reference local imports. 2026-03-04 23:29:39 +00:00
Matiss Janis Aboltins
f1dc0b4a6e Update yarn.lock and API package to enhance TypeScript build process and add new dependencies 2026-03-04 22:22:06 +00:00
Matiss Janis Aboltins
a41d0b3323 Update TypeScript configuration in API package to use ES2022 module and bundler resolution. This change enhances compatibility with modern JavaScript features and improves the build process. 2026-03-04 21:13:40 +00:00
Matiss Janis Aboltins
6ce931ca20 Merge branch 'master' into matiss/fix-6804 2026-03-04 21:08:35 +00:00
Matiss Janis Aboltins
01c94453b7 Merge branch 'master' into matiss/fix-6804 2026-03-04 18:55:49 +00:00
Matiss Janis Aboltins
ac86c89851 Revert to solution without types 2026-02-22 21:34:08 +00:00
Matiss Janis Aboltins
1cb862c74f Refactor api package configuration to update type declaration paths and enhance build process. Changed type definitions reference in package.json, streamlined tsconfig.json exclusions, and added functionality to copy inlined types during the build. Removed obsolete vitest setup file for improved test isolation. 2026-02-22 21:14:36 +00:00
Matiss Janis Aboltins
b4cc0baef5 Update TypeScript configurations in desktop-client and desktop-electron packages to enable noEmit option, allowing for output file generation during compilation. Additionally, add ts-strict-ignore comments in YNAB importers to suppress strict type checking, improving compatibility with embedded API usage. 2026-02-22 15:49:55 +00:00
Matiss Janis Aboltins
34273d4faa Update api package configuration to streamline build process and enhance type safety. Removed unnecessary build scripts, integrated vite-plugin-dts for type declaration generation, and added migration and default database copying functionality. Adjusted vitest setup to comment out CRDT proto file import for improved test isolation. 2026-02-22 15:43:52 +00:00
Matiss Janis Aboltins
dd7521d416 Update TypeScript configuration in sync-server package to enable noEmit option. This change allows for the generation of output files during compilation, facilitating the build process. 2026-02-22 15:32:48 +00:00
Matiss Janis Aboltins
134d546716 Update TypeScript configurations across multiple packages to enable noEmit option. This change enhances build processes by preventing unnecessary output files during compilation. Additionally, remove the obsolete tsconfig.api.json file from loot-core to streamline project structure. 2026-02-22 15:29:17 +00:00
Matiss Janis Aboltins
f096cb01b8 Update TypeScript configuration in api package to reposition the typescript-strict-plugin entry. This change improves the organization of the tsconfig.json file while maintaining the existing path mapping for loot-core, ensuring consistent type checking across the project. 2026-02-22 15:17:44 +00:00
Matiss Janis Aboltins
6488ca1ca9 Update TypeScript configuration in api package to include path mapping for loot-core. This change enhances module resolution and improves type safety by allowing direct imports from the loot-core source directory. 2026-02-22 15:14:51 +00:00
Matiss Janis Aboltins
40a74197db Refactor schedule configuration in loot-core to enhance type safety by introducing a new ScheduleRuleOptions type. This change improves the clarity of the recurring schedule configuration and ensures better type checking for frequency and interval properties. 2026-02-22 15:10:16 +00:00
Matiss Janis Aboltins
ab972b7e36 Refactor handler invocation in YNAB importers to use the new send function from main-app. This change improves code consistency and readability by standardizing the method of invoking handlers across different modules. 2026-02-22 15:06:38 +00:00
Matiss Janis Aboltins
73739eb91a Refactor imports and enhance code readability across multiple files in loot-core. Simplified import statements in the API and adjusted formatting in YNAB importers for consistency. Updated type annotations to improve type safety and maintainability. 2026-02-22 14:54:33 +00:00
Matiss Janis Aboltins
cd7663ecfd Refactor API integration in loot-core by removing api-helpers and directly invoking handlers. Update typecheck script in api package to include strict checks, and refine TypeScript configurations across multiple packages for improved type safety and build processes. 2026-02-21 22:22:40 +00:00
Matiss Janis Aboltins
0619198f50 Refactor typecheck script in api package and enhance api-helpers with new schedule and rule update functions. The typecheck command was simplified by removing the strict check, and new API methods for creating schedules and updating rules were added to improve functionality. 2026-02-21 22:12:26 +00:00
Matiss Janis Aboltins
7098a5fad7 Merge remote-tracking branch 'origin' into matiss/fix-6804 2026-02-21 22:02:01 +00:00
Matiss Janis Aboltins
4ff3b35168 feat(api): enhance build scripts and add file system utilities
- Update build scripts in package.json to include separate commands for building node, migrations, and default database.
- Introduce a new file system utility module in loot-core to handle file operations such as reading, writing, and directory management.
- Implement error handling and logging for file operations to improve robustness.
2026-02-03 09:42:19 +00:00
Matiss Janis Aboltins
6f9dab9aab refactor(api): streamline Vite configuration and remove vitest.config.ts
- Remove vitest.config.ts as its configuration is now integrated into vite.config.ts.
- Update vite.config.ts to include sourcemap generation and adjust CRDT path resolution.
- Modify vitest.setup.ts to correct the import path for the CRDT proto file.
2026-01-28 23:06:30 +00:00
Matiss Janis Aboltins
6d1cc5cd23 fix(api): update visualizer output path in vite configuration
- Change the output filename for the visualizer plugin from 'dist/stats.json' to 'app/stats.json' to align with the new directory structure.
2026-01-28 23:03:03 +00:00
Matiss Janis Aboltins
549f269511 chore(api): update dependencies and build configuration
- Replace tsc-alias with rollup-plugin-visualizer in package.json.
- Update build script to use vite for building the API package.
- Add vite configuration file for improved build process and visualization.
- Adjust tsconfig.dist.json to exclude additional configuration files from the build.
2026-01-28 23:01:46 +00:00
Matiss Janis Aboltins
68c0b35d05 refactor(api): update package structure and build scripts
- Change main entry point and types definition paths in package.json to reflect new structure.
- Simplify build script by removing migration and default database copy commands.
- Adjust tsconfig.dist.json to maintain declaration directory.
- Add typings for external modules in a new typings.ts file.
- Update comments in schedules.ts to improve clarity and maintainability.
2026-01-28 22:41:15 +00:00
Matiss Janis Aboltins
ae763af100 refactor(api): defineConfig vitest, api-helpers, drop vite.api build
- Wrap api vitest.config with defineConfig for typing/IDE
- Add loot-core api-helpers, use in YNAB4/YNAB5 importers
- Remove vite.api.config, build-api, injected.js; simplify api package
2026-01-28 22:06:18 +00:00
21 changed files with 842 additions and 238 deletions

View File

@@ -54,10 +54,10 @@
"vrt:docker": "./bin/run-vrt",
"rebuild-electron": "./node_modules/.bin/electron-rebuild -m ./packages/loot-core",
"rebuild-node": "yarn workspace loot-core rebuild",
"lint": "yarn workspace @actual-app/api clean && oxfmt --check . && oxlint --type-aware",
"lint:fix": "yarn workspace @actual-app/api clean && oxfmt . && oxlint --fix --type-aware",
"lint": "oxfmt --check . && oxlint --type-aware",
"lint:fix": "oxfmt . && oxlint --fix --type-aware",
"install:server": "yarn workspaces focus @actual-app/sync-server --production",
"typecheck": "yarn workspace @actual-app/api clean && tsc -b && tsc -p tsconfig.root.json --noEmit && lage typecheck",
"typecheck": "tsc -b && tsc -p tsconfig.root.json --noEmit && lage typecheck",
"jq": "./node_modules/node-jq/bin/jq",
"prepare": "husky"
},

View File

@@ -3,26 +3,18 @@ import type {
RequestInit as FetchInit,
} from 'node-fetch';
// loot-core types
import type { InitConfig } from 'loot-core/server/main';
import { init as initLootCore } from 'loot-core/server/main';
import type { InitConfig, lib } from 'loot-core/server/main';
// oxlint-disable-next-line typescript/ban-ts-comment
// @ts-ignore: bundle not available until we build it
import * as bundle from './app/bundle.api.js';
import * as injected from './injected';
import { validateNodeVersion } from './validateNodeVersion';
let actualApp: null | typeof bundle.lib;
export const internal = bundle.lib;
export * from './methods';
export * as utils from './utils';
export async function init(config: InitConfig = {}) {
if (actualApp) {
return;
}
/** @deprecated Please use return value of `init` instead */
export let internal: typeof lib | null = null;
export async function init(config: InitConfig = {}) {
validateNodeVersion();
if (!globalThis.fetch) {
@@ -33,21 +25,19 @@ export async function init(config: InitConfig = {}) {
};
}
await bundle.init(config);
actualApp = bundle.lib;
injected.override(bundle.lib.send);
return bundle.lib;
internal = await initLootCore(config);
return internal;
}
export async function shutdown() {
if (actualApp) {
if (internal) {
try {
await actualApp.send('sync');
await internal.send('sync');
} catch {
// most likely that no budget is loaded, so the sync failed
}
await actualApp.send('close-budget');
actualApp = null;
await internal.send('close-budget');
internal = null;
}
}

View File

@@ -1,7 +0,0 @@
// TODO: comment on why it works this way
export let send;
export function override(sendImplementation) {
send = sendImplementation;
}

View File

@@ -1,10 +1,29 @@
import * as fs from 'fs/promises';
import * as path from 'path';
import { vi } from 'vitest';
import type { RuleEntity } from 'loot-core/types/models';
import * as api from './index';
// In tests we run from source; loot-core's API fs uses __dirname (for the built dist/).
// Mock the fs so path constants point at loot-core package root where migrations live.
vi.mock(
'../loot-core/src/platform/server/fs/index.api',
async importOriginal => {
const actual = (await importOriginal()) as Record<string, unknown>;
const pathMod = await import('path');
const lootCoreRoot = pathMod.join(__dirname, '..', 'loot-core');
return {
...actual,
migrationsPath: pathMod.join(lootCoreRoot, 'migrations'),
bundledDatabasePath: pathMod.join(lootCoreRoot, 'default-db.sqlite'),
demoBudgetPath: pathMod.join(lootCoreRoot, 'demo-budget'),
};
},
);
const budgetName = 'test-budget';
global.IS_TESTING = true;

View File

@@ -7,6 +7,7 @@ import type {
APIScheduleEntity,
APITagEntity,
} from 'loot-core/server/api-models';
import { lib } from 'loot-core/server/main';
import type { Query } from 'loot-core/shared/query';
import type { ImportTransactionsOpts } from 'loot-core/types/api-handlers';
import type { Handlers } from 'loot-core/types/handlers';
@@ -16,15 +17,13 @@ import type {
TransactionEntity,
} from 'loot-core/types/models';
import * as injected from './injected';
export { q } from './app/query';
function send<K extends keyof Handlers, T extends Handlers[K]>(
name: K,
args?: Parameters<T>[0],
): Promise<Awaited<ReturnType<T>>> {
return injected.send(name, args);
return lib.send(name, args);
}
export async function runImport(

View File

@@ -10,27 +10,25 @@
"main": "dist/index.js",
"types": "@types/index.d.ts",
"scripts": {
"build:app": "yarn workspace loot-core build:api",
"build:crdt": "yarn workspace @actual-app/crdt build",
"build:node": "tsc && tsc-alias",
"build:migrations": "cp migrations/*.sql dist/migrations",
"build:default-db": "cp default-db.sqlite dist/",
"build": "yarn run clean && yarn run build:app && yarn run build:node && yarn run build:migrations && yarn run build:default-db",
"test": "yarn run clean && yarn run build:app && yarn run build:crdt && vitest --run",
"clean": "rm -rf dist @types",
"typecheck": "yarn build && tsc --noEmit && tsc-strict"
"build": "yarn workspace loot-core exec tsc && vite build && node scripts/inline-loot-core-types.mjs",
"test": "vitest --run",
"typecheck": "tsc --noEmit && tsc-strict"
},
"dependencies": {
"@actual-app/crdt": "workspace:^",
"better-sqlite3": "^12.6.2",
"compare-versions": "^6.1.1",
"loot-core": "workspace:^",
"node-fetch": "^3.3.2",
"uuid": "^13.0.0"
},
"devDependencies": {
"tsc-alias": "^1.8.16",
"rollup-plugin-visualizer": "^6.0.5",
"typescript": "^5.9.3",
"typescript-strict-plugin": "^2.4.4",
"vite": "^7.3.1",
"vite-plugin-dts": "^4.5.4",
"vite-plugin-peggy-loader": "^2.0.1",
"vitest": "^4.0.18"
},
"engines": {

View File

@@ -0,0 +1,60 @@
/**
* Post-build script: copies loot-core declaration tree into @types/loot-core
* and rewrites index.d.ts to reference it so the published package is self-contained.
* Run after vite build; requires loot-core declarations (yarn workspace loot-core exec tsc).
*/
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const apiRoot = path.resolve(__dirname, '..');
const typesDir = path.join(apiRoot, '@types');
const indexDts = path.join(typesDir, 'index.d.ts');
const lootCoreDeclRoot = path.resolve(apiRoot, '../loot-core/lib-dist/decl');
const lootCoreDeclSrc = path.join(lootCoreDeclRoot, 'src');
const lootCoreDeclTypings = path.join(lootCoreDeclRoot, 'typings');
const lootCoreTypesDir = path.join(typesDir, 'loot-core');
function main() {
if (!fs.existsSync(indexDts)) {
console.error('Missing @types/index.d.ts; run vite build first.');
process.exit(1);
}
if (!fs.existsSync(lootCoreDeclSrc)) {
console.error(
'Missing loot-core declarations; run: yarn workspace loot-core exec tsc',
);
process.exit(1);
}
// Remove existing loot-core output (dir or legacy single file)
if (fs.existsSync(lootCoreTypesDir)) {
fs.rmSync(lootCoreTypesDir, { recursive: true });
}
const legacyDts = path.join(typesDir, 'loot-core.d.ts');
if (fs.existsSync(legacyDts)) {
fs.rmSync(legacyDts);
}
// Copy declaration tree: src (main exports) plus emitted typings so no declarations are dropped
fs.cpSync(lootCoreDeclSrc, lootCoreTypesDir, { recursive: true });
if (fs.existsSync(lootCoreDeclTypings)) {
fs.cpSync(lootCoreDeclTypings, path.join(lootCoreTypesDir, 'typings'), {
recursive: true,
});
}
// Rewrite index.d.ts: remove reference, point imports at local ./loot-core/
let indexContent = fs.readFileSync(indexDts, 'utf8');
indexContent = indexContent.replace(
/\/\/\/ <reference path="\.\/loot-core\.d\.ts" \/>\n?/,
'',
);
indexContent = indexContent
.replace(/'loot-core\//g, "'./loot-core/")
.replace(/"loot-core\//g, '"./loot-core/');
fs.writeFileSync(indexDts, indexContent, 'utf8');
}
main();

View File

@@ -5,8 +5,8 @@
// Using ES2021 because that's the newest version where
// the latest Node 16.x release supports all of the features
"target": "ES2021",
"module": "CommonJS",
"moduleResolution": "node10",
"module": "es2022",
"moduleResolution": "bundler",
"noEmit": false,
"declaration": true,
"declarationMap": true,
@@ -14,13 +14,9 @@
"rootDir": ".",
"declarationDir": "@types",
"tsBuildInfoFile": "dist/.tsbuildinfo",
"paths": {
// TEMPORARY
"loot-core/*": ["../loot-core/src/*"]
},
"plugins": [{ "name": "typescript-strict-plugin", "paths": ["."] }]
},
"references": [{ "path": "../crdt" }, { "path": "../loot-core" }],
"include": ["."],
"exclude": ["**/node_modules/*", "dist", "@types", "*.test.ts"]
"exclude": ["**/node_modules/*", "dist", "@types", "*.test.ts", "*.config.ts"]
}

2
packages/api/typings.ts Normal file
View File

@@ -0,0 +1,2 @@
declare module 'hyperformula/i18n/languages/enUS';
declare module '*.pegjs';

View File

@@ -1,6 +1,4 @@
// oxlint-disable-next-line typescript/ban-ts-comment
// @ts-ignore: bundle not available until we build it
import * as bundle from './app/bundle.api.js';
import { lib } from 'loot-core/server/main';
export const amountToInteger = bundle.lib.amountToInteger;
export const integerToAmount = bundle.lib.integerToAmount;
export const amountToInteger = lib.amountToInteger;
export const integerToAmount = lib.integerToAmount;

View File

@@ -0,0 +1,99 @@
import fs from 'fs';
import path from 'path';
import { visualizer } from 'rollup-plugin-visualizer';
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
import peggyLoader from 'vite-plugin-peggy-loader';
const lootCoreRoot = path.resolve(__dirname, '../loot-core');
const distDir = path.resolve(__dirname, 'dist');
const typesDir = path.resolve(__dirname, '@types');
function cleanOutputDirs() {
return {
name: 'clean-output-dirs',
buildStart() {
if (fs.existsSync(distDir)) fs.rmSync(distDir, { recursive: true });
if (fs.existsSync(typesDir)) fs.rmSync(typesDir, { recursive: true });
},
};
}
function copyMigrationsAndDefaultDb() {
return {
name: 'copy-migrations-and-default-db',
closeBundle() {
const migrationsSrc = path.join(lootCoreRoot, 'migrations');
const defaultDbPath = path.join(lootCoreRoot, 'default-db.sqlite');
if (!fs.existsSync(migrationsSrc)) {
throw new Error(`migrations directory not found at ${migrationsSrc}`);
}
const migrationsStat = fs.statSync(migrationsSrc);
if (!migrationsStat.isDirectory()) {
throw new Error(`migrations path is not a directory: ${migrationsSrc}`);
}
const migrationsDest = path.join(distDir, 'migrations');
fs.mkdirSync(migrationsDest, { recursive: true });
for (const name of fs.readdirSync(migrationsSrc)) {
if (name.endsWith('.sql') || name.endsWith('.js')) {
fs.copyFileSync(
path.join(migrationsSrc, name),
path.join(migrationsDest, name),
);
}
}
if (!fs.existsSync(defaultDbPath)) {
throw new Error(`default-db.sqlite not found at ${defaultDbPath}`);
}
fs.copyFileSync(defaultDbPath, path.join(distDir, 'default-db.sqlite'));
},
};
}
export default defineConfig({
ssr: { noExternal: true, external: ['better-sqlite3'] },
build: {
ssr: true,
target: 'node20',
outDir: distDir,
emptyOutDir: true,
sourcemap: true,
lib: {
entry: path.resolve(__dirname, 'index.ts'),
formats: ['cjs'],
fileName: () => 'index.js',
},
},
plugins: [
cleanOutputDirs(),
peggyLoader(),
dts({
tsconfigPath: path.resolve(__dirname, 'tsconfig.json'),
outDir: path.resolve(__dirname, '@types'),
rollupTypes: true,
}),
copyMigrationsAndDefaultDb(),
visualizer({ template: 'raw-data', filename: 'app/stats.json' }),
],
resolve: {
extensions: ['.api.ts', '.js', '.ts', '.tsx', '.json'],
alias: [
{
find: /^@actual-app\/crdt(\/.*)?$/,
replacement: path.resolve(__dirname, '../crdt/src') + '$1',
},
],
},
test: {
globals: true,
onConsoleLog(log: string, type: 'stdout' | 'stderr'): boolean | void {
// print only console.error
return type === 'stderr';
},
maxWorkers: 2,
},
});

View File

@@ -1,10 +0,0 @@
export default {
test: {
globals: true,
onConsoleLog(log: string, type: 'stdout' | 'stderr'): boolean | void {
// print only console.error
return type === 'stderr';
},
maxWorkers: 2,
},
};

View File

@@ -1,11 +0,0 @@
#!/bin/bash
set -euo pipefail
cd "$(dirname "$0")/.." || exit 1
ROOT="$(pwd -P)"
# Emit declarations to lib-dist/decl so api package (and tsc -b) can consume them
yarn tsc -p tsconfig.json
yarn vite build --config ./vite.api.config.ts
./bin/copy-migrations ../api

View File

@@ -55,7 +55,6 @@
"scripts": {
"build:node": "cross-env NODE_ENV=production vite build --config ./vite.desktop.config.ts",
"watch:node": "cross-env NODE_ENV=development vite build --config ./vite.desktop.config.ts --watch",
"build:api": "cross-env NODE_ENV=development ./bin/build-api",
"build:browser": "cross-env NODE_ENV=production ./bin/build-browser",
"watch:browser": "cross-env NODE_ENV=development ./bin/build-browser",
"generate:i18n": "i18next",
@@ -82,6 +81,7 @@
"md5": "^2.3.0",
"memoize-one": "^6.0.0",
"mitt": "^3.0.1",
"promise-retry": "^2.0.1",
"slash": "5.1.0",
"typescript": "^5.9.3",
"typescript-strict-plugin": "^2.4.4",
@@ -89,7 +89,6 @@
"uuid": "^13.0.0"
},
"devDependencies": {
"@actual-app/api": "workspace:^",
"@actual-app/crdt": "workspace:^",
"@swc/core": "^1.15.11",
"@types/adm-zip": "^0.5.7",

View File

@@ -1,2 +1,198 @@
// oxlint-disable-next-line no-restricted-imports
export * from './index.electron';
// @ts-strict-ignore
import * as fs from 'fs';
import * as path from 'path';
import promiseRetry from 'promise-retry';
import { logger } from '../log';
import type * as T from './index';
export { getDocumentDir, getBudgetDir, _setDocumentDir } from './shared';
export const init: typeof T.init = async () => {
// Nothing to do
};
export const getDataDir: typeof T.getDataDir = () => {
if (!process.env.ACTUAL_DATA_DIR) {
throw new Error('ACTUAL_DATA_DIR env variable is required');
}
return process.env.ACTUAL_DATA_DIR;
};
export const bundledDatabasePath: typeof T.bundledDatabasePath = path.join(
__dirname,
'default-db.sqlite',
);
export const migrationsPath: typeof T.migrationsPath = path.join(
__dirname,
'migrations',
);
export const demoBudgetPath: typeof T.demoBudgetPath = path.join(
__dirname,
'demo-budget',
);
export const join: typeof T.join = (...args: Parameters<typeof path.join>) =>
path.join(...args);
export const basename: typeof T.basename = filepath => path.basename(filepath);
export const listDir: typeof T.listDir = filepath =>
new Promise((resolve, reject) => {
fs.readdir(filepath, (err, files) => {
if (err) {
reject(err);
} else {
resolve(files);
}
});
});
export const exists: typeof T.exists = filepath =>
new Promise(resolve => {
fs.access(filepath, fs.constants.F_OK, err => {
return resolve(!err);
});
});
export const mkdir: typeof T.mkdir = filepath =>
new Promise((resolve, reject) => {
fs.mkdir(filepath, err => {
if (err) {
reject(err);
} else {
resolve(undefined);
}
});
});
export const size: typeof T.size = filepath =>
new Promise((resolve, reject) => {
fs.stat(filepath, (err, stats) => {
if (err) {
reject(err);
} else {
resolve(stats.size);
}
});
});
export const copyFile: typeof T.copyFile = (frompath, topath) => {
return new Promise<boolean>((resolve, reject) => {
const readStream = fs.createReadStream(frompath);
const writeStream = fs.createWriteStream(topath);
readStream.on('error', reject);
writeStream.on('error', reject);
writeStream.on('open', () => readStream.pipe(writeStream));
writeStream.once('close', () => resolve(true));
});
};
export const readFile: typeof T.readFile = (
filepath: string,
encoding: 'utf8' | 'binary' | null = 'utf8',
) => {
if (encoding === 'binary') {
// `binary` is not actually a valid encoding, you pass `null` into node if
// you want a buffer
encoding = null;
}
// `any` as cannot refine return with two function overrides
// oxlint-disable-next-line typescript/no-explicit-any
return new Promise<any>((resolve, reject) => {
fs.readFile(filepath, encoding, (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
};
export const writeFile: typeof T.writeFile = async (filepath, contents) => {
try {
await promiseRetry(
(retry, attempt) => {
return new Promise((resolve, reject) => {
fs.writeFile(filepath, contents, 'utf8', err => {
if (err) {
logger.error(
`Failed to write to ${filepath}. Attempted ${attempt} times. Something is locking the file - potentially a virus scanner or backup software.`,
);
reject(err);
} else {
if (attempt > 1) {
logger.info(
`Successfully recovered from file lock. It took ${attempt} retries`,
);
}
resolve(undefined);
}
});
}).catch(retry);
},
{
retries: 20,
minTimeout: 100,
maxTimeout: 500,
factor: 1.5,
},
);
return undefined;
} catch (err) {
logger.error(`Unable to recover from file lock on file ${filepath}`);
throw err;
}
};
export const removeFile: typeof T.removeFile = filepath => {
return new Promise(function (resolve, reject) {
fs.unlink(filepath, err => {
return err ? reject(err) : resolve(undefined);
});
});
};
export const removeDir: typeof T.removeDir = dirpath => {
return new Promise(function (resolve, reject) {
fs.rmdir(dirpath, err => {
return err ? reject(err) : resolve(undefined);
});
});
};
export const removeDirRecursively: typeof T.removeDirRecursively =
async dirpath => {
if (await exists(dirpath)) {
for (const file of await listDir(dirpath)) {
const fullpath = join(dirpath, file);
if (fs.statSync(fullpath).isDirectory()) {
await removeDirRecursively(fullpath);
} else {
await removeFile(fullpath);
}
}
await removeDir(dirpath);
}
};
export const getModifiedTime: typeof T.getModifiedTime = filepath => {
return new Promise(function (resolve, reject) {
fs.stat(filepath, (err, stats) => {
if (err) {
reject(err);
} else {
resolve(new Date(stats.mtime));
}
});
});
};

View File

@@ -13,9 +13,6 @@ export { getDocumentDir, getBudgetDir, _setDocumentDir } from './shared';
let rootPath = path.join(__dirname, '..', '..', '..', '..');
switch (path.basename(__filename)) {
case 'bundle.api.js': // api bundle uses the electron bundle - account for its file structure
rootPath = path.join(__dirname, '..');
break;
case 'bundle.desktop.js': // electron app
rootPath = path.join(__dirname, '..', '..');
break;

View File

@@ -1,7 +1,5 @@
// @ts-strict-ignore
import './polyfills';
import * as injectAPI from '@actual-app/api/injected';
import * as asyncStorage from '../platform/server/asyncStorage';
import * as connection from '../platform/server/connection';
import * as fs from '../platform/server/fs';
@@ -126,8 +124,6 @@ handlers['app-focused'] = async function () {
handlers = installAPI(handlers) as Handlers;
injectAPI.override((name, args) => runHandler(app.handlers[name], args));
// A hack for now until we clean up everything
app.handlers = handlers;
app.combine(

View File

@@ -147,15 +147,29 @@ function checkDatabaseValidity(
appliedIds: number[],
available: string[],
): void {
for (let i = 0; i < appliedIds.length; i++) {
if (
i >= available.length ||
appliedIds[i] !== getMigrationId(available[i])
) {
logger.error('Database is out of sync with migrations:', {
if (appliedIds.length > available.length) {
logger.error(
'Database is out of sync with migrations (index past available):',
{
appliedIds,
available,
});
},
);
throw new Error('out-of-sync-migrations');
}
for (let i = 0; i < appliedIds.length; i++) {
if (appliedIds[i] !== getMigrationId(available[i])) {
logger.error(
'Database is out of sync with migrations (migration id mismatch):',
{
appliedIds,
available,
missing: available.filter(
m => !appliedIds.includes(getMigrationId(m)),
),
},
);
throw new Error('out-of-sync-migrations');
}
}

View File

@@ -1,58 +0,0 @@
import path from 'path';
import { visualizer } from 'rollup-plugin-visualizer';
import { defineConfig } from 'vite';
import peggyLoader from 'vite-plugin-peggy-loader';
export default defineConfig(({ mode }) => {
const outDir = path.resolve(__dirname, '../api/app');
const crdtDir = path.resolve(__dirname, '../crdt');
return {
mode,
ssr: { noExternal: true, external: ['better-sqlite3'] },
build: {
target: 'node18',
outDir,
emptyOutDir: false,
ssr: true,
lib: {
entry: path.resolve(__dirname, 'src/server/main.ts'),
formats: ['cjs'],
},
sourcemap: true,
rollupOptions: {
output: {
entryFileNames: 'bundle.api.js',
format: 'cjs',
name: 'api',
},
},
},
resolve: {
extensions: [
'.api.js',
'.api.ts',
'.api.tsx',
'.js',
'.ts',
'.tsx',
'.json',
],
alias: [
{
find: 'handlebars',
replacement: require.resolve('handlebars/dist/handlebars.js'),
},
{
find: /^@actual-app\/crdt(\/.*)?$/,
replacement: path.resolve(crdtDir, 'src') + '$1',
},
],
},
plugins: [
peggyLoader(),
visualizer({ template: 'raw-data', filename: `${outDir}/stats.json` }),
],
};
});

View File

@@ -0,0 +1,6 @@
---
category: Maintenance
authors: [MatissJanis]
---
Remove cyclic dependency between API and loot-core

489
yarn.lock
View File

@@ -19,18 +19,22 @@ __metadata:
languageName: node
linkType: hard
"@actual-app/api@workspace:^, @actual-app/api@workspace:packages/api":
"@actual-app/api@workspace:packages/api":
version: 0.0.0-use.local
resolution: "@actual-app/api@workspace:packages/api"
dependencies:
"@actual-app/crdt": "workspace:^"
better-sqlite3: "npm:^12.6.2"
compare-versions: "npm:^6.1.1"
loot-core: "workspace:^"
node-fetch: "npm:^3.3.2"
tsc-alias: "npm:^1.8.16"
rollup-plugin-visualizer: "npm:^6.0.5"
typescript: "npm:^5.9.3"
typescript-strict-plugin: "npm:^2.4.4"
uuid: "npm:^13.0.0"
vite: "npm:^7.3.1"
vite-plugin-dts: "npm:^4.5.4"
vite-plugin-peggy-loader: "npm:^2.0.1"
vitest: "npm:^4.0.18"
languageName: unknown
linkType: soft
@@ -4879,6 +4883,60 @@ __metadata:
languageName: node
linkType: hard
"@microsoft/api-extractor-model@npm:7.33.1":
version: 7.33.1
resolution: "@microsoft/api-extractor-model@npm:7.33.1"
dependencies:
"@microsoft/tsdoc": "npm:~0.16.0"
"@microsoft/tsdoc-config": "npm:~0.18.0"
"@rushstack/node-core-library": "npm:5.20.1"
checksum: 10/cb267ca0020a68b84570bc99e974d050acf8b17a47f1999998a9dbc2ef81453f8188a93970a6b2274890a5dd5015502b6cebe94da06d3583e65ca490dabf4c1e
languageName: node
linkType: hard
"@microsoft/api-extractor@npm:^7.50.1":
version: 7.57.2
resolution: "@microsoft/api-extractor@npm:7.57.2"
dependencies:
"@microsoft/api-extractor-model": "npm:7.33.1"
"@microsoft/tsdoc": "npm:~0.16.0"
"@microsoft/tsdoc-config": "npm:~0.18.0"
"@rushstack/node-core-library": "npm:5.20.1"
"@rushstack/rig-package": "npm:0.7.1"
"@rushstack/terminal": "npm:0.22.1"
"@rushstack/ts-command-line": "npm:5.3.1"
diff: "npm:~8.0.2"
lodash: "npm:~4.17.23"
minimatch: "npm:10.2.1"
resolve: "npm:~1.22.1"
semver: "npm:~7.5.4"
source-map: "npm:~0.6.1"
typescript: "npm:5.8.2"
bin:
api-extractor: bin/api-extractor
checksum: 10/7e6ff99a7ee07e34ae4e3d4e271ea794f20ba3b892932e94f3757f230b8f3d6a3f4c18c723c71d3bffdc7a5dd51c732201fc911089cdebae7a4a194d3e4de2e7
languageName: node
linkType: hard
"@microsoft/tsdoc-config@npm:~0.18.0":
version: 0.18.0
resolution: "@microsoft/tsdoc-config@npm:0.18.0"
dependencies:
"@microsoft/tsdoc": "npm:0.16.0"
ajv: "npm:~8.12.0"
jju: "npm:~1.4.0"
resolve: "npm:~1.22.2"
checksum: 10/0470df5326181d876faba51617d011a632b2e3b420953e521bb865715d0db2fb0b8bfb3ccbcaef267356a1a7150d2ffba40022db5930db6b15fcb348bf846a4b
languageName: node
linkType: hard
"@microsoft/tsdoc@npm:0.16.0, @microsoft/tsdoc@npm:~0.16.0":
version: 0.16.0
resolution: "@microsoft/tsdoc@npm:0.16.0"
checksum: 10/1eaad3605234dc7e44898c15d1ba3c97fb968af1117025400cba572ce268da05afc36634d1fb9e779457af3ff7f13330aee07a962510a4d9c6612c13f71ee41e
languageName: node
linkType: hard
"@napi-rs/wasm-runtime@npm:^0.2.3":
version: 0.2.12
resolution: "@napi-rs/wasm-runtime@npm:0.2.12"
@@ -8016,7 +8074,7 @@ __metadata:
languageName: node
linkType: hard
"@rollup/pluginutils@npm:^5.0.1, @rollup/pluginutils@npm:^5.0.2":
"@rollup/pluginutils@npm:^5.0.1, @rollup/pluginutils@npm:^5.0.2, @rollup/pluginutils@npm:^5.1.4":
version: 5.3.0
resolution: "@rollup/pluginutils@npm:5.3.0"
dependencies:
@@ -8197,6 +8255,77 @@ __metadata:
languageName: node
linkType: hard
"@rushstack/node-core-library@npm:5.20.1":
version: 5.20.1
resolution: "@rushstack/node-core-library@npm:5.20.1"
dependencies:
ajv: "npm:~8.13.0"
ajv-draft-04: "npm:~1.0.0"
ajv-formats: "npm:~3.0.1"
fs-extra: "npm:~11.3.0"
import-lazy: "npm:~4.0.0"
jju: "npm:~1.4.0"
resolve: "npm:~1.22.1"
semver: "npm:~7.5.4"
peerDependencies:
"@types/node": "*"
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10/bd05a400fd96818a6382df7bc6a284adc78bbc8ae81c40760f2fee56a4124f0e56a38e007745bcf39c7449913e97f182860c1a344b56a31b8ba8445c21c6c012
languageName: node
linkType: hard
"@rushstack/problem-matcher@npm:0.2.1":
version: 0.2.1
resolution: "@rushstack/problem-matcher@npm:0.2.1"
peerDependencies:
"@types/node": "*"
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10/62fda91629577a2f57de19be357cd0990da145ff4933f4d2cd48f423cc03b92fca06dd8916dcbaf1d307a201c104847c77066d45d79fd3c323c4949f0c99bf44
languageName: node
linkType: hard
"@rushstack/rig-package@npm:0.7.1":
version: 0.7.1
resolution: "@rushstack/rig-package@npm:0.7.1"
dependencies:
resolve: "npm:~1.22.1"
strip-json-comments: "npm:~3.1.1"
checksum: 10/080a80e5c36b6861ee4a9a6e5ad9692cc3861cfb9edd0b02e9438aaaaa5a6e1b6f65275469d9f997696487841c7bb7daa69bba69c5e7301426056437bf544138
languageName: node
linkType: hard
"@rushstack/terminal@npm:0.22.1":
version: 0.22.1
resolution: "@rushstack/terminal@npm:0.22.1"
dependencies:
"@rushstack/node-core-library": "npm:5.20.1"
"@rushstack/problem-matcher": "npm:0.2.1"
supports-color: "npm:~8.1.1"
peerDependencies:
"@types/node": "*"
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10/fe4da212e11c60b8a6a2de9cb7658b03c510831d365c560eedf26a20fa85c62a45f1865cff99c2b252dcd773329fcd2347dd89e5e2efd5694d7746f0a8aec172
languageName: node
linkType: hard
"@rushstack/ts-command-line@npm:5.3.1":
version: 5.3.1
resolution: "@rushstack/ts-command-line@npm:5.3.1"
dependencies:
"@rushstack/terminal": "npm:0.22.1"
"@types/argparse": "npm:1.0.38"
argparse: "npm:~1.0.9"
string-argv: "npm:~0.3.1"
checksum: 10/51ca262eefbf07875f3e57fb402cba80e7ff36c14c0fc98c59af7be65407cafb4cbfe9b6738b549d91e687e40bb5720afb214efa1352a7a13c186241f92795f0
languageName: node
linkType: hard
"@sideway/address@npm:^4.1.5":
version: 4.1.5
resolution: "@sideway/address@npm:4.1.5"
@@ -8900,6 +9029,13 @@ __metadata:
languageName: node
linkType: hard
"@types/argparse@npm:1.0.38":
version: 1.0.38
resolution: "@types/argparse@npm:1.0.38"
checksum: 10/26ed7e3f1e3595efdb883a852f5205f971b798e4c28b7e30a32c5298eee596e8b45834ce831f014d250b9730819ab05acff5b31229666d3af4ba465b4697d0eb
languageName: node
linkType: hard
"@types/aria-query@npm:^5.0.1":
version: 5.0.4
resolution: "@types/aria-query@npm:5.0.4"
@@ -10519,6 +10655,94 @@ __metadata:
languageName: node
linkType: hard
"@volar/language-core@npm:2.4.28, @volar/language-core@npm:~2.4.11":
version: 2.4.28
resolution: "@volar/language-core@npm:2.4.28"
dependencies:
"@volar/source-map": "npm:2.4.28"
checksum: 10/6c735027df0dfee142654e0aa9265111a82c21134366c08f4764743f74875ba8314fdc98865d37bf83ac7409dfea90b8538181a966681f3d01f68bbd999fef3a
languageName: node
linkType: hard
"@volar/source-map@npm:2.4.28":
version: 2.4.28
resolution: "@volar/source-map@npm:2.4.28"
checksum: 10/494b086be7ef6a46993941144a6961dcf9ecc4c830e2279031004496a7480727d6b0dc3f16776bf83aafe005084655c5664198f362a2c975d8267855de7b0a27
languageName: node
linkType: hard
"@volar/typescript@npm:^2.4.11":
version: 2.4.28
resolution: "@volar/typescript@npm:2.4.28"
dependencies:
"@volar/language-core": "npm:2.4.28"
path-browserify: "npm:^1.0.1"
vscode-uri: "npm:^3.0.8"
checksum: 10/6176e1fccc3c060a6393ab33b9befb828542a813a72201f0a83a8e6607055ac98a838db32ce9f54fe305df51cd1fa0eefc30d5e16dd2391af0563c76746f6679
languageName: node
linkType: hard
"@vue/compiler-core@npm:3.5.28":
version: 3.5.28
resolution: "@vue/compiler-core@npm:3.5.28"
dependencies:
"@babel/parser": "npm:^7.29.0"
"@vue/shared": "npm:3.5.28"
entities: "npm:^7.0.1"
estree-walker: "npm:^2.0.2"
source-map-js: "npm:^1.2.1"
checksum: 10/12af441c9ca51df2c0fb31f88b20966fc710c272818f65827dab44168f6d479b994d6f801d94511e78a7ddeced933c5b15e88f86b5528b155138a1938675a46f
languageName: node
linkType: hard
"@vue/compiler-dom@npm:^3.5.0":
version: 3.5.28
resolution: "@vue/compiler-dom@npm:3.5.28"
dependencies:
"@vue/compiler-core": "npm:3.5.28"
"@vue/shared": "npm:3.5.28"
checksum: 10/172ae6cf07dfdd94601981c27574a1329b25dded32a423627f7ecedd79492f5ad548305538f50e21900481f53881dff862a1c472ce5cc18ce38fad7c59bdc53a
languageName: node
linkType: hard
"@vue/compiler-vue2@npm:^2.7.16":
version: 2.7.16
resolution: "@vue/compiler-vue2@npm:2.7.16"
dependencies:
de-indent: "npm:^1.0.2"
he: "npm:^1.2.0"
checksum: 10/739ad06be19206b2715707c226a070509bcf28c31b539a6fc932d220eb7b0c09109d71fded573ed0c4073429793a3513ca4a4e69ad4f7afc0c5bc3c28639e871
languageName: node
linkType: hard
"@vue/language-core@npm:2.2.0":
version: 2.2.0
resolution: "@vue/language-core@npm:2.2.0"
dependencies:
"@volar/language-core": "npm:~2.4.11"
"@vue/compiler-dom": "npm:^3.5.0"
"@vue/compiler-vue2": "npm:^2.7.16"
"@vue/shared": "npm:^3.5.0"
alien-signals: "npm:^0.4.9"
minimatch: "npm:^9.0.3"
muggle-string: "npm:^0.4.1"
path-browserify: "npm:^1.0.1"
peerDependencies:
typescript: "*"
peerDependenciesMeta:
typescript:
optional: true
checksum: 10/dc22d038509a58e5a5569fe19f67e7373067cde3531b1e405270dcbe026a8cdbb1de8a7a93d6aaa76a3c5b71393f5c6ec5d9125f0b050898cb96a5c62b4a8d88
languageName: node
linkType: hard
"@vue/shared@npm:3.5.28, @vue/shared@npm:^3.5.0":
version: 3.5.28
resolution: "@vue/shared@npm:3.5.28"
checksum: 10/7d4132479462da5443b174d74052a00b796b57881e8e15298fad88acf4a9552db84ad8bb4104628d78bf7a57e43bfa985e65336abea6776b56277a1b95677a91
languageName: node
linkType: hard
"@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.14.1":
version: 1.14.1
resolution: "@webassemblyjs/ast@npm:1.14.1"
@@ -10852,6 +11076,18 @@ __metadata:
languageName: node
linkType: hard
"ajv-draft-04@npm:~1.0.0":
version: 1.0.0
resolution: "ajv-draft-04@npm:1.0.0"
peerDependencies:
ajv: ^8.5.0
peerDependenciesMeta:
ajv:
optional: true
checksum: 10/3f11fa0e7f7359bef6608657f02ab78e9cc62b1fb7bdd860db0d00351b3863a1189c1a23b72466d2d82726cab4eb20725c76f5e7c134a89865e2bfd0e6828137
languageName: node
linkType: hard
"ajv-formats@npm:^2.1.1":
version: 2.1.1
resolution: "ajv-formats@npm:2.1.1"
@@ -10866,6 +11102,20 @@ __metadata:
languageName: node
linkType: hard
"ajv-formats@npm:~3.0.1":
version: 3.0.1
resolution: "ajv-formats@npm:3.0.1"
dependencies:
ajv: "npm:^8.0.0"
peerDependencies:
ajv: ^8.0.0
peerDependenciesMeta:
ajv:
optional: true
checksum: 10/5679b9f9ced9d0213a202a37f3aa91efcffe59a6de1a6e3da5c873344d3c161820a1f11cc29899661fee36271fd2895dd3851b6461c902a752ad661d1c1e8722
languageName: node
linkType: hard
"ajv-keywords@npm:^3.4.1, ajv-keywords@npm:^3.5.2":
version: 3.5.2
resolution: "ajv-keywords@npm:3.5.2"
@@ -10910,6 +11160,30 @@ __metadata:
languageName: node
linkType: hard
"ajv@npm:~8.12.0":
version: 8.12.0
resolution: "ajv@npm:8.12.0"
dependencies:
fast-deep-equal: "npm:^3.1.1"
json-schema-traverse: "npm:^1.0.0"
require-from-string: "npm:^2.0.2"
uri-js: "npm:^4.2.2"
checksum: 10/b406f3b79b5756ac53bfe2c20852471b08e122bc1ee4cde08ae4d6a800574d9cd78d60c81c69c63ff81e4da7cd0b638fafbb2303ae580d49cf1600b9059efb85
languageName: node
linkType: hard
"ajv@npm:~8.13.0":
version: 8.13.0
resolution: "ajv@npm:8.13.0"
dependencies:
fast-deep-equal: "npm:^3.1.3"
json-schema-traverse: "npm:^1.0.0"
require-from-string: "npm:^2.0.2"
uri-js: "npm:^4.4.1"
checksum: 10/4ada268c9a6e44be87fd295df0f0a91267a7bae8dbc8a67a2d5799c3cb459232839c99d18b035597bb6e3ffe88af6979f7daece854f590a81ebbbc2dfa80002c
languageName: node
linkType: hard
"algoliasearch-helper@npm:^3.26.0":
version: 3.26.0
resolution: "algoliasearch-helper@npm:3.26.0"
@@ -10943,6 +11217,13 @@ __metadata:
languageName: node
linkType: hard
"alien-signals@npm:^0.4.9":
version: 0.4.14
resolution: "alien-signals@npm:0.4.14"
checksum: 10/306a7f4a88a982d1619ff313ed078bdfe52bb9d1381590ef4c1c245812ce7274b9b645a6233214e764a1adbef21863bdf74d10aa4fb30917456b7dd7779df5fc
languageName: node
linkType: hard
"ansi-align@npm:^3.0.1":
version: 3.0.1
resolution: "ansi-align@npm:3.0.1"
@@ -11101,7 +11382,7 @@ __metadata:
languageName: node
linkType: hard
"argparse@npm:^1.0.7":
"argparse@npm:^1.0.7, argparse@npm:~1.0.9":
version: 1.0.10
resolution: "argparse@npm:1.0.10"
dependencies:
@@ -12881,7 +13162,7 @@ __metadata:
languageName: node
linkType: hard
"commander@npm:^9.0.0, commander@npm:^9.4.1":
"commander@npm:^9.4.1":
version: 9.5.0
resolution: "commander@npm:9.5.0"
checksum: 10/41c49b3d0f94a1fbeb0463c85b13f15aa15a9e0b4d5e10a49c0a1d58d4489b549d62262b052ae0aa6cfda53299bee487bfe337825df15e342114dde543f82906
@@ -14164,6 +14445,13 @@ __metadata:
languageName: node
linkType: hard
"de-indent@npm:^1.0.2":
version: 1.0.2
resolution: "de-indent@npm:1.0.2"
checksum: 10/30bf43744dca005f9252dbb34ed95dcb3c30dfe52bfed84973b89c29eccff04e27769f222a34c61a93354acf47457785e9032e6184be390ed1d324fb9ab3f427
languageName: node
linkType: hard
"debounce@npm:^1.2.1":
version: 1.2.1
resolution: "debounce@npm:1.2.1"
@@ -14500,6 +14788,13 @@ __metadata:
languageName: node
linkType: hard
"diff@npm:~8.0.2":
version: 8.0.3
resolution: "diff@npm:8.0.3"
checksum: 10/52f957e1fa53db4616ff5f4811b92b22b97a160c12a2f86f22debd4181227b0f6751aa8fd711d6a8fcf4618acb13b86bc702e6d9d6d6ed82acfd00c9cb26ace2
languageName: node
linkType: hard
"diffie-hellman@npm:^5.0.3":
version: 5.0.3
resolution: "diffie-hellman@npm:5.0.3"
@@ -15044,6 +15339,13 @@ __metadata:
languageName: node
linkType: hard
"entities@npm:^7.0.1":
version: 7.0.1
resolution: "entities@npm:7.0.1"
checksum: 10/3c0c58d869c45148463e96d21dee2d1b801bd3fe4cf47aa470cd26dfe81d59e9e0a9be92ae083fa02fa441283c883a471486e94538dcfb8544428aa80a55271b
languageName: node
linkType: hard
"env-paths@npm:^2.2.0":
version: 2.2.1
resolution: "env-paths@npm:2.2.1"
@@ -16506,7 +16808,7 @@ __metadata:
languageName: node
linkType: hard
"fs-extra@npm:^11.1.1, fs-extra@npm:^11.2.0, fs-extra@npm:^11.3.3":
"fs-extra@npm:^11.1.1, fs-extra@npm:^11.2.0, fs-extra@npm:^11.3.3, fs-extra@npm:~11.3.0":
version: 11.3.3
resolution: "fs-extra@npm:11.3.3"
dependencies:
@@ -16767,15 +17069,6 @@ __metadata:
languageName: node
linkType: hard
"get-tsconfig@npm:^4.10.0":
version: 4.11.0
resolution: "get-tsconfig@npm:4.11.0"
dependencies:
resolve-pkg-maps: "npm:^1.0.0"
checksum: 10/f569a533ba6f68701e99a9af65c4b72186fc3446be7af9478906f047443d715a728959adae8661299ce49b5bb8edc06d942c81bce57632166104bce633600db8
languageName: node
linkType: hard
"github-from-package@npm:0.0.0":
version: 0.0.0
resolution: "github-from-package@npm:0.0.0"
@@ -17016,7 +17309,7 @@ __metadata:
languageName: node
linkType: hard
"globby@npm:^11.0.4, globby@npm:^11.1.0":
"globby@npm:^11.1.0":
version: 11.1.0
resolution: "globby@npm:11.1.0"
dependencies:
@@ -18028,7 +18321,7 @@ __metadata:
languageName: node
linkType: hard
"import-lazy@npm:^4.0.0":
"import-lazy@npm:^4.0.0, import-lazy@npm:~4.0.0":
version: 4.0.0
resolution: "import-lazy@npm:4.0.0"
checksum: 10/943309cc8eb01ada12700448c288b0384f77a1bc33c7e00fa4cb223c665f467a13ce9aaceb8d2e4cf586b07c1d2828040263dcc069873ce63cfc2ac6fd087971
@@ -18942,6 +19235,13 @@ __metadata:
languageName: node
linkType: hard
"jju@npm:~1.4.0":
version: 1.4.0
resolution: "jju@npm:1.4.0"
checksum: 10/1067ff8ce02221faac5a842116ed0ec79a53312a111d0bf8342a80bd02c0a3fdf0b8449694a65947db0a3e8420e8b326dffb489c7dd5866efc380c0d1708a707
languageName: node
linkType: hard
"joi@npm:^17.9.2":
version: 17.13.3
resolution: "joi@npm:17.13.3"
@@ -19456,7 +19756,7 @@ __metadata:
languageName: node
linkType: hard
"local-pkg@npm:^1.1.1":
"local-pkg@npm:^1.0.0, local-pkg@npm:^1.1.1":
version: 1.1.2
resolution: "local-pkg@npm:1.1.2"
dependencies:
@@ -19590,7 +19890,7 @@ __metadata:
languageName: node
linkType: hard
"lodash@npm:^4.17.23":
"lodash@npm:^4.17.23, lodash@npm:~4.17.23":
version: 4.17.23
resolution: "lodash@npm:4.17.23"
checksum: 10/82504c88250f58da7a5a4289f57a4f759c44946c005dd232821c7688b5fcfbf4a6268f6a6cdde4b792c91edd2f3b5398c1d2a0998274432cff76def48735e233
@@ -19652,11 +19952,10 @@ __metadata:
languageName: node
linkType: hard
"loot-core@workspace:*, loot-core@workspace:packages/loot-core":
"loot-core@workspace:*, loot-core@workspace:^, loot-core@workspace:packages/loot-core":
version: 0.0.0-use.local
resolution: "loot-core@workspace:packages/loot-core"
dependencies:
"@actual-app/api": "workspace:^"
"@actual-app/crdt": "workspace:^"
"@jlongster/sql.js": "npm:^1.6.7"
"@reduxjs/toolkit": "npm:^2.11.2"
@@ -19695,6 +19994,7 @@ __metadata:
npm-run-all: "npm:^4.1.5"
path-browserify: "npm:^1.0.1"
peggy: "npm:5.0.6"
promise-retry: "npm:^2.0.1"
rollup-plugin-visualizer: "npm:^6.0.5"
slash: "npm:5.1.0"
stream-browserify: "npm:^3.0.0"
@@ -19812,7 +20112,7 @@ __metadata:
languageName: node
linkType: hard
"magic-string@npm:^0.30.0, magic-string@npm:^0.30.21, magic-string@npm:^0.30.3":
"magic-string@npm:^0.30.0, magic-string@npm:^0.30.17, magic-string@npm:^0.30.21, magic-string@npm:^0.30.3":
version: 0.30.21
resolution: "magic-string@npm:0.30.21"
dependencies:
@@ -21001,6 +21301,15 @@ __metadata:
languageName: node
linkType: hard
"minimatch@npm:10.2.1, minimatch@npm:^10.1.2, minimatch@npm:^10.2.1":
version: 10.2.1
resolution: "minimatch@npm:10.2.1"
dependencies:
brace-expansion: "npm:^5.0.2"
checksum: 10/d41c195ee1f2c70a75641088e36d0fa5fa286cb6fe48558e6d3bf3d95f640eda453c217707215389b12234df12175f65f338c0b841b36b0125177dbd6a80d026
languageName: node
linkType: hard
"minimatch@npm:3.1.2, minimatch@npm:^3.0.2, minimatch@npm:^3.0.3, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
version: 3.1.2
resolution: "minimatch@npm:3.1.2"
@@ -21019,15 +21328,6 @@ __metadata:
languageName: node
linkType: hard
"minimatch@npm:^10.1.2, minimatch@npm:^10.2.1":
version: 10.2.1
resolution: "minimatch@npm:10.2.1"
dependencies:
brace-expansion: "npm:^5.0.2"
checksum: 10/d41c195ee1f2c70a75641088e36d0fa5fa286cb6fe48558e6d3bf3d95f640eda453c217707215389b12234df12175f65f338c0b841b36b0125177dbd6a80d026
languageName: node
linkType: hard
"minimatch@npm:^5.0.1":
version: 5.1.6
resolution: "minimatch@npm:5.1.6"
@@ -21232,6 +21532,13 @@ __metadata:
languageName: node
linkType: hard
"muggle-string@npm:^0.4.1":
version: 0.4.1
resolution: "muggle-string@npm:0.4.1"
checksum: 10/8fa2ea08f497c04069718bd3fd1909b382114dacbad832d10967ca72690de43f5f8492d8ccfbf827d6be63868ed5fc10395e7b7c082aa95997eea498586c6620
languageName: node
linkType: hard
"multicast-dns@npm:^7.2.5":
version: 7.2.5
resolution: "multicast-dns@npm:7.2.5"
@@ -21251,13 +21558,6 @@ __metadata:
languageName: node
linkType: hard
"mylas@npm:^2.1.9":
version: 2.1.13
resolution: "mylas@npm:2.1.13"
checksum: 10/37f335424463c422f48d50317aa0a34fe410fabb146cbf27b453a0aa743732b5626f56deaa190bca2ce29836f809d88759007976dc78d5d22b75918a00586577
languageName: node
linkType: hard
"nano-spawn@npm:^2.0.0":
version: 2.0.0
resolution: "nano-spawn@npm:2.0.0"
@@ -22658,15 +22958,6 @@ __metadata:
languageName: node
linkType: hard
"plimit-lit@npm:^1.2.6":
version: 1.6.1
resolution: "plimit-lit@npm:1.6.1"
dependencies:
queue-lit: "npm:^1.5.1"
checksum: 10/e4eaf018dc311fd4d452954c10992cd8a9eb72d168ec2274bb831d86558422703e1405a8978ffdd5c418654e6a25e10a0765a39bf3ce3a84dc799fe6268e0ea4
languageName: node
linkType: hard
"plist@npm:3.1.0, plist@npm:^3.0.4, plist@npm:^3.0.5, plist@npm:^3.1.0":
version: 3.1.0
resolution: "plist@npm:3.1.0"
@@ -23864,13 +24155,6 @@ __metadata:
languageName: node
linkType: hard
"queue-lit@npm:^1.5.1":
version: 1.5.2
resolution: "queue-lit@npm:1.5.2"
checksum: 10/8dd45c79bd25b33b0c7d587391eb0b4acc4deb797bf92fef62b2d8e7c03b64083f5304f09d52a18267d34d020cc67ccde97a88185b67590eeccb194938ff1f98
languageName: node
linkType: hard
"queue-microtask@npm:^1.2.2":
version: 1.2.3
resolution: "queue-microtask@npm:1.2.3"
@@ -25169,13 +25453,6 @@ __metadata:
languageName: node
linkType: hard
"resolve-pkg-maps@npm:^1.0.0":
version: 1.0.0
resolution: "resolve-pkg-maps@npm:1.0.0"
checksum: 10/0763150adf303040c304009231314d1e84c6e5ebfa2d82b7d94e96a6e82bacd1dcc0b58ae257315f3c8adb89a91d8d0f12928241cba2df1680fbe6f60bf99b0e
languageName: node
linkType: hard
"resolve@npm:^1.10.0, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.22.1, resolve@npm:^1.22.10":
version: 1.22.10
resolution: "resolve@npm:1.22.10"
@@ -25189,7 +25466,7 @@ __metadata:
languageName: node
linkType: hard
"resolve@npm:^1.22.8":
"resolve@npm:^1.22.8, resolve@npm:~1.22.1, resolve@npm:~1.22.2":
version: 1.22.11
resolution: "resolve@npm:1.22.11"
dependencies:
@@ -25215,7 +25492,7 @@ __metadata:
languageName: node
linkType: hard
"resolve@patch:resolve@npm%3A^1.22.8#optional!builtin<compat/resolve>":
"resolve@patch:resolve@npm%3A^1.22.8#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A~1.22.1#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A~1.22.2#optional!builtin<compat/resolve>":
version: 1.22.11
resolution: "resolve@patch:resolve@npm%3A1.22.11#optional!builtin<compat/resolve>::version=1.22.11&hash=c3c19d"
dependencies:
@@ -25754,6 +26031,17 @@ __metadata:
languageName: node
linkType: hard
"semver@npm:~7.5.4":
version: 7.5.4
resolution: "semver@npm:7.5.4"
dependencies:
lru-cache: "npm:^6.0.0"
bin:
semver: bin/semver.js
checksum: 10/985dec0d372370229a262c737063860fabd4a1c730662c1ea3200a2f649117761a42184c96df62a0e885e76fbd5dace41087d6c1ac0351b13c0df5d6bcb1b5ac
languageName: node
linkType: hard
"send@npm:0.19.0":
version: 0.19.0
resolution: "send@npm:0.19.0"
@@ -26572,7 +26860,7 @@ __metadata:
languageName: node
linkType: hard
"string-argv@npm:^0.3.2":
"string-argv@npm:^0.3.2, string-argv@npm:~0.3.1":
version: 0.3.2
resolution: "string-argv@npm:0.3.2"
checksum: 10/f9d3addf887026b4b5f997a271149e93bf71efc8692e7dc0816e8807f960b18bcb9787b45beedf0f97ff459575ee389af3f189d8b649834cac602f2e857e75af
@@ -26801,7 +27089,7 @@ __metadata:
languageName: node
linkType: hard
"strip-json-comments@npm:^3.1.1":
"strip-json-comments@npm:^3.1.1, strip-json-comments@npm:~3.1.1":
version: 3.1.1
resolution: "strip-json-comments@npm:3.1.1"
checksum: 10/492f73e27268f9b1c122733f28ecb0e7e8d8a531a6662efbd08e22cccb3f9475e90a1b82cab06a392f6afae6d2de636f977e231296400d0ec5304ba70f166443
@@ -26930,7 +27218,7 @@ __metadata:
languageName: node
linkType: hard
"supports-color@npm:^8.0.0":
"supports-color@npm:^8.0.0, supports-color@npm:~8.1.1":
version: 8.1.1
resolution: "supports-color@npm:8.1.1"
dependencies:
@@ -27556,23 +27844,6 @@ __metadata:
languageName: node
linkType: hard
"tsc-alias@npm:^1.8.16":
version: 1.8.16
resolution: "tsc-alias@npm:1.8.16"
dependencies:
chokidar: "npm:^3.5.3"
commander: "npm:^9.0.0"
get-tsconfig: "npm:^4.10.0"
globby: "npm:^11.0.4"
mylas: "npm:^2.1.9"
normalize-path: "npm:^3.0.0"
plimit-lit: "npm:^1.2.6"
bin:
tsc-alias: dist/bin/index.js
checksum: 10/a4c1988e645c0bbb993629f1cde79189549db35c2aeff7aa23bbf0864437f6dd15f91de3b51fe05cbd53e56ed32529710cc22855a8925c637357ab4c5e4f862a
languageName: node
linkType: hard
"tsconfck@npm:^3.0.3":
version: 3.1.6
resolution: "tsconfck@npm:3.1.6"
@@ -27764,6 +28035,16 @@ __metadata:
languageName: node
linkType: hard
"typescript@npm:5.8.2":
version: 5.8.2
resolution: "typescript@npm:5.8.2"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 10/dbc2168a55d56771f4d581997be52bab5cbc09734fec976cfbaabd787e61fb4c6cf9125fd48c6f98054ce549c77ecedefc7f64252a830dd8e9c3381f61fbeb78
languageName: node
linkType: hard
"typescript@npm:^5.0.4, typescript@npm:^5.9.3":
version: 5.9.3
resolution: "typescript@npm:5.9.3"
@@ -27774,6 +28055,16 @@ __metadata:
languageName: node
linkType: hard
"typescript@patch:typescript@npm%3A5.8.2#optional!builtin<compat/typescript>":
version: 5.8.2
resolution: "typescript@patch:typescript@npm%3A5.8.2#optional!builtin<compat/typescript>::version=5.8.2&hash=5786d5"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 10/97920a082ffc57583b1cb6bc4faa502acc156358e03f54c7fc7fdf0b61c439a717f4c9070c449ee9ee683d4cfc3bb203127c2b9794b2950f66d9d307a4ff262c
languageName: node
linkType: hard
"typescript@patch:typescript@npm%3A^5.0.4#optional!builtin<compat/typescript>, typescript@patch:typescript@npm%3A^5.9.3#optional!builtin<compat/typescript>":
version: 5.9.3
resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin<compat/typescript>::version=5.9.3&hash=5786d5"
@@ -28113,7 +28404,7 @@ __metadata:
languageName: node
linkType: hard
"uri-js@npm:^4.2.2":
"uri-js@npm:^4.2.2, uri-js@npm:^4.4.1":
version: 4.4.1
resolution: "uri-js@npm:4.4.1"
dependencies:
@@ -28443,6 +28734,29 @@ __metadata:
languageName: node
linkType: hard
"vite-plugin-dts@npm:^4.5.4":
version: 4.5.4
resolution: "vite-plugin-dts@npm:4.5.4"
dependencies:
"@microsoft/api-extractor": "npm:^7.50.1"
"@rollup/pluginutils": "npm:^5.1.4"
"@volar/typescript": "npm:^2.4.11"
"@vue/language-core": "npm:2.2.0"
compare-versions: "npm:^6.1.1"
debug: "npm:^4.4.0"
kolorist: "npm:^1.8.0"
local-pkg: "npm:^1.0.0"
magic-string: "npm:^0.30.17"
peerDependencies:
typescript: "*"
vite: "*"
peerDependenciesMeta:
vite:
optional: true
checksum: 10/1504a8da02f8015c3138ef57a690179ad9b9d4369a054ae48b52a1c8cbc7ad05474551eab309cd90cf758800e17b67ccd13317aa5f8e28efde957547c7a339fb
languageName: node
linkType: hard
"vite-plugin-node-polyfills@npm:^0.25.0":
version: 0.25.0
resolution: "vite-plugin-node-polyfills@npm:0.25.0"
@@ -28671,6 +28985,13 @@ __metadata:
languageName: node
linkType: hard
"vscode-uri@npm:^3.0.8":
version: 3.1.0
resolution: "vscode-uri@npm:3.1.0"
checksum: 10/80c2a2421f44b64008ef1f91dfa52a2d68105cbb4dcea197dbf5b00c65ccaccf218b615e93ec587f26fc3ba04796898f3631a9406e3b04cda970c3ca8eadf646
languageName: node
linkType: hard
"vscode-uri@npm:~3.0.8":
version: 3.0.8
resolution: "vscode-uri@npm:3.0.8"