Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d4fe5e9
[AI] Desktop client, E2E, loot-core, sync-server and tooling updates
MatissJanis Feb 15, 2026
da1d8dc
Refactor database handling in various modules to use async/await for …
MatissJanis Feb 15, 2026
3f773a3
Refactor sync migration tests to utilize async/await for improved rea…
MatissJanis Feb 15, 2026
79d34e7
Refactor various functions to utilize async/await for improved readab…
MatissJanis Feb 15, 2026
f7b0c80
Refactor BudgetFileSelection component to use async/await for onSelec…
MatissJanis Feb 15, 2026
c8125b2
Refactor filesystem module to use async/await for init function and r…
MatissJanis Feb 15, 2026
a29297b
Fix typo in init function declaration to ensure it returns a Promise<…
MatissJanis Feb 15, 2026
90df214
Update VRT screenshots
github-actions[bot] Feb 15, 2026
3efec43
Update tests to use async/await for init function in web filesystem, …
MatissJanis Feb 15, 2026
5cf54ad
Merge branch 'master' into matiss/desktop-and-tooling-updates
MatissJanis Feb 16, 2026
3c08b94
Update VRT screenshot for payees filter test to reflect recent changes
MatissJanis Feb 16, 2026
6a124cb
Update filesystem module to remove web-specific implementations and s…
MatissJanis Feb 16, 2026
715b82c
[AI] Merge master, resolve conflicts keeping master
MatissJanis Feb 19, 2026
63a1db1
Add release notes for maintenance: Remove usage of 'web' file types
MatissJanis Feb 19, 2026
f0dff64
Refactor filesystem module to use type annotations for exports and im…
MatissJanis Feb 19, 2026
062f53d
Trigger CI
MatissJanis Feb 19, 2026
d34a425
Add asyncStorage API file to export Electron index module
MatissJanis Feb 19, 2026
b1dd5a5
Trigger CI
MatissJanis Feb 19, 2026
ffbd902
Feedback: typo
MatissJanis Feb 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/component-library/vitest.web.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { defineConfig } from 'vitest/config';

const resolveExtensions = [
'.testing.ts',
'.web.ts',
'.mjs',
'.js',
'.mts',
Expand Down
4 changes: 0 additions & 4 deletions packages/desktop-client/vite.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,6 @@ export default defineConfig(async ({ mode }) => {
}

let resolveExtensions = [
'.web.js',
'.web.jsx',
'.web.ts',
'.web.tsx',
'.mjs',
'.js',
'.mts',
Expand Down
8 changes: 4 additions & 4 deletions packages/loot-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@
"./platform/exceptions": "./src/platform/exceptions/index.ts",
"./platform/server/asyncStorage": "./src/platform/server/asyncStorage/index.ts",
"./platform/server/connection": "./src/platform/server/connection/index.ts",
"./platform/server/fetch": "./src/platform/server/fetch/index.web.ts",
"./platform/server/fs": "./src/platform/server/fs/index.web.ts",
"./platform/server/log": "./src/platform/server/log/index.web.ts",
"./platform/server/sqlite": "./src/platform/server/sqlite/index.web.ts",
"./platform/server/fetch": "./src/platform/server/fetch/index.ts",
"./platform/server/fs": "./src/platform/server/fs/index.ts",
"./platform/server/log": "./src/platform/server/log/index.ts",
"./platform/server/sqlite": "./src/platform/server/sqlite/index.ts",
"./server/budget/types/*": "./src/server/budget/types/*.d.ts",
"./server/*": "./src/server/*.ts",
"./shared/*": "./src/shared/*.ts",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// oxlint-disable-next-line no-restricted-imports
export * from './index.electron';
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { logger } from '../log';

export const fetch = async (
input: RequestInfo | URL,
options?: RequestInit,
) => {
import type * as T from './index';

export const fetch: typeof T.fetch = async (input, options) => {
try {
return await globalThis.fetch(input, {
...options,
Expand Down
2 changes: 2 additions & 0 deletions packages/loot-core/src/platform/server/fs/index.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// oxlint-disable-next-line no-restricted-imports
export * from './index.electron';
71 changes: 40 additions & 31 deletions packages/loot-core/src/platform/server/fs/index.electron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import promiseRetry from 'promise-retry';

import { logger } from '../log';

import type * as T from '.';
import type * as T from './index';

export { getDocumentDir, getBudgetDir, _setDocumentDir } from './shared';

Expand All @@ -23,28 +23,37 @@ switch (path.basename(__filename)) {
break;
}

export const init = async () => {
export const init: typeof T.init = async () => {
// Nothing to do
};

export const getDataDir = () => {
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 = path.join(rootPath, 'default-db.sqlite');
export const bundledDatabasePath: typeof T.bundledDatabasePath = path.join(
rootPath,
'default-db.sqlite',
);

export const migrationsPath = path.join(rootPath, 'migrations');
export const migrationsPath: typeof T.migrationsPath = path.join(
rootPath,
'migrations',
);

export const demoBudgetPath = path.join(rootPath, 'demo-budget');
export const demoBudgetPath: typeof T.demoBudgetPath = path.join(
rootPath,
'demo-budget',
);

export const join = path.join;
export const join: typeof T.join = path.join;

export const basename = filepath => path.basename(filepath);
export const basename: typeof T.basename = filepath => path.basename(filepath);

export const listDir: T.ListDir = filepath =>
export const listDir: typeof T.listDir = filepath =>
new Promise((resolve, reject) => {
fs.readdir(filepath, (err, files) => {
if (err) {
Expand All @@ -55,14 +64,14 @@ export const listDir: T.ListDir = filepath =>
});
});

export const exists = filepath =>
export const exists: typeof T.exists = filepath =>
new Promise(resolve => {
fs.access(filepath, fs.constants.F_OK, err => {
return resolve(!err);
});
});

export const mkdir = filepath =>
export const mkdir: typeof T.mkdir = filepath =>
new Promise((resolve, reject) => {
fs.mkdir(filepath, err => {
if (err) {
Expand All @@ -73,7 +82,7 @@ export const mkdir = filepath =>
});
});

export const size = filepath =>
export const size: typeof T.size = filepath =>
new Promise((resolve, reject) => {
fs.stat(filepath, (err, stats) => {
if (err) {
Expand All @@ -84,7 +93,7 @@ export const size = filepath =>
});
});

export const copyFile: T.CopyFile = (frompath, topath) => {
export const copyFile: typeof T.copyFile = (frompath, topath) => {
return new Promise<boolean>((resolve, reject) => {
const readStream = fs.createReadStream(frompath);
const writeStream = fs.createWriteStream(topath);
Expand All @@ -97,7 +106,7 @@ export const copyFile: T.CopyFile = (frompath, topath) => {
});
};

export const readFile: T.ReadFile = (
export const readFile: typeof T.readFile = (
filepath: string,
encoding: 'utf8' | 'binary' | null = 'utf8',
) => {
Expand All @@ -119,12 +128,11 @@ export const readFile: T.ReadFile = (
});
};

export const writeFile: T.WriteFile = async (filepath, contents) => {
export const writeFile: typeof T.writeFile = async (filepath, contents) => {
try {
await promiseRetry(
(retry, attempt) => {
return new Promise((resolve, reject) => {
// @ts-expect-error contents type needs refining
fs.writeFile(filepath, contents, 'utf8', err => {
if (err) {
logger.error(
Expand Down Expand Up @@ -157,38 +165,39 @@ export const writeFile: T.WriteFile = async (filepath, contents) => {
}
};

export const removeFile = filepath => {
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 = dirpath => {
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 = 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);
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);
}
};
await removeDir(dirpath);
}
};

export const getModifiedTime = filepath => {
export const getModifiedTime: typeof T.getModifiedTime = filepath => {
return new Promise(function (resolve, reject) {
fs.stat(filepath, (err, stats) => {
if (err) {
Expand Down
Loading
Loading