@glw907/cairn-cms 0.60.0 → 0.62.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 (281) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/dist/components/AdminLayout.svelte +152 -229
  3. package/dist/components/CairnAdmin.svelte +13 -42
  4. package/dist/components/CairnLogo.svelte +1 -6
  5. package/dist/components/CairnMediaLibrary.svelte +821 -1210
  6. package/dist/components/CairnTidySettings.svelte +194 -261
  7. package/dist/components/CairnTidySettings.svelte.d.ts +1 -1
  8. package/dist/components/ComponentForm.svelte +110 -185
  9. package/dist/components/ComponentInsertDialog.svelte +163 -283
  10. package/dist/components/ConceptList.svelte +111 -191
  11. package/dist/components/ConfirmPage.svelte +5 -12
  12. package/dist/components/CsrfField.svelte +5 -11
  13. package/dist/components/DeleteDialog.svelte +15 -42
  14. package/dist/components/EditPage.svelte +781 -1205
  15. package/dist/components/EditorToolbar.svelte +108 -170
  16. package/dist/components/HelpHome.svelte +824 -0
  17. package/dist/components/HelpHome.svelte.d.ts +22 -0
  18. package/dist/components/IconPicker.svelte +23 -53
  19. package/dist/components/LinkPicker.svelte +34 -58
  20. package/dist/components/LoginPage.svelte +14 -27
  21. package/dist/components/ManageEditors.svelte +3 -15
  22. package/dist/components/MarkdownEditor.svelte +689 -957
  23. package/dist/components/MarkdownHelpDialog.svelte +12 -27
  24. package/dist/components/MediaCaptureCard.svelte +18 -57
  25. package/dist/components/MediaFigureControl.svelte +32 -71
  26. package/dist/components/MediaHeroField.svelte +210 -329
  27. package/dist/components/MediaInsertPopover.svelte +156 -283
  28. package/dist/components/MediaPicker.svelte +67 -131
  29. package/dist/components/NavTree.svelte +46 -78
  30. package/dist/components/RenameDialog.svelte +16 -43
  31. package/dist/components/ShortcutsDialog.svelte +9 -13
  32. package/dist/components/ShortcutsGrid.svelte +1 -2
  33. package/dist/components/TidyReview.svelte +140 -248
  34. package/dist/components/WebLinkDialog.svelte +19 -40
  35. package/dist/components/cairn-admin.css +4 -0
  36. package/dist/components/client-ingest.d.ts +16 -8
  37. package/dist/components/client-ingest.js +12 -6
  38. package/dist/components/editor-media.js +16 -8
  39. package/dist/components/editor-placeholder.d.ts +4 -2
  40. package/dist/components/editor-tidy.d.ts +24 -12
  41. package/dist/components/editor-tidy.js +8 -4
  42. package/dist/components/index.d.ts +1 -0
  43. package/dist/components/index.js +1 -0
  44. package/dist/components/link-completion.d.ts +12 -6
  45. package/dist/components/link-completion.js +12 -6
  46. package/dist/components/markdown-directives.d.ts +9 -6
  47. package/dist/components/markdown-directives.js +9 -6
  48. package/dist/components/markdown-format.d.ts +7 -2
  49. package/dist/components/markdown-format.js +59 -28
  50. package/dist/components/markdown-reference.d.ts +8 -0
  51. package/dist/components/markdown-reference.js +22 -0
  52. package/dist/components/media-upload-outcome.d.ts +12 -6
  53. package/dist/components/objective-errors.d.ts +8 -4
  54. package/dist/components/objective-errors.js +8 -4
  55. package/dist/components/preview-doc.d.ts +4 -2
  56. package/dist/components/preview-doc.js +4 -2
  57. package/dist/components/spellcheck.d.ts +57 -29
  58. package/dist/components/spellcheck.js +50 -20
  59. package/dist/components/tidy-categorize.d.ts +20 -10
  60. package/dist/components/tidy-categorize.js +16 -8
  61. package/dist/components/tidy-validate.d.ts +12 -6
  62. package/dist/components/tidy-validate.js +20 -10
  63. package/dist/components/topbar-context.d.ts +4 -2
  64. package/dist/content/advisories.d.ts +51 -0
  65. package/dist/content/advisories.js +79 -0
  66. package/dist/content/compose.d.ts +4 -2
  67. package/dist/content/compose.js +1 -0
  68. package/dist/content/excerpt.js +4 -2
  69. package/dist/content/getting-started.d.ts +18 -0
  70. package/dist/content/getting-started.js +12 -0
  71. package/dist/content/links.d.ts +16 -8
  72. package/dist/content/links.js +12 -6
  73. package/dist/content/manifest.d.ts +36 -18
  74. package/dist/content/manifest.js +32 -16
  75. package/dist/content/media-refs.d.ts +4 -2
  76. package/dist/content/media-refs.js +4 -2
  77. package/dist/content/media-rewrite.d.ts +8 -4
  78. package/dist/content/media-rewrite.js +76 -38
  79. package/dist/content/schema.d.ts +20 -10
  80. package/dist/content/site-dictionary.d.ts +4 -2
  81. package/dist/content/site-dictionary.js +8 -4
  82. package/dist/content/types.d.ts +97 -42
  83. package/dist/delivery/CairnHead.svelte +8 -11
  84. package/dist/delivery/content-index.d.ts +16 -8
  85. package/dist/delivery/feeds.js +4 -2
  86. package/dist/delivery/json-ld.d.ts +3 -0
  87. package/dist/delivery/json-ld.js +3 -0
  88. package/dist/delivery/manifest.d.ts +4 -2
  89. package/dist/delivery/manifest.js +4 -2
  90. package/dist/delivery/public-routes.d.ts +12 -6
  91. package/dist/delivery/public-routes.js +4 -2
  92. package/dist/delivery/seo-fields.d.ts +12 -6
  93. package/dist/delivery/seo-fields.js +8 -4
  94. package/dist/delivery/site-indexes.d.ts +4 -2
  95. package/dist/delivery/site-resolver.d.ts +4 -2
  96. package/dist/delivery/site-resolver.js +4 -2
  97. package/dist/doctor/cloudflare-api.d.ts +6 -0
  98. package/dist/doctor/cloudflare-api.js +6 -0
  99. package/dist/doctor/index.d.ts +12 -6
  100. package/dist/doctor/report.d.ts +3 -0
  101. package/dist/doctor/report.js +3 -0
  102. package/dist/doctor/run.d.ts +3 -0
  103. package/dist/doctor/run.js +3 -0
  104. package/dist/doctor/types.d.ts +10 -2
  105. package/dist/doctor/types.js +6 -0
  106. package/dist/doctor/wrangler-config.d.ts +7 -2
  107. package/dist/doctor/wrangler-config.js +3 -0
  108. package/dist/email.d.ts +4 -2
  109. package/dist/env.d.ts +0 -3
  110. package/dist/env.js +0 -3
  111. package/dist/github/branches.d.ts +4 -2
  112. package/dist/github/branches.js +4 -2
  113. package/dist/github/signing.d.ts +1 -1
  114. package/dist/github/signing.js +2 -2
  115. package/dist/log/events.d.ts +1 -1
  116. package/dist/media/bulk-delete-plan.d.ts +8 -4
  117. package/dist/media/config.d.ts +12 -6
  118. package/dist/media/config.js +16 -8
  119. package/dist/media/delivery-bucket.d.ts +4 -2
  120. package/dist/media/library-entry.d.ts +4 -2
  121. package/dist/media/library-entry.js +4 -2
  122. package/dist/media/manifest.d.ts +29 -15
  123. package/dist/media/manifest.js +29 -16
  124. package/dist/media/naming.d.ts +12 -6
  125. package/dist/media/naming.js +24 -12
  126. package/dist/media/orphan-scan.d.ts +4 -2
  127. package/dist/media/reconcile.d.ts +21 -11
  128. package/dist/media/reconcile.js +12 -6
  129. package/dist/media/reference.d.ts +8 -4
  130. package/dist/media/reference.js +12 -6
  131. package/dist/media/rewrite-plan.d.ts +12 -6
  132. package/dist/media/sniff.d.ts +4 -2
  133. package/dist/media/sniff.js +28 -14
  134. package/dist/media/store.d.ts +16 -8
  135. package/dist/media/store.js +4 -2
  136. package/dist/media/transform-url.d.ts +12 -6
  137. package/dist/media/transform-url.js +8 -4
  138. package/dist/media/usage.d.ts +8 -4
  139. package/dist/nav/site-config.d.ts +16 -8
  140. package/dist/render/component-grammar.d.ts +23 -10
  141. package/dist/render/component-grammar.js +19 -8
  142. package/dist/render/component-insert.d.ts +8 -4
  143. package/dist/render/component-insert.js +4 -2
  144. package/dist/render/component-reference.d.ts +4 -2
  145. package/dist/render/component-reference.js +4 -2
  146. package/dist/render/component-validate.d.ts +3 -0
  147. package/dist/render/component-validate.js +3 -0
  148. package/dist/render/glyph.d.ts +4 -2
  149. package/dist/render/glyph.js +4 -2
  150. package/dist/render/pipeline.d.ts +20 -10
  151. package/dist/render/pipeline.js +4 -2
  152. package/dist/render/registry.d.ts +40 -20
  153. package/dist/render/registry.js +16 -8
  154. package/dist/render/rehype-dispatch.d.ts +22 -8
  155. package/dist/render/rehype-dispatch.js +22 -8
  156. package/dist/render/remark-directives.d.ts +3 -0
  157. package/dist/render/remark-directives.js +3 -0
  158. package/dist/render/remark-figure.d.ts +4 -2
  159. package/dist/render/remark-figure.js +4 -2
  160. package/dist/render/resolve-links.d.ts +4 -2
  161. package/dist/render/resolve-links.js +4 -2
  162. package/dist/render/resolve-media.d.ts +16 -8
  163. package/dist/render/resolve-media.js +12 -6
  164. package/dist/sveltekit/admin-dispatch.d.ts +2 -0
  165. package/dist/sveltekit/admin-dispatch.js +9 -3
  166. package/dist/sveltekit/auth-routes.d.ts +3 -0
  167. package/dist/sveltekit/auth-routes.js +3 -0
  168. package/dist/sveltekit/cairn-admin.d.ts +16 -5
  169. package/dist/sveltekit/cairn-admin.js +26 -10
  170. package/dist/sveltekit/content-routes.d.ts +191 -86
  171. package/dist/sveltekit/content-routes.js +295 -107
  172. package/dist/sveltekit/editors-routes.d.ts +3 -0
  173. package/dist/sveltekit/editors-routes.js +3 -0
  174. package/dist/sveltekit/guard.d.ts +4 -2
  175. package/dist/sveltekit/guard.js +4 -2
  176. package/dist/sveltekit/https-required-page.d.ts +1 -1
  177. package/dist/sveltekit/https-required-page.js +1 -1
  178. package/dist/sveltekit/index.d.ts +1 -1
  179. package/dist/sveltekit/media-route.d.ts +1 -2
  180. package/dist/sveltekit/media-route.js +13 -8
  181. package/dist/sveltekit/nav-routes.d.ts +7 -2
  182. package/dist/sveltekit/nav-routes.js +3 -0
  183. package/dist/sveltekit/types.d.ts +4 -2
  184. package/dist/vite/index.d.ts +32 -16
  185. package/dist/vite/index.js +52 -26
  186. package/dist/vite/resolve-root.d.ts +8 -4
  187. package/dist/vite/resolve-root.js +4 -2
  188. package/package.json +8 -2
  189. package/src/lib/components/AdminLayout.svelte +22 -0
  190. package/src/lib/components/CairnAdmin.svelte +3 -0
  191. package/src/lib/components/CairnTidySettings.svelte +2 -2
  192. package/src/lib/components/ComponentForm.svelte +0 -1
  193. package/src/lib/components/EditPage.svelte +133 -41
  194. package/src/lib/components/HelpHome.svelte +850 -0
  195. package/src/lib/components/MarkdownHelpDialog.svelte +4 -15
  196. package/src/lib/components/client-ingest.ts +20 -10
  197. package/src/lib/components/editor-media.ts +20 -10
  198. package/src/lib/components/editor-placeholder.ts +12 -6
  199. package/src/lib/components/editor-tidy.ts +28 -14
  200. package/src/lib/components/index.ts +1 -0
  201. package/src/lib/components/link-completion.ts +12 -6
  202. package/src/lib/components/markdown-directives.ts +13 -8
  203. package/src/lib/components/markdown-format.ts +63 -30
  204. package/src/lib/components/markdown-reference.ts +30 -0
  205. package/src/lib/components/media-upload-outcome.ts +12 -6
  206. package/src/lib/components/objective-errors.ts +16 -8
  207. package/src/lib/components/preview-doc.ts +4 -2
  208. package/src/lib/components/spellcheck.ts +92 -40
  209. package/src/lib/components/tidy-categorize.ts +28 -14
  210. package/src/lib/components/tidy-validate.ts +28 -14
  211. package/src/lib/components/topbar-context.ts +4 -2
  212. package/src/lib/content/advisories.ts +141 -0
  213. package/src/lib/content/compose.ts +5 -2
  214. package/src/lib/content/excerpt.ts +4 -2
  215. package/src/lib/content/getting-started.ts +31 -0
  216. package/src/lib/content/links.ts +16 -8
  217. package/src/lib/content/manifest.ts +36 -18
  218. package/src/lib/content/media-refs.ts +4 -2
  219. package/src/lib/content/media-rewrite.ts +100 -50
  220. package/src/lib/content/schema.ts +20 -10
  221. package/src/lib/content/site-dictionary.ts +8 -4
  222. package/src/lib/content/types.ts +97 -42
  223. package/src/lib/delivery/content-index.ts +16 -8
  224. package/src/lib/delivery/feeds.ts +4 -2
  225. package/src/lib/delivery/json-ld.ts +3 -0
  226. package/src/lib/delivery/manifest.ts +4 -2
  227. package/src/lib/delivery/public-routes.ts +16 -8
  228. package/src/lib/delivery/seo-fields.ts +12 -6
  229. package/src/lib/delivery/site-indexes.ts +4 -2
  230. package/src/lib/delivery/site-resolver.ts +4 -2
  231. package/src/lib/doctor/cloudflare-api.ts +6 -0
  232. package/src/lib/doctor/index.ts +12 -6
  233. package/src/lib/doctor/report.ts +3 -0
  234. package/src/lib/doctor/run.ts +3 -0
  235. package/src/lib/doctor/types.ts +10 -2
  236. package/src/lib/doctor/wrangler-config.ts +7 -2
  237. package/src/lib/email.ts +4 -2
  238. package/src/lib/env.ts +0 -3
  239. package/src/lib/github/branches.ts +4 -2
  240. package/src/lib/github/signing.ts +2 -2
  241. package/src/lib/log/events.ts +1 -0
  242. package/src/lib/media/bulk-delete-plan.ts +8 -4
  243. package/src/lib/media/config.ts +24 -12
  244. package/src/lib/media/delivery-bucket.ts +4 -2
  245. package/src/lib/media/library-entry.ts +4 -2
  246. package/src/lib/media/manifest.ts +33 -18
  247. package/src/lib/media/naming.ts +24 -12
  248. package/src/lib/media/orphan-scan.ts +4 -2
  249. package/src/lib/media/reconcile.ts +21 -11
  250. package/src/lib/media/reference.ts +12 -6
  251. package/src/lib/media/rewrite-plan.ts +12 -6
  252. package/src/lib/media/sniff.ts +28 -14
  253. package/src/lib/media/store.ts +16 -8
  254. package/src/lib/media/transform-url.ts +12 -6
  255. package/src/lib/media/usage.ts +8 -4
  256. package/src/lib/nav/site-config.ts +16 -8
  257. package/src/lib/render/component-grammar.ts +23 -10
  258. package/src/lib/render/component-insert.ts +8 -4
  259. package/src/lib/render/component-reference.ts +4 -2
  260. package/src/lib/render/component-validate.ts +3 -0
  261. package/src/lib/render/glyph.ts +4 -2
  262. package/src/lib/render/pipeline.ts +20 -10
  263. package/src/lib/render/registry.ts +44 -22
  264. package/src/lib/render/rehype-dispatch.ts +22 -8
  265. package/src/lib/render/remark-directives.ts +3 -0
  266. package/src/lib/render/remark-figure.ts +4 -2
  267. package/src/lib/render/resolve-links.ts +4 -2
  268. package/src/lib/render/resolve-media.ts +16 -8
  269. package/src/lib/sveltekit/admin-dispatch.ts +10 -4
  270. package/src/lib/sveltekit/auth-routes.ts +3 -0
  271. package/src/lib/sveltekit/cairn-admin.ts +37 -15
  272. package/src/lib/sveltekit/content-routes.ts +492 -197
  273. package/src/lib/sveltekit/editors-routes.ts +3 -0
  274. package/src/lib/sveltekit/guard.ts +4 -2
  275. package/src/lib/sveltekit/https-required-page.ts +1 -1
  276. package/src/lib/sveltekit/index.ts +3 -0
  277. package/src/lib/sveltekit/media-route.ts +13 -8
  278. package/src/lib/sveltekit/nav-routes.ts +7 -2
  279. package/src/lib/sveltekit/types.ts +4 -2
  280. package/src/lib/vite/index.ts +60 -30
  281. package/src/lib/vite/resolve-root.ts +8 -4
@@ -5,8 +5,10 @@
5
5
  * advisory. Recognizes JPEG, PNG, GIF, WebP, and the AVIF/HEIC ISO-BMFF brands.
6
6
  */
7
7
  export declare function sniffMediaType(bytes: Uint8Array): string | null;
8
- /** The storage extension for a sniffed media type, or null for a type the upload path does not store
9
- * (HEIC, an unknown type). Driven by the sniffed type, so the key's ext is server-owned. */
8
+ /**
9
+ * The storage extension for a sniffed media type, or null for a type the upload path does not store
10
+ * (HEIC, an unknown type). Driven by the sniffed type, so the key's ext is server-owned.
11
+ */
10
12
  export declare function extForMediaType(type: string): string | null;
11
13
  /**
12
14
  * The engine-level upload deny predicate. Returns true (reject) when the upload is markup a site can
@@ -7,21 +7,29 @@
7
7
  // and this byte check sees only the magic. The delivery route's response headers (X-Content-Type-Options:
8
8
  // nosniff, Content-Disposition: inline, a restrictive Content-Security-Policy) are the real XSS control
9
9
  // for the served bytes; sniffing here is the ingest gate, not the served-bytes defense.
10
- /** The leading ASCII whitespace bytes skipped before the deny-list's first-byte-is-`<` check:
11
- * tab (0x09), newline (0x0A), carriage return (0x0D), and space (0x20). */
10
+ /**
11
+ * The leading ASCII whitespace bytes skipped before the deny-list's first-byte-is-`<` check:
12
+ * tab (0x09), newline (0x0A), carriage return (0x0D), and space (0x20).
13
+ */
12
14
  const WHITESPACE = new Set([0x09, 0x0a, 0x0d, 0x20]);
13
- /** The single byte `<` (0x3C). A payload whose first non-whitespace byte is `<` is markup (SVG, HTML,
14
- * XML) and is denied regardless of its declared type or any site `allowedTypes`. */
15
+ /**
16
+ * The single byte `<` (0x3C). A payload whose first non-whitespace byte is `<` is markup (SVG, HTML,
17
+ * XML) and is denied regardless of its declared type or any site `allowedTypes`.
18
+ */
15
19
  const LT = 0x3c;
16
- /** Declared content types denied at the engine level, independent of any site `allowedTypes`. SVG and
17
- * the markup types carry active content (script, foreignObject), so they never ingest as media. */
20
+ /**
21
+ * Declared content types denied at the engine level, independent of any site `allowedTypes`. SVG and
22
+ * the markup types carry active content (script, foreignObject), so they never ingest as media.
23
+ */
18
24
  const DENIED_TYPES = new Set(['image/svg+xml', 'image/svg', 'text/html', 'application/xml']);
19
25
  /** The ISO-BMFF major-brand codes (at bytes 8..11 of an `ftyp` box) that mean an AVIF image. */
20
26
  const AVIF_BRANDS = new Set(['avif', 'avis']);
21
27
  /** The ISO-BMFF major-brand codes that mean a HEIF/HEIC image. */
22
28
  const HEIC_BRANDS = new Set(['heic', 'heix', 'heif', 'hevc', 'hevx', 'mif1', 'msf1']);
23
- /** True when every byte of `magic` matches `bytes` starting at `offset`. False if `bytes` is too
24
- * short to hold the whole magic. */
29
+ /**
30
+ * True when every byte of `magic` matches `bytes` starting at `offset`. False if `bytes` is too
31
+ * short to hold the whole magic.
32
+ */
25
33
  function matches(bytes, offset, magic) {
26
34
  if (bytes.length < offset + magic.length)
27
35
  return false;
@@ -31,8 +39,10 @@ function matches(bytes, offset, magic) {
31
39
  }
32
40
  return true;
33
41
  }
34
- /** The four ASCII characters at bytes `offset..offset+3`, or null when the input is too short. Used to
35
- * read an ISO-BMFF brand code as a string. */
42
+ /**
43
+ * The four ASCII characters at bytes `offset..offset+3`, or null when the input is too short. Used to
44
+ * read an ISO-BMFF brand code as a string.
45
+ */
36
46
  function ascii4(bytes, offset) {
37
47
  if (bytes.length < offset + 4)
38
48
  return null;
@@ -71,9 +81,11 @@ export function sniffMediaType(bytes) {
71
81
  }
72
82
  return null;
73
83
  }
74
- /** The bare file extension (no dot) for each sniffed media type the upload path stores. The ext is
84
+ /**
85
+ * The bare file extension (no dot) for each sniffed media type the upload path stores. The ext is
75
86
  * derived from the server-sniffed type, never the client filename, so the stored key and the
76
- * delivery extension allow-list always agree. An unmappable type returns null (the upload 415s). */
87
+ * delivery extension allow-list always agree. An unmappable type returns null (the upload 415s).
88
+ */
77
89
  const EXT_BY_TYPE = {
78
90
  'image/jpeg': 'jpg',
79
91
  'image/png': 'png',
@@ -81,8 +93,10 @@ const EXT_BY_TYPE = {
81
93
  'image/webp': 'webp',
82
94
  'image/avif': 'avif',
83
95
  };
84
- /** The storage extension for a sniffed media type, or null for a type the upload path does not store
85
- * (HEIC, an unknown type). Driven by the sniffed type, so the key's ext is server-owned. */
96
+ /**
97
+ * The storage extension for a sniffed media type, or null for a type the upload path does not store
98
+ * (HEIC, an unknown type). Driven by the sniffed type, so the key's ext is server-owned.
99
+ */
86
100
  export function extForMediaType(type) {
87
101
  return EXT_BY_TYPE[type] ?? null;
88
102
  }
@@ -1,17 +1,23 @@
1
1
  import type { R2Bucket, R2Conditional, R2HTTPMetadata, R2Object, R2ObjectBody, R2Range } from '@cloudflare/workers-types';
2
- /** The narrow R2 surface the media pipeline uses. The engine depends on this, not on R2Bucket, so the
3
- * multipart, list, and conditional-read surface R2 also carries never leaks into the media code. */
2
+ /**
3
+ * The narrow R2 surface the media pipeline uses. The engine depends on this, not on R2Bucket, so the
4
+ * multipart, list, and conditional-read surface R2 also carries never leaks into the media code.
5
+ */
4
6
  export interface MediaStore {
5
- /** Store bytes under a content-addressed key, with the response HTTP metadata (the content type)
7
+ /**
8
+ * Store bytes under a content-addressed key, with the response HTTP metadata (the content type)
6
9
  * and optional custom metadata (the upload stores the full sha256 here, so a short-hash collision
7
- * is detectable on a later dedup probe). */
10
+ * is detectable on a later dedup probe).
11
+ */
8
12
  put(key: string, bytes: ArrayBuffer | Uint8Array, httpMetadata?: R2HTTPMetadata, customMetadata?: Record<string, string>): Promise<void>;
9
13
  /** The object's metadata, or null when no object lives at the key (the dedup probe). */
10
14
  head(key: string): Promise<R2Object | null>;
11
- /** The object body for streaming to a delivery response, or null when the key is absent. The
15
+ /**
16
+ * The object body for streaming to a delivery response, or null when the key is absent. The
12
17
  * delivery route passes `onlyIf` and `range` through for conditional and partial reads: an
13
18
  * `onlyIf` etag match returns a body-less R2Object (the 304 shape), so the return widens to
14
- * `R2Object` alongside `R2ObjectBody`. */
19
+ * `R2Object` alongside `R2ObjectBody`.
20
+ */
15
21
  get(key: string, opts?: {
16
22
  range?: R2Range;
17
23
  onlyIf?: R2Conditional;
@@ -19,7 +25,9 @@ export interface MediaStore {
19
25
  /** Remove the object at the key. A delete of an absent key is a no-op, the R2 contract. */
20
26
  delete(key: string): Promise<void>;
21
27
  }
22
- /** Wrap an R2 bucket binding as a MediaStore. Each method delegates to the binding; put folds the
28
+ /**
29
+ * Wrap an R2 bucket binding as a MediaStore. Each method delegates to the binding; put folds the
23
30
  * HTTP and custom metadata into R2's options shape and drops the returned R2Object the pipeline does
24
- * not read. */
31
+ * not read.
32
+ */
25
33
  export declare function r2Store(bucket: R2Bucket): MediaStore;
@@ -1,6 +1,8 @@
1
- /** Wrap an R2 bucket binding as a MediaStore. Each method delegates to the binding; put folds the
1
+ /**
2
+ * Wrap an R2 bucket binding as a MediaStore. Each method delegates to the binding; put folds the
2
3
  * HTTP and custom metadata into R2's options shape and drops the returned R2Object the pipeline does
3
- * not read. */
4
+ * not read.
5
+ */
4
6
  export function r2Store(bucket) {
5
7
  return {
6
8
  async put(key, bytes, httpMetadata, customMetadata) {
@@ -1,6 +1,8 @@
1
- /** A single image variant: the resize and format directives Cloudflare Images applies to the
1
+ /**
2
+ * A single image variant: the resize and format directives Cloudflare Images applies to the
2
3
  * original bytes. Every field is optional. width, height, quality, and fit are emitted only when
3
- * set; format and gravity always appear, defaulting to auto. */
4
+ * set; format and gravity always appear, defaulting to auto.
5
+ */
4
6
  export interface VariantSpec {
5
7
  /** Target width in pixels. */
6
8
  width?: number;
@@ -15,12 +17,16 @@ export interface VariantSpec {
15
17
  /** Output format, `auto` to let Cloudflare negotiate, or a forced codec. */
16
18
  format?: 'auto' | 'webp' | 'avif' | string;
17
19
  }
18
- /** Build the on-demand Cloudflare Images transform URL for a delivery path. The options are
20
+ /**
21
+ * Build the on-demand Cloudflare Images transform URL for a delivery path. The options are
19
22
  * comma-joined in the stable order width, height, quality, fit, format, gravity, with width through
20
23
  * fit emitted only when the spec sets them and format and gravity always present (defaulting to
21
- * auto). The publicPath is appended unaltered, so the result is `/cdn-cgi/image/<options><publicPath>`. */
24
+ * auto). The publicPath is appended unaltered, so the result is `/cdn-cgi/image/<options><publicPath>`.
25
+ */
22
26
  export declare function variantUrl(publicPath: string, spec: VariantSpec): string;
23
- /** Build a variant URL from a named preset. Looks up presetName in variants and builds its spec with
27
+ /**
28
+ * Build a variant URL from a named preset. Looks up presetName in variants and builds its spec with
24
29
  * variantUrl. Throws a cairn:-prefixed error naming the unknown preset when the name is absent, so a
25
- * typo in a preset name fails loudly rather than silently rendering an unsized image. */
30
+ * typo in a preset name fails loudly rather than silently rendering an unsized image.
31
+ */
26
32
  export declare function presetUrl(publicPath: string, presetName: string, variants: Record<string, VariantSpec>): string;
@@ -4,10 +4,12 @@
4
4
  // the option encoding and the stable option order, so the same spec always builds the same URL and
5
5
  // a CDN cache keys on it cleanly. The delivery path is appended unaltered, since it already carries
6
6
  // its own leading slash.
7
- /** Build the on-demand Cloudflare Images transform URL for a delivery path. The options are
7
+ /**
8
+ * Build the on-demand Cloudflare Images transform URL for a delivery path. The options are
8
9
  * comma-joined in the stable order width, height, quality, fit, format, gravity, with width through
9
10
  * fit emitted only when the spec sets them and format and gravity always present (defaulting to
10
- * auto). The publicPath is appended unaltered, so the result is `/cdn-cgi/image/<options><publicPath>`. */
11
+ * auto). The publicPath is appended unaltered, so the result is `/cdn-cgi/image/<options><publicPath>`.
12
+ */
11
13
  export function variantUrl(publicPath, spec) {
12
14
  const options = [];
13
15
  if (spec.width !== undefined)
@@ -26,9 +28,11 @@ export function variantUrl(publicPath, spec) {
26
28
  const source = publicPath.startsWith('/') ? publicPath : `/${publicPath}`;
27
29
  return `/cdn-cgi/image/${options.join(',')}${source}`;
28
30
  }
29
- /** Build a variant URL from a named preset. Looks up presetName in variants and builds its spec with
31
+ /**
32
+ * Build a variant URL from a named preset. Looks up presetName in variants and builds its spec with
30
33
  * variantUrl. Throws a cairn:-prefixed error naming the unknown preset when the name is absent, so a
31
- * typo in a preset name fails loudly rather than silently rendering an unsized image. */
34
+ * typo in a preset name fails loudly rather than silently rendering an unsized image.
35
+ */
32
36
  export function presetUrl(publicPath, presetName, variants) {
33
37
  const spec = variants[presetName];
34
38
  if (spec === undefined) {
@@ -21,13 +21,17 @@ export interface UsageEntry {
21
21
  /** Published vs the cairn/* branch the edit lives on. */
22
22
  origin: UsageOrigin;
23
23
  }
24
- /** Content hash to the distinct entries that reference it. A hash with no row is "no references
25
- * found" (see the raw-HTML caveat above), never a proven orphan. */
24
+ /**
25
+ * Content hash to the distinct entries that reference it. A hash with no row is "no references
26
+ * found" (see the raw-HTML caveat above), never a proven orphan.
27
+ */
26
28
  export type UsageIndex = Map<string, UsageEntry[]>;
27
- /** Build options. `branches` lets a caller that already listed the open cairn/* branches pass them
29
+ /**
30
+ * Build options. `branches` lets a caller that already listed the open cairn/* branches pass them
28
31
  * in so the index does not list them a second time (the load path lists once for the media-union).
29
32
  * `strict` flips the per-branch read from degrade-and-skip to fail-closed: a delete gate must not
30
- * treat a transient branch-read failure as an absent reference, so it rethrows instead. */
33
+ * treat a transient branch-read failure as an absent reference, so it rethrows instead.
34
+ */
31
35
  export interface BuildUsageOptions {
32
36
  /** The open cairn/* branch names, already listed. When present the index skips its own listing. */
33
37
  branches?: string[];
@@ -34,16 +34,20 @@ export interface SiteConfig {
34
34
  menus?: Record<string, unknown>;
35
35
  /** Per-concept URL policy: the permalink pattern and date-prefix granularity, keyed by concept id. */
36
36
  content?: Record<string, ConceptUrlPolicy>;
37
- /** The editor spellcheck settings. The dialect is declared once per site (spec 1.2), so a British
37
+ /**
38
+ * The editor spellcheck settings. The dialect is declared once per site (spec 1.2), so a British
38
39
  * site loads the British word list and "colour" reads as correct. Today only US English ships, so an
39
- * unset or unknown dialect resolves to it. */
40
+ * unset or unknown dialect resolves to it.
41
+ */
40
42
  spellcheck?: {
41
43
  dialect?: string;
42
44
  };
43
- /** The editor tidy (LLM copy-edit) settings. Opt-in at the site level (spec 2.8): tidy is a remote,
45
+ /**
46
+ * The editor tidy (LLM copy-edit) settings. Opt-in at the site level (spec 2.8): tidy is a remote,
44
47
  * costly model call, so the whole block is optional and `enabled` defaults false. The model is a
45
48
  * developer-tier fact; the `conventions` block is the editor-tier per-convention config that builds
46
- * the prompt's CONVENTIONS section. The Anthropic API key is a Worker secret, never config. */
49
+ * the prompt's CONVENTIONS section. The Anthropic API key is a Worker secret, never config.
50
+ */
47
51
  tidy?: TidyConfig;
48
52
  [key: string]: unknown;
49
53
  }
@@ -69,14 +73,18 @@ export declare const DEFAULT_TIDY_MODEL = "claude-sonnet-4-6";
69
73
  * Sentence spacing is dropped on purpose and regional spelling is `spellcheck.dialect`, not a toggle.
70
74
  */
71
75
  export interface TidyConventions {
72
- /** The objective Fixes group (spelling, grammar, doubled words, whitespace, capitals, terminal
76
+ /**
77
+ * The objective Fixes group (spelling, grammar, doubled words, whitespace, capitals, terminal
73
78
  * punctuation). Default on. The always-on core governs it; this toggle lets the screen turn the
74
- * group off. */
79
+ * group off.
80
+ */
75
81
  fixes: boolean;
76
82
  /** Oxford comma position. Off when undefined; `always` | `complex-only` (AP) | `never`. */
77
83
  oxfordComma?: 'always' | 'complex-only' | 'never';
78
- /** Number style threshold. Off when undefined; the always-numeral exception sets (ages, dates,
79
- * measurements, percentages) apply at any threshold. */
84
+ /**
85
+ * Number style threshold. Off when undefined; the always-numeral exception sets (ages, dates,
86
+ * measurements, percentages) apply at any threshold.
87
+ */
80
88
  numberStyle?: 'under-ten' | 'under-hundred' | 'always-numerals';
81
89
  /** Measurement notation only (never the system, never the number). Off when undefined. */
82
90
  measurements?: 'abbreviate' | 'spell-out';
@@ -1,21 +1,31 @@
1
1
  import type { ComponentDef, ComponentValues } from './registry.js';
2
+ /**
3
+ *
4
+ */
2
5
  export declare function serializeComponent(def: ComponentDef, values: ComponentValues): string;
3
- /** Parse a serialized component directive back into guided-form values, the inverse of
6
+ /**
7
+ * Parse a serialized component directive back into guided-form values, the inverse of
4
8
  * {@link serializeComponent}. The grammar is reversible, so the editor can round-trip a
5
- * saved directive through the form. */
9
+ * saved directive through the form.
10
+ */
6
11
  export declare function parseComponent(markdown: string, def: ComponentDef): Promise<ComponentValues>;
7
- /** The raw attribute keys present on the component's opening directive, read from the parsed tree
8
- * (quote-aware, unlike a regex over the source). Used by validation to flag unknown keys. */
12
+ /**
13
+ * The raw attribute keys present on the component's opening directive, read from the parsed tree
14
+ * (quote-aware, unlike a regex over the source). Used by validation to flag unknown keys.
15
+ */
9
16
  export declare function parseRawAttributeKeys(markdown: string, def: ComponentDef): string[];
10
- /** The result of {@link componentRoundTripSafety}: whether re-opening a placed block into the
11
- * guided form and re-serializing it is provably lossless. */
17
+ /**
18
+ * The result of {@link componentRoundTripSafety}: whether re-opening a placed block into the
19
+ * guided form and re-serializing it is provably lossless.
20
+ */
12
21
  export type RoundTripSafety = {
13
22
  safe: true;
14
23
  } | {
15
24
  safe: false;
16
25
  reason: 'unknown-attribute' | 'undeclared-child' | 'not-idempotent' | 'not-a-component';
17
26
  };
18
- /** Decide whether guided edit of this placed block is provably lossless. A block a person typed by
27
+ /**
28
+ * Decide whether guided edit of this placed block is provably lossless. A block a person typed by
19
29
  * hand can carry more than the schema models (an attribute the def does not list, a child container
20
30
  * the def does not declare, slot content the form cannot represent stably), and parsing such a block
21
31
  * into the form then re-serializing would silently drop it. The edit affordance is offered only when
@@ -25,11 +35,14 @@ export type RoundTripSafety = {
25
35
  * 2. `unknown-attribute`: the block carries an attribute key the def does not declare.
26
36
  * 3. `undeclared-child`: the root has a direct child container directive that is not a declared
27
37
  * nested slot. Such a child would otherwise fold into the body slot and move on re-serialize.
28
- * 4. `not-idempotent`: `parse -> serialize -> parse` does not recover the same values. */
38
+ * 4. `not-idempotent`: `parse -> serialize -> parse` does not recover the same values.
39
+ */
29
40
  export declare function componentRoundTripSafety(markdown: string, def: ComponentDef): Promise<RoundTripSafety>;
30
- /** Parse the component once and derive both the guided-form values and the raw attribute keys.
41
+ /**
42
+ * Parse the component once and derive both the guided-form values and the raw attribute keys.
31
43
  * Validation needs both, so this seam spares it the double parse that calling
32
- * {@link parseComponent} and {@link parseRawAttributeKeys} separately would cost. */
44
+ * {@link parseComponent} and {@link parseRawAttributeKeys} separately would cost.
45
+ */
33
46
  export declare function parseComponentWithRawKeys(markdown: string, def: ComponentDef): Promise<{
34
47
  values: ComponentValues;
35
48
  rawKeys: string[];
@@ -28,6 +28,9 @@ function slotByName(def, name) {
28
28
  function nestedSlots(def) {
29
29
  return (def.slots ?? []).filter((s) => s.name !== 'title' && s.name !== 'body');
30
30
  }
31
+ /**
32
+ *
33
+ */
31
34
  export function serializeComponent(def, values) {
32
35
  const fence = COLON.repeat(nestedSlots(def).length > 0 ? 4 : 3);
33
36
  const title = slotByName(def, 'title') ? values.slots.title ?? '' : '';
@@ -109,18 +112,23 @@ function valuesFromRoot(root, def) {
109
112
  function rawKeysFromRoot(root) {
110
113
  return Object.keys(root?.attributes ?? {});
111
114
  }
112
- /** Parse a serialized component directive back into guided-form values, the inverse of
115
+ /**
116
+ * Parse a serialized component directive back into guided-form values, the inverse of
113
117
  * {@link serializeComponent}. The grammar is reversible, so the editor can round-trip a
114
- * saved directive through the form. */
118
+ * saved directive through the form.
119
+ */
115
120
  export async function parseComponent(markdown, def) {
116
121
  return valuesFromRoot(findComponentRoot(markdown, def), def);
117
122
  }
118
- /** The raw attribute keys present on the component's opening directive, read from the parsed tree
119
- * (quote-aware, unlike a regex over the source). Used by validation to flag unknown keys. */
123
+ /**
124
+ * The raw attribute keys present on the component's opening directive, read from the parsed tree
125
+ * (quote-aware, unlike a regex over the source). Used by validation to flag unknown keys.
126
+ */
120
127
  export function parseRawAttributeKeys(markdown, def) {
121
128
  return rawKeysFromRoot(findComponentRoot(markdown, def));
122
129
  }
123
- /** Decide whether guided edit of this placed block is provably lossless. A block a person typed by
130
+ /**
131
+ * Decide whether guided edit of this placed block is provably lossless. A block a person typed by
124
132
  * hand can carry more than the schema models (an attribute the def does not list, a child container
125
133
  * the def does not declare, slot content the form cannot represent stably), and parsing such a block
126
134
  * into the form then re-serializing would silently drop it. The edit affordance is offered only when
@@ -130,7 +138,8 @@ export function parseRawAttributeKeys(markdown, def) {
130
138
  * 2. `unknown-attribute`: the block carries an attribute key the def does not declare.
131
139
  * 3. `undeclared-child`: the root has a direct child container directive that is not a declared
132
140
  * nested slot. Such a child would otherwise fold into the body slot and move on re-serialize.
133
- * 4. `not-idempotent`: `parse -> serialize -> parse` does not recover the same values. */
141
+ * 4. `not-idempotent`: `parse -> serialize -> parse` does not recover the same values.
142
+ */
134
143
  export async function componentRoundTripSafety(markdown, def) {
135
144
  const root = findComponentRoot(markdown, def);
136
145
  if (!root)
@@ -154,9 +163,11 @@ export async function componentRoundTripSafety(markdown, def) {
154
163
  return { safe: false, reason: 'not-idempotent' };
155
164
  return { safe: true };
156
165
  }
157
- /** Parse the component once and derive both the guided-form values and the raw attribute keys.
166
+ /**
167
+ * Parse the component once and derive both the guided-form values and the raw attribute keys.
158
168
  * Validation needs both, so this seam spares it the double parse that calling
159
- * {@link parseComponent} and {@link parseRawAttributeKeys} separately would cost. */
169
+ * {@link parseComponent} and {@link parseRawAttributeKeys} separately would cost.
170
+ */
160
171
  export async function parseComponentWithRawKeys(markdown, def) {
161
172
  const root = findComponentRoot(markdown, def);
162
173
  return { values: valuesFromRoot(root, def), rawKeys: rawKeysFromRoot(root) };
@@ -1,6 +1,8 @@
1
1
  import type { ComponentDef, ComponentValues } from './registry.js';
2
- /** The outcome of preparing a guided-form component for insertion: the markdown to insert, or the
3
- * field-keyed errors to show on the form. */
2
+ /**
3
+ * The outcome of preparing a guided-form component for insertion: the markdown to insert, or the
4
+ * field-keyed errors to show on the form.
5
+ */
4
6
  export type ComponentInsert = {
5
7
  ok: true;
6
8
  markdown: string;
@@ -8,6 +10,8 @@ export type ComponentInsert = {
8
10
  ok: false;
9
11
  errors: Record<string, string>;
10
12
  };
11
- /** Serialize a component's form values, then validate the result against its schema. Returns the
12
- * markdown to insert at the cursor, or the field errors keyed by attribute key or slot name. */
13
+ /**
14
+ * Serialize a component's form values, then validate the result against its schema. Returns the
15
+ * markdown to insert at the cursor, or the field errors keyed by attribute key or slot name.
16
+ */
13
17
  export declare function buildComponentInsert(def: ComponentDef, values: ComponentValues): Promise<ComponentInsert>;
@@ -1,7 +1,9 @@
1
1
  import { serializeComponent } from './component-grammar.js';
2
2
  import { validateComponent } from './component-validate.js';
3
- /** Serialize a component's form values, then validate the result against its schema. Returns the
4
- * markdown to insert at the cursor, or the field errors keyed by attribute key or slot name. */
3
+ /**
4
+ * Serialize a component's form values, then validate the result against its schema. Returns the
5
+ * markdown to insert at the cursor, or the field errors keyed by attribute key or slot name.
6
+ */
5
7
  export async function buildComponentInsert(def, values) {
6
8
  const markdown = serializeComponent(def, values);
7
9
  const verdict = await validateComponent(markdown, def);
@@ -5,6 +5,8 @@ export interface ReferenceOptions {
5
5
  /** The one-line blockquote summary under the title. */
6
6
  summary: string;
7
7
  }
8
- /** Build a self-contained markdown reference (the llms-full.txt shape) for a component registry, for
9
- * authors and for pointing an LLM at one curated file. */
8
+ /**
9
+ * Build a self-contained markdown reference (the llms-full.txt shape) for a component registry, for
10
+ * authors and for pointing an LLM at one curated file.
11
+ */
10
12
  export declare function generateComponentReference(registry: ComponentRegistry, opts: ReferenceOptions): string;
@@ -1,7 +1,9 @@
1
1
  import { serializeComponent } from './component-grammar.js';
2
2
  import { emptyValues } from './registry.js';
3
- /** Build a self-contained markdown reference (the llms-full.txt shape) for a component registry, for
4
- * authors and for pointing an LLM at one curated file. */
3
+ /**
4
+ * Build a self-contained markdown reference (the llms-full.txt shape) for a component registry, for
5
+ * authors and for pointing an LLM at one curated file.
6
+ */
5
7
  export function generateComponentReference(registry, opts) {
6
8
  const sections = registry.defs.map((def) => componentSection(def));
7
9
  return `# ${opts.title}\n\n> ${opts.summary}\n\n${sections.join('\n\n')}\n`;
@@ -6,4 +6,7 @@ export type ComponentValidation = {
6
6
  ok: false;
7
7
  errors: Record<string, string>;
8
8
  };
9
+ /**
10
+ *
11
+ */
9
12
  export declare function validateComponent(markdown: string, def: ComponentDef): Promise<ComponentValidation>;
@@ -1,4 +1,7 @@
1
1
  import { parseComponentWithRawKeys } from './component-grammar.js';
2
+ /**
3
+ *
4
+ */
2
5
  export async function validateComponent(markdown, def) {
3
6
  const { values, rawKeys } = await parseComponentWithRawKeys(markdown, def);
4
7
  const errors = {};
@@ -1,8 +1,10 @@
1
1
  import type { Element } from 'hast';
2
2
  /** A glyph name to SVG path-data map (the site owns the icon set). */
3
3
  export type IconSet = Record<string, string>;
4
- /** Inline SVG glyph as a real hast node: class ec-glyph, 256 viewBox, currentColor fill.
4
+ /**
5
+ * Inline SVG glyph as a real hast node: class ec-glyph, 256 viewBox, currentColor fill.
5
6
  * An unknown icon name yields the bare svg shell with no path child, so it never serializes
6
7
  * a stray empty (or undefined) path. Callers always wrap the returned element, so the shell
7
- * keeps them safe. */
8
+ * keeps them safe.
9
+ */
8
10
  export declare function glyph(name: string, icons: IconSet): Element;
@@ -1,8 +1,10 @@
1
1
  import { s } from 'hastscript';
2
- /** Inline SVG glyph as a real hast node: class ec-glyph, 256 viewBox, currentColor fill.
2
+ /**
3
+ * Inline SVG glyph as a real hast node: class ec-glyph, 256 viewBox, currentColor fill.
3
4
  * An unknown icon name yields the bare svg shell with no path child, so it never serializes
4
5
  * a stray empty (or undefined) path. Callers always wrap the returned element, so the shell
5
- * keeps them safe. */
6
+ * keeps them safe.
7
+ */
6
8
  export function glyph(name, icons) {
7
9
  const d = icons[name];
8
10
  return s('svg', { className: ['ec-glyph'], viewBox: '0 0 256 256', fill: 'currentColor', ariaHidden: 'true' }, d == null ? [] : [s('path', { d })]);
@@ -4,27 +4,37 @@ import { type MediaResolve } from './resolve-media.js';
4
4
  import { type ComponentRegistry } from './registry.js';
5
5
  import type { LinkResolve } from '../content/links.js';
6
6
  export interface RendererOptions {
7
- /** Stamp a `data-rise` ordinal (0, 1, 2, …) on each top-level component so a site's
7
+ /**
8
+ * Stamp a `data-rise` ordinal (0, 1, 2, …) on each top-level component so a site's
8
9
  * CSS can drive an entrance-cascade delay off it. Omit for no stagger. The ordinal
9
- * is inert, so a consumer's sanitize floor can keep `data-rise` and drop `style`. */
10
+ * is inert, so a consumer's sanitize floor can keep `data-rise` and drop `style`.
11
+ */
10
12
  stagger?: boolean;
11
- /** Extend the sanitize allowlist. Receives cairn's default schema (defaultSchema plus the
13
+ /**
14
+ * Extend the sanitize allowlist. Receives cairn's default schema (defaultSchema plus the
12
15
  * directive markers and the common benign tags) and returns the schema to use. Add to the
13
16
  * allowlist for the benign HTML a site's content needs; start from the argument so the
14
- * dangerous strip is preserved. */
17
+ * dangerous strip is preserved.
18
+ */
15
19
  sanitizeSchema?: (defaults: Schema) => Schema;
16
- /** Developer-only escape hatch: disable the sanitize floor entirely. This reintroduces the XSS
20
+ /**
21
+ * Developer-only escape hatch: disable the sanitize floor entirely. This reintroduces the XSS
17
22
  * vector the floor closes, so it is only for a site whose content is fully developer-controlled.
18
- * It is a code-level adapter decision, never an editor-facing setting. */
23
+ * It is a code-level adapter decision, never an editor-facing setting.
24
+ */
19
25
  unsafeDisableSanitize?: boolean;
20
- /** The `rel` value forced on every `target="_blank"` anchor, applied last so it also covers
26
+ /**
27
+ * The `rel` value forced on every `target="_blank"` anchor, applied last so it also covers
21
28
  * component-built anchors. Defaults to `'noopener noreferrer'`. Set a different string to change
22
- * it, or `false` to disable the injection (a site that owns its own anchor hardening). */
29
+ * it, or `false` to disable the injection (a site that owns its own anchor hardening).
30
+ */
23
31
  anchorRel?: string | false;
24
32
  }
25
- /** Compose a site's render pipeline from its component registry: directive syntax to
33
+ /**
34
+ * Compose a site's render pipeline from its component registry: directive syntax to
26
35
  * stamped markers to registry-built hast. Returns `renderMarkdown` plus the remark/
27
- * rehype plugin arrays (so the admin editor preview can reuse the exact same set). */
36
+ * rehype plugin arrays (so the admin editor preview can reuse the exact same set).
37
+ */
28
38
  export declare function createRenderer(registry?: ComponentRegistry, options?: RendererOptions): {
29
39
  remarkPlugins: PluggableList;
30
40
  rehypePlugins: PluggableList;
@@ -15,9 +15,11 @@ import { remarkResolveCairnLinks, CAIRN_RESOLVE } from './resolve-links.js';
15
15
  import { remarkResolveMedia, MEDIA_RESOLVE } from './resolve-media.js';
16
16
  import { rehypeDispatch } from './rehype-dispatch.js';
17
17
  import { defineRegistry } from './registry.js';
18
- /** Compose a site's render pipeline from its component registry: directive syntax to
18
+ /**
19
+ * Compose a site's render pipeline from its component registry: directive syntax to
19
20
  * stamped markers to registry-built hast. Returns `renderMarkdown` plus the remark/
20
- * rehype plugin arrays (so the admin editor preview can reuse the exact same set). */
21
+ * rehype plugin arrays (so the admin editor preview can reuse the exact same set).
22
+ */
21
23
  export function createRenderer(registry = defineRegistry({ components: [] }), options = {}) {
22
24
  const remarkPlugins = [
23
25
  remarkDirective,