@pitlane/content 0.2.1 → 0.2.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.
- package/CHANGELOG.md +18 -0
- package/README.md +57 -6
- package/dist/codegen.d.mts +1 -1
- package/dist/hot.d.mts +2 -0
- package/dist/hot.mjs +11 -0
- package/dist/index.d.mts +37 -2
- package/dist/index.mjs +35 -0
- package/dist/loaders.d.mts +12 -1
- package/dist/loaders.mjs +9 -0
- package/dist/prebuild.d.mts +1 -1
- package/dist/{types-xSR1WTBq.d.mts → types-C13GEJhr.d.mts} +14 -3
- package/dist/vite.d.mts +2 -0
- package/dist/vite.mjs +11 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @pitlane/content
|
|
2
2
|
|
|
3
|
+
## 0.2.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6be8e56: Documentation only. No code changed.
|
|
8
|
+
|
|
9
|
+
- Every README now says where the documentation is published as Markdown for AI agents and other LLM tools: `https://pitlane.tools/llms.txt` indexes every page, `https://pitlane.tools/llms-full.txt` holds them all in one file, and any page URL with `.md` appended returns that page as Markdown.
|
|
10
|
+
- The `@pitlane/content` README gains the Vite setup the content guide describes. That setup covers the `satteri` and `vite-plugin-satteri` dev dependencies, and a `vite.config.ts` registering `satteri()` with `jsxImportSource: "remix/ui"`, `headings()`, `rawStyles()`, and `contentLayer()` before `remix()`. Before this, the README named `contentLayer()` but not the plugins it has to sit beside, and an MDX file compiled without `jsxImportSource: "remix/ui"` is a React component rather than a Remix one.
|
|
11
|
+
- The `@pitlane/content` entry-point table lists `@pitlane/content/hot`, and the README describes the four `@pitlane/content/internal/*` entry points as internal and unstable, with what each one is for: reuse by a plugin for a bundler other than Vite.
|
|
12
|
+
|
|
13
|
+
- d4dfade: Documentation comments, plus two type-only exports from `@pitlane/content`. No runtime behavior changed.
|
|
14
|
+
|
|
15
|
+
- `@pitlane/content` now exports the `Content` and `ReferenceSchema` types. `Content<T>` is what `createContent()` returns, and `ReferenceSchema<C>` is what `c.reference(collection)` returns. Both already appeared in those signatures; now code can import them by name.
|
|
16
|
+
- The TSDoc that editors show and the reference at pitlane.tools is built from now covers more. `remix()` and `createContent()` have examples. The package entry points and the main functions link to their guides. `RemixPluginOptions`, `PrerenderConfig`, `PrerenderOption`, `CrawlOptions`, `D1DatabaseOptions`, `D1DriverOptions`, `D1Meta`, `D1PreparedStatement`, and `D1Result` have summaries. Every `@pitlane/content` entry point and the `@pitlane/theme/default` and `@pitlane/theme/dtcg` entry points have module summaries.
|
|
17
|
+
- `loaders.file()` describes the file shapes it accepts and when `options.parser` is required. `ThemeResult.extend()` describes what its patch may hold. `DefaultTheme` lists its top-level token groups.
|
|
18
|
+
|
|
19
|
+
`@pitlane/dev/assets` documents each `?assets` import form and `pitlane:dev`, and has its own reference page.
|
|
20
|
+
|
|
3
21
|
## 0.2.1
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -47,14 +47,63 @@ if (post) {
|
|
|
47
47
|
|
|
48
48
|
The loaders are ordinary runtime code, which covers Node, Bun, Deno, and container hosts. For a host with no filesystem, add `contentLayer()` from `@pitlane/content/vite` and the build resolves the collections ahead of time, inlining entry data and compiling Markdown bodies into the bundle. The collection declarations do not change.
|
|
49
49
|
|
|
50
|
+
## Configuring Vite
|
|
51
|
+
|
|
52
|
+
With a Vite build, Markdown and MDX need two build-only dependencies. [`@pitlane/dev`](https://pitlane.tools/guides/vite-plugin) is assumed and installs the same way:
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
npm install --save-dev satteri vite-plugin-satteri
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Register the Sätteri plugin and `contentLayer()` in your Vite config, before `remix()`:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
// vite.config.ts
|
|
62
|
+
import { headings, rawStyles } from "@pitlane/content/satteri";
|
|
63
|
+
import { contentLayer } from "@pitlane/content/vite";
|
|
64
|
+
import { remix } from "@pitlane/dev";
|
|
65
|
+
import { defineConfig } from "vite";
|
|
66
|
+
import satteri from "vite-plugin-satteri";
|
|
67
|
+
|
|
68
|
+
export default defineConfig({
|
|
69
|
+
plugins: [
|
|
70
|
+
satteri({
|
|
71
|
+
mdx: { jsxImportSource: "remix/ui" },
|
|
72
|
+
mdastPlugins: [headings()],
|
|
73
|
+
hastPlugins: [rawStyles()],
|
|
74
|
+
}),
|
|
75
|
+
contentLayer(),
|
|
76
|
+
remix(),
|
|
77
|
+
],
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`satteri()` compiles Markdown and MDX bodies during the build. `jsxImportSource: "remix/ui"` is required, because it is what makes a compiled MDX file a Remix component rather than a React one. `headings()` collects the heading list that `render()` returns, and `rawStyles()` keeps the CSS inside a `<style>` element intact, which any content with a highlighted code block produces.
|
|
82
|
+
|
|
83
|
+
`contentLayer()` executes `app/content.ts` in Node during the build and inlines every collection's entries into the bundle, so a deployed application never reads the filesystem. Name a module at another path with `contentLayer({ entry: "app/collections.ts" })`. A collection of only JSON or YAML files needs `contentLayer()` alone, with none of the Sätteri setup.
|
|
84
|
+
|
|
85
|
+
The [content guide](https://pitlane.tools/guides/content#configuring-vite) covers this setup in full.
|
|
86
|
+
|
|
50
87
|
## Entry points
|
|
51
88
|
|
|
52
|
-
| Entry point | Exports
|
|
53
|
-
| -------------------------- |
|
|
54
|
-
| `@pitlane/content` | `createContent` and the collection types
|
|
55
|
-
| `@pitlane/content/loaders` | `glob`, `file`
|
|
56
|
-
| `@pitlane/content/satteri` | `headings` and `rawStyles`, Sätteri plugins
|
|
57
|
-
| `@pitlane/content/vite` | `contentLayer`, the build-time plugin
|
|
89
|
+
| Entry point | Exports |
|
|
90
|
+
| -------------------------- | ------------------------------------------------------------ |
|
|
91
|
+
| `@pitlane/content` | `createContent` and the collection types |
|
|
92
|
+
| `@pitlane/content/loaders` | `glob`, `file` |
|
|
93
|
+
| `@pitlane/content/satteri` | `headings` and `rawStyles`, Sätteri plugins |
|
|
94
|
+
| `@pitlane/content/vite` | `contentLayer`, the build-time plugin |
|
|
95
|
+
| `@pitlane/content/hot` | `hotContent`, which reloads the browser when content changes |
|
|
96
|
+
|
|
97
|
+
`hotContent()` is for an application that runs from source with no build. It does nothing unless `remix/node-hmr` supervises the process, so it can stay in production code.
|
|
98
|
+
|
|
99
|
+
### Internal entry points
|
|
100
|
+
|
|
101
|
+
Four more entry points exist so that a plugin for a bundler other than Vite can reuse the pieces `contentLayer()` is built from. They are internal and unstable: they have no reference pages, and they can change in any release.
|
|
102
|
+
|
|
103
|
+
- `@pitlane/content/internal/manifest` is the module a build plugin replaces with the collections it prebuilt. As published, it declares that nothing was prebuilt, so without a plugin every collection falls through to its loader.
|
|
104
|
+
- `@pitlane/content/internal/prebuild` is the channel between the build plugin and `createContent()`. `openPrebuild()` and `closePrebuild()` bracket evaluating the content module, and the returned channel carries the collections, watched paths, and pending loads recorded in between.
|
|
105
|
+
- `@pitlane/content/internal/codegen` writes the manifest module as JavaScript source with `manifestModule()`, and exports `BODY_PREFIX`, the prefix of the virtual modules that carry each entry's body.
|
|
106
|
+
- `@pitlane/content/internal/mdx` exports `readEsm()`, which separates the imports in an MDX document's top-level ESM block from the rest of it.
|
|
58
107
|
|
|
59
108
|
## Without Remix
|
|
60
109
|
|
|
@@ -67,6 +116,8 @@ The loaders, schema validation, and query methods work with any [Standard Schema
|
|
|
67
116
|
- [Custom loaders](https://pitlane.tools/guides/content#custom-loaders)
|
|
68
117
|
- [API reference](https://pitlane.tools/package/content/)
|
|
69
118
|
|
|
119
|
+
For AI agents and other LLM tools, the documentation is also published as Markdown. [`llms.txt`](https://pitlane.tools/llms.txt) indexes every page, [`llms-full.txt`](https://pitlane.tools/llms-full.txt) holds them all in one file, and every page has a Markdown twin at its URL plus `.md`, or plus `index.md` when the URL ends in `/`, such as [`https://pitlane.tools/guides/content.md`](https://pitlane.tools/guides/content.md).
|
|
120
|
+
|
|
70
121
|
## License
|
|
71
122
|
|
|
72
123
|
MIT
|
package/dist/codegen.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { p as LoadedEntry } from "./types-
|
|
1
|
+
import { p as LoadedEntry } from "./types-C13GEJhr.mjs";
|
|
2
2
|
//#region src/codegen.d.ts
|
|
3
3
|
/** The prefix of the virtual modules that carry each entry's raw body. */
|
|
4
4
|
declare const BODY_PREFIX = "\0pitlane-content/entry/";
|
package/dist/hot.d.mts
CHANGED
|
@@ -37,6 +37,8 @@ interface BrowserHmrChannel {
|
|
|
37
37
|
* follow this module into a Worker bundle.
|
|
38
38
|
*
|
|
39
39
|
* @param content The object `createContent` returned.
|
|
40
|
+
*
|
|
41
|
+
* @see {@link https://pitlane.tools/guides/content-no-build | Content guide, without a build}
|
|
40
42
|
*/
|
|
41
43
|
declare function hotContent(content: Record<string, unknown>): Promise<void>;
|
|
42
44
|
/**
|
package/dist/hot.mjs
CHANGED
|
@@ -3,6 +3,15 @@ import { contentRoot } from "./prebuild.mjs";
|
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
//#region src/hot.ts
|
|
5
5
|
/**
|
|
6
|
+
* Browser reloads during development when a file behind a collection
|
|
7
|
+
* changes, for servers that `remix/node-hmr` supervises rather than Vite.
|
|
8
|
+
* See {@link hotContent}.
|
|
9
|
+
*
|
|
10
|
+
* @see {@link https://pitlane.tools/guides/content-no-build | Content guide, without a build}
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
6
15
|
* Reloads the browser when a file behind a collection changes.
|
|
7
16
|
*
|
|
8
17
|
* Call it once, beside `createContent`, and leave it in for production: it
|
|
@@ -13,6 +22,8 @@ import * as path from "node:path";
|
|
|
13
22
|
* follow this module into a Worker bundle.
|
|
14
23
|
*
|
|
15
24
|
* @param content The object `createContent` returned.
|
|
25
|
+
*
|
|
26
|
+
* @see {@link https://pitlane.tools/guides/content-no-build | Content guide, without a build}
|
|
16
27
|
*/
|
|
17
28
|
async function hotContent(content) {
|
|
18
29
|
if (!process.env.REMIX_NODE_HMR) return;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as Reference, a as ContentBuilder, c as EntryBody, d as LiveEntry, f as LiveLoader, h as LoaderContext, i as Content, l as GenerateIdOptions, m as Loader, n as CollectionDefinition, o as ContentLoader, p as LoadedEntry, r as CollectionEntry, s as Entry, t as Collection, u as Heading, v as RenderedEntry } from "./types-
|
|
1
|
+
import { _ as Reference, a as ContentBuilder, c as EntryBody, d as LiveEntry, f as LiveLoader, h as LoaderContext, i as Content, l as GenerateIdOptions, m as Loader, n as CollectionDefinition, o as ContentLoader, p as LoadedEntry, r as CollectionEntry, s as Entry, t as Collection, u as Heading, v as ReferenceSchema, y as RenderedEntry } from "./types-C13GEJhr.mjs";
|
|
2
2
|
//#region src/content.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Declares a set of content collections.
|
|
@@ -8,7 +8,42 @@ import { _ as Reference, a as ContentBuilder, c as EntryBody, d as LiveEntry, f
|
|
|
8
8
|
*
|
|
9
9
|
* Under `contentLayer()`, registers deferred population work. The plugin
|
|
10
10
|
* awaits it after evaluating the declarations and before emitting the bundle.
|
|
11
|
+
*
|
|
12
|
+
* @param build - Receives the {@link ContentBuilder} and returns one
|
|
13
|
+
* collection per key, each declared with `c.collection({ loader, schema })`
|
|
14
|
+
* @returns One {@link Collection} per key of the object `build` returned
|
|
15
|
+
* @throws Error when `c.reference()` names a collection `build` did not declare
|
|
16
|
+
*
|
|
17
|
+
* @see {@link https://pitlane.tools/guides/content | Content guide}
|
|
18
|
+
* @see {@link https://pitlane.tools/guides/content-no-build | Content guide, without a build}
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* // app/content.ts
|
|
23
|
+
* import { createContent } from "@pitlane/content";
|
|
24
|
+
* import * as loaders from "@pitlane/content/loaders";
|
|
25
|
+
* import * as s from "remix/data-schema";
|
|
26
|
+
* import * as coerce from "remix/data-schema/coerce";
|
|
27
|
+
*
|
|
28
|
+
* export let content = createContent(c => ({
|
|
29
|
+
* blog: c.collection({
|
|
30
|
+
* loader: loaders.glob({ base: "app/content/blog", pattern: "*.{md,mdx}" }),
|
|
31
|
+
* schema: s.object({
|
|
32
|
+
* title: s.string(),
|
|
33
|
+
* pubDate: coerce.date(),
|
|
34
|
+
* author: c.reference("authors"),
|
|
35
|
+
* }),
|
|
36
|
+
* }),
|
|
37
|
+
* authors: c.collection({
|
|
38
|
+
* loader: loaders.file("app/content/authors.json"),
|
|
39
|
+
* schema: s.object({ name: s.string() }),
|
|
40
|
+
* }),
|
|
41
|
+
* }));
|
|
42
|
+
*
|
|
43
|
+
* let posts = await content.blog.getCollection();
|
|
44
|
+
* let post = await content.blog.getEntry("hello-world");
|
|
45
|
+
* ```
|
|
11
46
|
*/
|
|
12
47
|
declare function createContent<T extends Record<string, CollectionDefinition>>(build: (c: ContentBuilder) => T): Content<T>;
|
|
13
48
|
//#endregion
|
|
14
|
-
export { type Collection, type CollectionDefinition, type CollectionEntry, type ContentBuilder, type ContentLoader, type Entry, type EntryBody, type GenerateIdOptions, type Heading, type LiveEntry, type LiveLoader, type LoadedEntry, type Loader, type LoaderContext, type Reference, type RenderedEntry, createContent };
|
|
49
|
+
export { type Collection, type CollectionDefinition, type CollectionEntry, type Content, type ContentBuilder, type ContentLoader, type Entry, type EntryBody, type GenerateIdOptions, type Heading, type LiveEntry, type LiveLoader, type LoadedEntry, type Loader, type LoaderContext, type Reference, type ReferenceSchema, type RenderedEntry, createContent };
|
package/dist/index.mjs
CHANGED
|
@@ -126,6 +126,41 @@ function relativeTo(root, filePath) {
|
|
|
126
126
|
*
|
|
127
127
|
* Under `contentLayer()`, registers deferred population work. The plugin
|
|
128
128
|
* awaits it after evaluating the declarations and before emitting the bundle.
|
|
129
|
+
*
|
|
130
|
+
* @param build - Receives the {@link ContentBuilder} and returns one
|
|
131
|
+
* collection per key, each declared with `c.collection({ loader, schema })`
|
|
132
|
+
* @returns One {@link Collection} per key of the object `build` returned
|
|
133
|
+
* @throws Error when `c.reference()` names a collection `build` did not declare
|
|
134
|
+
*
|
|
135
|
+
* @see {@link https://pitlane.tools/guides/content | Content guide}
|
|
136
|
+
* @see {@link https://pitlane.tools/guides/content-no-build | Content guide, without a build}
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* // app/content.ts
|
|
141
|
+
* import { createContent } from "@pitlane/content";
|
|
142
|
+
* import * as loaders from "@pitlane/content/loaders";
|
|
143
|
+
* import * as s from "remix/data-schema";
|
|
144
|
+
* import * as coerce from "remix/data-schema/coerce";
|
|
145
|
+
*
|
|
146
|
+
* export let content = createContent(c => ({
|
|
147
|
+
* blog: c.collection({
|
|
148
|
+
* loader: loaders.glob({ base: "app/content/blog", pattern: "*.{md,mdx}" }),
|
|
149
|
+
* schema: s.object({
|
|
150
|
+
* title: s.string(),
|
|
151
|
+
* pubDate: coerce.date(),
|
|
152
|
+
* author: c.reference("authors"),
|
|
153
|
+
* }),
|
|
154
|
+
* }),
|
|
155
|
+
* authors: c.collection({
|
|
156
|
+
* loader: loaders.file("app/content/authors.json"),
|
|
157
|
+
* schema: s.object({ name: s.string() }),
|
|
158
|
+
* }),
|
|
159
|
+
* }));
|
|
160
|
+
*
|
|
161
|
+
* let posts = await content.blog.getCollection();
|
|
162
|
+
* let post = await content.blog.getEntry("hello-world");
|
|
163
|
+
* ```
|
|
129
164
|
*/
|
|
130
165
|
function createContent(build) {
|
|
131
166
|
let referenced = [];
|
package/dist/loaders.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { l as GenerateIdOptions, o as ContentLoader } from "./types-
|
|
1
|
+
import { l as GenerateIdOptions, o as ContentLoader } from "./types-C13GEJhr.mjs";
|
|
2
2
|
import { CompileOptions } from "satteri";
|
|
3
3
|
//#region src/loaders/file.d.ts
|
|
4
4
|
/**
|
|
@@ -9,6 +9,8 @@ import { CompileOptions } from "satteri";
|
|
|
9
9
|
* TOML reader — is typed as returning a JSON-value union, which a narrower
|
|
10
10
|
* type rejects. `entriesOf` refuses an unusable result by name, so demanding
|
|
11
11
|
* the caller narrow first would buy a wrapper and no safety.
|
|
12
|
+
*
|
|
13
|
+
* @inline
|
|
12
14
|
*/
|
|
13
15
|
type Parser = (text: string) => unknown;
|
|
14
16
|
/**
|
|
@@ -16,6 +18,13 @@ type Parser = (text: string) => unknown;
|
|
|
16
18
|
*
|
|
17
19
|
* Every entry is data rather than a document: a file of records has no body to
|
|
18
20
|
* render, so `render()` on one of these entries is a mistake and says so.
|
|
21
|
+
*
|
|
22
|
+
* The file holds either an object whose keys are entry ids or an array of
|
|
23
|
+
* entries that each carry an `id`. `.json`, `.yaml`, and `.yml` parse without
|
|
24
|
+
* options; any other format needs `options.parser`, which turns the file's
|
|
25
|
+
* text into that object or array.
|
|
26
|
+
*
|
|
27
|
+
* @see {@link https://pitlane.tools/guides/content | Content guide}
|
|
19
28
|
*/
|
|
20
29
|
declare function file(fileName: string, options?: {
|
|
21
30
|
parser?: Parser;
|
|
@@ -27,6 +36,8 @@ declare function file(fileName: string, options?: {
|
|
|
27
36
|
*
|
|
28
37
|
* `pattern` is an ordinary runtime value — computed, read from the environment,
|
|
29
38
|
* or assembled in a loop — because nothing about it is read statically.
|
|
39
|
+
*
|
|
40
|
+
* @see {@link https://pitlane.tools/guides/content | Content guide}
|
|
30
41
|
*/
|
|
31
42
|
declare function glob(options: {
|
|
32
43
|
pattern: string | string[];
|
package/dist/loaders.mjs
CHANGED
|
@@ -49,6 +49,13 @@ function read(parse, text, filePath) {
|
|
|
49
49
|
*
|
|
50
50
|
* Every entry is data rather than a document: a file of records has no body to
|
|
51
51
|
* render, so `render()` on one of these entries is a mistake and says so.
|
|
52
|
+
*
|
|
53
|
+
* The file holds either an object whose keys are entry ids or an array of
|
|
54
|
+
* entries that each carry an `id`. `.json`, `.yaml`, and `.yml` parse without
|
|
55
|
+
* options; any other format needs `options.parser`, which turns the file's
|
|
56
|
+
* text into that object or array.
|
|
57
|
+
*
|
|
58
|
+
* @see {@link https://pitlane.tools/guides/content | Content guide}
|
|
52
59
|
*/
|
|
53
60
|
function file(fileName, options) {
|
|
54
61
|
let watched = [];
|
|
@@ -163,6 +170,8 @@ let formats = {
|
|
|
163
170
|
*
|
|
164
171
|
* `pattern` is an ordinary runtime value — computed, read from the environment,
|
|
165
172
|
* or assembled in a loop — because nothing about it is read statically.
|
|
173
|
+
*
|
|
174
|
+
* @see {@link https://pitlane.tools/guides/content | Content guide}
|
|
166
175
|
*/
|
|
167
176
|
function glob(options) {
|
|
168
177
|
let watched = [];
|
package/dist/prebuild.d.mts
CHANGED
|
@@ -83,7 +83,14 @@ interface ChainableSchema<Input, Output> {
|
|
|
83
83
|
refine: (predicate: (value: Output) => boolean, message?: string) => ChainableSchema<Input, Output>;
|
|
84
84
|
transform: <Next>(transformer: (value: Output) => Next) => ChainableSchema<Input, Next>;
|
|
85
85
|
}
|
|
86
|
-
/**
|
|
86
|
+
/**
|
|
87
|
+
* The schema `c.reference(collection)` returns: a Standard Schema that reads
|
|
88
|
+
* an entry id (a string) and outputs a {@link Reference} into `collection`.
|
|
89
|
+
*
|
|
90
|
+
* It composes inside `remix/data-schema`'s `s.object`, `s.array`, and
|
|
91
|
+
* `s.optional` like any other schema. It does not check that the target entry
|
|
92
|
+
* exists; a dangling id surfaces as `getEntry` resolving to `undefined`.
|
|
93
|
+
*/
|
|
87
94
|
type ReferenceSchema<C extends string> = ChainableSchema<string, Reference<C>>;
|
|
88
95
|
/** A heading collected from a Markdown or MDX document. */
|
|
89
96
|
interface Heading {
|
|
@@ -200,7 +207,11 @@ interface ContentBuilder {
|
|
|
200
207
|
}): CollectionDefinition<S>;
|
|
201
208
|
reference<C extends string>(collection: C): ReferenceSchema<C>;
|
|
202
209
|
}
|
|
203
|
-
/**
|
|
210
|
+
/**
|
|
211
|
+
* The object `createContent` returns: one {@link Collection} per key of the
|
|
212
|
+
* definitions its callback returned, named after that key and typed by the
|
|
213
|
+
* output of that collection's schema.
|
|
214
|
+
*/
|
|
204
215
|
type Content<T extends Record<string, CollectionDefinition>> = { [K in keyof T]: Collection<K & string, InferSchema<T[K]["schema"]>>; };
|
|
205
216
|
/** How `contentLayer()` spells an entry's body in the manifest it emits. */
|
|
206
217
|
type PrebuiltBody = {
|
|
@@ -235,4 +246,4 @@ interface GenerateIdOptions {
|
|
|
235
246
|
data: Record<string, unknown>;
|
|
236
247
|
}
|
|
237
248
|
//#endregion
|
|
238
|
-
export { Reference as _, ContentBuilder as a, EntryBody as c, LiveEntry as d, LiveLoader as f, PrebuiltCollections as g, LoaderContext as h, Content as i, GenerateIdOptions as l, Loader as m, CollectionDefinition as n, ContentLoader as o, LoadedEntry as p, CollectionEntry as r, Entry as s, Collection as t, Heading as u,
|
|
249
|
+
export { Reference as _, ContentBuilder as a, EntryBody as c, LiveEntry as d, LiveLoader as f, PrebuiltCollections as g, LoaderContext as h, Content as i, GenerateIdOptions as l, Loader as m, CollectionDefinition as n, ContentLoader as o, LoadedEntry as p, CollectionEntry as r, Entry as s, Collection as t, Heading as u, ReferenceSchema as v, RenderedEntry as y };
|
package/dist/vite.d.mts
CHANGED
|
@@ -10,6 +10,8 @@ import { Plugin } from "vite";
|
|
|
10
10
|
*
|
|
11
11
|
* The result is a host with no filesystem serving the collections the
|
|
12
12
|
* application declared, with no change to the declarations.
|
|
13
|
+
*
|
|
14
|
+
* @see {@link https://pitlane.tools/guides/content | Content guide}
|
|
13
15
|
*/
|
|
14
16
|
declare function contentLayer(options?: {
|
|
15
17
|
entry?: string;
|
package/dist/vite.mjs
CHANGED
|
@@ -4,6 +4,15 @@ import { dirname, resolve } from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { createRunnableDevEnvironment, createServer } from "vite";
|
|
6
6
|
//#region src/vite.ts
|
|
7
|
+
/**
|
|
8
|
+
* The {@link contentLayer} Vite plugin, which resolves every collection
|
|
9
|
+
* during the build and inlines the entries into the bundle, so a host with no
|
|
10
|
+
* filesystem serves the same collections.
|
|
11
|
+
*
|
|
12
|
+
* @see {@link https://pitlane.tools/guides/content | Content guide}
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
7
16
|
const MANIFEST_OWNER = "@pitlane/content";
|
|
8
17
|
const MANIFEST_SPECIFIER = `${MANIFEST_OWNER}/internal/manifest`;
|
|
9
18
|
const VIRTUAL_MANIFEST = "\0pitlane-content/manifest";
|
|
@@ -17,6 +26,8 @@ const VIRTUAL_MANIFEST = "\0pitlane-content/manifest";
|
|
|
17
26
|
*
|
|
18
27
|
* The result is a host with no filesystem serving the collections the
|
|
19
28
|
* application declared, with no change to the declarations.
|
|
29
|
+
*
|
|
30
|
+
* @see {@link https://pitlane.tools/guides/content | Content guide}
|
|
20
31
|
*/
|
|
21
32
|
function contentLayer(options) {
|
|
22
33
|
let entry = options?.entry ?? "app/content.ts";
|