content-query 0.3.0 → 0.5.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 +46 -15
- package/dist/{build-CI4s0oFP.mjs → build-DWpB69_c.mjs} +826 -69
- package/dist/{build-jKnjDjQE.d.mts → build-DfoncKL8.d.mts} +17 -5
- package/dist/build.d.mts +1 -1
- package/dist/build.mjs +1 -1
- package/dist/cli.mjs +14 -8
- package/dist/{content-N1gYshjg.mjs → collection-Cb5eWGnv.mjs} +998 -344
- package/dist/collection-types-CsQtGw7_.d.mts +119 -0
- package/dist/computed.d.mts +2 -2
- package/dist/{types-FmUJ3cH1.d.mts → descriptor-bcPa6XLk.d.mts} +17 -1
- package/dist/{diagnostics-Cu94mZhl.mjs → diagnostics-DmUZtrJ6.mjs} +3 -1
- package/dist/{errors-C2iuBM0G.mjs → errors-Bfd0R4_P.mjs} +16 -1
- package/dist/file-DSOcdFj0.mjs +81 -0
- package/dist/{glob-Bv0dpvCQ.mjs → glob-BXJuwy_p.mjs} +94 -6
- package/dist/index.d.mts +76 -18
- package/dist/index.mjs +1 -1
- package/dist/internal.d.mts +54 -7
- package/dist/internal.mjs +424 -19
- package/dist/loaders.d.mts +1 -2
- package/dist/loaders.mjs +2 -81
- package/dist/next.d.mts +3 -2
- package/dist/next.mjs +67 -14
- package/dist/operators-D-w1-gDg.mjs +391 -0
- package/dist/query-style-C2FcT1f9.d.mts +23 -0
- package/dist/query.d.mts +25 -2
- package/dist/query.mjs +1 -1
- package/dist/{relational-types-B45zM34W.d.mts → relational-types-CTcalUNW.d.mts} +241 -50
- package/dist/revision-DBwU-aC9.d.mts +56 -0
- package/dist/runtime.d.mts +3 -2
- package/dist/runtime.mjs +1 -1
- package/dist/types-Dz1vTXa2.d.mts +214 -0
- package/dist/vite.d.mts +1 -1
- package/dist/vite.mjs +77 -35
- package/package.json +1 -1
- package/dist/content-lwPxE9Yu.d.mts +0 -109
- package/dist/descriptor-BUPT2J7X.d.mts +0 -18
- package/dist/operators-UqWUhKQJ.mjs +0 -173
- package/dist/types-BC8gVJ6u.d.mts +0 -69
- package/dist/validation-D_XdE1pF.mjs +0 -84
package/README.md
CHANGED
|
@@ -9,7 +9,9 @@ Use it with your existing framework. Your application owns its routes, layouts,
|
|
|
9
9
|
- **Typed schemas.** Validate metadata with bundled schema builders or any Standard Schema V1 provider, with inferred TypeScript types.
|
|
10
10
|
- **Flexible sources.** Load local files, use Astro-compatible content loaders, or write your own loader.
|
|
11
11
|
- **Queries and relationships.** Select fields, filter, sort, paginate, and load related entries with validated references.
|
|
12
|
+
- **Per-collection entries.** Import each collection from its own generated module with named types such as `ContentPost`, so a route bundles and traces only the collections it uses.
|
|
12
13
|
- **Markdown rendering.** Request HTML, headings, and syntax highlighting as query payloads, loaded only when a query asks for them.
|
|
14
|
+
- **Custom payloads.** Declare schema-validated per-entry data, optionally by variant such as locale, resolved during the build from tracked related files, and loaded only when a query names it. Development edits re-resolve only the variants whose files changed.
|
|
13
15
|
- **Optional MDX companion.** [`@content-query/mdx`](https://github.com/yangshun/content-query/tree/main/packages/mdx) supplies React islands and ordinary React document modules with Vite SSR. Core has no MDX or React dependency.
|
|
14
16
|
- **Framework integrations.** Use Vite, Next.js, or the standalone CLI, with content updates during development.
|
|
15
17
|
|
|
@@ -44,38 +46,65 @@ Add Markdown files with `title` frontmatter under `content/posts/`, then build:
|
|
|
44
46
|
npx content-query build
|
|
45
47
|
```
|
|
46
48
|
|
|
47
|
-
|
|
49
|
+
Each collection gets its own generated entry, which exports the collection under its name. Query it from server code:
|
|
48
50
|
|
|
49
51
|
```ts
|
|
50
|
-
import {
|
|
52
|
+
import { posts } from "./.content-query/collections/posts/server.js";
|
|
51
53
|
import { eq } from "content-query/query";
|
|
52
54
|
|
|
53
|
-
const
|
|
55
|
+
const summaries = await posts
|
|
54
56
|
.select("id", "title")
|
|
55
|
-
.from("posts")
|
|
56
57
|
.where((fields) => eq(fields.draft, false))
|
|
57
58
|
.orderBy("title");
|
|
58
59
|
|
|
59
|
-
const post = await
|
|
60
|
-
where: { id:
|
|
60
|
+
const post = await posts.findFirst({
|
|
61
|
+
where: { id: summaries[0]!.id },
|
|
61
62
|
payloads: { _rendered: true },
|
|
62
63
|
});
|
|
63
64
|
const { html, headings } = post!._payloads._rendered;
|
|
64
65
|
```
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
Built-in payloads are `_body` and `_rendered`. JSON, YAML, and TOML sources and `file()` collections have none, and a custom `BodyLoader` offers only `_body`. A query for a missing entry returns `undefined`.
|
|
68
|
+
|
|
69
|
+
An entry imports only its own collection's data, so a route that imports `posts` never bundles or traces another collection. With Vite, import from `content-query:collections/posts`. Elsewhere, such as in Next.js, map the entries in `package.json` to import `{ posts }` from `#content-query/posts` at any directory depth:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"imports": {
|
|
74
|
+
"#content-query/*": "./.content-query/collections/*/server.js"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Queries return only the data they select, not even `id` implicitly. A query must select fields, include a relationship, request a payload, or select adjacent entries; otherwise it fails to type-check and throws an `invalid-query` error. Counts need no selection.
|
|
80
|
+
|
|
81
|
+
To follow a relationship, pass its target collection to `using()`. Nothing related loads implicitly:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import { authors } from "#content-query/authors";
|
|
85
|
+
import { posts } from "#content-query/posts";
|
|
86
|
+
|
|
87
|
+
const withAuthors = await posts.using(authors).findMany({
|
|
88
|
+
columns: { title: true },
|
|
89
|
+
with: { author: { columns: { name: true } } },
|
|
90
|
+
});
|
|
91
|
+
```
|
|
67
92
|
|
|
68
|
-
|
|
93
|
+
A relationship whose target was not supplied is a type error and throws `invalid-query`. Nested relationships need every collection they reach, such as `posts.using(authors, publishers)`. Self-relationships need nothing.
|
|
69
94
|
|
|
70
|
-
|
|
95
|
+
Each entry also exports the collection's types. `ContentPost` is a full entry; pass the selected fields to type query results, such as props for a list component:
|
|
71
96
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
97
|
+
```ts
|
|
98
|
+
import type { ContentPost } from "#content-query/posts";
|
|
99
|
+
|
|
100
|
+
type PostLink = ContentPost<"id" | "title">; // What select("id", "title") returns.
|
|
101
|
+
```
|
|
77
102
|
|
|
78
|
-
|
|
103
|
+
Type names are `Content` plus the export name, capitalized and made singular by dropping one trailing `s` (`jobs` gives `ContentJob`, `coding` gives `ContentCoding`). Set `typeName: "Category"` in `defineCollection()` for irregular plurals. Declared payloads are typed as `ContentPostPayload<"detail">`. Collection names that are not identifiers are converted for the export and import path, such as `blog-posts` to `blogPosts`; two collections that would share an export or type name fail the build.
|
|
104
|
+
|
|
105
|
+
Paginate root queries in one call. `paginate({ page: 2, size: 10 })` returns `items`, `total`, `page`, `pageCount`, `hasNextPage`, and `hasPreviousPage` for numbered archive pages. `paginate({ size: 10, after: previous.endCursor })` returns cursor pages with `startCursor` and `endCursor` for "load more" lists. Both work in fluent queries and in `posts.paginate()`; see [pagination](https://github.com/yangshun/content-query/blob/main/docs/API.md#pagination).
|
|
106
|
+
|
|
107
|
+
Add `.content-query/` to `.gitignore`. Follow the quick start for a complete walkthrough, or choose a framework example below.
|
|
79
108
|
|
|
80
109
|
## Documentation
|
|
81
110
|
|
|
@@ -86,6 +115,8 @@ Built-in payload names start with an underscore: `_body` and `_rendered`. A quer
|
|
|
86
115
|
|
|
87
116
|
The Vite integration supports Vite 8, and the Next.js integration supports Next.js 15 and 16. Both integrations are optional; standalone builds and queries require neither framework.
|
|
88
117
|
|
|
118
|
+
To allow only one query API, export `queryStyle` from the config: `export const queryStyle = "relational";` keeps `posts.findMany()`, `findFirst()`, `paginate()`, and `count(options)`, and `"fluent"` keeps `posts.select()` and the other fluent starters. `count()` without options works in both. Generated types report the disabled API in the editor, and the runtime throws an `invalid-query` error for it. See [query style](https://github.com/yangshun/content-query/blob/main/docs/API.md#query-style).
|
|
119
|
+
|
|
89
120
|
Pass `contentQuery()` directly to Vite or Vite+'s `plugins` array. No `Plugin` type cast is needed; workspace consumers share the pinned toolchain versions in the dependency catalog.
|
|
90
121
|
|
|
91
122
|
Repository development checks package types and isolated consumers with [tsrs](https://github.com/oxc-project/tsrs). Run `vp run check` in the package directory for formatting, linting, and type checks; build tools use the shared TypeScript 6 compatibility package for its `6.0.3` JavaScript API. Native TypeScript `7.1.0-beta` is available at the repository root as `vp exec tsc`.
|