hledger-lsp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +632 -0
  3. package/out/extension.d.ts +1 -0
  4. package/out/extension.d.ts.map +1 -0
  5. package/out/extension.js +2 -0
  6. package/out/extension.js.map +1 -0
  7. package/out/features/codeActions.d.ts +73 -0
  8. package/out/features/codeActions.d.ts.map +1 -0
  9. package/out/features/codeActions.js +417 -0
  10. package/out/features/codeActions.js.map +1 -0
  11. package/out/features/completion.d.ts +94 -0
  12. package/out/features/completion.d.ts.map +1 -0
  13. package/out/features/completion.js +323 -0
  14. package/out/features/completion.js.map +1 -0
  15. package/out/features/definition.d.ts +12 -0
  16. package/out/features/definition.d.ts.map +1 -0
  17. package/out/features/definition.js +61 -0
  18. package/out/features/definition.js.map +1 -0
  19. package/out/features/documentLinks.d.ts +17 -0
  20. package/out/features/documentLinks.d.ts.map +1 -0
  21. package/out/features/documentLinks.js +68 -0
  22. package/out/features/documentLinks.js.map +1 -0
  23. package/out/features/findReferences.d.ts +33 -0
  24. package/out/features/findReferences.d.ts.map +1 -0
  25. package/out/features/findReferences.js +79 -0
  26. package/out/features/findReferences.js.map +1 -0
  27. package/out/features/foldingRanges.d.ts +27 -0
  28. package/out/features/foldingRanges.d.ts.map +1 -0
  29. package/out/features/foldingRanges.js +111 -0
  30. package/out/features/foldingRanges.js.map +1 -0
  31. package/out/features/formatter.d.ts +70 -0
  32. package/out/features/formatter.d.ts.map +1 -0
  33. package/out/features/formatter.js +373 -0
  34. package/out/features/formatter.js.map +1 -0
  35. package/out/features/hover.d.ts +66 -0
  36. package/out/features/hover.d.ts.map +1 -0
  37. package/out/features/hover.js +387 -0
  38. package/out/features/hover.js.map +1 -0
  39. package/out/features/inlayHints.d.ts +43 -0
  40. package/out/features/inlayHints.d.ts.map +1 -0
  41. package/out/features/inlayHints.js +221 -0
  42. package/out/features/inlayHints.js.map +1 -0
  43. package/out/features/selectionRange.d.ts +47 -0
  44. package/out/features/selectionRange.d.ts.map +1 -0
  45. package/out/features/selectionRange.js +273 -0
  46. package/out/features/selectionRange.js.map +1 -0
  47. package/out/features/semanticTokens.d.ts +83 -0
  48. package/out/features/semanticTokens.d.ts.map +1 -0
  49. package/out/features/semanticTokens.js +370 -0
  50. package/out/features/semanticTokens.js.map +1 -0
  51. package/out/features/symbols.d.ts +47 -0
  52. package/out/features/symbols.d.ts.map +1 -0
  53. package/out/features/symbols.js +249 -0
  54. package/out/features/symbols.js.map +1 -0
  55. package/out/features/transactionAnalyzer.d.ts +63 -0
  56. package/out/features/transactionAnalyzer.d.ts.map +1 -0
  57. package/out/features/transactionAnalyzer.js +127 -0
  58. package/out/features/transactionAnalyzer.js.map +1 -0
  59. package/out/features/validator.d.ts +142 -0
  60. package/out/features/validator.d.ts.map +1 -0
  61. package/out/features/validator.js +633 -0
  62. package/out/features/validator.js.map +1 -0
  63. package/out/parser/ast.d.ts +37 -0
  64. package/out/parser/ast.d.ts.map +1 -0
  65. package/out/parser/ast.js +606 -0
  66. package/out/parser/ast.js.map +1 -0
  67. package/out/parser/includes.d.ts +25 -0
  68. package/out/parser/includes.d.ts.map +1 -0
  69. package/out/parser/includes.js +106 -0
  70. package/out/parser/includes.js.map +1 -0
  71. package/out/parser/index.d.ts +54 -0
  72. package/out/parser/index.d.ts.map +1 -0
  73. package/out/parser/index.js +146 -0
  74. package/out/parser/index.js.map +1 -0
  75. package/out/server/deps.d.ts +19 -0
  76. package/out/server/deps.d.ts.map +1 -0
  77. package/out/server/deps.js +77 -0
  78. package/out/server/deps.js.map +1 -0
  79. package/out/server/settings.d.ts +60 -0
  80. package/out/server/settings.d.ts.map +1 -0
  81. package/out/server/settings.js +110 -0
  82. package/out/server/settings.js.map +1 -0
  83. package/out/server.d.ts +3 -0
  84. package/out/server.d.ts.map +1 -0
  85. package/out/server.js +420 -0
  86. package/out/server.js.map +1 -0
  87. package/out/types.d.ts +84 -0
  88. package/out/types.d.ts.map +1 -0
  89. package/out/types.js +6 -0
  90. package/out/types.js.map +1 -0
  91. package/out/utils/index.d.ts +38 -0
  92. package/out/utils/index.d.ts.map +1 -0
  93. package/out/utils/index.js +89 -0
  94. package/out/utils/index.js.map +1 -0
  95. package/out/utils/uri.d.ts +32 -0
  96. package/out/utils/uri.d.ts.map +1 -0
  97. package/out/utils/uri.js +215 -0
  98. package/out/utils/uri.js.map +1 -0
  99. package/package.json +58 -0
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+ /**
3
+ * Symbol providers for document outline and workspace-wide search
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.workspaceSymbolProvider = exports.documentSymbolProvider = exports.WorkspaceSymbolProvider = exports.DocumentSymbolProvider = void 0;
7
+ const vscode_languageserver_1 = require("vscode-languageserver");
8
+ class DocumentSymbolProvider {
9
+ /**
10
+ * Provide document symbols for outline view
11
+ * Returns hierarchical symbols representing the structure of the document
12
+ */
13
+ provideDocumentSymbols(document, parsedDoc) {
14
+ const symbols = [];
15
+ const lines = document.getText().split('\n');
16
+ // Add directive symbols
17
+ for (const directive of parsedDoc.directives) {
18
+ // Only include directives from the current document
19
+ if (directive.sourceUri && directive.sourceUri !== document.uri) {
20
+ continue;
21
+ }
22
+ const line = this.findDirectiveLine(lines, directive);
23
+ if (line !== -1) {
24
+ const range = vscode_languageserver_1.Range.create(line, 0, line, lines[line].length);
25
+ const kind = this.getDirectiveSymbolKind(directive.type);
26
+ symbols.push({
27
+ name: `${directive.type} ${directive.value}`,
28
+ detail: directive.comment || undefined,
29
+ kind,
30
+ range,
31
+ selectionRange: range
32
+ });
33
+ }
34
+ }
35
+ // Add transaction symbols
36
+ for (const transaction of parsedDoc.transactions) {
37
+ // Only include transactions from the current document
38
+ if (transaction.sourceUri && transaction.sourceUri !== document.uri) {
39
+ continue;
40
+ }
41
+ const line = this.findTransactionLine(lines, transaction);
42
+ if (line !== -1) {
43
+ // Calculate the range of the entire transaction (including postings)
44
+ const endLine = this.findTransactionEndLine(lines, line);
45
+ const range = vscode_languageserver_1.Range.create(line, 0, endLine, lines[endLine].length);
46
+ const selectionRange = vscode_languageserver_1.Range.create(line, 0, line, lines[line].length);
47
+ const statusIcon = transaction.status === 'cleared' ? '* ' :
48
+ transaction.status === 'pending' ? '! ' : '';
49
+ const name = `${transaction.date} ${statusIcon}${transaction.description}`;
50
+ // Create child symbols for postings
51
+ const children = [];
52
+ for (const posting of transaction.postings) {
53
+ const postingLine = this.findPostingLine(lines, posting.account, line, endLine);
54
+ if (postingLine !== -1) {
55
+ const postingRange = vscode_languageserver_1.Range.create(postingLine, 0, postingLine, lines[postingLine].length);
56
+ const amountStr = posting.amount ? ` ${posting.amount.quantity}${posting.amount.commodity}` : '';
57
+ children.push({
58
+ name: posting.account + amountStr,
59
+ kind: vscode_languageserver_1.SymbolKind.Field,
60
+ range: postingRange,
61
+ selectionRange: postingRange
62
+ });
63
+ }
64
+ }
65
+ symbols.push({
66
+ name,
67
+ detail: transaction.code || undefined,
68
+ kind: vscode_languageserver_1.SymbolKind.Event,
69
+ range,
70
+ selectionRange,
71
+ children: children.length > 0 ? children : undefined
72
+ });
73
+ }
74
+ }
75
+ return symbols;
76
+ }
77
+ /**
78
+ * Find the line number of a directive in the document
79
+ */
80
+ findDirectiveLine(lines, directive) {
81
+ const pattern = new RegExp(`^${directive.type}\\s+${this.escapeRegex(directive.value)}`);
82
+ for (let i = 0; i < lines.length; i++) {
83
+ if (pattern.test(lines[i])) {
84
+ return i;
85
+ }
86
+ }
87
+ return -1;
88
+ }
89
+ /**
90
+ * Find the line number of a transaction in the document
91
+ */
92
+ findTransactionLine(lines, transaction) {
93
+ const datePattern = transaction.date.replace(/\//g, '\\/');
94
+ const statusChar = transaction.status === 'cleared' ? '\\*' :
95
+ transaction.status === 'pending' ? '!' : '';
96
+ const codeStr = transaction.code ? `\\(${this.escapeRegex(transaction.code)}\\)\\s*` : '';
97
+ const descPattern = this.escapeRegex(transaction.description);
98
+ const pattern = new RegExp(`^${datePattern}(?:\\s*=\\s*[0-9/-]+)?\\s*${statusChar}\\s*${codeStr}${descPattern}`);
99
+ for (let i = 0; i < lines.length; i++) {
100
+ if (pattern.test(lines[i])) {
101
+ return i;
102
+ }
103
+ }
104
+ return -1;
105
+ }
106
+ /**
107
+ * Find the end line of a transaction (last posting or comment)
108
+ */
109
+ findTransactionEndLine(lines, startLine) {
110
+ let endLine = startLine;
111
+ // Move to the next line and keep going while we have indented lines (postings/comments)
112
+ for (let i = startLine + 1; i < lines.length; i++) {
113
+ const line = lines[i];
114
+ // Empty line or unindented line marks the end
115
+ if (line.trim() === '' || !line.match(/^\s/)) {
116
+ break;
117
+ }
118
+ endLine = i;
119
+ }
120
+ return endLine;
121
+ }
122
+ /**
123
+ * Find a posting line within a transaction
124
+ */
125
+ findPostingLine(lines, account, startLine, endLine) {
126
+ const accountPattern = new RegExp(`^\\s+${this.escapeRegex(account)}`);
127
+ for (let i = startLine + 1; i <= endLine; i++) {
128
+ if (accountPattern.test(lines[i])) {
129
+ return i;
130
+ }
131
+ }
132
+ return -1;
133
+ }
134
+ /**
135
+ * Get the appropriate SymbolKind for a directive type
136
+ */
137
+ getDirectiveSymbolKind(directiveType) {
138
+ switch (directiveType) {
139
+ case 'account':
140
+ return vscode_languageserver_1.SymbolKind.Class;
141
+ case 'commodity':
142
+ return vscode_languageserver_1.SymbolKind.Number;
143
+ case 'payee':
144
+ return vscode_languageserver_1.SymbolKind.String;
145
+ case 'tag':
146
+ return vscode_languageserver_1.SymbolKind.Property;
147
+ case 'include':
148
+ return vscode_languageserver_1.SymbolKind.File;
149
+ case 'alias':
150
+ return vscode_languageserver_1.SymbolKind.Variable;
151
+ default:
152
+ return vscode_languageserver_1.SymbolKind.Constant;
153
+ }
154
+ }
155
+ /**
156
+ * Escape special regex characters
157
+ */
158
+ escapeRegex(str) {
159
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
160
+ }
161
+ }
162
+ exports.DocumentSymbolProvider = DocumentSymbolProvider;
163
+ class WorkspaceSymbolProvider {
164
+ /**
165
+ * Provide workspace-wide symbol search
166
+ * Returns flat list of symbols matching the query across all files
167
+ */
168
+ provideWorkspaceSymbols(query, parsedDoc) {
169
+ const symbols = [];
170
+ const lowerQuery = query.toLowerCase();
171
+ // Search accounts
172
+ for (const account of parsedDoc.accounts) {
173
+ if (account.name.toLowerCase().includes(lowerQuery)) {
174
+ const uri = account.sourceUri || '';
175
+ const line = account.line ?? 0;
176
+ const location = vscode_languageserver_1.Location.create(uri, vscode_languageserver_1.Range.create(line, 0, line, 0));
177
+ symbols.push({
178
+ name: account.name,
179
+ kind: vscode_languageserver_1.SymbolKind.Class,
180
+ location,
181
+ containerName: account.declared ? 'Declared Account' : 'Account'
182
+ });
183
+ }
184
+ }
185
+ // Search payees
186
+ for (const payee of parsedDoc.payees) {
187
+ if (payee.name.toLowerCase().includes(lowerQuery)) {
188
+ const uri = payee.sourceUri || '';
189
+ const line = payee.line ?? 0;
190
+ const location = vscode_languageserver_1.Location.create(uri, vscode_languageserver_1.Range.create(line, 0, line, 0));
191
+ symbols.push({
192
+ name: payee.name,
193
+ kind: vscode_languageserver_1.SymbolKind.String,
194
+ location,
195
+ containerName: payee.declared ? 'Declared Payee' : 'Payee'
196
+ });
197
+ }
198
+ }
199
+ // Search commodities
200
+ for (const commodity of parsedDoc.commodities) {
201
+ if (commodity.name.toLowerCase().includes(lowerQuery)) {
202
+ const uri = commodity.sourceUri || '';
203
+ const line = commodity.line ?? 0;
204
+ const location = vscode_languageserver_1.Location.create(uri, vscode_languageserver_1.Range.create(line, 0, line, 0));
205
+ symbols.push({
206
+ name: commodity.name,
207
+ kind: vscode_languageserver_1.SymbolKind.Number,
208
+ location,
209
+ containerName: commodity.declared ? 'Declared Commodity' : 'Commodity'
210
+ });
211
+ }
212
+ }
213
+ // Search tags
214
+ for (const tag of parsedDoc.tags) {
215
+ if (tag.name.toLowerCase().includes(lowerQuery)) {
216
+ const uri = tag.sourceUri || '';
217
+ const line = tag.line ?? 0;
218
+ const location = vscode_languageserver_1.Location.create(uri, vscode_languageserver_1.Range.create(line, 0, line, 0));
219
+ symbols.push({
220
+ name: tag.name,
221
+ kind: vscode_languageserver_1.SymbolKind.Property,
222
+ location,
223
+ containerName: tag.declared ? 'Declared Tag' : 'Tag'
224
+ });
225
+ }
226
+ }
227
+ // Search transactions by description
228
+ for (const transaction of parsedDoc.transactions) {
229
+ if (transaction.description.toLowerCase().includes(lowerQuery)) {
230
+ const uri = transaction.sourceUri || '';
231
+ const line = transaction.line ?? 0;
232
+ const location = vscode_languageserver_1.Location.create(uri, vscode_languageserver_1.Range.create(line, 0, line, 0));
233
+ const statusIcon = transaction.status === 'cleared' ? '* ' :
234
+ transaction.status === 'pending' ? '! ' : '';
235
+ symbols.push({
236
+ name: `${transaction.date} ${statusIcon}${transaction.description}`,
237
+ kind: vscode_languageserver_1.SymbolKind.Event,
238
+ location,
239
+ containerName: 'Transaction'
240
+ });
241
+ }
242
+ }
243
+ return symbols;
244
+ }
245
+ }
246
+ exports.WorkspaceSymbolProvider = WorkspaceSymbolProvider;
247
+ exports.documentSymbolProvider = new DocumentSymbolProvider();
248
+ exports.workspaceSymbolProvider = new WorkspaceSymbolProvider();
249
+ //# sourceMappingURL=symbols.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbols.js","sourceRoot":"","sources":["../../src/features/symbols.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Transaction history analyzer for smart completions
3
+ *
4
+ * Analyzes transaction patterns to provide intelligent suggestions:
5
+ * - Payee to account associations
6
+ * - Account usage frequency
7
+ * - Common amounts for payee/account combinations
8
+ */
9
+ import { ParsedDocument } from '../types';
10
+ export interface PayeeAccountPattern {
11
+ account: string;
12
+ frequency: number;
13
+ lastUsed?: Date;
14
+ }
15
+ export interface AccountFrequency {
16
+ account: string;
17
+ count: number;
18
+ lastUsed?: Date;
19
+ }
20
+ export interface AmountSuggestion {
21
+ amount: number;
22
+ commodity: string;
23
+ frequency: number;
24
+ }
25
+ export declare class TransactionAnalyzer {
26
+ private payeeToAccounts;
27
+ private accountFrequency;
28
+ private payeeAccountAmounts;
29
+ /**
30
+ * Analyze a parsed document to build pattern maps
31
+ */
32
+ analyze(parsed: ParsedDocument): void;
33
+ /**
34
+ * Analyze a single transaction
35
+ */
36
+ private analyzeTransaction;
37
+ /**
38
+ * Get accounts commonly used with a payee, sorted by frequency
39
+ */
40
+ getAccountsForPayee(payee: string, limit?: number): PayeeAccountPattern[];
41
+ /**
42
+ * Get all accounts sorted by usage frequency
43
+ */
44
+ getAccountsByFrequency(limit?: number): AccountFrequency[];
45
+ /**
46
+ * Get common amounts for a payee/account combination
47
+ */
48
+ getAmountSuggestionsForPayeeAccount(payee: string, account: string, commodity: string, limit?: number): AmountSuggestion[];
49
+ /**
50
+ * Get the most common payee/account pairs (for general insights)
51
+ */
52
+ getMostCommonPayeeAccountPairs(limit?: number): Array<{
53
+ payee: string;
54
+ account: string;
55
+ frequency: number;
56
+ }>;
57
+ /**
58
+ * Check if we have any pattern data
59
+ */
60
+ hasPatterns(): boolean;
61
+ }
62
+ export declare const transactionAnalyzer: TransactionAnalyzer;
63
+ //# sourceMappingURL=transactionAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transactionAnalyzer.d.ts","sourceRoot":"","sources":["../../src/features/transactionAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAe,MAAM,UAAU,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,eAAe,CAA+C;IACtE,OAAO,CAAC,gBAAgB,CAAkC;IAC1D,OAAO,CAAC,mBAAmB,CAA+C;IAE1E;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAYrC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA+B1B;;OAEG;IACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,mBAAmB,EAAE;IAe7E;;OAEG;IACH,sBAAsB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,EAAE;IAY1D;;OAEG;IACH,mCAAmC,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAU,GAChB,gBAAgB,EAAE;IAgBrB;;OAEG;IACH,8BAA8B,CAAC,KAAK,GAAE,MAAW,GAAG,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAehH;;OAEG;IACH,WAAW,IAAI,OAAO;CAGvB;AAED,eAAO,MAAM,mBAAmB,qBAA4B,CAAC"}
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ /**
3
+ * Transaction history analyzer for smart completions
4
+ *
5
+ * Analyzes transaction patterns to provide intelligent suggestions:
6
+ * - Payee to account associations
7
+ * - Account usage frequency
8
+ * - Common amounts for payee/account combinations
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.transactionAnalyzer = exports.TransactionAnalyzer = void 0;
12
+ class TransactionAnalyzer {
13
+ constructor() {
14
+ this.payeeToAccounts = new Map();
15
+ this.accountFrequency = new Map();
16
+ this.payeeAccountAmounts = new Map(); // payee:account -> amount -> count
17
+ }
18
+ /**
19
+ * Analyze a parsed document to build pattern maps
20
+ */
21
+ analyze(parsed) {
22
+ // Reset maps
23
+ this.payeeToAccounts.clear();
24
+ this.accountFrequency.clear();
25
+ this.payeeAccountAmounts.clear();
26
+ // Analyze each transaction
27
+ for (const transaction of parsed.transactions) {
28
+ this.analyzeTransaction(transaction);
29
+ }
30
+ }
31
+ /**
32
+ * Analyze a single transaction
33
+ */
34
+ analyzeTransaction(transaction) {
35
+ const payee = transaction.description;
36
+ if (!payee)
37
+ return;
38
+ // Track accounts used with this payee
39
+ for (const posting of transaction.postings) {
40
+ const account = posting.account;
41
+ // Update payee-to-account mapping
42
+ if (!this.payeeToAccounts.has(payee)) {
43
+ this.payeeToAccounts.set(payee, new Map());
44
+ }
45
+ const accountMap = this.payeeToAccounts.get(payee);
46
+ accountMap.set(account, (accountMap.get(account) || 0) + 1);
47
+ // Update account frequency
48
+ this.accountFrequency.set(account, (this.accountFrequency.get(account) || 0) + 1);
49
+ // Track amounts for this payee/account combination
50
+ if (posting.amount) {
51
+ const key = `${payee}:${account}`;
52
+ if (!this.payeeAccountAmounts.has(key)) {
53
+ this.payeeAccountAmounts.set(key, new Map());
54
+ }
55
+ const amountMap = this.payeeAccountAmounts.get(key);
56
+ const amount = posting.amount.quantity;
57
+ amountMap.set(amount, (amountMap.get(amount) || 0) + 1);
58
+ }
59
+ }
60
+ }
61
+ /**
62
+ * Get accounts commonly used with a payee, sorted by frequency
63
+ */
64
+ getAccountsForPayee(payee, limit = 10) {
65
+ const accountMap = this.payeeToAccounts.get(payee);
66
+ if (!accountMap)
67
+ return [];
68
+ const patterns = [];
69
+ for (const [account, frequency] of accountMap.entries()) {
70
+ patterns.push({ account, frequency });
71
+ }
72
+ // Sort by frequency (descending)
73
+ patterns.sort((a, b) => b.frequency - a.frequency);
74
+ return patterns.slice(0, limit);
75
+ }
76
+ /**
77
+ * Get all accounts sorted by usage frequency
78
+ */
79
+ getAccountsByFrequency(limit) {
80
+ const frequencies = [];
81
+ for (const [account, count] of this.accountFrequency.entries()) {
82
+ frequencies.push({ account, count });
83
+ }
84
+ // Sort by frequency (descending)
85
+ frequencies.sort((a, b) => b.count - a.count);
86
+ return limit ? frequencies.slice(0, limit) : frequencies;
87
+ }
88
+ /**
89
+ * Get common amounts for a payee/account combination
90
+ */
91
+ getAmountSuggestionsForPayeeAccount(payee, account, commodity, limit = 5) {
92
+ const key = `${payee}:${account}`;
93
+ const amountMap = this.payeeAccountAmounts.get(key);
94
+ if (!amountMap)
95
+ return [];
96
+ const suggestions = [];
97
+ for (const [amount, frequency] of amountMap.entries()) {
98
+ suggestions.push({ amount, commodity, frequency });
99
+ }
100
+ // Sort by frequency (descending)
101
+ suggestions.sort((a, b) => b.frequency - a.frequency);
102
+ return suggestions.slice(0, limit);
103
+ }
104
+ /**
105
+ * Get the most common payee/account pairs (for general insights)
106
+ */
107
+ getMostCommonPayeeAccountPairs(limit = 20) {
108
+ const pairs = [];
109
+ for (const [payee, accountMap] of this.payeeToAccounts.entries()) {
110
+ for (const [account, frequency] of accountMap.entries()) {
111
+ pairs.push({ payee, account, frequency });
112
+ }
113
+ }
114
+ // Sort by frequency (descending)
115
+ pairs.sort((a, b) => b.frequency - a.frequency);
116
+ return pairs.slice(0, limit);
117
+ }
118
+ /**
119
+ * Check if we have any pattern data
120
+ */
121
+ hasPatterns() {
122
+ return this.payeeToAccounts.size > 0;
123
+ }
124
+ }
125
+ exports.TransactionAnalyzer = TransactionAnalyzer;
126
+ exports.transactionAnalyzer = new TransactionAnalyzer();
127
+ //# sourceMappingURL=transactionAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transactionAnalyzer.js","sourceRoot":"","sources":["../../src/features/transactionAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Validator for hledger journal files
3
+ *
4
+ * Provides validation for:
5
+ * - Transaction balance
6
+ * - Undeclared items (accounts, payees, commodities, tags)
7
+ * - Missing amounts
8
+ * - Include directives
9
+ */
10
+ import { Diagnostic } from 'vscode-languageserver/node';
11
+ import { TextDocument } from 'vscode-languageserver-textdocument';
12
+ import { ParsedDocument } from '../types';
13
+ import { FileReader } from '../parser/index';
14
+ export interface ValidationResult {
15
+ diagnostics: Diagnostic[];
16
+ }
17
+ /**
18
+ * Validation settings
19
+ */
20
+ export interface ValidationSettings {
21
+ validation?: {
22
+ balance?: boolean;
23
+ missingAmounts?: boolean;
24
+ undeclaredAccounts?: boolean;
25
+ undeclaredPayees?: boolean;
26
+ undeclaredCommodities?: boolean;
27
+ undeclaredTags?: boolean;
28
+ dateOrdering?: boolean;
29
+ balanceAssertions?: boolean;
30
+ emptyTransactions?: boolean;
31
+ invalidDates?: boolean;
32
+ futureDates?: boolean;
33
+ emptyDescriptions?: boolean;
34
+ includeFiles?: boolean;
35
+ circularIncludes?: boolean;
36
+ };
37
+ severity?: {
38
+ undeclaredAccounts?: 'error' | 'warning' | 'information' | 'hint';
39
+ undeclaredPayees?: 'error' | 'warning' | 'information' | 'hint';
40
+ undeclaredCommodities?: 'error' | 'warning' | 'information' | 'hint';
41
+ undeclaredTags?: 'error' | 'warning' | 'information' | 'hint';
42
+ };
43
+ }
44
+ /**
45
+ * Options for validation
46
+ */
47
+ export interface ValidationOptions {
48
+ /**
49
+ * Base URI for resolving include paths
50
+ */
51
+ baseUri?: string;
52
+ /**
53
+ * Function to check if files exist
54
+ */
55
+ fileReader?: FileReader;
56
+ /**
57
+ * Validation settings from user configuration
58
+ */
59
+ settings?: ValidationSettings;
60
+ }
61
+ export declare class Validator {
62
+ /**
63
+ * Validate a parsed hledger document
64
+ */
65
+ validate(document: TextDocument, parsedDoc: ParsedDocument, options?: ValidationOptions): ValidationResult;
66
+ /**
67
+ * Validate transaction balance
68
+ * Transactions must balance (all amounts sum to zero per commodity)
69
+ */
70
+ private validateBalance;
71
+ /**
72
+ * Validate missing amounts in transaction
73
+ * At most one posting can omit an amount
74
+ */
75
+ private validateMissingAmounts;
76
+ /**
77
+ * Validate undeclared items
78
+ * Warn when accounts, payees, commodities, or tags are used but not declared
79
+ */
80
+ private validateUndeclaredItems;
81
+ /**
82
+ * Get the range for a transaction (first line only for now)
83
+ */
84
+ private getTransactionRange;
85
+ /**
86
+ * Find the first occurrence of a string in the document
87
+ */
88
+ private findFirstOccurrence;
89
+ /**
90
+ * Validate date ordering
91
+ * Warn if transactions are not in chronological order
92
+ */
93
+ private validateDateOrdering;
94
+ /**
95
+ * Format an amount with commodity according to declared format
96
+ */
97
+ private formatAmountWithCommodity;
98
+ /**
99
+ * Validate balance assertions
100
+ * Check if balance assertions match calculated balances
101
+ */
102
+ private validateBalanceAssertions;
103
+ /**
104
+ * Parse a date string to a Date object
105
+ */
106
+ private parseDate;
107
+ /**
108
+ * Find the range for a specific posting within a transaction
109
+ */
110
+ private findPostingRange;
111
+ /**
112
+ * Validate empty transactions
113
+ * Transactions must have at least 2 postings
114
+ */
115
+ private validateEmptyTransaction;
116
+ /**
117
+ * Validate date format
118
+ * Check for invalid dates like 2024-13-01 or 2024-02-30
119
+ */
120
+ private validateDateFormat;
121
+ /**
122
+ * Validate future dates
123
+ * Warn about transactions dated in the future
124
+ */
125
+ private validateFutureDate;
126
+ /**
127
+ * Validate empty descriptions
128
+ * Warn about transactions with no description/payee
129
+ */
130
+ private validateEmptyDescription;
131
+ /**
132
+ * Validate include directives
133
+ * Check for missing files and circular includes
134
+ */
135
+ private validateIncludeDirectives;
136
+ /**
137
+ * Check if a circular include exists by recursively following includes
138
+ */
139
+ private checkCircularInclude;
140
+ }
141
+ export declare const validator: Validator;
142
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/features/validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAsB,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EAAE,cAAc,EAAwB,MAAM,UAAU,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAI7C,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE;QACX,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,qBAAqB,CAAC,EAAE,OAAO,CAAC;QAChC,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,aAAa,GAAG,MAAM,CAAC;QAClE,gBAAgB,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,aAAa,GAAG,MAAM,CAAC;QAChE,qBAAqB,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,aAAa,GAAG,MAAM,CAAC;QACrE,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,aAAa,GAAG,MAAM,CAAC;KAC/D,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAED,qBAAa,SAAS;IACpB;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,gBAAgB;IAuF1G;;;OAGG;IACH,OAAO,CAAC,eAAe;IAwDvB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAiB9B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAiG/B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAsB3B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAkB3B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA8BjC;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAoDjC;;OAEG;IACH,OAAO,CAAC,SAAS;IAOjB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAiCxB;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAgBhC;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA2E1B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAwB1B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAgBhC;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAyEjC;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAmC7B;AAED,eAAO,MAAM,SAAS,WAAkB,CAAC"}