@refrakt-md/runes 0.14.3 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/config.d.ts +40 -4
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +154 -88
  4. package/dist/config.js.map +1 -1
  5. package/dist/drawer-pipeline.d.ts +33 -0
  6. package/dist/drawer-pipeline.d.ts.map +1 -0
  7. package/dist/drawer-pipeline.js +206 -0
  8. package/dist/drawer-pipeline.js.map +1 -0
  9. package/dist/expand-pipeline.d.ts +51 -0
  10. package/dist/expand-pipeline.d.ts.map +1 -0
  11. package/dist/expand-pipeline.js +305 -0
  12. package/dist/expand-pipeline.js.map +1 -0
  13. package/dist/index.d.ts +9 -3
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +32 -3
  16. package/dist/index.js.map +1 -1
  17. package/dist/lang-map.d.ts +32 -0
  18. package/dist/lang-map.d.ts.map +1 -0
  19. package/dist/lang-map.js +76 -0
  20. package/dist/lang-map.js.map +1 -0
  21. package/dist/lib/read-file.d.ts +78 -0
  22. package/dist/lib/read-file.d.ts.map +1 -0
  23. package/dist/lib/read-file.js +166 -0
  24. package/dist/lib/read-file.js.map +1 -0
  25. package/dist/nodes.d.ts.map +1 -1
  26. package/dist/nodes.js +12 -1
  27. package/dist/nodes.js.map +1 -1
  28. package/dist/outline-scope.d.ts +29 -0
  29. package/dist/outline-scope.d.ts.map +1 -0
  30. package/dist/outline-scope.js +149 -0
  31. package/dist/outline-scope.js.map +1 -0
  32. package/dist/plugins.d.ts +13 -0
  33. package/dist/plugins.d.ts.map +1 -1
  34. package/dist/plugins.js +65 -1
  35. package/dist/plugins.js.map +1 -1
  36. package/dist/snippet-pipeline.d.ts +42 -0
  37. package/dist/snippet-pipeline.d.ts.map +1 -0
  38. package/dist/snippet-pipeline.js +219 -0
  39. package/dist/snippet-pipeline.js.map +1 -0
  40. package/dist/tags/drawer.d.ts +26 -0
  41. package/dist/tags/drawer.d.ts.map +1 -0
  42. package/dist/tags/drawer.js +134 -0
  43. package/dist/tags/drawer.js.map +1 -0
  44. package/dist/tags/expand.d.ts +22 -0
  45. package/dist/tags/expand.d.ts.map +1 -0
  46. package/dist/tags/expand.js +76 -0
  47. package/dist/tags/expand.js.map +1 -0
  48. package/dist/tags/snippet.d.ts +19 -0
  49. package/dist/tags/snippet.d.ts.map +1 -0
  50. package/dist/tags/snippet.js +49 -0
  51. package/dist/tags/snippet.js.map +1 -0
  52. package/dist/util.d.ts +11 -0
  53. package/dist/util.d.ts.map +1 -1
  54. package/dist/util.js +35 -0
  55. package/dist/util.js.map +1 -1
  56. package/dist/xref-patterns.d.ts +57 -0
  57. package/dist/xref-patterns.d.ts.map +1 -0
  58. package/dist/xref-patterns.js +140 -0
  59. package/dist/xref-patterns.js.map +1 -0
  60. package/dist/xref-resolve.d.ts +22 -5
  61. package/dist/xref-resolve.d.ts.map +1 -1
  62. package/dist/xref-resolve.js +203 -79
  63. package/dist/xref-resolve.js.map +1 -1
  64. package/package.json +3 -3
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Drawer pipeline hooks (SPEC-060, WORK-257).
3
+ *
4
+ * - **Register** walks each page's renderable for drawer tags
5
+ * (`data-rune="drawer"`), and adds each as a page-scoped entity
6
+ * (`type: 'drawer'`, `scope: 'page'`, `sourceUrl: "${pageUrl}#drawer-${id}"`).
7
+ * Page scope means two pages can both declare `id="auth"` without
8
+ * colliding in the site-wide registry (WORK-256).
9
+ *
10
+ * - **postProcess** resolves drawer title heading levels for drawers that
11
+ * were authored without an explicit `headingLevel`. The title carries
12
+ * a `data-drawer-title-auto` marker emitted by the schema; the walk
13
+ * tracks document outline depth (the most recent `<h{n}>` seen) and
14
+ * rewrites the marked tag to `h{n+1}` (clamped 1..6, default h2 when
15
+ * no preceding heading exists).
16
+ */
17
+ import Markdoc from '@markdoc/markdoc';
18
+ import { DRAWER_TITLE_AUTO_MARKER } from './tags/drawer.js';
19
+ const { Tag } = Markdoc;
20
+ const HEADING_TAG_RE = /^h([1-6])$/;
21
+ /** Read a `data-*` attribute from a tag, treating undefined as undefined. */
22
+ function readDataAttr(tag, key) {
23
+ const v = tag.attributes?.[key];
24
+ return typeof v === 'string' ? v : undefined;
25
+ }
26
+ /** Read the `content` of a property meta tag (`<meta data-field="...">`)
27
+ * immediately under the drawer tag. The schema emits side/size/shortcut as
28
+ * meta tags; the identity-transform engine consumes them later and stamps
29
+ * them as `data-side` etc. on the wrapper. The register hook runs before
30
+ * the engine, so we have to read directly from the meta tags. */
31
+ function readPropertyMeta(drawerTag, field) {
32
+ for (const child of drawerTag.children ?? []) {
33
+ if (!Tag.isTag(child))
34
+ continue;
35
+ const c = child;
36
+ if (c.name !== 'meta')
37
+ continue;
38
+ if (c.attributes?.['data-field'] !== field)
39
+ continue;
40
+ const content = c.attributes?.['content'];
41
+ return typeof content === 'string' ? content : undefined;
42
+ }
43
+ return undefined;
44
+ }
45
+ /**
46
+ * Walk the renderable tree of every page and register each drawer rune
47
+ * as a page-scoped entity. Each drawer surfaces in the registry as
48
+ * `{ type: 'drawer', id, scope: 'page', sourceUrl: '<pageUrl>#drawer-<id>' }`
49
+ * with `data.title`, `data.side`, `data.size`, `data.shortcut` for
50
+ * downstream consumers (xref resolver, registry-driven tooling).
51
+ */
52
+ export function registerDrawers(pages, registry, ctx) {
53
+ for (const page of pages) {
54
+ const drawersOnPage = [];
55
+ const seenIds = new Set();
56
+ walkForDrawers(page.renderable, (tag) => {
57
+ const id = readDataAttr(tag, 'data-drawer-id');
58
+ if (!id) {
59
+ ctx.error('drawer rune is missing required `id` attribute', page.url);
60
+ return;
61
+ }
62
+ if (seenIds.has(id)) {
63
+ ctx.warn(`drawer id="${id}" is declared more than once on this page — last declaration wins`, page.url);
64
+ }
65
+ seenIds.add(id);
66
+ drawersOnPage.push({
67
+ id,
68
+ title: extractTitleText(tag),
69
+ side: readPropertyMeta(tag, 'side') ?? 'right',
70
+ size: readPropertyMeta(tag, 'size') ?? 'md',
71
+ shortcut: readPropertyMeta(tag, 'shortcut'),
72
+ });
73
+ });
74
+ for (const d of drawersOnPage) {
75
+ registry.register({
76
+ type: 'drawer',
77
+ id: d.id,
78
+ scope: 'page',
79
+ sourceUrl: `${page.url}#drawer-${d.id}`,
80
+ data: {
81
+ title: d.title,
82
+ side: d.side,
83
+ size: d.size,
84
+ shortcut: d.shortcut,
85
+ },
86
+ });
87
+ }
88
+ }
89
+ }
90
+ /** Walk the renderable looking for drawer-rune tags. Visits each drawer's
91
+ * shell exactly once (we don't recurse into a drawer's body, drawer-in-drawer
92
+ * is out of scope). */
93
+ function walkForDrawers(node, visit) {
94
+ if (Array.isArray(node)) {
95
+ for (const c of node)
96
+ walkForDrawers(c, visit);
97
+ return;
98
+ }
99
+ if (!Tag.isTag(node))
100
+ return;
101
+ const tag = node;
102
+ if (tag.attributes?.['data-rune'] === 'drawer') {
103
+ visit(tag);
104
+ // Don't recurse — drawer-in-drawer isn't supported and skipping the
105
+ // body avoids treating a future inner-drawer descendant as a sibling
106
+ // of the outer one.
107
+ return;
108
+ }
109
+ if (!tag.children)
110
+ return;
111
+ for (const c of tag.children)
112
+ walkForDrawers(c, visit);
113
+ }
114
+ /** Pull the drawer's title text out of its header → title element. Returns
115
+ * `undefined` when the drawer has no title (the rune renders headerless
116
+ * in that case). String concatenation of leaf text nodes is good enough —
117
+ * drawer titles are short. */
118
+ function extractTitleText(drawerTag) {
119
+ const titleTag = findByDataName(drawerTag, 'title');
120
+ if (!titleTag)
121
+ return undefined;
122
+ const text = collectText(titleTag);
123
+ return text.length > 0 ? text : undefined;
124
+ }
125
+ function findByDataName(root, name) {
126
+ if (root.attributes?.['data-name'] === name) {
127
+ return root;
128
+ }
129
+ for (const c of root.children ?? []) {
130
+ if (Tag.isTag(c)) {
131
+ const hit = findByDataName(c, name);
132
+ if (hit)
133
+ return hit;
134
+ }
135
+ }
136
+ return undefined;
137
+ }
138
+ function collectText(node) {
139
+ if (typeof node === 'string')
140
+ return node;
141
+ if (Array.isArray(node))
142
+ return node.map(collectText).join('');
143
+ if (Tag.isTag(node)) {
144
+ const tag = node;
145
+ return (tag.children ?? []).map(collectText).join('');
146
+ }
147
+ return '';
148
+ }
149
+ /**
150
+ * postProcess walk: rewrite each `data-drawer-title-auto` heading to the
151
+ * level computed from the outline depth at that position on the page.
152
+ * Returns the same renderable identity when no drawer titles needed
153
+ * rewriting, so downstream postProcess steps can skip a no-op pass.
154
+ */
155
+ export function resolveAutoDrawerTitleLevels(renderable) {
156
+ const state = { lastHeadingLevel: 0, mutated: false };
157
+ const next = walkAndRewriteTitles(renderable, state);
158
+ return state.mutated ? next : renderable;
159
+ }
160
+ function walkAndRewriteTitles(node, state) {
161
+ if (typeof node === 'string' || typeof node === 'number' || node == null)
162
+ return node;
163
+ if (Array.isArray(node)) {
164
+ let mutated = false;
165
+ const next = node.map((c) => {
166
+ const w = walkAndRewriteTitles(c, state);
167
+ if (w !== c)
168
+ mutated = true;
169
+ return w;
170
+ });
171
+ return mutated ? next : node;
172
+ }
173
+ if (!Tag.isTag(node))
174
+ return node;
175
+ const tag = node;
176
+ const headingMatch = HEADING_TAG_RE.exec(tag.name);
177
+ // Auto-title placeholder: rewrite this node's tag name based on the
178
+ // last heading level we saw. Default to h2 when no heading has been
179
+ // encountered yet (the page-title h1 lives in layout, so the next
180
+ // reasonable level inside the body is h2).
181
+ const isAutoTitle = tag.attributes?.[DRAWER_TITLE_AUTO_MARKER] === 'true';
182
+ if (isAutoTitle) {
183
+ const base = state.lastHeadingLevel === 0 ? 1 : state.lastHeadingLevel;
184
+ const targetLevel = Math.min(6, Math.max(1, base + 1));
185
+ state.mutated = true;
186
+ const newAttrs = { ...tag.attributes };
187
+ delete newAttrs[DRAWER_TITLE_AUTO_MARKER];
188
+ return new Tag(`h${targetLevel}`, newAttrs, tag.children);
189
+ }
190
+ if (headingMatch) {
191
+ state.lastHeadingLevel = Number(headingMatch[1]);
192
+ }
193
+ if (!tag.children || tag.children.length === 0)
194
+ return tag;
195
+ let mutated = false;
196
+ const newChildren = tag.children.map((c) => {
197
+ const w = walkAndRewriteTitles(c, state);
198
+ if (w !== c)
199
+ mutated = true;
200
+ return w;
201
+ });
202
+ if (!mutated)
203
+ return tag;
204
+ return new Tag(tag.name, tag.attributes, newChildren);
205
+ }
206
+ //# sourceMappingURL=drawer-pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawer-pipeline.js","sourceRoot":"","sources":["../src/drawer-pipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Expand pipeline (SPEC-066, WORK-260).
3
+ *
4
+ * Post-process resolver that finds `{% expand %}` placeholder tags
5
+ * (`data-rune="expand-pending"`) in a page's renderable tree, looks
6
+ * each up in the registry, reads + parses the entity's `sourceFile`
7
+ * (cached per build), calls the plugin's `extract()` to grab the
8
+ * embeddable AST subtree, optionally shifts heading levels, transforms
9
+ * the subtree using the build's full tags+nodes config, and substitutes
10
+ * the result in place wrapped in `<section class="rf-expand"
11
+ * data-rune="expand" data-outline-scope="${id}">`.
12
+ *
13
+ * The wrapper's `data-outline-scope` attribute is picked up by the
14
+ * WORK-259 walkers — heading IDs inside get prefixed, TOC items
15
+ * pointing at them get dropped — without expand needing to coordinate.
16
+ *
17
+ * Per-build caches:
18
+ * - `sourceFile → parsedAst` (one parse per file regardless of how
19
+ * many pages embed it)
20
+ *
21
+ * Per-page state:
22
+ * - resolution stack (`(type, id)` tuples) for cycle detection
23
+ */
24
+ import type { Node } from '@markdoc/markdoc';
25
+ import type { EntityRegistry, PipelineContext } from '@refrakt-md/types';
26
+ import type { CompiledXrefPattern } from './xref-patterns.js';
27
+ export interface ExpandResolveContext {
28
+ pageUrl: string;
29
+ registry: Readonly<EntityRegistry>;
30
+ patterns: CompiledXrefPattern[];
31
+ embedConfig?: {
32
+ tags: Record<string, unknown>;
33
+ nodes: Record<string, unknown>;
34
+ projectRoot?: string;
35
+ };
36
+ ctx: PipelineContext;
37
+ /** Per-build source-file cache. Shared across calls within one build,
38
+ * so a file embedded on twenty pages is parsed once. */
39
+ parseCache: Map<string, Node>;
40
+ }
41
+ /** Reset the per-build cache. Tests call this between cases; production
42
+ * builds rely on the cache living for the build's lifetime (each build
43
+ * starts fresh because the runes package is imported anew). */
44
+ export declare function __resetExpandCache(): void;
45
+ /**
46
+ * Walk a renderable tree, replace every `expand-pending` placeholder
47
+ * with the substituted entity content. Returns the same renderable
48
+ * reference when no placeholders were found.
49
+ */
50
+ export declare function resolveExpands(renderable: unknown, pageUrl: string, registry: Readonly<EntityRegistry>, patterns: CompiledXrefPattern[], embedConfig: ExpandResolveContext['embedConfig'], ctx: PipelineContext): unknown;
51
+ //# sourceMappingURL=expand-pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expand-pipeline.d.ts","sourceRoot":"","sources":["../src/expand-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAsB,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAG7F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAI9D,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IACnC,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,WAAW,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,GAAG,EAAE,eAAe,CAAC;IACrB;6DACyD;IACzD,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;CAC9B;AAOD;;gEAEgE;AAChE,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC7B,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,CAAC,cAAc,CAAC,EAClC,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,WAAW,EAAE,oBAAoB,CAAC,aAAa,CAAC,EAChD,GAAG,EAAE,eAAe,GAClB,OAAO,CAUT"}
@@ -0,0 +1,305 @@
1
+ /**
2
+ * Expand pipeline (SPEC-066, WORK-260).
3
+ *
4
+ * Post-process resolver that finds `{% expand %}` placeholder tags
5
+ * (`data-rune="expand-pending"`) in a page's renderable tree, looks
6
+ * each up in the registry, reads + parses the entity's `sourceFile`
7
+ * (cached per build), calls the plugin's `extract()` to grab the
8
+ * embeddable AST subtree, optionally shifts heading levels, transforms
9
+ * the subtree using the build's full tags+nodes config, and substitutes
10
+ * the result in place wrapped in `<section class="rf-expand"
11
+ * data-rune="expand" data-outline-scope="${id}">`.
12
+ *
13
+ * The wrapper's `data-outline-scope` attribute is picked up by the
14
+ * WORK-259 walkers — heading IDs inside get prefixed, TOC items
15
+ * pointing at them get dropped — without expand needing to coordinate.
16
+ *
17
+ * Per-build caches:
18
+ * - `sourceFile → parsedAst` (one parse per file regardless of how
19
+ * many pages embed it)
20
+ *
21
+ * Per-page state:
22
+ * - resolution stack (`(type, id)` tuples) for cycle detection
23
+ */
24
+ import Markdoc from '@markdoc/markdoc';
25
+ import { EXPAND_PLACEHOLDER_MARKER } from './tags/expand.js';
26
+ import { readWholeSandboxedFile, SnippetSandboxError } from './lib/read-file.js';
27
+ const { Tag } = Markdoc;
28
+ /** Per-build source-file parse cache. Lives outside the resolve context
29
+ * so a single build's runs reuse the same instance — the resolver is
30
+ * invoked per page, but the cache is per build. */
31
+ const buildParseCache = new Map();
32
+ /** Reset the per-build cache. Tests call this between cases; production
33
+ * builds rely on the cache living for the build's lifetime (each build
34
+ * starts fresh because the runes package is imported anew). */
35
+ export function __resetExpandCache() {
36
+ buildParseCache.clear();
37
+ }
38
+ /**
39
+ * Walk a renderable tree, replace every `expand-pending` placeholder
40
+ * with the substituted entity content. Returns the same renderable
41
+ * reference when no placeholders were found.
42
+ */
43
+ export function resolveExpands(renderable, pageUrl, registry, patterns, embedConfig, ctx) {
44
+ const rc = {
45
+ pageUrl,
46
+ registry,
47
+ patterns,
48
+ embedConfig,
49
+ ctx,
50
+ parseCache: buildParseCache,
51
+ };
52
+ return walk(renderable, rc, []);
53
+ }
54
+ function walk(node, rc, stack) {
55
+ if (Array.isArray(node)) {
56
+ let mutated = false;
57
+ const next = node.map((c) => {
58
+ const w = walk(c, rc, stack);
59
+ if (w !== c)
60
+ mutated = true;
61
+ return w;
62
+ });
63
+ return mutated ? next : node;
64
+ }
65
+ if (!Tag.isTag(node))
66
+ return node;
67
+ const tag = node;
68
+ const dataRune = tag.attributes?.['data-rune'];
69
+ if (dataRune === EXPAND_PLACEHOLDER_MARKER) {
70
+ return resolveOnePlaceholder(tag, rc, stack);
71
+ }
72
+ if (!tag.children || tag.children.length === 0)
73
+ return tag;
74
+ let mutated = false;
75
+ const newChildren = tag.children.map((c) => {
76
+ const w = walk(c, rc, stack);
77
+ if (w !== c)
78
+ mutated = true;
79
+ return w;
80
+ });
81
+ if (!mutated)
82
+ return tag;
83
+ return new Tag(tag.name, tag.attributes, newChildren);
84
+ }
85
+ function resolveOnePlaceholder(tag, rc, stack) {
86
+ const attrs = tag.attributes;
87
+ const id = String(attrs['data-expand-id'] ?? '');
88
+ const typeHint = attrs['data-expand-type'];
89
+ const levelAttr = attrs['data-expand-level'];
90
+ const canonical = attrs['data-expand-canonical'] === 'true';
91
+ const authoredLabel = attrs['data-expand-label'];
92
+ if (!id) {
93
+ rc.ctx.error(`expand placeholder is missing \`primary\`/id attribute on ${rc.pageUrl}`, rc.pageUrl);
94
+ return errorNode(id, 'missing id attribute');
95
+ }
96
+ const level = levelAttr !== undefined ? Number(levelAttr) : undefined;
97
+ const entity = findEmbeddableEntity(rc.registry, id, rc.pageUrl, typeHint);
98
+ if (!entity) {
99
+ rc.ctx.error(`expand "${id}" on ${rc.pageUrl} — entity not found`, rc.pageUrl);
100
+ return errorNode(id, 'entity not found');
101
+ }
102
+ if (!entity.sourceFile || !entity.extract) {
103
+ rc.ctx.error(`expand "${id}" on ${rc.pageUrl} — entity type "${entity.type}" does not support embedding (no sourceFile/extract)`, rc.pageUrl);
104
+ return errorNode(id, `entity type "${entity.type}" does not support embedding`);
105
+ }
106
+ // Cycle detection. The stack is per-page-render — embedding the same
107
+ // entity on two different pages is fine; embedding it inside itself
108
+ // transitively is the bug we catch.
109
+ if (stack.some(s => s.type === entity.type && s.id === entity.id)) {
110
+ const cyclePath = [...stack, { type: entity.type, id: entity.id }]
111
+ .map(s => `${s.id} (${s.type})`)
112
+ .join(' → ');
113
+ rc.ctx.error(`expand cycle detected on ${rc.pageUrl}. Cycle: ${cyclePath}`, rc.pageUrl);
114
+ return errorNode(id, 'cycle detected');
115
+ }
116
+ const projectRoot = rc.embedConfig?.projectRoot;
117
+ if (!projectRoot) {
118
+ rc.ctx.error(`expand "${id}" — no project root configured (embedConfig.projectRoot is unset)`, rc.pageUrl);
119
+ return errorNode(id, 'no project root configured');
120
+ }
121
+ let parsed;
122
+ try {
123
+ parsed = parseSourceFile(entity.sourceFile, projectRoot, rc.parseCache);
124
+ }
125
+ catch (err) {
126
+ const msg = err instanceof SnippetSandboxError ? err.message : err.message;
127
+ rc.ctx.error(`expand "${id}" — failed to read source file "${entity.sourceFile}": ${msg}`, rc.pageUrl);
128
+ return errorNode(id, msg);
129
+ }
130
+ const extracted = entity.extract(parsed);
131
+ if (!extracted) {
132
+ rc.ctx.error(`expand "${id}" — extractor returned no content; "${entity.sourceFile}" may have been edited out-of-sync with the registry`, rc.pageUrl);
133
+ return errorNode(id, 'extractor returned no content');
134
+ }
135
+ // Heading processing — `level=N` shifts headings by `N - 1`. Without
136
+ // `level=` the embed stays in peer-document mode; the outline-scope
137
+ // walkers (WORK-259) handle ID namespacing + TOC isolation downstream.
138
+ let processed = extracted;
139
+ if (level !== undefined && level !== 1) {
140
+ const shift = level - 1;
141
+ const clampedHeadings = [];
142
+ processed = shiftHeadings(extracted, shift, clampedHeadings);
143
+ if (clampedHeadings.length > 0) {
144
+ rc.ctx.warn(`expand "${id}" at ${rc.pageUrl} — heading demotion (level=${level}) would push ${clampedHeadings.length} heading(s) past H6. Clamped to H6: ${clampedHeadings.map(t => `"${t}"`).join(', ')}`, rc.pageUrl);
145
+ }
146
+ }
147
+ if (!rc.embedConfig) {
148
+ rc.ctx.error(`expand "${id}" — no embedConfig threaded through the pipeline`, rc.pageUrl);
149
+ return errorNode(id, 'no embed transform config');
150
+ }
151
+ // Transform the extracted subtree using the build's full tags+nodes
152
+ // config so embedded plan runes (or any other plugin-contributed
153
+ // schemas) execute normally. A nested walk handles any expand placeholders
154
+ // inside the embedded content (e.g. an embedded spec that references
155
+ // other specs).
156
+ const childStack = [...stack, { type: entity.type, id: entity.id }];
157
+ const transformed = Markdoc.transform(processed, rc.embedConfig);
158
+ const recursivelyResolved = walk(transformed, rc, childStack);
159
+ // Canonical-link affordance — resolve via the same chain xref uses.
160
+ const canonicalHref = resolveCanonicalHref(entity, rc.patterns);
161
+ // The engine's identity transform adds `class="rf-expand"` from the
162
+ // `Expand: { block: 'expand' }` config entry; don't set it here or it
163
+ // renders duplicated.
164
+ const wrapperAttrs = {
165
+ 'data-rune': 'expand',
166
+ 'data-entity-id': entity.id,
167
+ 'data-entity-type': entity.type,
168
+ 'data-source': 'registry',
169
+ };
170
+ // Outline-scope marker only when `level=` is unset (peer-document mode).
171
+ if (level === undefined) {
172
+ wrapperAttrs['data-outline-scope'] = entity.id;
173
+ }
174
+ if (canonicalHref) {
175
+ wrapperAttrs['data-canonical-href'] = canonicalHref;
176
+ }
177
+ const children = [];
178
+ if (Array.isArray(recursivelyResolved)) {
179
+ children.push(...recursivelyResolved);
180
+ }
181
+ else {
182
+ children.push(recursivelyResolved);
183
+ }
184
+ if (canonical) {
185
+ const label = authoredLabel || canonicalLinkDefault(entity);
186
+ const linkAttrs = {
187
+ class: canonicalHref
188
+ ? 'rf-expand__canonical-link'
189
+ : 'rf-expand__canonical-link rf-xref--unresolved',
190
+ };
191
+ if (canonicalHref)
192
+ linkAttrs.href = canonicalHref;
193
+ children.push(new Tag('a', linkAttrs, [label]));
194
+ }
195
+ return new Tag('section', wrapperAttrs, children);
196
+ }
197
+ /** Resolve an entity by id and (optional) type hint. Uses the same
198
+ * registry surface as xref. */
199
+ function findEmbeddableEntity(registry, id, pageUrl, typeHint) {
200
+ const types = typeHint ? [typeHint] : registry.getTypes();
201
+ for (const type of types) {
202
+ const e = registry.getById(type, id, pageUrl);
203
+ if (e)
204
+ return e;
205
+ }
206
+ // Name-match fallback (same algorithm as xref).
207
+ const idLower = id.toLowerCase();
208
+ for (const type of types) {
209
+ for (const e of registry.getAll(type)) {
210
+ const name = e.data.name ?? '';
211
+ const title = e.data.title ?? '';
212
+ if (name.toLowerCase() === idLower || title.toLowerCase() === idLower)
213
+ return e;
214
+ }
215
+ }
216
+ return undefined;
217
+ }
218
+ /** Resolve an entity's canonical URL using the same chain as xref: the
219
+ * registered `sourceUrl` first, then pattern matching against the id. */
220
+ function resolveCanonicalHref(entity, patterns) {
221
+ const sourceUrl = entity.sourceUrl;
222
+ const dataUrl = entity.data.url;
223
+ const baseUrl = dataUrl || sourceUrl;
224
+ if (baseUrl) {
225
+ const headingId = entity.data.headingId;
226
+ return headingId ? `${baseUrl}#${headingId}` : baseUrl;
227
+ }
228
+ for (const p of patterns) {
229
+ const m = p.match.exec(entity.id);
230
+ if (!m)
231
+ continue;
232
+ const groups = (m.groups ?? {});
233
+ const PLACEHOLDER_RE = /\{([a-zA-Z_$][a-zA-Z0-9_$]*)\}/g;
234
+ return p.template.replace(PLACEHOLDER_RE, (_match, name) => {
235
+ const value = name === 'id' ? entity.id : (groups[name] ?? '');
236
+ return value.split('/').map(encodeURIComponent).join('/');
237
+ });
238
+ }
239
+ return undefined;
240
+ }
241
+ function canonicalLinkDefault(entity) {
242
+ const title = entity.data.title;
243
+ const name = entity.data.name;
244
+ if (title)
245
+ return `View ${entity.type}: ${title}`;
246
+ if (name)
247
+ return `View ${entity.type}: ${name}`;
248
+ return `View ${entity.type} ${entity.id}`;
249
+ }
250
+ /** Parse a source file, caching per build. The path is resolved through
251
+ * the same sandbox as snippet so absolute paths and traversal escapes
252
+ * are rejected. File-system access lives behind a helper in
253
+ * `lib/read-file.ts` so the `node:fs` import stays out of this module
254
+ * and Vite can tree-shake it from browser bundles. */
255
+ function parseSourceFile(sourceFile, projectRoot, cache) {
256
+ const cached = cache.get(sourceFile);
257
+ if (cached)
258
+ return cached;
259
+ const raw = readWholeSandboxedFile({ relativePath: sourceFile, projectRoot });
260
+ const ast = Markdoc.parse(raw);
261
+ cache.set(sourceFile, ast);
262
+ return ast;
263
+ }
264
+ /** Recursively shift heading levels in a Markdoc AST subtree. Tracks
265
+ * headings that would push past H6 so the caller can warn. */
266
+ function shiftHeadings(node, shift, clampedHeadings) {
267
+ if (node.type === 'heading') {
268
+ const originalLevel = node.attributes.level;
269
+ const newLevel = originalLevel + shift;
270
+ if (newLevel > 6) {
271
+ const text = collectHeadingText(node);
272
+ clampedHeadings.push(text);
273
+ node.attributes.level = 6;
274
+ }
275
+ else {
276
+ node.attributes.level = newLevel;
277
+ }
278
+ }
279
+ for (const child of node.children ?? []) {
280
+ shiftHeadings(child, shift, clampedHeadings);
281
+ }
282
+ return node;
283
+ }
284
+ function collectHeadingText(node) {
285
+ const parts = [];
286
+ for (const child of node.walk()) {
287
+ if (child.type === 'text' && typeof child.attributes.content === 'string') {
288
+ parts.push(child.attributes.content);
289
+ }
290
+ }
291
+ return parts.join('');
292
+ }
293
+ /** Build a visible error placeholder for an expand resolution that
294
+ * failed. The build also surfaces the error via `ctx.error` — the
295
+ * inline rendering exists so the failure shows up on the page. */
296
+ function errorNode(id, message) {
297
+ // Engine adds `rf-expand` from the block config. Error variant gets a
298
+ // static modifier via the engine config; we only set the data attrs.
299
+ return new Tag('section', {
300
+ 'data-rune': 'expand',
301
+ 'data-entity-id': id,
302
+ 'data-expand-error': message,
303
+ }, [`expand "${id}" — ${message}`]);
304
+ }
305
+ //# sourceMappingURL=expand-pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expand-pipeline.js","sourceRoot":"","sources":["../src/expand-pipeline.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -9,7 +9,8 @@ export type { DeprecationRule, ContentModelSchemaOptions } from './lib/index.js'
9
9
  export { resolve, resolveSequence, resolveDelimited, resolveContentModel, resolveListItems, evaluateCondition, matchesType } from './lib/resolver.js';
10
10
  export { linkItem, pageSectionProperties, buildLayoutMetas, extractMediaImage, unwrapParagraphImages, name as nameHelper, description as descriptionHelper, SplitablePageSectionModel, SplitLayoutModel, splitLayoutAttributes } from './tags/common.js';
11
11
  export type { LayoutMetas } from './tags/common.js';
12
- export { extractHeadings, headingsToList } from './util.js';
12
+ export { extractHeadings, firstH1, headingsToList } from './util.js';
13
+ export { LANG_MAP, FALLBACK_LANG, inferLanguage } from './lang-map.js';
13
14
  export type { HeadingInfo } from './util.js';
14
15
  export { extractSeo, collectJsonLd, textContent } from './seo.js';
15
16
  export type { PageSeo, OgMeta } from './seo.js';
@@ -19,9 +20,9 @@ export { describeRune, renderContentModel, serializeContentModel, stripContentMo
19
20
  export type { RuneInfo, RuneBasePresetInfo, RuneLike, HydrateOptions, ReferenceContext, ReferenceGroup, RenderReferenceOptions, SerializedAttribute, SerializedRune, SerializedContentModel, SerializedSequenceModel, SerializedSectionsModel, SerializedDelimitedModel, SerializedCustomModel, SerializedContentField, SerializedDelimitedZone, SerializedHeadingExtractField, SerializedKnownSection, } from './reference.js';
20
21
  export { registerAttributePreset, lookupAttributePreset, schemaBasePresets, UNIVERSAL_ATTRIBUTE_NAMES, } from './attribute-presets.js';
21
22
  export type { AttributePresetMetadata } from './attribute-presets.js';
22
- export { loadPlugin, mergePlugins, applyAliases, loadLocalRunes, discoverPluginFixtures } from './plugins.js';
23
+ export { loadPlugin, mergePlugins, applyAliases, loadLocalRunes, discoverPluginFixtures, assertFileRootNamespaceAllowed } from './plugins.js';
23
24
  export type { LoadedPlugin, MergedPluginResult } from './plugins.js';
24
- export { coreConfig, baseConfig, corePipelineHooks, resolveCoreSentinels, type PageTreeNode } from './config.js';
25
+ export { coreConfig, baseConfig, corePipelineHooks, createCorePipelineHooks, resolveCoreSentinels, type PageTreeNode, type CorePipelineHooksOptions } from './config.js';
25
26
  export { BREADCRUMB_AUTO_SENTINEL } from './tags/breadcrumb.js';
26
27
  export { NAV_AUTO_SENTINEL } from './tags/nav.js';
27
28
  export { PAGINATION_AUTO_SENTINEL } from './tags/pagination.js';
@@ -29,6 +30,8 @@ export { TINT_TOKENS } from './tags/tint.js';
29
30
  export type { TintToken } from './tags/tint.js';
30
31
  export { XREF_RUNE_MARKER } from './tags/xref.js';
31
32
  export { resolveXrefs } from './xref-resolve.js';
33
+ export { compileXrefPatterns } from './xref-patterns.js';
34
+ export type { CompiledXrefPattern, CompiledXrefPatternsResult } from './xref-patterns.js';
32
35
  export { escapeFenceTags } from './fence-escape.js';
33
36
  export type { AccordionItemProps, AccordionProps, AnnotateNoteProps, AnnotateProps, BlogProps, BreadcrumbItemProps, BreadcrumbProps, BudgetLineItemProps, BudgetCategoryProps, BudgetProps, ChartProps, CodeGroupProps, CompareProps, ConversationMessageProps, ConversationProps, DataTableProps, DetailsProps, DiagramProps, DiffProps, EmbedProps, ErrorProps, FigureProps, FormProps, GalleryProps, GridProps, HintProps, JuxtaposePanelProps, JuxtaposeProps, MediaTextProps, NavItemProps, NavGroupProps, NavProps, PullQuoteProps, RevealStepProps, RevealProps, SandboxProps, ShowcaseProps, SidenoteProps, TabProps, TabPanelProps, TabGroupProps, TextBlockProps, TableOfContentsProps, } from './props.js';
34
37
  export declare const documents: {
@@ -45,6 +48,7 @@ export declare const runes: {
45
48
  tab: import("./rune.js").Rune;
46
49
  tabs: import("./rune.js").Rune;
47
50
  details: import("./rune.js").Rune;
51
+ drawer: import("./rune.js").Rune;
48
52
  figure: import("./rune.js").Rune;
49
53
  gallery: import("./rune.js").Rune;
50
54
  accordion: import("./rune.js").Rune;
@@ -59,6 +63,7 @@ export declare const runes: {
59
63
  compare: import("./rune.js").Rune;
60
64
  datatable: import("./rune.js").Rune;
61
65
  diff: import("./rune.js").Rune;
66
+ snippet: import("./rune.js").Rune;
62
67
  chart: import("./rune.js").Rune;
63
68
  diagram: import("./rune.js").Rune;
64
69
  sidenote: import("./rune.js").Rune;
@@ -81,6 +86,7 @@ export declare const runes: {
81
86
  bg: import("./rune.js").Rune;
82
87
  blog: import("./rune.js").Rune;
83
88
  xref: import("./rune.js").Rune;
89
+ expand: import("./rune.js").Rune;
84
90
  badge: import("./rune.js").Rune;
85
91
  };
86
92
  /** Markdoc-compatible tags map derived from runes + Markdoc built-in tags */