content-query 0.5.1 → 0.6.1
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 +6 -0
- package/dist/{build-CIw4yWs9.mjs → build-CfxMqm_9.mjs} +1 -1
- package/dist/{build-Aoi7Unm0.d.mts → build-MlsJ12d8.d.mts} +4 -4
- package/dist/build.d.mts +1 -1
- package/dist/build.mjs +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/{collection-Cb5eWGnv.mjs → collection-DYeLLOXP.mjs} +100 -25
- package/dist/{collection-types-DhIxnCSM.d.mts → collection-types-BjSEeKN-.d.mts} +20 -9
- package/dist/computed.d.mts +52 -3
- package/dist/computed.mjs +58 -1
- package/dist/{descriptor-bcPa6XLk.d.mts → descriptor-BseHJvUB.d.mts} +7 -1
- package/dist/index.d.mts +4 -4
- package/dist/internal.d.mts +5 -5
- package/dist/internal.mjs +1 -1
- package/dist/loaders.d.mts +1 -1
- package/dist/next.d.mts +1 -1
- package/dist/next.mjs +1 -1
- package/dist/{query-style-C2FcT1f9.d.mts → query-style-k8Qd7wh5.d.mts} +1 -1
- package/dist/query.d.mts +1 -1
- package/dist/{relational-types-PtrzENt0.d.mts → relational-types-Bh34u01H.d.mts} +55 -31
- package/dist/{revision-aqGUf6YV.d.mts → revision-C7GpzihD.d.mts} +4 -4
- package/dist/runtime.d.mts +4 -3
- package/dist/{types-WOsFmNnN.d.mts → types-B_p8k_g6.d.mts} +8 -2
- package/dist/vite.d.mts +1 -1
- package/dist/vite.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -78,6 +78,12 @@ An entry imports only its own collection's data, so a route that imports `posts`
|
|
|
78
78
|
|
|
79
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
80
|
|
|
81
|
+
Later `select()` calls add fields, so a shared builder such as `const postLink = posts.select("id", "title")` can become `postLink.select("publishedAt")` where a page needs more. For detail pages, `posts.byId(id)` starts a query for one entry, and awaiting it returns that entry or `undefined`:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
const post = await posts.byId("hello").select("title").withPayload("_rendered");
|
|
85
|
+
```
|
|
86
|
+
|
|
81
87
|
To follow a relationship, pass its target collection to `using()`. Nothing related loads implicitly:
|
|
82
88
|
|
|
83
89
|
```ts
|
|
@@ -4,7 +4,7 @@ import { i as detach, l as valuePath, o as encode } from "./values-BbTV4QT-.mjs"
|
|
|
4
4
|
import { t as assertServerOnly } from "./server-only-CIJUlyL-.mjs";
|
|
5
5
|
import { n as loadFile } from "./file-DSOcdFj0.mjs";
|
|
6
6
|
import { I as collectionNames } from "./operators-D-w1-gDg.mjs";
|
|
7
|
-
import { a as variantKey, c as CODEC_VERSION, i as isQueryStyle, n as createCollections, o as isRelationship, s as prepareRelationships } from "./collection-
|
|
7
|
+
import { a as variantKey, c as CODEC_VERSION, i as isQueryStyle, n as createCollections, o as isRelationship, s as prepareRelationships } from "./collection-DYeLLOXP.mjs";
|
|
8
8
|
import { t as renderMarkdown } from "./markdown-CHvBBJNa.mjs";
|
|
9
9
|
import { access, link, mkdir, readFile, readdir, realpath, rm, rmdir, stat, writeFile } from "node:fs/promises";
|
|
10
10
|
import path from "node:path";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as InvalidRelationships, r as CollectionHandles, s as ContentError } from "./collection-types-
|
|
2
|
-
import { i as CollectionRegistry } from "./types-
|
|
3
|
-
import { n as QueryStyle } from "./query-style-
|
|
4
|
-
import "./revision-
|
|
1
|
+
import { a as InvalidRelationships, r as CollectionHandles, s as ContentError } from "./collection-types-BjSEeKN-.mjs";
|
|
2
|
+
import { i as CollectionRegistry } from "./types-B_p8k_g6.mjs";
|
|
3
|
+
import { n as QueryStyle } from "./query-style-k8Qd7wh5.mjs";
|
|
4
|
+
import "./revision-C7GpzihD.mjs";
|
|
5
5
|
//#region src/preparation/session.d.ts
|
|
6
6
|
/** A local source captured by a successfully prepared content revision. */
|
|
7
7
|
type ContentSourceEntry = Readonly<{
|
package/dist/build.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as ContentSourceEvent, i as ContentSourceEntry, n as buildContent, o as ContentSourceSnapshot, r as ContentSession, t as BuildContentOptions } from "./build-
|
|
1
|
+
import { a as ContentSourceEvent, i as ContentSourceEntry, n as buildContent, o as ContentSourceSnapshot, r as ContentSession, t as BuildContentOptions } from "./build-MlsJ12d8.mjs";
|
|
2
2
|
export { type BuildContentOptions, type ContentSession, type ContentSourceEntry, type ContentSourceEvent, type ContentSourceSnapshot, buildContent };
|
package/dist/build.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { n as buildContent } from "./build-
|
|
1
|
+
export { n as buildContent } from "./build-CfxMqm_9.mjs";
|
package/dist/cli.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { o as payloadIdentity, t as ContentError } from "./errors-Bfd0R4_P.mjs";
|
|
3
|
-
import { t as buildAtRoot } from "./build-
|
|
3
|
+
import { t as buildAtRoot } from "./build-CfxMqm_9.mjs";
|
|
4
4
|
import { cac } from "cac";
|
|
5
5
|
//#region package.json
|
|
6
|
-
var version = "0.
|
|
6
|
+
var version = "0.6.1";
|
|
7
7
|
//#endregion
|
|
8
8
|
//#region src/integrations/cli/arguments.ts
|
|
9
9
|
/** Validates one path option after CAC's automatic numeric conversion. */
|
|
@@ -320,8 +320,28 @@ function checkedPayload(registry, collection, name, request) {
|
|
|
320
320
|
return { variant: {} };
|
|
321
321
|
}
|
|
322
322
|
const variant = request;
|
|
323
|
-
if (!variant || typeof variant !== "object" || Array.isArray(variant) || Object.keys(variant).length !== variants.length || variants.some((key) => !Object.hasOwn(variant, key) ||
|
|
324
|
-
|
|
323
|
+
if (!variant || typeof variant !== "object" || Array.isArray(variant) || Object.keys(variant).length !== variants.length || variants.some((key) => !Object.hasOwn(variant, key) || !isVariantValue(variant[key]))) invalidQuery(`Payload "${name}" requires exactly these variant keys, each a string or a nonempty array of strings: ${variants.join(", ") || "none"}.`);
|
|
324
|
+
let combinations = [{}];
|
|
325
|
+
for (const key of Object.keys(variant)) {
|
|
326
|
+
const values = [variant[key]].flat();
|
|
327
|
+
combinations = combinations.flatMap((partial) => values.map((value) => ({
|
|
328
|
+
...partial,
|
|
329
|
+
[key]: value
|
|
330
|
+
})));
|
|
331
|
+
}
|
|
332
|
+
const sorted = [...variants].sort();
|
|
333
|
+
const [first, ...fallbacks] = new Map(combinations.map((combination) => {
|
|
334
|
+
const canonical = Object.fromEntries(sorted.map((key) => [key, combination[key]]));
|
|
335
|
+
return [JSON.stringify(canonical), canonical];
|
|
336
|
+
})).values();
|
|
337
|
+
return fallbacks.length ? {
|
|
338
|
+
variant: first,
|
|
339
|
+
fallbacks
|
|
340
|
+
} : { variant: first };
|
|
341
|
+
}
|
|
342
|
+
/** Checks one variant key's request: a value, or a nonempty list of values to try in order. */
|
|
343
|
+
function isVariantValue(value) {
|
|
344
|
+
return typeof value === "string" || Array.isArray(value) && value.length > 0 && value.every((item) => typeof item === "string");
|
|
325
345
|
}
|
|
326
346
|
/** Compiles a payloads option into plan requests, omitting payloads set to false. */
|
|
327
347
|
function checkedPayloads(registry, collection, payloads) {
|
|
@@ -481,7 +501,10 @@ function objectPlan(registry, collection, options, many = true, allowAdjacent =
|
|
|
481
501
|
//#region src/query/builder.ts
|
|
482
502
|
const planSymbol = Symbol("content-query.query-plan");
|
|
483
503
|
const scopeSymbol = Symbol("content-query.query-scope");
|
|
484
|
-
/**
|
|
504
|
+
/**
|
|
505
|
+
* Creates immutable root or relationship builders over one backend-independent plan. A root
|
|
506
|
+
* builder that is not `many` is a `byId()` query, which returns one entry or `undefined`.
|
|
507
|
+
*/
|
|
485
508
|
function createBuilder(registry, run, plan, many = true, root = true, scopeToken = {}, allowAdjacent = true, allowPagination = true) {
|
|
486
509
|
const scope = registry[plan.collection];
|
|
487
510
|
if (!scope) invalidQuery(`Unknown collection "${plan.collection}".`);
|
|
@@ -492,9 +515,12 @@ function createBuilder(registry, run, plan, many = true, root = true, scopeToken
|
|
|
492
515
|
const builder = {
|
|
493
516
|
[planSymbol]: plan,
|
|
494
517
|
[scopeSymbol]: scopeToken,
|
|
518
|
+
/** Selects fields, adding to earlier selections; a field selected again is kept once. */
|
|
495
519
|
select(...fields) {
|
|
496
|
-
if (
|
|
497
|
-
|
|
520
|
+
if (fields.length === 0) invalidQuery("select() requires at least one prepared field.");
|
|
521
|
+
const checked = checkedFields(registry, plan.collection, fields);
|
|
522
|
+
const earlier = plan.select ?? [];
|
|
523
|
+
return branch({ select: [...earlier, ...checked.filter((field) => !earlier.includes(field))] });
|
|
498
524
|
},
|
|
499
525
|
where(configure) {
|
|
500
526
|
if (typeof configure !== "function") invalidQuery("where() requires a configuration callback.");
|
|
@@ -503,6 +529,7 @@ function createBuilder(registry, run, plan, many = true, root = true, scopeToken
|
|
|
503
529
|
return branch({ filters: [...plan.filters, detach(resolveRelations(registry, plan.collection, expression))] });
|
|
504
530
|
},
|
|
505
531
|
orderBy(field, direction = "asc") {
|
|
532
|
+
assertList("orderBy()");
|
|
506
533
|
return branch({ order: checkedOrder(plan, field, direction, many) });
|
|
507
534
|
},
|
|
508
535
|
limit(value) {
|
|
@@ -541,6 +568,7 @@ function createBuilder(registry, run, plan, many = true, root = true, scopeToken
|
|
|
541
568
|
if (!allowAdjacent || plan.adjacent !== void 0) invalidQuery("Adjacency cannot be repeated or selected recursively.");
|
|
542
569
|
const [configure] = arguments_;
|
|
543
570
|
if (configure === void 0 || typeof configure === "string") {
|
|
571
|
+
assertList("Results-scope selectAdjacent()");
|
|
544
572
|
if (!arguments_.length || arguments_.some((field) => typeof field !== "string")) invalidQuery("selectAdjacent() requires neighbor fields, such as selectAdjacent(\"id\"), or a sibling query.");
|
|
545
573
|
const selection = {
|
|
546
574
|
...emptyPlan(plan.collection),
|
|
@@ -569,11 +597,12 @@ function createBuilder(registry, run, plan, many = true, root = true, scopeToken
|
|
|
569
597
|
} });
|
|
570
598
|
},
|
|
571
599
|
all() {
|
|
600
|
+
assertList("all()");
|
|
572
601
|
return rows("all");
|
|
573
602
|
},
|
|
574
603
|
/** Executes a selected root query, matching direct await behavior. */
|
|
575
604
|
execute() {
|
|
576
|
-
return rows("all");
|
|
605
|
+
return rows(many ? "all" : "first");
|
|
577
606
|
},
|
|
578
607
|
first() {
|
|
579
608
|
return rows("first");
|
|
@@ -589,6 +618,7 @@ function createBuilder(registry, run, plan, many = true, root = true, scopeToken
|
|
|
589
618
|
*/
|
|
590
619
|
paginate(options) {
|
|
591
620
|
if (!root) invalidQuery("Nested builders have no terminal methods.");
|
|
621
|
+
assertList("paginate()");
|
|
592
622
|
if (!hasSelection(plan)) invalidQuery(NO_SELECTION_MESSAGE);
|
|
593
623
|
return run({
|
|
594
624
|
...plan,
|
|
@@ -599,7 +629,7 @@ function createBuilder(registry, run, plan, many = true, root = true, scopeToken
|
|
|
599
629
|
if (root) Object.defineProperty(builder, "then", { value: (fulfilled, rejected) => {
|
|
600
630
|
let result;
|
|
601
631
|
try {
|
|
602
|
-
result = rows("all");
|
|
632
|
+
result = rows(many ? "all" : "first");
|
|
603
633
|
} catch (cause) {
|
|
604
634
|
result = Promise.reject(cause);
|
|
605
635
|
}
|
|
@@ -614,8 +644,13 @@ function createBuilder(registry, run, plan, many = true, root = true, scopeToken
|
|
|
614
644
|
if (!hasSelection(plan)) invalidQuery(NO_SELECTION_MESSAGE);
|
|
615
645
|
return run(plan, terminal);
|
|
616
646
|
}
|
|
647
|
+
/** Rejects a list-only clause or terminal on a `byId()` query, which returns one entry. */
|
|
648
|
+
function assertList(member) {
|
|
649
|
+
if (root && !many) invalidQuery(`${member} is unavailable after byId(), which returns one entry.`);
|
|
650
|
+
}
|
|
617
651
|
/** Checks pagination before creating an independent branch. */
|
|
618
652
|
function pagination(key, value) {
|
|
653
|
+
assertList(`${key}()`);
|
|
619
654
|
if (!allowPagination || plan[key] !== void 0) invalidQuery("Pagination requires a nonnegative safe integer, one call per clause, and a many-valued scope.");
|
|
620
655
|
return branch({ [key]: checkedPagination(value, many) });
|
|
621
656
|
}
|
|
@@ -633,9 +668,38 @@ function createBuilder(registry, run, plan, many = true, root = true, scopeToken
|
|
|
633
668
|
* @returns An immutable, reusable root builder.
|
|
634
669
|
*/
|
|
635
670
|
function createFrom(registry, run, collection) {
|
|
671
|
+
return createBuilder(currentRegistry(registry, collection), run, emptyPlan(collection));
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Starts a fluent query for the entry with one ID. The builder returns that entry or `undefined`
|
|
675
|
+
* when awaited, offers no ordering, pagination, `all()`, or results-scope adjacency, and still
|
|
676
|
+
* selects nothing until the query requests data.
|
|
677
|
+
*
|
|
678
|
+
* @param registry - Reads the current query registry, so development builders bind the latest one.
|
|
679
|
+
* @param run - Executes a plan against one pinned revision.
|
|
680
|
+
* @param collection - The collection to query.
|
|
681
|
+
* @param id - The entry's ID.
|
|
682
|
+
* @returns An immutable, reusable single-entry root builder.
|
|
683
|
+
*/
|
|
684
|
+
function createById(registry, run, collection, id) {
|
|
685
|
+
const current = currentRegistry(registry, collection);
|
|
686
|
+
if (typeof id !== "string") invalidQuery("byId() requires an entry ID string.");
|
|
687
|
+
const filter = {
|
|
688
|
+
kind: "predicate",
|
|
689
|
+
operator: "eq",
|
|
690
|
+
field: "id",
|
|
691
|
+
value: id
|
|
692
|
+
};
|
|
693
|
+
return createBuilder(current, run, {
|
|
694
|
+
...emptyPlan(collection),
|
|
695
|
+
filters: [filter]
|
|
696
|
+
}, false);
|
|
697
|
+
}
|
|
698
|
+
/** Reads the registry a new root query binds, rejecting unknown collections. */
|
|
699
|
+
function currentRegistry(registry, collection) {
|
|
636
700
|
const current = registry();
|
|
637
701
|
if (typeof collection !== "string" || !Object.hasOwn(current, collection)) invalidQuery(`Unknown collection "${String(collection)}".`);
|
|
638
|
-
return
|
|
702
|
+
return current;
|
|
639
703
|
}
|
|
640
704
|
//#endregion
|
|
641
705
|
//#region src/query/relational.ts
|
|
@@ -1275,20 +1339,29 @@ async function renderedPayload(revision, collection, id) {
|
|
|
1275
1339
|
}
|
|
1276
1340
|
return rendered;
|
|
1277
1341
|
}
|
|
1278
|
-
/**
|
|
1279
|
-
|
|
1342
|
+
/**
|
|
1343
|
+
* Lazily loads one custom payload variant once per revision, retrying after failures. The request's
|
|
1344
|
+
* combinations are tried in order, and only the first one the entry has is loaded.
|
|
1345
|
+
*/
|
|
1346
|
+
function loadCustom(revision, collection, id, name, request) {
|
|
1280
1347
|
const entries = revision.collections[collection].payloads?.get(name);
|
|
1281
1348
|
if (!entries) invalidQuery(`Payload "${name}" no longer matches the prepared collection.`);
|
|
1282
|
-
const
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1349
|
+
const candidates = [request.variant, ...request.fallbacks ?? []];
|
|
1350
|
+
const variants = entries.get(id);
|
|
1351
|
+
const variant = candidates.find((candidate) => variants?.has(variantKey(candidate)));
|
|
1352
|
+
const load = variant && variants.get(variantKey(variant));
|
|
1353
|
+
if (!variant || !load) {
|
|
1354
|
+
const tried = candidates.map((candidate) => payloadIdentity(name, candidate));
|
|
1355
|
+
return Promise.reject(new ContentError({
|
|
1356
|
+
code: "variant-not-found",
|
|
1357
|
+
operation: "query",
|
|
1358
|
+
collection,
|
|
1359
|
+
id,
|
|
1360
|
+
payload: name,
|
|
1361
|
+
variant: request.variant,
|
|
1362
|
+
message: tried.length === 1 ? `Entry "${id}" has no ${tried[0]} payload.` : `Entry "${id}" has none of the ${tried.join(", ")} payloads.`
|
|
1363
|
+
}));
|
|
1364
|
+
}
|
|
1292
1365
|
const key = JSON.stringify([
|
|
1293
1366
|
collection,
|
|
1294
1367
|
id,
|
|
@@ -1313,10 +1386,10 @@ function loadCustom(revision, collection, id, name, variant) {
|
|
|
1313
1386
|
return loaded;
|
|
1314
1387
|
}
|
|
1315
1388
|
/** Loads one requested payload value from the pinned revision. */
|
|
1316
|
-
async function loadPayload(revision, collection, id, name,
|
|
1389
|
+
async function loadPayload(revision, collection, id, name, request) {
|
|
1317
1390
|
if (name === "_body") return (await loadBuiltin(revision, collection, id)).body;
|
|
1318
1391
|
if (name === "_rendered") return renderedPayload(revision, collection, id);
|
|
1319
|
-
return loadCustom(revision, collection, id, name,
|
|
1392
|
+
return loadCustom(revision, collection, id, name, request);
|
|
1320
1393
|
}
|
|
1321
1394
|
/**
|
|
1322
1395
|
* Loads every requested payload with bounded concurrency, then attaches detached copies under
|
|
@@ -1336,13 +1409,13 @@ async function attachPayloads(revision, requests) {
|
|
|
1336
1409
|
collection: request.collection,
|
|
1337
1410
|
id: request.id,
|
|
1338
1411
|
name,
|
|
1339
|
-
|
|
1412
|
+
request: request.payloads[name]
|
|
1340
1413
|
});
|
|
1341
1414
|
}
|
|
1342
1415
|
const keys = [...loads.keys()];
|
|
1343
1416
|
const values = await mapConcurrent(keys, PAYLOAD_CONCURRENCY, (key) => {
|
|
1344
|
-
const { collection, id, name,
|
|
1345
|
-
return loadPayload(revision, collection, id, name,
|
|
1417
|
+
const { collection, id, name, request } = loads.get(key);
|
|
1418
|
+
return loadPayload(revision, collection, id, name, request);
|
|
1346
1419
|
});
|
|
1347
1420
|
const loaded = new Map(keys.map((key, index) => [key, values[index]]));
|
|
1348
1421
|
for (const request of requests) request.target._payloads = Object.fromEntries(Object.keys(request.payloads).map((name) => [name, detach(loaded.get(JSON.stringify([
|
|
@@ -1376,6 +1449,7 @@ function createRunner(state) {
|
|
|
1376
1449
|
*/
|
|
1377
1450
|
const queryStyleMembers = {
|
|
1378
1451
|
fluent: [
|
|
1452
|
+
"byId",
|
|
1379
1453
|
"select",
|
|
1380
1454
|
"where",
|
|
1381
1455
|
"orderBy",
|
|
@@ -1602,6 +1676,7 @@ function createCollection(primary, supplied = []) {
|
|
|
1602
1676
|
};
|
|
1603
1677
|
for (const member of queryStyleMembers.fluent) handle[member] = (...arguments_) => {
|
|
1604
1678
|
allow(member);
|
|
1679
|
+
if (member === "byId") return createById(registry, run, name, arguments_[0]);
|
|
1605
1680
|
return createFrom(registry, run, name)[member](...arguments_);
|
|
1606
1681
|
};
|
|
1607
1682
|
handleSources.set(handle, sources);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { _ as Unavailable } from "./descriptor-BseHJvUB.mjs";
|
|
2
|
+
import { _ as Relationship, g as QueryData, i as CollectionRegistry, u as LoadedMarker, v as RelationshipsOf } from "./types-B_p8k_g6.mjs";
|
|
3
|
+
import { n as RelationalCountOptions, t as RelationalCollectionQueries, v as Query } from "./relational-types-Bh34u01H.mjs";
|
|
4
|
+
import { i as QueryStyleMember, n as QueryStyle, r as QueryStyleDisabled, t as MembersOf } from "./query-style-k8Qd7wh5.mjs";
|
|
4
5
|
//#region src/shared/errors.d.ts
|
|
5
6
|
type ContentErrorCode = "variant-not-found" | "not-renderable" | "source-error" | "validation-error" | "duplicate-id" | "invalid-reference" | "invalid-query" | "invalid-cursor" | "artifact-error" | "render-error";
|
|
6
7
|
type ContentDiagnostic = {
|
|
@@ -58,13 +59,23 @@ type LoadedRegistry<Registry extends CollectionRegistry, Loaded extends keyof Re
|
|
|
58
59
|
type FluentMember = MembersOf<"fluent">;
|
|
59
60
|
/** The relational members, apart from `count`, which both styles share. */
|
|
60
61
|
type RelationalMember = "findMany" | "findFirst" | "paginate";
|
|
62
|
+
/** Fluent starters that only a collection handle offers, not a query builder. */
|
|
63
|
+
type HandleStarters<Registry extends CollectionRegistry, Name extends keyof Registry & string> = {
|
|
64
|
+
/**
|
|
65
|
+
* Starts a query for the entry with this ID. Select its data as usual; awaiting the query, or
|
|
66
|
+
* calling `first()` or `execute()`, returns the entry or `undefined`. Later `where()` filters
|
|
67
|
+
* also apply. Lookups use the collection's ID index.
|
|
68
|
+
*
|
|
69
|
+
* @param id - The entry's ID.
|
|
70
|
+
* @returns A single-entry root query, without ordering, pagination, `all()`, or results-scope
|
|
71
|
+
* adjacency.
|
|
72
|
+
*/
|
|
73
|
+
byId(id: string): Query<Registry, Name, {}, false, false>;
|
|
74
|
+
};
|
|
61
75
|
/** Every member before `queryStyle` gating. */
|
|
62
|
-
type CollectionMethods<Registry extends CollectionRegistry, Name extends keyof Registry & string> = Pick<Query<Registry, Name>, FluentMember & keyof Query<Registry, Name>> & RelationalCollectionQueries<Registry, Name>;
|
|
63
|
-
/**
|
|
64
|
-
|
|
65
|
-
* whatever arguments they pass.
|
|
66
|
-
*/
|
|
67
|
-
type DisabledMembers<Name extends string, Style extends QueryStyle> = { readonly [Member in Exclude<FluentMember | RelationalMember, MembersOf<Style>>]: (this: QueryStyleDisabled<Name, Member & QueryStyleMember, Style>, ...arguments_: readonly unknown[]) => never; };
|
|
76
|
+
type CollectionMethods<Registry extends CollectionRegistry, Name extends keyof Registry & string> = Pick<Query<Registry, Name>, FluentMember & keyof Query<Registry, Name>> & HandleStarters<Registry, Name> & RelationalCollectionQueries<Registry, Name>;
|
|
77
|
+
/** Members outside the allowed style. They are not callable, and their type gives the message. */
|
|
78
|
+
type DisabledMembers<Name extends string, Style extends QueryStyle> = { readonly [Member in Exclude<FluentMember | RelationalMember, MembersOf<Style>>]: Unavailable<QueryStyleDisabled<Name, Member & QueryStyleMember, Style>>; };
|
|
68
79
|
/** `count()` counts every entry in both styles; options take relational filters. */
|
|
69
80
|
type CountMember<Registry extends CollectionRegistry, Name extends keyof Registry & string, Style extends QueryStyle> = [Style] extends ["fluent"] ? {
|
|
70
81
|
/** Counts every entry. Count filtered entries with `where(...).count()`. */
|
package/dist/computed.d.mts
CHANGED
|
@@ -1,6 +1,55 @@
|
|
|
1
|
-
import { g as MaybePromise } from "./descriptor-
|
|
2
|
-
import { a as ComputedContext } from "./types-
|
|
1
|
+
import { g as MaybePromise } from "./descriptor-BseHJvUB.mjs";
|
|
2
|
+
import { a as ComputedContext } from "./types-B_p8k_g6.mjs";
|
|
3
3
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
|
+
//#region src/computed/fields.d.ts
|
|
5
|
+
/** Result schemas for computed fields that one resolver call fills, keyed by field name. */
|
|
6
|
+
type ComputedFieldSchemas = Record<string, StandardSchemaV1>;
|
|
7
|
+
/**
|
|
8
|
+
* The object a shared resolver returns: one value per field, checked by that field's schema.
|
|
9
|
+
* Fields whose schema accepts `undefined` may be omitted.
|
|
10
|
+
*/
|
|
11
|
+
type ComputedFieldValues<Fields extends ComputedFieldSchemas> = { [Key in keyof Fields as undefined extends StandardSchemaV1.InferInput<Fields[Key]> ? never : Key]: StandardSchemaV1.InferInput<Fields[Key]>; } & { [Key in keyof Fields as undefined extends StandardSchemaV1.InferInput<Fields[Key]> ? Key : never]?: StandardSchemaV1.InferInput<Fields[Key]>; };
|
|
12
|
+
/** Declares several computed fields and the one resolver that returns all of their values. */
|
|
13
|
+
type ComputedFieldsOptions<Fields extends ComputedFieldSchemas, Data = Record<string, unknown>, Source = unknown> = {
|
|
14
|
+
/**
|
|
15
|
+
* Each field's result schema, keyed by field name. A JSDoc comment on a key documents that
|
|
16
|
+
* field in entry types and query results.
|
|
17
|
+
*/
|
|
18
|
+
fields: Fields;
|
|
19
|
+
/**
|
|
20
|
+
* Returns every field's value for one entry. It runs once per entry each time the entry is
|
|
21
|
+
* prepared, however many fields it fills; files it reads through `files` are tracked as usual.
|
|
22
|
+
* Annotate the context, such as `(context: ComputedContext<Post>)`, to type `data`.
|
|
23
|
+
*/
|
|
24
|
+
resolve(this: void, context: ComputedContext<Data, Source>): MaybePromise<ComputedFieldValues<Fields>>;
|
|
25
|
+
};
|
|
26
|
+
/** The computed field definitions that {@link computedFields} returns, one per declared field. */
|
|
27
|
+
type ComputedFieldDefinitions<Fields extends ComputedFieldSchemas, Data = Record<string, unknown>, Source = unknown> = { [Key in keyof Fields]: {
|
|
28
|
+
schema: Fields[Key];
|
|
29
|
+
resolve(context: ComputedContext<Data, Source>): Promise<unknown>;
|
|
30
|
+
}; };
|
|
31
|
+
/**
|
|
32
|
+
* Creates computed fields that share one resolver call per entry, for values that come from the
|
|
33
|
+
* same expensive read, such as several properties of one JSON file beside the entry. Spread the
|
|
34
|
+
* result into `computed`; each field is validated by its own schema and is selected, filtered, and
|
|
35
|
+
* sorted like any other computed field.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* computed: {
|
|
40
|
+
* ...computedFields({
|
|
41
|
+
* fields: { title: schema.string(), description: schema.string() },
|
|
42
|
+
* resolve: async ({ files }) => JSON.parse(await files.text("info/en-US.json")),
|
|
43
|
+
* }),
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @param options - The fields' result schemas and the resolver that returns their values.
|
|
48
|
+
* @returns One computed field definition per key of `options.fields`.
|
|
49
|
+
* @throws TypeError - When `fields` declares no schemas or `resolve` is not a function.
|
|
50
|
+
*/
|
|
51
|
+
export declare function computedFields<const Fields extends ComputedFieldSchemas, Data = Record<string, unknown>, Source = unknown>(options: ComputedFieldsOptions<Fields, Data, Source>): ComputedFieldDefinitions<Fields, Data, Source>;
|
|
52
|
+
//#endregion
|
|
4
53
|
//#region src/computed/text.d.ts
|
|
5
54
|
/** The syntax removed before computing text-derived fields; literal text preserves all characters. */
|
|
6
55
|
type TextFormat = "markdown" | "text" | "html";
|
|
@@ -40,4 +89,4 @@ export declare function excerpt<Data = Record<string, unknown>, Source = unknown
|
|
|
40
89
|
resolve(context: ComputedContext<Data, Source>): Promise<string>;
|
|
41
90
|
};
|
|
42
91
|
//#endregion
|
|
43
|
-
export type { ExcerptOptions, ReadingTimeOptions, TextFormat, TextOptions };
|
|
92
|
+
export type { ComputedFieldDefinitions, ComputedFieldSchemas, ComputedFieldValues, ComputedFieldsOptions, ExcerptOptions, ReadingTimeOptions, TextFormat, TextOptions };
|
package/dist/computed.mjs
CHANGED
|
@@ -3,6 +3,63 @@ import { n as number, r as string } from "./schema-C5Str-E8.mjs";
|
|
|
3
3
|
import { t as src_default } from "./dist-C7_FOzY_.mjs";
|
|
4
4
|
import getReadingTime from "reading-time";
|
|
5
5
|
import { Parser } from "htmlparser2";
|
|
6
|
+
//#region src/computed/fields.ts
|
|
7
|
+
assertServerOnly();
|
|
8
|
+
/**
|
|
9
|
+
* Creates computed fields that share one resolver call per entry, for values that come from the
|
|
10
|
+
* same expensive read, such as several properties of one JSON file beside the entry. Spread the
|
|
11
|
+
* result into `computed`; each field is validated by its own schema and is selected, filtered, and
|
|
12
|
+
* sorted like any other computed field.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* computed: {
|
|
17
|
+
* ...computedFields({
|
|
18
|
+
* fields: { title: schema.string(), description: schema.string() },
|
|
19
|
+
* resolve: async ({ files }) => JSON.parse(await files.text("info/en-US.json")),
|
|
20
|
+
* }),
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @param options - The fields' result schemas and the resolver that returns their values.
|
|
25
|
+
* @returns One computed field definition per key of `options.fields`.
|
|
26
|
+
* @throws TypeError - When `fields` declares no schemas or `resolve` is not a function.
|
|
27
|
+
*/
|
|
28
|
+
function computedFields(options) {
|
|
29
|
+
const { fields, resolve } = options ?? {};
|
|
30
|
+
if (!fields || typeof fields !== "object" || Array.isArray(fields)) throw new TypeError("computedFields() fields must be an object of result schemas.");
|
|
31
|
+
const entries = Object.entries(fields);
|
|
32
|
+
if (!entries.length || entries.some(([, schema]) => !isSchema(schema))) throw new TypeError("computedFields() fields must declare at least one field, each with a Standard Schema.");
|
|
33
|
+
if (typeof resolve !== "function") throw new TypeError("computedFields() resolve must be a function.");
|
|
34
|
+
const resolutions = /* @__PURE__ */ new WeakMap();
|
|
35
|
+
/** Resolves every field's value once for the entry being prepared. */
|
|
36
|
+
function values(context) {
|
|
37
|
+
let pending = resolutions.get(context.files);
|
|
38
|
+
if (!pending) {
|
|
39
|
+
pending = (async () => {
|
|
40
|
+
context.signal.throwIfAborted();
|
|
41
|
+
const result = await resolve(context);
|
|
42
|
+
if (!result || typeof result !== "object" || Array.isArray(result)) throw new TypeError("computedFields() resolve must return an object with a value for each field.");
|
|
43
|
+
return result;
|
|
44
|
+
})();
|
|
45
|
+
resolutions.set(context.files, pending);
|
|
46
|
+
}
|
|
47
|
+
return pending;
|
|
48
|
+
}
|
|
49
|
+
return Object.fromEntries(entries.map(([name, schema]) => [name, {
|
|
50
|
+
schema,
|
|
51
|
+
/** Reads this field's value from the entry's shared resolution. */
|
|
52
|
+
async resolve(context) {
|
|
53
|
+
const result = await values(context);
|
|
54
|
+
return Object.hasOwn(result, name) ? result[name] : void 0;
|
|
55
|
+
}
|
|
56
|
+
}]));
|
|
57
|
+
}
|
|
58
|
+
/** Checks for a Standard Schema V1 validator. */
|
|
59
|
+
function isSchema(value) {
|
|
60
|
+
return (typeof value === "object" || typeof value === "function") && value !== null && "~standard" in value;
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
6
63
|
//#region src/computed/plain-text.ts
|
|
7
64
|
const markdown = new src_default({ html: true });
|
|
8
65
|
const ignoredElements = /* @__PURE__ */ new Set([
|
|
@@ -136,4 +193,4 @@ function excerpt(options = {}) {
|
|
|
136
193
|
return textField(string(), options, (text) => truncate(text, maxLength));
|
|
137
194
|
}
|
|
138
195
|
//#endregion
|
|
139
|
-
export { excerpt, readingTime, wordCount };
|
|
196
|
+
export { computedFields, excerpt, readingTime, wordCount };
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { r as RenderedContent } from "./types-Dh-Sydyw.mjs";
|
|
2
2
|
//#region src/shared/types.d.ts
|
|
3
3
|
type MaybePromise<Value> = Value | Promise<Value>;
|
|
4
|
+
/**
|
|
5
|
+
* The type of a member that a query or configuration does not allow. It has no call signatures,
|
|
6
|
+
* so calling the member fails with the reason near the start of the error:
|
|
7
|
+
* `This expression is not callable. Type 'Unavailable<"…">' has no call signatures.`
|
|
8
|
+
*/
|
|
9
|
+
type Unavailable<Reason extends string> = { readonly [Key in Reason]: never; };
|
|
4
10
|
//#endregion
|
|
5
11
|
//#region src/loaders/types.d.ts
|
|
6
12
|
declare const loaderSourceType: unique symbol;
|
|
@@ -165,4 +171,4 @@ type FileOptions = {
|
|
|
165
171
|
parser?: (text: string) => MaybePromise<unknown>;
|
|
166
172
|
};
|
|
167
173
|
//#endregion
|
|
168
|
-
export { DataStore as a, Loader as c, LoaderLogger as d, LoaderSource as f, MaybePromise as g, RecordLoader as h, DataEntry as i, LoaderConfig as l, MetaStore as m, GlobOptions as n, FileEntrySource as o, LoaderWatcher as p, BodyLoader as r, FileSource as s, FileOptions as t, LoaderContext as u };
|
|
174
|
+
export { Unavailable as _, DataStore as a, Loader as c, LoaderLogger as d, LoaderSource as f, MaybePromise as g, RecordLoader as h, DataEntry as i, LoaderConfig as l, MetaStore as m, GlobOptions as n, FileEntrySource as o, LoaderWatcher as p, BodyLoader as r, FileSource as s, FileOptions as t, LoaderContext as u };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as DataStore, c as Loader, d as LoaderLogger, f as LoaderSource, g as MaybePromise, h as RecordLoader, i as DataEntry, l as LoaderConfig, m as MetaStore, n as GlobOptions, o as FileEntrySource, p as LoaderWatcher, r as BodyLoader, s as FileSource, u as LoaderContext } from "./descriptor-
|
|
1
|
+
import { a as DataStore, c as Loader, d as LoaderLogger, f as LoaderSource, g as MaybePromise, h as RecordLoader, i as DataEntry, l as LoaderConfig, m as MetaStore, n as GlobOptions, o as FileEntrySource, p as LoaderWatcher, r as BodyLoader, s as FileSource, u as LoaderContext } from "./descriptor-BseHJvUB.mjs";
|
|
2
2
|
import { n as ContentRenderResult, r as RenderedContent, t as ContentHeading } from "./types-Dh-Sydyw.mjs";
|
|
3
|
-
import { D as
|
|
4
|
-
import { n as QueryStyle } from "./query-style-
|
|
3
|
+
import { D as VariantRequest, E as VariantOf, O as VariantValues, T as VariantField, _ as Relationship, a as ComputedContext, b as SchemaOutput, c as EntryFiles, d as PayloadContext, f as PayloadData, g as QueryData, h as PayloadsOf, i as CollectionRegistry, l as FileEntry, m as PayloadDefinition, n as BuiltinPayloads, o as CustomPayload, p as PayloadDeclaration, r as CollectionDefinition, s as CustomPayloadMarker, t as BuiltinPayloadMarker, w as VariantContext, x as SelectedData, y as Schema } from "./types-B_p8k_g6.mjs";
|
|
4
|
+
import { n as QueryStyle } from "./query-style-k8Qd7wh5.mjs";
|
|
5
5
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
6
6
|
//#region src/collection/source.d.ts
|
|
7
7
|
type CollectionSource = string | ({
|
|
@@ -134,4 +134,4 @@ export declare function defineCollection<const SourceSchema extends StandardSche
|
|
|
134
134
|
*/
|
|
135
135
|
export declare function defineCollection<const SourceSchema extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined = undefined, const ComputedSchemas extends Record<string, Schema> = {}, const Relationships extends Record<string, Relationship> = {}, const PayloadSchemas extends Record<string, Schema> = {}, const PayloadVariants extends Record<string, unknown> = {}, const ContentLoader extends Loader = Loader>(definition: Definition<SourceSchema, ComputedSchemas, Relationships, PayloadSchemas, PayloadVariants, ContentLoader>): Defined<SourceSchema, ComputedSchemas, Relationships, PayloadSchemas, PayloadVariants, ContentLoader> & BuiltinPayloadMarker<[ContentLoader] extends [RecordLoader] ? never : [ContentLoader] extends [BodyLoader] ? "_body" : keyof BuiltinPayloads>;
|
|
136
136
|
//#endregion
|
|
137
|
-
export type { BodyLoader, BuiltinPayloads, CollectionDefinition, CollectionRegistry, CollectionSource, ComputedContext, ContentHeading, ContentRenderResult, DataEntry, DataStore, EntryFiles, FileEntry, FileEntrySource, FileSource, Loader, LoaderConfig, LoaderContext, LoaderLogger, LoaderSource, LoaderWatcher, MaybePromise, MetaStore, PayloadContext, PayloadData, PayloadDeclaration, PayloadDefinition, PayloadsOf, QueryData, QueryStyle, RecordLoader, Relationship, RenderedContent, SelectedData, VariantContext, VariantField, VariantOf, VariantValues };
|
|
137
|
+
export type { BodyLoader, BuiltinPayloads, CollectionDefinition, CollectionRegistry, CollectionSource, ComputedContext, ContentHeading, ContentRenderResult, DataEntry, DataStore, EntryFiles, FileEntry, FileEntrySource, FileSource, Loader, LoaderConfig, LoaderContext, LoaderLogger, LoaderSource, LoaderWatcher, MaybePromise, MetaStore, PayloadContext, PayloadData, PayloadDeclaration, PayloadDefinition, PayloadsOf, QueryData, QueryStyle, RecordLoader, Relationship, RenderedContent, SelectedData, VariantContext, VariantField, VariantOf, VariantRequest, VariantValues };
|
package/dist/internal.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { n as Collection, r as CollectionHandles, s as ContentError } from "./collection-types-
|
|
1
|
+
import { n as Collection, r as CollectionHandles, s as ContentError } from "./collection-types-BjSEeKN-.mjs";
|
|
2
2
|
import { n as ContentRenderResult } from "./types-Dh-Sydyw.mjs";
|
|
3
|
-
import { i as CollectionRegistry } from "./types-
|
|
4
|
-
import { O as QueryRegistry } from "./relational-types-
|
|
5
|
-
import { n as QueryStyle } from "./query-style-
|
|
6
|
-
import { n as PreparedRevision, t as ContentState } from "./revision-
|
|
3
|
+
import { i as CollectionRegistry } from "./types-B_p8k_g6.mjs";
|
|
4
|
+
import { O as QueryRegistry } from "./relational-types-Bh34u01H.mjs";
|
|
5
|
+
import { n as QueryStyle } from "./query-style-k8Qd7wh5.mjs";
|
|
6
|
+
import { n as PreparedRevision, t as ContentState } from "./revision-C7GpzihD.mjs";
|
|
7
7
|
//#region src/artifacts/types.d.ts
|
|
8
8
|
type ArtifactManifest = {
|
|
9
9
|
version: number;
|
package/dist/internal.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as ContentError } from "./errors-Bfd0R4_P.mjs";
|
|
2
2
|
import { r as decode } from "./values-BbTV4QT-.mjs";
|
|
3
|
-
import { i as isQueryStyle, n as createCollections, r as createLiveCollection, t as createCollection } from "./collection-
|
|
3
|
+
import { i as isQueryStyle, n as createCollections, r as createLiveCollection, t as createCollection } from "./collection-DYeLLOXP.mjs";
|
|
4
4
|
import { t as restoreContentError } from "./diagnostics-DmUZtrJ6.mjs";
|
|
5
5
|
//#region src/artifacts/runtime.ts
|
|
6
6
|
/** Checks that a value is a plain record before reading generated payload tables from it. */
|
package/dist/loaders.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as DataStore, c as Loader, d as LoaderLogger, f as LoaderSource, h as RecordLoader, i as DataEntry, l as LoaderConfig, m as MetaStore, n as GlobOptions, o as FileEntrySource, p as LoaderWatcher, r as BodyLoader, s as FileSource, t as FileOptions, u as LoaderContext } from "./descriptor-
|
|
1
|
+
import { a as DataStore, c as Loader, d as LoaderLogger, f as LoaderSource, h as RecordLoader, i as DataEntry, l as LoaderConfig, m as MetaStore, n as GlobOptions, o as FileEntrySource, p as LoaderWatcher, r as BodyLoader, s as FileSource, t as FileOptions, u as LoaderContext } from "./descriptor-BseHJvUB.mjs";
|
|
2
2
|
//#region src/loaders/file.d.ts
|
|
3
3
|
/** Declares a multi-entry data file with typed source paths and record keys, plus an optional parser. */
|
|
4
4
|
export declare function file(filename: string, options?: FileOptions): RecordLoader<FileEntrySource>;
|
package/dist/next.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as BuildContentOptions } from "./build-
|
|
1
|
+
import { t as BuildContentOptions } from "./build-MlsJ12d8.mjs";
|
|
2
2
|
import { NextConfig } from "next";
|
|
3
3
|
//#region src/integrations/next/plugin.d.ts
|
|
4
4
|
/** Content locations for Next.js; the adapter chooses generated storage and the watch lifecycle. */
|
package/dist/next.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { I as collectionNames } from "./operators-D-w1-gDg.mjs";
|
|
2
|
-
import { c as collectionDeclarations, i as resolveConfigPath, t as buildAtRoot } from "./build-
|
|
2
|
+
import { c as collectionDeclarations, i as resolveConfigPath, t as buildAtRoot } from "./build-CfxMqm_9.mjs";
|
|
3
3
|
import { n as serializeContentError } from "./diagnostics-DmUZtrJ6.mjs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { randomUUID } from "node:crypto";
|
|
@@ -7,7 +7,7 @@ type QueryStyle = "fluent" | "relational";
|
|
|
7
7
|
* belongs to both styles; `count(options)` takes relational options.
|
|
8
8
|
*/
|
|
9
9
|
declare const queryStyleMembers: {
|
|
10
|
-
readonly fluent: readonly ["select", "where", "orderBy", "limit", "offset", "with", "withPayload", "selectAdjacent"];
|
|
10
|
+
readonly fluent: readonly ["byId", "select", "where", "orderBy", "limit", "offset", "with", "withPayload", "selectAdjacent"];
|
|
11
11
|
readonly relational: readonly ["findMany", "findFirst", "paginate", "count(options)"];
|
|
12
12
|
};
|
|
13
13
|
/** A collection member that belongs to exactly one query style. */
|
package/dist/query.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as Selection, E as Expression, S as ScalarField, T as Where, _ as PaginateResult, a as RelationalQueryOptions, b as RelationField, c as Adjacent, d as Field, f as Fields, g as PaginateOptions, h as PageOptions, i as RelationalQueries, l as CursorOptions, m as Ordered, n as RelationalCountOptions, o as RelationalQueryResult, p as NumberedPage, r as RelationalPaginateOptions, s as RelationalWhere, u as CursorPage, w as SelectionResult, x as Scalar, y as QueryFields } from "./relational-types-
|
|
1
|
+
import { C as Selection, E as Expression, S as ScalarField, T as Where, _ as PaginateResult, a as RelationalQueryOptions, b as RelationField, c as Adjacent, d as Field, f as Fields, g as PaginateOptions, h as PageOptions, i as RelationalQueries, l as CursorOptions, m as Ordered, n as RelationalCountOptions, o as RelationalQueryResult, p as NumberedPage, r as RelationalPaginateOptions, s as RelationalWhere, u as CursorPage, w as SelectionResult, x as Scalar, y as QueryFields } from "./relational-types-Bh34u01H.mjs";
|
|
2
2
|
//#region src/query/operators.d.ts
|
|
3
3
|
/** Matches a scalar using strict value/date equality. */
|
|
4
4
|
export declare function eq<Value>(field: ScalarField<Value>, value: NoInfer<Value>): Expression;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as Unavailable } from "./descriptor-BseHJvUB.mjs";
|
|
2
|
+
import { C as UnavailableRelationshipsOf, D as VariantRequest, E as VariantOf, S as UnavailableRelationship, _ as Relationship, g as QueryData, h as PayloadsOf, i as CollectionRegistry, v as RelationshipsOf, x as SelectedData } from "./types-B_p8k_g6.mjs";
|
|
2
3
|
//#region src/query/plan.d.ts
|
|
3
4
|
type PredicateOperator = "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "in-array" | "not-in-array" | "contains" | "starts-with" | "ends-with" | "like" | "ilike" | "array-contains" | "array-contains-any" | "array-contains-all" | "array-contained" | "is-null" | "is-undefined" | "is-missing";
|
|
4
5
|
type Expression = {
|
|
@@ -67,9 +68,13 @@ type AdjacentPlan = {
|
|
|
67
68
|
scope: "results" | "collection";
|
|
68
69
|
plan: QueryPlan;
|
|
69
70
|
};
|
|
70
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* One requested payload; variant keys are empty for payloads without variants. `fallbacks` lists
|
|
73
|
+
* further combinations to try, in order, when the entry lacks `variant`.
|
|
74
|
+
*/
|
|
71
75
|
type PlanPayload = {
|
|
72
76
|
variant: Readonly<Record<string, string>>;
|
|
77
|
+
fallbacks?: readonly Readonly<Record<string, string>>[];
|
|
73
78
|
};
|
|
74
79
|
/** How a plan returns its results; `paginate` requires the plan's `paginate` request. */
|
|
75
80
|
type QueryTerminal = "all" | "first" | "count" | "paginate";
|
|
@@ -96,8 +101,6 @@ declare const PAGINATE_AFTER_LIMIT_MESSAGE: "paginate() sets the limit and offse
|
|
|
96
101
|
//#endregion
|
|
97
102
|
//#region src/query/types.d.ts
|
|
98
103
|
declare const queryType: unique symbol;
|
|
99
|
-
/** Running an unselected query reports the explicit-selection rule as its required `this` type. */
|
|
100
|
-
type UnselectedTerminal = (this: typeof NO_SELECTION_MESSAGE, ...arguments_: readonly unknown[]) => never;
|
|
101
104
|
/** A `then` that cannot resolve a value, so awaiting an unselected query fails to compile. */
|
|
102
105
|
type UnselectedThen = (selectBeforeAwaiting: typeof NO_SELECTION_MESSAGE) => never;
|
|
103
106
|
declare const fieldType: unique symbol;
|
|
@@ -127,12 +130,23 @@ type QueryInfo<Result = unknown, Selected extends boolean = boolean, Filtered ex
|
|
|
127
130
|
filtered: Filtered;
|
|
128
131
|
};
|
|
129
132
|
};
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
type
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Flattens an intersection into one object type, keeping each property's declaration. The
|
|
135
|
+
* conditional resolves to a mapped type that no alias owns, so TypeScript compares two rows by
|
|
136
|
+
* their properties instead of by the collection definitions in their type arguments. Comparing
|
|
137
|
+
* those definitions computes variances deep inside schema libraries such as Zod, which can exceed
|
|
138
|
+
* the instantiation limit when `Promise.all()` or `Awaited` infers a query's result.
|
|
139
|
+
*/
|
|
140
|
+
type Simplify$1<Value> = Value extends (infer Shape) ? { [Key in keyof Shape]: Shape[Key]; } : never;
|
|
141
|
+
/** One returned entry: the accumulated result, flattened, with its `_payloads` flattened too. */
|
|
142
|
+
type Row<Result> = Result extends (infer Shape) ? { [Key in keyof Shape]: Key extends "_payloads" ? Simplify$1<Shape[Key]> : Shape[Key]; } : never;
|
|
143
|
+
/**
|
|
144
|
+
* Adds one requested payload under `_payloads`. Intersecting with earlier requests merges their
|
|
145
|
+
* `_payloads` objects; {@link Row} flattens them when the query returns. Unlike `Omit`, this adds
|
|
146
|
+
* no type that later calls must re-evaluate, so long chains stay cheap to check.
|
|
147
|
+
*/
|
|
148
|
+
type WithPayload<Result, Key extends PropertyKey, Value> = Result & {
|
|
149
|
+
_payloads: { [Name in Key]: Value; };
|
|
136
150
|
};
|
|
137
151
|
type ResultOf<Configured> = Configured extends QueryInfo<infer Result> ? Result : never;
|
|
138
152
|
type FilteredOf<Configured> = Configured extends QueryInfo<unknown, boolean, infer Filtered> ? Filtered : false;
|
|
@@ -140,9 +154,10 @@ type RelationOf<Registry extends CollectionRegistry, Name extends keyof Registry
|
|
|
140
154
|
type RelatedName$1<Registry extends CollectionRegistry, Relation extends Relationship> = Relation["collection"] & keyof Registry & string;
|
|
141
155
|
/** Applies declared relationship cardinality, optional reference fields, and filtering to a result. */
|
|
142
156
|
type RelationshipResult<Definition, Relation extends Relationship, Result, Filtered extends boolean = false> = Relation["type"] extends "many" ? Result[] : Result | (Filtered extends true ? null : Relation["referenceSide"] extends "from" ? Relation["from"] extends keyof QueryData<Definition> ? null extends QueryData<Definition>[Relation["from"]] ? null : undefined extends QueryData<Definition>[Relation["from"]] ? null : never : null : null);
|
|
143
|
-
type RelationValue<Definition, Relation extends Relationship, Configured> = RelationshipResult<Definition, Relation, ResultOf<Configured
|
|
157
|
+
type RelationValue<Definition, Relation extends Relationship, Configured> = RelationshipResult<Definition, Relation, Row<ResultOf<Configured>>, FilteredOf<Configured>>;
|
|
144
158
|
type Query<Registry extends CollectionRegistry, Name extends keyof Registry & string, Result = {}, Selected extends boolean = false, Many extends boolean = true, Root extends boolean = true, Filtered extends boolean = false, AllowAdjacent extends boolean = true, Pagination extends boolean = true, Paged extends boolean = false> = QueryInfo<Result, Selected, Filtered> & {
|
|
145
|
-
|
|
159
|
+
/** Selects fields, adding to fields that earlier `select()` calls on this scope selected. */
|
|
160
|
+
select<const Keys extends readonly [keyof QueryData<Registry[Name]> & string, ...(keyof QueryData<Registry[Name]> & string)[]]>(...keys: Keys): Query<Registry, Name, Simplify$1<Result & SelectedData<QueryData<Registry[Name]>, Keys[number]>>, true, Many, Root, Filtered, AllowAdjacent, Pagination, Paged>;
|
|
146
161
|
where(configure: (fields: QueryFields<Registry, Name>) => Expression): Query<Registry, Name, Result, Selected, Many, Root, true, AllowAdjacent, Pagination, Paged>;
|
|
147
162
|
with<Key extends keyof RelationshipsOf<Registry[Name]> & string, Configured extends QueryInfo<unknown, true>>(name: Key, configure: (query: Query<Registry, RelatedName$1<Registry, RelationOf<Registry, Name, Key>>, {}, false, RelationOf<Registry, Name, Key>["type"] extends "many" ? true : false, false, false, AllowAdjacent>) => Configured): Query<Registry, Name, Result & { [Property in Key]: RelationValue<Registry[Name], RelationOf<Registry, Name, Key>, Configured>; }, true, Many, Root, Filtered, AllowAdjacent, Pagination, Paged>;
|
|
148
163
|
/** A relationship into a collection the query has not loaded reports which one to supply. */
|
|
@@ -152,36 +167,42 @@ type Query<Registry extends CollectionRegistry, Name extends keyof Registry & st
|
|
|
152
167
|
} : {}) & (Many extends true ? Pagination extends true ? {
|
|
153
168
|
limit(value: number): Query<Registry, Name, Result, Selected, Many, Root, Filtered, AllowAdjacent, Pagination, true>;
|
|
154
169
|
offset(value: number): Query<Registry, Name, Result, Selected, Many, Root, Filtered, AllowAdjacent, Pagination, true>;
|
|
155
|
-
} : {} : {}) & (AllowAdjacent extends true ? {
|
|
156
|
-
/** Attaches a payload under `_payloads` after filtering, ordering, and pagination. */
|
|
157
|
-
withPayload<Key extends keyof PayloadsOf<Registry[Name]> & string>(name: Key, ...variant: keyof VariantOf<Registry[Name], Key> extends never ? [] : [variant: Readonly<VariantOf<Registry[Name], Key>>]): Query<Registry, Name, WithPayload<Result, Key, PayloadsOf<Registry[Name]>[Key]>, true, Many, Root, Filtered, AllowAdjacent, Pagination, Paged>;
|
|
170
|
+
} : {} : {}) & (AllowAdjacent extends true ? [Root, Many] extends [true, false] ? {} : {
|
|
158
171
|
/** Selects neighbor fields within this scope's filtered and ordered results. */
|
|
159
172
|
selectAdjacent<const Keys extends readonly [keyof QueryData<Registry[Name]> & string, ...(keyof QueryData<Registry[Name]> & string)[]]>(...fields: Keys): Query<Registry, Name, Result & {
|
|
160
173
|
_adjacent: Adjacent<SelectedData<QueryData<Registry[Name]>, Keys[number]>>;
|
|
161
174
|
}, true, Many, Root, Filtered, AllowAdjacent, Pagination, Paged>;
|
|
175
|
+
} : {}) & (AllowAdjacent extends true ? {
|
|
176
|
+
/** Attaches a payload under `_payloads` after filtering, ordering, and pagination. */
|
|
177
|
+
withPayload<Key extends keyof PayloadsOf<Registry[Name]> & string>(name: Key, ...variant: keyof VariantOf<Registry[Name], Key> extends never ? [] : [variant: VariantRequest<VariantOf<Registry[Name], Key>>]): Query<Registry, Name, WithPayload<Result, Key, PayloadsOf<Registry[Name]>[Key]>, true, Many, Root, Filtered, AllowAdjacent, Pagination, Paged>;
|
|
178
|
+
/** Selects neighbors from an independent sibling scope. */
|
|
162
179
|
selectAdjacent<Configured extends QueryInfo<unknown, true>>(configure: (siblings: Query<Registry, Name, {}, false, true, false, false, false, false>) => Configured): Query<Registry, Name, Result & {
|
|
163
180
|
_adjacent: Adjacent<ResultOf<Configured>>;
|
|
164
181
|
}, true, Many, Root, Filtered, AllowAdjacent, Pagination, Paged>;
|
|
165
182
|
selectAdjacent<const Options extends AdjacentOptions<Registry, Name>>(options: Options & CheckedOptions<Registry, Name, NoInfer<Options>, true, false, false>): Query<Registry, Name, Result & {
|
|
166
183
|
_adjacent: Adjacent<SelectionResult<Registry, Name, Options["select"]>>;
|
|
167
184
|
}, true, Many, Root, Filtered, AllowAdjacent, Pagination, Paged>;
|
|
168
|
-
} : {}) & (Root extends true ? {
|
|
169
|
-
all: Selected extends true ? () => Promise<
|
|
170
|
-
execute: Selected extends true ? () => Promise<
|
|
171
|
-
then: Selected extends true ? Promise<
|
|
172
|
-
first: Selected extends true ? () => Promise<Simplify$1<Result> | undefined> : UnselectedTerminal;
|
|
173
|
-
/** Counts matching entries without a selection; unavailable once payloads are requested. */
|
|
174
|
-
count: [Result] extends [never] ? () => Promise<number> : [Result] extends [{
|
|
175
|
-
_payloads: unknown;
|
|
176
|
-
}] ? never : () => Promise<number>;
|
|
185
|
+
} : {}) & (Root extends true ? (Many extends true ? {
|
|
186
|
+
all: Selected extends true ? () => Promise<Row<Result>[]> : Unavailable<typeof NO_SELECTION_MESSAGE>;
|
|
187
|
+
execute: Selected extends true ? () => Promise<Row<Result>[]> : Unavailable<typeof NO_SELECTION_MESSAGE>;
|
|
188
|
+
then: Selected extends true ? Promise<Row<Result>[]>["then"] : UnselectedThen;
|
|
177
189
|
/**
|
|
178
190
|
* Returns one page from one revision: `{ page, size }` for page numbers, or
|
|
179
|
-
* `{ size, after?, before?, total? }` for cursors. Unavailable after `limit()` or
|
|
191
|
+
* `{ size, after?, before?, total? }` for cursors. Unavailable after `limit()` or
|
|
192
|
+
* `offset()`.
|
|
180
193
|
*/
|
|
181
|
-
paginate: Selected extends true ? [Paged] extends [true] ?
|
|
194
|
+
paginate: Selected extends true ? [Paged] extends [true] ? Unavailable<typeof PAGINATE_AFTER_LIMIT_MESSAGE> : Paginate<Row<Result>> : Unavailable<typeof NO_SELECTION_MESSAGE>;
|
|
195
|
+
} : {
|
|
196
|
+
/** Runs a `byId()` query, matching direct await: the entry, or `undefined`. */
|
|
197
|
+
execute: Selected extends true ? () => Promise<Row<Result> | undefined> : Unavailable<typeof NO_SELECTION_MESSAGE>;
|
|
198
|
+
then: Selected extends true ? Promise<Row<Result> | undefined>["then"] : UnselectedThen;
|
|
199
|
+
}) & {
|
|
200
|
+
first: Selected extends true ? () => Promise<Row<Result> | undefined> : Unavailable<typeof NO_SELECTION_MESSAGE>;
|
|
201
|
+
/** Counts matching entries without a selection; unavailable once payloads are requested. */
|
|
202
|
+
count: [Result] extends [never] ? () => Promise<number> : [Result] extends [{
|
|
203
|
+
_payloads: unknown;
|
|
204
|
+
}] ? Unavailable<"Counts cannot request payloads; count without withPayload()."> : () => Promise<number>;
|
|
182
205
|
} : {});
|
|
183
|
-
/** `paginate()` after `limit()` or `offset()` reports why as its required `this` type. */
|
|
184
|
-
type PaginateAfterLimit = (this: typeof PAGINATE_AFTER_LIMIT_MESSAGE, ...arguments_: readonly unknown[]) => never;
|
|
185
206
|
/** The `paginate()` overloads for one item type. */
|
|
186
207
|
type Paginate<Item> = {
|
|
187
208
|
(options: PageOptions): Promise<NumberedPage<Item>>;
|
|
@@ -364,12 +385,15 @@ type RelationalWhere<Registry extends CollectionRegistry, Name extends keyof Reg
|
|
|
364
385
|
NOT?: RelationalWhere<Registry, Name> | readonly RelationalWhere<Registry, Name>[];
|
|
365
386
|
RAW?: (fields: Fields<QueryData<Registry[Name]>>) => Expression;
|
|
366
387
|
};
|
|
367
|
-
/**
|
|
368
|
-
|
|
388
|
+
/**
|
|
389
|
+
* Requests one payload: `true` without variants, or a record giving every variant key a value or
|
|
390
|
+
* a nonempty list of values to try in order.
|
|
391
|
+
*/
|
|
392
|
+
type PayloadRequest<Variant> = keyof Variant extends never ? true : VariantRequest<Variant>;
|
|
369
393
|
/** Payloads to attach under `_payloads`; payloads set to false are omitted. */
|
|
370
394
|
type PayloadOptions<Registry extends CollectionRegistry, Name extends keyof Registry & string> = { [Key in keyof PayloadsOf<Registry[Name]>]?: false | PayloadRequest<VariantOf<Registry[Name], Key>>; };
|
|
371
395
|
/** Rejects variant keys a payload does not declare, including through inferred variables. */
|
|
372
|
-
type CheckedPayloadRequest<Request, Variant> = Request extends boolean ? Request : { [Key in keyof Request]: Key extends keyof Variant ? string : never; };
|
|
396
|
+
type CheckedPayloadRequest<Request, Variant> = Request extends boolean ? Request : { [Key in keyof Request]: Key extends keyof Variant ? string | readonly [string, ...string[]] : never; };
|
|
373
397
|
/**
|
|
374
398
|
* Collection-scoped metadata queries with Drizzle-style columns, relationships, and filters.
|
|
375
399
|
* Nothing is selected implicitly, not even `id`: list fields in `columns`, include relationships
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { s as ContentError } from "./collection-types-
|
|
1
|
+
import { s as ContentError } from "./collection-types-BjSEeKN-.mjs";
|
|
2
2
|
import { n as ContentRenderResult } from "./types-Dh-Sydyw.mjs";
|
|
3
|
-
import { _ as Relationship } from "./types-
|
|
4
|
-
import { D as QueryPlan, O as QueryRegistry, k as QueryTerminal } from "./relational-types-
|
|
5
|
-
import { n as QueryStyle } from "./query-style-
|
|
3
|
+
import { _ as Relationship } from "./types-B_p8k_g6.mjs";
|
|
4
|
+
import { D as QueryPlan, O as QueryRegistry, k as QueryTerminal } from "./relational-types-Bh34u01H.mjs";
|
|
5
|
+
import { n as QueryStyle } from "./query-style-k8Qd7wh5.mjs";
|
|
6
6
|
//#region src/runtime/revision.d.ts
|
|
7
7
|
type QueryRecord = Record<string, unknown> & {
|
|
8
8
|
id: string;
|
package/dist/runtime.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { c as ContentErrorCode, i as LoadedRegistry, n as Collection, o as ContentDiagnostic, r as CollectionHandles, s as ContentError, t as AnyCollection } from "./collection-types-
|
|
1
|
+
import { c as ContentErrorCode, i as LoadedRegistry, n as Collection, o as ContentDiagnostic, r as CollectionHandles, s as ContentError, t as AnyCollection } from "./collection-types-BjSEeKN-.mjs";
|
|
2
|
+
import { _ as Unavailable } from "./descriptor-BseHJvUB.mjs";
|
|
2
3
|
import { n as ContentRenderResult, t as ContentHeading } from "./types-Dh-Sydyw.mjs";
|
|
3
|
-
import { n as QueryStyle, r as QueryStyleDisabled } from "./query-style-
|
|
4
|
-
export { type AnyCollection, type Collection, type CollectionHandles, type ContentDiagnostic, ContentError, type ContentErrorCode, type ContentHeading, type ContentRenderResult, type LoadedRegistry, type QueryStyle, type QueryStyleDisabled };
|
|
4
|
+
import { n as QueryStyle, r as QueryStyleDisabled } from "./query-style-k8Qd7wh5.mjs";
|
|
5
|
+
export { type AnyCollection, type Collection, type CollectionHandles, type ContentDiagnostic, ContentError, type ContentErrorCode, type ContentHeading, type ContentRenderResult, type LoadedRegistry, type QueryStyle, type QueryStyleDisabled, type Unavailable };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as Loader, n as GlobOptions, t as FileOptions } from "./descriptor-
|
|
1
|
+
import { c as Loader, n as GlobOptions, t as FileOptions } from "./descriptor-BseHJvUB.mjs";
|
|
2
2
|
import { n as ContentRenderResult, r as RenderedContent } from "./types-Dh-Sydyw.mjs";
|
|
3
3
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
4
|
//#region src/collection/types.d.ts
|
|
@@ -227,5 +227,11 @@ type PayloadsOf<Definition> = (Definition extends {
|
|
|
227
227
|
type PayloadData<Definition, Name extends keyof PayloadsOf<Definition>> = PayloadsOf<Definition>[Name];
|
|
228
228
|
/** The variant keys a payload request must supply; empty for built-in and single-value payloads. */
|
|
229
229
|
type VariantOf<Definition, Name> = Name extends keyof CustomPayloadsOf<Definition> ? CustomPayloadsOf<Definition>[Name] extends CustomPayload<unknown, infer Variant> ? Variant : {} : {};
|
|
230
|
+
/**
|
|
231
|
+
* How a query requests a payload variant: each key gives one value, or a nonempty list of values
|
|
232
|
+
* to try in order, such as `{ locale: ["fr-FR", "en-US"] }`. The query returns the first
|
|
233
|
+
* combination the entry has; with lists for several keys, earlier keys change slowest.
|
|
234
|
+
*/
|
|
235
|
+
type VariantRequest<Variant> = { readonly [Key in keyof Variant]: Variant[Key] | readonly [Variant[Key], ...Variant[Key][]]; };
|
|
230
236
|
//#endregion
|
|
231
|
-
export { UnavailableRelationshipsOf as C,
|
|
237
|
+
export { UnavailableRelationshipsOf as C, VariantRequest as D, VariantOf as E, VariantValues as O, UnavailableRelationship as S, VariantField as T, Relationship as _, ComputedContext as a, SchemaOutput as b, EntryFiles as c, PayloadContext as d, PayloadData as f, QueryData as g, PayloadsOf as h, CollectionRegistry as i, FileEntry as l, PayloadDefinition as m, BuiltinPayloads as n, CustomPayload as o, PayloadDeclaration as p, CollectionDefinition as r, CustomPayloadMarker as s, BuiltinPayloadMarker as t, LoadedMarker as u, RelationshipsOf as v, VariantContext as w, SelectedData as x, Schema as y };
|
package/dist/vite.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ContentSourceEvent, o as ContentSourceSnapshot, t as BuildContentOptions } from "./build-
|
|
1
|
+
import { a as ContentSourceEvent, o as ContentSourceSnapshot, t as BuildContentOptions } from "./build-MlsJ12d8.mjs";
|
|
2
2
|
import { Plugin } from "vite";
|
|
3
3
|
//#region src/integrations/vite/plugin.d.ts
|
|
4
4
|
/** Public, format-neutral hooks for integrations sharing this plugin's preparation session. */
|
package/dist/vite.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { I as collectionNames } from "./operators-D-w1-gDg.mjs";
|
|
2
|
-
import { a as sessionInternals, i as resolveConfigPath, l as virtualDeclarations, o as withinDirectory, r as configCandidates, s as writeChanged, t as buildAtRoot, u as revisionModules } from "./build-
|
|
2
|
+
import { a as sessionInternals, i as resolveConfigPath, l as virtualDeclarations, o as withinDirectory, r as configCandidates, s as writeChanged, t as buildAtRoot, u as revisionModules } from "./build-CfxMqm_9.mjs";
|
|
3
3
|
import { n as serializeContentError } from "./diagnostics-DmUZtrJ6.mjs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import path from "node:path";
|
package/package.json
CHANGED