@pagesmith/core 0.1.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/README.md +481 -0
- package/assets/fonts/OFL.txt +7 -0
- package/assets/fonts/jetbrains-mono-variable.woff2 +0 -0
- package/assets/fonts/open-sans-variable.woff2 +0 -0
- package/assets/fonts.css +17 -0
- package/dist/ai/index.d.mts +41 -0
- package/dist/ai/index.d.mts.map +1 -0
- package/dist/ai/index.mjs +414 -0
- package/dist/ai/index.mjs.map +1 -0
- package/dist/assets/index.d.mts +31 -0
- package/dist/assets/index.d.mts.map +1 -0
- package/dist/assets/index.mjs +2 -0
- package/dist/assets-bX08zEJm.mjs +155 -0
- package/dist/assets-bX08zEJm.mjs.map +1 -0
- package/dist/content-config-fHPaFZ7i.d.mts +1128 -0
- package/dist/content-config-fHPaFZ7i.d.mts.map +1 -0
- package/dist/content-layer-B7fQ3im4.mjs +590 -0
- package/dist/content-layer-B7fQ3im4.mjs.map +1 -0
- package/dist/convert-DnuB6SVV.mjs +52 -0
- package/dist/convert-DnuB6SVV.mjs.map +1 -0
- package/dist/create/index.d.mts +20 -0
- package/dist/create/index.d.mts.map +1 -0
- package/dist/create/index.mjs +215 -0
- package/dist/create/index.mjs.map +1 -0
- package/dist/css/index.d.mts +2 -0
- package/dist/css/index.mjs +2 -0
- package/dist/css-ekIt2Fdb.mjs +19 -0
- package/dist/css-ekIt2Fdb.mjs.map +1 -0
- package/dist/heading-Dhvzlay-.d.mts +27 -0
- package/dist/heading-Dhvzlay-.d.mts.map +1 -0
- package/dist/index-BQ6B1-qG.d.mts +41 -0
- package/dist/index-BQ6B1-qG.d.mts.map +1 -0
- package/dist/index-CeNDTM-y.d.mts +7 -0
- package/dist/index-CeNDTM-y.d.mts.map +1 -0
- package/dist/index-DpRBzO8Q.d.mts +15 -0
- package/dist/index-DpRBzO8Q.d.mts.map +1 -0
- package/dist/index-sFCx17CD.d.mts +59 -0
- package/dist/index-sFCx17CD.d.mts.map +1 -0
- package/dist/index.d.mts +131 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +56 -0
- package/dist/index.mjs.map +1 -0
- package/dist/jsx-runtime/index.d.mts +24 -0
- package/dist/jsx-runtime/index.d.mts.map +1 -0
- package/dist/jsx-runtime/index.mjs +88 -0
- package/dist/jsx-runtime/index.mjs.map +1 -0
- package/dist/loaders/index.d.mts +3 -0
- package/dist/loaders/index.mjs +2 -0
- package/dist/loaders-DyABmDrE.mjs +179 -0
- package/dist/loaders-DyABmDrE.mjs.map +1 -0
- package/dist/markdown/index.d.mts +3 -0
- package/dist/markdown/index.mjs +2 -0
- package/dist/markdown-Cj5X26FL.mjs +95 -0
- package/dist/markdown-Cj5X26FL.mjs.map +1 -0
- package/dist/runtime/index.d.mts +28 -0
- package/dist/runtime/index.d.mts.map +1 -0
- package/dist/runtime/index.mjs +90 -0
- package/dist/runtime/index.mjs.map +1 -0
- package/dist/schemas/index.d.mts +4 -0
- package/dist/schemas/index.mjs +2 -0
- package/dist/schemas-DJS7wOzd.mjs +47 -0
- package/dist/schemas-DJS7wOzd.mjs.map +1 -0
- package/dist/types-DUsjRE7Y.d.mts +28 -0
- package/dist/types-DUsjRE7Y.d.mts.map +1 -0
- package/dist/vite/index.d.mts +9878 -0
- package/dist/vite/index.d.mts.map +1 -0
- package/dist/vite/index.mjs +549 -0
- package/dist/vite/index.mjs.map +1 -0
- package/package.json +136 -0
- package/src/styles/code/inline.css +26 -0
- package/src/styles/content/alerts.css +87 -0
- package/src/styles/content/prose.css +225 -0
- package/src/styles/content/toc.css +87 -0
- package/src/styles/content.css +22 -0
- package/src/styles/foundations/reset.css +49 -0
- package/src/styles/foundations/tokens.css +66 -0
- package/src/styles/layout/grid.css +179 -0
- package/src/styles/layout/sidebar.css +18 -0
- package/src/styles/standalone.css +18 -0
- package/src/styles/viewport.css +20 -0
- package/templates/docs/content/README.md +18 -0
- package/templates/docs/content/guide/README.md +11 -0
- package/templates/docs/content/guide/getting-started/README.md +9 -0
- package/templates/docs/content/reference/README.md +11 -0
- package/templates/docs/pagesmith.config.json5 +15 -0
package/README.md
ADDED
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
# @pagesmith/core
|
|
2
|
+
|
|
3
|
+
File-based content toolkit for Vite. Schema-validated collections, lazy markdown rendering with Expressive Code syntax highlighting, and runtime CSS/JS exports.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm add @pagesmith/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { createContentLayer, defineCollection, defineConfig, z } from '@pagesmith/core'
|
|
15
|
+
|
|
16
|
+
const posts = defineCollection({
|
|
17
|
+
loader: 'markdown',
|
|
18
|
+
directory: 'content/posts',
|
|
19
|
+
schema: z.object({
|
|
20
|
+
title: z.string(),
|
|
21
|
+
date: z.coerce.date(),
|
|
22
|
+
tags: z.array(z.string()).default([]),
|
|
23
|
+
}),
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const layer = createContentLayer(defineConfig({ collections: { posts } }))
|
|
27
|
+
const entries = await layer.getCollection('posts')
|
|
28
|
+
const rendered = await entries[0]?.render()
|
|
29
|
+
// rendered.html, rendered.headings, rendered.readTime
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Vite Integration
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { defineCollection, defineCollections, z } from '@pagesmith/core'
|
|
36
|
+
import { pagesmithContent, pagesmithSsg, sharedAssetsPlugin } from '@pagesmith/core/vite'
|
|
37
|
+
import { defineConfig } from 'vite'
|
|
38
|
+
|
|
39
|
+
const collections = defineCollections({
|
|
40
|
+
posts: defineCollection({
|
|
41
|
+
loader: 'markdown',
|
|
42
|
+
directory: 'content/posts',
|
|
43
|
+
schema: z.object({ title: z.string(), date: z.coerce.date() }),
|
|
44
|
+
}),
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
export default defineConfig({
|
|
48
|
+
plugins: [
|
|
49
|
+
sharedAssetsPlugin(),
|
|
50
|
+
pagesmithContent({ collections }),
|
|
51
|
+
pagesmithSsg({ entry: './src/entry-server.tsx' }),
|
|
52
|
+
],
|
|
53
|
+
})
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Import collections as virtual modules in your SSR entry:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import posts from 'virtual:content/posts'
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Content Layer API
|
|
63
|
+
|
|
64
|
+
| Method | Description |
|
|
65
|
+
|---|---|
|
|
66
|
+
| `createContentLayer(config)` | Create a content layer from a config object |
|
|
67
|
+
| `layer.getCollection(name)` | Load all entries in a collection (cached) |
|
|
68
|
+
| `layer.getEntry(collection, slug)` | Get a single entry by slug |
|
|
69
|
+
| `layer.convert(markdown, options?)` | Convert raw markdown to HTML outside collections |
|
|
70
|
+
| `layer.validate(collection?)` | Run all validators and return results |
|
|
71
|
+
| `layer.invalidate(collection, slug)` | Cache-bust a single entry |
|
|
72
|
+
| `layer.invalidateCollection(name)` | Cache-bust an entire collection |
|
|
73
|
+
| `layer.invalidateAll()` | Cache-bust all collections |
|
|
74
|
+
|
|
75
|
+
### Content Entry
|
|
76
|
+
|
|
77
|
+
Each entry from `getCollection()` or `getEntry()` has:
|
|
78
|
+
|
|
79
|
+
- `slug` — URL-friendly identifier
|
|
80
|
+
- `collection` — collection name
|
|
81
|
+
- `filePath` — absolute source path
|
|
82
|
+
- `data` — validated data (frontmatter or parsed file content, typed by your Zod schema)
|
|
83
|
+
- `rawContent` — raw markdown body (markdown loader only)
|
|
84
|
+
- `render(options?)` — lazy markdown-to-HTML; returns `{ html, headings, readTime }` (cached)
|
|
85
|
+
- `clearRenderCache()` — force re-render on next call
|
|
86
|
+
|
|
87
|
+
## Collections
|
|
88
|
+
|
|
89
|
+
Define collections with `defineCollection()` and a Zod schema:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
const posts = defineCollection({
|
|
93
|
+
loader: 'markdown',
|
|
94
|
+
directory: 'content/posts',
|
|
95
|
+
schema: z.object({
|
|
96
|
+
title: z.string(),
|
|
97
|
+
description: z.string(),
|
|
98
|
+
date: z.coerce.date(),
|
|
99
|
+
tags: z.array(z.string()).min(1),
|
|
100
|
+
draft: z.boolean().optional().default(false),
|
|
101
|
+
}),
|
|
102
|
+
computed: {
|
|
103
|
+
year: (entry) => new Date(entry.data.date).getFullYear(),
|
|
104
|
+
},
|
|
105
|
+
filter: (entry) => !entry.data.draft,
|
|
106
|
+
slugify: (filePath, directory) => customSlug(filePath),
|
|
107
|
+
transform: (entry) => ({ ...entry, data: { ...entry.data, title: entry.data.title.trim() } }),
|
|
108
|
+
validators: [myCustomValidator],
|
|
109
|
+
disableBuiltinValidators: false,
|
|
110
|
+
})
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Collection Options
|
|
114
|
+
|
|
115
|
+
| Option | Type | Description |
|
|
116
|
+
|---|---|---|
|
|
117
|
+
| `loader` | `string \| Loader` | `'markdown'`, `'json'`, `'json5'`, `'jsonc'`, `'yaml'`, `'toml'`, or custom |
|
|
118
|
+
| `directory` | `string` | Directory containing collection files (relative to root) |
|
|
119
|
+
| `schema` | `z.ZodType` | Zod schema for validating entry data |
|
|
120
|
+
| `include` | `string[]` | Glob include patterns (defaults based on loader) |
|
|
121
|
+
| `exclude` | `string[]` | Glob exclude patterns |
|
|
122
|
+
| `computed` | `Record<string, fn>` | Computed fields derived from entry data |
|
|
123
|
+
| `validate` | `fn` | Custom validation hook (return string for error) |
|
|
124
|
+
| `filter` | `fn` | Filter entries (return false to exclude) |
|
|
125
|
+
| `slugify` | `fn` | Custom slug generation |
|
|
126
|
+
| `transform` | `fn` | Pre-validation transform |
|
|
127
|
+
| `validators` | `ContentValidator[]` | Custom content validators |
|
|
128
|
+
| `disableBuiltinValidators` | `boolean` | Disable built-in markdown validators |
|
|
129
|
+
|
|
130
|
+
### Loaders
|
|
131
|
+
|
|
132
|
+
| Type | Extensions | Description |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| `markdown` | `.md` | gray-matter frontmatter + markdown body |
|
|
135
|
+
| `json` | `.json` | JSON.parse |
|
|
136
|
+
| `json5` | `.json` | JSON5 (relaxed JSON with comments, trailing commas) |
|
|
137
|
+
| `jsonc` | `.json`, `.jsonc` | JSON with comments |
|
|
138
|
+
| `yaml` | `.yml`, `.yaml` | YAML |
|
|
139
|
+
| `toml` | `.toml` | TOML |
|
|
140
|
+
|
|
141
|
+
Custom loaders: implement `Loader { name, kind, extensions, load(filePath) }`.
|
|
142
|
+
|
|
143
|
+
## Markdown Pipeline
|
|
144
|
+
|
|
145
|
+
The pipeline is built with unified and processes markdown through these stages:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
remark-parse → remark-gfm → remark-math → remark-frontmatter
|
|
149
|
+
→ remark-github-alerts → remark-smartypants → [user remark plugins]
|
|
150
|
+
→ remark-rehype
|
|
151
|
+
→ rehype-expressive-code (syntax highlighting)
|
|
152
|
+
→ rehype-mathjax → rehype-slug → rehype-autolink-headings
|
|
153
|
+
→ heading extraction → [user rehype plugins]
|
|
154
|
+
→ rehype-external-links → rehype-accessible-emojis → rehype-stringify
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Markdown Features
|
|
158
|
+
|
|
159
|
+
**GitHub Flavored Markdown (remark-gfm):**
|
|
160
|
+
- Tables, strikethrough, task lists, autolinks
|
|
161
|
+
|
|
162
|
+
**GitHub Alerts (remark-github-alerts):**
|
|
163
|
+
|
|
164
|
+
```md
|
|
165
|
+
> [!NOTE]
|
|
166
|
+
> Informational note.
|
|
167
|
+
|
|
168
|
+
> [!TIP]
|
|
169
|
+
> Helpful tip.
|
|
170
|
+
|
|
171
|
+
> [!IMPORTANT]
|
|
172
|
+
> Important information.
|
|
173
|
+
|
|
174
|
+
> [!WARNING]
|
|
175
|
+
> Warning message.
|
|
176
|
+
|
|
177
|
+
> [!CAUTION]
|
|
178
|
+
> Cautionary message.
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Math (remark-math + rehype-mathjax):**
|
|
182
|
+
|
|
183
|
+
```md
|
|
184
|
+
Inline: $E = mc^2$
|
|
185
|
+
|
|
186
|
+
Block:
|
|
187
|
+
$$
|
|
188
|
+
\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}
|
|
189
|
+
$$
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Smart Typography (remark-smartypants):**
|
|
193
|
+
- "Curly quotes", em—dashes, el...lipses
|
|
194
|
+
|
|
195
|
+
**External Links (rehype-external-links):**
|
|
196
|
+
- Absolute URLs automatically get `target="_blank" rel="noopener noreferrer"`
|
|
197
|
+
|
|
198
|
+
**Accessible Emojis (rehype-accessible-emojis):**
|
|
199
|
+
- Emoji characters wrapped in `<span role="img" aria-label="...">` for screen readers
|
|
200
|
+
|
|
201
|
+
**Heading Links (rehype-slug + rehype-autolink-headings):**
|
|
202
|
+
- Auto-generated `id` attributes and anchor links on all headings
|
|
203
|
+
|
|
204
|
+
### Expressive Code Features
|
|
205
|
+
|
|
206
|
+
Syntax highlighting is handled by [Expressive Code](https://expressive-code.com/) with dual themes (default: `github-light` / `github-dark`). All styling is injected inline — no external CSS required.
|
|
207
|
+
|
|
208
|
+
**Dual Themes:**
|
|
209
|
+
Automatically switches between light and dark themes via `prefers-color-scheme` media query. Configure themes:
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
defineConfig({
|
|
213
|
+
markdown: {
|
|
214
|
+
shiki: {
|
|
215
|
+
themes: { light: 'github-light', dark: 'github-dark' },
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
})
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Line Numbers:**
|
|
222
|
+
|
|
223
|
+
````md
|
|
224
|
+
```js showLineNumbers
|
|
225
|
+
const x = 1
|
|
226
|
+
const y = 2
|
|
227
|
+
```
|
|
228
|
+
````
|
|
229
|
+
|
|
230
|
+
Or enable globally: `shiki: { defaultShowLineNumbers: true }`
|
|
231
|
+
|
|
232
|
+
**File Titles:**
|
|
233
|
+
|
|
234
|
+
````md
|
|
235
|
+
```js title="app.js"
|
|
236
|
+
export default function App() {}
|
|
237
|
+
```
|
|
238
|
+
````
|
|
239
|
+
|
|
240
|
+
**Line Highlighting (mark, ins, del):**
|
|
241
|
+
|
|
242
|
+
````md
|
|
243
|
+
```js mark={3} ins={4} del={5}
|
|
244
|
+
const a = 1
|
|
245
|
+
const b = 2
|
|
246
|
+
const c = 3 // highlighted
|
|
247
|
+
const d = 4 // inserted (green)
|
|
248
|
+
const e = 5 // deleted (red)
|
|
249
|
+
```
|
|
250
|
+
````
|
|
251
|
+
|
|
252
|
+
**Collapsible Sections:**
|
|
253
|
+
|
|
254
|
+
````md
|
|
255
|
+
```js collapse={1-5}
|
|
256
|
+
// These lines are collapsed by default
|
|
257
|
+
import { a } from 'a'
|
|
258
|
+
import { b } from 'b'
|
|
259
|
+
import { c } from 'c'
|
|
260
|
+
import { d } from 'd'
|
|
261
|
+
// Visible code starts here
|
|
262
|
+
export function main() {}
|
|
263
|
+
```
|
|
264
|
+
````
|
|
265
|
+
|
|
266
|
+
**Copy Button:**
|
|
267
|
+
Automatically added to all code blocks.
|
|
268
|
+
|
|
269
|
+
**Language Badges:**
|
|
270
|
+
Automatic language indicator on code blocks.
|
|
271
|
+
|
|
272
|
+
**Combined Example:**
|
|
273
|
+
|
|
274
|
+
````md
|
|
275
|
+
```ts title="server.ts" showLineNumbers mark={3} ins={7-8} collapse={1-2}
|
|
276
|
+
import express from 'express'
|
|
277
|
+
import cors from 'cors'
|
|
278
|
+
const app = express() // highlighted
|
|
279
|
+
app.use(cors())
|
|
280
|
+
|
|
281
|
+
// New routes added
|
|
282
|
+
app.get('/api', handler)
|
|
283
|
+
app.post('/api', handler)
|
|
284
|
+
```
|
|
285
|
+
````
|
|
286
|
+
|
|
287
|
+
### Custom Plugins
|
|
288
|
+
|
|
289
|
+
Extend the pipeline with custom remark and rehype plugins:
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
defineConfig({
|
|
293
|
+
markdown: {
|
|
294
|
+
remarkPlugins: [myRemarkPlugin, [pluginWithOptions, { option: true }]],
|
|
295
|
+
rehypePlugins: [myRehypePlugin],
|
|
296
|
+
},
|
|
297
|
+
})
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Validation
|
|
301
|
+
|
|
302
|
+
### Schema Validation
|
|
303
|
+
|
|
304
|
+
Every entry is validated against its collection's Zod schema. Validation issues include field path, message, and severity (`'error'` | `'warn'`).
|
|
305
|
+
|
|
306
|
+
### Built-in Content Validators
|
|
307
|
+
|
|
308
|
+
For markdown collections, three validators run automatically on the parsed AST:
|
|
309
|
+
|
|
310
|
+
- **linkValidator** — warns on bare URLs, empty link text, suspicious protocols
|
|
311
|
+
- **headingValidator** — enforces single h1, sequential heading depth, non-empty text
|
|
312
|
+
- **codeBlockValidator** — warns on missing language, unknown language aliases
|
|
313
|
+
|
|
314
|
+
Disable with `disableBuiltinValidators: true`. Add custom validators via `validators` in the collection definition.
|
|
315
|
+
|
|
316
|
+
### Custom Validators
|
|
317
|
+
|
|
318
|
+
```ts
|
|
319
|
+
const myValidator: ContentValidator = {
|
|
320
|
+
name: 'my-validator',
|
|
321
|
+
validate(ctx) {
|
|
322
|
+
// ctx.mdast — parsed markdown AST (shared across validators)
|
|
323
|
+
// ctx.entry — the raw entry
|
|
324
|
+
// return ValidationIssue[] or throw
|
|
325
|
+
},
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Vite Plugins
|
|
330
|
+
|
|
331
|
+
### pagesmithContent
|
|
332
|
+
|
|
333
|
+
Virtual module plugin that exposes collections as importable modules:
|
|
334
|
+
|
|
335
|
+
```ts
|
|
336
|
+
pagesmithContent({
|
|
337
|
+
collections,
|
|
338
|
+
moduleId: 'virtual:content', // default
|
|
339
|
+
configPath: './content.config.ts', // default
|
|
340
|
+
dts: true, // generate .d.ts
|
|
341
|
+
})
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Import in your code:
|
|
345
|
+
|
|
346
|
+
```ts
|
|
347
|
+
import posts from 'virtual:content/posts'
|
|
348
|
+
// posts: ContentEntry<YourSchema>[]
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### pagesmithSsg
|
|
352
|
+
|
|
353
|
+
Static site generation plugin:
|
|
354
|
+
|
|
355
|
+
```ts
|
|
356
|
+
pagesmithSsg({
|
|
357
|
+
entry: './src/entry-server.tsx',
|
|
358
|
+
pagefind: true, // run Pagefind after build (default)
|
|
359
|
+
contentDirs: ['content'], // copy companion assets
|
|
360
|
+
})
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
Your SSR entry must export:
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
export function getRoutes(config: SsgRenderConfig): string[]
|
|
367
|
+
export function render(url: string, config: SsgRenderConfig): string | Promise<string>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### sharedAssetsPlugin
|
|
371
|
+
|
|
372
|
+
Serves shared font assets (Open Sans, JetBrains Mono) bundled with `@pagesmith/core`.
|
|
373
|
+
|
|
374
|
+
## JSX Runtime
|
|
375
|
+
|
|
376
|
+
Server-side HTML generation. No browser runtime required.
|
|
377
|
+
|
|
378
|
+
```json
|
|
379
|
+
// tsconfig.json
|
|
380
|
+
{
|
|
381
|
+
"compilerOptions": {
|
|
382
|
+
"jsx": "react-jsx",
|
|
383
|
+
"jsxImportSource": "@pagesmith/core"
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
```tsx
|
|
389
|
+
import { Fragment, HtmlString } from '@pagesmith/core'
|
|
390
|
+
|
|
391
|
+
function Page({ title, content }: { title: string; content: string }) {
|
|
392
|
+
return (
|
|
393
|
+
<html>
|
|
394
|
+
<head><title>{title}</title></head>
|
|
395
|
+
<body>
|
|
396
|
+
<Fragment innerHTML={content} />
|
|
397
|
+
</body>
|
|
398
|
+
</html>
|
|
399
|
+
)
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
- `h(tag, props, ...children)` — create HTML elements
|
|
404
|
+
- `Fragment` — render children or raw `innerHTML`
|
|
405
|
+
- `HtmlString` — wrapper that prevents double-escaping
|
|
406
|
+
|
|
407
|
+
## CSS Exports
|
|
408
|
+
|
|
409
|
+
| Import Path | Contents |
|
|
410
|
+
|---|---|
|
|
411
|
+
| `@pagesmith/core/css/content` | Prose typography + inline code styles |
|
|
412
|
+
| `@pagesmith/core/css/standalone` | Full layout + prose + TOC |
|
|
413
|
+
| `@pagesmith/core/css/viewport` | Responsive viewport base |
|
|
414
|
+
| `@pagesmith/core/css/fonts` | Bundled Open Sans + JetBrains Mono |
|
|
415
|
+
|
|
416
|
+
Code block styling is handled entirely by Expressive Code through inline styles injected during processing.
|
|
417
|
+
|
|
418
|
+
## Runtime Exports
|
|
419
|
+
|
|
420
|
+
```ts
|
|
421
|
+
import { getRuntimeCSS, getRuntimeJS, getContentCSS, getContentJS } from '@pagesmith/core/runtime'
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
Two tiers:
|
|
425
|
+
- **Standalone** (`getRuntimeCSS/JS`) — full site with layout, prose, TOC highlight
|
|
426
|
+
- **Content** (`getContentCSS/JS`) — markdown rendering only
|
|
427
|
+
|
|
428
|
+
## Frontmatter Schemas
|
|
429
|
+
|
|
430
|
+
Pre-defined schemas for common content types:
|
|
431
|
+
|
|
432
|
+
```ts
|
|
433
|
+
import { BaseFrontmatterSchema, BlogFrontmatterSchema, ProjectFrontmatterSchema } from '@pagesmith/core'
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
| Schema | Fields |
|
|
437
|
+
|---|---|
|
|
438
|
+
| `BaseFrontmatterSchema` | title, description, publishedDate, lastUpdatedOn, tags, draft |
|
|
439
|
+
| `BlogFrontmatterSchema` | extends base + category, featured, coverImage |
|
|
440
|
+
| `ProjectFrontmatterSchema` | extends base + gitRepo, links |
|
|
441
|
+
|
|
442
|
+
## AI Assistant Artifacts
|
|
443
|
+
|
|
444
|
+
Generate context files for AI assistants:
|
|
445
|
+
|
|
446
|
+
```ts
|
|
447
|
+
import { installAiArtifacts } from '@pagesmith/core/ai'
|
|
448
|
+
|
|
449
|
+
installAiArtifacts({
|
|
450
|
+
assistants: ['claude', 'codex', 'gemini'],
|
|
451
|
+
scope: 'project',
|
|
452
|
+
includeLlms: true,
|
|
453
|
+
})
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
Generates: `CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, skills, `llms.txt`, `llms-full.txt`
|
|
457
|
+
|
|
458
|
+
## Export Map
|
|
459
|
+
|
|
460
|
+
| Import Path | Purpose |
|
|
461
|
+
|---|---|
|
|
462
|
+
| `@pagesmith/core` | Main API barrel (defineCollection, createContentLayer, z, etc.) |
|
|
463
|
+
| `@pagesmith/core/jsx-runtime` | h, Fragment, HtmlString |
|
|
464
|
+
| `@pagesmith/core/jsx-dev-runtime` | JSX dev runtime (same as jsx-runtime) |
|
|
465
|
+
| `@pagesmith/core/markdown` | processMarkdown |
|
|
466
|
+
| `@pagesmith/core/css` | buildCss (LightningCSS) |
|
|
467
|
+
| `@pagesmith/core/css/content` | Content CSS file |
|
|
468
|
+
| `@pagesmith/core/css/standalone` | Standalone CSS file |
|
|
469
|
+
| `@pagesmith/core/css/viewport` | Viewport CSS file |
|
|
470
|
+
| `@pagesmith/core/css/fonts` | Bundled font faces |
|
|
471
|
+
| `@pagesmith/core/schemas` | Zod schemas and TypeScript types |
|
|
472
|
+
| `@pagesmith/core/loaders` | Loader classes and registry |
|
|
473
|
+
| `@pagesmith/core/assets` | Asset copying and hashing |
|
|
474
|
+
| `@pagesmith/core/runtime` | Pre-built CSS/JS accessors |
|
|
475
|
+
| `@pagesmith/core/ai` | AI assistant artifact generator |
|
|
476
|
+
| `@pagesmith/core/vite` | Vite plugins (pagesmithContent, pagesmithSsg, sharedAssetsPlugin) |
|
|
477
|
+
| `@pagesmith/core/create` | Project scaffolding utilities |
|
|
478
|
+
|
|
479
|
+
## License
|
|
480
|
+
|
|
481
|
+
MIT
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Open Sans and JetBrains Mono are licensed under the
|
|
2
|
+
SIL Open Font License, Version 1.1.
|
|
3
|
+
|
|
4
|
+
See https://scripts.sil.org/OFL for the full license text.
|
|
5
|
+
|
|
6
|
+
Open Sans — Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans)
|
|
7
|
+
JetBrains Mono — Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
|
|
Binary file
|
|
Binary file
|
package/assets/fonts.css
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/* Pagesmith — self-hosted font faces */
|
|
2
|
+
|
|
3
|
+
@font-face {
|
|
4
|
+
font-family: 'Open Sans';
|
|
5
|
+
src: url('fonts/open-sans-variable.woff2') format('woff2');
|
|
6
|
+
font-weight: 300 800;
|
|
7
|
+
font-style: normal;
|
|
8
|
+
font-display: swap;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@font-face {
|
|
12
|
+
font-family: 'JetBrains Mono';
|
|
13
|
+
src: url('fonts/jetbrains-mono-variable.woff2') format('woff2');
|
|
14
|
+
font-weight: 400 700;
|
|
15
|
+
font-style: normal;
|
|
16
|
+
font-display: swap;
|
|
17
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region src/ai/index.d.ts
|
|
2
|
+
type AiAssistant = 'claude' | 'codex' | 'gemini';
|
|
3
|
+
type AiInstallScope = 'project' | 'user';
|
|
4
|
+
type AiInstallProfile = 'default' | 'docs';
|
|
5
|
+
type AiArtifactKind = 'memory' | 'skill' | 'llms' | 'llms-full';
|
|
6
|
+
type AiWriteMode = 'merge' | 'replace';
|
|
7
|
+
type AiInstallStatus = 'written' | 'merged' | 'replaced' | 'unchanged';
|
|
8
|
+
type AiArtifact = {
|
|
9
|
+
assistant?: AiAssistant;
|
|
10
|
+
kind: AiArtifactKind;
|
|
11
|
+
path: string;
|
|
12
|
+
content: string;
|
|
13
|
+
mode: AiWriteMode;
|
|
14
|
+
label: string;
|
|
15
|
+
};
|
|
16
|
+
type AiInstallResult = {
|
|
17
|
+
assistant?: AiAssistant;
|
|
18
|
+
kind: AiArtifactKind;
|
|
19
|
+
path: string;
|
|
20
|
+
status: AiInstallStatus;
|
|
21
|
+
label: string;
|
|
22
|
+
};
|
|
23
|
+
type AiInstallOptions = {
|
|
24
|
+
assistants?: AiAssistant[] | 'all';
|
|
25
|
+
scope?: AiInstallScope;
|
|
26
|
+
profile?: AiInstallProfile;
|
|
27
|
+
cwd?: string;
|
|
28
|
+
homeDir?: string;
|
|
29
|
+
includeLlms?: boolean;
|
|
30
|
+
force?: boolean;
|
|
31
|
+
skillName?: string;
|
|
32
|
+
};
|
|
33
|
+
declare function getAiArtifactContent(assistant: AiAssistant | 'shared', kind: AiArtifactKind, options?: {
|
|
34
|
+
profile?: AiInstallProfile;
|
|
35
|
+
skillName?: string;
|
|
36
|
+
}): string;
|
|
37
|
+
declare function getAiArtifacts(options?: AiInstallOptions): AiArtifact[];
|
|
38
|
+
declare function installAiArtifacts(options?: AiInstallOptions): AiInstallResult[];
|
|
39
|
+
//#endregion
|
|
40
|
+
export { AiArtifact, AiArtifactKind, AiAssistant, AiInstallOptions, AiInstallProfile, AiInstallResult, AiInstallScope, AiInstallStatus, AiWriteMode, getAiArtifactContent, getAiArtifacts, installAiArtifacts };
|
|
41
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/ai/index.ts"],"mappings":";KAIY,WAAA;AAAA,KACA,cAAA;AAAA,KACA,gBAAA;AAAA,KACA,cAAA;AAAA,KACA,WAAA;AAAA,KACA,eAAA;AAAA,KAEA,UAAA;EACV,SAAA,GAAY,WAAA;EACZ,IAAA,EAAM,cAAA;EACN,IAAA;EACA,OAAA;EACA,IAAA,EAAM,WAAA;EACN,KAAA;AAAA;AAAA,KAGU,eAAA;EACV,SAAA,GAAY,WAAA;EACZ,IAAA,EAAM,cAAA;EACN,IAAA;EACA,MAAA,EAAQ,eAAA;EACR,KAAA;AAAA;AAAA,KAGU,gBAAA;EACV,UAAA,GAAa,WAAA;EACb,KAAA,GAAQ,cAAA;EACR,OAAA,GAAU,gBAAA;EACV,GAAA;EACA,OAAA;EACA,WAAA;EACA,KAAA;EACA,SAAA;AAAA;AAAA,iBAqUc,oBAAA,CACd,SAAA,EAAW,WAAA,aACX,IAAA,EAAM,cAAA,EACN,OAAA;EAAW,OAAA,GAAU,gBAAA;EAAkB,SAAA;AAAA;AAAA,iBA6BzB,cAAA,CAAe,OAAA,GAAS,gBAAA,GAAwB,UAAA;AAAA,iBA0GhD,kBAAA,CAAmB,OAAA,GAAS,gBAAA,GAAwB,eAAA"}
|