prismic 0.0.0-pr.28.59bf330
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/LICENSE +202 -0
- package/README.md +69 -0
- package/dist/builders-hKD4IrLX-DsO7BUQw.mjs +97 -0
- package/dist/dist-B11B2hHn.mjs +1 -0
- package/dist/dist-DT8CtumB.mjs +1 -0
- package/dist/framework-CfjEoVk0.mjs +17 -0
- package/dist/index.mjs +2537 -0
- package/dist/nextjs-9z7YrSnS.mjs +312 -0
- package/dist/nuxt-KoJ61G2q.mjs +59 -0
- package/dist/sveltekit-DjXKCG78.mjs +226 -0
- package/package.json +58 -0
- package/src/codegen-types.ts +82 -0
- package/src/codegen.ts +45 -0
- package/src/custom-type-add-field-boolean.ts +185 -0
- package/src/custom-type-add-field-color.ts +168 -0
- package/src/custom-type-add-field-date.ts +171 -0
- package/src/custom-type-add-field-embed.ts +168 -0
- package/src/custom-type-add-field-geo-point.ts +165 -0
- package/src/custom-type-add-field-group.ts +142 -0
- package/src/custom-type-add-field-image.ts +168 -0
- package/src/custom-type-add-field-key-text.ts +168 -0
- package/src/custom-type-add-field-link.ts +191 -0
- package/src/custom-type-add-field-number.ts +200 -0
- package/src/custom-type-add-field-rich-text.ts +192 -0
- package/src/custom-type-add-field-select.ts +174 -0
- package/src/custom-type-add-field-timestamp.ts +171 -0
- package/src/custom-type-add-field-uid.ts +151 -0
- package/src/custom-type-add-field.ts +116 -0
- package/src/custom-type-connect-slice.ts +178 -0
- package/src/custom-type-create.ts +98 -0
- package/src/custom-type-disconnect-slice.ts +134 -0
- package/src/custom-type-list.ts +110 -0
- package/src/custom-type-remove-field.ts +135 -0
- package/src/custom-type-remove.ts +103 -0
- package/src/custom-type-set-name.ts +102 -0
- package/src/custom-type-view.ts +118 -0
- package/src/custom-type.ts +85 -0
- package/src/docs-fetch.ts +146 -0
- package/src/docs-list.ts +131 -0
- package/src/docs.ts +54 -0
- package/src/env.d.ts +12 -0
- package/src/framework/index.ts +399 -0
- package/src/framework/nextjs.templates.ts +426 -0
- package/src/framework/nextjs.ts +216 -0
- package/src/framework/nuxt.templates.ts +74 -0
- package/src/framework/nuxt.ts +250 -0
- package/src/framework/sveltekit.templates.ts +278 -0
- package/src/framework/sveltekit.ts +241 -0
- package/src/index.ts +155 -0
- package/src/init.ts +173 -0
- package/src/lib/auth.ts +200 -0
- package/src/lib/browser.ts +11 -0
- package/src/lib/config.ts +111 -0
- package/src/lib/custom-types-api.ts +385 -0
- package/src/lib/field-path.ts +81 -0
- package/src/lib/file.ts +49 -0
- package/src/lib/json.ts +3 -0
- package/src/lib/packageJson.ts +35 -0
- package/src/lib/profile.ts +39 -0
- package/src/lib/request.ts +116 -0
- package/src/lib/segment.ts +145 -0
- package/src/lib/sentry.ts +63 -0
- package/src/lib/string.ts +10 -0
- package/src/lib/url.ts +31 -0
- package/src/locale-add.ts +116 -0
- package/src/locale-list.ts +107 -0
- package/src/locale-remove.ts +88 -0
- package/src/locale-set-default.ts +131 -0
- package/src/locale.ts +60 -0
- package/src/login.ts +45 -0
- package/src/logout.ts +36 -0
- package/src/page-type-add-field-boolean.ts +179 -0
- package/src/page-type-add-field-color.ts +165 -0
- package/src/page-type-add-field-date.ts +168 -0
- package/src/page-type-add-field-embed.ts +165 -0
- package/src/page-type-add-field-geo-point.ts +162 -0
- package/src/page-type-add-field-group.ts +139 -0
- package/src/page-type-add-field-image.ts +165 -0
- package/src/page-type-add-field-key-text.ts +165 -0
- package/src/page-type-add-field-link.ts +188 -0
- package/src/page-type-add-field-number.ts +197 -0
- package/src/page-type-add-field-rich-text.ts +189 -0
- package/src/page-type-add-field-select.ts +171 -0
- package/src/page-type-add-field-timestamp.ts +168 -0
- package/src/page-type-add-field-uid.ts +148 -0
- package/src/page-type-add-field.ts +116 -0
- package/src/page-type-connect-slice.ts +178 -0
- package/src/page-type-create.ts +128 -0
- package/src/page-type-disconnect-slice.ts +134 -0
- package/src/page-type-list.ts +109 -0
- package/src/page-type-remove-field.ts +135 -0
- package/src/page-type-remove.ts +103 -0
- package/src/page-type-set-name.ts +102 -0
- package/src/page-type-set-repeatable.ts +111 -0
- package/src/page-type-view.ts +118 -0
- package/src/page-type.ts +90 -0
- package/src/preview-add.ts +126 -0
- package/src/preview-get-simulator.ts +104 -0
- package/src/preview-list.ts +106 -0
- package/src/preview-remove-simulator.ts +80 -0
- package/src/preview-remove.ts +109 -0
- package/src/preview-set-name.ts +137 -0
- package/src/preview-set-simulator.ts +116 -0
- package/src/preview.ts +75 -0
- package/src/pull.ts +236 -0
- package/src/push.ts +409 -0
- package/src/repo-create.ts +175 -0
- package/src/repo-get-access.ts +86 -0
- package/src/repo-list.ts +100 -0
- package/src/repo-set-access.ts +100 -0
- package/src/repo-set-name.ts +102 -0
- package/src/repo-view.ts +113 -0
- package/src/repo.ts +70 -0
- package/src/slice-add-field-boolean.ts +219 -0
- package/src/slice-add-field-color.ts +205 -0
- package/src/slice-add-field-date.ts +205 -0
- package/src/slice-add-field-embed.ts +205 -0
- package/src/slice-add-field-geo-point.ts +202 -0
- package/src/slice-add-field-group.ts +170 -0
- package/src/slice-add-field-image.ts +202 -0
- package/src/slice-add-field-key-text.ts +205 -0
- package/src/slice-add-field-link.ts +224 -0
- package/src/slice-add-field-number.ts +205 -0
- package/src/slice-add-field-rich-text.ts +229 -0
- package/src/slice-add-field-select.ts +211 -0
- package/src/slice-add-field-timestamp.ts +205 -0
- package/src/slice-add-field.ts +111 -0
- package/src/slice-add-variation.ts +142 -0
- package/src/slice-create.ts +164 -0
- package/src/slice-list-variations.ts +71 -0
- package/src/slice-list.ts +60 -0
- package/src/slice-remove-field.ts +125 -0
- package/src/slice-remove-variation.ts +113 -0
- package/src/slice-remove.ts +92 -0
- package/src/slice-rename.ts +104 -0
- package/src/slice-set-screenshot.ts +239 -0
- package/src/slice-view.ts +83 -0
- package/src/slice.ts +95 -0
- package/src/status.ts +834 -0
- package/src/sync.ts +259 -0
- package/src/token-create.ts +203 -0
- package/src/token-delete.ts +182 -0
- package/src/token-list.ts +223 -0
- package/src/token-set-name.ts +193 -0
- package/src/token.ts +60 -0
- package/src/webhook-add-header.ts +118 -0
- package/src/webhook-create.ts +152 -0
- package/src/webhook-disable.ts +109 -0
- package/src/webhook-enable.ts +132 -0
- package/src/webhook-list.ts +93 -0
- package/src/webhook-remove-header.ts +117 -0
- package/src/webhook-remove.ts +106 -0
- package/src/webhook-set-triggers.ts +148 -0
- package/src/webhook-status.ts +90 -0
- package/src/webhook-test.ts +106 -0
- package/src/webhook-view.ts +147 -0
- package/src/webhook.ts +95 -0
- package/src/whoami.ts +62 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
import { pascalCase } from "change-case";
|
|
2
|
+
|
|
3
|
+
import { dedent } from "../lib/string";
|
|
4
|
+
|
|
5
|
+
const SLICE_MARKUP = dedent`
|
|
6
|
+
return (
|
|
7
|
+
<section
|
|
8
|
+
data-slice-type={slice.slice_type}
|
|
9
|
+
data-slice-variation={slice.variation}
|
|
10
|
+
>
|
|
11
|
+
Placeholder component for {slice.slice_type} (variation: {slice.variation}) slices.
|
|
12
|
+
<br />
|
|
13
|
+
<strong>You can edit this slice directly in your code editor.</strong>
|
|
14
|
+
</section>
|
|
15
|
+
)
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export function sliceTemplate(args: { name: string; typescript: boolean }): string {
|
|
19
|
+
const { name, typescript } = args;
|
|
20
|
+
|
|
21
|
+
const pascalName = pascalCase(name);
|
|
22
|
+
|
|
23
|
+
const TS = dedent`
|
|
24
|
+
import { FC } from "react";
|
|
25
|
+
import { Content } from "@prismicio/client";
|
|
26
|
+
import { SliceComponentProps } from "@prismicio/react";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Props for \`${pascalName}\`.
|
|
30
|
+
*/
|
|
31
|
+
export type ${pascalName}Props = SliceComponentProps<Content.${pascalName}Slice>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Component for "${name}" Slices.
|
|
35
|
+
*/
|
|
36
|
+
const ${pascalName}: FC<${pascalName}Props> = ({ slice }) => {
|
|
37
|
+
${SLICE_MARKUP}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default ${pascalName}
|
|
41
|
+
`;
|
|
42
|
+
|
|
43
|
+
const JS = dedent`
|
|
44
|
+
/**
|
|
45
|
+
* @typedef {import("@prismicio/client").Content.${pascalName}Slice} ${pascalName}Slice
|
|
46
|
+
* @typedef {import("@prismicio/react").SliceComponentProps<${pascalName}Slice>} ${pascalName}Props
|
|
47
|
+
* @type {import("react").FC<${pascalName}Props>}
|
|
48
|
+
*/
|
|
49
|
+
const ${pascalName} = ({ slice }) => {
|
|
50
|
+
${SLICE_MARKUP}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default ${pascalName};
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
return typescript ? TS : JS;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function prismicIOFileTemplate(args: {
|
|
60
|
+
typescript: boolean;
|
|
61
|
+
appRouter: boolean;
|
|
62
|
+
hasSrcDirectory: boolean;
|
|
63
|
+
}): string {
|
|
64
|
+
const { typescript, appRouter, hasSrcDirectory } = args;
|
|
65
|
+
const configImportPath = `${hasSrcDirectory ? ".." : "."}/prismic.config.json`;
|
|
66
|
+
|
|
67
|
+
let importsContents: string;
|
|
68
|
+
let createClientContents: string;
|
|
69
|
+
|
|
70
|
+
if (appRouter) {
|
|
71
|
+
if (typescript) {
|
|
72
|
+
importsContents = dedent`
|
|
73
|
+
import {
|
|
74
|
+
createClient as baseCreateClient,
|
|
75
|
+
type ClientConfig,
|
|
76
|
+
type Route,
|
|
77
|
+
} from "@prismicio/client";
|
|
78
|
+
import { enableAutoPreviews } from "@prismicio/next";
|
|
79
|
+
import prismicConfig from "${configImportPath}";
|
|
80
|
+
`;
|
|
81
|
+
|
|
82
|
+
createClientContents = dedent`
|
|
83
|
+
/**
|
|
84
|
+
* Creates a Prismic client for the project's repository. The client is used to
|
|
85
|
+
* query content from the Prismic API.
|
|
86
|
+
*
|
|
87
|
+
* @param config - Configuration for the Prismic client.
|
|
88
|
+
*/
|
|
89
|
+
export const createClient = (config: ClientConfig = {}) => {
|
|
90
|
+
const client = baseCreateClient(repositoryName, {
|
|
91
|
+
routes,
|
|
92
|
+
fetchOptions:
|
|
93
|
+
process.env.NODE_ENV === 'production'
|
|
94
|
+
? { next: { tags: ['prismic'] }, cache: 'force-cache' }
|
|
95
|
+
: { next: { revalidate: 5 } },
|
|
96
|
+
...config,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
enableAutoPreviews({ client });
|
|
100
|
+
|
|
101
|
+
return client;
|
|
102
|
+
};
|
|
103
|
+
`;
|
|
104
|
+
} else {
|
|
105
|
+
importsContents = dedent`
|
|
106
|
+
import { createClient as baseCreateClient } from "@prismicio/client";
|
|
107
|
+
import { enableAutoPreviews } from "@prismicio/next";
|
|
108
|
+
import prismicConfig from "${configImportPath}";
|
|
109
|
+
`;
|
|
110
|
+
|
|
111
|
+
createClientContents = dedent`
|
|
112
|
+
/**
|
|
113
|
+
* Creates a Prismic client for the project's repository. The client is used to
|
|
114
|
+
* query content from the Prismic API.
|
|
115
|
+
*
|
|
116
|
+
* @param {import("@prismicio/client").ClientConfig} config - Configuration for the Prismic client.
|
|
117
|
+
*/
|
|
118
|
+
export const createClient = (config = {}) => {
|
|
119
|
+
const client = baseCreateClient(repositoryName, {
|
|
120
|
+
routes,
|
|
121
|
+
fetchOptions:
|
|
122
|
+
process.env.NODE_ENV === 'production'
|
|
123
|
+
? { next: { tags: ['prismic'] }, cache: 'force-cache' }
|
|
124
|
+
: { next: { revalidate: 5 } },
|
|
125
|
+
...config,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
enableAutoPreviews({ client });
|
|
129
|
+
|
|
130
|
+
return client;
|
|
131
|
+
};
|
|
132
|
+
`;
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
if (typescript) {
|
|
136
|
+
importsContents = dedent`
|
|
137
|
+
import { createClient as baseCreateClient, type Routes } from "@prismicio/client";
|
|
138
|
+
import { enableAutoPreviews, type CreateClientConfig } from "@prismicio/next/pages";
|
|
139
|
+
import prismicConfig from "${configImportPath}";
|
|
140
|
+
`;
|
|
141
|
+
|
|
142
|
+
createClientContents = dedent`
|
|
143
|
+
/**
|
|
144
|
+
* Creates a Prismic client for the project's repository. The client is used to
|
|
145
|
+
* query content from the Prismic API.
|
|
146
|
+
*
|
|
147
|
+
* @param config - Configuration for the Prismic client.
|
|
148
|
+
*/
|
|
149
|
+
export const createClient = ({ previewData, req, ...config }: CreateClientConfig = {}) => {
|
|
150
|
+
const client = baseCreateClient(repositoryName, {
|
|
151
|
+
routes,
|
|
152
|
+
...config,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
enableAutoPreviews({ client, previewData, req });
|
|
156
|
+
|
|
157
|
+
return client;
|
|
158
|
+
};
|
|
159
|
+
`;
|
|
160
|
+
} else {
|
|
161
|
+
importsContents = dedent`
|
|
162
|
+
import { createClient as baseCreateClient } from "@prismicio/client";
|
|
163
|
+
import { enableAutoPreviews } from "@prismicio/next/pages";
|
|
164
|
+
import prismicConfig from "${configImportPath}";
|
|
165
|
+
`;
|
|
166
|
+
|
|
167
|
+
createClientContents = dedent`
|
|
168
|
+
/**
|
|
169
|
+
* Creates a Prismic client for the project's repository. The client is used to
|
|
170
|
+
* query content from the Prismic API.
|
|
171
|
+
*
|
|
172
|
+
* @param {import("@prismicio/next/pages").CreateClientConfig} config - Configuration for the Prismic client.
|
|
173
|
+
*/
|
|
174
|
+
export const createClient = ({ previewData, req, ...config } = {}) => {
|
|
175
|
+
const client = baseCreateClient(repositoryName, {
|
|
176
|
+
routes,
|
|
177
|
+
...config,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
enableAutoPreviews({ client, previewData, req });
|
|
181
|
+
|
|
182
|
+
return client;
|
|
183
|
+
};
|
|
184
|
+
`;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (typescript) {
|
|
189
|
+
return dedent`
|
|
190
|
+
${importsContents}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* The project's Prismic repository name.
|
|
194
|
+
*/
|
|
195
|
+
export const repositoryName = prismicConfig.repositoryName;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* A list of Route Resolver objects that define how a document's \`url\` field is resolved.
|
|
199
|
+
*
|
|
200
|
+
* {@link https://prismic.io/docs/route-resolver#route-resolver}
|
|
201
|
+
*
|
|
202
|
+
* Note: \`prismic sync\` may append new default routes for Page Types. Feel free
|
|
203
|
+
* to edit these to match your site's routing structure.
|
|
204
|
+
*/
|
|
205
|
+
// TODO: Update the routes array to match your project's route structure.
|
|
206
|
+
const routes: Route[] = [
|
|
207
|
+
// Examples:
|
|
208
|
+
// { type: "homepage", path: "/" },
|
|
209
|
+
// { type: "page", path: "/:uid" },
|
|
210
|
+
];
|
|
211
|
+
|
|
212
|
+
${createClientContents}
|
|
213
|
+
`;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return dedent`
|
|
217
|
+
${importsContents}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* The project's Prismic repository name.
|
|
221
|
+
*/
|
|
222
|
+
export const repositoryName = prismicConfig.repositoryName;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* A list of Route Resolver objects that define how a document's \`url\` field is resolved.
|
|
226
|
+
*
|
|
227
|
+
* {@link https://prismic.io/docs/route-resolver#route-resolver}
|
|
228
|
+
*
|
|
229
|
+
* Note: \`prismic sync\` may append new default routes for Page Types. Feel free
|
|
230
|
+
* to edit these to match your site's routing structure.
|
|
231
|
+
*
|
|
232
|
+
* @type {import("@prismicio/client").Route[]}
|
|
233
|
+
*/
|
|
234
|
+
// TODO: Update the routes array to match your project's route structure.
|
|
235
|
+
const routes = [
|
|
236
|
+
// Examples:
|
|
237
|
+
// { type: "homepage", path: "/" },
|
|
238
|
+
// { type: "page", path: "/:uid" },
|
|
239
|
+
];
|
|
240
|
+
|
|
241
|
+
${createClientContents}
|
|
242
|
+
`;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export function sliceSimulatorPageTemplate(args: {
|
|
246
|
+
typescript: boolean;
|
|
247
|
+
appRouter: boolean;
|
|
248
|
+
}): string {
|
|
249
|
+
const { typescript, appRouter } = args;
|
|
250
|
+
|
|
251
|
+
if (appRouter) {
|
|
252
|
+
if (typescript) {
|
|
253
|
+
return dedent`
|
|
254
|
+
import {
|
|
255
|
+
SliceSimulator,
|
|
256
|
+
SliceSimulatorParams,
|
|
257
|
+
getSlices,
|
|
258
|
+
} from "@prismicio/next";
|
|
259
|
+
import { SliceZone } from "@prismicio/react";
|
|
260
|
+
|
|
261
|
+
import { components } from "../../slices";
|
|
262
|
+
|
|
263
|
+
export default async function SliceSimulatorPage({
|
|
264
|
+
searchParams,
|
|
265
|
+
}: SliceSimulatorParams) {
|
|
266
|
+
const { state } = await searchParams
|
|
267
|
+
const slices = getSlices(state);
|
|
268
|
+
|
|
269
|
+
return (
|
|
270
|
+
<SliceSimulator>
|
|
271
|
+
<SliceZone slices={slices} components={components} />
|
|
272
|
+
</SliceSimulator>
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
`;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return dedent`
|
|
279
|
+
import { SliceSimulator, getSlices } from "@prismicio/next";
|
|
280
|
+
import { SliceZone } from "@prismicio/react";
|
|
281
|
+
|
|
282
|
+
import { components } from "../../slices";
|
|
283
|
+
|
|
284
|
+
export default async function SliceSimulatorPage({ searchParams }) {
|
|
285
|
+
const { state } = await searchParams
|
|
286
|
+
const slices = getSlices(state);
|
|
287
|
+
|
|
288
|
+
return (
|
|
289
|
+
<SliceSimulator>
|
|
290
|
+
<SliceZone slices={slices} components={components} />
|
|
291
|
+
</SliceSimulator>
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
`;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return dedent`
|
|
298
|
+
import { SliceSimulator } from "@prismicio/next/pages";
|
|
299
|
+
import { SliceZone } from "@prismicio/react";
|
|
300
|
+
|
|
301
|
+
import { components } from "../slices";
|
|
302
|
+
|
|
303
|
+
export default function SliceSimulatorPage() {
|
|
304
|
+
return (
|
|
305
|
+
<SliceSimulator
|
|
306
|
+
sliceZone={(props) => <SliceZone {...props} components={components} />}
|
|
307
|
+
/>
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
`;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export function previewRouteTemplate(args: { typescript: boolean; appRouter: boolean }): string {
|
|
314
|
+
const { typescript, appRouter } = args;
|
|
315
|
+
|
|
316
|
+
if (appRouter) {
|
|
317
|
+
if (typescript) {
|
|
318
|
+
return dedent`
|
|
319
|
+
import { NextRequest } from "next/server";
|
|
320
|
+
import { redirectToPreviewURL } from "@prismicio/next";
|
|
321
|
+
|
|
322
|
+
import { createClient } from "../../../prismicio";
|
|
323
|
+
|
|
324
|
+
export async function GET(request: NextRequest) {
|
|
325
|
+
const client = createClient();
|
|
326
|
+
|
|
327
|
+
return await redirectToPreviewURL({ client, request });
|
|
328
|
+
}
|
|
329
|
+
`;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
return dedent`
|
|
333
|
+
import { redirectToPreviewURL } from "@prismicio/next";
|
|
334
|
+
|
|
335
|
+
import { createClient } from "../../../prismicio";
|
|
336
|
+
|
|
337
|
+
export async function GET(request) {
|
|
338
|
+
const client = createClient();
|
|
339
|
+
|
|
340
|
+
return await redirectToPreviewURL({ client, request });
|
|
341
|
+
}
|
|
342
|
+
`;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (typescript) {
|
|
346
|
+
return dedent`
|
|
347
|
+
import { NextApiRequest, NextApiResponse } from "next";
|
|
348
|
+
import { setPreviewData, redirectToPreviewURL } from "@prismicio/next/pages";
|
|
349
|
+
|
|
350
|
+
import { createClient } from "../../prismicio";
|
|
351
|
+
|
|
352
|
+
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
353
|
+
const client = createClient({ req });
|
|
354
|
+
|
|
355
|
+
setPreviewData({ req, res });
|
|
356
|
+
|
|
357
|
+
return await redirectToPreviewURL({ req, res, client });
|
|
358
|
+
};
|
|
359
|
+
`;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return dedent`
|
|
363
|
+
import { setPreviewData, redirectToPreviewURL } from "@prismicio/next/pages";
|
|
364
|
+
|
|
365
|
+
import { createClient } from "../../prismicio";
|
|
366
|
+
|
|
367
|
+
export default async function handler(req, res) {
|
|
368
|
+
const client = createClient({ req });
|
|
369
|
+
|
|
370
|
+
setPreviewData({ req, res });
|
|
371
|
+
|
|
372
|
+
return await redirectToPreviewURL({ req, res, client });
|
|
373
|
+
};
|
|
374
|
+
`;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export function exitPreviewRouteTemplate(args: {
|
|
378
|
+
typescript: boolean;
|
|
379
|
+
appRouter: boolean;
|
|
380
|
+
}): string {
|
|
381
|
+
const { typescript, appRouter } = args;
|
|
382
|
+
|
|
383
|
+
if (appRouter) {
|
|
384
|
+
return dedent`
|
|
385
|
+
import { exitPreview } from "@prismicio/next";
|
|
386
|
+
|
|
387
|
+
export function GET() {
|
|
388
|
+
return exitPreview();
|
|
389
|
+
}
|
|
390
|
+
`;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (typescript) {
|
|
394
|
+
return dedent`
|
|
395
|
+
import { NextApiRequest, NextApiResponse } from "next";
|
|
396
|
+
import { exitPreview } from "@prismicio/next/pages";
|
|
397
|
+
|
|
398
|
+
export default function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
399
|
+
return exitPreview({ req, res });
|
|
400
|
+
}
|
|
401
|
+
`;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return dedent`
|
|
405
|
+
import { exitPreview } from "@prismicio/next/pages";
|
|
406
|
+
|
|
407
|
+
export default function handler(req, res) {
|
|
408
|
+
return exitPreview({ req, res });
|
|
409
|
+
}
|
|
410
|
+
`;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export function revalidateRouteTemplate(args: { supportsCacheLife: boolean }): string {
|
|
414
|
+
const { supportsCacheLife } = args;
|
|
415
|
+
|
|
416
|
+
return dedent`
|
|
417
|
+
import { NextResponse } from "next/server";
|
|
418
|
+
import { revalidateTag } from "next/cache";
|
|
419
|
+
|
|
420
|
+
export async function POST() {
|
|
421
|
+
revalidateTag("prismic"${supportsCacheLife ? ', "max"' : ""});
|
|
422
|
+
|
|
423
|
+
return NextResponse.json({ revalidated: true, now: Date.now() });
|
|
424
|
+
}
|
|
425
|
+
`;
|
|
426
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import type { SharedSlice } from "@prismicio/types-internal/lib/customtypes";
|
|
2
|
+
|
|
3
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
|
|
6
|
+
import type { Framework } from ".";
|
|
7
|
+
|
|
8
|
+
import { FrameworkAdapter } from ".";
|
|
9
|
+
import { exists } from "../lib/file";
|
|
10
|
+
import {
|
|
11
|
+
exitPreviewRouteTemplate,
|
|
12
|
+
previewRouteTemplate,
|
|
13
|
+
prismicIOFileTemplate,
|
|
14
|
+
revalidateRouteTemplate,
|
|
15
|
+
sliceSimulatorPageTemplate,
|
|
16
|
+
sliceTemplate,
|
|
17
|
+
} from "./nextjs.templates";
|
|
18
|
+
import { getNpmPackageVersion } from "../lib/packageJson";
|
|
19
|
+
|
|
20
|
+
export class NextJsFramework extends FrameworkAdapter {
|
|
21
|
+
readonly id: Framework = "next";
|
|
22
|
+
|
|
23
|
+
async getDependencies(): Promise<Record<string, string>> {
|
|
24
|
+
return {
|
|
25
|
+
"@prismicio/client": `^${await getNpmPackageVersion("@prismicio/client")}`,
|
|
26
|
+
"@prismicio/react": `^${await getNpmPackageVersion("@prismicio/react")}`,
|
|
27
|
+
"@prismicio/next": `^${await getNpmPackageVersion("@prismicio/next")}`,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async initProject(): Promise<void> {
|
|
32
|
+
await super.initProject();
|
|
33
|
+
|
|
34
|
+
await this.#createPrismicIOFile();
|
|
35
|
+
await this.#createSliceSimulatorPage();
|
|
36
|
+
await this.#createPreviewRoute();
|
|
37
|
+
await this.#createExitPreviewRoute();
|
|
38
|
+
await this.#createRevalidateRoute();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async createSliceComponent(
|
|
42
|
+
model: SharedSlice,
|
|
43
|
+
sliceDirectory: URL,
|
|
44
|
+
): Promise<{ componentPath: URL }> {
|
|
45
|
+
const extension = await this.getJsFileExtension();
|
|
46
|
+
const componentPath = new URL(`index.${extension}x`, sliceDirectory);
|
|
47
|
+
const contents = sliceTemplate({
|
|
48
|
+
name: model.name,
|
|
49
|
+
typescript: await this.checkIsTypeScriptProject(),
|
|
50
|
+
});
|
|
51
|
+
await writeFile(componentPath, contents);
|
|
52
|
+
return { componentPath };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
getSliceImportPath(relativeDirectory: string): string {
|
|
56
|
+
return `./${relativeDirectory}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async getDefaultSliceLibraryPath(projectRoot: URL): Promise<URL> {
|
|
60
|
+
const srcDirectory = new URL("src/", projectRoot);
|
|
61
|
+
const hasSrcDirectory = await exists(srcDirectory);
|
|
62
|
+
const sourceFilesRoot = hasSrcDirectory ? srcDirectory : projectRoot;
|
|
63
|
+
return new URL("slices/", sourceFilesRoot);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async getClientFilePath(): Promise<string | null> {
|
|
67
|
+
const hasSrcDirectory = await this.#checkHasSrcDirectory();
|
|
68
|
+
return hasSrcDirectory ? "src/prismicio.ts" : "prismicio.ts";
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async getSlicesDirectoryPath(): Promise<string> {
|
|
72
|
+
const hasSrcDirectory = await this.#checkHasSrcDirectory();
|
|
73
|
+
return hasSrcDirectory ? "src/slices/" : "slices/";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
getSliceComponentExtensions(): string[] {
|
|
77
|
+
return [".tsx", ".ts", ".jsx", ".js"];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async getRoutePath(route: string): Promise<{ path: string; extensions: string[] } | null> {
|
|
81
|
+
const hasSrcDirectory = await this.#checkHasSrcDirectory();
|
|
82
|
+
const base = hasSrcDirectory ? "src/app" : "app";
|
|
83
|
+
switch (route) {
|
|
84
|
+
case "/slice-simulator":
|
|
85
|
+
return { path: `${base}/slice-simulator/page`, extensions: [".tsx", ".ts", ".jsx", ".js"] };
|
|
86
|
+
case "/api/preview":
|
|
87
|
+
return { path: `${base}/api/preview/route`, extensions: [".ts", ".js"] };
|
|
88
|
+
case "/api/exit-preview":
|
|
89
|
+
return { path: `${base}/api/exit-preview/route`, extensions: [".ts", ".js"] };
|
|
90
|
+
case "/api/revalidate":
|
|
91
|
+
return { path: `${base}/api/revalidate/route`, extensions: [".ts", ".js"] };
|
|
92
|
+
default:
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async #checkHasAppRouter(): Promise<boolean> {
|
|
98
|
+
const appPath = await this.#buildSrcPath("app");
|
|
99
|
+
return await exists(appPath);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async #checkHasSrcDirectory(): Promise<boolean> {
|
|
103
|
+
const projectRoot = await this.getProjectRoot();
|
|
104
|
+
return await exists(new URL("src/", projectRoot));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async #getNextJSVersion(): Promise<string> {
|
|
108
|
+
const projectRoot = await this.getProjectRoot();
|
|
109
|
+
const require = createRequire(new URL("package.json", projectRoot));
|
|
110
|
+
const { version } = require("next/package.json");
|
|
111
|
+
return version;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async #buildSrcPath(filename: string): Promise<URL> {
|
|
115
|
+
const projectRoot = await this.getProjectRoot();
|
|
116
|
+
const hasSrcDirectory = await this.#checkHasSrcDirectory();
|
|
117
|
+
const prefix = hasSrcDirectory ? "src/" : "";
|
|
118
|
+
return new URL(`${prefix}${filename}`, projectRoot);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async #createPrismicIOFile(): Promise<void> {
|
|
122
|
+
const extension = await this.getJsFileExtension();
|
|
123
|
+
const filePath = await this.#buildSrcPath(`prismicio.${extension}`);
|
|
124
|
+
|
|
125
|
+
if (await exists(filePath)) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const typescript = await this.checkIsTypeScriptProject();
|
|
130
|
+
const appRouter = await this.#checkHasAppRouter();
|
|
131
|
+
const hasSrcDirectory = await this.#checkHasSrcDirectory();
|
|
132
|
+
|
|
133
|
+
const contents = prismicIOFileTemplate({
|
|
134
|
+
typescript,
|
|
135
|
+
appRouter,
|
|
136
|
+
hasSrcDirectory,
|
|
137
|
+
});
|
|
138
|
+
await writeFile(filePath, contents);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async #createSliceSimulatorPage(): Promise<void> {
|
|
142
|
+
const appRouter = await this.#checkHasAppRouter();
|
|
143
|
+
const typescript = await this.checkIsTypeScriptProject();
|
|
144
|
+
const extension = `${await this.getJsFileExtension()}x`;
|
|
145
|
+
const filename = appRouter
|
|
146
|
+
? `app/slice-simulator/page.${extension}`
|
|
147
|
+
: `pages/slice-simulator.${extension}`;
|
|
148
|
+
const filePath = await this.#buildSrcPath(filename);
|
|
149
|
+
|
|
150
|
+
if (await exists(filePath)) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const contents = sliceSimulatorPageTemplate({ typescript, appRouter });
|
|
155
|
+
await mkdir(new URL(".", filePath), { recursive: true });
|
|
156
|
+
await writeFile(filePath, contents);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async #createPreviewRoute(): Promise<void> {
|
|
160
|
+
const appRouter = await this.#checkHasAppRouter();
|
|
161
|
+
const typescript = await this.checkIsTypeScriptProject();
|
|
162
|
+
const extension = await this.getJsFileExtension();
|
|
163
|
+
const filename = appRouter
|
|
164
|
+
? `app/api/preview/route.${extension}`
|
|
165
|
+
: `pages/api/preview.${extension}`;
|
|
166
|
+
const filePath = await this.#buildSrcPath(filename);
|
|
167
|
+
|
|
168
|
+
if (await exists(filePath)) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const contents = previewRouteTemplate({ typescript, appRouter });
|
|
173
|
+
await mkdir(new URL(".", filePath), { recursive: true });
|
|
174
|
+
await writeFile(filePath, contents);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async #createExitPreviewRoute(): Promise<void> {
|
|
178
|
+
const appRouter = await this.#checkHasAppRouter();
|
|
179
|
+
const typescript = await this.checkIsTypeScriptProject();
|
|
180
|
+
const extension = await this.getJsFileExtension();
|
|
181
|
+
const filename = appRouter
|
|
182
|
+
? `app/api/exit-preview/route.${extension}`
|
|
183
|
+
: `pages/api/exit-preview.${extension}`;
|
|
184
|
+
const filePath = await this.#buildSrcPath(filename);
|
|
185
|
+
|
|
186
|
+
if (await exists(filePath)) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const contents = exitPreviewRouteTemplate({ typescript, appRouter });
|
|
191
|
+
await mkdir(new URL(".", filePath), { recursive: true });
|
|
192
|
+
await writeFile(filePath, contents);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async #createRevalidateRoute(): Promise<void> {
|
|
196
|
+
const appRouter = await this.#checkHasAppRouter();
|
|
197
|
+
if (!appRouter) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const extension = await this.getJsFileExtension();
|
|
202
|
+
const filePath = await this.#buildSrcPath(`app/api/revalidate/route.${extension}`);
|
|
203
|
+
|
|
204
|
+
if (await exists(filePath)) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const version = await this.#getNextJSVersion();
|
|
209
|
+
const major = Number.parseInt(version.split(".")[0]);
|
|
210
|
+
const supportsCacheLife = major >= 16;
|
|
211
|
+
|
|
212
|
+
const contents = revalidateRouteTemplate({ supportsCacheLife });
|
|
213
|
+
await mkdir(new URL(".", filePath), { recursive: true });
|
|
214
|
+
await writeFile(filePath, contents);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { pascalCase } from "change-case";
|
|
2
|
+
|
|
3
|
+
import { dedent } from "../lib/string";
|
|
4
|
+
|
|
5
|
+
export function sliceTemplate(args: { name: string; typescript: boolean }): string {
|
|
6
|
+
const { name, typescript } = args;
|
|
7
|
+
|
|
8
|
+
const pascalName = pascalCase(name);
|
|
9
|
+
|
|
10
|
+
if (typescript) {
|
|
11
|
+
return dedent`
|
|
12
|
+
<script setup lang="ts">
|
|
13
|
+
import type { Content } from "@prismicio/client";
|
|
14
|
+
|
|
15
|
+
// The array passed to \`getSliceComponentProps\` is purely optional.
|
|
16
|
+
// Consider it as a visual hint for you when templating your slice.
|
|
17
|
+
defineProps(getSliceComponentProps<Content.${pascalName}Slice>(
|
|
18
|
+
["slice", "index", "slices", "context"]
|
|
19
|
+
));
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<section
|
|
24
|
+
:data-slice-type="slice.slice_type"
|
|
25
|
+
:data-slice-variation="slice.variation"
|
|
26
|
+
>
|
|
27
|
+
Placeholder component for {{ slice.slice_type }} (variation: {{ slice.variation }}) slices.
|
|
28
|
+
<br />
|
|
29
|
+
<strong>You can edit this slice directly in your code editor.</strong>
|
|
30
|
+
</section>
|
|
31
|
+
</template>
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return dedent`
|
|
36
|
+
<script setup>
|
|
37
|
+
// The array passed to \`getSliceComponentProps\` is purely optional.
|
|
38
|
+
// Consider it as a visual hint for you when templating your slice.
|
|
39
|
+
defineProps(getSliceComponentProps(["slice", "index", "slices", "context"]));
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<template>
|
|
43
|
+
<section
|
|
44
|
+
:data-slice-type="slice.slice_type"
|
|
45
|
+
:data-slice-variation="slice.variation"
|
|
46
|
+
>
|
|
47
|
+
Placeholder component for {{ slice.slice_type }} (variation: {{ slice.variation }}) slices.
|
|
48
|
+
<br />
|
|
49
|
+
<strong>You can edit this slice directly in your code editor.</strong>
|
|
50
|
+
</section>
|
|
51
|
+
</template>
|
|
52
|
+
`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function sliceSimulatorPageTemplate(args: { typescript: boolean }): string {
|
|
56
|
+
const { typescript } = args;
|
|
57
|
+
|
|
58
|
+
const scriptAttributes = ["setup"];
|
|
59
|
+
if (typescript) {
|
|
60
|
+
scriptAttributes.push('lang="ts"');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return dedent`
|
|
64
|
+
<script ${scriptAttributes.join(" ")}>
|
|
65
|
+
import { components } from "~/slices";
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<template>
|
|
69
|
+
<SliceSimulator #default="{ slices }">
|
|
70
|
+
<SliceZone :slices="slices" :components="components" />
|
|
71
|
+
</SliceSimulator>
|
|
72
|
+
</template>
|
|
73
|
+
`;
|
|
74
|
+
}
|