@glw907/cairn-cms 0.60.1 → 0.62.2

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 (254) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/dist/components/AdminLayout.svelte +22 -0
  3. package/dist/components/CairnAdmin.svelte +3 -0
  4. package/dist/components/CairnTidySettings.svelte +2 -2
  5. package/dist/components/CairnTidySettings.svelte.d.ts +1 -1
  6. package/dist/components/EditPage.svelte +116 -39
  7. package/dist/components/HelpHome.svelte +824 -0
  8. package/dist/components/HelpHome.svelte.d.ts +22 -0
  9. package/dist/components/MarkdownHelpDialog.svelte +4 -15
  10. package/dist/components/client-ingest.d.ts +16 -8
  11. package/dist/components/client-ingest.js +12 -6
  12. package/dist/components/editor-media.js +16 -8
  13. package/dist/components/editor-placeholder.d.ts +4 -2
  14. package/dist/components/editor-tidy.d.ts +24 -12
  15. package/dist/components/editor-tidy.js +8 -4
  16. package/dist/components/index.d.ts +1 -0
  17. package/dist/components/index.js +1 -0
  18. package/dist/components/link-completion.d.ts +12 -6
  19. package/dist/components/link-completion.js +12 -6
  20. package/dist/components/markdown-directives.d.ts +9 -6
  21. package/dist/components/markdown-directives.js +9 -6
  22. package/dist/components/markdown-format.d.ts +7 -2
  23. package/dist/components/markdown-format.js +59 -28
  24. package/dist/components/markdown-reference.d.ts +8 -0
  25. package/dist/components/markdown-reference.js +22 -0
  26. package/dist/components/media-upload-outcome.d.ts +12 -6
  27. package/dist/components/objective-errors.d.ts +8 -4
  28. package/dist/components/objective-errors.js +8 -4
  29. package/dist/components/preview-doc.d.ts +4 -2
  30. package/dist/components/preview-doc.js +4 -2
  31. package/dist/components/spellcheck.d.ts +55 -29
  32. package/dist/components/spellcheck.js +39 -21
  33. package/dist/components/tidy-categorize.d.ts +20 -10
  34. package/dist/components/tidy-categorize.js +16 -8
  35. package/dist/components/tidy-validate.d.ts +12 -6
  36. package/dist/components/tidy-validate.js +20 -10
  37. package/dist/components/topbar-context.d.ts +4 -2
  38. package/dist/content/advisories.d.ts +56 -0
  39. package/dist/content/advisories.js +87 -0
  40. package/dist/content/compose.d.ts +4 -2
  41. package/dist/content/compose.js +1 -0
  42. package/dist/content/excerpt.js +4 -2
  43. package/dist/content/getting-started.d.ts +18 -0
  44. package/dist/content/getting-started.js +12 -0
  45. package/dist/content/links.d.ts +16 -8
  46. package/dist/content/links.js +12 -6
  47. package/dist/content/manifest.d.ts +36 -18
  48. package/dist/content/manifest.js +32 -16
  49. package/dist/content/media-refs.d.ts +4 -2
  50. package/dist/content/media-refs.js +4 -2
  51. package/dist/content/media-rewrite.d.ts +8 -4
  52. package/dist/content/media-rewrite.js +76 -38
  53. package/dist/content/schema.d.ts +20 -10
  54. package/dist/content/site-dictionary.d.ts +4 -2
  55. package/dist/content/site-dictionary.js +8 -4
  56. package/dist/content/types.d.ts +97 -42
  57. package/dist/delivery/content-index.d.ts +16 -8
  58. package/dist/delivery/feeds.js +4 -2
  59. package/dist/delivery/json-ld.d.ts +3 -0
  60. package/dist/delivery/json-ld.js +3 -0
  61. package/dist/delivery/manifest.d.ts +4 -2
  62. package/dist/delivery/manifest.js +4 -2
  63. package/dist/delivery/public-routes.d.ts +12 -6
  64. package/dist/delivery/public-routes.js +4 -2
  65. package/dist/delivery/seo-fields.d.ts +12 -6
  66. package/dist/delivery/seo-fields.js +8 -4
  67. package/dist/delivery/site-indexes.d.ts +4 -2
  68. package/dist/delivery/site-resolver.d.ts +4 -2
  69. package/dist/delivery/site-resolver.js +4 -2
  70. package/dist/doctor/cloudflare-api.d.ts +6 -0
  71. package/dist/doctor/cloudflare-api.js +6 -0
  72. package/dist/doctor/index.d.ts +12 -6
  73. package/dist/doctor/report.d.ts +3 -0
  74. package/dist/doctor/report.js +3 -0
  75. package/dist/doctor/run.d.ts +3 -0
  76. package/dist/doctor/run.js +3 -0
  77. package/dist/doctor/types.d.ts +10 -2
  78. package/dist/doctor/types.js +6 -0
  79. package/dist/doctor/wrangler-config.d.ts +7 -2
  80. package/dist/doctor/wrangler-config.js +3 -0
  81. package/dist/email.d.ts +4 -2
  82. package/dist/env.d.ts +0 -3
  83. package/dist/env.js +0 -3
  84. package/dist/github/branches.d.ts +4 -2
  85. package/dist/github/branches.js +4 -2
  86. package/dist/github/signing.d.ts +1 -1
  87. package/dist/github/signing.js +2 -2
  88. package/dist/log/events.d.ts +1 -1
  89. package/dist/media/bulk-delete-plan.d.ts +8 -4
  90. package/dist/media/config.d.ts +12 -6
  91. package/dist/media/config.js +16 -8
  92. package/dist/media/delivery-bucket.d.ts +4 -2
  93. package/dist/media/library-entry.d.ts +4 -2
  94. package/dist/media/library-entry.js +4 -2
  95. package/dist/media/manifest.d.ts +29 -15
  96. package/dist/media/manifest.js +29 -16
  97. package/dist/media/naming.d.ts +12 -6
  98. package/dist/media/naming.js +24 -12
  99. package/dist/media/orphan-scan.d.ts +4 -2
  100. package/dist/media/reconcile.d.ts +21 -11
  101. package/dist/media/reconcile.js +12 -6
  102. package/dist/media/reference.d.ts +8 -4
  103. package/dist/media/reference.js +12 -6
  104. package/dist/media/rewrite-plan.d.ts +12 -6
  105. package/dist/media/sniff.d.ts +4 -2
  106. package/dist/media/sniff.js +28 -14
  107. package/dist/media/store.d.ts +16 -8
  108. package/dist/media/store.js +4 -2
  109. package/dist/media/transform-url.d.ts +12 -6
  110. package/dist/media/transform-url.js +8 -4
  111. package/dist/media/usage.d.ts +8 -4
  112. package/dist/nav/site-config.d.ts +16 -8
  113. package/dist/render/component-grammar.d.ts +23 -10
  114. package/dist/render/component-grammar.js +19 -8
  115. package/dist/render/component-insert.d.ts +8 -4
  116. package/dist/render/component-insert.js +4 -2
  117. package/dist/render/component-reference.d.ts +4 -2
  118. package/dist/render/component-reference.js +4 -2
  119. package/dist/render/component-validate.d.ts +3 -0
  120. package/dist/render/component-validate.js +3 -0
  121. package/dist/render/glyph.d.ts +4 -2
  122. package/dist/render/glyph.js +4 -2
  123. package/dist/render/pipeline.d.ts +20 -10
  124. package/dist/render/pipeline.js +4 -2
  125. package/dist/render/registry.d.ts +40 -20
  126. package/dist/render/registry.js +16 -8
  127. package/dist/render/rehype-dispatch.d.ts +22 -8
  128. package/dist/render/rehype-dispatch.js +22 -8
  129. package/dist/render/remark-directives.d.ts +3 -0
  130. package/dist/render/remark-directives.js +3 -0
  131. package/dist/render/remark-figure.d.ts +4 -2
  132. package/dist/render/remark-figure.js +4 -2
  133. package/dist/render/resolve-links.d.ts +4 -2
  134. package/dist/render/resolve-links.js +4 -2
  135. package/dist/render/resolve-media.d.ts +16 -8
  136. package/dist/render/resolve-media.js +12 -6
  137. package/dist/sveltekit/admin-dispatch.d.ts +2 -0
  138. package/dist/sveltekit/admin-dispatch.js +9 -3
  139. package/dist/sveltekit/auth-routes.d.ts +3 -0
  140. package/dist/sveltekit/auth-routes.js +3 -0
  141. package/dist/sveltekit/cairn-admin.d.ts +16 -5
  142. package/dist/sveltekit/cairn-admin.js +26 -10
  143. package/dist/sveltekit/content-routes.d.ts +191 -86
  144. package/dist/sveltekit/content-routes.js +297 -107
  145. package/dist/sveltekit/editors-routes.d.ts +3 -0
  146. package/dist/sveltekit/editors-routes.js +3 -0
  147. package/dist/sveltekit/guard.d.ts +4 -2
  148. package/dist/sveltekit/guard.js +4 -2
  149. package/dist/sveltekit/https-required-page.d.ts +1 -1
  150. package/dist/sveltekit/https-required-page.js +1 -1
  151. package/dist/sveltekit/index.d.ts +1 -1
  152. package/dist/sveltekit/media-route.d.ts +1 -2
  153. package/dist/sveltekit/media-route.js +13 -8
  154. package/dist/sveltekit/nav-routes.d.ts +7 -2
  155. package/dist/sveltekit/nav-routes.js +3 -0
  156. package/dist/sveltekit/types.d.ts +4 -2
  157. package/dist/vite/index.d.ts +32 -16
  158. package/dist/vite/index.js +52 -26
  159. package/dist/vite/resolve-root.d.ts +8 -4
  160. package/dist/vite/resolve-root.js +4 -2
  161. package/package.json +7 -1
  162. package/src/lib/components/AdminLayout.svelte +22 -0
  163. package/src/lib/components/CairnAdmin.svelte +3 -0
  164. package/src/lib/components/CairnTidySettings.svelte +2 -2
  165. package/src/lib/components/ComponentForm.svelte +0 -1
  166. package/src/lib/components/EditPage.svelte +133 -41
  167. package/src/lib/components/HelpHome.svelte +850 -0
  168. package/src/lib/components/MarkdownHelpDialog.svelte +4 -15
  169. package/src/lib/components/client-ingest.ts +20 -10
  170. package/src/lib/components/editor-media.ts +20 -10
  171. package/src/lib/components/editor-placeholder.ts +12 -6
  172. package/src/lib/components/editor-tidy.ts +28 -14
  173. package/src/lib/components/index.ts +1 -0
  174. package/src/lib/components/link-completion.ts +12 -6
  175. package/src/lib/components/markdown-directives.ts +13 -8
  176. package/src/lib/components/markdown-format.ts +63 -30
  177. package/src/lib/components/markdown-reference.ts +30 -0
  178. package/src/lib/components/media-upload-outcome.ts +12 -6
  179. package/src/lib/components/objective-errors.ts +16 -8
  180. package/src/lib/components/preview-doc.ts +4 -2
  181. package/src/lib/components/spellcheck.ts +79 -41
  182. package/src/lib/components/tidy-categorize.ts +28 -14
  183. package/src/lib/components/tidy-validate.ts +28 -14
  184. package/src/lib/components/topbar-context.ts +4 -2
  185. package/src/lib/content/advisories.ts +150 -0
  186. package/src/lib/content/compose.ts +5 -2
  187. package/src/lib/content/excerpt.ts +4 -2
  188. package/src/lib/content/getting-started.ts +31 -0
  189. package/src/lib/content/links.ts +16 -8
  190. package/src/lib/content/manifest.ts +36 -18
  191. package/src/lib/content/media-refs.ts +4 -2
  192. package/src/lib/content/media-rewrite.ts +100 -50
  193. package/src/lib/content/schema.ts +20 -10
  194. package/src/lib/content/site-dictionary.ts +8 -4
  195. package/src/lib/content/types.ts +97 -42
  196. package/src/lib/delivery/content-index.ts +16 -8
  197. package/src/lib/delivery/feeds.ts +4 -2
  198. package/src/lib/delivery/json-ld.ts +3 -0
  199. package/src/lib/delivery/manifest.ts +4 -2
  200. package/src/lib/delivery/public-routes.ts +16 -8
  201. package/src/lib/delivery/seo-fields.ts +12 -6
  202. package/src/lib/delivery/site-indexes.ts +4 -2
  203. package/src/lib/delivery/site-resolver.ts +4 -2
  204. package/src/lib/doctor/cloudflare-api.ts +6 -0
  205. package/src/lib/doctor/index.ts +12 -6
  206. package/src/lib/doctor/report.ts +3 -0
  207. package/src/lib/doctor/run.ts +3 -0
  208. package/src/lib/doctor/types.ts +10 -2
  209. package/src/lib/doctor/wrangler-config.ts +7 -2
  210. package/src/lib/email.ts +4 -2
  211. package/src/lib/env.ts +0 -3
  212. package/src/lib/github/branches.ts +4 -2
  213. package/src/lib/github/signing.ts +2 -2
  214. package/src/lib/log/events.ts +1 -0
  215. package/src/lib/media/bulk-delete-plan.ts +8 -4
  216. package/src/lib/media/config.ts +24 -12
  217. package/src/lib/media/delivery-bucket.ts +4 -2
  218. package/src/lib/media/library-entry.ts +4 -2
  219. package/src/lib/media/manifest.ts +33 -18
  220. package/src/lib/media/naming.ts +24 -12
  221. package/src/lib/media/orphan-scan.ts +4 -2
  222. package/src/lib/media/reconcile.ts +21 -11
  223. package/src/lib/media/reference.ts +12 -6
  224. package/src/lib/media/rewrite-plan.ts +12 -6
  225. package/src/lib/media/sniff.ts +28 -14
  226. package/src/lib/media/store.ts +16 -8
  227. package/src/lib/media/transform-url.ts +12 -6
  228. package/src/lib/media/usage.ts +8 -4
  229. package/src/lib/nav/site-config.ts +16 -8
  230. package/src/lib/render/component-grammar.ts +23 -10
  231. package/src/lib/render/component-insert.ts +8 -4
  232. package/src/lib/render/component-reference.ts +4 -2
  233. package/src/lib/render/component-validate.ts +3 -0
  234. package/src/lib/render/glyph.ts +4 -2
  235. package/src/lib/render/pipeline.ts +20 -10
  236. package/src/lib/render/registry.ts +44 -22
  237. package/src/lib/render/rehype-dispatch.ts +22 -8
  238. package/src/lib/render/remark-directives.ts +3 -0
  239. package/src/lib/render/remark-figure.ts +4 -2
  240. package/src/lib/render/resolve-links.ts +4 -2
  241. package/src/lib/render/resolve-media.ts +16 -8
  242. package/src/lib/sveltekit/admin-dispatch.ts +10 -4
  243. package/src/lib/sveltekit/auth-routes.ts +3 -0
  244. package/src/lib/sveltekit/cairn-admin.ts +37 -15
  245. package/src/lib/sveltekit/content-routes.ts +494 -197
  246. package/src/lib/sveltekit/editors-routes.ts +3 -0
  247. package/src/lib/sveltekit/guard.ts +4 -2
  248. package/src/lib/sveltekit/https-required-page.ts +1 -1
  249. package/src/lib/sveltekit/index.ts +3 -0
  250. package/src/lib/sveltekit/media-route.ts +13 -8
  251. package/src/lib/sveltekit/nav-routes.ts +7 -2
  252. package/src/lib/sveltekit/types.ts +4 -2
  253. package/src/lib/vite/index.ts +60 -30
  254. package/src/lib/vite/resolve-root.ts +8 -4
@@ -4,31 +4,39 @@ import { type MediaManifest } from '../media/manifest.js';
4
4
  import type { ResolvedAssetConfig } from '../media/config.js';
5
5
  /** The VFile data key the renderer sets the per-call media resolver under. */
6
6
  export declare const MEDIA_RESOLVE = "mediaResolve";
7
- /** Resolve a media reference to its delivery URL. `undefined` is a preview miss (the plugin marks
7
+ /**
8
+ * Resolve a media reference to its delivery URL. `undefined` is a preview miss (the plugin marks
8
9
  * the image broken); a resolver that throws is the build backstop (the error propagates out of
9
- * render and fails the build), exactly like LinkResolve. */
10
+ * render and fails the build), exactly like LinkResolve.
11
+ */
10
12
  export type MediaResolve = (ref: MediaRef) => string | undefined;
11
- /** Build the per-call media resolver, closing over the manifest and the resolved config. The
13
+ /**
14
+ * Build the per-call media resolver, closing over the manifest and the resolved config. The
12
15
  * returned resolver looks a ref's content hash up in the manifest and builds the canonical delivery
13
16
  * path from the manifest entry's slug and ext, not the token's, so a rename never breaks the
14
17
  * reference. With a preset and zone transformations on it returns the variant URL; without a preset,
15
18
  * or when transformations are off, it returns the bare full-size path so a fresh zone with Image
16
19
  * Transformations disabled serves correct thumbnails rather than dead /cdn-cgi/image URLs. It returns
17
- * undefined when media is off or no entry carries the hash (the preview-miss backstop). */
20
+ * undefined when media is off or no entry carries the hash (the preview-miss backstop).
21
+ */
18
22
  export declare function makeMediaResolver(manifest: MediaManifest, resolved: ResolvedAssetConfig, opts?: {
19
23
  preset?: string;
20
24
  }): MediaResolve;
21
- /** A resolver backed by the lean `mediaTargets` projection, for the admin preview. It mirrors
25
+ /**
26
+ * A resolver backed by the lean `mediaTargets` projection, for the admin preview. It mirrors
22
27
  * manifestLinkResolver: a hash present in the projection builds the slug delivery path
23
28
  * (`/media/<slug>.<hash>.<ext>`); a miss returns undefined, so the render step marks the image
24
29
  * broken rather than throwing. Pure over the projection, with no manifest and no config, so the
25
- * edit page reaches it with the data it actually has. */
30
+ * edit page reaches it with the data it actually has.
31
+ */
26
32
  export declare function manifestMediaResolver(targets: Record<string, {
27
33
  slug: string;
28
34
  ext: string;
29
35
  contentType: string;
30
36
  }>): MediaResolve;
31
- /** Resolve media: image nodes against the VFile's resolver. A non-media src and a malformed token
37
+ /**
38
+ * Resolve media: image nodes against the VFile's resolver. A non-media src and a malformed token
32
39
  * pass through. A missing target is marked with the cairn-broken-media class (the resolver returns
33
- * undefined) or, when the resolver throws, the error propagates and fails the build. */
40
+ * undefined) or, when the resolver throws, the error propagates and fails the build.
41
+ */
34
42
  export declare function remarkResolveMedia(): (tree: unknown, file: VFile) => void;
@@ -11,13 +11,15 @@ import { presetUrl } from '../media/transform-url.js';
11
11
  import { log } from '../log/index.js';
12
12
  /** The VFile data key the renderer sets the per-call media resolver under. */
13
13
  export const MEDIA_RESOLVE = 'mediaResolve';
14
- /** Build the per-call media resolver, closing over the manifest and the resolved config. The
14
+ /**
15
+ * Build the per-call media resolver, closing over the manifest and the resolved config. The
15
16
  * returned resolver looks a ref's content hash up in the manifest and builds the canonical delivery
16
17
  * path from the manifest entry's slug and ext, not the token's, so a rename never breaks the
17
18
  * reference. With a preset and zone transformations on it returns the variant URL; without a preset,
18
19
  * or when transformations are off, it returns the bare full-size path so a fresh zone with Image
19
20
  * Transformations disabled serves correct thumbnails rather than dead /cdn-cgi/image URLs. It returns
20
- * undefined when media is off or no entry carries the hash (the preview-miss backstop). */
21
+ * undefined when media is off or no entry carries the hash (the preview-miss backstop).
22
+ */
21
23
  export function makeMediaResolver(manifest, resolved, opts) {
22
24
  return (ref) => {
23
25
  if (!resolved.enabled)
@@ -36,11 +38,13 @@ export function makeMediaResolver(manifest, resolved, opts) {
36
38
  return path;
37
39
  };
38
40
  }
39
- /** A resolver backed by the lean `mediaTargets` projection, for the admin preview. It mirrors
41
+ /**
42
+ * A resolver backed by the lean `mediaTargets` projection, for the admin preview. It mirrors
40
43
  * manifestLinkResolver: a hash present in the projection builds the slug delivery path
41
44
  * (`/media/<slug>.<hash>.<ext>`); a miss returns undefined, so the render step marks the image
42
45
  * broken rather than throwing. Pure over the projection, with no manifest and no config, so the
43
- * edit page reaches it with the data it actually has. */
46
+ * edit page reaches it with the data it actually has.
47
+ */
44
48
  export function manifestMediaResolver(targets) {
45
49
  return (ref) => {
46
50
  const entry = targets[ref.hash];
@@ -49,9 +53,11 @@ export function manifestMediaResolver(targets) {
49
53
  return publicPath(entry.slug, ref.hash, entry.ext, 'slug');
50
54
  };
51
55
  }
52
- /** Resolve media: image nodes against the VFile's resolver. A non-media src and a malformed token
56
+ /**
57
+ * Resolve media: image nodes against the VFile's resolver. A non-media src and a malformed token
53
58
  * pass through. A missing target is marked with the cairn-broken-media class (the resolver returns
54
- * undefined) or, when the resolver throws, the error propagates and fails the build. */
59
+ * undefined) or, when the resolver throws, the error propagates and fails the build.
60
+ */
55
61
  export function remarkResolveMedia() {
56
62
  return (tree, file) => {
57
63
  const resolve = file.data[MEDIA_RESOLVE];
@@ -21,6 +21,8 @@ export type AdminView = {
21
21
  view: 'media';
22
22
  } | {
23
23
  view: 'settings';
24
+ } | {
25
+ view: 'help';
24
26
  };
25
27
  /**
26
28
  * Parse a raw `URL.pathname` (the caller passes `event.url.pathname`, never a SvelteKit rest
@@ -3,10 +3,12 @@ import { isValidId } from '../content/ids.js';
3
3
  /**
4
4
  * Fixed first segments that never resolve as concepts. The engine only allows posts and pages
5
5
  * today, so no collision is possible, but the parser does not depend on that: a reserved
6
- * segment wins before concept lookup. `settings`, `nav`, and `media` are decided as views below,
7
- * so they are not in this no-view set.
6
+ * segment wins before concept lookup. `nav` and `media` are decided as views below, so they are
7
+ * not in this no-view set. `settings` and `help` are decided as views below AND kept here, so a
8
+ * deeper path (or a future concept claiming the segment) can never reach the two-segment edit
9
+ * branch through them.
8
10
  */
9
- const RESERVED_SEGMENTS = new Set(['login', 'auth', 'editors', 'nav', 'settings']);
11
+ const RESERVED_SEGMENTS = new Set(['login', 'auth', 'editors', 'nav', 'settings', 'help']);
10
12
  /**
11
13
  * Parse a raw `URL.pathname` (the caller passes `event.url.pathname`, never a SvelteKit rest
12
14
  * param) into the admin view it names. A single trailing slash is tolerated everywhere; empty
@@ -51,6 +53,10 @@ export function parseAdminPath(pathname, concepts) {
51
53
  // (the two-segment branch never matches settings), which is the correct shape.
52
54
  if (head === 'settings')
53
55
  return { view: 'settings' };
56
+ // help is its own view (the Help home, editor-help Pass 2), decided here like settings. It is
57
+ // also in the reserved set so /admin/help/<anything> 404s and no concept can claim the segment.
58
+ if (head === 'help')
59
+ return { view: 'help' };
54
60
  if (RESERVED_SEGMENTS.has(head))
55
61
  return null;
56
62
  const concept = findConcept(concepts, head);
@@ -19,6 +19,9 @@ export type RequestResult = {
19
19
  status: 'throttled';
20
20
  sent: false;
21
21
  };
22
+ /**
23
+ *
24
+ */
22
25
  export declare function createAuthRoutes(config: AuthRoutesConfig): {
23
26
  loginLoad: (event: RequestContext) => {
24
27
  siteName: string;
@@ -19,6 +19,9 @@ function scrubSendError(err) {
19
19
  .replace(/([?&]token=)[^&\s"'<]+/g, '$1[redacted]')
20
20
  .slice(0, 300);
21
21
  }
22
+ /**
23
+ *
24
+ */
22
25
  export function createAuthRoutes(config) {
23
26
  const send = config.send ?? cloudflareSend;
24
27
  /**
@@ -1,4 +1,4 @@
1
- import { type ContentRoutesDeps, type LayoutData, type ListData, type EditData, type MediaLibraryData, type SettingsData } from './content-routes.js';
1
+ import { type ContentRoutesDeps, type LayoutData, type ListData, type EditData, type MediaLibraryData, type SettingsData, type HelpData } from './content-routes.js';
2
2
  import { type NavLoadData } from './nav-routes.js';
3
3
  import type { AuthBranding, SendMagicLink } from '../email.js';
4
4
  import type { AuthEnv, Editor } from '../auth/types.js';
@@ -14,15 +14,19 @@ export interface AdminEvent extends EventBase<GithubKeyEnv & AuthEnv> {
14
14
  cookies: CookieJar;
15
15
  setHeaders(headers: Record<string, string>): void;
16
16
  }
17
- /** Injectable dependencies. Branding defaults from the runtime's siteName and sender, so a
17
+ /**
18
+ * Injectable dependencies. Branding defaults from the runtime's siteName and sender, so a
18
19
  * site overrides it only to change the magic-link email identity; `send` and `mintToken`
19
- * are the same seams the underlying factories take. */
20
+ * are the same seams the underlying factories take.
21
+ */
20
22
  export interface CairnAdminDeps {
21
23
  branding?: AuthBranding;
22
24
  send?: SendMagicLink;
23
25
  mintToken?: ContentRoutesDeps['mintToken'];
24
- /** Build the Anthropic client for the tidy action. Forwarded to the content routes; a site that
25
- * enables tidy injects a stub here to avoid a real network call. Defaults to the real SDK client. */
26
+ /**
27
+ * Build the Anthropic client for the tidy action. Forwarded to the content routes; a site that
28
+ * enables tidy injects a stub here to avoid a real network call. Defaults to the real SDK client.
29
+ */
26
30
  anthropic?: ContentRoutesDeps['anthropic'];
27
31
  /** The tidy action's own request deadline in milliseconds. Forwarded to the content routes. */
28
32
  tidyTimeoutMs?: ContentRoutesDeps['tidyTimeoutMs'];
@@ -74,7 +78,14 @@ export type AdminData = {
74
78
  view: 'settings';
75
79
  layout: LayoutData;
76
80
  page: SettingsData;
81
+ } | {
82
+ view: 'help';
83
+ layout: LayoutData;
84
+ page: HelpData;
77
85
  };
86
+ /**
87
+ *
88
+ */
78
89
  export declare function createCairnAdmin(runtime: CairnRuntime, deps?: CairnAdminDeps): {
79
90
  load: (event: AdminEvent) => Promise<AdminData>;
80
91
  actions: {
@@ -10,6 +10,9 @@ import { createAuthRoutes } from './auth-routes.js';
10
10
  import { createContentRoutes, } from './content-routes.js';
11
11
  import { createEditorRoutes } from './editors-routes.js';
12
12
  import { createNavRoutes } from './nav-routes.js';
13
+ /**
14
+ *
15
+ */
13
16
  export function createCairnAdmin(runtime, deps = {}) {
14
17
  // The runtime already composes the site name and the sender identity, so the magic-link
15
18
  // branding needs no second copy of either unless a site overrides it.
@@ -27,11 +30,13 @@ export function createCairnAdmin(runtime, deps = {}) {
27
30
  const editors = createEditorRoutes();
28
31
  // The nav surface exists only when the site configures a menu; without one its view is a 404.
29
32
  const nav = runtime.navMenu ? createNavRoutes(runtime, { mintToken: deps.mintToken }) : null;
30
- /** Build the event a wrapped content load reads. The catch-all route carries only a rest
33
+ /**
34
+ * Build the event a wrapped content load reads. The catch-all route carries only a rest
31
35
  * param, so `concept` and `id` are synthesized from the parsed view. The override names
32
36
  * each field explicitly rather than spreading: a real RequestEvent's fields can sit behind
33
37
  * getters a bare spread copies poorly, and the structural ContentEvent contract needs only
34
- * these. */
38
+ * these.
39
+ */
35
40
  function contentEvent(event, params) {
36
41
  return {
37
42
  url: event.url,
@@ -42,9 +47,11 @@ export function createCairnAdmin(runtime, deps = {}) {
42
47
  cookies: event.cookies,
43
48
  };
44
49
  }
45
- /** Serve the admin view the pathname names, or a 404 for any shape the parser refuses.
50
+ /**
51
+ * Serve the admin view the pathname names, or a 404 for any shape the parser refuses.
46
52
  * The authed views run the layout load and the view load concurrently; both mint a GitHub
47
- * token, and the installation-token cache coalesces the mints into one signing. */
53
+ * token, and the installation-token cache coalesces the mints into one signing.
54
+ */
48
55
  async function load(event) {
49
56
  const view = parseAdminPath(event.url.pathname, runtime.concepts);
50
57
  if (!view)
@@ -91,11 +98,18 @@ export function createCairnAdmin(runtime, deps = {}) {
91
98
  const [layout, page] = await Promise.all([content.layoutLoad(delegated), content.settingsLoad(delegated)]);
92
99
  return { view: 'settings', layout, page };
93
100
  }
101
+ case 'help': {
102
+ const delegated = contentEvent(event, {});
103
+ const [layout, page] = await Promise.all([content.layoutLoad(delegated), content.helpLoad(delegated)]);
104
+ return { view: 'help', layout, page };
105
+ }
94
106
  }
95
107
  }
96
- /** Wrap a delegate in the parse-and-check every action shares: parse the pathname exactly
108
+ /**
109
+ * Wrap a delegate in the parse-and-check every action shares: parse the pathname exactly
97
110
  * as load does, 404 on a null parse or a view outside the allowed set, then hand the
98
- * narrowed view to the delegate. */
111
+ * narrowed view to the delegate.
112
+ */
99
113
  function viewAction(allowed, delegate) {
100
114
  return async (event) => {
101
115
  const view = parseAdminPath(event.url.pathname, runtime.concepts);
@@ -106,13 +120,15 @@ export function createCairnAdmin(runtime, deps = {}) {
106
120
  };
107
121
  }
108
122
  // The topbar posts publishAll from every authed admin page; login and confirm may not.
109
- const authedViews = ['list', 'edit', 'editors', 'nav', 'media', 'settings'];
123
+ const authedViews = ['list', 'edit', 'editors', 'nav', 'media', 'settings', 'help'];
110
124
  // An editor signs out from wherever they are, so logout accepts any parsed view.
111
- const anyView = ['index', 'login', 'confirm', 'list', 'edit', 'editors', 'nav', 'media', 'settings'];
112
- /** The full admin action vocabulary, one named async function per action, so a site's
125
+ const anyView = ['index', 'login', 'confirm', 'list', 'edit', 'editors', 'nav', 'media', 'settings', 'help'];
126
+ /**
127
+ * The full admin action vocabulary, one named async function per action, so a site's
113
128
  * catch-all route exports `admin.actions` directly. Each wrapper stays thin: parse,
114
129
  * validate the view, synthesize the params the wrapped action reads, delegate. The
115
- * editor actions gate themselves with requireOwner, so no second gate is added here. */
130
+ * editor actions gate themselves with requireOwner, so no second gate is added here.
131
+ */
116
132
  const actions = {
117
133
  request: viewAction(['login'], (event) => auth.requestAction(event)),
118
134
  confirm: viewAction(['confirm'], (event) => auth.confirmAction(event)),