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.
- package/LICENSE +21 -0
- package/README.md +632 -0
- package/out/extension.d.ts +1 -0
- package/out/extension.d.ts.map +1 -0
- package/out/extension.js +2 -0
- package/out/extension.js.map +1 -0
- package/out/features/codeActions.d.ts +73 -0
- package/out/features/codeActions.d.ts.map +1 -0
- package/out/features/codeActions.js +417 -0
- package/out/features/codeActions.js.map +1 -0
- package/out/features/completion.d.ts +94 -0
- package/out/features/completion.d.ts.map +1 -0
- package/out/features/completion.js +323 -0
- package/out/features/completion.js.map +1 -0
- package/out/features/definition.d.ts +12 -0
- package/out/features/definition.d.ts.map +1 -0
- package/out/features/definition.js +61 -0
- package/out/features/definition.js.map +1 -0
- package/out/features/documentLinks.d.ts +17 -0
- package/out/features/documentLinks.d.ts.map +1 -0
- package/out/features/documentLinks.js +68 -0
- package/out/features/documentLinks.js.map +1 -0
- package/out/features/findReferences.d.ts +33 -0
- package/out/features/findReferences.d.ts.map +1 -0
- package/out/features/findReferences.js +79 -0
- package/out/features/findReferences.js.map +1 -0
- package/out/features/foldingRanges.d.ts +27 -0
- package/out/features/foldingRanges.d.ts.map +1 -0
- package/out/features/foldingRanges.js +111 -0
- package/out/features/foldingRanges.js.map +1 -0
- package/out/features/formatter.d.ts +70 -0
- package/out/features/formatter.d.ts.map +1 -0
- package/out/features/formatter.js +373 -0
- package/out/features/formatter.js.map +1 -0
- package/out/features/hover.d.ts +66 -0
- package/out/features/hover.d.ts.map +1 -0
- package/out/features/hover.js +387 -0
- package/out/features/hover.js.map +1 -0
- package/out/features/inlayHints.d.ts +43 -0
- package/out/features/inlayHints.d.ts.map +1 -0
- package/out/features/inlayHints.js +221 -0
- package/out/features/inlayHints.js.map +1 -0
- package/out/features/selectionRange.d.ts +47 -0
- package/out/features/selectionRange.d.ts.map +1 -0
- package/out/features/selectionRange.js +273 -0
- package/out/features/selectionRange.js.map +1 -0
- package/out/features/semanticTokens.d.ts +83 -0
- package/out/features/semanticTokens.d.ts.map +1 -0
- package/out/features/semanticTokens.js +370 -0
- package/out/features/semanticTokens.js.map +1 -0
- package/out/features/symbols.d.ts +47 -0
- package/out/features/symbols.d.ts.map +1 -0
- package/out/features/symbols.js +249 -0
- package/out/features/symbols.js.map +1 -0
- package/out/features/transactionAnalyzer.d.ts +63 -0
- package/out/features/transactionAnalyzer.d.ts.map +1 -0
- package/out/features/transactionAnalyzer.js +127 -0
- package/out/features/transactionAnalyzer.js.map +1 -0
- package/out/features/validator.d.ts +142 -0
- package/out/features/validator.d.ts.map +1 -0
- package/out/features/validator.js +633 -0
- package/out/features/validator.js.map +1 -0
- package/out/parser/ast.d.ts +37 -0
- package/out/parser/ast.d.ts.map +1 -0
- package/out/parser/ast.js +606 -0
- package/out/parser/ast.js.map +1 -0
- package/out/parser/includes.d.ts +25 -0
- package/out/parser/includes.d.ts.map +1 -0
- package/out/parser/includes.js +106 -0
- package/out/parser/includes.js.map +1 -0
- package/out/parser/index.d.ts +54 -0
- package/out/parser/index.d.ts.map +1 -0
- package/out/parser/index.js +146 -0
- package/out/parser/index.js.map +1 -0
- package/out/server/deps.d.ts +19 -0
- package/out/server/deps.d.ts.map +1 -0
- package/out/server/deps.js +77 -0
- package/out/server/deps.js.map +1 -0
- package/out/server/settings.d.ts +60 -0
- package/out/server/settings.d.ts.map +1 -0
- package/out/server/settings.js +110 -0
- package/out/server/settings.js.map +1 -0
- package/out/server.d.ts +3 -0
- package/out/server.d.ts.map +1 -0
- package/out/server.js +420 -0
- package/out/server.js.map +1 -0
- package/out/types.d.ts +84 -0
- package/out/types.d.ts.map +1 -0
- package/out/types.js +6 -0
- package/out/types.js.map +1 -0
- package/out/utils/index.d.ts +38 -0
- package/out/utils/index.d.ts.map +1 -0
- package/out/utils/index.js +89 -0
- package/out/utils/index.js.map +1 -0
- package/out/utils/uri.d.ts +32 -0
- package/out/utils/uri.d.ts.map +1 -0
- package/out/utils/uri.js +215 -0
- package/out/utils/uri.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Validator for hledger journal files
|
|
4
|
+
*
|
|
5
|
+
* Provides validation for:
|
|
6
|
+
* - Transaction balance
|
|
7
|
+
* - Undeclared items (accounts, payees, commodities, tags)
|
|
8
|
+
* - Missing amounts
|
|
9
|
+
* - Include directives
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.validator = exports.Validator = void 0;
|
|
13
|
+
const node_1 = require("vscode-languageserver/node");
|
|
14
|
+
const uri_1 = require("../utils/uri");
|
|
15
|
+
const settings_1 = require("../server/settings");
|
|
16
|
+
class Validator {
|
|
17
|
+
/**
|
|
18
|
+
* Validate a parsed hledger document
|
|
19
|
+
*/
|
|
20
|
+
validate(document, parsedDoc, options) {
|
|
21
|
+
const diagnostics = [];
|
|
22
|
+
const settings = options?.settings;
|
|
23
|
+
// Helper to check if validation is enabled
|
|
24
|
+
// Uses provided settings, or falls back to default settings
|
|
25
|
+
const isEnabled = (key) => {
|
|
26
|
+
// If settings are provided, use them
|
|
27
|
+
if (settings?.validation?.[key] !== undefined) {
|
|
28
|
+
return settings.validation[key] === true;
|
|
29
|
+
}
|
|
30
|
+
// Otherwise use defaults
|
|
31
|
+
return settings_1.defaultSettings.validation?.[key] ?? true;
|
|
32
|
+
};
|
|
33
|
+
// Validate each transaction
|
|
34
|
+
for (const transaction of parsedDoc.transactions) {
|
|
35
|
+
// Check balance
|
|
36
|
+
if (isEnabled('balance')) {
|
|
37
|
+
const balanceIssues = this.validateBalance(transaction, document);
|
|
38
|
+
diagnostics.push(...balanceIssues);
|
|
39
|
+
}
|
|
40
|
+
// Check missing amounts
|
|
41
|
+
if (isEnabled('missingAmounts')) {
|
|
42
|
+
const amountIssues = this.validateMissingAmounts(transaction, document);
|
|
43
|
+
diagnostics.push(...amountIssues);
|
|
44
|
+
}
|
|
45
|
+
// Check empty transactions
|
|
46
|
+
if (isEnabled('emptyTransactions')) {
|
|
47
|
+
const emptyTxnIssues = this.validateEmptyTransaction(transaction, document);
|
|
48
|
+
diagnostics.push(...emptyTxnIssues);
|
|
49
|
+
}
|
|
50
|
+
// Check invalid date formats
|
|
51
|
+
if (isEnabled('invalidDates')) {
|
|
52
|
+
const invalidDateIssues = this.validateDateFormat(transaction, document);
|
|
53
|
+
diagnostics.push(...invalidDateIssues);
|
|
54
|
+
}
|
|
55
|
+
// Check future dates
|
|
56
|
+
if (isEnabled('futureDates')) {
|
|
57
|
+
const futureDateIssues = this.validateFutureDate(transaction, document);
|
|
58
|
+
diagnostics.push(...futureDateIssues);
|
|
59
|
+
}
|
|
60
|
+
// Check empty descriptions
|
|
61
|
+
if (isEnabled('emptyDescriptions')) {
|
|
62
|
+
const emptyDescIssues = this.validateEmptyDescription(transaction, document);
|
|
63
|
+
diagnostics.push(...emptyDescIssues);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Check for undeclared items (each type can be enabled/disabled separately)
|
|
67
|
+
const undeclaredIssues = this.validateUndeclaredItems(document, parsedDoc, settings, isEnabled('undeclaredAccounts'), isEnabled('undeclaredPayees'), isEnabled('undeclaredCommodities'), isEnabled('undeclaredTags'));
|
|
68
|
+
diagnostics.push(...undeclaredIssues);
|
|
69
|
+
// Check date ordering
|
|
70
|
+
if (isEnabled('dateOrdering')) {
|
|
71
|
+
const dateOrderIssues = this.validateDateOrdering(parsedDoc.transactions, document);
|
|
72
|
+
diagnostics.push(...dateOrderIssues);
|
|
73
|
+
}
|
|
74
|
+
// Check balance assertions
|
|
75
|
+
if (isEnabled('balanceAssertions')) {
|
|
76
|
+
const assertionIssues = this.validateBalanceAssertions(parsedDoc.transactions, document, parsedDoc);
|
|
77
|
+
diagnostics.push(...assertionIssues);
|
|
78
|
+
}
|
|
79
|
+
// Check include directives
|
|
80
|
+
if (options?.fileReader && (isEnabled('includeFiles') || isEnabled('circularIncludes'))) {
|
|
81
|
+
const includeIssues = this.validateIncludeDirectives(document, parsedDoc, options, isEnabled('includeFiles'), isEnabled('circularIncludes'));
|
|
82
|
+
diagnostics.push(...includeIssues);
|
|
83
|
+
}
|
|
84
|
+
return { diagnostics };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Validate transaction balance
|
|
88
|
+
* Transactions must balance (all amounts sum to zero per commodity)
|
|
89
|
+
*/
|
|
90
|
+
validateBalance(transaction, document) {
|
|
91
|
+
const diagnostics = [];
|
|
92
|
+
// Group postings by commodity
|
|
93
|
+
const balances = new Map();
|
|
94
|
+
// Count how many postings have amounts
|
|
95
|
+
let postingsWithAmounts = 0;
|
|
96
|
+
for (const posting of transaction.postings) {
|
|
97
|
+
if (posting.amount) {
|
|
98
|
+
postingsWithAmounts++;
|
|
99
|
+
// If posting has a cost, use the cost commodity for balance calculation
|
|
100
|
+
if (posting.cost) {
|
|
101
|
+
const costCommodity = posting.cost.amount.commodity || '';
|
|
102
|
+
let costValue;
|
|
103
|
+
if (posting.cost.type === 'unit') {
|
|
104
|
+
// @ unitPrice: total cost = quantity * unitPrice
|
|
105
|
+
costValue = posting.amount.quantity * posting.cost.amount.quantity;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// @@ totalPrice: use total price directly
|
|
109
|
+
costValue = posting.cost.amount.quantity;
|
|
110
|
+
}
|
|
111
|
+
const current = balances.get(costCommodity) || 0;
|
|
112
|
+
balances.set(costCommodity, current + costValue);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// No cost notation, use the posting's commodity
|
|
116
|
+
const commodity = posting.amount.commodity || '';
|
|
117
|
+
const current = balances.get(commodity) || 0;
|
|
118
|
+
balances.set(commodity, current + posting.amount.quantity);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// If all postings have amounts, check if they balance
|
|
123
|
+
if (postingsWithAmounts === transaction.postings.length) {
|
|
124
|
+
for (const [commodity, balance] of balances.entries()) {
|
|
125
|
+
// Allow for small floating point errors
|
|
126
|
+
if (Math.abs(balance) > 0.005) {
|
|
127
|
+
const commodityStr = commodity ? ` ${commodity}` : '';
|
|
128
|
+
diagnostics.push({
|
|
129
|
+
severity: node_1.DiagnosticSeverity.Error,
|
|
130
|
+
range: this.getTransactionRange(transaction, document),
|
|
131
|
+
message: `Transaction does not balance: ${balance.toFixed(2)}${commodityStr} off`,
|
|
132
|
+
source: 'hledger'
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return diagnostics;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Validate missing amounts in transaction
|
|
141
|
+
* At most one posting can omit an amount
|
|
142
|
+
*/
|
|
143
|
+
validateMissingAmounts(transaction, document) {
|
|
144
|
+
const diagnostics = [];
|
|
145
|
+
const postingsWithoutAmounts = transaction.postings.filter(p => !p.amount);
|
|
146
|
+
if (postingsWithoutAmounts.length > 1) {
|
|
147
|
+
diagnostics.push({
|
|
148
|
+
severity: node_1.DiagnosticSeverity.Error,
|
|
149
|
+
range: this.getTransactionRange(transaction, document),
|
|
150
|
+
message: `Transaction has ${postingsWithoutAmounts.length} postings without amounts (maximum 1 allowed)`,
|
|
151
|
+
source: 'hledger'
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return diagnostics;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Validate undeclared items
|
|
158
|
+
* Warn when accounts, payees, commodities, or tags are used but not declared
|
|
159
|
+
*/
|
|
160
|
+
validateUndeclaredItems(document, parsedDoc, settings, checkAccounts = true, checkPayees = true, checkCommodities = true, checkTags = true) {
|
|
161
|
+
const diagnostics = [];
|
|
162
|
+
// Helper to convert severity string to DiagnosticSeverity
|
|
163
|
+
const getSeverity = (severityStr) => {
|
|
164
|
+
switch (severityStr) {
|
|
165
|
+
case 'error': return node_1.DiagnosticSeverity.Error;
|
|
166
|
+
case 'warning': return node_1.DiagnosticSeverity.Warning;
|
|
167
|
+
case 'information': return node_1.DiagnosticSeverity.Information;
|
|
168
|
+
case 'hint': return node_1.DiagnosticSeverity.Hint;
|
|
169
|
+
default: return node_1.DiagnosticSeverity.Warning; // default
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
// Check undeclared accounts (if enabled)
|
|
173
|
+
if (checkAccounts) {
|
|
174
|
+
const undeclaredAccounts = parsedDoc.accounts.filter(a => !a.declared);
|
|
175
|
+
for (const account of undeclaredAccounts) {
|
|
176
|
+
const range = this.findFirstOccurrence(document, account.name);
|
|
177
|
+
if (range) {
|
|
178
|
+
diagnostics.push({
|
|
179
|
+
severity: getSeverity(settings?.severity?.undeclaredAccounts),
|
|
180
|
+
range,
|
|
181
|
+
message: `Account "${account.name}" is used but not declared with 'account' directive`,
|
|
182
|
+
source: 'hledger',
|
|
183
|
+
code: 'undeclared-account',
|
|
184
|
+
data: { accountName: account.name }
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// Check undeclared payees (if enabled)
|
|
190
|
+
if (checkPayees) {
|
|
191
|
+
const undeclaredPayees = parsedDoc.payees.filter(p => !p.declared);
|
|
192
|
+
for (const payee of undeclaredPayees) {
|
|
193
|
+
const range = this.findFirstOccurrence(document, payee.name);
|
|
194
|
+
if (range) {
|
|
195
|
+
diagnostics.push({
|
|
196
|
+
severity: getSeverity(settings?.severity?.undeclaredPayees),
|
|
197
|
+
range,
|
|
198
|
+
message: `Payee "${payee.name}" is used but not declared with 'payee' directive`,
|
|
199
|
+
source: 'hledger',
|
|
200
|
+
code: 'undeclared-payee',
|
|
201
|
+
data: { payeeName: payee.name }
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Check undeclared commodities (if enabled)
|
|
207
|
+
if (checkCommodities) {
|
|
208
|
+
const undeclaredCommodities = parsedDoc.commodities.filter(c => !c.declared);
|
|
209
|
+
for (const commodity of undeclaredCommodities) {
|
|
210
|
+
const range = this.findFirstOccurrence(document, commodity.name);
|
|
211
|
+
if (range) {
|
|
212
|
+
diagnostics.push({
|
|
213
|
+
severity: getSeverity(settings?.severity?.undeclaredCommodities),
|
|
214
|
+
range,
|
|
215
|
+
message: `Commodity "${commodity.name}" is used but not declared with 'commodity' directive`,
|
|
216
|
+
source: 'hledger',
|
|
217
|
+
code: 'undeclared-commodity',
|
|
218
|
+
data: { commodityName: commodity.name }
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// Check undeclared tags (if enabled)
|
|
224
|
+
if (checkTags) {
|
|
225
|
+
const undeclaredTags = parsedDoc.tags.filter(t => !t.declared);
|
|
226
|
+
for (const tag of undeclaredTags) {
|
|
227
|
+
const range = this.findFirstOccurrence(document, tag.name + ':');
|
|
228
|
+
if (range) {
|
|
229
|
+
diagnostics.push({
|
|
230
|
+
severity: getSeverity(settings?.severity?.undeclaredTags || 'information'),
|
|
231
|
+
range,
|
|
232
|
+
message: `Tag "${tag.name}" is used but not declared with 'tag' directive`,
|
|
233
|
+
source: 'hledger',
|
|
234
|
+
code: 'undeclared-tag',
|
|
235
|
+
data: { tagName: tag.name }
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return diagnostics;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Get the range for a transaction (first line only for now)
|
|
244
|
+
*/
|
|
245
|
+
getTransactionRange(transaction, document) {
|
|
246
|
+
const text = document.getText();
|
|
247
|
+
const lines = text.split('\n');
|
|
248
|
+
// Find the transaction in the document
|
|
249
|
+
for (let i = 0; i < lines.length; i++) {
|
|
250
|
+
const line = lines[i];
|
|
251
|
+
if (line.includes(transaction.date) && line.includes(transaction.description)) {
|
|
252
|
+
return {
|
|
253
|
+
start: { line: i, character: 0 },
|
|
254
|
+
end: { line: i, character: line.length }
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// Fallback to first line if not found
|
|
259
|
+
return {
|
|
260
|
+
start: { line: 0, character: 0 },
|
|
261
|
+
end: { line: 0, character: 0 }
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Find the first occurrence of a string in the document
|
|
266
|
+
*/
|
|
267
|
+
findFirstOccurrence(document, searchStr) {
|
|
268
|
+
const text = document.getText();
|
|
269
|
+
const lines = text.split('\n');
|
|
270
|
+
for (let i = 0; i < lines.length; i++) {
|
|
271
|
+
const line = lines[i];
|
|
272
|
+
const index = line.indexOf(searchStr);
|
|
273
|
+
if (index !== -1) {
|
|
274
|
+
return {
|
|
275
|
+
start: { line: i, character: index },
|
|
276
|
+
end: { line: i, character: index + searchStr.length }
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Validate date ordering
|
|
284
|
+
* Warn if transactions are not in chronological order
|
|
285
|
+
*/
|
|
286
|
+
validateDateOrdering(transactions, document) {
|
|
287
|
+
const diagnostics = [];
|
|
288
|
+
for (let i = 1; i < transactions.length; i++) {
|
|
289
|
+
const prevDate = this.parseDate(transactions[i - 1].date);
|
|
290
|
+
const currDate = this.parseDate(transactions[i].date);
|
|
291
|
+
if (prevDate && currDate && currDate < prevDate) {
|
|
292
|
+
const range = this.getTransactionRange(transactions[i], document);
|
|
293
|
+
diagnostics.push({
|
|
294
|
+
severity: node_1.DiagnosticSeverity.Warning,
|
|
295
|
+
range,
|
|
296
|
+
message: `Transaction date ${transactions[i].date} is before previous transaction date ${transactions[i - 1].date}`,
|
|
297
|
+
source: 'hledger'
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return diagnostics;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Format an amount with commodity according to declared format
|
|
305
|
+
*/
|
|
306
|
+
formatAmountWithCommodity(quantity, commodityName, parsedDoc) {
|
|
307
|
+
// Find commodity format
|
|
308
|
+
const commodity = parsedDoc.commodities.find(c => c.name === commodityName);
|
|
309
|
+
if (!commodity?.format) {
|
|
310
|
+
// No format declared, use default: amount then commodity with space
|
|
311
|
+
return commodityName ? `${quantity.toFixed(2)} ${commodityName}` : quantity.toFixed(2);
|
|
312
|
+
}
|
|
313
|
+
const format = commodity.format;
|
|
314
|
+
const symbol = format.symbol || commodityName;
|
|
315
|
+
const symbolOnLeft = format.symbolOnLeft ?? false;
|
|
316
|
+
const spaceBetween = format.spaceBetween ?? true;
|
|
317
|
+
const space = spaceBetween ? ' ' : '';
|
|
318
|
+
// Use precision from format, or default to 2
|
|
319
|
+
const precision = format.precision ?? 2;
|
|
320
|
+
const formattedNumber = quantity.toFixed(precision);
|
|
321
|
+
if (symbolOnLeft) {
|
|
322
|
+
return `${symbol}${space}${formattedNumber}`;
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
return `${formattedNumber}${space}${symbol}`;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Validate balance assertions
|
|
330
|
+
* Check if balance assertions match calculated balances
|
|
331
|
+
*/
|
|
332
|
+
validateBalanceAssertions(transactions, document, parsedDoc) {
|
|
333
|
+
const diagnostics = [];
|
|
334
|
+
// Track running balances per account per commodity
|
|
335
|
+
const balances = new Map();
|
|
336
|
+
for (const transaction of transactions) {
|
|
337
|
+
for (const posting of transaction.postings) {
|
|
338
|
+
// Update running balance
|
|
339
|
+
// Note: Balance assertions check the ORIGINAL commodity (amount.commodity),
|
|
340
|
+
// not the cost commodity. So we always update balance in the amount's commodity.
|
|
341
|
+
if (posting.amount) {
|
|
342
|
+
const accountBalances = balances.get(posting.account) || new Map();
|
|
343
|
+
const commodity = posting.amount.commodity || '';
|
|
344
|
+
const currentBalance = accountBalances.get(commodity) || 0;
|
|
345
|
+
// Always use the original amount quantity for balance tracking,
|
|
346
|
+
// regardless of whether there's a cost notation
|
|
347
|
+
accountBalances.set(commodity, currentBalance + posting.amount.quantity);
|
|
348
|
+
balances.set(posting.account, accountBalances);
|
|
349
|
+
}
|
|
350
|
+
// Check assertion
|
|
351
|
+
if (posting.assertion) {
|
|
352
|
+
const accountBalances = balances.get(posting.account);
|
|
353
|
+
const commodity = posting.assertion.commodity || '';
|
|
354
|
+
const expectedBalance = posting.assertion.quantity;
|
|
355
|
+
const actualBalance = accountBalances?.get(commodity) || 0;
|
|
356
|
+
// Allow for small floating point errors
|
|
357
|
+
if (Math.abs(actualBalance - expectedBalance) > 0.005) {
|
|
358
|
+
const range = this.findPostingRange(transaction, posting, document);
|
|
359
|
+
const expectedFormatted = this.formatAmountWithCommodity(expectedBalance, commodity, parsedDoc);
|
|
360
|
+
const actualFormatted = this.formatAmountWithCommodity(actualBalance, commodity, parsedDoc);
|
|
361
|
+
diagnostics.push({
|
|
362
|
+
severity: node_1.DiagnosticSeverity.Error,
|
|
363
|
+
range,
|
|
364
|
+
message: `Balance assertion failed for ${posting.account}: expected ${expectedFormatted}, but calculated ${actualFormatted}`,
|
|
365
|
+
source: 'hledger'
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return diagnostics;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Parse a date string to a Date object
|
|
375
|
+
*/
|
|
376
|
+
parseDate(dateStr) {
|
|
377
|
+
// Handle both YYYY-MM-DD and YYYY/MM/DD formats
|
|
378
|
+
const normalized = dateStr.replace(/\//g, '-');
|
|
379
|
+
const date = new Date(normalized);
|
|
380
|
+
return isNaN(date.getTime()) ? null : date;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Find the range for a specific posting within a transaction
|
|
384
|
+
*/
|
|
385
|
+
findPostingRange(transaction, posting, document) {
|
|
386
|
+
const text = document.getText();
|
|
387
|
+
const lines = text.split('\n');
|
|
388
|
+
// Find the transaction, then find the posting
|
|
389
|
+
let inTransaction = false;
|
|
390
|
+
for (let i = 0; i < lines.length; i++) {
|
|
391
|
+
const line = lines[i];
|
|
392
|
+
// Check if this is our transaction
|
|
393
|
+
if (line.includes(transaction.date) && line.includes(transaction.description)) {
|
|
394
|
+
inTransaction = true;
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
// If we're in the transaction, look for the posting
|
|
398
|
+
if (inTransaction && line.trim().startsWith(posting.account)) {
|
|
399
|
+
return {
|
|
400
|
+
start: { line: i, character: 0 },
|
|
401
|
+
end: { line: i, character: line.length }
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
// Stop if we hit another transaction or empty line after being in a transaction
|
|
405
|
+
if (inTransaction && (!line.trim() || line.match(/^\d{4}[-/]\d{2}[-/]\d{2}/))) {
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
// Fallback to transaction range
|
|
410
|
+
return this.getTransactionRange(transaction, document);
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Validate empty transactions
|
|
414
|
+
* Transactions must have at least 2 postings
|
|
415
|
+
*/
|
|
416
|
+
validateEmptyTransaction(transaction, document) {
|
|
417
|
+
const diagnostics = [];
|
|
418
|
+
if (transaction.postings.length < 2) {
|
|
419
|
+
const range = this.getTransactionRange(transaction, document);
|
|
420
|
+
diagnostics.push({
|
|
421
|
+
severity: node_1.DiagnosticSeverity.Error,
|
|
422
|
+
range,
|
|
423
|
+
message: `Transaction has only ${transaction.postings.length} posting(s), minimum 2 required`,
|
|
424
|
+
source: 'hledger'
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
return diagnostics;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Validate date format
|
|
431
|
+
* Check for invalid dates like 2024-13-01 or 2024-02-30
|
|
432
|
+
*/
|
|
433
|
+
validateDateFormat(transaction, document) {
|
|
434
|
+
const diagnostics = [];
|
|
435
|
+
const normalized = transaction.date.replace(/\//g, '-');
|
|
436
|
+
const parts = normalized.split('-');
|
|
437
|
+
if (parts.length !== 3) {
|
|
438
|
+
const range = this.getTransactionRange(transaction, document);
|
|
439
|
+
diagnostics.push({
|
|
440
|
+
severity: node_1.DiagnosticSeverity.Error,
|
|
441
|
+
range,
|
|
442
|
+
message: `Invalid date format: ${transaction.date}`,
|
|
443
|
+
source: 'hledger'
|
|
444
|
+
});
|
|
445
|
+
return diagnostics;
|
|
446
|
+
}
|
|
447
|
+
const year = parseInt(parts[0], 10);
|
|
448
|
+
const month = parseInt(parts[1], 10);
|
|
449
|
+
const day = parseInt(parts[2], 10);
|
|
450
|
+
// Check if values are in valid ranges
|
|
451
|
+
if (month < 1 || month > 12) {
|
|
452
|
+
const range = this.getTransactionRange(transaction, document);
|
|
453
|
+
diagnostics.push({
|
|
454
|
+
severity: node_1.DiagnosticSeverity.Error,
|
|
455
|
+
range,
|
|
456
|
+
message: `Invalid month in date: ${transaction.date} (month must be 1-12)`,
|
|
457
|
+
source: 'hledger'
|
|
458
|
+
});
|
|
459
|
+
return diagnostics;
|
|
460
|
+
}
|
|
461
|
+
if (day < 1 || day > 31) {
|
|
462
|
+
const range = this.getTransactionRange(transaction, document);
|
|
463
|
+
diagnostics.push({
|
|
464
|
+
severity: node_1.DiagnosticSeverity.Error,
|
|
465
|
+
range,
|
|
466
|
+
message: `Invalid day in date: ${transaction.date} (day must be 1-31)`,
|
|
467
|
+
source: 'hledger'
|
|
468
|
+
});
|
|
469
|
+
return diagnostics;
|
|
470
|
+
}
|
|
471
|
+
// Now try to parse the date
|
|
472
|
+
const parsedDate = this.parseDate(transaction.date);
|
|
473
|
+
if (!parsedDate) {
|
|
474
|
+
const range = this.getTransactionRange(transaction, document);
|
|
475
|
+
diagnostics.push({
|
|
476
|
+
severity: node_1.DiagnosticSeverity.Error,
|
|
477
|
+
range,
|
|
478
|
+
message: `Invalid date format: ${transaction.date}`,
|
|
479
|
+
source: 'hledger'
|
|
480
|
+
});
|
|
481
|
+
return diagnostics;
|
|
482
|
+
}
|
|
483
|
+
// Check if the date components match the parsed date
|
|
484
|
+
// This catches cases like Feb 30 which get corrected to Mar 2
|
|
485
|
+
if (parsedDate.getFullYear() !== year ||
|
|
486
|
+
parsedDate.getMonth() + 1 !== month ||
|
|
487
|
+
parsedDate.getDate() !== day) {
|
|
488
|
+
const range = this.getTransactionRange(transaction, document);
|
|
489
|
+
diagnostics.push({
|
|
490
|
+
severity: node_1.DiagnosticSeverity.Error,
|
|
491
|
+
range,
|
|
492
|
+
message: `Invalid date: ${transaction.date} (date does not exist in calendar)`,
|
|
493
|
+
source: 'hledger'
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
return diagnostics;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Validate future dates
|
|
500
|
+
* Warn about transactions dated in the future
|
|
501
|
+
*/
|
|
502
|
+
validateFutureDate(transaction, document) {
|
|
503
|
+
const diagnostics = [];
|
|
504
|
+
const parsedDate = this.parseDate(transaction.date);
|
|
505
|
+
if (!parsedDate) {
|
|
506
|
+
return diagnostics; // Already handled by validateDateFormat
|
|
507
|
+
}
|
|
508
|
+
const today = new Date();
|
|
509
|
+
today.setHours(0, 0, 0, 0); // Reset time portion for date-only comparison
|
|
510
|
+
if (parsedDate > today) {
|
|
511
|
+
const range = this.getTransactionRange(transaction, document);
|
|
512
|
+
diagnostics.push({
|
|
513
|
+
severity: node_1.DiagnosticSeverity.Warning,
|
|
514
|
+
range,
|
|
515
|
+
message: `Transaction date ${transaction.date} is in the future`,
|
|
516
|
+
source: 'hledger'
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
return diagnostics;
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Validate empty descriptions
|
|
523
|
+
* Warn about transactions with no description/payee
|
|
524
|
+
*/
|
|
525
|
+
validateEmptyDescription(transaction, document) {
|
|
526
|
+
const diagnostics = [];
|
|
527
|
+
if (!transaction.description || transaction.description.trim() === '') {
|
|
528
|
+
const range = this.getTransactionRange(transaction, document);
|
|
529
|
+
diagnostics.push({
|
|
530
|
+
severity: node_1.DiagnosticSeverity.Warning,
|
|
531
|
+
range,
|
|
532
|
+
message: 'Transaction has no description',
|
|
533
|
+
source: 'hledger'
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
return diagnostics;
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Validate include directives
|
|
540
|
+
* Check for missing files and circular includes
|
|
541
|
+
*/
|
|
542
|
+
validateIncludeDirectives(document, parsedDoc, options, checkMissingFiles = true, checkCircularIncludes = true) {
|
|
543
|
+
const diagnostics = [];
|
|
544
|
+
const visited = new Set();
|
|
545
|
+
const baseUri = options.baseUri || document.uri;
|
|
546
|
+
const fileReader = options.fileReader;
|
|
547
|
+
// Find all include directives in the document
|
|
548
|
+
const includeDirectives = parsedDoc.directives.filter(d => d.type === 'include');
|
|
549
|
+
for (const directive of includeDirectives) {
|
|
550
|
+
const includePath = directive.value;
|
|
551
|
+
// Resolve the include path
|
|
552
|
+
const resolvedPath = (0, uri_1.resolveIncludePath)(includePath, baseUri);
|
|
553
|
+
// Check for duplicate includes in the same document
|
|
554
|
+
if (visited.has(resolvedPath)) {
|
|
555
|
+
const range = this.findFirstOccurrence(document, includePath);
|
|
556
|
+
if (range) {
|
|
557
|
+
diagnostics.push({
|
|
558
|
+
severity: node_1.DiagnosticSeverity.Warning,
|
|
559
|
+
range,
|
|
560
|
+
message: `Duplicate include: ${includePath}`,
|
|
561
|
+
source: 'hledger'
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
visited.add(resolvedPath);
|
|
567
|
+
// Check if file exists (if enabled)
|
|
568
|
+
const includeDoc = fileReader(resolvedPath);
|
|
569
|
+
if (!includeDoc && checkMissingFiles) {
|
|
570
|
+
// File doesn't exist
|
|
571
|
+
const range = this.findFirstOccurrence(document, includePath);
|
|
572
|
+
if (range) {
|
|
573
|
+
diagnostics.push({
|
|
574
|
+
severity: node_1.DiagnosticSeverity.Error,
|
|
575
|
+
range,
|
|
576
|
+
message: `Include file not found: ${includePath}`,
|
|
577
|
+
source: 'hledger'
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
// Check for circular includes (if enabled and file exists)
|
|
582
|
+
if (includeDoc && checkCircularIncludes) {
|
|
583
|
+
const circularCheck = this.checkCircularInclude(document.uri, includeDoc, fileReader, new Set([baseUri, resolvedPath]));
|
|
584
|
+
if (circularCheck) {
|
|
585
|
+
const range = this.findFirstOccurrence(document, includePath);
|
|
586
|
+
if (range) {
|
|
587
|
+
diagnostics.push({
|
|
588
|
+
severity: node_1.DiagnosticSeverity.Error,
|
|
589
|
+
range,
|
|
590
|
+
message: `Circular include detected: ${includePath}`,
|
|
591
|
+
source: 'hledger'
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
return diagnostics;
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Check if a circular include exists by recursively following includes
|
|
601
|
+
*/
|
|
602
|
+
checkCircularInclude(targetUri, document, fileReader, visited) {
|
|
603
|
+
const text = document.getText();
|
|
604
|
+
const lines = text.split('\n');
|
|
605
|
+
for (const line of lines) {
|
|
606
|
+
const trimmedLine = line.trim();
|
|
607
|
+
if (trimmedLine.startsWith('include ')) {
|
|
608
|
+
const includePath = trimmedLine.substring(8).trim();
|
|
609
|
+
const resolvedPath = (0, uri_1.resolveIncludePath)(includePath, document.uri);
|
|
610
|
+
// Check if this include points back to the target
|
|
611
|
+
if (resolvedPath === targetUri) {
|
|
612
|
+
return true;
|
|
613
|
+
}
|
|
614
|
+
// Avoid infinite recursion
|
|
615
|
+
if (visited.has(resolvedPath)) {
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
visited.add(resolvedPath);
|
|
619
|
+
// Recursively check this file
|
|
620
|
+
const includeDoc = fileReader(resolvedPath);
|
|
621
|
+
if (includeDoc) {
|
|
622
|
+
if (this.checkCircularInclude(targetUri, includeDoc, fileReader, visited)) {
|
|
623
|
+
return true;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
return false;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
exports.Validator = Validator;
|
|
632
|
+
exports.validator = new Validator();
|
|
633
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/features/validator.ts"],"names":[],"mappings":"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"}
|