@nowline/browser 0.8.6 → 0.10.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.
@@ -27,9 +27,17 @@ export declare function fromLexerError(err: LexerErrorLike, file: string): Diagn
27
27
  * is 0-based in the resolver (it comes from a CST range) and may be
28
28
  * undefined for whole-file diagnostics like circular include — fall
29
29
  * back to line 1 so a click-to-jump still puts the cursor near the top
30
- * of the offending file.
30
+ * of the offending file. A routed diagnostic with a `range` takes its
31
+ * column from it, the validator's column for the same finding; without
32
+ * one the column is 1.
33
+ *
34
+ * A wave-rule diagnostic (specs/waves.md §6.1) keeps its stable code
35
+ * (`NL.Exxxx`), and its message is rendered in `locale` when the caller
36
+ * knows one; WV8, the uncoded wave rule, is labelled like the validator's
37
+ * copy. An included file's syntax error is the row that file's own check
38
+ * gives. Every other resolver diagnostic is an `include` row, verbatim.
31
39
  */
32
- export declare function fromResolveDiagnostic(diag: ResolveDiagnostic): DiagnosticRow;
40
+ export declare function fromResolveDiagnostic(diag: ResolveDiagnostic, locale?: string): DiagnosticRow;
33
41
  /**
34
42
  * Adapt a render-time warning message into a diagnostic row. Renderer
35
43
  * warnings are bare strings without a source location, so callers
@@ -1 +1 @@
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;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC1B,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,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;AAQD,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;AAED,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CASrF"}
1
+ {"version":3,"file":"diagnostic-row.d.ts","sourceRoot":"","sources":["../src/diagnostic-row.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EAEnB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAEzB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC1B,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,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;AAQD,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;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CA4B7F;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,aAAa,CAAC,UAAU,CAAa,GAChD,aAAa,CASf;AAED,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CASrF"}
@@ -1,4 +1,4 @@
1
- import { extractSuggestion, resolveDiagnosticCode, } from '@nowline/core';
1
+ import { extractSuggestion, inferCodeFromMessage, isRoutedResolveDiagnostic, localizeResolveDiagnostic, resolveDiagnosticCode, } from '@nowline/core';
2
2
  function mapLangiumSeverity(severity) {
3
3
  if (severity === 2)
4
4
  return 'warning';
@@ -45,16 +45,44 @@ export function fromLexerError(err, file) {
45
45
  * is 0-based in the resolver (it comes from a CST range) and may be
46
46
  * undefined for whole-file diagnostics like circular include — fall
47
47
  * back to line 1 so a click-to-jump still puts the cursor near the top
48
- * of the offending file.
48
+ * of the offending file. A routed diagnostic with a `range` takes its
49
+ * column from it, the validator's column for the same finding; without
50
+ * one the column is 1.
51
+ *
52
+ * A wave-rule diagnostic (specs/waves.md §6.1) keeps its stable code
53
+ * (`NL.Exxxx`), and its message is rendered in `locale` when the caller
54
+ * knows one; WV8, the uncoded wave rule, is labelled like the validator's
55
+ * copy. An included file's syntax error is the row that file's own check
56
+ * gives. Every other resolver diagnostic is an `include` row, verbatim.
49
57
  */
50
- export function fromResolveDiagnostic(diag) {
58
+ export function fromResolveDiagnostic(diag, locale) {
59
+ if (diag.syntax?.origin === 'lexer')
60
+ return fromLexerError(diag.syntax.error, diag.sourcePath);
61
+ if (diag.syntax?.origin === 'parser') {
62
+ return fromParserError(diag.syntax.error, diag.sourcePath);
63
+ }
64
+ const line = (diag.range?.start.line ?? diag.line ?? 0) + 1;
65
+ const column = (diag.range?.start.character ?? 0) + 1;
66
+ if (!isRoutedResolveDiagnostic(diag)) {
67
+ return {
68
+ severity: diag.severity,
69
+ code: 'include',
70
+ message: diag.message,
71
+ file: diag.sourcePath,
72
+ line,
73
+ column: 1,
74
+ };
75
+ }
76
+ const message = locale ? localizeResolveDiagnostic(locale, diag) : diag.message;
77
+ const suggestion = extractSuggestion(message);
51
78
  return {
52
79
  severity: diag.severity,
53
- code: 'include',
54
- message: diag.message,
80
+ code: diag.code ?? inferCodeFromMessage(diag.message),
81
+ message,
82
+ ...(suggestion === undefined ? {} : { suggestion }),
55
83
  file: diag.sourcePath,
56
- line: diag.line !== undefined ? diag.line + 1 : 1,
57
- column: 1,
84
+ line,
85
+ column,
58
86
  };
59
87
  }
60
88
  /**
@@ -1 +1 @@
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;AAuBvB,SAAS,kBAAkB,CAAC,QAA4B;IACpD,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACrC,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAClC,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAA2B,EAAE,IAAY;IAC3E,OAAO;QACH,QAAQ,EAAE,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC3C,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,QAAQ,GAA8B,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;AAED,mFAAmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,OAAsB,EAAE,IAAY;IAClE,OAAO;QACH,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,IAAI;QACJ,IAAI,EAAE,CAAC;QACP,MAAM,EAAE,CAAC;KACZ,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"diagnostic-row.js","sourceRoot":"","sources":["../src/diagnostic-row.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export type { LangiumLikeDiagnostic } from '@nowline/core';
2
- export { civilDateInZone, type NormalizedZone, normalizeZone, type ResolveTodayOptions, resolveToday, TimezoneError, } from '@nowline/layout';
2
+ export { civilDateInZone, isNonWorkingDisplay, NON_WORKING_DISPLAYS, type NonWorkingDisplay, type NormalizedZone, normalizeZone, parseNonWorkingDisplay, type ResolveTodayOptions, resolveToday, TimezoneError, } from '@nowline/layout';
3
3
  export { type DiagnosticRow, fromLangiumDiagnostic, fromLayoutInsight, fromLexerError, fromParserError, fromRenderWarning, fromResolveDiagnostic, } from './diagnostic-row.js';
4
4
  export { showcaseSource } from './generated/showcase.js';
5
5
  export { isNoOpIncludeDiagnosticMessage, NOWLINE_BROWSER_NOOP_INCLUDE_TAG, noOpIncludeReadFile, type SkippedInclude, } from './no-op-include-resolver.js';
@@ -1 +1 @@
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,eAAe,EACf,KAAK,cAAc,EACnB,aAAa,EACb,KAAK,mBAAmB,EACxB,YAAY,EACZ,aAAa,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,KAAK,aAAa,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,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,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,YAAY,EACZ,4BAA4B,GAC/B,MAAM,eAAe,CAAC"}
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,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,aAAa,EACb,sBAAsB,EACtB,KAAK,mBAAmB,EACxB,YAAY,EACZ,aAAa,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,KAAK,aAAa,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,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,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,YAAY,EACZ,4BAA4B,GAC/B,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@
6
6
  // behaviour cannot drift between them. Surface-specific concerns (DOM
7
7
  // auto-scan, postMessage transport, save/copy commands) belong in the
8
8
  // consumer; this package stays a pure data transform.
9
- export { civilDateInZone, normalizeZone, resolveToday, TimezoneError, } from '@nowline/layout';
9
+ export { civilDateInZone, isNonWorkingDisplay, NON_WORKING_DISPLAYS, normalizeZone, parseNonWorkingDisplay, resolveToday, TimezoneError, } from '@nowline/layout';
10
10
  export { fromLangiumDiagnostic, fromLayoutInsight, fromLexerError, fromParserError, fromRenderWarning, fromResolveDiagnostic, } from './diagnostic-row.js';
11
11
  // Showcase source string is generated from `examples/showcase.nowline`
12
12
  // by `scripts/bundle-showcase.mjs` (m4.7 slice F) and re-exported here
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;AAMtD,OAAO,EACH,eAAe,EAEf,aAAa,EAEb,YAAY,EACZ,aAAa,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEH,qBAAqB,EACrB,iBAAiB,EACjB,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,EAItB,WAAW,EAGX,YAAY,EACZ,4BAA4B,GAC/B,MAAM,eAAe,CAAC"}
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,EACH,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EAGpB,aAAa,EACb,sBAAsB,EAEtB,YAAY,EACZ,aAAa,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEH,qBAAqB,EACrB,iBAAiB,EACjB,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,EAItB,WAAW,EAGX,YAAY,EACZ,4BAA4B,GAC/B,MAAM,eAAe,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { type NowlineFile } from '@nowline/core';
2
- import { type ThemeName } from '@nowline/layout';
2
+ import { type NonWorkingDisplay, type ThemeName } from '@nowline/layout';
3
3
  import { type AssetResolver, type FontFamilies } from '@nowline/renderer';
4
4
  import { type DiagnosticRow } from './diagnostic-row.js';
5
5
  import { type SkippedInclude } from './no-op-include-resolver.js';
@@ -65,8 +65,15 @@ export interface RenderOptions extends ParseOptions {
65
65
  timezone?: string;
66
66
  /** BCP-47 locale forwarded to the layout engine for axis labels. */
67
67
  locale?: string;
68
- /** Total canvas width in px. Layout's default is 1280. */
68
+ /** Best-effort maximum canvas width in px. Unset fits the content. */
69
69
  width?: number;
70
+ /**
71
+ * How a calendar's non-working days appear: `hide` collapses them,
72
+ * `show` draws them as shaded bands. Wins over the file's
73
+ * `default roadmap non-working:` key; leave it undefined to let the key
74
+ * apply, then `hide`.
75
+ */
76
+ nonWorking?: NonWorkingDisplay;
70
77
  /**
71
78
  * Override the deterministic id prefix used for in-SVG `<style>`
72
79
  * scoping. Multi-block surfaces (auto-scan) supply a fresh prefix
@@ -1 +1 @@
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,EAMH,KAAK,SAAS,EAEjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAa,MAAM,mBAAmB,CAAC;AAErF,OAAO,EACH,KAAK,aAAa,EAOrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGH,KAAK,cAAc,EACtB,MAAM,6BAA6B,CAAC;AAErC;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,4BAA4B,CAAC;AAEhE,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAc3D,wBAAgB,4BAA4B,CACxC,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,EACnC,KAAK,EAAE,eAAe,GACvB,OAAO,CAET;AAED,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;IAClD;;;OAGG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;CACrC;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;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,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;IAC9B;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC/B;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,CA6FvB;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAGrD"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAmBA,OAAO,EAIH,KAAK,WAAW,EAGnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAEH,KAAK,iBAAiB,EAItB,KAAK,SAAS,EAEjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAA2B,MAAM,mBAAmB,CAAC;AAEnG,OAAO,EACH,KAAK,aAAa,EAOrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGH,KAAK,cAAc,EACtB,MAAM,6BAA6B,CAAC;AAErC;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,4BAA4B,CAAC;AAEhE,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAc3D,wBAAgB,4BAA4B,CACxC,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,EACnC,KAAK,EAAE,eAAe,GACvB,OAAO,CAET;AAED,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;IAClD;;;OAGG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;CACrC;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;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B;;;;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;IAC9B;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC/B;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,CAQtB;AAoBD;;;;;GAKG;AACH,wBAAsB,YAAY,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,aAAkB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAiHvB;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAGrD"}
package/dist/pipeline.js CHANGED
@@ -16,9 +16,9 @@
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 { collectDocumentDiagnostics, createNowlineServices, resolveIncludes, } from '@nowline/core';
20
- import { collectLayoutInsights, layoutRoadmap, normalizeZone, resolveToday, TimezoneError, } from '@nowline/layout';
21
- import { renderSvg } from '@nowline/renderer';
19
+ import { collectDocumentDiagnostics, createNowlineServices, isRoutedResolveDiagnostic, } from '@nowline/core';
20
+ import { collectLayoutInsights, normalizeZone, resolveToday, TimezoneError, } from '@nowline/layout';
21
+ import { renderSvg, stageRoadmap } from '@nowline/renderer';
22
22
  import { URI } from 'langium';
23
23
  import { fromLangiumDiagnostic, fromLayoutInsight, fromLexerError, fromParserError, fromRenderWarning, fromResolveDiagnostic, } from './diagnostic-row.js';
24
24
  import { isNoOpIncludeDiagnosticMessage, noOpIncludeReadFile, } from './no-op-include-resolver.js';
@@ -65,22 +65,25 @@ export async function parseSource(source, options = {}) {
65
65
  const docFactory = services.shared.workspace.LangiumDocumentFactory;
66
66
  const doc = docFactory.fromString(source, freshUri());
67
67
  await services.shared.workspace.DocumentBuilder.build([doc], { validation: true });
68
- // collectDocumentDiagnostics owns the de-dup: Langium re-folds lexer +
69
- // parser errors into doc.diagnostics, so the shared collector skips those
70
- // copies and we map each origin to a row here.
71
- const diagnostics = [];
72
- for (const raw of collectDocumentDiagnostics(doc)) {
73
- if (raw.origin === 'lexer') {
74
- diagnostics.push(fromLexerError(raw.error, filePath));
75
- }
76
- else if (raw.origin === 'parser') {
77
- diagnostics.push(fromParserError(raw.error, filePath));
78
- }
79
- else {
80
- diagnostics.push(fromLangiumDiagnostic(raw.diagnostic, filePath));
81
- }
82
- }
83
- return { ast: doc.parseResult.value, diagnostics };
68
+ return { ast: doc.parseResult.value, diagnostics: documentRows(doc, filePath) };
69
+ }
70
+ /**
71
+ * Parse and validation diagnostics of a built document as rows.
72
+ * collectDocumentDiagnostics owns the de-dup: Langium re-folds lexer +
73
+ * parser errors into doc.diagnostics, so the shared collector skips those
74
+ * copies and we map each origin to a row here.
75
+ */
76
+ function documentRows(doc, filePath) {
77
+ return rawRows(collectDocumentDiagnostics(doc), filePath);
78
+ }
79
+ function rawRows(raws, filePath) {
80
+ return raws.map((raw) => {
81
+ if (raw.origin === 'lexer')
82
+ return fromLexerError(raw.error, filePath);
83
+ if (raw.origin === 'parser')
84
+ return fromParserError(raw.error, filePath);
85
+ return fromLangiumDiagnostic(raw.diagnostic, filePath);
86
+ });
84
87
  }
85
88
  /**
86
89
  * Run the full pipeline (parse + validate + resolveIncludes + layout
@@ -90,18 +93,50 @@ export async function parseSource(source, options = {}) {
90
93
  */
91
94
  export async function renderSource(source, options = {}) {
92
95
  const filePath = options.filePath ?? DEFAULT_SYNTHETIC_PATH;
93
- const parsed = await parseSource(source, { filePath });
94
- if (parsed.diagnostics.some((d) => d.severity === 'error')) {
95
- return { kind: 'diagnostics', diagnostics: parsed.diagnostics };
96
- }
97
96
  const services = getServices();
98
- const readFile = options.readFile ?? noOpIncludeReadFile;
99
- const resolved = await resolveIncludes(parsed.ast, filePath, {
100
- services: services.Nowline,
101
- readFile,
97
+ // A bad timezone is reported after validation and include errors, as it
98
+ // always was: stage with no now-line, then return the timezone row only
99
+ // if the roadmap staged.
100
+ let zone;
101
+ let zoneError;
102
+ if (options.timezone) {
103
+ try {
104
+ zone = normalizeZone(options.timezone);
105
+ }
106
+ catch (err) {
107
+ if (!(err instanceof TimezoneError))
108
+ throw err;
109
+ zoneError = err;
110
+ }
111
+ }
112
+ // Pass today as-is: null suppresses the now-line, undefined defaults to
113
+ // local today (or zone), a string is parsed, a Date is used directly.
114
+ const today = zoneError ? undefined : resolveToday({ now: options.today, zone });
115
+ const stage = await stageRoadmap({
116
+ source,
117
+ sourcePath: filePath,
118
+ services,
119
+ readSource: options.readFile ?? noOpIncludeReadFile,
120
+ assetResolver: options.assetResolver,
121
+ // The no-op reader's skipped includes are not errors in single-file
122
+ // mode: they are reported through `onSkippedInclude` instead.
123
+ isToleratedIncludeError: (d) => isNoOpIncludeDiagnosticMessage(d.message),
124
+ layout: {
125
+ theme: options.theme,
126
+ today,
127
+ locale: options.locale,
128
+ width: options.width,
129
+ nonWorking: options.nonWorking,
130
+ },
102
131
  });
103
- const rows = [...parsed.diagnostics];
104
- for (const diag of resolved.diagnostics) {
132
+ if (stage.kind === 'invalid') {
133
+ return { kind: 'diagnostics', diagnostics: rawRows(stage.diagnostics, filePath) };
134
+ }
135
+ // An uncoded include error takes precedence: when one is reported, the
136
+ // routed (wave-rule) diagnostics are dropped (specs/waves.md §6.1).
137
+ const hasLegacyError = stage.kind === 'include-error' && stage.legacy !== undefined;
138
+ const rows = documentRows(stage.document, filePath);
139
+ for (const diag of stage.resolved.diagnostics) {
105
140
  if (diag.severity === 'error' && isNoOpIncludeDiagnosticMessage(diag.message)) {
106
141
  options.onSkippedInclude?.({
107
142
  sourcePath: diag.sourcePath,
@@ -109,46 +144,34 @@ export async function renderSource(source, options = {}) {
109
144
  });
110
145
  continue;
111
146
  }
147
+ if (hasLegacyError && isRoutedResolveDiagnostic(diag))
148
+ continue;
112
149
  rows.push(fromResolveDiagnostic(diag));
113
150
  }
114
- if (rows.some((r) => r.severity === 'error')) {
151
+ if (stage.kind === 'include-error' || rows.some((r) => r.severity === 'error')) {
115
152
  return { kind: 'diagnostics', diagnostics: rows };
116
153
  }
117
- let zone;
118
- if (options.timezone) {
119
- try {
120
- zone = normalizeZone(options.timezone);
121
- }
122
- catch (err) {
123
- if (err instanceof TimezoneError) {
124
- // Surface timezone errors as a diagnostic row rather than throwing
125
- // so the caller gets a structured result instead of an uncaught error.
126
- return {
127
- kind: 'diagnostics',
128
- diagnostics: [
129
- {
130
- severity: 'error',
131
- code: 'invalid-timezone',
132
- message: err.message,
133
- file: filePath,
134
- line: 1,
135
- column: 1,
136
- },
137
- ],
138
- };
139
- }
140
- throw err;
141
- }
154
+ if (zoneError) {
155
+ // Surface timezone errors as a diagnostic row rather than throwing
156
+ // so the caller gets a structured result instead of an uncaught error.
157
+ return {
158
+ kind: 'diagnostics',
159
+ diagnostics: [
160
+ {
161
+ severity: 'error',
162
+ code: 'invalid-timezone',
163
+ message: zoneError.message,
164
+ file: filePath,
165
+ line: 1,
166
+ column: 1,
167
+ },
168
+ ],
169
+ };
142
170
  }
143
- // Pass today as-is: null suppresses the now-line, undefined defaults to
144
- // local today (or zone), a string is parsed, a Date is used directly.
145
- const today = resolveToday({ now: options.today, zone });
146
- const model = layoutRoadmap(parsed.ast, resolved, {
147
- theme: options.theme,
148
- today,
149
- locale: options.locale,
150
- width: options.width,
151
- });
171
+ // Renderer warnings, starting with the logo load: a failed load lays out
172
+ // as if no logo were declared and reports like any render warning.
173
+ const warnMessages = [...stage.warnings];
174
+ const { logo, model } = stage;
152
175
  const diagnosticLevel = options.diagnosticLevel ?? 'error';
153
176
  // Filtered once below as part of the combined `warnings` array.
154
177
  const layoutInsightRows = collectLayoutInsights(model, {
@@ -157,10 +180,10 @@ export async function renderSource(source, options = {}) {
157
180
  }).map((insight) => fromLayoutInsight(insight, filePath));
158
181
  const showLinks = options.showLinks !== false;
159
182
  const strict = options.strict === true;
160
- const warnMessages = [];
161
183
  const svg = await renderSvg(model, {
162
184
  idPrefix: options.idPrefix,
163
185
  assetResolver: options.assetResolver,
186
+ logo,
164
187
  noLinks: !showLinks,
165
188
  strict,
166
189
  warn: (msg) => warnMessages.push(msg),
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}
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.8.6",
3
+ "version": "0.10.0",
4
4
  "description": "Runs the whole Nowline pipeline — parse, validate, resolve includes, lay out, and render — in the browser, with pluggable I/O hooks. Powers @nowline/embed and the VS Code preview.",
5
5
  "license": "Apache-2.0",
6
6
  "engines": {
@@ -38,16 +38,16 @@
38
38
  "pipeline"
39
39
  ],
40
40
  "dependencies": {
41
- "@nowline/core": "0.8.6",
42
- "@nowline/layout": "0.8.6",
43
- "@nowline/renderer": "0.8.6",
41
+ "@nowline/core": "0.10.0",
42
+ "@nowline/layout": "0.10.0",
43
+ "@nowline/renderer": "0.10.0",
44
44
  "langium": "~4.4.0"
45
45
  },
46
46
  "devDependencies": {
47
- "@types/node": "^26.6.3",
48
- "happy-dom": "^20.14.5",
47
+ "@types/node": "^26.6.5",
48
+ "happy-dom": "^21.0.4",
49
49
  "typescript": "^7.0.2",
50
- "vitest": "^5.0.2"
50
+ "vitest": "^5.0.5"
51
51
  },
52
52
  "scripts": {
53
53
  "prebuild": "node scripts/bundle-showcase.mjs",
@@ -1,7 +1,10 @@
1
1
  import {
2
2
  extractSuggestion,
3
+ inferCodeFromMessage,
4
+ isRoutedResolveDiagnostic,
3
5
  type LangiumLikeDiagnostic,
4
6
  type LexerErrorLike,
7
+ localizeResolveDiagnostic,
5
8
  type ParserErrorLike,
6
9
  type ResolveDiagnostic,
7
10
  resolveDiagnosticCode,
@@ -76,16 +79,43 @@ export function fromLexerError(err: LexerErrorLike, file: string): DiagnosticRow
76
79
  * is 0-based in the resolver (it comes from a CST range) and may be
77
80
  * undefined for whole-file diagnostics like circular include — fall
78
81
  * back to line 1 so a click-to-jump still puts the cursor near the top
79
- * of the offending file.
82
+ * of the offending file. A routed diagnostic with a `range` takes its
83
+ * column from it, the validator's column for the same finding; without
84
+ * one the column is 1.
85
+ *
86
+ * A wave-rule diagnostic (specs/waves.md §6.1) keeps its stable code
87
+ * (`NL.Exxxx`), and its message is rendered in `locale` when the caller
88
+ * knows one; WV8, the uncoded wave rule, is labelled like the validator's
89
+ * copy. An included file's syntax error is the row that file's own check
90
+ * gives. Every other resolver diagnostic is an `include` row, verbatim.
80
91
  */
81
- export function fromResolveDiagnostic(diag: ResolveDiagnostic): DiagnosticRow {
92
+ export function fromResolveDiagnostic(diag: ResolveDiagnostic, locale?: string): DiagnosticRow {
93
+ if (diag.syntax?.origin === 'lexer') return fromLexerError(diag.syntax.error, diag.sourcePath);
94
+ if (diag.syntax?.origin === 'parser') {
95
+ return fromParserError(diag.syntax.error, diag.sourcePath);
96
+ }
97
+ const line = (diag.range?.start.line ?? diag.line ?? 0) + 1;
98
+ const column = (diag.range?.start.character ?? 0) + 1;
99
+ if (!isRoutedResolveDiagnostic(diag)) {
100
+ return {
101
+ severity: diag.severity,
102
+ code: 'include',
103
+ message: diag.message,
104
+ file: diag.sourcePath,
105
+ line,
106
+ column: 1,
107
+ };
108
+ }
109
+ const message = locale ? localizeResolveDiagnostic(locale, diag) : diag.message;
110
+ const suggestion = extractSuggestion(message);
82
111
  return {
83
112
  severity: diag.severity,
84
- code: 'include',
85
- message: diag.message,
113
+ code: diag.code ?? inferCodeFromMessage(diag.message),
114
+ message,
115
+ ...(suggestion === undefined ? {} : { suggestion }),
86
116
  file: diag.sourcePath,
87
- line: diag.line !== undefined ? diag.line + 1 : 1,
88
- column: 1,
117
+ line,
118
+ column,
89
119
  };
90
120
  }
91
121
 
package/src/index.ts CHANGED
@@ -13,8 +13,12 @@
13
13
  export type { LangiumLikeDiagnostic } from '@nowline/core';
14
14
  export {
15
15
  civilDateInZone,
16
+ isNonWorkingDisplay,
17
+ NON_WORKING_DISPLAYS,
18
+ type NonWorkingDisplay,
16
19
  type NormalizedZone,
17
20
  normalizeZone,
21
+ parseNonWorkingDisplay,
18
22
  type ResolveTodayOptions,
19
23
  resolveToday,
20
24
  TimezoneError,
package/src/pipeline.ts CHANGED
@@ -20,21 +20,22 @@
20
20
  import {
21
21
  collectDocumentDiagnostics,
22
22
  createNowlineServices,
23
+ isRoutedResolveDiagnostic,
23
24
  type NowlineFile,
24
25
  type NowlineServices,
25
- resolveIncludes,
26
+ type RawDiagnostic,
26
27
  } from '@nowline/core';
27
28
  import {
28
29
  collectLayoutInsights,
29
- layoutRoadmap,
30
+ type NonWorkingDisplay,
30
31
  type NormalizedZone,
31
32
  normalizeZone,
32
33
  resolveToday,
33
34
  type ThemeName,
34
35
  TimezoneError,
35
36
  } from '@nowline/layout';
36
- import { type AssetResolver, type FontFamilies, renderSvg } from '@nowline/renderer';
37
- import { URI } from 'langium';
37
+ import { type AssetResolver, type FontFamilies, renderSvg, stageRoadmap } from '@nowline/renderer';
38
+ import { type LangiumDocument, URI } from 'langium';
38
39
  import {
39
40
  type DiagnosticRow,
40
41
  fromLangiumDiagnostic,
@@ -134,8 +135,15 @@ export interface RenderOptions extends ParseOptions {
134
135
  timezone?: string;
135
136
  /** BCP-47 locale forwarded to the layout engine for axis labels. */
136
137
  locale?: string;
137
- /** Total canvas width in px. Layout's default is 1280. */
138
+ /** Best-effort maximum canvas width in px. Unset fits the content. */
138
139
  width?: number;
140
+ /**
141
+ * How a calendar's non-working days appear: `hide` collapses them,
142
+ * `show` draws them as shaded bands. Wins over the file's
143
+ * `default roadmap non-working:` key; leave it undefined to let the key
144
+ * apply, then `hide`.
145
+ */
146
+ nonWorking?: NonWorkingDisplay;
139
147
  /**
140
148
  * Override the deterministic id prefix used for in-SVG `<style>`
141
149
  * scoping. Multi-block surfaces (auto-scan) supply a fresh prefix
@@ -199,20 +207,25 @@ export async function parseSource(
199
207
  const doc = docFactory.fromString<NowlineFile>(source, freshUri());
200
208
  await services.shared.workspace.DocumentBuilder.build([doc], { validation: true });
201
209
 
202
- // collectDocumentDiagnostics owns the de-dup: Langium re-folds lexer +
203
- // parser errors into doc.diagnostics, so the shared collector skips those
204
- // copies and we map each origin to a row here.
205
- const diagnostics: DiagnosticRow[] = [];
206
- for (const raw of collectDocumentDiagnostics(doc)) {
207
- if (raw.origin === 'lexer') {
208
- diagnostics.push(fromLexerError(raw.error, filePath));
209
- } else if (raw.origin === 'parser') {
210
- diagnostics.push(fromParserError(raw.error, filePath));
211
- } else {
212
- diagnostics.push(fromLangiumDiagnostic(raw.diagnostic, filePath));
213
- }
214
- }
215
- return { ast: doc.parseResult.value, diagnostics };
210
+ return { ast: doc.parseResult.value, diagnostics: documentRows(doc, filePath) };
211
+ }
212
+
213
+ /**
214
+ * Parse and validation diagnostics of a built document as rows.
215
+ * collectDocumentDiagnostics owns the de-dup: Langium re-folds lexer +
216
+ * parser errors into doc.diagnostics, so the shared collector skips those
217
+ * copies and we map each origin to a row here.
218
+ */
219
+ function documentRows(doc: LangiumDocument<NowlineFile>, filePath: string): DiagnosticRow[] {
220
+ return rawRows(collectDocumentDiagnostics(doc), filePath);
221
+ }
222
+
223
+ function rawRows(raws: readonly RawDiagnostic[], filePath: string): DiagnosticRow[] {
224
+ return raws.map((raw) => {
225
+ if (raw.origin === 'lexer') return fromLexerError(raw.error, filePath);
226
+ if (raw.origin === 'parser') return fromParserError(raw.error, filePath);
227
+ return fromLangiumDiagnostic(raw.diagnostic, filePath);
228
+ });
216
229
  }
217
230
 
218
231
  /**
@@ -226,20 +239,51 @@ export async function renderSource(
226
239
  options: RenderOptions = {},
227
240
  ): Promise<RenderResult> {
228
241
  const filePath = options.filePath ?? DEFAULT_SYNTHETIC_PATH;
229
- const parsed = await parseSource(source, { filePath });
230
- if (parsed.diagnostics.some((d) => d.severity === 'error')) {
231
- return { kind: 'diagnostics', diagnostics: parsed.diagnostics };
242
+ const services = getServices();
243
+
244
+ // A bad timezone is reported after validation and include errors, as it
245
+ // always was: stage with no now-line, then return the timezone row only
246
+ // if the roadmap staged.
247
+ let zone: NormalizedZone | undefined;
248
+ let zoneError: TimezoneError | undefined;
249
+ if (options.timezone) {
250
+ try {
251
+ zone = normalizeZone(options.timezone);
252
+ } catch (err) {
253
+ if (!(err instanceof TimezoneError)) throw err;
254
+ zoneError = err;
255
+ }
232
256
  }
257
+ // Pass today as-is: null suppresses the now-line, undefined defaults to
258
+ // local today (or zone), a string is parsed, a Date is used directly.
259
+ const today = zoneError ? undefined : resolveToday({ now: options.today, zone });
233
260
 
234
- const services = getServices();
235
- const readFile = options.readFile ?? noOpIncludeReadFile;
236
- const resolved = await resolveIncludes(parsed.ast, filePath, {
237
- services: services.Nowline,
238
- readFile,
261
+ const stage = await stageRoadmap({
262
+ source,
263
+ sourcePath: filePath,
264
+ services,
265
+ readSource: options.readFile ?? noOpIncludeReadFile,
266
+ assetResolver: options.assetResolver,
267
+ // The no-op reader's skipped includes are not errors in single-file
268
+ // mode: they are reported through `onSkippedInclude` instead.
269
+ isToleratedIncludeError: (d) => isNoOpIncludeDiagnosticMessage(d.message),
270
+ layout: {
271
+ theme: options.theme,
272
+ today,
273
+ locale: options.locale,
274
+ width: options.width,
275
+ nonWorking: options.nonWorking,
276
+ },
239
277
  });
278
+ if (stage.kind === 'invalid') {
279
+ return { kind: 'diagnostics', diagnostics: rawRows(stage.diagnostics, filePath) };
280
+ }
240
281
 
241
- const rows: DiagnosticRow[] = [...parsed.diagnostics];
242
- for (const diag of resolved.diagnostics) {
282
+ // An uncoded include error takes precedence: when one is reported, the
283
+ // routed (wave-rule) diagnostics are dropped (specs/waves.md §6.1).
284
+ const hasLegacyError = stage.kind === 'include-error' && stage.legacy !== undefined;
285
+ const rows: DiagnosticRow[] = documentRows(stage.document, filePath);
286
+ for (const diag of stage.resolved.diagnostics) {
243
287
  if (diag.severity === 'error' && isNoOpIncludeDiagnosticMessage(diag.message)) {
244
288
  options.onSkippedInclude?.({
245
289
  sourcePath: diag.sourcePath,
@@ -247,46 +291,35 @@ export async function renderSource(
247
291
  });
248
292
  continue;
249
293
  }
294
+ if (hasLegacyError && isRoutedResolveDiagnostic(diag)) continue;
250
295
  rows.push(fromResolveDiagnostic(diag));
251
296
  }
252
- if (rows.some((r) => r.severity === 'error')) {
297
+ if (stage.kind === 'include-error' || rows.some((r) => r.severity === 'error')) {
253
298
  return { kind: 'diagnostics', diagnostics: rows };
254
299
  }
255
300
 
256
- let zone: NormalizedZone | undefined;
257
- if (options.timezone) {
258
- try {
259
- zone = normalizeZone(options.timezone);
260
- } catch (err) {
261
- if (err instanceof TimezoneError) {
262
- // Surface timezone errors as a diagnostic row rather than throwing
263
- // so the caller gets a structured result instead of an uncaught error.
264
- return {
265
- kind: 'diagnostics',
266
- diagnostics: [
267
- {
268
- severity: 'error' as const,
269
- code: 'invalid-timezone',
270
- message: err.message,
271
- file: filePath,
272
- line: 1,
273
- column: 1,
274
- },
275
- ],
276
- };
277
- }
278
- throw err;
279
- }
301
+ if (zoneError) {
302
+ // Surface timezone errors as a diagnostic row rather than throwing
303
+ // so the caller gets a structured result instead of an uncaught error.
304
+ return {
305
+ kind: 'diagnostics',
306
+ diagnostics: [
307
+ {
308
+ severity: 'error' as const,
309
+ code: 'invalid-timezone',
310
+ message: zoneError.message,
311
+ file: filePath,
312
+ line: 1,
313
+ column: 1,
314
+ },
315
+ ],
316
+ };
280
317
  }
281
- // Pass today as-is: null suppresses the now-line, undefined defaults to
282
- // local today (or zone), a string is parsed, a Date is used directly.
283
- const today = resolveToday({ now: options.today, zone });
284
- const model = layoutRoadmap(parsed.ast, resolved, {
285
- theme: options.theme,
286
- today,
287
- locale: options.locale,
288
- width: options.width,
289
- });
318
+
319
+ // Renderer warnings, starting with the logo load: a failed load lays out
320
+ // as if no logo were declared and reports like any render warning.
321
+ const warnMessages: string[] = [...stage.warnings];
322
+ const { logo, model } = stage;
290
323
 
291
324
  const diagnosticLevel = options.diagnosticLevel ?? 'error';
292
325
  // Filtered once below as part of the combined `warnings` array.
@@ -297,11 +330,11 @@ export async function renderSource(
297
330
 
298
331
  const showLinks = options.showLinks !== false;
299
332
  const strict = options.strict === true;
300
- const warnMessages: string[] = [];
301
333
 
302
334
  const svg = await renderSvg(model, {
303
335
  idPrefix: options.idPrefix,
304
336
  assetResolver: options.assetResolver,
337
+ logo,
305
338
  noLinks: !showLinks,
306
339
  strict,
307
340
  warn: (msg) => warnMessages.push(msg),