@lokascript/framework 2.3.1 → 2.5.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/dist/api/index.js +29 -516
- package/dist/api/index.js.map +1 -1
- package/dist/core/index.js +20 -128
- package/dist/core/index.js.map +1 -1
- package/dist/core/pattern-matching/index.js +19 -12
- package/dist/core/pattern-matching/index.js.map +1 -1
- package/dist/core/tokenization/index.js.map +1 -1
- package/dist/core/types.d.ts +7 -354
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +21 -129
- package/dist/core/types.js.map +1 -1
- package/dist/generation/diagnostics.d.ts +5 -115
- package/dist/generation/diagnostics.d.ts.map +1 -1
- package/dist/generation/index.js +20 -77
- package/dist/generation/index.js.map +1 -1
- package/dist/index.cjs +189 -1458
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +108 -1347
- package/dist/index.js.map +1 -1
- package/dist/interfaces/value-extractor.d.ts +20 -0
- package/dist/interfaces/value-extractor.d.ts.map +1 -1
- package/dist/ir/explicit-parser.d.ts +2 -83
- package/dist/ir/explicit-parser.d.ts.map +1 -1
- package/dist/ir/explicit-renderer.d.ts +2 -31
- package/dist/ir/explicit-renderer.d.ts.map +1 -1
- package/dist/ir/index.js +89 -1260
- package/dist/ir/index.js.map +1 -1
- package/dist/ir/protocol-json.d.ts +2 -70
- package/dist/ir/protocol-json.d.ts.map +1 -1
- package/dist/ir/references.d.ts +2 -16
- package/dist/ir/references.d.ts.map +1 -1
- package/dist/ir/types.d.ts +2 -148
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/parsing/index.js +19 -12
- package/dist/parsing/index.js.map +1 -1
- package/dist/schema/command-schema.d.ts +3 -92
- package/dist/schema/command-schema.d.ts.map +1 -1
- package/dist/schema/index.js +3 -20
- package/dist/schema/index.js.map +1 -1
- package/dist/testing/index.js +1066 -712
- package/dist/testing/index.js.map +1 -1
- package/package.json +6 -2
- package/src/core/types.ts +71 -600
- package/src/generation/diagnostics.ts +12 -233
- package/src/interfaces/value-extractor.ts +32 -0
- package/src/ir/explicit-parser.ts +12 -792
- package/src/ir/explicit-renderer.ts +2 -195
- package/src/ir/from-interchange.test.ts +91 -4
- package/src/ir/from-interchange.ts +59 -0
- package/src/ir/protocol-json.test.ts +16 -7
- package/src/ir/protocol-json.ts +9 -748
- package/src/ir/references.ts +2 -30
- package/src/ir/types.ts +18 -190
- package/src/schema/command-schema.ts +3 -134
|
@@ -1,239 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Structured Error Diagnostics
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - Severity levels (error, warning, info)
|
|
9
|
-
* - Machine-readable error codes
|
|
10
|
-
* - Source location tracking
|
|
11
|
-
* - Actionable suggestions
|
|
12
|
-
* - Programmatic fix lookup
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
// =============================================================================
|
|
16
|
-
// Diagnostic Types
|
|
17
|
-
// =============================================================================
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Severity level for a diagnostic.
|
|
21
|
-
*/
|
|
22
|
-
export type DiagnosticSeverity = 'error' | 'warning' | 'info';
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* A structured diagnostic message.
|
|
26
|
-
*
|
|
27
|
-
* Diagnostics provide rich error information beyond simple strings.
|
|
28
|
-
* They're used for parser errors, validation warnings, and hints.
|
|
29
|
-
*/
|
|
30
|
-
export interface Diagnostic {
|
|
31
|
-
/** Human-readable message */
|
|
32
|
-
readonly message: string;
|
|
33
|
-
|
|
34
|
-
/** Severity level */
|
|
35
|
-
readonly severity: DiagnosticSeverity;
|
|
36
|
-
|
|
37
|
-
/** Machine-readable code for programmatic handling (e.g., 'parse-error', 'missing-role') */
|
|
38
|
-
readonly code?: string;
|
|
39
|
-
|
|
40
|
-
/** 1-based line number in source */
|
|
41
|
-
readonly line?: number;
|
|
42
|
-
|
|
43
|
-
/** 0-based column offset in line */
|
|
44
|
-
readonly column?: number;
|
|
45
|
-
|
|
46
|
-
/** Original source text that triggered the diagnostic */
|
|
47
|
-
readonly source?: string;
|
|
48
|
-
|
|
49
|
-
/** Actionable suggestions for fixing the issue */
|
|
50
|
-
readonly suggestions?: readonly string[];
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Result of a diagnostic-aware validation.
|
|
55
|
-
*/
|
|
56
|
-
export interface DiagnosticResult {
|
|
57
|
-
/** Whether validation passed (no errors, though warnings/info may exist) */
|
|
58
|
-
readonly ok: boolean;
|
|
59
|
-
|
|
60
|
-
/** All diagnostics, including errors, warnings, and info */
|
|
61
|
-
readonly diagnostics: readonly Diagnostic[];
|
|
62
|
-
|
|
63
|
-
/** Convenience: count of each severity level */
|
|
64
|
-
readonly summary: DiagnosticSummary;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Summary counts by severity.
|
|
69
|
-
*/
|
|
70
|
-
export interface DiagnosticSummary {
|
|
71
|
-
readonly errors: number;
|
|
72
|
-
readonly warnings: number;
|
|
73
|
-
readonly infos: number;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// =============================================================================
|
|
77
|
-
// Diagnostic Collector
|
|
78
|
-
// =============================================================================
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Collects diagnostics during a parsing/validation/compilation pass.
|
|
82
|
-
*
|
|
83
|
-
* Use this in your domain's validate() or parse() to accumulate
|
|
84
|
-
* structured feedback instead of throwing on the first error.
|
|
85
|
-
*
|
|
86
|
-
* @example
|
|
87
|
-
* ```typescript
|
|
88
|
-
* const collector = createDiagnosticCollector();
|
|
89
|
-
*
|
|
90
|
-
* // During parsing:
|
|
91
|
-
* collector.error('Unknown command: foo', { code: 'unknown-command', line: 3 });
|
|
92
|
-
* collector.warning('Low confidence match', { code: 'low-confidence', line: 5 });
|
|
93
|
-
* collector.info('Consider using "select" instead of "get"', { line: 5 });
|
|
94
|
-
*
|
|
95
|
-
* // Get result:
|
|
96
|
-
* const result = collector.toResult();
|
|
97
|
-
* // { ok: false, diagnostics: [...], summary: { errors: 1, warnings: 1, infos: 1 } }
|
|
98
|
-
* ```
|
|
99
|
-
*/
|
|
100
|
-
export interface DiagnosticCollector {
|
|
101
|
-
/** Add an error diagnostic */
|
|
102
|
-
error(message: string, options?: DiagnosticOptions): void;
|
|
103
|
-
|
|
104
|
-
/** Add a warning diagnostic */
|
|
105
|
-
warning(message: string, options?: DiagnosticOptions): void;
|
|
106
|
-
|
|
107
|
-
/** Add an info diagnostic */
|
|
108
|
-
info(message: string, options?: DiagnosticOptions): void;
|
|
109
|
-
|
|
110
|
-
/** Add a diagnostic with explicit severity */
|
|
111
|
-
add(diagnostic: Diagnostic): void;
|
|
112
|
-
|
|
113
|
-
/** Whether any errors have been collected */
|
|
114
|
-
hasErrors(): boolean;
|
|
115
|
-
|
|
116
|
-
/** Get all collected diagnostics */
|
|
117
|
-
getDiagnostics(): readonly Diagnostic[];
|
|
118
|
-
|
|
119
|
-
/** Build a DiagnosticResult from collected diagnostics */
|
|
120
|
-
toResult(): DiagnosticResult;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Options for adding a diagnostic via the collector's convenience methods.
|
|
125
|
-
*/
|
|
126
|
-
export interface DiagnosticOptions {
|
|
127
|
-
readonly code?: string;
|
|
128
|
-
readonly line?: number;
|
|
129
|
-
readonly column?: number;
|
|
130
|
-
readonly source?: string;
|
|
131
|
-
readonly suggestions?: readonly string[];
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// =============================================================================
|
|
135
|
-
// Factory
|
|
136
|
-
// =============================================================================
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Create a new diagnostic collector.
|
|
4
|
+
* Re-exported from @lokascript/intent.
|
|
5
|
+
* This module is the framework's re-export point for the diagnostic types
|
|
6
|
+
* that live in the universal intent package.
|
|
140
7
|
*/
|
|
141
|
-
export function createDiagnosticCollector(): DiagnosticCollector {
|
|
142
|
-
const diagnostics: Diagnostic[] = [];
|
|
143
8
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
...(options?.code != null && { code: options.code }),
|
|
153
|
-
...(options?.line != null && { line: options.line }),
|
|
154
|
-
...(options?.column != null && { column: options.column }),
|
|
155
|
-
...(options?.source != null && { source: options.source }),
|
|
156
|
-
...(options?.suggestions != null &&
|
|
157
|
-
options.suggestions.length > 0 && { suggestions: options.suggestions }),
|
|
158
|
-
};
|
|
159
|
-
diagnostics.push(diag);
|
|
160
|
-
}
|
|
9
|
+
export type {
|
|
10
|
+
DiagnosticSeverity,
|
|
11
|
+
Diagnostic,
|
|
12
|
+
DiagnosticResult,
|
|
13
|
+
DiagnosticSummary,
|
|
14
|
+
DiagnosticCollector,
|
|
15
|
+
DiagnosticOptions,
|
|
16
|
+
} from '@lokascript/intent';
|
|
161
17
|
|
|
162
|
-
|
|
163
|
-
error(message, options) {
|
|
164
|
-
addWithSeverity('error', message, options);
|
|
165
|
-
},
|
|
166
|
-
|
|
167
|
-
warning(message, options) {
|
|
168
|
-
addWithSeverity('warning', message, options);
|
|
169
|
-
},
|
|
170
|
-
|
|
171
|
-
info(message, options) {
|
|
172
|
-
addWithSeverity('info', message, options);
|
|
173
|
-
},
|
|
174
|
-
|
|
175
|
-
add(diagnostic) {
|
|
176
|
-
diagnostics.push(diagnostic);
|
|
177
|
-
},
|
|
178
|
-
|
|
179
|
-
hasErrors() {
|
|
180
|
-
return diagnostics.some(d => d.severity === 'error');
|
|
181
|
-
},
|
|
182
|
-
|
|
183
|
-
getDiagnostics() {
|
|
184
|
-
return diagnostics;
|
|
185
|
-
},
|
|
186
|
-
|
|
187
|
-
toResult(): DiagnosticResult {
|
|
188
|
-
let errors = 0;
|
|
189
|
-
let warnings = 0;
|
|
190
|
-
let infos = 0;
|
|
191
|
-
for (const d of diagnostics) {
|
|
192
|
-
if (d.severity === 'error') errors++;
|
|
193
|
-
else if (d.severity === 'warning') warnings++;
|
|
194
|
-
else infos++;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return {
|
|
198
|
-
ok: errors === 0,
|
|
199
|
-
diagnostics,
|
|
200
|
-
summary: { errors, warnings, infos },
|
|
201
|
-
};
|
|
202
|
-
},
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// =============================================================================
|
|
207
|
-
// Helpers
|
|
208
|
-
// =============================================================================
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Create a diagnostic from an Error object.
|
|
212
|
-
* Useful for converting caught exceptions into structured diagnostics.
|
|
213
|
-
*/
|
|
214
|
-
export function fromError(
|
|
215
|
-
error: unknown,
|
|
216
|
-
options?: Omit<DiagnosticOptions, 'code'> & { code?: string }
|
|
217
|
-
): Diagnostic {
|
|
218
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
219
|
-
return {
|
|
220
|
-
message,
|
|
221
|
-
severity: 'error',
|
|
222
|
-
...(options?.code != null && { code: options.code }),
|
|
223
|
-
...(options?.line != null && { line: options.line }),
|
|
224
|
-
...(options?.column != null && { column: options.column }),
|
|
225
|
-
...(options?.source != null && { source: options.source }),
|
|
226
|
-
...(options?.suggestions != null &&
|
|
227
|
-
options.suggestions.length > 0 && { suggestions: options.suggestions }),
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Filter diagnostics by severity.
|
|
233
|
-
*/
|
|
234
|
-
export function filterBySeverity(
|
|
235
|
-
diagnostics: readonly Diagnostic[],
|
|
236
|
-
severity: DiagnosticSeverity
|
|
237
|
-
): readonly Diagnostic[] {
|
|
238
|
-
return diagnostics.filter(d => d.severity === severity);
|
|
239
|
-
}
|
|
18
|
+
export { createDiagnosticCollector, fromError, filterBySeverity } from '@lokascript/intent';
|
|
@@ -316,6 +316,38 @@ export class UnicodeIdentifierExtractor implements ValueExtractor {
|
|
|
316
316
|
}
|
|
317
317
|
}
|
|
318
318
|
|
|
319
|
+
/**
|
|
320
|
+
* Latin Extended identifier extractor — handles Latin-script languages with
|
|
321
|
+
* diacritics (Spanish ñ/á/é/í/ó/ú; French é/à/ù/ç; Turkish ç/ş/ı/ü/ğ/ö;
|
|
322
|
+
* Portuguese ã/õ; German ä/ö/ü/ß; etc).
|
|
323
|
+
*
|
|
324
|
+
* Use this in addition to (or instead of) the default `IdentifierExtractor`
|
|
325
|
+
* for any tokenizer whose language is Latin-script and may contain diacritic
|
|
326
|
+
* characters in identifiers. Without it, words like `añadir` tokenize as
|
|
327
|
+
* `["a", "ñadir"]` because the default ASCII extractor stops at `ñ` and the
|
|
328
|
+
* Unicode extractor only kicks in when a token *starts* with a non-ASCII
|
|
329
|
+
* character.
|
|
330
|
+
*
|
|
331
|
+
* Matches contiguous runs of `/[\p{L}\p{N}_-]/u` — any Unicode letter or
|
|
332
|
+
* number, plus underscore and hyphen.
|
|
333
|
+
*/
|
|
334
|
+
export class LatinExtendedIdentifierExtractor implements ValueExtractor {
|
|
335
|
+
readonly name = 'latin-extended-identifier';
|
|
336
|
+
|
|
337
|
+
canExtract(input: string, position: number): boolean {
|
|
338
|
+
return /\p{L}/u.test(input[position]);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
extract(input: string, position: number): ExtractionResult | null {
|
|
342
|
+
let end = position;
|
|
343
|
+
while (end < input.length && /[\p{L}\p{N}_-]/u.test(input[end])) {
|
|
344
|
+
end++;
|
|
345
|
+
}
|
|
346
|
+
if (end === position) return null;
|
|
347
|
+
return { value: input.slice(position, end), length: end - position };
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
319
351
|
/**
|
|
320
352
|
* Whitespace extractor - handles spaces, tabs, newlines.
|
|
321
353
|
*/
|