@capacms/sdk 1.0.0-next.1 → 1.0.0-next.10
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 +450 -0
- package/README.md +1698 -193
- package/bin/capa-codegen.js +192 -5
- package/bin/capa.js +235 -0
- package/bin/graphql-project.js +142 -0
- package/bin/project-env.js +58 -0
- package/dist/client.d.ts +5 -0
- package/dist/client.js +17 -0
- package/dist/codegen.d.ts +55 -0
- package/dist/codegen.js +320 -39
- package/dist/config.d.ts +5 -36
- package/dist/config.js +47 -1
- package/dist/esm/image/index.d.ts +120 -0
- package/dist/esm/image/index.js +250 -0
- package/dist/esm/image/shared-params.generated.d.ts +190 -0
- package/dist/esm/image/shared-params.generated.js +461 -0
- package/dist/esm/nextjs/image-loader.d.ts +60 -0
- package/dist/esm/nextjs/image-loader.js +67 -0
- package/dist/esm/nextjs/overlay.d.ts +30 -0
- package/dist/esm/nextjs/overlay.js +75 -0
- package/dist/esm/overlay/index.d.ts +32 -0
- package/dist/esm/overlay/index.js +576 -0
- package/dist/esm/overlay/protocol.d.ts +187 -0
- package/dist/esm/overlay/protocol.js +240 -0
- package/dist/esm/package.json +4 -0
- package/dist/graphql-codegen.d.ts +117 -0
- package/dist/graphql-codegen.js +705 -0
- package/dist/http.js +1 -1
- package/dist/image/index.d.ts +120 -0
- package/dist/image/index.js +257 -0
- package/dist/image/shared-params.generated.d.ts +190 -0
- package/dist/image/shared-params.generated.js +471 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -1
- package/dist/next/attrs.d.ts +84 -10
- package/dist/next/attrs.js +119 -2
- package/dist/next/client.d.ts +176 -32
- package/dist/next/client.js +212 -90
- package/dist/next/entry-fields.d.ts +162 -0
- package/dist/next/entry-fields.js +2 -0
- package/dist/next/errors.d.ts +136 -0
- package/dist/next/errors.js +214 -0
- package/dist/next/field-names.d.ts +37 -0
- package/dist/next/field-names.js +145 -0
- package/dist/next/graphql/build.d.ts +27 -0
- package/dist/next/graphql/build.js +98 -0
- package/dist/next/graphql/documents.d.ts +67 -0
- package/dist/next/graphql/documents.js +35 -0
- package/dist/next/graphql/edit-mode.d.ts +16 -0
- package/dist/next/graphql/edit-mode.js +93 -0
- package/dist/next/graphql/filter-values.d.ts +34 -0
- package/dist/next/graphql/filter-values.js +96 -0
- package/dist/next/graphql/introspection.d.ts +89 -0
- package/dist/next/graphql/introspection.js +102 -0
- package/dist/next/graphql/plan.d.ts +115 -0
- package/dist/next/graphql/plan.js +531 -0
- package/dist/next/graphql/request.d.ts +228 -0
- package/dist/next/graphql/request.js +283 -0
- package/dist/next/graphql/rest.d.ts +66 -0
- package/dist/next/graphql/rest.js +502 -0
- package/dist/next/graphql/selection.d.ts +55 -0
- package/dist/next/graphql/selection.js +212 -0
- package/dist/next/graphql/sha256.d.ts +13 -0
- package/dist/next/graphql/sha256.js +86 -0
- package/dist/next/graphql/summary.d.ts +83 -0
- package/dist/next/graphql/summary.js +151 -0
- package/dist/next/graphql/tree-layout.d.ts +36 -0
- package/dist/next/graphql/tree-layout.js +20 -0
- package/dist/next/graphql/tree.d.ts +171 -0
- package/dist/next/graphql/tree.js +249 -0
- package/dist/next/graphql/typed.d.ts +261 -0
- package/dist/next/graphql/typed.js +146 -0
- package/dist/next/index.d.ts +30 -5
- package/dist/next/index.js +32 -1
- package/dist/next/inflate.d.ts +51 -0
- package/dist/next/inflate.js +243 -0
- package/dist/next/key-family.d.ts +31 -0
- package/dist/next/key-family.js +66 -0
- package/dist/next/select-types.d.ts +58 -5
- package/dist/next/system-keys.d.ts +27 -0
- package/dist/next/system-keys.js +42 -0
- package/dist/nextjs/image-loader.d.ts +60 -0
- package/dist/nextjs/image-loader.js +71 -0
- package/dist/nextjs/index.d.ts +484 -5
- package/dist/nextjs/index.js +688 -6
- package/dist/nextjs/overlay.d.ts +30 -0
- package/dist/nextjs/overlay.js +78 -0
- package/dist/overlay/index.d.ts +14 -2
- package/dist/overlay/index.js +282 -43
- package/dist/overlay/protocol.d.ts +98 -2
- package/dist/overlay/protocol.js +151 -4
- package/package.json +63 -15
package/dist/next/attrs.js
CHANGED
|
@@ -1,8 +1,125 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CAPA_EDIT = void 0;
|
|
4
|
+
exports.isEditEntry = isEditEntry;
|
|
5
|
+
exports.markEditEntries = markEditEntries;
|
|
6
|
+
exports.markGraphQLEntries = markGraphQLEntries;
|
|
7
|
+
exports.hasGraphQLEntry = hasGraphQLEntry;
|
|
8
|
+
exports.carryEditMark = carryEditMark;
|
|
3
9
|
exports.capaAttrs = capaAttrs;
|
|
4
|
-
|
|
10
|
+
exports.fieldAttrs = fieldAttrs;
|
|
11
|
+
/** `Symbol.for`, so two copies of the SDK in one bundle agree on the mark. */
|
|
12
|
+
exports.CAPA_EDIT = Symbol.for("capacms.edit");
|
|
13
|
+
/** Whether an entry was read in edit mode. */
|
|
14
|
+
function isEditEntry(entry) {
|
|
15
|
+
return (typeof entry === "object" &&
|
|
16
|
+
entry !== null &&
|
|
17
|
+
entry[exports.CAPA_EDIT] === true);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Where a GraphQL node read in edit mode keeps the namespaces of the fields
|
|
21
|
+
* GraphQL renamed, by GraphQL name. Hidden like the mark itself.
|
|
22
|
+
*/
|
|
23
|
+
const CAPA_EDIT_NAMESPACES = Symbol.for("capacms.edit.namespaces");
|
|
24
|
+
/** A REST entry: an id beside `fields`. */
|
|
25
|
+
function looksLikeEntry(value) {
|
|
26
|
+
return typeof value.id === "string" && typeof value.fields === "object" && value.fields !== null;
|
|
27
|
+
}
|
|
28
|
+
/** A GraphQL entry: the `Entry` interface's `id` and `model`, which every model type has. */
|
|
29
|
+
function looksLikeGraphQLEntry(value) {
|
|
30
|
+
return typeof value.id === "string" && typeof value.model === "string";
|
|
31
|
+
}
|
|
32
|
+
/** Define a hidden property: absent from JSON, keys and spreads. */
|
|
33
|
+
function hide(record, key, value) {
|
|
34
|
+
Object.defineProperty(record, key, { value, enumerable: false, configurable: true });
|
|
35
|
+
}
|
|
36
|
+
/** Visit every plain object and array inside `value` once, cycles included. */
|
|
37
|
+
function eachObject(value, visit) {
|
|
38
|
+
const seen = new Set();
|
|
39
|
+
const walk = (node) => {
|
|
40
|
+
if (typeof node !== "object" || node === null || seen.has(node))
|
|
41
|
+
return;
|
|
42
|
+
seen.add(node);
|
|
43
|
+
if (Array.isArray(node)) {
|
|
44
|
+
for (const item of node)
|
|
45
|
+
walk(item);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const record = node;
|
|
49
|
+
visit(record);
|
|
50
|
+
for (const key of Object.keys(record))
|
|
51
|
+
walk(record[key]);
|
|
52
|
+
};
|
|
53
|
+
walk(value);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Mark every entry inside `value`, related entries included, so a click on an
|
|
57
|
+
* author inside an article opens the author. Walks arrays and plain objects,
|
|
58
|
+
* never the same object twice. Returns `value` for chaining.
|
|
59
|
+
*/
|
|
60
|
+
function markEditEntries(value) {
|
|
61
|
+
eachObject(value, (record) => {
|
|
62
|
+
if (looksLikeEntry(record) && Object.isExtensible(record))
|
|
63
|
+
hide(record, exports.CAPA_EDIT, true);
|
|
64
|
+
});
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Mark every entry inside a GraphQL result's `data`: each object that
|
|
69
|
+
* selected `id` and `model`, related entries included. `renamed(model)` gives
|
|
70
|
+
* that model's fields whose GraphQL name is not their namespace, by GraphQL
|
|
71
|
+
* name, so `capaAttrs` tags those by namespace. Returns `data`.
|
|
72
|
+
*/
|
|
73
|
+
function markGraphQLEntries(data, renamed = () => undefined) {
|
|
74
|
+
eachObject(data, (record) => {
|
|
75
|
+
if (!looksLikeGraphQLEntry(record) || !Object.isExtensible(record))
|
|
76
|
+
return;
|
|
77
|
+
hide(record, exports.CAPA_EDIT, true);
|
|
78
|
+
const namespaces = renamed(record.model);
|
|
79
|
+
if (namespaces)
|
|
80
|
+
hide(record, CAPA_EDIT_NAMESPACES, namespaces);
|
|
81
|
+
});
|
|
82
|
+
return data;
|
|
83
|
+
}
|
|
84
|
+
/** Whether a GraphQL result's `data` holds any entry `markGraphQLEntries` would mark. */
|
|
85
|
+
function hasGraphQLEntry(data) {
|
|
86
|
+
let found = false;
|
|
87
|
+
eachObject(data, (record) => {
|
|
88
|
+
found ||= looksLikeGraphQLEntry(record);
|
|
89
|
+
});
|
|
90
|
+
return found;
|
|
91
|
+
}
|
|
92
|
+
/** Keep `from`'s edit mark on `to`, for a copy of an entry in another shape (`toTree`). */
|
|
93
|
+
function carryEditMark(from, to) {
|
|
94
|
+
if (isEditEntry(from) && Object.isExtensible(to))
|
|
95
|
+
hide(to, exports.CAPA_EDIT, true);
|
|
96
|
+
return to;
|
|
97
|
+
}
|
|
98
|
+
/** The namespace a field of `entry` is tagged with: a renamed GraphQL field's own, else the name given. */
|
|
99
|
+
function namespaceOf(entry, field) {
|
|
100
|
+
const namespaces = entry[CAPA_EDIT_NAMESPACES];
|
|
101
|
+
return namespaces?.[field] ?? field;
|
|
102
|
+
}
|
|
103
|
+
function capaAttrs(entry, field, enabled = isEditEntry(entry)) {
|
|
5
104
|
if (!enabled)
|
|
6
105
|
return {};
|
|
7
|
-
return { "data-capa-entry": entry.id, "data-capa-field": field };
|
|
106
|
+
return { "data-capa-entry": entry.id, "data-capa-field": namespaceOf(entry, field) };
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Typed attributes for every field of one entry (M5), or of one GraphQL node:
|
|
110
|
+
*
|
|
111
|
+
* const a = fieldAttrs(article);
|
|
112
|
+
* <h1 {...a.title}>…</h1> // a.titel is a compile error
|
|
113
|
+
*
|
|
114
|
+
* Same rule as `capaAttrs`: empty unless the entry was read in edit mode, or
|
|
115
|
+
* `enabled` says otherwise.
|
|
116
|
+
*/
|
|
117
|
+
function fieldAttrs(entry, enabled = isEditEntry(entry)) {
|
|
118
|
+
return new Proxy({}, {
|
|
119
|
+
get(_target, key) {
|
|
120
|
+
if (typeof key !== "string")
|
|
121
|
+
return undefined;
|
|
122
|
+
return enabled ? { "data-capa-entry": entry.id, "data-capa-field": namespaceOf(entry, key) } : {};
|
|
123
|
+
},
|
|
124
|
+
});
|
|
8
125
|
}
|
package/dist/next/client.d.ts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CapaDocumentResult, CapaDocuments, CapaDocumentVariables, NotARecordedDocument } from "./graphql/documents";
|
|
2
|
+
import { type GraphQLCallOptions, type GraphQLResult, type TypedDocument, type VariablesThenOptions } from "./graphql/request";
|
|
3
|
+
import { type GraphQLSchemaSummary } from "./graphql/summary";
|
|
4
|
+
import { type ExactSelection, type QueryResult, type QuerySelection, type UntypedQuery } from "./graphql/typed";
|
|
5
|
+
export { CapaError, isCapaError } from "./errors";
|
|
6
|
+
import type { EntryFields, FlatFields, FlatRead, IncludedFields } from "./entry-fields";
|
|
7
|
+
import type { ExpandedTargets, Select } from "./select-types";
|
|
2
8
|
export interface CapaNextConfig {
|
|
3
9
|
baseUrl: string;
|
|
10
|
+
/**
|
|
11
|
+
* A `cap_` key, or the legacy key a site already holds: `pk_`, `sk_`, or
|
|
12
|
+
* an older key with no prefix. A legacy key reads through every read call,
|
|
13
|
+
* `preview()` included, and warns once per process; the draft clients of
|
|
14
|
+
* `@capacms/sdk/nextjs` take a `cap_` key only.
|
|
15
|
+
*/
|
|
4
16
|
apiKey: string;
|
|
5
17
|
version: string;
|
|
6
18
|
contract?: 1;
|
|
@@ -34,6 +46,23 @@ export interface CapaNextConfig {
|
|
|
34
46
|
* Config only, never per call: one build has one schema.
|
|
35
47
|
*/
|
|
36
48
|
schemaChecksum?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Read in edit mode: every entry this client returns carries the hidden edit
|
|
51
|
+
* mark, so `capaAttrs` tags it for the Capa editor. Leave it off for visitors
|
|
52
|
+
* and a published page ships no entry ids. `@capacms/sdk/nextjs` works it out
|
|
53
|
+
* per request with `editMode()`.
|
|
54
|
+
*
|
|
55
|
+
* The same request is sent either way. A GraphQL read marks each object
|
|
56
|
+
* that selected `id` and `model`, and to tag a field GraphQL renamed by its
|
|
57
|
+
* namespace, it also reads the key's schema, once a minute.
|
|
58
|
+
*/
|
|
59
|
+
editMode?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* The concrete path being rendered (`/blog/hello`), sent as `Capa-Path`
|
|
62
|
+
* beside `Capa-Page` (`/blog/[slug]`). Telemetry only, like `page`: it is how
|
|
63
|
+
* Capa lists every real URL an entry appears on. Usually set per call.
|
|
64
|
+
*/
|
|
65
|
+
path?: string;
|
|
37
66
|
/** Injected for tests, non-standard runtimes, and framework fetch wrappers. */
|
|
38
67
|
fetch?: typeof fetch;
|
|
39
68
|
}
|
|
@@ -53,7 +82,18 @@ export interface CallOptions {
|
|
|
53
82
|
* writing the code.
|
|
54
83
|
*/
|
|
55
84
|
page?: string;
|
|
85
|
+
/**
|
|
86
|
+
* The concrete path THIS read renders (`/blog/hello`). Overrides `path` on the
|
|
87
|
+
* config. Sent as `Capa-Path` only alongside a `Capa-Page`, since a path with
|
|
88
|
+
* no page says nothing Capa can group.
|
|
89
|
+
*/
|
|
90
|
+
path?: string;
|
|
56
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* One entry as `/api/entries` returns it: the system keys, and `fields`. A read
|
|
94
|
+
* types `fields` from its model and select (`EntryFields`), so a relation is a
|
|
95
|
+
* reference or the related entry, and a relation list is `{ items, pageInfo }`.
|
|
96
|
+
*/
|
|
57
97
|
export interface Entry<T = Record<string, unknown>> {
|
|
58
98
|
id: string;
|
|
59
99
|
model: string;
|
|
@@ -97,29 +137,80 @@ export type FilterOperator = "eq" | "ne" | "in" | "nin" | "lt" | "lte" | "gt" |
|
|
|
97
137
|
export type FilterScalar = string | number | boolean | null;
|
|
98
138
|
export type FilterValue = FilterScalar | readonly FilterScalar[];
|
|
99
139
|
export type Filter = Record<string, Partial<Record<FilterOperator, FilterValue>>>;
|
|
100
|
-
|
|
101
|
-
|
|
140
|
+
/**
|
|
141
|
+
* How expanded relations come back (`?shape=`). `tree`, the default, nests each
|
|
142
|
+
* one inline where it was selected. `flat` answers every relation as a
|
|
143
|
+
* `{ id, model }` reference and every expanded entry ONCE, in `included`, so
|
|
144
|
+
* twenty articles by one author carry that author once. `inflate(result)`
|
|
145
|
+
* turns a flat result back into the tree one.
|
|
146
|
+
*/
|
|
147
|
+
export type ResponseShape = "tree" | "flat";
|
|
148
|
+
export interface ListOptions<T = Record<string, unknown>, S extends Select<T> | string = Select<T> | string> extends CallOptions {
|
|
149
|
+
select?: S;
|
|
150
|
+
shape?: "tree";
|
|
102
151
|
filter?: Filter;
|
|
103
152
|
where?: Record<string, unknown>;
|
|
104
153
|
sort?: readonly string[];
|
|
105
154
|
limit?: number;
|
|
106
155
|
count?: boolean;
|
|
156
|
+
/** `page.next`: the page after it. */
|
|
107
157
|
after?: string;
|
|
158
|
+
/** `page.prev`: the page before it. Or `"end"`: the last `limit` entries of the list. */
|
|
108
159
|
before?: string;
|
|
109
160
|
}
|
|
110
|
-
export interface GetOptions<T = Record<string, unknown
|
|
111
|
-
select?:
|
|
161
|
+
export interface GetOptions<T = Record<string, unknown>, S extends Select<T> | string = Select<T> | string> extends CallOptions {
|
|
162
|
+
select?: S;
|
|
163
|
+
shape?: "tree";
|
|
164
|
+
}
|
|
165
|
+
/** `list` with `shape: "flat"`. `S` is the select, which types `included`. */
|
|
166
|
+
export type FlatListOptions<T, S extends Select<T> | string = Select<T>> = Omit<ListOptions<T>, "select" | "shape"> & {
|
|
167
|
+
select?: S;
|
|
168
|
+
shape: "flat";
|
|
169
|
+
};
|
|
170
|
+
/** `get` with `shape: "flat"`. */
|
|
171
|
+
export type FlatGetOptions<T, S extends Select<T> | string = Select<T>> = Omit<GetOptions<T>, "select" | "shape"> & {
|
|
172
|
+
select?: S;
|
|
173
|
+
shape: "flat";
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* `included` of a flat read: model namespace, then entry id, then the entry.
|
|
177
|
+
* Typed by the select: the union of every entry type it expands, each field
|
|
178
|
+
* of which may be absent, and every relation in it a reference.
|
|
179
|
+
*/
|
|
180
|
+
export type Included<I> = Record<string, Record<string, Entry<IncludedFields<I>>>>;
|
|
181
|
+
interface FlatExtras<T, S> extends FlatRead<T, S> {
|
|
182
|
+
included: Included<[ExpandedTargets<T, S>] extends [never] ? never : ExpandedTargets<T, S>>;
|
|
183
|
+
/** The select this read sent, which is what `inflate` walks. Absent when none was sent. */
|
|
184
|
+
select?: string;
|
|
112
185
|
}
|
|
186
|
+
/** A `shape=flat` list: every relation in `data` a reference, each expanded entry once in `included`. */
|
|
187
|
+
export type FlatPage<T, S = Select<T>> = Page<Entry<FlatFields<T, S>>> & FlatExtras<T, S>;
|
|
188
|
+
export type FlatSingle<T, S = Select<T>> = Single<Entry<FlatFields<T, S>>> & FlatExtras<T, S>;
|
|
189
|
+
/**
|
|
190
|
+
* `T` as given, never inferred from the options: a read's model type is
|
|
191
|
+
* written (`list<Article>`), and without one the read is untyped whatever its
|
|
192
|
+
* select names. Inferred from a select's names, `T` would be `{ title: any }`,
|
|
193
|
+
* which refuses the relations the same select expands.
|
|
194
|
+
*/
|
|
195
|
+
type Given<T> = [T][T extends unknown ? 0 : never];
|
|
196
|
+
/**
|
|
197
|
+
* Reads of `/api/entries`. `T` is the model type (`list<Articles>`), and `S`
|
|
198
|
+
* the select's own type, for `fields` typed exactly as the read returns them
|
|
199
|
+
* (`list<Articles, typeof select>`); see `EntryFields`.
|
|
200
|
+
*/
|
|
113
201
|
export interface EntriesResource {
|
|
114
|
-
list<T = Record<string, unknown>>(namespace: string, options
|
|
115
|
-
|
|
116
|
-
|
|
202
|
+
list<T = Record<string, unknown>, S extends Select<T> | string = Select<T>>(namespace: string, options: FlatListOptions<Given<T>, S>): Promise<FlatPage<T, S>>;
|
|
203
|
+
list<T = Record<string, unknown>, S extends Select<T> | string = Select<T> | string>(namespace: string, options?: ListOptions<Given<T>, S>): Promise<Page<Entry<EntryFields<T, S>>>>;
|
|
204
|
+
get<T = Record<string, unknown>, S extends Select<T> | string = Select<T>>(namespace: string, id: string, options: FlatGetOptions<Given<T>, S>): Promise<FlatSingle<T, S> | null>;
|
|
205
|
+
get<T = Record<string, unknown>, S extends Select<T> | string = Select<T> | string>(namespace: string, id: string, options?: GetOptions<Given<T>, S>): Promise<Single<Entry<EntryFields<T, S>>> | null>;
|
|
206
|
+
/** Tree only: it yields entries one at a time, which is what `included` exists to avoid. */
|
|
207
|
+
iterate<T = Record<string, unknown>, S extends Select<T> | string = Select<T> | string>(namespace: string, options?: ListOptions<Given<T>, S>): AsyncGenerator<Entry<EntryFields<T, S>>, void, undefined>;
|
|
117
208
|
}
|
|
118
209
|
/**
|
|
119
210
|
* One suggestion drawn from a page's own reads.
|
|
120
211
|
*
|
|
121
212
|
* Computed on the API, never here. Three clients want this answer (this SDK,
|
|
122
|
-
* the Capa admin and `@
|
|
213
|
+
* the Capa admin and `@capacms/mcp`), and a second implementation of "this page
|
|
123
214
|
* over-fetches" would drift from the first the moment a threshold moved.
|
|
124
215
|
*/
|
|
125
216
|
export interface PageInsight {
|
|
@@ -252,7 +343,56 @@ export interface PreviewClaim {
|
|
|
252
343
|
path: string | null;
|
|
253
344
|
expiresAt: string;
|
|
254
345
|
}
|
|
255
|
-
|
|
346
|
+
/**
|
|
347
|
+
* `client.graphql`: run a document, or build one from a typed selection with
|
|
348
|
+
* `client.graphql.query()`. `Q` is the `CapaQuery` type `capa-codegen
|
|
349
|
+
* --graphql` writes; without it selections and results are untyped. `O` is
|
|
350
|
+
* what a call takes: `getCapaClient` from `/nextjs` adds Next's cache `tags`
|
|
351
|
+
* and `revalidate`.
|
|
352
|
+
*/
|
|
353
|
+
export interface GraphQLClient<Q = UntypedQuery, O extends GraphQLCallOptions = GraphQLCallOptions> {
|
|
354
|
+
/**
|
|
355
|
+
* Run a document written as a literal (`#graphql`, `/* capa *\/` or
|
|
356
|
+
* gql(`...`)) that `capa-codegen --graphql` has checked: its text is looked
|
|
357
|
+
* up in `CapaDocuments`, so `data` and `variables` are typed with no cast.
|
|
358
|
+
*
|
|
359
|
+
* Resolves once the API ran the document, even when `errors` is not empty,
|
|
360
|
+
* because the root fields that worked still carry data. Throws `CapaError`
|
|
361
|
+
* when the API refused the request as a whole, with `graphqlErrors` holding
|
|
362
|
+
* every error it sent: `errors` and no `data`, whether sent as a 4xx or, as
|
|
363
|
+
* GraphQL over HTTP sends it on `application/json`, as a 200.
|
|
364
|
+
*/
|
|
365
|
+
<D extends keyof CapaDocuments>(document: D, ...rest: VariablesThenOptions<CapaDocumentVariables<D>, O>): Promise<GraphQLResult<CapaDocumentResult<D>>>;
|
|
366
|
+
/**
|
|
367
|
+
* Run a GraphQL document. A `<Name>Document` from `capa-codegen --graphql`
|
|
368
|
+
* types `data` and `variables` by itself; for any other string, pass the
|
|
369
|
+
* data type: `capa.graphql<{ articles: ... }>(query, variables)`.
|
|
370
|
+
*/
|
|
371
|
+
<TData = Record<string, unknown>, TVariables = Record<string, unknown>, D extends string = string>(document: NotARecordedDocument<D, TypedDocument<TData, TVariables> | D>, ...rest: VariablesThenOptions<TVariables, O>): Promise<GraphQLResult<TData>>;
|
|
372
|
+
/**
|
|
373
|
+
* Build the document from a selection object and run it. See "Typed
|
|
374
|
+
* builder" in the README. It takes no `persisted`: see `BuilderCallOptions`.
|
|
375
|
+
*/
|
|
376
|
+
query<const S extends QuerySelection<Q>>(selection: S & ExactSelection<S, Q>, options?: BuilderCallOptions<O>): Promise<GraphQLResult<QueryResult<Q, S>>>;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* What `graphql.query()` takes: a call's options without `persisted`. The
|
|
380
|
+
* builder prints its document when it runs, so `capa persist`, which stores
|
|
381
|
+
* the documents written in a project, never stored it, and a production key
|
|
382
|
+
* never registers one: every read would miss its hash and fall back to a POST,
|
|
383
|
+
* which is never cached. Unpersisted, a builder read is already a GET the API
|
|
384
|
+
* and the CDN cache. To persist a read, write it as a `#graphql` literal.
|
|
385
|
+
*/
|
|
386
|
+
export type BuilderCallOptions<O extends GraphQLCallOptions = GraphQLCallOptions> = Omit<O, "persisted">;
|
|
387
|
+
/**
|
|
388
|
+
* `client.graphql` over one way of reading a document: called with a
|
|
389
|
+
* document, and `query()` printing a selection's document for it. `createClient`
|
|
390
|
+
* reads straight from the API, and `getCapaClient` from `/nextjs` the same way
|
|
391
|
+
* unless a call gives `tags` or `revalidate`, then through Next's data cache,
|
|
392
|
+
* with the same refusals.
|
|
393
|
+
*/
|
|
394
|
+
export declare function graphqlClient<Q, O extends GraphQLCallOptions>(read: (document: string, variables: Record<string, unknown> | undefined, options: O | undefined) => Promise<GraphQLResult<unknown>>): GraphQLClient<Q, O>;
|
|
395
|
+
export interface CapaNextClient<Q = UntypedQuery, O extends GraphQLCallOptions = GraphQLCallOptions> {
|
|
256
396
|
entries: EntriesResource;
|
|
257
397
|
pages: PagesResource;
|
|
258
398
|
/**
|
|
@@ -261,34 +401,38 @@ export interface CapaNextClient {
|
|
|
261
401
|
* Returns the claim, or NULL when the token is invalid or expired, because
|
|
262
402
|
* both mean the same thing to a preview route: do not enable draft mode.
|
|
263
403
|
* Every other failure throws, so a Capa outage does not look like a bad link.
|
|
404
|
+
* Takes any key the site holds, a legacy `pk_`, `sk_` or unprefixed key
|
|
405
|
+
* included: Capa answers a token minted for another tenant as invalid.
|
|
264
406
|
*/
|
|
265
407
|
preview(token: string, options?: CallOptions): Promise<PreviewClaim | null>;
|
|
266
408
|
me<T = Record<string, unknown>>(options?: CallOptions): Promise<T>;
|
|
267
409
|
versions<T = Record<string, unknown>>(options?: CallOptions): Promise<T>;
|
|
410
|
+
graphql: GraphQLClient<Q, O>;
|
|
411
|
+
/**
|
|
412
|
+
* Every model this key can read over GraphQL, with its root fields, fields,
|
|
413
|
+
* filter operators and sort values, read from one introspection request.
|
|
414
|
+
* What `buildGraphQLQuery`, `graphqlToSelect` and `toTree` take.
|
|
415
|
+
*/
|
|
416
|
+
graphqlSchema(options?: {
|
|
417
|
+
signal?: AbortSignal;
|
|
418
|
+
}): Promise<GraphQLSchemaSummary<Q>>;
|
|
268
419
|
}
|
|
269
|
-
export declare class CapaError extends Error {
|
|
270
|
-
readonly status: number;
|
|
271
|
-
readonly type: string;
|
|
272
|
-
readonly code: string;
|
|
273
|
-
readonly param?: string;
|
|
274
|
-
readonly hint?: string;
|
|
275
|
-
readonly requestId: string;
|
|
276
|
-
readonly docs: string;
|
|
277
|
-
constructor(input: {
|
|
278
|
-
status: number;
|
|
279
|
-
type: string;
|
|
280
|
-
code: string;
|
|
281
|
-
message: string;
|
|
282
|
-
param?: string;
|
|
283
|
-
hint?: string;
|
|
284
|
-
requestId: string;
|
|
285
|
-
docs: string;
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
export declare function isCapaError(error: unknown): error is CapaError;
|
|
289
420
|
export declare function resolveNextConfig(config: CapaNextConfig): ResolvedNextConfig;
|
|
421
|
+
/**
|
|
422
|
+
* The page a layout (or template) reads for: none.
|
|
423
|
+
*
|
|
424
|
+
* A root layout renders around every page on the site, so charging its reads
|
|
425
|
+
* to `/`, the route its file sits at, made the home page look as if it read
|
|
426
|
+
* every Site singleton and nav on the site. `routeOf` returns this for a
|
|
427
|
+
* `layout.*` or `template.*` file, and a read that names it sends NO
|
|
428
|
+
* `Capa-Page` at all, even when the client was built with a `page`.
|
|
429
|
+
*
|
|
430
|
+
* Not sent as a value, because the API would drop it anyway: it is not a
|
|
431
|
+
* `PAGE_ID`, and the API ignores what it cannot store. Staying absent keeps a
|
|
432
|
+
* layout read byte-identical to one from a client that never named a page.
|
|
433
|
+
*/
|
|
434
|
+
export declare const LAYOUT_PAGE = "(layout)";
|
|
290
435
|
type SelectInput = string | ReadonlyArray<unknown>;
|
|
291
436
|
/** Serialize the SDK object form into the canonical `/api/entries` grammar. */
|
|
292
437
|
export declare function serializeSelect(select: SelectInput): string;
|
|
293
|
-
export declare function createClient(config: CapaNextConfig): CapaNextClient
|
|
294
|
-
export {};
|
|
438
|
+
export declare function createClient<Q = UntypedQuery>(config: CapaNextConfig): CapaNextClient<Q>;
|