@pitlane/content 0.1.0 → 0.2.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 +37 -16
- package/README.md +16 -21
- package/dist/index.mjs +1 -1
- package/dist/{render-U9dXN6f0.mjs → render-Bg0i1C_C.mjs} +8 -1
- package/dist/satteri.mjs +27 -6
- package/dist/vite.mjs +1 -0
- package/package.json +92 -94
package/CHANGELOG.md
CHANGED
|
@@ -1,22 +1,43 @@
|
|
|
1
1
|
# @pitlane/content
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 87ec1f6: Give headings the ids GitHub gives them. `headings()` now lowercases a heading, removes every character outside letters, marks, digits, and connector punctuation, and turns each space into a hyphen without collapsing or trimming any of them — the algorithm GitHub uses, and the one Astro's `rehype-heading-ids` uses through the same `github-slugger` package. `## Databases & Data Loading` was `databases-data-loading` and is now `databases--data-loading`; `## Jenni’s Quesadillas` was `jenni-s-quesadillas` and is now `jennis-quesadillas`.
|
|
8
|
+
|
|
9
|
+
A heading containing punctuation or symbols can therefore get a different `id` than it did before — `## Hello World!` keeps `hello-world`, but `## Databases & Data Loading` does not — so an anchor written by hand against the old ids needs checking once. In exchange, a table of contents carried over from GitHub or Astro keeps landing without being rewritten. A heading that slugs to nothing at all, such as `## 🎉`, still falls back to `heading` rather than to the empty `id` GitHub produces, and a later `## Heading` in the same document then takes `heading-1`.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- f8b0db5: Keep content prebuilds from deleting the running app's optimized browser dependencies. This fixes `504 (Outdated Optimize Dep)` errors that could leave MDX updates and client-side navigation broken until the dev server restarted.
|
|
14
|
+
- 98e8a77: Vite no longer warns that it cannot analyze a dynamic import in `@pitlane/content` when an app using `contentLayer()` starts its dev server. The runtime import of a document's resolved dependencies is now marked `/* @vite-ignore */`, since its target is only known at request time.
|
|
15
|
+
|
|
16
|
+
## 0.1.1
|
|
17
|
+
|
|
18
|
+
Published 2026-09-21. [npm](https://www.npmjs.com/package/@pitlane/content/v/0.1.1) · [GitHub release](https://github.com/pitlane-tools/pitlane/releases/tag/%40pitlane/content%400.1.1) · [Source](https://github.com/pitlane-tools/pitlane/commit/b725843491ad0c36c61c83d44466134f76dbd615).
|
|
19
|
+
|
|
20
|
+
Documentation only. No code changed.
|
|
21
|
+
|
|
22
|
+
- The npm description is one line now: "Schema-validated content collections for Remix." The old one led with `createContent()` and ran well past what a registry listing shows.
|
|
23
|
+
- The README quick start guards the entry it reads. `getEntry()` answers `undefined` when no entry has the requested id, and the sample called `render()` on the result regardless, so a route copied out of it threw on the first unknown slug.
|
|
24
|
+
- The install section states the supported Node range and what each optional peer is for: `remix` for `render()`, `satteri` for compiling Markdown and MDX bodies, `vite` 8 or newer for `contentLayer()`. A collection of JSON or YAML files alone needs no Sätteri setup.
|
|
25
|
+
- Link the content guide, the no-build guide, and the custom-loaders section separately. Replace the unpublished `/guides/content-loaders` URL with `/guides/content#custom-loaders`.
|
|
26
|
+
|
|
3
27
|
## 0.1.0
|
|
4
28
|
|
|
29
|
+
Published 2026-09-21. [npm](https://www.npmjs.com/package/@pitlane/content/v/0.1.0) · [GitHub release](https://github.com/pitlane-tools/pitlane/releases/tag/%40pitlane/content%400.1.0) · [Source](https://github.com/pitlane-tools/pitlane/commit/31aae9c3c941238fbb94769e578e320179dc8284).
|
|
30
|
+
|
|
5
31
|
Initial release.
|
|
6
32
|
|
|
7
|
-
- `createContent` returns typed collection handles synchronously without loading
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- `
|
|
11
|
-
|
|
12
|
-
- `
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
after evaluating their declarations and inlines them into the bundle. It waits
|
|
19
|
-
for loading and validation before emitting, and watches the loaders' sources
|
|
20
|
-
in dev.
|
|
21
|
-
- `headings()` from `@pitlane/content/satteri` produces the heading list on both
|
|
22
|
-
rendering paths.
|
|
33
|
+
- `createContent` returns typed collection handles synchronously without loading entries. Reads and rendering remain asynchronous; declaration errors throw synchronously.
|
|
34
|
+
- An entry's data is validated against its collection's schema as it loads, before any query returns it. Any Standard Schema validator does that work, `remix/data-schema` and Zod included, and the entry type is inferred from the schema rather than generated: `CollectionEntry<typeof content.blog>` names one. A failure reports the entry, the collection, the file it came from, and every issue.
|
|
35
|
+
- `getCollection`, `getCollection(filter)`, and `getEntry` over entries sorted by id; `c.reference(collection)` for typed pointers between collections.
|
|
36
|
+
- `render()` resolves an entry's Markdown or MDX to a Remix component and its heading list, parsing nothing until it is called.
|
|
37
|
+
- Without a bundler, `render()` also resolves an MDX document's own imports relative to the document. A namespace import and `import.meta` are refused by name, since neither survives the function body an MDX document compiles to here.
|
|
38
|
+
- Two loader interfaces: `ContentLoader` resolves a whole collection in one execution and can be prebuilt, `LiveLoader` answers one query at a time and runs on every read. `loaders.glob` and `loaders.file` implement the first. `glob` reads Markdown, MDX, JSON, and YAML, one entry per file; `file` reads a single JSON or YAML file holding many entries, and takes a `parser` for any other format.
|
|
39
|
+
- `contentLayer()` from `@pitlane/content/vite` loads `ContentLoader` collections after evaluating their declarations and inlines them into the bundle. It waits for loading and validation before emitting, and watches the loaders' sources in dev.
|
|
40
|
+
- `headings()` from `@pitlane/content/satteri` produces the heading list on both rendering paths. `rawStyles()` sits beside it and hands a `<style>` element's CSS to Remix as markup, which is what keeps an Expressive Code theme from reaching the page escaped into rules that match nothing. `render()` applies both; a Vite build passes them to `vite-plugin-satteri`.
|
|
41
|
+
- `hotContent()` from `@pitlane/content/hot` reloads the browser when a file behind a collection changes, for an application that runs from source with no build. It does nothing unless `remix/node-hmr` is supervising the process, so it can stay in production code. A file created after startup still needs a restart.
|
|
42
|
+
- Every peer dependency is optional, `remix` included. Reading and validating data imports neither it nor `satteri`; `render()` loads Remix only when something asks for a component, and names the entry that needed it if Remix is not installed. Node `^20.19.0 || >=22.12.0`.
|
|
43
|
+
- The prebuild channel, the manifest emitter, and the MDX import reader ship as `@pitlane/content/internal/prebuild`, `/internal/codegen`, and `/internal/mdx`, so a plugin for a bundler other than Vite can reuse them.
|
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# @pitlane/content
|
|
2
2
|
|
|
3
|
-
Schema-validated, cross-referenced content collections for [Remix
|
|
3
|
+
Schema-validated, cross-referenced content collections for [Remix](https://remix.run).
|
|
4
4
|
|
|
5
|
-
Reads Markdown, MDX, JSON, and YAML into collections a controller queries like a
|
|
6
|
-
database. Frontmatter is validated against a schema, one entry can reference
|
|
7
|
-
another, and the types come from the schema rather than from generated code.
|
|
5
|
+
Reads Markdown, MDX, JSON, and YAML into collections a controller queries like a database. Frontmatter is validated against a schema, one entry can reference another, and the types come from the schema rather than from generated code.
|
|
8
6
|
|
|
9
7
|
```sh
|
|
10
8
|
npm install @pitlane/content
|
|
11
9
|
```
|
|
12
10
|
|
|
11
|
+
Requires Node `^20.19.0 || >=22.12.0`. All three peer dependencies are optional: `remix` for `render()`, `satteri` for compiling Markdown and MDX bodies, and `vite` 8 or newer for `contentLayer()`. With a Vite build, `satteri` and `vite-plugin-satteri` are dev dependencies; without a build, `satteri` is a runtime dependency. A collection of only JSON or YAML files needs no Sätteri setup at all.
|
|
12
|
+
|
|
13
13
|
```ts
|
|
14
14
|
import { createContent } from "@pitlane/content";
|
|
15
15
|
import * as loaders from "@pitlane/content/loaders";
|
|
@@ -35,18 +35,17 @@ export let content = createContent(c => ({
|
|
|
35
35
|
```ts
|
|
36
36
|
let posts = await content.blog.getCollection();
|
|
37
37
|
let post = await content.blog.getEntry(params.slug);
|
|
38
|
-
|
|
39
|
-
let
|
|
38
|
+
if (post) {
|
|
39
|
+
let { Content, headings } = await post.render();
|
|
40
|
+
let author = await content.authors.getEntry(post.data.author);
|
|
41
|
+
}
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
`
|
|
43
|
-
|
|
44
|
+
`getEntry()` returns `undefined` when no entry has the requested ID.
|
|
45
|
+
|
|
46
|
+
`createContent()` returns synchronously without loading entries. Import the returned object wherever you need it; reads and rendering stay asynchronous.
|
|
44
47
|
|
|
45
|
-
The loaders are ordinary runtime code, which covers Node, Bun, Deno, and
|
|
46
|
-
container hosts. For a host with no filesystem, add `contentLayer()` from
|
|
47
|
-
`@pitlane/content/vite` and the build resolves the collections ahead of time,
|
|
48
|
-
inlining entry data and compiling Markdown bodies into the bundle. The
|
|
49
|
-
collection declarations do not change.
|
|
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.
|
|
50
49
|
|
|
51
50
|
## Entry points
|
|
52
51
|
|
|
@@ -59,17 +58,13 @@ collection declarations do not change.
|
|
|
59
58
|
|
|
60
59
|
## Without Remix
|
|
61
60
|
|
|
62
|
-
|
|
63
|
-
validation, and both query methods, has no static dependency on `remix` and
|
|
64
|
-
works with any [Standard Schema](https://standardschema.dev) validator. Only
|
|
65
|
-
`render()` needs Remix, because it resolves to a Remix component, and it says
|
|
66
|
-
so if you call it without one.
|
|
61
|
+
The loaders, schema validation, and query methods work with any [Standard Schema](https://standardschema.dev) validator without importing Remix. Rendering returns a Remix component, so it requires Remix. Rendering Markdown or MDX also needs `satteri` unless `contentLayer()` compiled the collection during the build.
|
|
67
62
|
|
|
68
63
|
## Documentation
|
|
69
64
|
|
|
70
|
-
- [Content](https://pitlane.tools/guides/content),
|
|
71
|
-
|
|
72
|
-
- [
|
|
65
|
+
- [Content](https://pitlane.tools/guides/content), for an application with a Vite build
|
|
66
|
+
- [Content (No Build)](https://pitlane.tools/guides/content-no-build), for an application that runs without one
|
|
67
|
+
- [Custom loaders](https://pitlane.tools/guides/content#custom-loaders)
|
|
73
68
|
- [API reference](https://pitlane.tools/package/content/)
|
|
74
69
|
|
|
75
70
|
## License
|
package/dist/index.mjs
CHANGED
|
@@ -280,7 +280,7 @@ function view(collection, entry) {
|
|
|
280
280
|
data: entry.data,
|
|
281
281
|
...entry.filePath === void 0 ? {} : { filePath: entry.filePath },
|
|
282
282
|
render: async () => {
|
|
283
|
-
return await (await import("./render-
|
|
283
|
+
return await (await import("./render-Bg0i1C_C.mjs").catch((cause) => {
|
|
284
284
|
throw missingRenderer(`${collection}/${entry.id}`, cause) ?? cause;
|
|
285
285
|
})).renderedEntry(collection, entry);
|
|
286
286
|
}
|
|
@@ -222,7 +222,14 @@ async function nodeResolution() {
|
|
|
222
222
|
async function importFrom(specifier, from, where, node, attributes) {
|
|
223
223
|
let resolved = specifier.startsWith(".") ? new URL(specifier, from).href : resolveBare(specifier, from, where, node);
|
|
224
224
|
try {
|
|
225
|
-
return await (attributes ? import(
|
|
225
|
+
return await (attributes ? import(
|
|
226
|
+
/* @vite-ignore */
|
|
227
|
+
resolved,
|
|
228
|
+
{ with: attributes }
|
|
229
|
+
) : import(
|
|
230
|
+
/* @vite-ignore */
|
|
231
|
+
resolved
|
|
232
|
+
));
|
|
226
233
|
} catch (error) {
|
|
227
234
|
let cause = error instanceof Error ? error.message : String(error);
|
|
228
235
|
throw new Error(`"${where}" imports "${specifier}", which could not be loaded: ${cause}`, { cause: error });
|
package/dist/satteri.mjs
CHANGED
|
@@ -1,19 +1,40 @@
|
|
|
1
1
|
//#region src/satteri.ts
|
|
2
2
|
/**
|
|
3
|
-
* The base slug for a heading
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* addressable and distinct.
|
|
3
|
+
* The base slug for a heading that slugs to nothing at all, such as `## ***` or
|
|
4
|
+
* `## 🎉`. GitHub answers the empty string there; an empty `id` is invalid HTML
|
|
5
|
+
* and makes the anchor a bare `#`, which lands nowhere, so a fixed word plus
|
|
6
|
+
* the usual collision suffix keeps such headings addressable and distinct. This
|
|
7
|
+
* is the one case where these slugs are deliberately not GitHub's.
|
|
7
8
|
*/
|
|
8
9
|
const FALLBACK_SLUG = "heading";
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* Every character GitHub's slugger removes: anything that is not alphabetic, a
|
|
12
|
+
* combining mark, a decimal digit, connector punctuation, a space, or a hyphen.
|
|
13
|
+
* Marks are kept because dropping them would shatter Devanagari, Hebrew, and
|
|
14
|
+
* Arabic words into bare consonants; letters of every script are kept so a
|
|
15
|
+
* Japanese or Cyrillic heading slugs to its own text rather than to nothing.
|
|
16
|
+
*
|
|
17
|
+
* `github-slugger` ships this set as a table generated from Unicode 13, while a
|
|
18
|
+
* regular expression matches against whatever Unicode version the engine
|
|
19
|
+
* carries. A character assigned after Unicode 13 therefore survives here and
|
|
20
|
+
* would be stripped there; nothing assigned in Unicode 13 or earlier differs.
|
|
21
|
+
*/
|
|
22
|
+
const STRIPPED = /[^\p{Alphabetic}\p{M}\p{Nd}\p{Pc} -]/gu;
|
|
23
|
+
/**
|
|
24
|
+
* The slug for `text`, built the way GitHub builds a heading's `id`: lowercase
|
|
25
|
+
* it, remove every stripped character, then turn each remaining space into a
|
|
26
|
+
* hyphen. Nothing is collapsed and nothing is trimmed, so `Databases & Data
|
|
27
|
+
* Loading` slugs to `databases--data-loading` and `## ---` to `---`. Astro slugs
|
|
28
|
+
* with the same algorithm, so a table of contents written by hand against
|
|
29
|
+
* either of them keeps landing after a move to Pitlane.
|
|
30
|
+
*
|
|
31
|
+
* The result is then kept distinct from every slug `taken` already holds by
|
|
11
32
|
* suffixing `-1`, `-2`, … The map remembers the last suffix tried for a base so
|
|
12
33
|
* a document of a hundred identical headings stays linear, and the loop covers
|
|
13
34
|
* the case where the suffixed candidate is itself a real heading's slug.
|
|
14
35
|
*/
|
|
15
36
|
function uniqueSlug(text, taken) {
|
|
16
|
-
let base = text.toLowerCase().replace(
|
|
37
|
+
let base = text.toLowerCase().replace(STRIPPED, "").replaceAll(" ", "-");
|
|
17
38
|
if (!base) base = FALLBACK_SLUG;
|
|
18
39
|
let suffix = taken.get(base) ?? 0;
|
|
19
40
|
let slug = base;
|
package/dist/vite.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,104 +1,102 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
2
|
+
"name": "@pitlane/content",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Schema-validated content collections for Remix.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"content",
|
|
7
|
+
"content-collections",
|
|
8
|
+
"markdown",
|
|
9
|
+
"mdx",
|
|
10
|
+
"pitlane",
|
|
11
|
+
"remix",
|
|
12
|
+
"satteri"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://pitlane.tools/package/content/",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/pitlane-tools/pitlane/issues"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"author": "Mark Malstrom <mark@malstrom.me>",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/pitlane-tools/pitlane.git",
|
|
23
|
+
"directory": "packages/content"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"CHANGELOG.md"
|
|
28
|
+
],
|
|
29
|
+
"type": "module",
|
|
30
|
+
"types": "./dist/index.d.mts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/index.d.mts",
|
|
34
|
+
"import": "./dist/index.mjs"
|
|
17
35
|
},
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"type": "git",
|
|
22
|
-
"url": "git+https://github.com/pitlane-tools/pitlane.git",
|
|
23
|
-
"directory": "packages/content"
|
|
36
|
+
"./loaders": {
|
|
37
|
+
"types": "./dist/loaders.d.mts",
|
|
38
|
+
"import": "./dist/loaders.mjs"
|
|
24
39
|
},
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
],
|
|
29
|
-
"type": "module",
|
|
30
|
-
"types": "./dist/index.d.mts",
|
|
31
|
-
"exports": {
|
|
32
|
-
".": {
|
|
33
|
-
"types": "./dist/index.d.mts",
|
|
34
|
-
"import": "./dist/index.mjs"
|
|
35
|
-
},
|
|
36
|
-
"./loaders": {
|
|
37
|
-
"types": "./dist/loaders.d.mts",
|
|
38
|
-
"import": "./dist/loaders.mjs"
|
|
39
|
-
},
|
|
40
|
-
"./satteri": {
|
|
41
|
-
"types": "./dist/satteri.d.mts",
|
|
42
|
-
"import": "./dist/satteri.mjs"
|
|
43
|
-
},
|
|
44
|
-
"./vite": {
|
|
45
|
-
"types": "./dist/vite.d.mts",
|
|
46
|
-
"import": "./dist/vite.mjs"
|
|
47
|
-
},
|
|
48
|
-
"./hot": {
|
|
49
|
-
"types": "./dist/hot.d.mts",
|
|
50
|
-
"import": "./dist/hot.mjs"
|
|
51
|
-
},
|
|
52
|
-
"./internal/manifest": {
|
|
53
|
-
"types": "./dist/manifest.d.mts",
|
|
54
|
-
"import": "./dist/manifest.mjs"
|
|
55
|
-
},
|
|
56
|
-
"./internal/prebuild": {
|
|
57
|
-
"types": "./dist/prebuild.d.mts",
|
|
58
|
-
"import": "./dist/prebuild.mjs"
|
|
59
|
-
},
|
|
60
|
-
"./internal/codegen": {
|
|
61
|
-
"types": "./dist/codegen.d.mts",
|
|
62
|
-
"import": "./dist/codegen.mjs"
|
|
63
|
-
},
|
|
64
|
-
"./internal/mdx": {
|
|
65
|
-
"types": "./dist/mdx.d.mts",
|
|
66
|
-
"import": "./dist/mdx.mjs"
|
|
67
|
-
}
|
|
40
|
+
"./satteri": {
|
|
41
|
+
"types": "./dist/satteri.d.mts",
|
|
42
|
+
"import": "./dist/satteri.mjs"
|
|
68
43
|
},
|
|
69
|
-
"
|
|
70
|
-
|
|
44
|
+
"./vite": {
|
|
45
|
+
"types": "./dist/vite.d.mts",
|
|
46
|
+
"import": "./dist/vite.mjs"
|
|
71
47
|
},
|
|
72
|
-
"
|
|
73
|
-
|
|
74
|
-
|
|
48
|
+
"./hot": {
|
|
49
|
+
"types": "./dist/hot.d.mts",
|
|
50
|
+
"import": "./dist/hot.mjs"
|
|
75
51
|
},
|
|
76
|
-
"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"satteri": "^0.10.5",
|
|
80
|
-
"typescript": "^7.0.2",
|
|
81
|
-
"vite": "^8.1.5",
|
|
82
|
-
"vite-plugin-satteri": "^0.3.5",
|
|
83
|
-
"vite-plus": "^0.2.6"
|
|
52
|
+
"./internal/manifest": {
|
|
53
|
+
"types": "./dist/manifest.d.mts",
|
|
54
|
+
"import": "./dist/manifest.mjs"
|
|
84
55
|
},
|
|
85
|
-
"
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
"vite": ">=8.0.0"
|
|
56
|
+
"./internal/prebuild": {
|
|
57
|
+
"types": "./dist/prebuild.d.mts",
|
|
58
|
+
"import": "./dist/prebuild.mjs"
|
|
89
59
|
},
|
|
90
|
-
"
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
},
|
|
94
|
-
"satteri": {
|
|
95
|
-
"optional": true
|
|
96
|
-
},
|
|
97
|
-
"vite": {
|
|
98
|
-
"optional": true
|
|
99
|
-
}
|
|
60
|
+
"./internal/codegen": {
|
|
61
|
+
"types": "./dist/codegen.d.mts",
|
|
62
|
+
"import": "./dist/codegen.mjs"
|
|
100
63
|
},
|
|
101
|
-
"
|
|
102
|
-
|
|
64
|
+
"./internal/mdx": {
|
|
65
|
+
"types": "./dist/mdx.d.mts",
|
|
66
|
+
"import": "./dist/mdx.mjs"
|
|
103
67
|
}
|
|
104
|
-
}
|
|
68
|
+
},
|
|
69
|
+
"dependencies": {
|
|
70
|
+
"es-module-lexer": "^2.3.1",
|
|
71
|
+
"yaml": "^2.8.1"
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@types/node": "^25.5.0",
|
|
75
|
+
"remix": "3.0.0-rc.2",
|
|
76
|
+
"satteri": "^0.10.5",
|
|
77
|
+
"typescript": "^7.0.2",
|
|
78
|
+
"vite": "^8.1.5",
|
|
79
|
+
"vite-plugin-satteri": "^0.3.5",
|
|
80
|
+
"vite-plus": "^0.2.6"
|
|
81
|
+
},
|
|
82
|
+
"peerDependencies": {
|
|
83
|
+
"remix": "^3.0.0-rc.1",
|
|
84
|
+
"satteri": "^0.10.5",
|
|
85
|
+
"vite": ">=8.0.0"
|
|
86
|
+
},
|
|
87
|
+
"peerDependenciesMeta": {
|
|
88
|
+
"remix": {
|
|
89
|
+
"optional": true
|
|
90
|
+
},
|
|
91
|
+
"satteri": {
|
|
92
|
+
"optional": true
|
|
93
|
+
},
|
|
94
|
+
"vite": {
|
|
95
|
+
"optional": true
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"engines": {
|
|
99
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
100
|
+
},
|
|
101
|
+
"scripts": {}
|
|
102
|
+
}
|