@nowline/browser 0.4.2 → 0.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/diagnostic-row.d.ts +3 -32
- package/dist/diagnostic-row.d.ts.map +1 -1
- package/dist/diagnostic-row.js +5 -31
- package/dist/diagnostic-row.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +14 -9
- package/dist/pipeline.js.map +1 -1
- package/package.json +4 -4
- package/src/diagnostic-row.ts +14 -55
- package/src/index.ts +4 -1
- package/src/pipeline.ts +12 -9
package/dist/diagnostic-row.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type LangiumLikeDiagnostic, type LexerErrorLike, type ParserErrorLike, type ResolveDiagnostic } from '@nowline/core';
|
|
2
2
|
/**
|
|
3
3
|
* JSON-friendly diagnostic shape consumed by browser preview surfaces.
|
|
4
4
|
*
|
|
@@ -18,37 +18,9 @@ export interface DiagnosticRow {
|
|
|
18
18
|
line: number;
|
|
19
19
|
column: number;
|
|
20
20
|
}
|
|
21
|
-
/** Minimal LSP-style diagnostic shape. Mirrors `LangiumLikeDiagnostic` in the CLI. */
|
|
22
|
-
export interface LangiumLikeDiagnostic {
|
|
23
|
-
message: string;
|
|
24
|
-
severity?: number;
|
|
25
|
-
code?: string | number;
|
|
26
|
-
range?: {
|
|
27
|
-
start: {
|
|
28
|
-
line: number;
|
|
29
|
-
character: number;
|
|
30
|
-
};
|
|
31
|
-
end: {
|
|
32
|
-
line: number;
|
|
33
|
-
character: number;
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
interface ChevrotainParserError {
|
|
38
|
-
message: string;
|
|
39
|
-
token?: {
|
|
40
|
-
startLine?: number;
|
|
41
|
-
startColumn?: number;
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
interface ChevrotainLexerError {
|
|
45
|
-
message: string;
|
|
46
|
-
line?: number;
|
|
47
|
-
column?: number;
|
|
48
|
-
}
|
|
49
21
|
export declare function fromLangiumDiagnostic(diag: LangiumLikeDiagnostic, file: string): DiagnosticRow;
|
|
50
|
-
export declare function fromParserError(err:
|
|
51
|
-
export declare function fromLexerError(err:
|
|
22
|
+
export declare function fromParserError(err: ParserErrorLike, file: string): DiagnosticRow;
|
|
23
|
+
export declare function fromLexerError(err: LexerErrorLike, file: string): DiagnosticRow;
|
|
52
24
|
/**
|
|
53
25
|
* Adapt a `ResolveDiagnostic` (cross-file include resolution). The line
|
|
54
26
|
* is 0-based in the resolver (it comes from a CST range) and may be
|
|
@@ -64,5 +36,4 @@ export declare function fromResolveDiagnostic(diag: ResolveDiagnostic): Diagnost
|
|
|
64
36
|
* severity to `error` before passing the result on.
|
|
65
37
|
*/
|
|
66
38
|
export declare function fromRenderWarning(message: string, file: string, severity?: DiagnosticRow['severity']): DiagnosticRow;
|
|
67
|
-
export {};
|
|
68
39
|
//# sourceMappingURL=diagnostic-row.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostic-row.d.ts","sourceRoot":"","sources":["../src/diagnostic-row.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"diagnostic-row.d.ts","sourceRoot":"","sources":["../src/diagnostic-row.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAEzB,MAAM,eAAe,CAAC;AAEvB;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC1B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAa9F;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CASjF;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAS/E;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa,CAS5E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,aAAa,CAAC,UAAU,CAAa,GAChD,aAAa,CASf"}
|
package/dist/diagnostic-row.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import { extractSuggestion, resolveDiagnosticCode, } from '@nowline/core';
|
|
2
2
|
export function fromLangiumDiagnostic(diag, file) {
|
|
3
3
|
return {
|
|
4
4
|
severity: diag.severity === 2 ? 'warning' : 'error',
|
|
5
|
-
code
|
|
5
|
+
// resolveDiagnosticCode prefers the stable validator code (NL.Exxxx)
|
|
6
|
+
// carried in `data` so the preview table matches the CLI / Problems
|
|
7
|
+
// panel, then falls back to Langium's `code`, then a message heuristic.
|
|
8
|
+
code: resolveDiagnosticCode(diag),
|
|
6
9
|
message: diag.message,
|
|
7
10
|
suggestion: extractSuggestion(diag.message),
|
|
8
11
|
file,
|
|
@@ -63,33 +66,4 @@ export function fromRenderWarning(message, file, severity = 'warning') {
|
|
|
63
66
|
column: 1,
|
|
64
67
|
};
|
|
65
68
|
}
|
|
66
|
-
function diagnosticCode(diag) {
|
|
67
|
-
if (typeof diag.code === 'string' && diag.code !== '')
|
|
68
|
-
return diag.code;
|
|
69
|
-
if (typeof diag.code === 'number')
|
|
70
|
-
return String(diag.code);
|
|
71
|
-
return inferCodeFromMessage(diag.message);
|
|
72
|
-
}
|
|
73
|
-
function inferCodeFromMessage(message) {
|
|
74
|
-
const lower = message.toLowerCase();
|
|
75
|
-
if (lower.includes('duplicate identifier'))
|
|
76
|
-
return 'duplicate-identifier';
|
|
77
|
-
if (lower.includes('unknown reference') || lower.includes('did you mean'))
|
|
78
|
-
return 'unknown-reference';
|
|
79
|
-
if (lower.includes('circular'))
|
|
80
|
-
return 'circular-dependency';
|
|
81
|
-
if (lower.includes('requires') && lower.includes('date:'))
|
|
82
|
-
return 'missing-date';
|
|
83
|
-
if (lower.includes('duration'))
|
|
84
|
-
return 'duration';
|
|
85
|
-
if (lower.includes('include'))
|
|
86
|
-
return 'include';
|
|
87
|
-
if (lower.includes('indent'))
|
|
88
|
-
return 'indentation';
|
|
89
|
-
return 'validation';
|
|
90
|
-
}
|
|
91
|
-
function extractSuggestion(message) {
|
|
92
|
-
const match = message.match(DID_YOU_MEAN_RE);
|
|
93
|
-
return match ? match[1].trim() : undefined;
|
|
94
|
-
}
|
|
95
69
|
//# sourceMappingURL=diagnostic-row.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostic-row.js","sourceRoot":"","sources":["../src/diagnostic-row.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"diagnostic-row.js","sourceRoot":"","sources":["../src/diagnostic-row.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,iBAAiB,EAKjB,qBAAqB,GACxB,MAAM,eAAe,CAAC;AAsBvB,MAAM,UAAU,qBAAqB,CAAC,IAA2B,EAAE,IAAY;IAC3E,OAAO;QACH,QAAQ,EAAE,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;QACnD,qEAAqE;QACrE,oEAAoE;QACpE,wEAAwE;QACxE,IAAI,EAAE,qBAAqB,CAAC,IAAI,CAAC;QACjC,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,UAAU,EAAE,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;QAC3C,IAAI;QACJ,IAAI,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC;QACvC,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC;KACjD,CAAC;AACN,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAoB,EAAE,IAAY;IAC9D,OAAO;QACH,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,IAAI;QACJ,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC;QAC/B,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE,WAAW,IAAI,CAAC;KACtC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAmB,EAAE,IAAY;IAC5D,OAAO;QACH,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,IAAI;QACJ,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC;QACnB,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,CAAC;KAC1B,CAAC;AACN,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAuB;IACzD,OAAO;QACH,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,IAAI,EAAE,IAAI,CAAC,UAAU;QACrB,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACjD,MAAM,EAAE,CAAC;KACZ,CAAC;AACN,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC7B,OAAe,EACf,IAAY,EACZ,WAAsC,SAAS;IAE/C,OAAO;QACH,QAAQ;QACR,IAAI,EAAE,gBAAgB;QACtB,OAAO;QACP,IAAI;QACJ,IAAI,EAAE,CAAC;QACP,MAAM,EAAE,CAAC;KACZ,CAAC;AACN,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type { LangiumLikeDiagnostic } from '@nowline/core';
|
|
2
|
+
export { type DiagnosticRow, fromLangiumDiagnostic, fromLexerError, fromParserError, fromRenderWarning, fromResolveDiagnostic, } from './diagnostic-row.js';
|
|
2
3
|
export { showcaseSource } from './generated/showcase.js';
|
|
3
4
|
export { isNoOpIncludeDiagnosticMessage, NOWLINE_BROWSER_NOOP_INCLUDE_TAG, noOpIncludeReadFile, type SkippedInclude, } from './no-op-include-resolver.js';
|
|
4
5
|
export { __resetBrowserPipelineForTests, DEFAULT_SYNTHETIC_PATH, type ParseOptions, type ParseResult, parseSource, type RenderOptions, type RenderResult, renderSource, } from './pipeline.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EACH,KAAK,aAAa,EAClB,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,qBAAqB,GACxB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACH,8BAA8B,EAC9B,gCAAgC,EAChC,mBAAmB,EACnB,KAAK,cAAc,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACH,8BAA8B,EAC9B,sBAAsB,EACtB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,YAAY,GACf,MAAM,eAAe,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,uEAAuE;AACvE,sEAAsE;AACtE,sEAAsE;AACtE,sDAAsD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,uEAAuE;AACvE,sEAAsE;AACtE,sEAAsE;AACtE,sDAAsD;AAMtD,OAAO,EAEH,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,qBAAqB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,uEAAuE;AACvE,uEAAuE;AACvE,2CAA2C;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACH,8BAA8B,EAC9B,gCAAgC,EAChC,mBAAmB,GAEtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACH,8BAA8B,EAC9B,sBAAsB,EAGtB,WAAW,EAGX,YAAY,GACf,MAAM,eAAe,CAAC"}
|
package/dist/pipeline.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAmBA,OAAO,
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAmBA,OAAO,EAGH,KAAK,WAAW,EAGnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,KAAK,aAAa,EAAa,MAAM,mBAAmB,CAAC;AAElE,OAAO,EACH,KAAK,aAAa,EAMrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGH,KAAK,cAAc,EACtB,MAAM,6BAA6B,CAAC;AAErC;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,4BAA4B,CAAC;AAEhE,MAAM,WAAW,YAAY;IACzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,WAAW;IACxB,GAAG,EAAE,WAAW,CAAC;IACjB,WAAW,EAAE,aAAa,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IAC/C,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACpB,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,mEAAmE;IACnE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;CACjC;AAED,MAAM,MAAM,YAAY,GAClB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,WAAW,EAAE,aAAa,EAAE,CAAA;CAAE,CAAC;AAqB5D;;;;;GAKG;AACH,wBAAsB,WAAW,CAC7B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,YAAiB,GAC3B,OAAO,CAAC,WAAW,CAAC,CAqBtB;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,aAAkB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAyDvB;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAGrD"}
|
package/dist/pipeline.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
//
|
|
17
17
|
// The package itself imports zero `node:*` modules so the embed esbuild
|
|
18
18
|
// bundle stays free of any Node literal even before tree-shaking.
|
|
19
|
-
import { createNowlineServices, resolveIncludes, } from '@nowline/core';
|
|
19
|
+
import { collectDocumentDiagnostics, createNowlineServices, resolveIncludes, } from '@nowline/core';
|
|
20
20
|
import { layoutRoadmap } from '@nowline/layout';
|
|
21
21
|
import { renderSvg } from '@nowline/renderer';
|
|
22
22
|
import { URI } from 'langium';
|
|
@@ -52,15 +52,20 @@ export async function parseSource(source, options = {}) {
|
|
|
52
52
|
const docFactory = services.shared.workspace.LangiumDocumentFactory;
|
|
53
53
|
const doc = docFactory.fromString(source, freshUri());
|
|
54
54
|
await services.shared.workspace.DocumentBuilder.build([doc], { validation: true });
|
|
55
|
+
// collectDocumentDiagnostics owns the de-dup: Langium re-folds lexer +
|
|
56
|
+
// parser errors into doc.diagnostics, so the shared collector skips those
|
|
57
|
+
// copies and we map each origin to a row here.
|
|
55
58
|
const diagnostics = [];
|
|
56
|
-
for (const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
for (const raw of collectDocumentDiagnostics(doc)) {
|
|
60
|
+
if (raw.origin === 'lexer') {
|
|
61
|
+
diagnostics.push(fromLexerError(raw.error, filePath));
|
|
62
|
+
}
|
|
63
|
+
else if (raw.origin === 'parser') {
|
|
64
|
+
diagnostics.push(fromParserError(raw.error, filePath));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
diagnostics.push(fromLangiumDiagnostic(raw.diagnostic, filePath));
|
|
68
|
+
}
|
|
64
69
|
}
|
|
65
70
|
return { ast: doc.parseResult.value, diagnostics };
|
|
66
71
|
}
|
package/dist/pipeline.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,mEAAmE;AACnE,mBAAmB;AACnB,EAAE;AACF,uEAAuE;AACvE,wEAAwE;AACxE,sEAAsE;AACtE,yEAAyE;AACzE,yDAAyD;AACzD,EAAE;AACF,mEAAmE;AACnE,kEAAkE;AAClE,yEAAyE;AACzE,kEAAkE;AAClE,wEAAwE;AACxE,EAAE;AACF,wEAAwE;AACxE,kEAAkE;AAElE,OAAO,EACH,qBAAqB,EAGrB,eAAe,GAClB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAkB,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAsB,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAEH,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nowline/browser",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Browser-safe Nowline pipeline: parse + validate + resolve includes + layout + render with pluggable I/O hooks. Consumed by @nowline/embed, the VS Code preview, and any third-party browser tool.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"engines": {
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"langium": "~4.2.4",
|
|
42
|
-
"@nowline/
|
|
43
|
-
"@nowline/layout": "0.
|
|
44
|
-
"@nowline/
|
|
42
|
+
"@nowline/core": "0.5.0",
|
|
43
|
+
"@nowline/layout": "0.5.0",
|
|
44
|
+
"@nowline/renderer": "0.5.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/node": "^25.9.1",
|
package/src/diagnostic-row.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
extractSuggestion,
|
|
3
|
+
type LangiumLikeDiagnostic,
|
|
4
|
+
type LexerErrorLike,
|
|
5
|
+
type ParserErrorLike,
|
|
6
|
+
type ResolveDiagnostic,
|
|
7
|
+
resolveDiagnosticCode,
|
|
8
|
+
} from '@nowline/core';
|
|
2
9
|
|
|
3
10
|
/**
|
|
4
11
|
* JSON-friendly diagnostic shape consumed by browser preview surfaces.
|
|
@@ -20,37 +27,13 @@ export interface DiagnosticRow {
|
|
|
20
27
|
column: number;
|
|
21
28
|
}
|
|
22
29
|
|
|
23
|
-
/** Minimal LSP-style diagnostic shape. Mirrors `LangiumLikeDiagnostic` in the CLI. */
|
|
24
|
-
export interface LangiumLikeDiagnostic {
|
|
25
|
-
message: string;
|
|
26
|
-
severity?: number;
|
|
27
|
-
code?: string | number;
|
|
28
|
-
range?: {
|
|
29
|
-
start: { line: number; character: number };
|
|
30
|
-
end: { line: number; character: number };
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
interface ChevrotainParserError {
|
|
35
|
-
message: string;
|
|
36
|
-
token?: {
|
|
37
|
-
startLine?: number;
|
|
38
|
-
startColumn?: number;
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
interface ChevrotainLexerError {
|
|
43
|
-
message: string;
|
|
44
|
-
line?: number;
|
|
45
|
-
column?: number;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const DID_YOU_MEAN_RE = /did you mean ['"]?([^'"?]+)['"]?\??/i;
|
|
49
|
-
|
|
50
30
|
export function fromLangiumDiagnostic(diag: LangiumLikeDiagnostic, file: string): DiagnosticRow {
|
|
51
31
|
return {
|
|
52
32
|
severity: diag.severity === 2 ? 'warning' : 'error',
|
|
53
|
-
code
|
|
33
|
+
// resolveDiagnosticCode prefers the stable validator code (NL.Exxxx)
|
|
34
|
+
// carried in `data` so the preview table matches the CLI / Problems
|
|
35
|
+
// panel, then falls back to Langium's `code`, then a message heuristic.
|
|
36
|
+
code: resolveDiagnosticCode(diag),
|
|
54
37
|
message: diag.message,
|
|
55
38
|
suggestion: extractSuggestion(diag.message),
|
|
56
39
|
file,
|
|
@@ -59,7 +42,7 @@ export function fromLangiumDiagnostic(diag: LangiumLikeDiagnostic, file: string)
|
|
|
59
42
|
};
|
|
60
43
|
}
|
|
61
44
|
|
|
62
|
-
export function fromParserError(err:
|
|
45
|
+
export function fromParserError(err: ParserErrorLike, file: string): DiagnosticRow {
|
|
63
46
|
return {
|
|
64
47
|
severity: 'error',
|
|
65
48
|
code: 'parse-error',
|
|
@@ -70,7 +53,7 @@ export function fromParserError(err: ChevrotainParserError, file: string): Diagn
|
|
|
70
53
|
};
|
|
71
54
|
}
|
|
72
55
|
|
|
73
|
-
export function fromLexerError(err:
|
|
56
|
+
export function fromLexerError(err: LexerErrorLike, file: string): DiagnosticRow {
|
|
74
57
|
return {
|
|
75
58
|
severity: 'error',
|
|
76
59
|
code: 'lex-error',
|
|
@@ -119,27 +102,3 @@ export function fromRenderWarning(
|
|
|
119
102
|
column: 1,
|
|
120
103
|
};
|
|
121
104
|
}
|
|
122
|
-
|
|
123
|
-
function diagnosticCode(diag: LangiumLikeDiagnostic): string {
|
|
124
|
-
if (typeof diag.code === 'string' && diag.code !== '') return diag.code;
|
|
125
|
-
if (typeof diag.code === 'number') return String(diag.code);
|
|
126
|
-
return inferCodeFromMessage(diag.message);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function inferCodeFromMessage(message: string): string {
|
|
130
|
-
const lower = message.toLowerCase();
|
|
131
|
-
if (lower.includes('duplicate identifier')) return 'duplicate-identifier';
|
|
132
|
-
if (lower.includes('unknown reference') || lower.includes('did you mean'))
|
|
133
|
-
return 'unknown-reference';
|
|
134
|
-
if (lower.includes('circular')) return 'circular-dependency';
|
|
135
|
-
if (lower.includes('requires') && lower.includes('date:')) return 'missing-date';
|
|
136
|
-
if (lower.includes('duration')) return 'duration';
|
|
137
|
-
if (lower.includes('include')) return 'include';
|
|
138
|
-
if (lower.includes('indent')) return 'indentation';
|
|
139
|
-
return 'validation';
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function extractSuggestion(message: string): string | undefined {
|
|
143
|
-
const match = message.match(DID_YOU_MEAN_RE);
|
|
144
|
-
return match ? match[1].trim() : undefined;
|
|
145
|
-
}
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
// auto-scan, postMessage transport, save/copy commands) belong in the
|
|
8
8
|
// consumer; this package stays a pure data transform.
|
|
9
9
|
|
|
10
|
+
// LangiumLikeDiagnostic now lives in @nowline/core (shared with the CLI);
|
|
11
|
+
// re-exported here so existing @nowline/browser consumers keep importing it
|
|
12
|
+
// from the same place.
|
|
13
|
+
export type { LangiumLikeDiagnostic } from '@nowline/core';
|
|
10
14
|
export {
|
|
11
15
|
type DiagnosticRow,
|
|
12
16
|
fromLangiumDiagnostic,
|
|
@@ -14,7 +18,6 @@ export {
|
|
|
14
18
|
fromParserError,
|
|
15
19
|
fromRenderWarning,
|
|
16
20
|
fromResolveDiagnostic,
|
|
17
|
-
type LangiumLikeDiagnostic,
|
|
18
21
|
} from './diagnostic-row.js';
|
|
19
22
|
// Showcase source string is generated from `examples/showcase.nowline`
|
|
20
23
|
// by `scripts/bundle-showcase.mjs` (m4.7 slice F) and re-exported here
|
package/src/pipeline.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
// bundle stays free of any Node literal even before tree-shaking.
|
|
19
19
|
|
|
20
20
|
import {
|
|
21
|
+
collectDocumentDiagnostics,
|
|
21
22
|
createNowlineServices,
|
|
22
23
|
type NowlineFile,
|
|
23
24
|
type NowlineServices,
|
|
@@ -33,7 +34,6 @@ import {
|
|
|
33
34
|
fromParserError,
|
|
34
35
|
fromRenderWarning,
|
|
35
36
|
fromResolveDiagnostic,
|
|
36
|
-
type LangiumLikeDiagnostic,
|
|
37
37
|
} from './diagnostic-row.js';
|
|
38
38
|
import {
|
|
39
39
|
isNoOpIncludeDiagnosticMessage,
|
|
@@ -146,15 +146,18 @@ export async function parseSource(
|
|
|
146
146
|
const doc = docFactory.fromString<NowlineFile>(source, freshUri());
|
|
147
147
|
await services.shared.workspace.DocumentBuilder.build([doc], { validation: true });
|
|
148
148
|
|
|
149
|
+
// collectDocumentDiagnostics owns the de-dup: Langium re-folds lexer +
|
|
150
|
+
// parser errors into doc.diagnostics, so the shared collector skips those
|
|
151
|
+
// copies and we map each origin to a row here.
|
|
149
152
|
const diagnostics: DiagnosticRow[] = [];
|
|
150
|
-
for (const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
153
|
+
for (const raw of collectDocumentDiagnostics(doc)) {
|
|
154
|
+
if (raw.origin === 'lexer') {
|
|
155
|
+
diagnostics.push(fromLexerError(raw.error, filePath));
|
|
156
|
+
} else if (raw.origin === 'parser') {
|
|
157
|
+
diagnostics.push(fromParserError(raw.error, filePath));
|
|
158
|
+
} else {
|
|
159
|
+
diagnostics.push(fromLangiumDiagnostic(raw.diagnostic, filePath));
|
|
160
|
+
}
|
|
158
161
|
}
|
|
159
162
|
return { ast: doc.parseResult.value, diagnostics };
|
|
160
163
|
}
|