From eadd88ce31240b85426f515a7dbccb9ec99dba34 Mon Sep 17 00:00:00 2001 From: Julian Dominguez-Schatz Date: Sat, 21 Jun 2025 00:16:55 -0400 Subject: [PATCH] Move more `.d.ts` files to `.ts` (#5204) * Rename .d.ts files to .ts * Fix type and lint errors * Add release notes * CodeRabbit feedback --- packages/loot-core/package.json | 1 + .../server/connection/__mocks__/index.ts | 2 +- .../connection/{index.d.ts => index-types.ts} | 8 +- .../platform/server/connection/index.api.ts | 2 +- .../server/connection/index.electron.ts | 2 +- .../src/platform/server/connection/index.ts | 2 +- .../src/platform/server/fs/index.d.ts | 71 -------- .../src/platform/server/fs/index.electron.ts | 6 +- .../loot-core/src/platform/server/fs/index.ts | 79 +++++++++ .../src/platform/server/fs/index.web.test.ts | 2 +- .../src/platform/server/fs/index.web.ts | 22 ++- .../src/platform/server/fs/path-join.d.ts | 2 - .../src/platform/server/fs/path-join.ts | 2 + .../src/platform/server/fs/shared.ts | 4 +- .../src/platform/server/sqlite/index.d.ts | 35 ---- .../src/platform/server/sqlite/index.ts | 58 ++++++ .../src/platform/server/sqlite/index.web.ts | 11 +- .../src/server/importers/ynab4-types.d.ts | 165 ------------------ .../src/server/importers/ynab4-types.ts | 163 +++++++++++++++++ .../loot-core/src/server/importers/ynab4.ts | 2 +- .../src/server/importers/ynab5-types.d.ts | 79 --------- .../src/server/importers/ynab5-types.ts | 77 ++++++++ .../loot-core/src/server/importers/ynab5.ts | 2 +- .../src/types/{prefs.d.ts => prefs.ts} | 0 upcoming-release-notes/5204.md | 6 + yarn.lock | 8 + 26 files changed, 433 insertions(+), 378 deletions(-) rename packages/loot-core/src/platform/server/connection/{index.d.ts => index-types.ts} (70%) delete mode 100644 packages/loot-core/src/platform/server/fs/index.d.ts create mode 100644 packages/loot-core/src/platform/server/fs/index.ts delete mode 100644 packages/loot-core/src/platform/server/fs/path-join.d.ts create mode 100644 packages/loot-core/src/platform/server/fs/path-join.ts delete mode 100644 packages/loot-core/src/platform/server/sqlite/index.d.ts create mode 100644 packages/loot-core/src/platform/server/sqlite/index.ts delete mode 100644 packages/loot-core/src/server/importers/ynab4-types.d.ts create mode 100644 packages/loot-core/src/server/importers/ynab4-types.ts delete mode 100644 packages/loot-core/src/server/importers/ynab5-types.d.ts create mode 100644 packages/loot-core/src/server/importers/ynab5-types.ts rename packages/loot-core/src/types/{prefs.d.ts => prefs.ts} (100%) create mode 100644 upcoming-release-notes/5204.md diff --git a/packages/loot-core/package.json b/packages/loot-core/package.json index d8ea05e6c2..3a9ce4b4bc 100644 --- a/packages/loot-core/package.json +++ b/packages/loot-core/package.json @@ -46,6 +46,7 @@ "@swc/core": "^1.11.24", "@types/adm-zip": "^0.5.7", "@types/better-sqlite3": "^7.6.13", + "@types/emscripten": "^1.40.1", "@types/jlongster__sql.js": "npm:@types/sql.js@latest", "@types/node": "^22.15.18", "@types/pegjs": "^0.10.6", diff --git a/packages/loot-core/src/platform/server/connection/__mocks__/index.ts b/packages/loot-core/src/platform/server/connection/__mocks__/index.ts index afbe779d38..c1fed480b8 100644 --- a/packages/loot-core/src/platform/server/connection/__mocks__/index.ts +++ b/packages/loot-core/src/platform/server/connection/__mocks__/index.ts @@ -1,4 +1,4 @@ -import type * as T from '../index.d'; +import type * as T from '../index-types'; let events = []; diff --git a/packages/loot-core/src/platform/server/connection/index.d.ts b/packages/loot-core/src/platform/server/connection/index-types.ts similarity index 70% rename from packages/loot-core/src/platform/server/connection/index.d.ts rename to packages/loot-core/src/platform/server/connection/index-types.ts index d681d6ccd7..de0667fb14 100644 --- a/packages/loot-core/src/platform/server/connection/index.d.ts +++ b/packages/loot-core/src/platform/server/connection/index-types.ts @@ -1,20 +1,20 @@ import type { Handlers } from '../../../types/handlers'; import type { ServerEvents } from '../../../types/server-events'; -export function init( +export declare function init( channel: Window | number, // in electron the port number, in web the worker handlers: Handlers, ): void; export type Init = typeof init; -export function send( +export declare function send( type: K, args?: ServerEvents[K], ): void; export type Send = typeof send; -export function getNumClients(): number; +export declare function getNumClients(): number; export type GetNumClients = typeof getNumClients; -export function resetEvents(): void; +export declare function resetEvents(): void; export type ResetEvents = typeof resetEvents; diff --git a/packages/loot-core/src/platform/server/connection/index.api.ts b/packages/loot-core/src/platform/server/connection/index.api.ts index 8307ce4127..d21679d810 100644 --- a/packages/loot-core/src/platform/server/connection/index.api.ts +++ b/packages/loot-core/src/platform/server/connection/index.api.ts @@ -1,4 +1,4 @@ -import type * as T from './index.d'; +import type * as T from './index-types'; export const init: T.Init = function () {}; diff --git a/packages/loot-core/src/platform/server/connection/index.electron.ts b/packages/loot-core/src/platform/server/connection/index.electron.ts index 5e801622ca..6ad1094c37 100644 --- a/packages/loot-core/src/platform/server/connection/index.electron.ts +++ b/packages/loot-core/src/platform/server/connection/index.electron.ts @@ -3,7 +3,7 @@ import { APIError } from '../../../server/errors'; import { runHandler, isMutating } from '../../../server/mutators'; import { captureException } from '../../exceptions'; -import type * as T from './index.d'; +import type * as T from './index-types'; function coerceError(error) { if (error.type && error.type === 'APIError') { diff --git a/packages/loot-core/src/platform/server/connection/index.ts b/packages/loot-core/src/platform/server/connection/index.ts index 469c7f8ffe..98b67cf256 100644 --- a/packages/loot-core/src/platform/server/connection/index.ts +++ b/packages/loot-core/src/platform/server/connection/index.ts @@ -3,7 +3,7 @@ import { APIError } from '../../../server/errors'; import { runHandler, isMutating } from '../../../server/mutators'; import { captureException } from '../../exceptions'; -import type * as T from './index.d'; +import type * as T from './index-types'; function getGlobalObject() { const obj = diff --git a/packages/loot-core/src/platform/server/fs/index.d.ts b/packages/loot-core/src/platform/server/fs/index.d.ts deleted file mode 100644 index d83079467f..0000000000 --- a/packages/loot-core/src/platform/server/fs/index.d.ts +++ /dev/null @@ -1,71 +0,0 @@ -export { join } from './path-join'; - -export function init(): void; -export type Init = typeof init; - -export function getDataDir(): string; -export type GetDataDir = typeof getDataDir; - -export function _setDocumentDir(dir: string): string; -export type _setDocumentDir = typeof _setDocumentDir; - -export function getDocumentDir(): string; -export type GetDocumentDir = typeof getDocumentDir; - -export function getBudgetDir(id: string): string; -export type GetBudgetDir = typeof getBudgetDir; - -export const bundledDatabasePath: string; -export type BundledDatabasePath = typeof bundledDatabasePath; - -export const migrationsPath: string; -export type MigrationsPath = typeof migrationsPath; - -export const demoBudgetPath: string; -export type DemoBudgetPath = typeof demoBudgetPath; - -export function pathToId(filepath: string): string; -export type PathToId = typeof pathToId; - -export function basename(filepath: string): string; -export type Basename = typeof basename; - -export function listDir(filepath: string): Promise; -export type ListDir = typeof listDir; - -export function exists(filepath: string): Promise; -export type Exists = typeof exists; - -export function mkdir(filepath: string): Promise; -export type Mkdir = typeof mkdir; - -export function size(filepath: string): Promise; -export type Size = typeof size; - -export function copyFile(frompath: string, topath: string): Promise; -export type CopyFile = typeof copyFile; - -export function readFile( - filepath: string, - encoding: 'binary' | null, -): Promise; -export function readFile(filepath: string, encoding?: 'utf8'): Promise; -export type ReadFile = typeof readFile; - -export function writeFile( - filepath: string, - contents: string | ArrayBuffer | NodeJS.ArrayBufferView, -): Promise; -export type WriteFile = typeof writeFile; - -export function removeFile(filepath: string): Promise; -export type RemoveFile = typeof removeFile; - -export function removeDir(dirpath: string): Promise; -export type RemoveDir = typeof removeDir; - -export function removeDirRecursively(dirpath: string): Promise; -export type RemoveDirRecursively = typeof removeDirRecursively; - -export function getModifiedTime(filepath: string): Promise; -export type GetModifiedTime = typeof getModifiedTime; diff --git a/packages/loot-core/src/platform/server/fs/index.electron.ts b/packages/loot-core/src/platform/server/fs/index.electron.ts index e9a51c051c..edb88f8a18 100644 --- a/packages/loot-core/src/platform/server/fs/index.electron.ts +++ b/packages/loot-core/src/platform/server/fs/index.electron.ts @@ -82,8 +82,8 @@ export const size = filepath => }); }); -export const copyFile = (frompath, topath) => { - return new Promise((resolve, reject) => { +export const copyFile: T.CopyFile = (frompath, topath) => { + return new Promise((resolve, reject) => { const readStream = fs.createReadStream(frompath); const writeStream = fs.createWriteStream(topath); @@ -91,7 +91,7 @@ export const copyFile = (frompath, topath) => { writeStream.on('error', reject); writeStream.on('open', () => readStream.pipe(writeStream)); - writeStream.once('close', () => resolve()); + writeStream.once('close', () => resolve(true)); }); }; diff --git a/packages/loot-core/src/platform/server/fs/index.ts b/packages/loot-core/src/platform/server/fs/index.ts new file mode 100644 index 0000000000..b613ffba38 --- /dev/null +++ b/packages/loot-core/src/platform/server/fs/index.ts @@ -0,0 +1,79 @@ +export { join } from './path-join'; + +export declare function init(): void; +export type Init = typeof init; + +export declare function getDataDir(): string; +export type GetDataDir = typeof getDataDir; + +export declare function _setDocumentDir(dir: string): string; +export type _SetDocumentDir = typeof _setDocumentDir; + +export declare function getDocumentDir(): string; +export type GetDocumentDir = typeof getDocumentDir; + +export declare function getBudgetDir(id: string): string; +export type GetBudgetDir = typeof getBudgetDir; + +export declare const bundledDatabasePath: string; +export type BundledDatabasePath = typeof bundledDatabasePath; + +export declare const migrationsPath: string; +export type MigrationsPath = typeof migrationsPath; + +export declare const demoBudgetPath: string; +export type DemoBudgetPath = typeof demoBudgetPath; + +export declare function pathToId(filepath: string): string; +export type PathToId = typeof pathToId; + +export declare function basename(filepath: string): string; +export type Basename = typeof basename; + +export declare function listDir(filepath: string): Promise; +export type ListDir = typeof listDir; + +export declare function exists(filepath: string): Promise; +export type Exists = typeof exists; + +export declare function mkdir(filepath: string): Promise; +export type Mkdir = typeof mkdir; + +export declare function size(filepath: string): Promise; +export type Size = typeof size; + +export declare function copyFile( + frompath: string, + topath: string, +): Promise; +export type CopyFile = typeof copyFile; + +export declare function readFile( + filepath: string, + encoding: 'binary' | null, +): Promise; +export declare function readFile( + filepath: string, + encoding?: 'utf8', +): Promise; +export type ReadFile = typeof readFile; + +export declare function writeFile( + filepath: string, + contents: string | ArrayBuffer | NodeJS.ArrayBufferView, +): Promise; +export type WriteFile = typeof writeFile; + +export declare function removeFile(filepath: string): Promise; +export type RemoveFile = typeof removeFile; + +export declare function removeDir(dirpath: string): Promise; +export type RemoveDir = typeof removeDir; + +export declare function removeDirRecursively( + dirpath: string, +): Promise; +export type RemoveDirRecursively = typeof removeDirRecursively; + +export declare function getModifiedTime(filepath: string): Promise; +export type GetModifiedTime = typeof getModifiedTime; diff --git a/packages/loot-core/src/platform/server/fs/index.web.test.ts b/packages/loot-core/src/platform/server/fs/index.web.test.ts index 5456c76f4e..17542c748e 100644 --- a/packages/loot-core/src/platform/server/fs/index.web.test.ts +++ b/packages/loot-core/src/platform/server/fs/index.web.test.ts @@ -98,7 +98,7 @@ describe('web filesystem', () => { expect(await readFile('/documents/deep/nested/file/ok.txt')).toBe('deeper'); const FS = sqlite._getModule().FS; - const { node } = FS.lookupPath('/documents/deep/nested/db.sqlite'); + const { node } = FS.lookupPath('/documents/deep/nested/db.sqlite', {}); expect(node.link).toBe( '/blocked/' + pathToId('/documents/deep/nested/db.sqlite'), ); diff --git a/packages/loot-core/src/platform/server/fs/index.web.ts b/packages/loot-core/src/platform/server/fs/index.web.ts index e42ab0f9fa..59d343fc07 100644 --- a/packages/loot-core/src/platform/server/fs/index.web.ts +++ b/packages/loot-core/src/platform/server/fs/index.web.ts @@ -4,11 +4,11 @@ import IndexedDBBackend from 'absurd-sql/dist/indexeddb-backend'; import * as connection from '../connection'; import * as idb from '../indexeddb'; -import { _getModule } from '../sqlite'; +import { _getModule, SqlJsModule } from '../sqlite'; import { join } from './path-join'; -let FS = null; +let FS: SqlJsModule['FS'] = null; let BFS = null; const NO_PERSIST = false; @@ -67,7 +67,10 @@ function _createFile(filepath: string) { return filepath; } -async function _readFile(filepath: string, opts?: { encoding?: string }) { +async function _readFile( + filepath: string, + opts?: { encoding: 'utf8' } | { encoding: 'binary' }, +): Promise { // We persist stuff in /documents, but don't need to handle sqlite // file specifically because those are symlinked to a separate // filesystem and will be handled in the BlockedFS @@ -97,7 +100,13 @@ async function _readFile(filepath: string, opts?: { encoding?: string }) { return item.contents; } else { - return FS.readFile(resolveLink(filepath), opts); + if (opts?.encoding === 'utf8') { + return FS.readFile(resolveLink(filepath), { encoding: 'utf8' }); + } else if (opts?.encoding === 'binary') { + return FS.readFile(resolveLink(filepath), { encoding: 'binary' }); + } else { + return FS.readFile(resolveLink(filepath)); + } } } @@ -341,7 +350,10 @@ export const copyFile = async function ( return result; }; -export const readFile = async function (filepath: string, encoding = 'utf8') { +export const readFile = async function ( + filepath: string, + encoding: 'binary' | 'utf8' = 'utf8', +) { return _readFile(filepath, { encoding }); }; diff --git a/packages/loot-core/src/platform/server/fs/path-join.d.ts b/packages/loot-core/src/platform/server/fs/path-join.d.ts deleted file mode 100644 index 7954dc6831..0000000000 --- a/packages/loot-core/src/platform/server/fs/path-join.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export function join(...args: string[]): string; -export type Join = typeof join; diff --git a/packages/loot-core/src/platform/server/fs/path-join.ts b/packages/loot-core/src/platform/server/fs/path-join.ts new file mode 100644 index 0000000000..1479912d44 --- /dev/null +++ b/packages/loot-core/src/platform/server/fs/path-join.ts @@ -0,0 +1,2 @@ +export declare function join(...args: string[]): string; +export type Join = typeof join; diff --git a/packages/loot-core/src/platform/server/fs/shared.ts b/packages/loot-core/src/platform/server/fs/shared.ts index d9552ddb99..3cf6e03e2d 100644 --- a/packages/loot-core/src/platform/server/fs/shared.ts +++ b/packages/loot-core/src/platform/server/fs/shared.ts @@ -1,8 +1,10 @@ // @ts-strict-ignore import { join } from './path-join'; +import type * as T from '.'; + let documentDir; -export const _setDocumentDir = dir => (documentDir = dir); +export const _setDocumentDir: T._SetDocumentDir = dir => (documentDir = dir); export const getDocumentDir = () => { if (!documentDir) { diff --git a/packages/loot-core/src/platform/server/sqlite/index.d.ts b/packages/loot-core/src/platform/server/sqlite/index.d.ts deleted file mode 100644 index 1c2b9fc04c..0000000000 --- a/packages/loot-core/src/platform/server/sqlite/index.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { type Database } from '@jlongster/sql.js'; - -export async function init(): Promise; - -export function _getModule(): SqlJsStatic; - -export function prepare(db: Database, sql: string): string; - -export function runQuery( - db: Database, - sql: string, - params?: (string | number)[], - fetchAll?: false, -): { changes: unknown }; -export function runQuery( - db: Database, - sql: string, - params: (string | number)[], - fetchAll: true, -): T[]; - -export function execQuery(db: Database, sql): void; - -export function transaction(db: Database, fn: () => void): void; - -export async function asyncTransaction( - db: Database, - fn: () => Promise, -): Promise; - -export async function openDatabase(pathOrBuffer?: string | Buffer): Database; - -export function closeDatabase(db: Database): void; - -export async function exportDatabase(db: Database): Promise; diff --git a/packages/loot-core/src/platform/server/sqlite/index.ts b/packages/loot-core/src/platform/server/sqlite/index.ts new file mode 100644 index 0000000000..166c144ceb --- /dev/null +++ b/packages/loot-core/src/platform/server/sqlite/index.ts @@ -0,0 +1,58 @@ +import { type Database, type SqlJsStatic } from '@jlongster/sql.js'; +/// + +// Types exported from sql.js (and Emscripten) are incomplete, so we need to redefine them here +type FSStream = (typeof FS)['FSStream'] & { + node: (typeof FS)['FSNode'] & { + contents: { + readIfFallback: () => Promise; + }; + }; +}; +type FS = Omit & { + lookupPath: ( + path: string, + opts?: { follow?: boolean }, + ) => { node: (typeof FS)['FSNode'] & { link?: string } }; + open: (path: string, flags: string, mode?: number) => FSStream; + close: (stream: FSStream) => void; +}; +export type SqlJsModule = SqlJsStatic & { + FS: FS; + reset_filesystem: () => void; + register_for_idb: (idb: IDBDatabase) => void; +}; + +export declare function init(): Promise; + +export declare function _getModule(): SqlJsModule; + +export declare function prepare(db: Database, sql: string): string; + +export declare function runQuery( + db: Database, + sql: string, + params?: (string | number)[], + fetchAll?: false, +): { changes: unknown }; +export declare function runQuery( + db: Database, + sql: string, + params: (string | number)[], + fetchAll: true, +): T[]; + +export declare function execQuery(db: Database, sql: string): void; + +export declare function transaction(db: Database, fn: () => void): void; + +export declare function asyncTransaction( + db: Database, + fn: () => Promise, +): Promise; + +export declare function openDatabase(pathOrBuffer?: string | Buffer): Database; + +export declare function closeDatabase(db: Database): void; + +export declare function exportDatabase(db: Database): Promise; diff --git a/packages/loot-core/src/platform/server/sqlite/index.web.ts b/packages/loot-core/src/platform/server/sqlite/index.web.ts index 95872ac44a..39502709ac 100644 --- a/packages/loot-core/src/platform/server/sqlite/index.web.ts +++ b/packages/loot-core/src/platform/server/sqlite/index.web.ts @@ -1,10 +1,12 @@ // @ts-strict-ignore -import initSqlJS, { type SqlJsStatic, type Database } from '@jlongster/sql.js'; +import initSqlJS, { type Database } from '@jlongster/sql.js'; import { normalise } from './normalise'; import { unicodeLike } from './unicodeLike'; -let SQL: SqlJsStatic | null = null; +import type { SqlJsModule } from '.'; + +let SQL: SqlJsModule | null = null; export async function init({ baseURL = process.env.PUBLIC_URL, @@ -16,7 +18,7 @@ export async function init({ locateFile: file => baseURL + file, }).then( sql => { - SQL = sql; + SQL = sql as SqlJsModule; resolve(undefined); }, err => { @@ -173,15 +175,12 @@ export async function openDatabase(pathOrBuffer?: string | Buffer) { const path = pathOrBuffer; if (path !== ':memory:') { if (typeof SharedArrayBuffer === 'undefined') { - // @ts-expect-error FS missing in sql.js types const stream = SQL.FS.open(SQL.FS.readlink(path), 'a+'); await stream.node.contents.readIfFallback(); - // @ts-expect-error FS missing in sql.js types SQL.FS.close(stream); } db = new SQL.Database( - // @ts-expect-error FS missing in sql.js types path.includes('/blocked') ? path : SQL.FS.readlink(path), // @ts-expect-error 2nd argument missed in sql.js types { filename: true }, diff --git a/packages/loot-core/src/server/importers/ynab4-types.d.ts b/packages/loot-core/src/server/importers/ynab4-types.d.ts deleted file mode 100644 index 69cf3284b8..0000000000 --- a/packages/loot-core/src/server/importers/ynab4-types.d.ts +++ /dev/null @@ -1,165 +0,0 @@ -export namespace YNAB4 { - export interface YFull { - masterCategories: MasterCategory[]; - payees: Payee[]; - monthlyBudgets: MonthlyBudget[]; - fileMetaData: FileMetaData; - transactions: Transaction[]; - scheduledTransactions: ScheduledTransaction[]; - // accountMappings: []; - budgetMetaData: BudgetMetaData; - accounts: Account[]; - } - - export interface MasterCategory { - entityType: string; - expanded: boolean; - note?: string; - name: string; - type: string; - deleteable: boolean; - subCategories?: SubCategory[]; - entityVersion: string; - entityId: string; - sortableIndex: number; - - // speculative - isTombstone?: boolean; - } - - export interface SubCategory { - entityType: string; - name: string; - note?: string; - type: string; - // cachedBalance: null; - masterCategoryId: string; - entityVersion: string; - entityId: string; - sortableIndex: number; - - // speculative - isTombstone?: boolean; - } - - export interface Payee { - entityType: string; - autoFillCategoryId?: string; - autoFillAmount: number; - name: string; - renameConditions?: RenameCondition[]; - autoFillMemo?: string; - targetAccountId?: string; - // locations: null; - enabled: boolean; - entityVersion: string; - entityId: string; - - // speculative - isTombstone?: boolean; - } - - export interface RenameCondition { - entityType: string; - parentPayeeId: string; - operator: string; - operand: string; - entityVersion: string; - entityId: string; - } - - export interface MonthlyBudget { - entityType: string; - monthlySubCategoryBudgets: MonthlySubCategoryBudget[]; - month: string; - entityVersion: string; - entityId: string; - } - - export interface MonthlySubCategoryBudget { - entityType: string; - categoryId: string; - budgeted: number; - // overspendingHandling: null; - entityVersion: string; - entityId: string; - parentMonthlyBudgetId: string; - - // speculative - isTombstone?: boolean; - } - - export interface FileMetaData { - entityType: string; - budgetDataVersion: string; - currentKnowledge: string; - } - - export interface Transaction { - entityType: string; - entityId: string; - categoryId: string; - payeeId: string; - amount: number; - date: string; - accountId: string; - entityVersion: string; - cleared: string; - accepted: boolean; - isTombstone?: boolean; - memo?: string; - dateEnteredFromSchedule?: string; - // speculative: - subTransactions?: SubTransaction[]; - transferTransactionId?: string; - targetAccountId?: string; - } - - // speculative, not in the test data - export type SubTransaction = Exclude; - - export interface ScheduledTransaction { - entityType: string; - entityId: string; - categoryId: string; - payeeId: string; - amount: number; - date: string; - isTombstone?: boolean; - accountId: string; - entityVersion: string; - memo: string; - twiceAMonthStartDay: number; - cleared: string; - frequency: string; - accepted: boolean; - } - - export interface BudgetMetaData { - entityType: string; - strictBudget: string; - currencyISOSymbol?: string; - entityVersion: string; - currencyLocale: string; - budgetType: string; - dateLocale: string; - entityId: string; - } - - export interface Account { - entityType: string; - // lastReconciledDate: null; - lastEnteredCheckNumber: number; - lastReconciledBalance: number; - accountType: string; - hidden: boolean; - sortableIndex: number; - onBudget: boolean; - accountName: string; - entityVersion: string; - entityId: string; - - // speculative - isTombstone?: boolean; - } -} diff --git a/packages/loot-core/src/server/importers/ynab4-types.ts b/packages/loot-core/src/server/importers/ynab4-types.ts new file mode 100644 index 0000000000..f62d666041 --- /dev/null +++ b/packages/loot-core/src/server/importers/ynab4-types.ts @@ -0,0 +1,163 @@ +export interface YFull { + masterCategories: MasterCategory[]; + payees: Payee[]; + monthlyBudgets: MonthlyBudget[]; + fileMetaData: FileMetaData; + transactions: Transaction[]; + scheduledTransactions: ScheduledTransaction[]; + // accountMappings: []; + budgetMetaData: BudgetMetaData; + accounts: Account[]; +} + +export interface MasterCategory { + entityType: string; + expanded: boolean; + note?: string; + name: string; + type: string; + deleteable: boolean; + subCategories?: SubCategory[]; + entityVersion: string; + entityId: string; + sortableIndex: number; + + // speculative + isTombstone?: boolean; +} + +export interface SubCategory { + entityType: string; + name: string; + note?: string; + type: string; + // cachedBalance: null; + masterCategoryId: string; + entityVersion: string; + entityId: string; + sortableIndex: number; + + // speculative + isTombstone?: boolean; +} + +export interface Payee { + entityType: string; + autoFillCategoryId?: string; + autoFillAmount: number; + name: string; + renameConditions?: RenameCondition[]; + autoFillMemo?: string; + targetAccountId?: string; + // locations: null; + enabled: boolean; + entityVersion: string; + entityId: string; + + // speculative + isTombstone?: boolean; +} + +export interface RenameCondition { + entityType: string; + parentPayeeId: string; + operator: string; + operand: string; + entityVersion: string; + entityId: string; +} + +export interface MonthlyBudget { + entityType: string; + monthlySubCategoryBudgets: MonthlySubCategoryBudget[]; + month: string; + entityVersion: string; + entityId: string; +} + +export interface MonthlySubCategoryBudget { + entityType: string; + categoryId: string; + budgeted: number; + overspendingHandling?: string | undefined | null; + entityVersion: string; + entityId: string; + parentMonthlyBudgetId: string; + + // speculative + isTombstone?: boolean; +} + +export interface FileMetaData { + entityType: string; + budgetDataVersion: string; + currentKnowledge: string; +} + +export interface Transaction { + entityType: string; + entityId: string; + categoryId: string; + payeeId: string; + amount: number; + date: string; + accountId: string; + entityVersion: string; + cleared: string; + accepted: boolean; + isTombstone?: boolean; + memo?: string; + dateEnteredFromSchedule?: string; + // speculative: + subTransactions?: SubTransaction[]; + transferTransactionId?: string; + targetAccountId?: string; +} + +// speculative, not in the test data +export type SubTransaction = Omit; + +export interface ScheduledTransaction { + entityType: string; + entityId: string; + categoryId: string; + payeeId: string; + amount: number; + date: string; + isTombstone?: boolean; + accountId: string; + entityVersion: string; + memo: string; + twiceAMonthStartDay: number; + cleared: string; + frequency: string; + accepted: boolean; +} + +export interface BudgetMetaData { + entityType: string; + strictBudget: string; + currencyISOSymbol?: string; + entityVersion: string; + currencyLocale: string; + budgetType: string; + dateLocale: string; + entityId: string; +} + +export interface Account { + entityType: string; + // lastReconciledDate: null; + lastEnteredCheckNumber: number; + lastReconciledBalance: number; + accountType: string; + hidden: boolean; + sortableIndex: number; + onBudget: boolean; + accountName: string; + entityVersion: string; + entityId: string; + + // speculative + isTombstone?: boolean; +} diff --git a/packages/loot-core/src/server/importers/ynab4.ts b/packages/loot-core/src/server/importers/ynab4.ts index e6c474e675..a11285d846 100644 --- a/packages/loot-core/src/server/importers/ynab4.ts +++ b/packages/loot-core/src/server/importers/ynab4.ts @@ -13,7 +13,7 @@ import { v4 as uuidv4 } from 'uuid'; import * as monthUtils from '../../shared/months'; import { groupBy, sortByKey } from '../../shared/util'; -import { YNAB4 } from './ynab4-types'; +import * as YNAB4 from './ynab4-types'; // Importer diff --git a/packages/loot-core/src/server/importers/ynab5-types.d.ts b/packages/loot-core/src/server/importers/ynab5-types.d.ts deleted file mode 100644 index d43cc36b15..0000000000 --- a/packages/loot-core/src/server/importers/ynab5-types.d.ts +++ /dev/null @@ -1,79 +0,0 @@ -export namespace YNAB5 { - export interface Budget { - name?: string; - budget_name?: string; - accounts: Account[]; - payees: Payee[]; - category_groups: CategoryGroup[]; - categories: Category[]; - transactions: Transaction[]; - subtransactions: Subtransaction[]; - months: Month[]; - } - - interface Account { - id: string; - name: string; - on_budget: boolean; - deleted: boolean; - closed: boolean; - } - - interface Payee { - id: string; - name: string; - deleted: boolean; - transfer_acct?: string; - } - - interface CategoryGroup { - id: string; - name: string; - deleted: boolean; - hidden: boolean; - } - - interface Category { - id: string; - category_group_id: string; - name: string; - deleted: boolean; - hidden: boolean; - } - - interface Transaction { - id: string; - account_id: string; - date: string; - payee_id: string; - import_id: string; - category_id: string; - transfer_account_id: string; - transfer_transaction_id: string; - memo: string; - cleared: string; - amount: number; - deleted: boolean; - } - - interface Subtransaction { - id: string; - transaction_id: string; - category_id: string; - memo: string; - amount: number; - transfer_account_id: string; - payee_id: string; - } - - interface Month { - month: string; - categories: MonthCategory[]; - } - - interface MonthCategory { - category_group_id: string; - id: string; - budgeted: number; - } -} diff --git a/packages/loot-core/src/server/importers/ynab5-types.ts b/packages/loot-core/src/server/importers/ynab5-types.ts new file mode 100644 index 0000000000..1a9529e8b1 --- /dev/null +++ b/packages/loot-core/src/server/importers/ynab5-types.ts @@ -0,0 +1,77 @@ +export interface Budget { + name?: string; + budget_name?: string; + accounts: Account[]; + payees: Payee[]; + category_groups: CategoryGroup[]; + categories: Category[]; + transactions: Transaction[]; + subtransactions: Subtransaction[]; + months: Month[]; +} + +export interface Account { + id: string; + name: string; + on_budget: boolean; + deleted: boolean; + closed: boolean; +} + +export interface Payee { + id: string; + name: string; + deleted: boolean; + transfer_acct?: string; +} + +export interface CategoryGroup { + id: string; + name: string; + deleted: boolean; + hidden: boolean; +} + +export interface Category { + id: string; + category_group_id: string; + name: string; + deleted: boolean; + hidden: boolean; +} + +export interface Transaction { + id: string; + account_id: string; + date: string; + payee_id: string; + import_id: string; + category_id: string; + transfer_account_id: string; + transfer_transaction_id: string; + memo: string; + cleared: string; + amount: number; + deleted: boolean; +} + +export interface Subtransaction { + id: string; + transaction_id: string; + category_id: string; + memo: string; + amount: number; + transfer_account_id: string; + payee_id: string; +} + +export interface Month { + month: string; + categories: MonthCategory[]; +} + +export interface MonthCategory { + category_group_id: string; + id: string; + budgeted: number; +} diff --git a/packages/loot-core/src/server/importers/ynab5.ts b/packages/loot-core/src/server/importers/ynab5.ts index 9ef226d9e7..a831234a94 100644 --- a/packages/loot-core/src/server/importers/ynab5.ts +++ b/packages/loot-core/src/server/importers/ynab5.ts @@ -9,7 +9,7 @@ import { v4 as uuidv4 } from 'uuid'; import * as monthUtils from '../../shared/months'; import { sortByKey, groupBy } from '../../shared/util'; -import { YNAB5 } from './ynab5-types'; +import * as YNAB5 from './ynab5-types'; function amountFromYnab(amount: number) { // ynabs multiplies amount by 1000 and actual by 100 diff --git a/packages/loot-core/src/types/prefs.d.ts b/packages/loot-core/src/types/prefs.ts similarity index 100% rename from packages/loot-core/src/types/prefs.d.ts rename to packages/loot-core/src/types/prefs.ts diff --git a/upcoming-release-notes/5204.md b/upcoming-release-notes/5204.md new file mode 100644 index 0000000000..51f1dab2a9 --- /dev/null +++ b/upcoming-release-notes/5204.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [jfdoming] +--- + +Move more .d.ts files to .ts diff --git a/yarn.lock b/yarn.lock index 2671f4f6e6..cc0725fbb7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6437,6 +6437,13 @@ __metadata: languageName: node linkType: hard +"@types/emscripten@npm:^1.40.1": + version: 1.40.1 + resolution: "@types/emscripten@npm:1.40.1" + checksum: 10/d1aa8b91416c0d8ea7d2f3b99c8c40327350dff632ad98cb67f9df9afa13efd4d755c273b49a37797390a94180c7cc98397bbbe1d8def4ea1d5d3bff9c816ac9 + languageName: node + linkType: hard + "@types/eslint-scope@npm:^3.7.7": version: 3.7.7 resolution: "@types/eslint-scope@npm:3.7.7" @@ -14120,6 +14127,7 @@ __metadata: "@swc/core": "npm:^1.11.24" "@types/adm-zip": "npm:^0.5.7" "@types/better-sqlite3": "npm:^7.6.13" + "@types/emscripten": "npm:^1.40.1" "@types/jlongster__sql.js": "npm:@types/sql.js@latest" "@types/node": "npm:^22.15.18" "@types/pegjs": "npm:^0.10.6"