@glw907/cairn-cms 0.68.0 → 0.76.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +82 -0
- package/dist/ambient.d.ts +2 -0
- package/dist/components/CairnAdmin.svelte.d.ts +2 -7
- package/dist/components/ComponentForm.svelte +44 -27
- package/dist/components/ComponentInsertDialog.svelte +5 -5
- package/dist/components/ComponentInsertDialog.svelte.d.ts +2 -6
- package/dist/components/EditPage.svelte +29 -107
- package/dist/components/EditPage.svelte.d.ts +2 -7
- package/dist/components/EntryPicker.svelte +117 -0
- package/dist/components/EntryPicker.svelte.d.ts +35 -0
- package/dist/components/FieldInput.svelte +218 -0
- package/dist/components/FieldInput.svelte.d.ts +51 -0
- package/dist/components/IconPicker.svelte +2 -2
- package/dist/components/IconPicker.svelte.d.ts +2 -0
- package/dist/components/LinkPicker.svelte +8 -75
- package/dist/components/LinkPicker.svelte.d.ts +4 -5
- package/dist/components/MediaHeroField.svelte +8 -5
- package/dist/components/MediaHeroField.svelte.d.ts +4 -0
- package/dist/components/ObjectGroupField.svelte +54 -0
- package/dist/components/ObjectGroupField.svelte.d.ts +47 -0
- package/dist/components/ReferenceField.svelte +94 -0
- package/dist/components/ReferenceField.svelte.d.ts +27 -0
- package/dist/components/RepeatableField.svelte +221 -0
- package/dist/components/RepeatableField.svelte.d.ts +53 -0
- package/dist/components/cairn-admin.css +4 -0
- package/dist/components/preview-doc.js +5 -1
- package/dist/components/tidy-validate.js +1 -1
- package/dist/content/adapter.js +18 -0
- package/dist/content/advisories.d.ts +2 -2
- package/dist/content/advisories.js +3 -5
- package/dist/content/compose.d.ts +7 -6
- package/dist/content/compose.js +26 -20
- package/dist/content/concepts.d.ts +21 -15
- package/dist/content/concepts.js +55 -32
- package/dist/content/field-rules.js +3 -4
- package/dist/content/fields.d.ts +49 -1
- package/dist/content/fields.js +11 -0
- package/dist/content/fieldset.d.ts +31 -10
- package/dist/content/fieldset.js +262 -109
- package/dist/content/frontmatter-region.d.ts +38 -0
- package/dist/content/frontmatter-region.js +75 -0
- package/dist/content/frontmatter.d.ts +35 -2
- package/dist/content/frontmatter.js +232 -11
- package/dist/content/manifest.d.ts +34 -0
- package/dist/content/manifest.js +80 -4
- package/dist/content/media-refs.d.ts +2 -2
- package/dist/content/media-rewrite.js +1 -69
- package/dist/content/reference-index.d.ts +56 -0
- package/dist/content/reference-index.js +95 -0
- package/dist/content/references.d.ts +40 -0
- package/dist/content/references.js +0 -0
- package/dist/content/standard-schema.d.ts +30 -0
- package/dist/content/standard-schema.js +4 -0
- package/dist/content/types.d.ts +127 -178
- package/dist/delivery/data.d.ts +2 -2
- package/dist/delivery/data.js +1 -1
- package/dist/delivery/public-routes.d.ts +2 -5
- package/dist/delivery/public-routes.js +15 -1
- package/dist/delivery/site-descriptors.d.ts +5 -1
- package/dist/delivery/site-descriptors.js +8 -3
- package/dist/delivery/site-indexes.d.ts +2 -2
- package/dist/delivery/site-resolver.d.ts +25 -0
- package/dist/delivery/site-resolver.js +49 -0
- package/dist/doctor/checks-local.js +6 -11
- package/dist/github/backend.d.ts +83 -0
- package/dist/github/backend.js +76 -0
- package/dist/github/credentials.d.ts +11 -5
- package/dist/github/credentials.js +3 -3
- package/dist/github/repo.d.ts +8 -19
- package/dist/github/repo.js +69 -80
- package/dist/github/types.d.ts +1 -1
- package/dist/github/types.js +4 -4
- package/dist/index.d.ts +16 -12
- package/dist/index.js +7 -8
- package/dist/islands/index.d.ts +12 -0
- package/dist/islands/index.js +83 -0
- package/dist/islands/types.d.ts +7 -0
- package/dist/islands/types.js +1 -0
- package/dist/media/rewrite-plan.d.ts +2 -3
- package/dist/media/rewrite-plan.js +2 -3
- package/dist/media/usage.d.ts +2 -2
- package/dist/media/usage.js +3 -5
- package/dist/nav/site-config.d.ts +0 -6
- package/dist/nav/site-config.js +6 -4
- package/dist/render/component-grammar.js +11 -11
- package/dist/render/component-reference.js +5 -3
- package/dist/render/component-validate.d.ts +4 -1
- package/dist/render/component-validate.js +10 -35
- package/dist/render/pipeline.d.ts +0 -6
- package/dist/render/pipeline.js +1 -1
- package/dist/render/registry.d.ts +34 -34
- package/dist/render/registry.js +26 -5
- package/dist/render/rehype-dispatch.d.ts +4 -4
- package/dist/render/rehype-dispatch.js +36 -11
- package/dist/render/remark-directives.js +4 -5
- package/dist/render/sanitize-schema.js +1 -1
- package/dist/sveltekit/cairn-admin.d.ts +5 -5
- package/dist/sveltekit/cairn-admin.js +3 -4
- package/dist/sveltekit/content-routes.d.ts +10 -8
- package/dist/sveltekit/content-routes.js +269 -181
- package/dist/sveltekit/health.d.ts +7 -3
- package/dist/sveltekit/health.js +9 -3
- package/dist/sveltekit/index.d.ts +1 -1
- package/dist/sveltekit/nav-routes.d.ts +6 -5
- package/dist/sveltekit/nav-routes.js +22 -20
- package/dist/sveltekit/types.d.ts +2 -0
- package/dist/vite/index.d.ts +3 -3
- package/dist/vite/index.js +17 -8
- package/package.json +5 -1
- package/src/lib/ambient.ts +7 -0
- package/src/lib/components/CairnAdmin.svelte +2 -6
- package/src/lib/components/ComponentForm.svelte +48 -27
- package/src/lib/components/ComponentInsertDialog.svelte +9 -8
- package/src/lib/components/EditPage.svelte +43 -119
- package/src/lib/components/EntryPicker.svelte +154 -0
- package/src/lib/components/FieldInput.svelte +262 -0
- package/src/lib/components/IconPicker.svelte +4 -2
- package/src/lib/components/LinkPicker.svelte +10 -81
- package/src/lib/components/MediaHeroField.svelte +12 -5
- package/src/lib/components/ObjectGroupField.svelte +97 -0
- package/src/lib/components/ReferenceField.svelte +126 -0
- package/src/lib/components/RepeatableField.svelte +310 -0
- package/src/lib/components/preview-doc.ts +5 -1
- package/src/lib/components/tidy-validate.ts +1 -1
- package/src/lib/content/adapter.ts +21 -0
- package/src/lib/content/advisories.ts +4 -7
- package/src/lib/content/compose.ts +30 -23
- package/src/lib/content/concepts.ts +68 -40
- package/src/lib/content/field-rules.ts +3 -4
- package/src/lib/content/fields.ts +52 -1
- package/src/lib/content/fieldset.ts +291 -128
- package/src/lib/content/frontmatter-region.ts +90 -0
- package/src/lib/content/frontmatter.ts +231 -15
- package/src/lib/content/manifest.ts +101 -4
- package/src/lib/content/media-refs.ts +2 -2
- package/src/lib/content/media-rewrite.ts +7 -80
- package/src/lib/content/reference-index.ts +159 -0
- package/src/lib/content/references.ts +0 -0
- package/src/lib/content/standard-schema.ts +25 -0
- package/src/lib/content/types.ts +128 -195
- package/src/lib/delivery/data.ts +2 -2
- package/src/lib/delivery/public-routes.ts +17 -3
- package/src/lib/delivery/site-descriptors.ts +8 -3
- package/src/lib/delivery/site-indexes.ts +2 -2
- package/src/lib/delivery/site-resolver.ts +64 -0
- package/src/lib/doctor/checks-local.ts +6 -14
- package/src/lib/github/backend.ts +161 -0
- package/src/lib/github/credentials.ts +10 -7
- package/src/lib/github/repo.ts +79 -83
- package/src/lib/github/types.ts +5 -5
- package/src/lib/index.ts +38 -23
- package/src/lib/islands/index.ts +84 -0
- package/src/lib/islands/types.ts +11 -0
- package/src/lib/media/rewrite-plan.ts +4 -6
- package/src/lib/media/usage.ts +4 -7
- package/src/lib/nav/site-config.ts +8 -9
- package/src/lib/render/component-grammar.ts +10 -10
- package/src/lib/render/component-reference.ts +4 -3
- package/src/lib/render/component-validate.ts +10 -35
- package/src/lib/render/pipeline.ts +1 -7
- package/src/lib/render/registry.ts +58 -39
- package/src/lib/render/rehype-dispatch.ts +45 -10
- package/src/lib/render/remark-directives.ts +4 -5
- package/src/lib/render/sanitize-schema.ts +1 -1
- package/src/lib/sveltekit/cairn-admin.ts +8 -9
- package/src/lib/sveltekit/content-routes.ts +330 -221
- package/src/lib/sveltekit/health.ts +13 -6
- package/src/lib/sveltekit/index.ts +2 -2
- package/src/lib/sveltekit/nav-routes.ts +33 -29
- package/src/lib/sveltekit/types.ts +5 -1
- package/src/lib/vite/index.ts +20 -11
- package/dist/content/schema.d.ts +0 -87
- package/dist/content/schema.js +0 -85
- package/dist/content/validate.d.ts +0 -17
- package/dist/content/validate.js +0 -93
- package/src/lib/content/schema.ts +0 -163
- package/src/lib/content/validate.ts +0 -90
|
@@ -29,10 +29,10 @@ export declare function headRow(title: ElementContent[], icon?: Element, level?:
|
|
|
29
29
|
export declare function markFirstList(children: ElementContent[]): Element | undefined;
|
|
30
30
|
/**
|
|
31
31
|
* Rehype transformer: dispatch each stamped element through its registry `build`
|
|
32
|
-
* fn.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* fn. Each top-level primitive gets a `data-rise` attribute carrying its
|
|
33
|
+
* document-order index (0, 1, 2, …); the site's CSS maps that ordinal to an
|
|
34
|
+
* entrance delay. The index is inert, so a consumer's sanitize floor can keep
|
|
35
35
|
* `data-rise` while dropping `style`. Nested primitives never get it. Non-primitive
|
|
36
36
|
* content (lede, intro paragraphs, the page-toc nav) passes through untouched.
|
|
37
37
|
*/
|
|
38
|
-
export declare function rehypeDispatch(registry: ComponentRegistry
|
|
38
|
+
export declare function rehypeDispatch(registry: ComponentRegistry): (tree: Root) => void;
|
|
@@ -56,7 +56,7 @@ export function markFirstList(children) {
|
|
|
56
56
|
}
|
|
57
57
|
// Recurse into a node's children, transforming any nested primitive sections
|
|
58
58
|
// (a grid inside a card, panels inside a split). Nested primitives never carry the
|
|
59
|
-
// entrance
|
|
59
|
+
// entrance ordinal; only top-level ones do (stamped in the transformer below).
|
|
60
60
|
function transformChildren(children, registry) {
|
|
61
61
|
return children.map((c) => {
|
|
62
62
|
if (isElement(c) && c.properties?.dataPrimitive)
|
|
@@ -70,11 +70,11 @@ function transformChildren(children, registry) {
|
|
|
70
70
|
// 'true'/'false'; everything else is the literal string the author wrote.
|
|
71
71
|
function readAttributes(node, def) {
|
|
72
72
|
const out = {};
|
|
73
|
-
for (const field of def.attributes ??
|
|
74
|
-
const value = strProp(node, dataAttrProp(
|
|
73
|
+
for (const [name, field] of Object.entries(def.attributes ?? {})) {
|
|
74
|
+
const value = strProp(node, dataAttrProp(name));
|
|
75
75
|
if (value == null)
|
|
76
76
|
continue;
|
|
77
|
-
out[
|
|
77
|
+
out[name] = field.type === 'boolean' ? value === 'true' : value;
|
|
78
78
|
}
|
|
79
79
|
return out;
|
|
80
80
|
}
|
|
@@ -126,6 +126,31 @@ function partitionSlots(node) {
|
|
|
126
126
|
},
|
|
127
127
|
};
|
|
128
128
|
}
|
|
129
|
+
// Serialize a hydrate component's declared attributes into the island prop payload. A `number` field is
|
|
130
|
+
// coerced from its stamped string to a JSON number here; a `boolean` already arrived as a real boolean
|
|
131
|
+
// from readAttributes (which coerces 'true'/'false' upstream), and every other field stays the literal
|
|
132
|
+
// string the author wrote. The result is JSON.stringify-ed into data-cairn-props and parsed on the client.
|
|
133
|
+
function serializeIslandProps(def, attributes) {
|
|
134
|
+
const out = {};
|
|
135
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
136
|
+
const type = def.attributes?.[key]?.type;
|
|
137
|
+
out[key] = type === 'number' && typeof value === 'string' ? Number(value) : value;
|
|
138
|
+
}
|
|
139
|
+
return out;
|
|
140
|
+
}
|
|
141
|
+
// Wrap a hydrate component's static fallback in its island boundary. The boundary carries the directive
|
|
142
|
+
// name and the JSON prop payload; a 'visible' island also carries data-cairn-hydrate="visible". The
|
|
143
|
+
// boundary attributes are inert data-* and survive both the sanitize floor (this runs after it) and the
|
|
144
|
+
// sink guard (which strips only style/on*). The fallback is build()'s no-JS, first-paint representation.
|
|
145
|
+
function islandBoundary(name, def, attributes, fallback) {
|
|
146
|
+
const properties = {
|
|
147
|
+
dataCairnIsland: name,
|
|
148
|
+
dataCairnProps: JSON.stringify(serializeIslandProps(def, attributes)),
|
|
149
|
+
};
|
|
150
|
+
if (def.hydrate === 'visible')
|
|
151
|
+
properties.dataCairnHydrate = 'visible';
|
|
152
|
+
return { type: 'element', tagName: 'div', properties, children: [fallback] };
|
|
153
|
+
}
|
|
129
154
|
function transformNode(node, registry) {
|
|
130
155
|
node.children = transformChildren(node.children, registry);
|
|
131
156
|
const name = strProp(node, 'dataPrimitive');
|
|
@@ -139,24 +164,24 @@ function transformNode(node, registry) {
|
|
|
139
164
|
items: parts.items,
|
|
140
165
|
node,
|
|
141
166
|
};
|
|
142
|
-
|
|
167
|
+
const built = def.build(ctx);
|
|
168
|
+
return def.hydrate ? islandBoundary(name, def, ctx.attributes, built) : built;
|
|
143
169
|
}
|
|
144
170
|
/**
|
|
145
171
|
* Rehype transformer: dispatch each stamped element through its registry `build`
|
|
146
|
-
* fn.
|
|
147
|
-
*
|
|
148
|
-
*
|
|
172
|
+
* fn. Each top-level primitive gets a `data-rise` attribute carrying its
|
|
173
|
+
* document-order index (0, 1, 2, …); the site's CSS maps that ordinal to an
|
|
174
|
+
* entrance delay. The index is inert, so a consumer's sanitize floor can keep
|
|
149
175
|
* `data-rise` while dropping `style`. Nested primitives never get it. Non-primitive
|
|
150
176
|
* content (lede, intro paragraphs, the page-toc nav) passes through untouched.
|
|
151
177
|
*/
|
|
152
|
-
export function rehypeDispatch(registry
|
|
178
|
+
export function rehypeDispatch(registry) {
|
|
153
179
|
return (tree) => {
|
|
154
180
|
let idx = 0;
|
|
155
181
|
tree.children = tree.children.map((child) => {
|
|
156
182
|
if (isElement(child) && child.properties?.dataPrimitive) {
|
|
157
183
|
const el = transformNode(child, registry);
|
|
158
|
-
|
|
159
|
-
el.properties = { ...el.properties, dataRise: String(idx++) };
|
|
184
|
+
el.properties = { ...el.properties, dataRise: String(idx++) };
|
|
160
185
|
return el;
|
|
161
186
|
}
|
|
162
187
|
if (isElement(child))
|
|
@@ -63,8 +63,7 @@ export function remarkDirectiveStamp(registry) {
|
|
|
63
63
|
const def = registry.get(node.name);
|
|
64
64
|
const attrs = node.attributes ?? {};
|
|
65
65
|
const role = attrs.role || undefined;
|
|
66
|
-
const
|
|
67
|
-
const iconKey = iconField?.key ?? 'icon';
|
|
66
|
+
const iconKey = registry.iconField(node.name) ?? 'icon';
|
|
68
67
|
let icon = attrs[iconKey] || undefined;
|
|
69
68
|
if (!icon && role)
|
|
70
69
|
icon = registry.defaultIcon(node.name, role);
|
|
@@ -78,10 +77,10 @@ export function remarkDirectiveStamp(registry) {
|
|
|
78
77
|
// back to that default the same way a missing one does. data-attr-<key> survives to the
|
|
79
78
|
// element; build() consumes it and returns a fresh element, so the marker never reaches the
|
|
80
79
|
// published DOM.
|
|
81
|
-
for (const
|
|
82
|
-
const raw =
|
|
80
|
+
for (const name of Object.keys(def?.attributes ?? {})) {
|
|
81
|
+
const raw = name === iconKey ? icon : attrs[name];
|
|
83
82
|
if (raw != null)
|
|
84
|
-
properties[dataAttrProp(
|
|
83
|
+
properties[dataAttrProp(name)] = raw;
|
|
85
84
|
}
|
|
86
85
|
const data = node.data ?? (node.data = {});
|
|
87
86
|
data.hName = 'div';
|
|
@@ -17,7 +17,7 @@ const FIXED_MARKERS = ['dataPrimitive', 'dataSlot', 'dataRole', 'dataRise'];
|
|
|
17
17
|
* allowlist but not weaken the core strip.
|
|
18
18
|
*/
|
|
19
19
|
export function buildSanitizeSchema(registry, extend) {
|
|
20
|
-
const attrMarkers = registry.defs.flatMap((d) => (d.attributes ??
|
|
20
|
+
const attrMarkers = registry.defs.flatMap((d) => Object.keys(d.attributes ?? {}).map((key) => dataAttrProp(key)));
|
|
21
21
|
const markers = [...FIXED_MARKERS, ...attrMarkers];
|
|
22
22
|
const attributes = defaultSchema.attributes ?? {};
|
|
23
23
|
// defaultSchema's `a` entry carries a className tuple (`['className', 'data-footnote-backref']`)
|
|
@@ -2,7 +2,7 @@ import { type ContentRoutesDeps, type LayoutData, type ListData, type EditData,
|
|
|
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';
|
|
5
|
-
import type {
|
|
5
|
+
import type { BackendEnv } from '../github/credentials.js';
|
|
6
6
|
import type { CairnRuntime } from '../content/types.js';
|
|
7
7
|
import type { CookieJar, EventBase } from './types.js';
|
|
8
8
|
/**
|
|
@@ -10,19 +10,19 @@ import type { CookieJar, EventBase } from './types.js';
|
|
|
10
10
|
* (ContentEvent minus params, which the dispatcher synthesizes, plus RequestContext's cookies
|
|
11
11
|
* and setHeaders). A real SvelteKit RequestEvent satisfies it.
|
|
12
12
|
*/
|
|
13
|
-
export interface AdminEvent extends EventBase<
|
|
13
|
+
export interface AdminEvent extends EventBase<BackendEnv & AuthEnv> {
|
|
14
14
|
cookies: CookieJar;
|
|
15
15
|
setHeaders(headers: Record<string, string>): void;
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* Injectable dependencies. Branding defaults from the runtime's siteName and sender, so a
|
|
19
|
-
* site overrides it only to change the magic-link email identity; `send`
|
|
20
|
-
*
|
|
19
|
+
* site overrides it only to change the magic-link email identity; `send` is the same seam the
|
|
20
|
+
* underlying auth factory takes. The content backend rides `event.locals.backend` (the dev double)
|
|
21
|
+
* or the adapter's provider, so it is not a dep here.
|
|
21
22
|
*/
|
|
22
23
|
export interface CairnAdminDeps {
|
|
23
24
|
branding?: AuthBranding;
|
|
24
25
|
send?: SendMagicLink;
|
|
25
|
-
mintToken?: ContentRoutesDeps['mintToken'];
|
|
26
26
|
/**
|
|
27
27
|
* Build the Anthropic client for the tidy action. Forwarded to the content routes; a site that
|
|
28
28
|
* enables tidy injects a stub here to avoid a real network call. Defaults to the real SDK client.
|
|
@@ -23,13 +23,12 @@ export function createCairnAdmin(runtime, deps = {}) {
|
|
|
23
23
|
};
|
|
24
24
|
const auth = createAuthRoutes({ branding, send: deps.send });
|
|
25
25
|
const content = createContentRoutes(runtime, {
|
|
26
|
-
mintToken: deps.mintToken,
|
|
27
26
|
anthropic: deps.anthropic,
|
|
28
27
|
tidyTimeoutMs: deps.tidyTimeoutMs,
|
|
29
28
|
});
|
|
30
29
|
const editors = createEditorRoutes();
|
|
31
30
|
// The nav surface exists only when the site configures a menu; without one its view is a 404.
|
|
32
|
-
const nav = runtime.navMenu ? createNavRoutes(runtime
|
|
31
|
+
const nav = runtime.navMenu ? createNavRoutes(runtime) : null;
|
|
33
32
|
/**
|
|
34
33
|
* Build the event a wrapped content load reads. The catch-all route carries only a rest
|
|
35
34
|
* param, so `concept` and `id` are synthesized from the parsed view. The override names
|
|
@@ -49,8 +48,8 @@ export function createCairnAdmin(runtime, deps = {}) {
|
|
|
49
48
|
}
|
|
50
49
|
/**
|
|
51
50
|
* Serve the admin view the pathname names, or a 404 for any shape the parser refuses.
|
|
52
|
-
* The authed views run the layout load and the view load concurrently; both
|
|
53
|
-
*
|
|
51
|
+
* The authed views run the layout load and the view load concurrently; both resolve the same
|
|
52
|
+
* backend, and the installation-token cache coalesces their lazy mints into one signing.
|
|
54
53
|
*/
|
|
55
54
|
async function load(event) {
|
|
56
55
|
const view = parseAdminPath(event.url.pathname, runtime.concepts);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { fail } from '@sveltejs/kit';
|
|
2
2
|
import { type AdvisoryNotice } from '../content/advisories.js';
|
|
3
|
-
import {
|
|
3
|
+
import type { BackendEnv } from '../github/credentials.js';
|
|
4
|
+
import type { Backend } from '../github/backend.js';
|
|
4
5
|
import { type LinkTarget, type InboundLink } from '../content/manifest.js';
|
|
5
6
|
import { type GettingStarted } from '../content/getting-started.js';
|
|
6
7
|
import { type MarkdownReferenceRow } from '../components/markdown-reference.js';
|
|
@@ -13,7 +14,7 @@ import type { RepointPlacement, AltPlacement } from '../content/media-rewrite.js
|
|
|
13
14
|
import type { BranchRef } from '../media/rewrite-plan.js';
|
|
14
15
|
import type { BulkDeleteSkip } from '../media/bulk-delete-plan.js';
|
|
15
16
|
import type { CookieJar, EventBase } from './types.js';
|
|
16
|
-
import type { CairnRuntime,
|
|
17
|
+
import type { CairnRuntime, NamedField, ResolvedPreview } from '../content/types.js';
|
|
17
18
|
import type { Role } from '../auth/types.js';
|
|
18
19
|
export type { AdvisoryNotice, AdvisoryAction } from '../content/advisories.js';
|
|
19
20
|
/** A sidebar concept entry: just enough to render the nav without shipping validators to the client. */
|
|
@@ -90,7 +91,7 @@ export interface EditData {
|
|
|
90
91
|
conceptId: string;
|
|
91
92
|
id: string;
|
|
92
93
|
label: string;
|
|
93
|
-
fields:
|
|
94
|
+
fields: NamedField[];
|
|
94
95
|
frontmatter: Record<string, unknown>;
|
|
95
96
|
body: string;
|
|
96
97
|
title: string;
|
|
@@ -259,7 +260,7 @@ export interface HelpData {
|
|
|
259
260
|
supportContact?: string;
|
|
260
261
|
}
|
|
261
262
|
/** The structural event the content routes read; a real SvelteKit RequestEvent satisfies it. */
|
|
262
|
-
export interface ContentEvent extends EventBase<
|
|
263
|
+
export interface ContentEvent extends EventBase<BackendEnv> {
|
|
263
264
|
params: Record<string, string>;
|
|
264
265
|
/**
|
|
265
266
|
* SvelteKit's cookie jar. The layout load reads the persisted admin theme and issues the CSRF
|
|
@@ -303,10 +304,12 @@ export interface TidyClient {
|
|
|
303
304
|
}
|
|
304
305
|
export interface ContentRoutesDeps {
|
|
305
306
|
/**
|
|
306
|
-
*
|
|
307
|
-
*
|
|
307
|
+
* Override the resolved content backend. A test injects a live `Backend` (a `makeGithubBackend`
|
|
308
|
+
* over a fetch double, or an in-memory fake) so the read and commit paths run with no real token
|
|
309
|
+
* mint. When set it replaces the per-handler `locals.backend ?? runtime.backend.connect(env)`
|
|
310
|
+
* resolve; a production caller leaves it unset and the dev double rides `event.locals.backend`.
|
|
308
311
|
*/
|
|
309
|
-
|
|
312
|
+
backend?: Backend;
|
|
310
313
|
/**
|
|
311
314
|
* Build the Anthropic client for the tidy action from the resolved API key. Defaults to the real
|
|
312
315
|
* SDK client. Injected in tests so `messages.create` is stubbed and no network call (or real key)
|
|
@@ -579,5 +582,4 @@ export declare function createContentRoutes(runtime: CairnRuntime, deps?: Conten
|
|
|
579
582
|
mediaAltApply: (event: ContentEvent) => Promise<ReturnType<typeof fail> | never>;
|
|
580
583
|
addDictionaryWord: (event: ContentEvent) => Promise<ReturnType<typeof fail> | DictionaryAddResult>;
|
|
581
584
|
tidyAction: (event: ContentEvent) => Promise<ReturnType<typeof fail> | TidyResult>;
|
|
582
|
-
mintToken: (env: GithubKeyEnv) => string | Promise<string>;
|
|
583
585
|
};
|