@glw907/cairn-cms 0.24.0 → 0.26.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 +87 -0
- package/README.md +50 -37
- package/dist/content/compose.d.ts +15 -4
- package/dist/content/compose.d.ts.map +1 -1
- package/dist/content/compose.js +9 -4
- package/dist/content/manifest.d.ts +20 -3
- package/dist/content/manifest.d.ts.map +1 -1
- package/dist/content/manifest.js +49 -6
- package/dist/content/validate.d.ts +4 -1
- package/dist/content/validate.d.ts.map +1 -1
- package/dist/content/validate.js +4 -1
- package/dist/delivery/content-index.d.ts +4 -0
- package/dist/delivery/content-index.d.ts.map +1 -1
- package/dist/delivery/data.d.ts +24 -0
- package/dist/delivery/data.d.ts.map +1 -0
- package/dist/delivery/data.js +18 -0
- package/dist/delivery/index.d.ts +1 -23
- package/dist/delivery/index.d.ts.map +1 -1
- package/dist/delivery/index.js +5 -20
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/render/pipeline.d.ts +2 -2
- package/dist/render/pipeline.d.ts.map +1 -1
- package/dist/render/pipeline.js +2 -1
- package/dist/vite/bin.d.ts +3 -0
- package/dist/vite/bin.d.ts.map +1 -0
- package/dist/vite/bin.js +9 -0
- package/dist/vite/index.d.ts +33 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +178 -0
- package/package.json +21 -4
- package/src/lib/content/compose.ts +18 -9
- package/src/lib/content/manifest.ts +63 -7
- package/src/lib/content/validate.ts +4 -1
- package/src/lib/delivery/content-index.ts +4 -0
- package/src/lib/delivery/data.ts +26 -0
- package/src/lib/delivery/index.ts +5 -28
- package/src/lib/index.ts +3 -1
- package/src/lib/render/pipeline.ts +5 -2
- package/src/lib/vite/bin.ts +10 -0
- package/src/lib/vite/index.ts +213 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are recorded here, most recent first.
|
|
4
|
+
|
|
5
|
+
## 0.26.0
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- A `cairnManifest()` Vite plugin (`@glw907/cairn-cms/vite`) verifies the committed content manifest on
|
|
9
|
+
every build and fails the build with a diff naming what drifted. The check runs outside the prerender
|
|
10
|
+
lifecycle, so `handleHttpError` cannot mask it. Consumers must: add `cairnManifest({ configModule,
|
|
11
|
+
content, manifestPath })` to the Vite config.
|
|
12
|
+
- A `cairn-manifest` bin regenerates the committed manifest from a Vite context. Consumers must: set the
|
|
13
|
+
regenerate script to `"cairn:manifest": "cairn-manifest"` and delete the hand-written
|
|
14
|
+
`scripts/build-manifest.mjs`.
|
|
15
|
+
- A node-safe `@glw907/cairn-cms/delivery/data` entry exposes the pure delivery projections with no
|
|
16
|
+
`@sveltejs/kit` in the graph. Consumers must: move any plain-Node import of a delivery data helper
|
|
17
|
+
(such as `buildSiteManifest`) from `@glw907/cairn-cms/delivery` to `@glw907/cairn-cms/delivery/data`.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
- `verifyManifest` now throws an error that names the added, removed, and changed entries. Consumers
|
|
21
|
+
must: nothing. The message is strictly more informative.
|
|
22
|
+
|
|
23
|
+
## 0.25.0
|
|
24
|
+
|
|
25
|
+
### Changed (breaking)
|
|
26
|
+
- `composeRuntime` now takes a single object, `composeRuntime({ adapter, siteConfig, extensions? })`,
|
|
27
|
+
and derives the per-concept URL policy from `siteConfig`. The loose third `urlPolicy` argument is
|
|
28
|
+
gone, and a missing `siteConfig` throws. Consumers must: pass the parsed site config to every
|
|
29
|
+
`composeRuntime` call and drop any hand-passed URL policy.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
- `createRenderer()` now defaults its registry to the empty registry, so a plain-prose site calls
|
|
33
|
+
`createRenderer()` with no argument. Consumers must: nothing; passing a built registry is unchanged.
|
|
34
|
+
|
|
35
|
+
### Docs
|
|
36
|
+
- A render sanitize-floor reference (`docs/render-sanitize-floor.md`) states what the floor keeps,
|
|
37
|
+
strips, and rewrites, including the `target="_blank"` rel policy.
|
|
38
|
+
- An upgrade guide (`docs/upgrading.md`) collects the `0.x` renames with a consumer action each.
|
|
39
|
+
|
|
40
|
+
## 0.24.0
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
- `headRow(title, icon?)` builds the icon-plus-heading component head, exported beside `cardShell` and
|
|
44
|
+
`iconSpan`.
|
|
45
|
+
- A `createRenderer` `anchorRel` option sets the `rel` value forced on `target="_blank"` anchors
|
|
46
|
+
(default `'noopener noreferrer'`), or disables the injection when set to `false`.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
- A component's `defaultIconByRole` default now reaches the build through the declared `type: 'icon'`
|
|
50
|
+
attribute (`ctx.attributes`), so a role default no longer needs a hardcoded fallback in the build. A
|
|
51
|
+
component using `defaultIconByRole` must declare a `type: 'icon'` attribute.
|
|
52
|
+
- The engine drops an unclaimed directive `[label]` when a component has no `title` slot, so a stray
|
|
53
|
+
`[]` no longer renders an empty paragraph.
|
|
54
|
+
|
|
55
|
+
### Removed
|
|
56
|
+
- The internal `data-icon` marker, which no build read. The resolved icon now travels on the declared
|
|
57
|
+
attribute path.
|
|
58
|
+
|
|
59
|
+
## 0.23.0
|
|
60
|
+
|
|
61
|
+
### Changed (breaking)
|
|
62
|
+
- A `date` field now validates a real `YYYY-MM-DD` calendar date. A site adopting this version whose
|
|
63
|
+
committed content holds a malformed or impossible date will see it fail validation, which is the loud
|
|
64
|
+
failure this restores.
|
|
65
|
+
- A `tags` field now enforces its declared `options` as a closed vocabulary. A committed value outside
|
|
66
|
+
the list fails validation. Use a `freetags` field for free-form tags.
|
|
67
|
+
- `normalizeConcepts` now throws when a `summaryFields` key names no declared field, so a typo fails at
|
|
68
|
+
config load instead of silently producing an empty list card.
|
|
69
|
+
|
|
70
|
+
### Changed
|
|
71
|
+
- `AttributeField.options` is now `readonly string[]`, so a site can share one frozen `as const`
|
|
72
|
+
vocabulary across components. Read-only by use, so no call site changes.
|
|
73
|
+
|
|
74
|
+
## 0.22.0
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
- `ContentSummary.concept` and `EntryData.concept`: the read model carries its resolved concept id, so a
|
|
78
|
+
list or page branches per concept without re-deriving it from `entry.date`.
|
|
79
|
+
- A `summaryFields` knob on a concept config surfaces named frontmatter keys on `ContentSummary.fields`,
|
|
80
|
+
so a list card reads an authored field with no per-entry detail read.
|
|
81
|
+
- The package root re-exports the delivery route loaders (`createPublicRoutes`) and the response helpers
|
|
82
|
+
(`rssResponse`, `jsonFeedResponse`, `sitemapResponse`, `robotsResponse`).
|
|
83
|
+
|
|
84
|
+
### Changed (breaking)
|
|
85
|
+
- `CairnHead` moved off the `@glw907/cairn-cms/delivery` barrel to its own `@glw907/cairn-cms/delivery/head`
|
|
86
|
+
entry, so a node-environment data import from `/delivery` stays component-free. Update the import:
|
|
87
|
+
`import { CairnHead } from '@glw907/cairn-cms/delivery/head'`.
|
package/README.md
CHANGED
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
# cairn-cms
|
|
2
2
|
|
|
3
3
|
An embedded, **magic-link**, GitHub-committing CMS for SvelteKit + Cloudflare sites.
|
|
4
|
-
Non-technical authors log in by email (no GitHub account, no password), edit **raw
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
and auto-deploys.
|
|
4
|
+
Non-technical authors log in by email (no GitHub account, no password), edit **raw markdown**
|
|
5
|
+
in a client-only CodeMirror editor with a live preview, and save. Each save commits to `main`
|
|
6
|
+
via a **GitHub App** (committer = `cairn-cms[bot]`, author = the editor) and auto-deploys.
|
|
8
7
|
|
|
9
|
-
It is **design-agnostic
|
|
10
|
-
|
|
11
|
-
sites with completely different markdown pipelines
|
|
12
|
-
|
|
8
|
+
It is **design-agnostic**. Each consumer site supplies an adapter (the content contract through
|
|
9
|
+
`defineAdapter`/`defineFields`, the slug and permalink rules, and its render configuration), so the
|
|
10
|
+
same engine drives sites with completely different markdown pipelines. Two run in production today:
|
|
11
|
+
[ecnordic.ski](https://ecnordic.ski) (a remark-to-rehype directive pipeline) and
|
|
12
|
+
[907.life](https://907.life) (the engine's own `createRenderer`). Content is a fixed set of
|
|
13
|
+
first-class concepts (Posts and Pages), not open-ended collections.
|
|
13
14
|
|
|
14
15
|
## Status
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
17
|
+
cairn-cms runs two production sites today, [ecnordic.ski](https://ecnordic.ski) and
|
|
18
|
+
[907.life](https://907.life). It is `0.x` and breaks between minor versions. The author is
|
|
19
|
+
still working through the core-feature roadmap, and the project stays closely held until that
|
|
20
|
+
core lands. See the [ROADMAP](./ROADMAP.md) for what is planned and the
|
|
21
|
+
[CHANGELOG](./CHANGELOG.md) for what changed.
|
|
22
|
+
|
|
23
|
+
Editor auth is self-owned: an atomic single-use magic-link token, a POST-confirm flow, opaque
|
|
24
|
+
D1-backed session rows, and two-tier `owner`/`editor` roles. There is no better-auth, Drizzle,
|
|
25
|
+
or ORM. Pin a caret range and read the CHANGELOG before bumping; every breaking entry carries a
|
|
26
|
+
"Consumers must" line.
|
|
27
|
+
|
|
28
|
+
A contributor who feels inspired is welcome to open an issue or a discussion to start a
|
|
29
|
+
conversation. There is no formal contribution process yet, so this is not an open call for
|
|
30
|
+
pull requests.
|
|
30
31
|
|
|
31
32
|
## Install
|
|
32
33
|
|
|
@@ -34,23 +35,35 @@ range and expect 0.x churn.
|
|
|
34
35
|
npm install @glw907/cairn-cms
|
|
35
36
|
```
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
`@glw907/cairn-cms/sveltekit` (server logic) and `@glw907/cairn-cms/components` (the admin UI).
|
|
38
|
+
Peer dependencies: `svelte@^5` and `@sveltejs/kit@^2`. A consumer site implements a `CairnAdapter`
|
|
39
|
+
and mounts thin `/admin` route shims around the package subpaths:
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
- `@glw907/cairn-cms`: the core engine and adapter contract.
|
|
42
|
+
- `@glw907/cairn-cms/sveltekit`: the server load and action logic.
|
|
43
|
+
- `@glw907/cairn-cms/components`: the admin Svelte UI.
|
|
44
|
+
- `@glw907/cairn-cms/delivery` and `/delivery/data`: the public read model (indexes, feeds,
|
|
45
|
+
sitemap, SEO head). The `/delivery/data` barrel is node-safe, with no `@sveltejs/kit` in its graph.
|
|
46
|
+
- `@glw907/cairn-cms/vite`: the `cairnManifest()` Vite plugin, paired with the `cairn-manifest` bin,
|
|
47
|
+
that builds and verifies the committed content manifest at build time.
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
Each site binds a Cloudflare D1 database as `AUTH_DB` (the editor allowlist, sessions, and single-use
|
|
50
|
+
magic tokens) and a `[[send_email]]` binding named `EMAIL`. The worked reference for every shape is
|
|
51
|
+
`examples/showcase`.
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
## Documentation
|
|
54
|
+
|
|
55
|
+
The [`docs/`](./docs/README.md) tree is organized in four arms: a tutorial that builds a first
|
|
56
|
+
site end to end, how-to guides for each setup task, a reference for every package export, and
|
|
57
|
+
explanation pages for the architecture and design rules. Start at the
|
|
58
|
+
[documentation index](./docs/README.md). The [security policy](./SECURITY.md) covers reporting
|
|
59
|
+
and the security posture.
|
|
60
|
+
|
|
61
|
+
## How it's developed
|
|
51
62
|
|
|
52
|
-
|
|
53
|
-
|
|
63
|
+
This is a standalone repo. Consumer sites install the published package from the npm registry by
|
|
64
|
+
version range. The library's own development proves changes against `examples/showcase`, a
|
|
65
|
+
self-contained SvelteKit site that consumes the package through the relative `file:../..` path, so a
|
|
66
|
+
change is exercised end to end before it publishes.
|
|
54
67
|
|
|
55
|
-
|
|
56
|
-
|
|
68
|
+
The historical rebuild plan and the early architecture writeups live under `docs/internal/`.
|
|
69
|
+
They are kept for history and are not current.
|
|
@@ -1,7 +1,18 @@
|
|
|
1
|
-
import type { CairnAdapter, CairnExtension, CairnRuntime
|
|
1
|
+
import type { CairnAdapter, CairnExtension, CairnRuntime } from './types.js';
|
|
2
|
+
import { type SiteConfig } from '../nav/site-config.js';
|
|
3
|
+
/** The input to {@link composeRuntime}. `siteConfig` is required so the per-concept URL policy is
|
|
4
|
+
* always derived from one source and can never be silently dropped. `extensions` fold in after the
|
|
5
|
+
* adapter's concepts. */
|
|
6
|
+
export interface ComposeInput {
|
|
7
|
+
adapter: CairnAdapter;
|
|
8
|
+
siteConfig: SiteConfig;
|
|
9
|
+
extensions?: CairnExtension[];
|
|
10
|
+
}
|
|
2
11
|
/**
|
|
3
|
-
* Fold an adapter and any extensions into the composed runtime (seam 2).
|
|
4
|
-
*
|
|
12
|
+
* Fold an adapter and any extensions into the composed runtime (seam 2). The per-concept URL policy
|
|
13
|
+
* is derived from the site config, the same source the delivery path uses, so the runtime and
|
|
14
|
+
* delivery permalinks cannot diverge. Extension concepts merge after the adapter's. The asset slot
|
|
15
|
+
* (seam 4) passes through untouched.
|
|
5
16
|
*/
|
|
6
|
-
export declare function composeRuntime(adapter
|
|
17
|
+
export declare function composeRuntime({ adapter, siteConfig, extensions }: ComposeInput): CairnRuntime;
|
|
7
18
|
//# sourceMappingURL=compose.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/lib/content/compose.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAc,YAAY,EAAE,cAAc,EAAE,YAAY,EAAiB,
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/lib/content/compose.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAc,YAAY,EAAE,cAAc,EAAE,YAAY,EAA+B,MAAM,YAAY,CAAC;AAEtH,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEvE;;0BAE0B;AAC1B,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,UAAe,EAAE,EAAE,YAAY,GAAG,YAAY,CA0BnG"}
|
package/dist/content/compose.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { normalizeConcepts } from './concepts.js';
|
|
2
|
+
import { urlPolicyFrom } from '../nav/site-config.js';
|
|
2
3
|
/**
|
|
3
|
-
* Fold an adapter and any extensions into the composed runtime (seam 2).
|
|
4
|
-
*
|
|
4
|
+
* Fold an adapter and any extensions into the composed runtime (seam 2). The per-concept URL policy
|
|
5
|
+
* is derived from the site config, the same source the delivery path uses, so the runtime and
|
|
6
|
+
* delivery permalinks cannot diverge. Extension concepts merge after the adapter's. The asset slot
|
|
7
|
+
* (seam 4) passes through untouched.
|
|
5
8
|
*/
|
|
6
|
-
export function composeRuntime(adapter, extensions = []
|
|
9
|
+
export function composeRuntime({ adapter, siteConfig, extensions = [] }) {
|
|
10
|
+
if (!siteConfig)
|
|
11
|
+
throw new Error('composeRuntime needs a site config to derive the URL policy');
|
|
7
12
|
const content = { ...adapter.content };
|
|
8
13
|
const adminPanels = [];
|
|
9
14
|
const fieldTypes = [];
|
|
@@ -19,7 +24,7 @@ export function composeRuntime(adapter, extensions = [], urlPolicy = {}) {
|
|
|
19
24
|
}
|
|
20
25
|
return {
|
|
21
26
|
siteName: adapter.siteName,
|
|
22
|
-
concepts: normalizeConcepts(content,
|
|
27
|
+
concepts: normalizeConcepts(content, urlPolicyFrom(siteConfig)),
|
|
23
28
|
backend: adapter.backend,
|
|
24
29
|
sender: adapter.sender,
|
|
25
30
|
render: adapter.render,
|
|
@@ -39,9 +39,26 @@ export declare function serializeManifest(manifest: Manifest): string;
|
|
|
39
39
|
* error. The build regenerates the manifest, so a real file is always canonical; this guards a
|
|
40
40
|
* hand-edited or truncated one. */
|
|
41
41
|
export declare function parseManifest(raw: string): Manifest;
|
|
42
|
-
/**
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
/** A changed entry and the fields that differ between the built and committed manifests. */
|
|
43
|
+
export interface ManifestEntryDiff {
|
|
44
|
+
concept: string;
|
|
45
|
+
id: string;
|
|
46
|
+
fields: string[];
|
|
47
|
+
}
|
|
48
|
+
/** The drift between a freshly built manifest and the committed one, keyed by concept+id. */
|
|
49
|
+
export interface ManifestDiff {
|
|
50
|
+
added: ManifestEntry[];
|
|
51
|
+
removed: ManifestEntry[];
|
|
52
|
+
changed: ManifestEntryDiff[];
|
|
53
|
+
}
|
|
54
|
+
/** Compare a built manifest against a committed one, keyed by concept+id (the same identity
|
|
55
|
+
* upsertEntry and removeEntry use). A changed entry names the fields that differ. Pure, so it is
|
|
56
|
+
* unit-tested apart from any build. */
|
|
57
|
+
export declare function diffManifests(built: Manifest, committed: Manifest): ManifestDiff;
|
|
58
|
+
/** Throw if the committed manifest drifts from what the corpus says. The canonical serialized form
|
|
59
|
+
* is the fast-path equality guard, so semantic equality never spuriously fails. On a mismatch the
|
|
60
|
+
* error names the added, removed, and changed entries, so a raw-git content edit that leaves the
|
|
61
|
+
* committed manifest stale fails the build loudly with what drifted. */
|
|
45
62
|
export declare function verifyManifest(built: Manifest, committedRaw: string): void;
|
|
46
63
|
/** Replace the entry with the same concept and id, or add it. Order does not matter, since
|
|
47
64
|
* serializeManifest sorts. This is the save path's incremental patch. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/lib/content/manifest.ts"],"names":[],"mappings":"AAQA,OAAO,EAAqB,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,4FAA4F;AAC5F,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,yFAAyF;AACzF,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,+EAA+E;AAC/E,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB;AAmBD,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,iBAAiB,EAAE,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,CAiBvH;AAED,+EAA+E;AAC/E,wBAAgB,aAAa,IAAI,QAAQ,CAExC;AAMD;oGACoG;AACpG,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAW5D;AAED;;;oCAGoC;AACpC,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAqCnD;AAED
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/lib/content/manifest.ts"],"names":[],"mappings":"AAQA,OAAO,EAAqB,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,4FAA4F;AAC5F,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,yFAAyF;AACzF,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,+EAA+E;AAC/E,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB;AAmBD,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,iBAAiB,EAAE,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,CAiBvH;AAED,+EAA+E;AAC/E,wBAAgB,aAAa,IAAI,QAAQ,CAExC;AAMD;oGACoG;AACpG,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAW5D;AAED;;;oCAGoC;AACpC,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAqCnD;AAED,4FAA4F;AAC5F,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,6FAA6F;AAC7F,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAID;;wCAEwC;AACxC,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,GAAG,YAAY,CAkBhF;AAWD;;;yEAGyE;AACzE,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAa1E;AAED;0EAC0E;AAC1E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,GAAG,QAAQ,CAI9E;AAED,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,QAAQ,CAErF;AAED,2FAA2F;AAC3F,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;sFAEsF;AACtF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,WAAW,EAAE,CAK3F;AAED;iGACiG;AACjG,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,WAAW,CAG/G"}
|
package/dist/content/manifest.js
CHANGED
|
@@ -104,13 +104,56 @@ export function parseManifest(raw) {
|
|
|
104
104
|
}
|
|
105
105
|
return { version: 1, entries: obj.entries };
|
|
106
106
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
*
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
107
|
+
const keyOf = (e) => `${e.concept}/${e.id}`;
|
|
108
|
+
/** Compare a built manifest against a committed one, keyed by concept+id (the same identity
|
|
109
|
+
* upsertEntry and removeEntry use). A changed entry names the fields that differ. Pure, so it is
|
|
110
|
+
* unit-tested apart from any build. */
|
|
111
|
+
export function diffManifests(built, committed) {
|
|
112
|
+
const builtByKey = new Map(built.entries.map((e) => [keyOf(e), e]));
|
|
113
|
+
const committedByKey = new Map(committed.entries.map((e) => [keyOf(e), e]));
|
|
114
|
+
const added = built.entries.filter((e) => !committedByKey.has(keyOf(e)));
|
|
115
|
+
const removed = committed.entries.filter((e) => !builtByKey.has(keyOf(e)));
|
|
116
|
+
const changed = [];
|
|
117
|
+
for (const b of built.entries) {
|
|
118
|
+
const c = committedByKey.get(keyOf(b));
|
|
119
|
+
if (!c)
|
|
120
|
+
continue;
|
|
121
|
+
// ManifestEntry has no index signature, so read its keys through an unknown-cast record.
|
|
122
|
+
const br = b;
|
|
123
|
+
const cr = c;
|
|
124
|
+
const fields = [...new Set([...Object.keys(b), ...Object.keys(c)])].filter((k) => JSON.stringify(br[k]) !== JSON.stringify(cr[k]));
|
|
125
|
+
if (fields.length > 0)
|
|
126
|
+
changed.push({ concept: b.concept, id: b.id, fields });
|
|
113
127
|
}
|
|
128
|
+
return { added, removed, changed };
|
|
129
|
+
}
|
|
130
|
+
/** Format a diff into a short human-readable block for a build error. */
|
|
131
|
+
function formatDiff(d) {
|
|
132
|
+
const lines = [];
|
|
133
|
+
for (const e of d.added)
|
|
134
|
+
lines.push(` + ${keyOf(e)}`);
|
|
135
|
+
for (const e of d.removed)
|
|
136
|
+
lines.push(` - ${keyOf(e)}`);
|
|
137
|
+
for (const e of d.changed)
|
|
138
|
+
lines.push(` ~ ${e.concept}/${e.id} (${e.fields.join(', ')})`);
|
|
139
|
+
return lines.join('\n');
|
|
140
|
+
}
|
|
141
|
+
/** Throw if the committed manifest drifts from what the corpus says. The canonical serialized form
|
|
142
|
+
* is the fast-path equality guard, so semantic equality never spuriously fails. On a mismatch the
|
|
143
|
+
* error names the added, removed, and changed entries, so a raw-git content edit that leaves the
|
|
144
|
+
* committed manifest stale fails the build loudly with what drifted. */
|
|
145
|
+
export function verifyManifest(built, committedRaw) {
|
|
146
|
+
const builtRaw = serializeManifest(built);
|
|
147
|
+
if (committedRaw === builtRaw)
|
|
148
|
+
return;
|
|
149
|
+
// Diff the canonical built form, not the raw one. serializeManifest sorts each entry's links, so a
|
|
150
|
+
// build whose links are in extraction order would otherwise report a false (links) drift for an
|
|
151
|
+
// entry whose link set is identical and only the order differs. Reuse the serialized form so both
|
|
152
|
+
// sides are canonical.
|
|
153
|
+
const diff = diffManifests(parseManifest(builtRaw), parseManifest(committedRaw));
|
|
154
|
+
throw new Error('content manifest is stale: the committed file does not match the corpus.\n' +
|
|
155
|
+
formatDiff(diff) +
|
|
156
|
+
'\nRegenerate it (npm run cairn:manifest) and commit the result.');
|
|
114
157
|
}
|
|
115
158
|
/** Replace the entry with the same concept and id, or add it. Order does not matter, since
|
|
116
159
|
* serializeManifest sorts. This is the save path's incremental patch. */
|
|
@@ -3,7 +3,10 @@ import type { FrontmatterField, ValidationResult } from './types.js';
|
|
|
3
3
|
* Validate raw frontmatter against a field list. Required text and date fields must be
|
|
4
4
|
* non-empty; required tag fields must be non-empty lists. A present boolean coerces to `true`
|
|
5
5
|
* and an unchecked one is omitted; a present tag field coerces to a string array and an empty
|
|
6
|
-
* one is omitted
|
|
6
|
+
* one is omitted, so validated data carries no key for an absent tag field (`tags` or `freetags`).
|
|
7
|
+
* The delivery read model
|
|
8
|
+
* (`ContentSummary.tags`) fills that case with an empty array; the two layers differ on purpose.
|
|
9
|
+
* An empty optional text or date field is omitted, so the normalized data
|
|
7
10
|
* carries only meaningful values and committed frontmatter stays minimal. Returns the
|
|
8
11
|
* normalized data, or field-keyed errors when any required field is empty.
|
|
9
12
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/lib/content/validate.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGrE
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/lib/content/validate.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGrE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,gBAAgB,EAAE,EAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,gBAAgB,CAoClB"}
|
package/dist/content/validate.js
CHANGED
|
@@ -3,7 +3,10 @@ import { dateInputValue, isCalendarDate } from './frontmatter.js';
|
|
|
3
3
|
* Validate raw frontmatter against a field list. Required text and date fields must be
|
|
4
4
|
* non-empty; required tag fields must be non-empty lists. A present boolean coerces to `true`
|
|
5
5
|
* and an unchecked one is omitted; a present tag field coerces to a string array and an empty
|
|
6
|
-
* one is omitted
|
|
6
|
+
* one is omitted, so validated data carries no key for an absent tag field (`tags` or `freetags`).
|
|
7
|
+
* The delivery read model
|
|
8
|
+
* (`ContentSummary.tags`) fills that case with an empty array; the two layers differ on purpose.
|
|
9
|
+
* An empty optional text or date field is omitted, so the normalized data
|
|
7
10
|
* carries only meaningful values and committed frontmatter stays minimal. Returns the
|
|
8
11
|
* normalized data, or field-keyed errors when any required field is empty.
|
|
9
12
|
*
|
|
@@ -15,6 +15,10 @@ export interface ContentSummary {
|
|
|
15
15
|
title: string;
|
|
16
16
|
date?: string;
|
|
17
17
|
updated?: string;
|
|
18
|
+
/** The entry's tags, always present as an array and empty when the file declares none. This is the
|
|
19
|
+
* read-model normalization. It differs on purpose from the validated `frontmatter.tags`, which the
|
|
20
|
+
* validator omits when empty, so a published file carries no `tags: []` noise. Read `tags` here for
|
|
21
|
+
* a list; read `frontmatter.tags` only when you need the validated, possibly-absent value. */
|
|
18
22
|
tags: string[];
|
|
19
23
|
excerpt: string;
|
|
20
24
|
wordCount: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-index.d.ts","sourceRoot":"","sources":["../../src/lib/delivery/content-index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,yFAAyF;AACzF,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC7B;yEACqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf;;mFAE+E;IAC/E,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;wEAEwE;AACxE,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,cAAc;IAC/E,WAAW,EAAE,CAAC,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wFAAwF;AACxF,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,qCAAqC;AACrC,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACvD,GAAG,CAAC,IAAI,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,cAAc,EAAE,CAAC;IAC1D,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAC9C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,cAAc,EAAE,CAAC;IACzE,OAAO,IAAI;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG;QAAE,KAAK,CAAC,EAAE,cAAc,CAAC;QAAC,KAAK,CAAC,EAAE,cAAc,CAAA;KAAE,CAAC;IACzE,sFAAsF;IACtF,QAAQ,IAAI,cAAc,EAAE,CAAC;CAC9B;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,EAAE,CAElE;AAqBD,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,KAAK,EAAE,OAAO,EAAE,EAChB,UAAU,EAAE,iBAAiB,GAC5B,YAAY,CAAC,CAAC,CAAC,CA4EjB"}
|
|
1
|
+
{"version":3,"file":"content-index.d.ts","sourceRoot":"","sources":["../../src/lib/delivery/content-index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,yFAAyF;AACzF,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC7B;yEACqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;mGAG+F;IAC/F,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf;;mFAE+E;IAC/E,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;wEAEwE;AACxE,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,cAAc;IAC/E,WAAW,EAAE,CAAC,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wFAAwF;AACxF,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,qCAAqC;AACrC,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACvD,GAAG,CAAC,IAAI,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,cAAc,EAAE,CAAC;IAC1D,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAC9C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,cAAc,EAAE,CAAC;IACzE,OAAO,IAAI;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG;QAAE,KAAK,CAAC,EAAE,cAAc,CAAC;QAAC,KAAK,CAAC,EAAE,cAAc,CAAA;KAAE,CAAC;IACzE,sFAAsF;IACtF,QAAQ,IAAI,cAAc,EAAE,CAAC;CAC9B;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,EAAE,CAElE;AAqBD,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,KAAK,EAAE,OAAO,EAAE,EAChB,UAAU,EAAE,iBAAiB,GAC5B,YAAY,CAAC,CAAC,CAAC,CA4EjB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export { createContentIndex, fromGlob } from './content-index.js';
|
|
2
|
+
export type { RawFile, ContentSummary, ContentEntry, ContentIndex, ContentProblem } from './content-index.js';
|
|
3
|
+
export { createSiteIndex } from './site-index.js';
|
|
4
|
+
export type { SiteIndex, ConceptIndex } from './site-index.js';
|
|
5
|
+
export { createSiteIndexes } from './site-indexes.js';
|
|
6
|
+
export type { SiteIndexes, SiteGlobs } from './site-indexes.js';
|
|
7
|
+
export { siteDescriptors } from './site-descriptors.js';
|
|
8
|
+
export { deriveExcerpt, wordCount } from './excerpt.js';
|
|
9
|
+
export { buildRssFeed, buildJsonFeed } from './feeds.js';
|
|
10
|
+
export type { FeedChannel, FeedItem } from './feeds.js';
|
|
11
|
+
export { buildSitemap } from './sitemap.js';
|
|
12
|
+
export type { SitemapUrl } from './sitemap.js';
|
|
13
|
+
export { buildRobots } from './robots.js';
|
|
14
|
+
export { buildSeoMeta } from './seo.js';
|
|
15
|
+
export type { SeoInput, SeoMeta } from './seo.js';
|
|
16
|
+
export { readSeoFields, resolveImageUrl } from './seo-fields.js';
|
|
17
|
+
export type { SeoFields } from './seo-fields.js';
|
|
18
|
+
export { paginate } from './paginate.js';
|
|
19
|
+
export type { Page } from './paginate.js';
|
|
20
|
+
export { rssResponse, jsonFeedResponse, sitemapResponse, robotsResponse } from './responses.js';
|
|
21
|
+
export { jsonLdScript } from './json-ld.js';
|
|
22
|
+
export { permalink } from '../content/permalink.js';
|
|
23
|
+
export { buildSiteManifest, buildLinkResolver } from './manifest.js';
|
|
24
|
+
//# sourceMappingURL=data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../src/lib/delivery/data.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAClE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC9G,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACjE,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// cairn-cms: the node-safe delivery data surface (@glw907/cairn-cms/delivery/data). The pure corpus
|
|
2
|
+
// projections a SvelteKit site or a plain-Node tool reads, with no @sveltejs/kit and no .svelte in
|
|
3
|
+
// the graph. The full ./delivery barrel re-exports this and adds the route loaders.
|
|
4
|
+
export { createContentIndex, fromGlob } from './content-index.js';
|
|
5
|
+
export { createSiteIndex } from './site-index.js';
|
|
6
|
+
export { createSiteIndexes } from './site-indexes.js';
|
|
7
|
+
export { siteDescriptors } from './site-descriptors.js';
|
|
8
|
+
export { deriveExcerpt, wordCount } from './excerpt.js';
|
|
9
|
+
export { buildRssFeed, buildJsonFeed } from './feeds.js';
|
|
10
|
+
export { buildSitemap } from './sitemap.js';
|
|
11
|
+
export { buildRobots } from './robots.js';
|
|
12
|
+
export { buildSeoMeta } from './seo.js';
|
|
13
|
+
export { readSeoFields, resolveImageUrl } from './seo-fields.js';
|
|
14
|
+
export { paginate } from './paginate.js';
|
|
15
|
+
export { rssResponse, jsonFeedResponse, sitemapResponse, robotsResponse } from './responses.js';
|
|
16
|
+
export { jsonLdScript } from './json-ld.js';
|
|
17
|
+
export { permalink } from '../content/permalink.js';
|
|
18
|
+
export { buildSiteManifest, buildLinkResolver } from './manifest.js';
|
package/dist/delivery/index.d.ts
CHANGED
|
@@ -1,26 +1,4 @@
|
|
|
1
|
-
export
|
|
2
|
-
export type { RawFile, ContentSummary, ContentEntry, ContentIndex, ContentProblem } from './content-index.js';
|
|
3
|
-
export { createSiteIndex } from './site-index.js';
|
|
4
|
-
export type { SiteIndex, ConceptIndex } from './site-index.js';
|
|
5
|
-
export { createSiteIndexes } from './site-indexes.js';
|
|
6
|
-
export type { SiteIndexes, SiteGlobs } from './site-indexes.js';
|
|
7
|
-
export { siteDescriptors } from './site-descriptors.js';
|
|
8
|
-
export { deriveExcerpt, wordCount } from './excerpt.js';
|
|
9
|
-
export { buildRssFeed, buildJsonFeed } from './feeds.js';
|
|
10
|
-
export type { FeedChannel, FeedItem } from './feeds.js';
|
|
11
|
-
export { buildSitemap } from './sitemap.js';
|
|
12
|
-
export type { SitemapUrl } from './sitemap.js';
|
|
13
|
-
export { buildRobots } from './robots.js';
|
|
14
|
-
export { buildSeoMeta } from './seo.js';
|
|
15
|
-
export type { SeoInput, SeoMeta } from './seo.js';
|
|
16
|
-
export { readSeoFields, resolveImageUrl } from './seo-fields.js';
|
|
17
|
-
export type { SeoFields } from './seo-fields.js';
|
|
18
|
-
export { paginate } from './paginate.js';
|
|
19
|
-
export type { Page } from './paginate.js';
|
|
20
|
-
export { rssResponse, jsonFeedResponse, sitemapResponse, robotsResponse } from './responses.js';
|
|
21
|
-
export { jsonLdScript } from './json-ld.js';
|
|
22
|
-
export { permalink } from '../content/permalink.js';
|
|
23
|
-
export { buildSiteManifest, buildLinkResolver } from './manifest.js';
|
|
1
|
+
export * from './data.js';
|
|
24
2
|
export { createPublicRoutes } from '../sveltekit/public-routes.js';
|
|
25
3
|
export type { PublicRoutesDeps, ListData, TagData, TagIndexData, EntryData, } from '../sveltekit/public-routes.js';
|
|
26
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/delivery/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/delivery/index.ts"],"names":[],"mappings":"AAIA,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,YAAY,EACV,gBAAgB,EAChB,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,SAAS,GACV,MAAM,+BAA+B,CAAC"}
|
package/dist/delivery/index.js
CHANGED
|
@@ -1,21 +1,6 @@
|
|
|
1
|
-
// cairn-cms: the public delivery entry (@glw907/cairn-cms/delivery). The
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
export { createContentIndex, fromGlob } from './content-index.js';
|
|
7
|
-
export { createSiteIndex } from './site-index.js';
|
|
8
|
-
export { createSiteIndexes } from './site-indexes.js';
|
|
9
|
-
export { siteDescriptors } from './site-descriptors.js';
|
|
10
|
-
export { deriveExcerpt, wordCount } from './excerpt.js';
|
|
11
|
-
export { buildRssFeed, buildJsonFeed } from './feeds.js';
|
|
12
|
-
export { buildSitemap } from './sitemap.js';
|
|
13
|
-
export { buildRobots } from './robots.js';
|
|
14
|
-
export { buildSeoMeta } from './seo.js';
|
|
15
|
-
export { readSeoFields, resolveImageUrl } from './seo-fields.js';
|
|
16
|
-
export { paginate } from './paginate.js';
|
|
17
|
-
export { rssResponse, jsonFeedResponse, sitemapResponse, robotsResponse } from './responses.js';
|
|
18
|
-
export { jsonLdScript } from './json-ld.js';
|
|
19
|
-
export { permalink } from '../content/permalink.js';
|
|
20
|
-
export { buildSiteManifest, buildLinkResolver } from './manifest.js';
|
|
1
|
+
// cairn-cms: the public delivery entry (@glw907/cairn-cms/delivery). The node-safe data surface
|
|
2
|
+
// (re-exported from ./delivery/data) plus the SvelteKit catch-all route loaders. The head component
|
|
3
|
+
// lives at ./delivery/head. Importing this pulls @sveltejs/kit through the route loaders, so a
|
|
4
|
+
// plain-Node tool imports from ./delivery/data instead.
|
|
5
|
+
export * from './data.js';
|
|
21
6
|
export { createPublicRoutes } from '../sveltekit/public-routes.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { buildMagicLinkMessage, cloudflareSend } from './email.js';
|
|
|
5
5
|
export type { CairnAdapter, ConceptConfig, FrontmatterField, TextField, TextareaField, DateField, BooleanField, TagsField, FreeTagsField, ValidationResult, BackendConfig, SenderConfig, NavMenuConfig, AssetConfig, RoutingRule, ConceptDescriptor, ConceptUrlPolicy, CairnExtension, CairnRuntime, AdminPanel, FieldTypeDef, } from './content/types.js';
|
|
6
6
|
export { CONCEPT_ROUTING, normalizeConcepts, findConcept } from './content/concepts.js';
|
|
7
7
|
export { composeRuntime } from './content/compose.js';
|
|
8
|
+
export type { ComposeInput } from './content/compose.js';
|
|
8
9
|
export { frontmatterFromForm, dateInputValue, serializeMarkdown, parseMarkdown, } from './content/frontmatter.js';
|
|
9
10
|
export { defineFields } from './content/schema.js';
|
|
10
11
|
export { defineAdapter } from './content/adapter.js';
|
|
@@ -13,8 +14,8 @@ export { isValidId, idFromFilename, filenameFromId, slugify, slugFromId, compose
|
|
|
13
14
|
export type { DatePrefix } from './content/ids.js';
|
|
14
15
|
export { parseCairnToken, extractCairnLinks, formatCairnToken, escapeLinkText } from './content/links.js';
|
|
15
16
|
export type { CairnRef, LinkResolve } from './content/links.js';
|
|
16
|
-
export { serializeManifest, parseManifest, emptyManifest, verifyManifest, upsertEntry, removeEntry, manifestEntryFromFile, manifestLinkResolver, inboundLinks, } from './content/manifest.js';
|
|
17
|
-
export type { Manifest, ManifestEntry, LinkTarget, InboundLink } from './content/manifest.js';
|
|
17
|
+
export { serializeManifest, parseManifest, emptyManifest, verifyManifest, diffManifests, upsertEntry, removeEntry, manifestEntryFromFile, manifestLinkResolver, inboundLinks, } from './content/manifest.js';
|
|
18
|
+
export type { Manifest, ManifestEntry, ManifestDiff, ManifestEntryDiff, LinkTarget, InboundLink } from './content/manifest.js';
|
|
18
19
|
export { defineRegistry, emptyValues } from './render/registry.js';
|
|
19
20
|
export type { ComponentDef, ComponentRegistry, FieldType, AttributeField, SlotKind, SlotDef, ComponentValues, } from './render/registry.js';
|
|
20
21
|
export { serializeComponent, parseComponent } from './render/component-grammar.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC7D,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGnE,YAAY,EACV,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,SAAS,EACT,YAAY,EACZ,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,YAAY,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACnI,OAAO,EACL,SAAS,EACT,cAAc,EACd,cAAc,EACd,OAAO,EACP,UAAU,EACV,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC1G,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,cAAc,EACd,WAAW,EACX,WAAW,EACX,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,GACb,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ export { isValidId, idFromFilename, filenameFromId, slugify, slugFromId, compose
|
|
|
12
12
|
// builder and the request-time resolver ship from the delivery entry; this surface is the
|
|
13
13
|
// grammar, the manifest operations, and their types a migrating site adopts.
|
|
14
14
|
export { parseCairnToken, extractCairnLinks, formatCairnToken, escapeLinkText } from './content/links.js';
|
|
15
|
-
export { serializeManifest, parseManifest, emptyManifest, verifyManifest, upsertEntry, removeEntry, manifestEntryFromFile, manifestLinkResolver, inboundLinks, } from './content/manifest.js';
|
|
15
|
+
export { serializeManifest, parseManifest, emptyManifest, verifyManifest, diffManifests, upsertEntry, removeEntry, manifestEntryFromFile, manifestLinkResolver, inboundLinks, } from './content/manifest.js';
|
|
16
16
|
// Render engine (Plan 04): generic directive pipeline; sites own the component registry.
|
|
17
17
|
export { defineRegistry, emptyValues } from './render/registry.js';
|
|
18
18
|
export { serializeComponent, parseComponent } from './render/component-grammar.js';
|