@capacms/sdk 1.0.0-next.3 → 1.0.0-next.6
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 +323 -0
- package/README.md +1163 -186
- package/bin/capa-codegen.js +192 -5
- package/bin/capa.js +208 -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 -1
- package/dist/graphql-codegen.d.ts +117 -0
- package/dist/graphql-codegen.js +705 -0
- package/dist/http.js +1 -1
- 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 +160 -31
- package/dist/next/client.js +178 -89
- 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 +29 -4
- package/dist/next/index.js +31 -1
- package/dist/next/inflate.d.ts +51 -0
- package/dist/next/inflate.js +243 -0
- package/dist/next/key-family.d.ts +34 -0
- package/dist/next/key-family.js +74 -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/index.d.ts +333 -6
- package/dist/nextjs/index.js +450 -4
- package/dist/nextjs/overlay.d.ts +5 -0
- package/dist/nextjs/overlay.js +35 -0
- package/package.json +35 -13
package/dist/nextjs/index.d.ts
CHANGED
|
@@ -1,20 +1,54 @@
|
|
|
1
|
-
import { LAYOUT_PAGE, type CapaNextClient, type CapaNextConfig, type PagesResource, type PreviewClaim } from "../next";
|
|
1
|
+
import { gql, LAYOUT_PAGE, type CapaDocumentResult, type CapaDocuments, type CapaDocumentVariables, type CapaNextClient, type CapaNextConfig, type GraphQLCallOptions, type GraphQLResult, type NotARecordedDocument, type PagesResource, type PreviewClaim, type TypedDocument, type UntypedQuery, type VariablesThenOptions } from "../next";
|
|
2
2
|
export interface CacheOptions {
|
|
3
3
|
tags?: string[];
|
|
4
4
|
revalidate?: number | false;
|
|
5
5
|
}
|
|
6
6
|
/** Add Next.js fetch-cache options without importing `next/*`. */
|
|
7
7
|
export declare function withCache(fetchImpl: typeof fetch, options: CacheOptions): typeof fetch;
|
|
8
|
+
/**
|
|
9
|
+
* The Next.js cache tag for every read of a model, by its namespace. A GraphQL
|
|
10
|
+
* query names its models by namespace (`articles`), not by id, so this is the
|
|
11
|
+
* tag a GraphQL read is cached under, and `revalidateFromWebhook` revalidates
|
|
12
|
+
* it when an entry of that model changes.
|
|
13
|
+
*/
|
|
14
|
+
export declare function modelTag(namespace: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* The tag `graphql()` gives a read that names no `tags`, and that
|
|
17
|
+
* `revalidateFromWebhook` revalidates on every content change: such a page is
|
|
18
|
+
* never stale after a publish, at the price of refreshing on any publish.
|
|
19
|
+
* Name the models it reads with `tagsFor({ namespace })` to refresh it only
|
|
20
|
+
* when one of those changes.
|
|
21
|
+
*/
|
|
22
|
+
export declare const GRAPHQL_TAG = "capa:graphql";
|
|
23
|
+
/**
|
|
24
|
+
* The tag `tagsFor({ namespace })` adds beside its model tags, and that
|
|
25
|
+
* `revalidateFromWebhook` revalidates on a media event: a GraphQL read shows
|
|
26
|
+
* a file's URL and alt text whichever models it names, so editing a file in
|
|
27
|
+
* the media library refreshes it.
|
|
28
|
+
*/
|
|
29
|
+
export declare const MEDIA_TAG = "capa:media";
|
|
30
|
+
/**
|
|
31
|
+
* Next.js cache tags for a read. `model`, `entry`, `key` and `tenant` are the
|
|
32
|
+
* API's surrogate keys (`m:`, `e:`, `k:`, `t:`), by id; `namespace` is one
|
|
33
|
+
* `capa:model:<namespace>` tag per model a GraphQL query reads, which
|
|
34
|
+
* `capa-codegen --graphql` lists as `<Name>Models`, and `MEDIA_TAG`, since
|
|
35
|
+
* the query may show a file from the media library. Each pairs with
|
|
36
|
+
* `revalidateFromWebhook`.
|
|
37
|
+
*/
|
|
8
38
|
export declare function tagsFor(input: {
|
|
9
39
|
model?: string;
|
|
10
40
|
entry?: string;
|
|
11
41
|
key?: string;
|
|
12
42
|
tenant?: string;
|
|
43
|
+
namespace?: string | readonly string[];
|
|
13
44
|
}): string[];
|
|
14
45
|
export interface WebhookPayload {
|
|
46
|
+
type?: unknown;
|
|
15
47
|
data?: {
|
|
16
48
|
instanceId?: unknown;
|
|
17
49
|
modelId?: unknown;
|
|
50
|
+
modelNamespace?: unknown;
|
|
51
|
+
namespace?: unknown;
|
|
18
52
|
[key: string]: unknown;
|
|
19
53
|
};
|
|
20
54
|
instanceId?: unknown;
|
|
@@ -22,17 +56,34 @@ export interface WebhookPayload {
|
|
|
22
56
|
modelId?: unknown;
|
|
23
57
|
[key: string]: unknown;
|
|
24
58
|
}
|
|
25
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* Revalidate every tag a webhook's entry and model can be cached under: the
|
|
61
|
+
* entry (`e:`), the model by id (`m:`) and by namespace (`capa:model:`, the
|
|
62
|
+
* tag a GraphQL read uses). The namespace is `data.modelNamespace` on
|
|
63
|
+
* `instance.published`, `instance.unpublished` and `model.published`, and
|
|
64
|
+
* `data.namespace` on the other events (docs/WEBHOOKS.md). Any of those, and
|
|
65
|
+
* a `media.` event, also revalidates `GRAPHQL_TAG`, the tag of a `graphql()`
|
|
66
|
+
* read that named no tags. A `media.` event (a file's alt text, name or
|
|
67
|
+
* visibility changed, or the file went) revalidates the file's own key
|
|
68
|
+
* (`f:<fileId>`, as REST's `Surrogate-Key` names it) and `MEDIA_TAG`, which
|
|
69
|
+
* every read tagged by namespace carries, since it may show that file.
|
|
70
|
+
*/
|
|
26
71
|
export declare function revalidateFromWebhook(input: {
|
|
27
72
|
payload: WebhookPayload;
|
|
28
73
|
revalidateTag: (tag: string) => void | Promise<void>;
|
|
29
74
|
}): Promise<string[]>;
|
|
30
|
-
/**
|
|
31
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Select a client using server-only draft state supplied by the caller. Pass
|
|
77
|
+
* codegen's `CapaQuery` to type the builder, as with `createClient`:
|
|
78
|
+
* `draftClient<CapaQuery>({ ... })`. `production` may hold the legacy key a
|
|
79
|
+
* site already has; `draft` needs a `cap_` key, and a legacy one throws a
|
|
80
|
+
* `TypeError` when draft mode selects it.
|
|
81
|
+
*/
|
|
82
|
+
export declare function draftClient<Q = UntypedQuery>(input: {
|
|
32
83
|
production: CapaNextConfig;
|
|
33
84
|
draft: CapaNextConfig;
|
|
34
85
|
isDraft: () => boolean | Promise<boolean>;
|
|
35
|
-
}): Promise<CapaNextClient
|
|
86
|
+
}): Promise<CapaNextClient<Q>>;
|
|
36
87
|
export declare function routeOf(file: string): string;
|
|
37
88
|
/**
|
|
38
89
|
* Verify a preview token from a Next route handler.
|
|
@@ -50,5 +101,281 @@ export declare function preview(token: string, client: CapaNextClient): Promise<
|
|
|
50
101
|
* this and never hold the whole client.
|
|
51
102
|
*/
|
|
52
103
|
export declare function pagesFor(client: CapaNextClient): PagesResource;
|
|
53
|
-
export { LAYOUT_PAGE };
|
|
104
|
+
export { gql, LAYOUT_PAGE };
|
|
54
105
|
export type { PreviewClaim };
|
|
106
|
+
/**
|
|
107
|
+
* The query parameter that turns edit mode on for one request without draft
|
|
108
|
+
* content: `?capa-edit=<token>`, where the token is a Capa preview token. The
|
|
109
|
+
* Capa editor's Published view sends it so the published page is still
|
|
110
|
+
* clickable. It never switches the site to draft data.
|
|
111
|
+
*/
|
|
112
|
+
export declare const EDIT_PARAM = "capa-edit";
|
|
113
|
+
/**
|
|
114
|
+
* The request header `resolveEditRequest` sets once a `capa-edit` token has
|
|
115
|
+
* been verified, for `editMode()` to read. Any copy a browser sent is removed
|
|
116
|
+
* first, so it cannot be forged from outside.
|
|
117
|
+
*/
|
|
118
|
+
export declare const EDIT_HEADER = "x-capa-edit";
|
|
119
|
+
/** The cookie Next's `draftMode().enable()` sets. */
|
|
120
|
+
export declare const DRAFT_COOKIE = "__prerender_bypass";
|
|
121
|
+
/** What every edit-mode response must send: never cached, never shared. */
|
|
122
|
+
export declare const EDIT_CACHE_CONTROL = "private, no-store";
|
|
123
|
+
interface HeaderReader {
|
|
124
|
+
get(name: string): string | null;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Whether this request renders in edit mode: Next draft mode is on, or the
|
|
128
|
+
* request carried a verified `capa-edit` token (see `resolveEditRequest`).
|
|
129
|
+
*
|
|
130
|
+
* Pass Next's own functions; this package imports nothing from `next`:
|
|
131
|
+
*
|
|
132
|
+
* import { draftMode, headers } from "next/headers";
|
|
133
|
+
* const edit = await editMode({ draftMode, headers });
|
|
134
|
+
* const client = createClient({ ...config, editMode: edit });
|
|
135
|
+
*
|
|
136
|
+
* A client built with `editMode: edit` marks what it reads, and `capaAttrs`
|
|
137
|
+
* then tags those entries and only those.
|
|
138
|
+
*/
|
|
139
|
+
export declare function editMode(input: {
|
|
140
|
+
draftMode: () => {
|
|
141
|
+
isEnabled: boolean;
|
|
142
|
+
} | Promise<{
|
|
143
|
+
isEnabled: boolean;
|
|
144
|
+
}>;
|
|
145
|
+
headers: () => HeaderReader | Promise<HeaderReader>;
|
|
146
|
+
}): Promise<boolean>;
|
|
147
|
+
export interface EditRequest {
|
|
148
|
+
/** True when the page must render in edit mode. */
|
|
149
|
+
edit: boolean;
|
|
150
|
+
/** True when a `capa-edit` token was presented and Capa accepted it. */
|
|
151
|
+
verified: boolean;
|
|
152
|
+
/**
|
|
153
|
+
* The request headers to forward: `x-capa-edit` removed, then set to `1`
|
|
154
|
+
* when the token verified. Hand them to `NextResponse.next({ request: { headers } })`.
|
|
155
|
+
*/
|
|
156
|
+
headers: Headers;
|
|
157
|
+
/** `EDIT_CACHE_CONTROL` in edit mode, otherwise null. Set it on the response. */
|
|
158
|
+
cacheControl: string | null;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* The middleware half of edit mode.
|
|
162
|
+
*
|
|
163
|
+
* export async function middleware(request: NextRequest) {
|
|
164
|
+
* const edit = await resolveEditRequest(request, publishedClient());
|
|
165
|
+
* const response = NextResponse.next({ request: { headers: edit.headers } });
|
|
166
|
+
* if (edit.cacheControl) response.headers.set("Cache-Control", edit.cacheControl);
|
|
167
|
+
* return response;
|
|
168
|
+
* }
|
|
169
|
+
*
|
|
170
|
+
* The token is checked with Capa (`client.preview`), exactly as a preview link
|
|
171
|
+
* is: the site never holds the signing key. A bad, expired or unverifiable
|
|
172
|
+
* token means not in edit mode; it never throws, because a broken edit link
|
|
173
|
+
* must still render the public page.
|
|
174
|
+
*/
|
|
175
|
+
export declare function resolveEditRequest(request: {
|
|
176
|
+
url: string | URL;
|
|
177
|
+
headers: Headers;
|
|
178
|
+
cookies?: {
|
|
179
|
+
has(name: string): boolean;
|
|
180
|
+
};
|
|
181
|
+
}, client: Pick<CapaNextClient, "preview">): Promise<EditRequest>;
|
|
182
|
+
/**
|
|
183
|
+
* Where the env-driven helpers read their settings (M6): the one pair of
|
|
184
|
+
* names the whole product uses (the MCP server, `capa-codegen`, `capa
|
|
185
|
+
* persist`, every curl example in the API docs).
|
|
186
|
+
*/
|
|
187
|
+
export declare const CAPA_ENV: {
|
|
188
|
+
readonly baseUrl: "CAPA_API_URL";
|
|
189
|
+
readonly apiKey: "CAPA_KEY";
|
|
190
|
+
readonly draftKey: "CAPA_DRAFT_KEY";
|
|
191
|
+
readonly version: "CAPA_API_VERSION";
|
|
192
|
+
};
|
|
193
|
+
/** Older names that still work, read only when the name above is unset. */
|
|
194
|
+
export declare const CAPA_ENV_ALIASES: Readonly<Record<string, string>>;
|
|
195
|
+
export declare const DEFAULT_API_VERSION = "2026-10-01";
|
|
196
|
+
type DraftModeFn = () => {
|
|
197
|
+
isEnabled: boolean;
|
|
198
|
+
enable?: () => void;
|
|
199
|
+
disable?: () => void;
|
|
200
|
+
} | Promise<{
|
|
201
|
+
isEnabled: boolean;
|
|
202
|
+
enable?: () => void;
|
|
203
|
+
disable?: () => void;
|
|
204
|
+
}>;
|
|
205
|
+
/**
|
|
206
|
+
* The published-key client from env: what verifying a token needs. `overrides`
|
|
207
|
+
* win over env, and pass codegen's `CapaQuery` to type the builder:
|
|
208
|
+
* `getPublishedClient<CapaQuery>()`.
|
|
209
|
+
*/
|
|
210
|
+
export declare function getPublishedClient<Q = UntypedQuery>(overrides?: Partial<CapaNextConfig>): CapaNextClient<Q>;
|
|
211
|
+
/**
|
|
212
|
+
* The client for this request, from env: the draft key under draft mode,
|
|
213
|
+
* otherwise the published key, and `editMode` worked out for you.
|
|
214
|
+
*
|
|
215
|
+
* import { draftMode, headers } from "next/headers";
|
|
216
|
+
* const capa = await getCapaClient<CapaQuery>({ draftMode, headers });
|
|
217
|
+
* const { data } = await capa.graphql.query(selection, { tags: tagsFor({ namespace: "articles" }) });
|
|
218
|
+
*
|
|
219
|
+
* `CapaQuery` (from `capa-codegen --graphql`) types the builder, as with
|
|
220
|
+
* `createClient`; leave it out for an untyped client. `config` wins over env.
|
|
221
|
+
*
|
|
222
|
+
* Its GraphQL reads, a document or the builder, are kept in Next's data cache
|
|
223
|
+
* exactly as `graphql()` keeps them, each under the `tags` and `revalidate`
|
|
224
|
+
* it is called with: a published read with no errors, never a draft or an
|
|
225
|
+
* edit-mode page. Its REST reads are sent as `createClient` sends them.
|
|
226
|
+
*/
|
|
227
|
+
export declare function getCapaClient<Q = UntypedQuery>(input: {
|
|
228
|
+
draftMode: DraftModeFn;
|
|
229
|
+
headers: () => HeaderReader | Promise<HeaderReader>;
|
|
230
|
+
config?: Partial<CapaNextConfig>;
|
|
231
|
+
/** Next's `unstable_cache`, as `graphql()` takes it. Leave it out: Next's own is loaded. */
|
|
232
|
+
unstable_cache?: UnstableCache;
|
|
233
|
+
}): Promise<CapaNextClient<Q, NextCacheOptions>>;
|
|
234
|
+
/** Where a GraphQL read in Next keeps its answer: Next's data cache, as `graphql()` and `getCapaClient` keep it. */
|
|
235
|
+
export interface NextCacheOptions extends GraphQLCallOptions {
|
|
236
|
+
/**
|
|
237
|
+
* Next.js cache tags for this read. `tagsFor({ namespace: <Name>Models })`,
|
|
238
|
+
* with the list `capa-codegen --graphql` writes beside each document, tags
|
|
239
|
+
* it with every model the query reads, which `revalidateFromWebhook`
|
|
240
|
+
* revalidates on a publish. Without tags the read is tagged `GRAPHQL_TAG`,
|
|
241
|
+
* which every publish revalidates.
|
|
242
|
+
*/
|
|
243
|
+
tags?: string[];
|
|
244
|
+
/** Seconds to cache, or `false` to cache until a tag is revalidated. */
|
|
245
|
+
revalidate?: number | false;
|
|
246
|
+
}
|
|
247
|
+
export interface NextGraphQLOptions extends NextCacheOptions {
|
|
248
|
+
/**
|
|
249
|
+
* Next's `draftMode` and `headers`, to work out draft and edit mode as
|
|
250
|
+
* `getCapaClient` does: drafts under draft mode, and in edit mode every
|
|
251
|
+
* entry the query reads marked for `capaAttrs`.
|
|
252
|
+
*/
|
|
253
|
+
draftMode?: DraftModeFn;
|
|
254
|
+
headers?: () => HeaderReader | Promise<HeaderReader>;
|
|
255
|
+
/**
|
|
256
|
+
* Read drafts with `CAPA_DRAFT_KEY`, uncached. Worked out from `draftMode`
|
|
257
|
+
* when that is passed; set it to decide yourself.
|
|
258
|
+
*/
|
|
259
|
+
draft?: boolean;
|
|
260
|
+
/** Overrides for the env-derived client (base URL, key, version, edit mode, fetch). Each one given is not read from env. */
|
|
261
|
+
config?: Partial<CapaNextConfig>;
|
|
262
|
+
/**
|
|
263
|
+
* Next's `unstable_cache`, from `next/cache`. Leave it out: `graphql()`
|
|
264
|
+
* loads Next's own. A published read is kept in Next's data cache only when
|
|
265
|
+
* it answered with no `errors`, under `tags` for `revalidate` seconds, or
|
|
266
|
+
* with no `revalidate` until one of its tags is revalidated. Next's fetch
|
|
267
|
+
* cache is not used for it: that cache keeps any 200, and a GraphQL error
|
|
268
|
+
* is a 200 (a root field that timed out), and in Next 15 it keeps nothing
|
|
269
|
+
* without a `revalidate`, tags or not. Pass it only to supply another.
|
|
270
|
+
*/
|
|
271
|
+
unstable_cache?: UnstableCache;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Next's `unstable_cache` (`import { unstable_cache } from "next/cache"`),
|
|
275
|
+
* typed here so this package never imports `next/*`.
|
|
276
|
+
*/
|
|
277
|
+
export type UnstableCache = <T extends (...args: any[]) => Promise<any>>(cb: T, keyParts?: string[], options?: {
|
|
278
|
+
revalidate?: number | false;
|
|
279
|
+
tags?: string[];
|
|
280
|
+
}) => T;
|
|
281
|
+
/**
|
|
282
|
+
* GraphQL in a server component, one line, from env:
|
|
283
|
+
*
|
|
284
|
+
* import { draftMode, headers } from "next/headers";
|
|
285
|
+
* import { graphql, tagsFor } from "@capacms/sdk/nextjs";
|
|
286
|
+
* import { LatestModels } from "./capa-graphql";
|
|
287
|
+
* const LATEST = `#graphql
|
|
288
|
+
* query Latest($first: Int) { articles(first: $first) { nodes { id model title } } }
|
|
289
|
+
* `;
|
|
290
|
+
* const { data } = await graphql(LATEST, { first: 5 }, { draftMode, headers, tags: tagsFor({ namespace: LatestModels }) });
|
|
291
|
+
*
|
|
292
|
+
* Once `capa-codegen --graphql` has seen the literal, `data` and the
|
|
293
|
+
* variables are typed from it, as they are for a `<Name>Document` it writes,
|
|
294
|
+
* and `LatestModels` lists the models it reads.
|
|
295
|
+
*
|
|
296
|
+
* A published read is kept in Next's data cache (`unstable_cache`) when it
|
|
297
|
+
* answered with no errors: under `tags`, for `revalidate` seconds, or with no
|
|
298
|
+
* `revalidate` until `revalidateFromWebhook` revalidates one of its tags on a
|
|
299
|
+
* publish. It goes as a GET, which the CDN and the API also cache for the
|
|
300
|
+
* published key; a document too long for a GET URL goes as a POST, which only
|
|
301
|
+
* Next's data cache keeps. Under draft mode the read uses `CAPA_DRAFT_KEY`, a
|
|
302
|
+
* `cap_` key, and bypasses the cache (the API answers a development key's GET
|
|
303
|
+
* `no-store`), the same split `getCapaClient` makes for REST, and in edit mode
|
|
304
|
+
* each entry that selects `id` and `model` is marked for `capaAttrs`, uncached.
|
|
305
|
+
* Outside a Next request (a script, a test) the read is simply sent.
|
|
306
|
+
*
|
|
307
|
+
* `persisted: true` sends only the hash, and pays off once the documents are
|
|
308
|
+
* stored with `capa persist`, which takes a development key: a production
|
|
309
|
+
* key never stores one. Until then a
|
|
310
|
+
* hash misses, and the client remembers the miss for five minutes and sends
|
|
311
|
+
* the document by POST meanwhile, so it costs one extra GET per five minutes.
|
|
312
|
+
*/
|
|
313
|
+
export declare function graphql<D extends keyof CapaDocuments>(document: D, ...rest: VariablesThenOptions<CapaDocumentVariables<D>, NextGraphQLOptions>): Promise<GraphQLResult<CapaDocumentResult<D>>>;
|
|
314
|
+
export declare function graphql<TData = Record<string, unknown>, TVariables = Record<string, unknown>, D extends string = string>(document: NotARecordedDocument<D, TypedDocument<TData, TVariables> | D>, ...rest: VariablesThenOptions<TVariables, NextGraphQLOptions>): Promise<GraphQLResult<TData>>;
|
|
315
|
+
/** Only a path on this site: never `//elsewhere.example` or a full URL. */
|
|
316
|
+
export declare function safeSitePath(value: string | null | undefined): string;
|
|
317
|
+
/**
|
|
318
|
+
* `app/api/capa/preview/route.ts`:
|
|
319
|
+
*
|
|
320
|
+
* import { draftMode } from "next/headers";
|
|
321
|
+
* import { redirect } from "next/navigation";
|
|
322
|
+
* export const GET = createPreviewRoute({ draftMode, redirect });
|
|
323
|
+
*
|
|
324
|
+
* Checks the token with Capa (the site never holds the signing key), turns
|
|
325
|
+
* draft mode on and lands on the entry's page. A bad or expired token lands on
|
|
326
|
+
* the page without draft mode and `?preview=expired`; Capa unreachable gives
|
|
327
|
+
* `?preview=unavailable`.
|
|
328
|
+
*/
|
|
329
|
+
export declare function createPreviewRoute(input: {
|
|
330
|
+
draftMode: DraftModeFn;
|
|
331
|
+
redirect: (url: string) => never | void;
|
|
332
|
+
client?: () => Pick<CapaNextClient, "preview">;
|
|
333
|
+
/** Runs after draft mode is enabled, before the redirect (cookie tweaks). */
|
|
334
|
+
onEnable?: () => void | Promise<void>;
|
|
335
|
+
}): (request: Request) => Promise<Response | void>;
|
|
336
|
+
/** `app/api/capa/exit/route.ts`: `export const GET = exitPreviewRoute({ draftMode, redirect });` */
|
|
337
|
+
export declare function exitPreviewRoute(input: {
|
|
338
|
+
draftMode: DraftModeFn;
|
|
339
|
+
redirect: (url: string) => never | void;
|
|
340
|
+
}): (request: Request) => Promise<Response | void>;
|
|
341
|
+
interface MiddlewareRequest {
|
|
342
|
+
url: string;
|
|
343
|
+
headers: Headers;
|
|
344
|
+
nextUrl: URL & {
|
|
345
|
+
clone(): URL;
|
|
346
|
+
};
|
|
347
|
+
cookies: {
|
|
348
|
+
getAll(): Array<{
|
|
349
|
+
name: string;
|
|
350
|
+
value: string;
|
|
351
|
+
}>;
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
interface NextResponseLike {
|
|
355
|
+
next(init?: {
|
|
356
|
+
request?: {
|
|
357
|
+
headers?: Headers;
|
|
358
|
+
};
|
|
359
|
+
}): {
|
|
360
|
+
headers: Headers;
|
|
361
|
+
};
|
|
362
|
+
rewrite(url: URL): unknown;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* `middleware.ts` in one line:
|
|
366
|
+
*
|
|
367
|
+
* import { NextResponse } from "next/server";
|
|
368
|
+
* export const middleware = capaMiddleware({ NextResponse });
|
|
369
|
+
*
|
|
370
|
+
* - `?capa-preview=<token>` on any page goes to `previewRoute`, which turns
|
|
371
|
+
* draft mode on and comes back;
|
|
372
|
+
* - `?capa-view=published` renders without the draft cookie, for the editor's
|
|
373
|
+
* Published view;
|
|
374
|
+
* - `?capa-edit=<token>` turns edit mode on (ids and overlay, published data);
|
|
375
|
+
* - every edit-mode response is `private, no-store`.
|
|
376
|
+
*/
|
|
377
|
+
export declare function capaMiddleware(input: {
|
|
378
|
+
NextResponse: NextResponseLike;
|
|
379
|
+
previewRoute?: string;
|
|
380
|
+
client?: () => Pick<CapaNextClient, "preview">;
|
|
381
|
+
}): (request: MiddlewareRequest) => Promise<unknown>;
|