@refrakt-md/runes 0.16.0 → 0.16.1

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 (47) hide show
  1. package/dist/config.d.ts +7 -0
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +32 -4
  4. package/dist/config.js.map +1 -1
  5. package/dist/drawer-pipeline.d.ts +72 -1
  6. package/dist/drawer-pipeline.d.ts.map +1 -1
  7. package/dist/drawer-pipeline.js +242 -1
  8. package/dist/drawer-pipeline.js.map +1 -1
  9. package/dist/file-ref-resolve.d.ts +22 -0
  10. package/dist/file-ref-resolve.d.ts.map +1 -0
  11. package/dist/file-ref-resolve.js +233 -0
  12. package/dist/file-ref-resolve.js.map +1 -0
  13. package/dist/index.d.ts +8 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +17 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/nodes.d.ts.map +1 -1
  18. package/dist/nodes.js +62 -8
  19. package/dist/nodes.js.map +1 -1
  20. package/dist/snippet-pipeline.d.ts +7 -5
  21. package/dist/snippet-pipeline.d.ts.map +1 -1
  22. package/dist/snippet-pipeline.js +32 -13
  23. package/dist/snippet-pipeline.js.map +1 -1
  24. package/dist/tags/codegroup.d.ts.map +1 -1
  25. package/dist/tags/codegroup.js +37 -1
  26. package/dist/tags/codegroup.js.map +1 -1
  27. package/dist/tags/diff.d.ts.map +1 -1
  28. package/dist/tags/diff.js +85 -18
  29. package/dist/tags/diff.js.map +1 -1
  30. package/dist/tags/drawer.d.ts.map +1 -1
  31. package/dist/tags/drawer.js +32 -2
  32. package/dist/tags/drawer.js.map +1 -1
  33. package/dist/tags/file-ref.d.ts +21 -0
  34. package/dist/tags/file-ref.d.ts.map +1 -0
  35. package/dist/tags/file-ref.js +88 -0
  36. package/dist/tags/file-ref.js.map +1 -0
  37. package/dist/tags/snippet.d.ts.map +1 -1
  38. package/dist/tags/snippet.js +10 -0
  39. package/dist/tags/snippet.js.map +1 -1
  40. package/dist/tags/xref.d.ts.map +1 -1
  41. package/dist/tags/xref.js +9 -0
  42. package/dist/tags/xref.js.map +1 -1
  43. package/dist/xref-preview-resolve.d.ts +35 -0
  44. package/dist/xref-preview-resolve.d.ts.map +1 -0
  45. package/dist/xref-preview-resolve.js +188 -0
  46. package/dist/xref-preview-resolve.js.map +1 -0
  47. package/package.json +3 -3
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Drawer pipeline hooks (SPEC-060, WORK-257).
2
+ * Drawer pipeline hooks (SPEC-060, WORK-257; preview hoist SPEC-078, WORK-300).
3
3
  *
4
4
  * - **Register** walks each page's renderable for drawer tags
5
5
  * (`data-rune="drawer"`), and adds each as a page-scoped entity
@@ -13,8 +13,23 @@
13
13
  * tracks document outline depth (the most recent `<h{n}>` seen) and
14
14
  * rewrites the marked tag to `h{n+1}` (clamped 1..6, default h2 when
15
15
  * no preceding heading exists).
16
+ *
17
+ * - **postProcess (hoist)** turns inline `preview="drawer"` references
18
+ * into hoisted drawer sections at the page root. Reference runes
19
+ * (file-ref, xref) emit a `<meta data-field="hoist-drawer">` sentinel
20
+ * next to their inline `<a>` link; the hoist pass collects these,
21
+ * dedups by target id, detects collisions with author-declared
22
+ * drawers (author wins, hoist defers), and appends a `<section
23
+ * class="rf-drawer">` per unique reference to the end of the page
24
+ * renderable. The drawer's body and footer content is built by a
25
+ * source-specific builder that the consuming rune registers via
26
+ * `registerHoistBuilder` at module load time, so this file knows
27
+ * nothing about file paths, entity ids, or rune-specific rendering.
16
28
  */
29
+ import Markdoc from '@markdoc/markdoc';
17
30
  import type { EntityRegistry, PipelineContext, TransformedPage } from '@refrakt-md/types';
31
+ declare const Tag: typeof Markdoc.Tag;
32
+ type TagNode = InstanceType<typeof Tag>;
18
33
  /**
19
34
  * Walk the renderable tree of every page and register each drawer rune
20
35
  * as a page-scoped entity. Each drawer surfaces in the registry as
@@ -30,4 +45,60 @@ export declare function registerDrawers(pages: readonly TransformedPage[], regis
30
45
  * rewriting, so downstream postProcess steps can skip a no-op pass.
31
46
  */
32
47
  export declare function resolveAutoDrawerTitleLevels(renderable: unknown): unknown;
48
+ /** Sentinel `data-field` value emitted by reference runes on the meta tag
49
+ * that carries the drawer payload. The hoist pass collects these and
50
+ * removes them from the rendered tree. */
51
+ export declare const HOIST_DRAWER_SENTINEL = "hoist-drawer";
52
+ /** Per-page context handed to source-specific hoist builders so they can
53
+ * read the entity registry (for xref), resolve file paths against the
54
+ * project root (for file-ref), or emit pipeline messages. */
55
+ export interface HoistBuildContext {
56
+ pageUrl: string;
57
+ registry: Readonly<EntityRegistry> | undefined;
58
+ projectRoot: string | undefined;
59
+ ctx: PipelineContext;
60
+ }
61
+ /** Builder for a single hoist source (`file-ref`, `xref`, …). Reads
62
+ * the sentinel's `data-*` attributes (payload) and returns a complete
63
+ * hoisted drawer subtree — a `<section class="rf-drawer">` ready to be
64
+ * appended to the page root. Returning `null` skips the hoist (used
65
+ * when the source can't render anything meaningful, e.g. xref with an
66
+ * unresolvable entity id). */
67
+ export type HoistBuilder = (payload: Record<string, string>, context: HoistBuildContext) => TagNode | null;
68
+ /** Register a hoist builder for a given `source` value. Called by
69
+ * reference runes at module load (e.g. `file-ref.ts` calls
70
+ * `registerHoistBuilder('file-ref', …)`). Re-registration overwrites,
71
+ * which lets tests stub out a builder per case. */
72
+ export declare function registerHoistBuilder(source: string, builder: HoistBuilder): void;
73
+ /** Get the registered builder for a `source`, or undefined when none is
74
+ * registered. Exposed for diagnostics / tests. */
75
+ export declare function getHoistBuilder(source: string): HoistBuilder | undefined;
76
+ /**
77
+ * Walk a page's renderable, collect every `<meta data-field="hoist-drawer">`
78
+ * sentinel, dedup by `data-target-id`, build a hoisted `<section>` per
79
+ * unique target via the registered source builder, and return a new
80
+ * renderable with the sentinels stripped and the hoisted drawers
81
+ * appended at the page root.
82
+ *
83
+ * Rules:
84
+ * - **Dedup**: N mentions of the same target id collapse to one drawer.
85
+ * - **Collision with author-declared drawer**: if the page already
86
+ * declares `{% drawer id="X" %}` block-level and a hoist would emit
87
+ * the same id, the author drawer wins — the hoist defers, no new
88
+ * `<section>` is emitted, and an info-level pipeline message names
89
+ * both sources.
90
+ * - **Nested preview**: a hoist sentinel inside another drawer's body
91
+ * still hoists (we don't block it), but emits an info-level note so
92
+ * authors can spot it in CI output.
93
+ */
94
+ export declare function hoistPreviewDrawers(renderable: unknown, pageUrl: string, registry: Readonly<EntityRegistry> | undefined, projectRoot: string | undefined, ctx: PipelineContext): unknown;
95
+ /** Derive a drawer slug for a `file-ref` target. Encodes both path and
96
+ * lines so different ranges of the same path produce distinct ids.
97
+ *
98
+ * Examples:
99
+ * - `pathToSlug('packages/types/src/token-contract.ts')` → `'packages-types-src-token-contract-ts'`
100
+ * - `pathToSlug('packages/types/src/token-contract.ts', '42-58')` → `'packages-types-src-token-contract-ts-L42-L58'`
101
+ * - `pathToSlug('docs/My File.md', '12')` → `'docs-my-file-md-L12'` */
102
+ export declare function pathToSlug(path: string, lines?: string): string;
103
+ export {};
33
104
  //# sourceMappingURL=drawer-pipeline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"drawer-pipeline.d.ts","sourceRoot":"","sources":["../src/drawer-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AA8B1F;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC9B,KAAK,EAAE,SAAS,eAAe,EAAE,EACjC,QAAQ,EAAE,cAAc,EACxB,GAAG,EAAE,eAAe,GAClB,IAAI,CAqDN;AA+DD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAIzE"}
1
+ {"version":3,"file":"drawer-pipeline.d.ts","sourceRoot":"","sources":["../src/drawer-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAG1F,QAAA,MAAQ,GAAG,oBAAY,CAAC;AACxB,KAAK,OAAO,GAAG,YAAY,CAAC,OAAO,GAAG,CAAC,CAAC;AA2BxC;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC9B,KAAK,EAAE,SAAS,eAAe,EAAE,EACjC,QAAQ,EAAE,cAAc,EACxB,GAAG,EAAE,eAAe,GAClB,IAAI,CAqDN;AA+DD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAIzE;AAsDD;;2CAE2C;AAC3C,eAAO,MAAM,qBAAqB,iBAAiB,CAAC;AAEpD;;8DAE8D;AAC9D,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAC/C,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,GAAG,EAAE,eAAe,CAAC;CACrB;AAED;;;;;+BAK+B;AAC/B,MAAM,MAAM,YAAY,GAAG,CAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,OAAO,EAAE,iBAAiB,KACtB,OAAO,GAAG,IAAI,CAAC;AAIpB;;;oDAGoD;AACpD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAEhF;AAED;mDACmD;AACnD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAExE;AAgBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAClC,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,SAAS,EAC9C,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,GAAG,EAAE,eAAe,GAClB,OAAO,CAuDT;AAkHD;;;;;;wEAMwE;AACxE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAe/D"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Drawer pipeline hooks (SPEC-060, WORK-257).
2
+ * Drawer pipeline hooks (SPEC-060, WORK-257; preview hoist SPEC-078, WORK-300).
3
3
  *
4
4
  * - **Register** walks each page's renderable for drawer tags
5
5
  * (`data-rune="drawer"`), and adds each as a page-scoped entity
@@ -13,6 +13,18 @@
13
13
  * tracks document outline depth (the most recent `<h{n}>` seen) and
14
14
  * rewrites the marked tag to `h{n+1}` (clamped 1..6, default h2 when
15
15
  * no preceding heading exists).
16
+ *
17
+ * - **postProcess (hoist)** turns inline `preview="drawer"` references
18
+ * into hoisted drawer sections at the page root. Reference runes
19
+ * (file-ref, xref) emit a `<meta data-field="hoist-drawer">` sentinel
20
+ * next to their inline `<a>` link; the hoist pass collects these,
21
+ * dedups by target id, detects collisions with author-declared
22
+ * drawers (author wins, hoist defers), and appends a `<section
23
+ * class="rf-drawer">` per unique reference to the end of the page
24
+ * renderable. The drawer's body and footer content is built by a
25
+ * source-specific builder that the consuming rune registers via
26
+ * `registerHoistBuilder` at module load time, so this file knows
27
+ * nothing about file paths, entity ids, or rune-specific rendering.
16
28
  */
17
29
  import Markdoc from '@markdoc/markdoc';
18
30
  import { DRAWER_TITLE_AUTO_MARKER } from './tags/drawer.js';
@@ -203,4 +215,233 @@ function walkAndRewriteTitles(node, state) {
203
215
  return tag;
204
216
  return new Tag(tag.name, tag.attributes, newChildren);
205
217
  }
218
+ // ─────────────────────────────────────────────────────────────────────
219
+ // Hoist preview drawers (SPEC-078, WORK-300)
220
+ // ─────────────────────────────────────────────────────────────────────
221
+ /** Sentinel `data-field` value emitted by reference runes on the meta tag
222
+ * that carries the drawer payload. The hoist pass collects these and
223
+ * removes them from the rendered tree. */
224
+ export const HOIST_DRAWER_SENTINEL = 'hoist-drawer';
225
+ const hoistBuilders = new Map();
226
+ /** Register a hoist builder for a given `source` value. Called by
227
+ * reference runes at module load (e.g. `file-ref.ts` calls
228
+ * `registerHoistBuilder('file-ref', …)`). Re-registration overwrites,
229
+ * which lets tests stub out a builder per case. */
230
+ export function registerHoistBuilder(source, builder) {
231
+ hoistBuilders.set(source, builder);
232
+ }
233
+ /** Get the registered builder for a `source`, or undefined when none is
234
+ * registered. Exposed for diagnostics / tests. */
235
+ export function getHoistBuilder(source) {
236
+ return hoistBuilders.get(source);
237
+ }
238
+ /** Internal: read every `data-*` attribute off a sentinel meta tag into
239
+ * a plain string-string record. Non-string attribute values are
240
+ * ignored. */
241
+ function readPayload(meta) {
242
+ const out = {};
243
+ const attrs = meta.attributes;
244
+ if (!attrs)
245
+ return out;
246
+ for (const [k, v] of Object.entries(attrs)) {
247
+ if (!k.startsWith('data-'))
248
+ continue;
249
+ if (typeof v === 'string')
250
+ out[k.slice('data-'.length)] = v;
251
+ }
252
+ return out;
253
+ }
254
+ /**
255
+ * Walk a page's renderable, collect every `<meta data-field="hoist-drawer">`
256
+ * sentinel, dedup by `data-target-id`, build a hoisted `<section>` per
257
+ * unique target via the registered source builder, and return a new
258
+ * renderable with the sentinels stripped and the hoisted drawers
259
+ * appended at the page root.
260
+ *
261
+ * Rules:
262
+ * - **Dedup**: N mentions of the same target id collapse to one drawer.
263
+ * - **Collision with author-declared drawer**: if the page already
264
+ * declares `{% drawer id="X" %}` block-level and a hoist would emit
265
+ * the same id, the author drawer wins — the hoist defers, no new
266
+ * `<section>` is emitted, and an info-level pipeline message names
267
+ * both sources.
268
+ * - **Nested preview**: a hoist sentinel inside another drawer's body
269
+ * still hoists (we don't block it), but emits an info-level note so
270
+ * authors can spot it in CI output.
271
+ */
272
+ export function hoistPreviewDrawers(renderable, pageUrl, registry, projectRoot, ctx) {
273
+ // First pass: collect author-declared drawer ids so collisions can
274
+ // be detected before any hoist work runs.
275
+ const authorIds = collectAuthorDrawerIds(renderable);
276
+ // Second pass: walk the tree, strip hoist sentinels, collect their
277
+ // payloads (deduped, collision-checked, nesting-checked).
278
+ const payloads = new Map();
279
+ const seenIds = new Set();
280
+ const state = {
281
+ payloads,
282
+ seenIds,
283
+ authorIds,
284
+ drawerDepth: 0,
285
+ pageUrl,
286
+ ctx,
287
+ mutated: false,
288
+ };
289
+ const stripped = walkStripSentinels(renderable, state);
290
+ if (payloads.size === 0)
291
+ return state.mutated ? stripped : renderable;
292
+ // Third pass: build hoisted drawer sections via source-specific
293
+ // builders and append to the page renderable root.
294
+ const buildContext = { pageUrl, registry, projectRoot, ctx };
295
+ const drawers = [];
296
+ for (const payload of payloads.values()) {
297
+ const source = payload.source;
298
+ if (!source) {
299
+ ctx.warn(`hoist drawer payload is missing required \`source\` attribute (target-id=${payload['target-id'] ?? '?'})`, pageUrl);
300
+ continue;
301
+ }
302
+ const builder = hoistBuilders.get(source);
303
+ if (!builder) {
304
+ ctx.warn(`hoist drawer source "${source}" has no registered builder — skipping target-id=${payload['target-id'] ?? '?'}`, pageUrl);
305
+ continue;
306
+ }
307
+ const node = builder(payload, buildContext);
308
+ if (node)
309
+ drawers.push(node);
310
+ }
311
+ if (drawers.length === 0)
312
+ return stripped;
313
+ if (Array.isArray(stripped))
314
+ return [...stripped, ...drawers];
315
+ if (Tag.isTag(stripped)) {
316
+ const t = stripped;
317
+ return new Tag(t.name, t.attributes, [...(t.children ?? []), ...drawers]);
318
+ }
319
+ return [stripped, ...drawers];
320
+ }
321
+ function collectAuthorDrawerIds(renderable) {
322
+ const ids = new Set();
323
+ const walk = (node) => {
324
+ if (Array.isArray(node)) {
325
+ for (const c of node)
326
+ walk(c);
327
+ return;
328
+ }
329
+ if (!Tag.isTag(node))
330
+ return;
331
+ const tag = node;
332
+ if (tag.attributes?.['data-rune'] === 'drawer') {
333
+ const id = tag.attributes?.['data-drawer-id'];
334
+ if (typeof id === 'string')
335
+ ids.add(id);
336
+ return; // don't recurse into a drawer's body — drawer-in-drawer is its own concern
337
+ }
338
+ for (const c of tag.children ?? [])
339
+ walk(c);
340
+ };
341
+ walk(renderable);
342
+ return ids;
343
+ }
344
+ function walkStripSentinels(node, state) {
345
+ if (Array.isArray(node)) {
346
+ let mutated = false;
347
+ const out = [];
348
+ for (const c of node) {
349
+ const w = walkStripSentinels(c, state);
350
+ if (w !== c)
351
+ mutated = true;
352
+ if (w !== STRIP)
353
+ out.push(w);
354
+ }
355
+ if (!mutated)
356
+ return node;
357
+ state.mutated = true;
358
+ return out;
359
+ }
360
+ if (!Tag.isTag(node))
361
+ return node;
362
+ const tag = node;
363
+ // Strip the sentinel meta itself.
364
+ if (tag.name === 'meta'
365
+ && tag.attributes?.['data-field'] === HOIST_DRAWER_SENTINEL) {
366
+ const payload = readPayload(tag);
367
+ const targetId = payload['target-id'];
368
+ if (!targetId) {
369
+ state.ctx.warn(`hoist drawer sentinel is missing required \`data-target-id\` attribute`, state.pageUrl);
370
+ return STRIP;
371
+ }
372
+ // Collision with author-declared drawer? Author wins; hoist defers.
373
+ if (state.authorIds.has(targetId)) {
374
+ state.ctx.info(`Hoist preview "${targetId}" (source=${payload.source ?? '?'}) collides with an author-declared {% drawer id="${targetId}" %} on this page — author drawer wins, hoist defers.`, state.pageUrl);
375
+ return STRIP;
376
+ }
377
+ // Nested preview inside another drawer's body? Still hoist, but
378
+ // flag it — dialog stacking handles it but the shape is awkward.
379
+ if (state.drawerDepth > 0) {
380
+ state.ctx.info(`Hoist preview "${targetId}" (source=${payload.source ?? '?'}) appears inside another drawer's body — nested previews stack on modern browsers, consider not nesting.`, state.pageUrl);
381
+ }
382
+ // Dedup: keep the first occurrence's payload.
383
+ if (!state.seenIds.has(targetId)) {
384
+ state.payloads.set(targetId, payload);
385
+ state.seenIds.add(targetId);
386
+ }
387
+ return STRIP;
388
+ }
389
+ const isDrawer = tag.attributes?.['data-rune'] === 'drawer';
390
+ if (isDrawer)
391
+ state.drawerDepth++;
392
+ if (!tag.children || tag.children.length === 0) {
393
+ if (isDrawer)
394
+ state.drawerDepth--;
395
+ return tag;
396
+ }
397
+ let mutated = false;
398
+ const newChildren = [];
399
+ for (const c of tag.children) {
400
+ const w = walkStripSentinels(c, state);
401
+ if (w !== c)
402
+ mutated = true;
403
+ if (w !== STRIP)
404
+ newChildren.push(w);
405
+ }
406
+ if (isDrawer)
407
+ state.drawerDepth--;
408
+ if (!mutated)
409
+ return tag;
410
+ state.mutated = true;
411
+ return new Tag(tag.name, tag.attributes, newChildren);
412
+ }
413
+ /** Sentinel value returned by `walkStripSentinels` for elements that
414
+ * should be removed from their position in the tree. Using a symbol
415
+ * lets the array-walk path tell "removed" apart from "replaced with
416
+ * another node". */
417
+ const STRIP = Symbol('hoist-strip');
418
+ // ─────────────────────────────────────────────────────────────────────
419
+ // Slug derivation helpers — used by reference runes when emitting
420
+ // sentinels and re-derived here so tests can lock the shape.
421
+ // ─────────────────────────────────────────────────────────────────────
422
+ /** Derive a drawer slug for a `file-ref` target. Encodes both path and
423
+ * lines so different ranges of the same path produce distinct ids.
424
+ *
425
+ * Examples:
426
+ * - `pathToSlug('packages/types/src/token-contract.ts')` → `'packages-types-src-token-contract-ts'`
427
+ * - `pathToSlug('packages/types/src/token-contract.ts', '42-58')` → `'packages-types-src-token-contract-ts-L42-L58'`
428
+ * - `pathToSlug('docs/My File.md', '12')` → `'docs-my-file-md-L12'` */
429
+ export function pathToSlug(path, lines) {
430
+ const base = path
431
+ .toLowerCase()
432
+ // keep [a-z0-9._-]; turn everything else (including `/`, ` `, parens) into `-`.
433
+ .replace(/[^a-z0-9.]+/g, '-')
434
+ // collapse repeated dashes and trim ends.
435
+ .replace(/-+/g, '-')
436
+ .replace(/^-|-$/g, '');
437
+ if (!lines)
438
+ return base;
439
+ const trimmed = lines.trim();
440
+ const dash = trimmed.indexOf('-');
441
+ if (dash < 0)
442
+ return `${base}-L${trimmed}`;
443
+ const start = trimmed.slice(0, dash).trim();
444
+ const end = trimmed.slice(dash + 1).trim();
445
+ return end ? `${base}-L${start}-L${end}` : `${base}-L${start}`;
446
+ }
206
447
  //# sourceMappingURL=drawer-pipeline.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"drawer-pipeline.js","sourceRoot":"","sources":["../src/drawer-pipeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"drawer-pipeline.js","sourceRoot":"","sources":["../src/drawer-pipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * file-ref postProcess resolver (SPEC-078, WORK-301).
3
+ *
4
+ * Walks the rendered page, finds `file-ref` sentinels, binds each inline
5
+ * `<a>` to the canonical GitHub URL built from the site's `repoUrl` /
6
+ * `repoBranch`, and (when `preview="drawer"` is set) emits a
7
+ * `hoist-drawer` sentinel that the drawer pipeline picks up to render a
8
+ * preview drawer containing the file's snippet + a "View source on
9
+ * GitHub →" footer link.
10
+ */
11
+ import type { PipelineContext } from '@refrakt-md/types';
12
+ /**
13
+ * Resolve every `file-ref` sentinel on the page: bind the inline `<a>` to
14
+ * the GitHub URL (or in-page anchor when `preview="drawer"`), emit a
15
+ * sibling hoist sentinel for the drawer pipeline when previewing, and
16
+ * strip the file-ref metas from the rendered tree.
17
+ *
18
+ * Re-entrant per page — the "missing repoUrl" build warning fires at most
19
+ * once per page even when many file-refs share the gap.
20
+ */
21
+ export declare function resolveFileRefs(renderable: unknown, pageUrl: string, repoUrl: string | undefined, repoBranch: string | undefined, ctx: PipelineContext): unknown;
22
+ //# sourceMappingURL=file-ref-resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-ref-resolve.d.ts","sourceRoot":"","sources":["../src/file-ref-resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAyDzD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC9B,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,GAAG,EAAE,eAAe,GAClB,OAAO,CA6BT"}
@@ -0,0 +1,233 @@
1
+ /**
2
+ * file-ref postProcess resolver (SPEC-078, WORK-301).
3
+ *
4
+ * Walks the rendered page, finds `file-ref` sentinels, binds each inline
5
+ * `<a>` to the canonical GitHub URL built from the site's `repoUrl` /
6
+ * `repoBranch`, and (when `preview="drawer"` is set) emits a
7
+ * `hoist-drawer` sentinel that the drawer pipeline picks up to render a
8
+ * preview drawer containing the file's snippet + a "View source on
9
+ * GitHub →" footer link.
10
+ */
11
+ import Markdoc from '@markdoc/markdoc';
12
+ import { buildGithubBlobUrl } from '@refrakt-md/transform';
13
+ import { HOIST_DRAWER_SENTINEL, pathToSlug, registerHoistBuilder, } from './drawer-pipeline.js';
14
+ import { FILE_REF_SENTINEL } from './tags/file-ref.js';
15
+ import { readSnippetFile, SnippetSandboxError } from './lib/read-file.js';
16
+ import { inferLanguage } from './lang-map.js';
17
+ const { Tag } = Markdoc;
18
+ function isTag(node) {
19
+ return Tag.isTag(node);
20
+ }
21
+ function metaContent(tag, field) {
22
+ for (const child of tag.children ?? []) {
23
+ if (isTag(child) && child.name === 'meta' && child.attributes['data-field'] === field) {
24
+ return String(child.attributes.content ?? '');
25
+ }
26
+ }
27
+ return '';
28
+ }
29
+ function hasSentinel(tag) {
30
+ return (tag.children ?? []).some(c => isTag(c) && c.name === 'meta' && c.attributes['data-field'] === FILE_REF_SENTINEL);
31
+ }
32
+ function readQuery(tag) {
33
+ return {
34
+ path: metaContent(tag, 'file-ref-path'),
35
+ lines: metaContent(tag, 'file-ref-lines'),
36
+ label: metaContent(tag, 'file-ref-label'),
37
+ preview: metaContent(tag, 'file-ref-preview'),
38
+ };
39
+ }
40
+ function defaultLabel(path) {
41
+ if (!path)
42
+ return '';
43
+ const trimmed = path.endsWith('/') ? path.slice(0, -1) : path;
44
+ const slash = trimmed.lastIndexOf('/');
45
+ return slash >= 0 ? trimmed.slice(slash + 1) : trimmed;
46
+ }
47
+ /**
48
+ * Resolve every `file-ref` sentinel on the page: bind the inline `<a>` to
49
+ * the GitHub URL (or in-page anchor when `preview="drawer"`), emit a
50
+ * sibling hoist sentinel for the drawer pipeline when previewing, and
51
+ * strip the file-ref metas from the rendered tree.
52
+ *
53
+ * Re-entrant per page — the "missing repoUrl" build warning fires at most
54
+ * once per page even when many file-refs share the gap.
55
+ */
56
+ export function resolveFileRefs(renderable, pageUrl, repoUrl, repoBranch, ctx) {
57
+ // Reset the per-page "missing repoUrl" warning gate.
58
+ const localWarned = { value: false };
59
+ const walk = (node) => {
60
+ if (Array.isArray(node)) {
61
+ let mutated = false;
62
+ const out = node.map(c => {
63
+ const w = walk(c);
64
+ if (w !== c)
65
+ mutated = true;
66
+ return w;
67
+ });
68
+ return mutated ? out : node;
69
+ }
70
+ if (!isTag(node))
71
+ return node;
72
+ const tag = node;
73
+ if (tag.attributes?.['data-rune'] === 'file-ref' && hasSentinel(tag)) {
74
+ return resolveOne(tag, pageUrl, repoUrl, repoBranch, ctx, localWarned);
75
+ }
76
+ if (!tag.children || tag.children.length === 0)
77
+ return tag;
78
+ let mutated = false;
79
+ const next = tag.children.map(c => {
80
+ const w = walk(c);
81
+ if (w !== c)
82
+ mutated = true;
83
+ return w;
84
+ });
85
+ if (!mutated)
86
+ return tag;
87
+ return new Tag(tag.name, tag.attributes, next);
88
+ };
89
+ return walk(renderable);
90
+ }
91
+ function resolveOne(tag, pageUrl, repoUrl, repoBranch, ctx, localWarned) {
92
+ const q = readQuery(tag);
93
+ const label = q.label || defaultLabel(q.path) || q.path;
94
+ const slug = pathToSlug(q.path, q.lines);
95
+ const previewDrawer = q.preview === 'drawer';
96
+ const githubUrl = buildGithubBlobUrl(repoUrl, repoBranch, q.path, q.lines);
97
+ if (!githubUrl && !localWarned.value) {
98
+ ctx.warn(`file-ref on this page has no GitHub URL — site config is missing \`repoUrl\` (path="${q.path}"). Configure \`SiteConfig.repoUrl\` to render canonical "View source" links.`, pageUrl);
99
+ localWarned.value = true;
100
+ }
101
+ // Build the inline anchor. With preview, it points at the hoist anchor;
102
+ // without preview, it points at the GitHub URL (or has no href when
103
+ // repoUrl is absent).
104
+ const anchorAttrs = {};
105
+ if (previewDrawer) {
106
+ anchorAttrs.href = `#drawer-${slug}`;
107
+ anchorAttrs['aria-controls'] = `drawer-${slug}`;
108
+ anchorAttrs['aria-expanded'] = 'false';
109
+ anchorAttrs['data-target-type'] = 'drawer';
110
+ }
111
+ else if (githubUrl) {
112
+ anchorAttrs.href = githubUrl;
113
+ }
114
+ const anchor = new Tag('a', anchorAttrs, [label]);
115
+ const children = [anchor];
116
+ if (previewDrawer) {
117
+ // Emit the hoist sentinel as a sibling of the inline link. The
118
+ // drawer pipeline (WORK-300) picks this up, builds the drawer via
119
+ // the registered builder, and strips this meta from the tree.
120
+ const sentinel = new Tag('meta', {
121
+ 'data-field': HOIST_DRAWER_SENTINEL,
122
+ 'data-source': 'file-ref',
123
+ 'data-target-id': slug,
124
+ 'data-title': label,
125
+ 'data-path': q.path,
126
+ 'data-lines': q.lines,
127
+ 'data-github-url': githubUrl ?? '',
128
+ });
129
+ children.push(sentinel);
130
+ }
131
+ // Preserve the outer span (carrying `data-rune="file-ref"`) so the
132
+ // engine's BEM class on it survives; replace the children with the
133
+ // resolved anchor + (when previewing) hoist sentinel.
134
+ return new Tag(tag.name, tag.attributes, children);
135
+ }
136
+ // ─────────────────────────────────────────────────────────────────────
137
+ // Hoist builder — registered with the drawer pipeline so it can build
138
+ // preview drawers for `file-ref preview="drawer"` references.
139
+ // ─────────────────────────────────────────────────────────────────────
140
+ function buildFileRefHoist(payload, context) {
141
+ const filePath = payload.path;
142
+ const lines = payload.lines;
143
+ const title = payload.title || defaultLabel(filePath);
144
+ const targetId = payload['target-id'];
145
+ const githubUrl = payload['github-url'];
146
+ if (!filePath || !targetId) {
147
+ context.ctx.warn(`file-ref hoist payload missing required path or target-id`, context.pageUrl);
148
+ return null;
149
+ }
150
+ if (!context.projectRoot) {
151
+ context.ctx.error(`file-ref hoist for "${filePath}" requires a project root in the pipeline; none was threaded through. Drawer body will be empty.`, context.pageUrl);
152
+ return null;
153
+ }
154
+ // Read the file (same sandbox as snippet). Errors surface as build
155
+ // errors naming the resolved path and the referencing page.
156
+ let fileContent = '';
157
+ let lang = 'text';
158
+ try {
159
+ const result = readSnippetFile({
160
+ pathAttr: filePath,
161
+ projectRoot: context.projectRoot,
162
+ lines: lines || undefined,
163
+ referencingPage: context.pageUrl,
164
+ });
165
+ fileContent = result.content;
166
+ lang = inferLanguage(result.relativePath);
167
+ for (const w of result.warnings)
168
+ context.ctx.warn(`file-ref ${filePath}: ${w}`, context.pageUrl);
169
+ }
170
+ catch (err) {
171
+ const msg = err instanceof SnippetSandboxError
172
+ ? err.message
173
+ : `file-ref ${filePath}: ${err instanceof Error ? err.message : String(err)}`;
174
+ context.ctx.error(msg, context.pageUrl);
175
+ return null;
176
+ }
177
+ // Drawer body — a figure.rf-snippet wrapping a `<pre data-language>`
178
+ // so the existing snippet CSS + highlight transform pick it up.
179
+ // `data-language` lives on BOTH the <pre> (for snippet CSS hooks +
180
+ // the highlight transform's color-scheme stamping pass) AND on the
181
+ // <code> with text children — the highlight walker only highlights
182
+ // nodes whose children are text, so the <code> is the actual hit.
183
+ const codeBlock = new Tag('pre', {
184
+ 'data-language': lang,
185
+ 'data-codeblock': 'true',
186
+ }, [new Tag('code', { 'data-language': lang, 'data-codeblock': 'true' }, [fileContent])]);
187
+ const snippetFigure = new Tag('figure', {
188
+ class: 'rf-snippet',
189
+ 'data-rune': 'snippet',
190
+ 'data-source-path': filePath,
191
+ ...(lines ? { 'data-lines': lines } : {}),
192
+ }, [codeBlock]);
193
+ const body = new Tag('div', { 'data-name': 'body', class: 'rf-drawer__body' }, [snippetFigure]);
194
+ // Header — title + close button (close hidden until the behavior
195
+ // layer reveals it, same as authored drawers).
196
+ const titleHeading = new Tag('h3', { 'data-name': 'title', class: 'rf-drawer__title' }, [title]);
197
+ const closeButton = new Tag('button', {
198
+ type: 'button',
199
+ 'aria-label': 'Close',
200
+ hidden: true,
201
+ 'data-name': 'close',
202
+ class: 'rf-drawer__close',
203
+ }, ['×']);
204
+ const header = new Tag('header', {
205
+ 'data-name': 'header',
206
+ class: 'rf-drawer__header',
207
+ }, [titleHeading, closeButton]);
208
+ // Footer — "View source on GitHub →" link. Hides when no
209
+ // repoUrl is configured (githubUrl will be empty in the payload).
210
+ const footerChildren = [];
211
+ if (githubUrl) {
212
+ const arrow = ' →';
213
+ footerChildren.push(new Tag('a', { href: githubUrl, rel: 'external noopener', target: '_blank' }, [`View source on GitHub${arrow}`]));
214
+ }
215
+ const footer = footerChildren.length > 0
216
+ ? new Tag('footer', { 'data-name': 'footer', class: 'rf-drawer__footer' }, footerChildren)
217
+ : null;
218
+ const drawerChildren = [header, body];
219
+ if (footer)
220
+ drawerChildren.push(footer);
221
+ const section = new Tag('section', {
222
+ id: `drawer-${targetId}`,
223
+ class: 'rf-drawer',
224
+ 'data-rune': 'drawer',
225
+ 'data-drawer-id': targetId,
226
+ 'data-side': 'right',
227
+ 'data-size': 'md',
228
+ }, drawerChildren);
229
+ return section;
230
+ }
231
+ // Register the builder when this module is imported.
232
+ registerHoistBuilder('file-ref', buildFileRefHoist);
233
+ //# sourceMappingURL=file-ref-resolve.js.map