@prismicio/next 0.1.3 → 0.1.4-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
  Helpers to integrate Prismic into Next.js apps.
11
11
 
12
12
  - 👁️  Easily set up Prismic Preview
13
- - _More features coming!_
13
+ - 🖼️  Render optimized images using [`next/image`][next-image] and Prismic's built-in [Imgix][imgix] integration
14
14
 
15
15
  ## Install
16
16
 
@@ -57,6 +57,8 @@ For more clarity on this project and its structure you can also check out the de
57
57
  <!-- Links -->
58
58
 
59
59
  [prismic]: https://prismic.io
60
+ [imgix]: https://imgix.com/
61
+ [next-image]: https://nextjs.org/docs/basic-features/image-optimization
60
62
 
61
63
  <!-- TODO: Replace link with a more useful one if available -->
62
64
 
@@ -0,0 +1,60 @@
1
+ import * as React from 'react';
2
+ import Image from 'next/image';
3
+ import { buildURL } from 'imgix-url-builder';
4
+ import * as prismicH from '@prismicio/helpers';
5
+ import { __PRODUCTION__ } from './lib/__PRODUCTION__.mjs';
6
+ import { devMsg } from './lib/devMsg.mjs';
7
+
8
+ const imgixLoader = (args) => {
9
+ const url = new URL(args.src);
10
+ const params = {
11
+ fit: url.searchParams.get("fit") || "max",
12
+ w: args.width,
13
+ h: void 0
14
+ };
15
+ if (args.quality) {
16
+ params.q = args.quality;
17
+ }
18
+ return buildURL(args.src, params);
19
+ };
20
+ const PrismicNextImage = ({
21
+ field,
22
+ imgixParams = {},
23
+ alt,
24
+ fallbackAlt,
25
+ layout,
26
+ ...restProps
27
+ }) => {
28
+ if (!__PRODUCTION__) {
29
+ if (typeof alt === "string" && alt !== "") {
30
+ console.warn(
31
+ `[PrismicNextImage] The "alt" prop can only be used to declare an image as decorative by passing an empty string (alt="") but was provided a non-empty string. You can resolve this warning by removing the "alt" prop or changing it to alt="". For more details, see ${devMsg(
32
+ "alt-must-be-an-empty-string"
33
+ )}`
34
+ );
35
+ }
36
+ if (typeof fallbackAlt === "string" && fallbackAlt !== "") {
37
+ console.warn(
38
+ `[PrismicNextImage] The "fallbackAlt" prop can only be used to declare an image as decorative by passing an empty string (fallbackAlt="") but was provided a non-empty string. You can resolve this warning by removing the "fallbackAlt" prop or changing it to fallbackAlt="". For more details, see ${devMsg(
39
+ "alt-must-be-an-empty-string"
40
+ )}`
41
+ );
42
+ }
43
+ }
44
+ if (prismicH.isFilled.imageThumbnail(field)) {
45
+ const src = buildURL(field.url, imgixParams);
46
+ return /* @__PURE__ */ React.createElement(Image, {
47
+ src,
48
+ width: layout === "fill" ? void 0 : field.dimensions.width,
49
+ height: layout === "fill" ? void 0 : field.dimensions.height,
50
+ alt: alt ?? (field.alt || fallbackAlt),
51
+ loader: imgixLoader,
52
+ layout,
53
+ ...restProps
54
+ });
55
+ } else {
56
+ return null;
57
+ }
58
+ };
59
+
60
+ export { PrismicNextImage };
@@ -0,0 +1,81 @@
1
+ import * as React from 'react';
2
+ import { PrismicToolbar } from '@prismicio/react';
3
+ import { useRouter } from 'next/router';
4
+ import { getPrismicPreviewCookie } from './lib/getPrismicPreviewCookie.mjs';
5
+ import { getPreviewCookieRepositoryName } from './lib/getPreviewCookieRepositoryName.mjs';
6
+
7
+ function PrismicPreview({
8
+ repositoryName,
9
+ children,
10
+ updatePreviewURL = "/api/preview",
11
+ exitPreviewURL = "/api/exit-preview"
12
+ }) {
13
+ const router = useRouter();
14
+ const resolvedUpdatePreviewURL = router.basePath + updatePreviewURL;
15
+ const resolvedExitPreviewURL = router.basePath + exitPreviewURL;
16
+ React.useEffect(() => {
17
+ const startPreviewMode = async () => {
18
+ const res = await globalThis.fetch(resolvedUpdatePreviewURL);
19
+ if (res.ok) {
20
+ globalThis.location.reload();
21
+ } else {
22
+ console.error(
23
+ `[<PrismicPreview>] Failed to start or update Preview Mode using the "${resolvedUpdatePreviewURL}" API endpoint. Does it exist?`
24
+ );
25
+ }
26
+ };
27
+ const handlePrismicPreviewUpdate = async (event) => {
28
+ event.preventDefault();
29
+ await startPreviewMode();
30
+ };
31
+ const handlePrismicPreviewEnd = async (event) => {
32
+ event.preventDefault();
33
+ const res = await globalThis.fetch(resolvedExitPreviewURL);
34
+ if (res.ok) {
35
+ globalThis.location.reload();
36
+ } else {
37
+ console.error(
38
+ `[<PrismicPreview>] Failed to exit Preview Mode using the "${resolvedExitPreviewURL}" API endpoint. Does it exist?`
39
+ );
40
+ }
41
+ };
42
+ if (router.isPreview) {
43
+ window.addEventListener(
44
+ "prismicPreviewUpdate",
45
+ handlePrismicPreviewUpdate
46
+ );
47
+ window.addEventListener("prismicPreviewEnd", handlePrismicPreviewEnd);
48
+ } else {
49
+ const prismicPreviewCookie = getPrismicPreviewCookie(
50
+ globalThis.document.cookie
51
+ );
52
+ if (prismicPreviewCookie) {
53
+ const locationIsDescendantOfBasePath = window.location.href.startsWith(
54
+ window.location.origin + router.basePath
55
+ );
56
+ const prismicPreviewCookieRepositoryName = getPreviewCookieRepositoryName(prismicPreviewCookie);
57
+ if (locationIsDescendantOfBasePath && prismicPreviewCookieRepositoryName === repositoryName) {
58
+ startPreviewMode();
59
+ }
60
+ }
61
+ }
62
+ return () => {
63
+ window.removeEventListener(
64
+ "prismicPreviewUpdate",
65
+ handlePrismicPreviewUpdate
66
+ );
67
+ window.removeEventListener("prismicPreviewEnd", handlePrismicPreviewEnd);
68
+ };
69
+ }, [
70
+ repositoryName,
71
+ resolvedExitPreviewURL,
72
+ resolvedUpdatePreviewURL,
73
+ router.isPreview,
74
+ router.basePath
75
+ ]);
76
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, children, /* @__PURE__ */ React.createElement(PrismicToolbar, {
77
+ repositoryName
78
+ }));
79
+ }
80
+
81
+ export { PrismicPreview };
@@ -0,0 +1,15 @@
1
+ const isPrismicNextPreviewData = (previewData) => {
2
+ return typeof previewData === "object" && "ref" in previewData;
3
+ };
4
+ const enableAutoPreviews = (config) => {
5
+ if ("previewData" in config && config.previewData) {
6
+ const { previewData } = config;
7
+ if (isPrismicNextPreviewData(previewData) && previewData.ref) {
8
+ config.client.queryContentFromRef(previewData.ref);
9
+ }
10
+ } else if ("req" in config && config.req) {
11
+ config.client.enableAutoPreviewsFromReq(config.req);
12
+ }
13
+ };
14
+
15
+ export { enableAutoPreviews };
@@ -0,0 +1,6 @@
1
+ function exitPreview(config) {
2
+ config.res.clearPreviewData();
3
+ config.res.status(205).json({ success: true });
4
+ }
5
+
6
+ export { exitPreview };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NextApiRequest, NextApiResponse, PreviewData } from 'next';
2
2
  import * as React from 'react';
3
- import { Client, HttpRequestLike } from '@prismicio/client';
3
+ import { Client, HttpRequestLike, ClientConfig } from '@prismicio/client';
4
4
  import { LinkResolverFunction } from '@prismicio/helpers';
5
5
  import { ImageProps } from 'next/image';
6
6
  import { ImgixURLParams } from 'imgix-url-builder';
@@ -56,6 +56,7 @@ declare type ExitPreviewConfig = {
56
56
  */
57
57
  res: {
58
58
  clearPreviewData: NextApiResponse["clearPreviewData"];
59
+ status: NextApiResponse["status"];
59
60
  json: NextApiResponse["json"];
60
61
  };
61
62
  /**
@@ -264,6 +265,6 @@ declare type CreateClientConfig = {
264
265
  * Pass a `req` object when using in a Next.js API endpoint.
265
266
  */
266
267
  req?: NextApiRequest;
267
- };
268
+ } & ClientConfig;
268
269
 
269
270
  export { CreateClientConfig, EnableAutoPreviewsConfig, ExitPreviewConfig, PrismicNextImage, PrismicNextImageProps, PrismicPreview, PrismicPreviewProps, RedirectToPreviewURLConfig, SetPreviewDataConfig, enableAutoPreviews, exitPreview, redirectToPreviewURL, setPreviewData };
package/dist/index.mjs ADDED
@@ -0,0 +1,6 @@
1
+ export { setPreviewData } from './setPreviewData.mjs';
2
+ export { exitPreview } from './exitPreview.mjs';
3
+ export { PrismicPreview } from './PrismicPreview.mjs';
4
+ export { enableAutoPreviews } from './enableAutoPreviews.mjs';
5
+ export { redirectToPreviewURL } from './redirectToPreviewURL.mjs';
6
+ export { PrismicNextImage } from './PrismicNextImage.mjs';
@@ -0,0 +1,3 @@
1
+ const __PRODUCTION__ = process.env.NODE_ENV === "production";
2
+
3
+ export { __PRODUCTION__ };
@@ -0,0 +1,7 @@
1
+ import { version } from '../package.mjs';
2
+
3
+ const devMsg = (slug) => {
4
+ return `https://prismic.dev/msg/next/v${version}/${slug}`;
5
+ };
6
+
7
+ export { devMsg };
@@ -0,0 +1,5 @@
1
+ const getPreviewCookieRepositoryName = (previewCookie) => {
2
+ return (decodeURIComponent(previewCookie).match(/"(.+).prismic.io"/) || [])[1];
3
+ };
4
+
5
+ export { getPreviewCookieRepositoryName };
@@ -0,0 +1,20 @@
1
+ import * as prismic from '@prismicio/client';
2
+
3
+ const readValue = (value) => {
4
+ return value.replace(/%3B/g, ";");
5
+ };
6
+ const getPrismicPreviewCookie = (cookieJar) => {
7
+ const cookies = cookieJar.split("; ");
8
+ let value;
9
+ for (const cookie of cookies) {
10
+ const parts = cookie.split("=");
11
+ const name = readValue(parts[0]).replace(/%3D/g, "=");
12
+ if (name === prismic.cookie.preview) {
13
+ value = readValue(parts.slice(1).join("="));
14
+ continue;
15
+ }
16
+ }
17
+ return value;
18
+ };
19
+
20
+ export { getPrismicPreviewCookie };
@@ -0,0 +1,3 @@
1
+ const version = "0.1.4-alpha.0";
2
+
3
+ export { version };
@@ -0,0 +1,20 @@
1
+ const isPrismicNextQuery = (query) => {
2
+ return typeof query.documentId === "string" && typeof query.token === "string";
3
+ };
4
+ async function redirectToPreviewURL(config) {
5
+ const defaultURL = config.defaultURL || "/";
6
+ const basePath = config.basePath || "";
7
+ if (isPrismicNextQuery(config.req.query)) {
8
+ const previewUrl = await config.client.resolvePreviewURL({
9
+ linkResolver: config.linkResolver,
10
+ defaultURL,
11
+ documentID: config.req.query.documentId,
12
+ previewToken: config.req.query.token
13
+ });
14
+ config.res.redirect(basePath + previewUrl);
15
+ return;
16
+ }
17
+ config.res.redirect(basePath + defaultURL);
18
+ }
19
+
20
+ export { redirectToPreviewURL };
@@ -0,0 +1,10 @@
1
+ import * as prismic from '@prismicio/client';
2
+
3
+ function setPreviewData({ req, res }) {
4
+ const ref = req.query.token || req.cookies[prismic.cookie.preview];
5
+ if (ref) {
6
+ res.setPreviewData({ ref });
7
+ }
8
+ }
9
+
10
+ export { setPreviewData };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prismicio/next",
3
- "version": "0.1.3",
3
+ "version": "0.1.4-alpha.0",
4
4
  "description": "Helpers to integrate Prismic into Next.js apps",
5
5
  "keywords": [
6
6
  "typescript",
@@ -15,23 +15,19 @@
15
15
  },
16
16
  "license": "Apache-2.0",
17
17
  "author": "Prismic <contact@prismic.io> (https://prismic.io)",
18
+ "sideEffects": false,
19
+ "type": "module",
18
20
  "exports": {
19
- ".": {
20
- "require": "./dist/index.cjs",
21
- "import": "./dist/index.js"
22
- },
23
- "./package.json": "./package.json"
21
+ ".": "./dist/index.mjs"
24
22
  },
25
- "main": "./dist/index.cjs",
26
- "module": "dist/index.js",
27
23
  "types": "dist/index.d.ts",
28
24
  "files": [
29
25
  "dist",
30
26
  "src"
31
27
  ],
32
28
  "scripts": {
33
- "build": "siroc build",
34
- "dev": "siroc build --watch",
29
+ "build": "unbuild",
30
+ "dev": "unbuild --stub",
35
31
  "format": "prettier --write .",
36
32
  "lint": "eslint --ext .js,.ts .",
37
33
  "prepare": "npm run build",
@@ -45,36 +41,37 @@
45
41
  "unit:watch": "vitest watch"
46
42
  },
47
43
  "dependencies": {
48
- "@prismicio/client": "^6.4.3",
49
- "@prismicio/helpers": "^2.3.0",
50
- "@prismicio/react": "^2.4.0",
51
- "@prismicio/types": "^0.1.27",
52
- "eslint-plugin-react": "^7.30.0",
53
- "eslint-plugin-react-hooks": "^4.5.0"
44
+ "@prismicio/client": "^6.7.0",
45
+ "@prismicio/helpers": "^2.3.3",
46
+ "@prismicio/react": "^2.5.0",
47
+ "@prismicio/types": "^0.2.3",
48
+ "eslint-plugin-react": "^7.30.1",
49
+ "eslint-plugin-react-hooks": "^4.6.0",
50
+ "imgix-url-builder": "^0.0.3"
54
51
  },
55
52
  "devDependencies": {
56
- "@prismicio/mock": "^0.0.10",
57
- "@size-limit/preset-small-lib": "^7.0.8",
53
+ "@prismicio/mock": "^0.1.1",
54
+ "@size-limit/preset-small-lib": "^8.0.1",
58
55
  "@types/react-test-renderer": "^18.0.0",
59
- "@typescript-eslint/eslint-plugin": "^5.26.0",
60
- "@typescript-eslint/parser": "^5.26.0",
61
- "c8": "^7.11.3",
62
- "eslint": "^8.16.0",
56
+ "@typescript-eslint/eslint-plugin": "^5.34.0",
57
+ "@typescript-eslint/parser": "^5.34.0",
58
+ "@vitest/coverage-c8": "^0.22.1",
59
+ "eslint": "^8.22.0",
63
60
  "eslint-config-prettier": "^8.5.0",
64
- "eslint-plugin-prettier": "^4.0.0",
61
+ "eslint-plugin-prettier": "^4.2.1",
65
62
  "eslint-plugin-tsdoc": "^0.2.16",
66
- "happy-dom": "^4.0.1",
63
+ "happy-dom": "^6.0.4",
67
64
  "next": "^12.1.4",
68
65
  "nyc": "^15.1.0",
69
- "prettier": "^2.6.2",
66
+ "prettier": "^2.7.1",
70
67
  "prettier-plugin-jsdoc": "^0.3.38",
71
68
  "react": "^18.1.0",
72
- "react-test-renderer": "^18.1.0",
73
- "siroc": "^0.16.0",
74
- "size-limit": "^7.0.8",
69
+ "react-test-renderer": "^18.2.0",
70
+ "size-limit": "^8.0.1",
75
71
  "standard-version": "^9.5.0",
76
- "typescript": "^4.7.2",
77
- "vitest": "^0.12.9"
72
+ "typescript": "^4.7.4",
73
+ "unbuild": "^0.8.9",
74
+ "vitest": "^0.22.1"
78
75
  },
79
76
  "peerDependencies": {
80
77
  "@prismicio/client": "^6.0.0",
@@ -1,9 +1,8 @@
1
1
  import * as React from "react";
2
- import * as prismic from "@prismicio/client";
3
2
  import { PrismicToolbar } from "@prismicio/react";
4
3
  import { useRouter } from "next/router";
5
4
 
6
- import { getCookie } from "./lib/getCookie";
5
+ import { getPrismicPreviewCookie } from "./lib/getPrismicPreviewCookie";
7
6
  import { getPreviewCookieRepositoryName } from "./lib/getPreviewCookieRepositoryName";
8
7
 
9
8
  /**
@@ -109,8 +108,7 @@ export function PrismicPreview({
109
108
  );
110
109
  window.addEventListener("prismicPreviewEnd", handlePrismicPreviewEnd);
111
110
  } else {
112
- const prismicPreviewCookie = getCookie(
113
- prismic.cookie.preview,
111
+ const prismicPreviewCookie = getPrismicPreviewCookie(
114
112
  globalThis.document.cookie,
115
113
  );
116
114
 
@@ -32,6 +32,7 @@ export type ExitPreviewConfig = {
32
32
  */
33
33
  res: {
34
34
  clearPreviewData: NextApiResponse["clearPreviewData"];
35
+ status: NextApiResponse["status"];
35
36
  json: NextApiResponse["json"];
36
37
  };
37
38
 
@@ -48,5 +49,7 @@ export function exitPreview(config: ExitPreviewConfig): void {
48
49
  // Exit the current user from Preview Mode.
49
50
  config.res.clearPreviewData();
50
51
 
51
- config.res.json({ success: true });
52
+ // 205 status is used to prevent CDN-level caching. The default 200
53
+ // status code is typically treated as non-changing and cacheable.
54
+ config.res.status(205).json({ success: true });
52
55
  }
@@ -1,3 +1,5 @@
1
+ import * as prismic from "@prismicio/client";
2
+
1
3
  const readValue = (value: string): string => {
2
4
  return value.replace(/%3B/g, ";");
3
5
  };
@@ -5,25 +7,26 @@ const readValue = (value: string): string => {
5
7
  /**
6
8
  * Returns the value of a cookie from a given cookie store.
7
9
  *
8
- * @param name - Name of the cookie.
9
10
  * @param cookieJar - The stringified cookie store from which to read the cookie.
10
11
  *
11
12
  * @returns The value of the cookie, if it exists.
12
13
  */
13
- export const getCookie = (
14
- name: string,
14
+ export const getPrismicPreviewCookie = (
15
15
  cookieJar: string,
16
16
  ): string | undefined => {
17
17
  const cookies = cookieJar.split("; ");
18
18
 
19
+ let value: string | undefined;
20
+
19
21
  for (const cookie of cookies) {
20
22
  const parts = cookie.split("=");
21
- const thisName = readValue(parts[0]).replace(/%3D/g, "=");
23
+ const name = readValue(parts[0]).replace(/%3D/g, "=");
22
24
 
23
- if (thisName === name) {
24
- const value = parts.slice(1).join("=");
25
-
26
- return readValue(value);
25
+ if (name === prismic.cookie.preview) {
26
+ value = readValue(parts.slice(1).join("="));
27
+ continue;
27
28
  }
28
29
  }
30
+
31
+ return value;
29
32
  };
package/src/types.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { PreviewData, NextApiRequest } from "next";
1
+ import type { PreviewData, NextApiRequest } from "next";
2
+ import type { ClientConfig } from "@prismicio/client";
2
3
 
3
4
  /**
4
5
  * Configuration for creating a Prismic client with automatic preview support in
@@ -19,4 +20,4 @@ export type CreateClientConfig = {
19
20
  * Pass a `req` object when using in a Next.js API endpoint.
20
21
  */
21
22
  req?: NextApiRequest;
22
- };
23
+ } & ClientConfig;
package/dist/index.cjs DELETED
@@ -1,244 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- const prismic = require('@prismicio/client');
6
- const React = require('react');
7
- const react = require('@prismicio/react');
8
- const router = require('next/router');
9
- const Image = require('next/image');
10
- const prismicH = require('@prismicio/helpers');
11
-
12
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
-
14
- function _interopNamespace(e) {
15
- if (e && e.__esModule) return e;
16
- const n = Object.create(null);
17
- if (e) {
18
- for (const k in e) {
19
- if (k !== 'default') {
20
- const d = Object.getOwnPropertyDescriptor(e, k);
21
- Object.defineProperty(n, k, d.get ? d : {
22
- enumerable: true,
23
- get: function () { return e[k]; }
24
- });
25
- }
26
- }
27
- }
28
- n["default"] = e;
29
- return Object.freeze(n);
30
- }
31
-
32
- const prismic__namespace = /*#__PURE__*/_interopNamespace(prismic);
33
- const React__namespace = /*#__PURE__*/_interopNamespace(React);
34
- const Image__default = /*#__PURE__*/_interopDefaultLegacy(Image);
35
- const prismicH__namespace = /*#__PURE__*/_interopNamespace(prismicH);
36
-
37
- function setPreviewData({ req, res }) {
38
- const ref = req.query.token || req.cookies[prismic__namespace.cookie.preview];
39
- if (ref) {
40
- res.setPreviewData({ ref });
41
- }
42
- }
43
-
44
- function exitPreview(config) {
45
- config.res.clearPreviewData();
46
- config.res.json({ success: true });
47
- }
48
-
49
- const readValue = (value) => {
50
- return value.replace(/%3B/g, ";");
51
- };
52
- const getCookie = (name, cookieJar) => {
53
- const cookies = cookieJar.split("; ");
54
- for (const cookie of cookies) {
55
- const parts = cookie.split("=");
56
- const thisName = readValue(parts[0]).replace(/%3D/g, "=");
57
- if (thisName === name) {
58
- const value = parts.slice(1).join("=");
59
- return readValue(value);
60
- }
61
- }
62
- };
63
-
64
- const getPreviewCookieRepositoryName = (previewCookie) => {
65
- return (decodeURIComponent(previewCookie).match(/"(.+).prismic.io"/) || [])[1];
66
- };
67
-
68
- function PrismicPreview({
69
- repositoryName,
70
- children,
71
- updatePreviewURL = "/api/preview",
72
- exitPreviewURL = "/api/exit-preview"
73
- }) {
74
- const router$1 = router.useRouter();
75
- const resolvedUpdatePreviewURL = router$1.basePath + updatePreviewURL;
76
- const resolvedExitPreviewURL = router$1.basePath + exitPreviewURL;
77
- React__namespace.useEffect(() => {
78
- const startPreviewMode = async () => {
79
- const res = await globalThis.fetch(resolvedUpdatePreviewURL);
80
- if (res.ok) {
81
- globalThis.location.reload();
82
- } else {
83
- console.error(`[<PrismicPreview>] Failed to start or update Preview Mode using the "${resolvedUpdatePreviewURL}" API endpoint. Does it exist?`);
84
- }
85
- };
86
- const handlePrismicPreviewUpdate = async (event) => {
87
- event.preventDefault();
88
- await startPreviewMode();
89
- };
90
- const handlePrismicPreviewEnd = async (event) => {
91
- event.preventDefault();
92
- const res = await globalThis.fetch(resolvedExitPreviewURL);
93
- if (res.ok) {
94
- globalThis.location.reload();
95
- } else {
96
- console.error(`[<PrismicPreview>] Failed to exit Preview Mode using the "${resolvedExitPreviewURL}" API endpoint. Does it exist?`);
97
- }
98
- };
99
- if (router$1.isPreview) {
100
- window.addEventListener("prismicPreviewUpdate", handlePrismicPreviewUpdate);
101
- window.addEventListener("prismicPreviewEnd", handlePrismicPreviewEnd);
102
- } else {
103
- const prismicPreviewCookie = getCookie(prismic__namespace.cookie.preview, globalThis.document.cookie);
104
- if (prismicPreviewCookie) {
105
- const locationIsDescendantOfBasePath = window.location.href.startsWith(window.location.origin + router$1.basePath);
106
- const prismicPreviewCookieRepositoryName = getPreviewCookieRepositoryName(prismicPreviewCookie);
107
- if (locationIsDescendantOfBasePath && prismicPreviewCookieRepositoryName === repositoryName) {
108
- startPreviewMode();
109
- }
110
- }
111
- }
112
- return () => {
113
- window.removeEventListener("prismicPreviewUpdate", handlePrismicPreviewUpdate);
114
- window.removeEventListener("prismicPreviewEnd", handlePrismicPreviewEnd);
115
- };
116
- }, [
117
- repositoryName,
118
- resolvedExitPreviewURL,
119
- resolvedUpdatePreviewURL,
120
- router$1.isPreview,
121
- router$1.basePath
122
- ]);
123
- return /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, children, /* @__PURE__ */ React__namespace.createElement(react.PrismicToolbar, {
124
- repositoryName
125
- }));
126
- }
127
-
128
- const isPrismicNextPreviewData = (previewData) => {
129
- return typeof previewData === "object" && "ref" in previewData;
130
- };
131
- const enableAutoPreviews = (config) => {
132
- if ("previewData" in config && config.previewData) {
133
- const { previewData } = config;
134
- if (isPrismicNextPreviewData(previewData) && previewData.ref) {
135
- config.client.queryContentFromRef(previewData.ref);
136
- }
137
- } else if ("req" in config && config.req) {
138
- config.client.enableAutoPreviewsFromReq(config.req);
139
- }
140
- };
141
-
142
- const isPrismicNextQuery = (query) => {
143
- return typeof query.documentId === "string" && typeof query.token === "string";
144
- };
145
- async function redirectToPreviewURL(config) {
146
- const defaultURL = config.defaultURL || "/";
147
- const basePath = config.basePath || "";
148
- if (isPrismicNextQuery(config.req.query)) {
149
- const previewUrl = await config.client.resolvePreviewURL({
150
- linkResolver: config.linkResolver,
151
- defaultURL,
152
- documentID: config.req.query.documentId,
153
- previewToken: config.req.query.token
154
- });
155
- config.res.redirect(basePath + previewUrl);
156
- return;
157
- }
158
- config.res.redirect(basePath + defaultURL);
159
- }
160
-
161
- const camelCaseToParamCase = (input) => {
162
- return input.replace(/[A-Z]/g, (match) => {
163
- return `-${match.toLowerCase()}`;
164
- });
165
- };
166
- const buildURL = (url, params) => {
167
- const instance = new URL(url);
168
- for (const camelCasedParamKey in params) {
169
- const paramKey = camelCaseToParamCase(camelCasedParamKey);
170
- const paramValue = params[camelCasedParamKey];
171
- if (paramValue === void 0) {
172
- instance.searchParams.delete(paramKey);
173
- } else if (Array.isArray(paramValue)) {
174
- instance.searchParams.set(paramKey, paramValue.join(","));
175
- } else {
176
- instance.searchParams.set(paramKey, `${paramValue}`);
177
- }
178
- }
179
- const s = instance.searchParams.get("s");
180
- if (s) {
181
- instance.searchParams.delete("s");
182
- instance.searchParams.append("s", s);
183
- }
184
- return instance.toString();
185
- };
186
-
187
- const __PRODUCTION__ = process.env.NODE_ENV === "production";
188
-
189
- var version = "0.1.3";
190
-
191
- const devMsg = (slug) => {
192
- return `https://prismic.dev/msg/next/v${version}/${slug}`;
193
- };
194
-
195
- const imgixLoader = (args) => {
196
- const url = new URL(args.src);
197
- const params = {
198
- fit: url.searchParams.get("fit") || "max",
199
- w: args.width,
200
- h: void 0
201
- };
202
- if (args.quality) {
203
- params.q = args.quality;
204
- }
205
- return buildURL(args.src, params);
206
- };
207
- const PrismicNextImage = ({
208
- field,
209
- imgixParams = {},
210
- alt,
211
- fallbackAlt,
212
- layout,
213
- ...restProps
214
- }) => {
215
- if (!__PRODUCTION__) {
216
- if (typeof alt === "string" && alt !== "") {
217
- console.warn(`[PrismicNextImage] The "alt" prop can only be used to declare an image as decorative by passing an empty string (alt="") but was provided a non-empty string. You can resolve this warning by removing the "alt" prop or changing it to alt="". For more details, see ${devMsg("alt-must-be-an-empty-string")}`);
218
- }
219
- if (typeof fallbackAlt === "string" && fallbackAlt !== "") {
220
- console.warn(`[PrismicNextImage] The "fallbackAlt" prop can only be used to declare an image as decorative by passing an empty string (fallbackAlt="") but was provided a non-empty string. You can resolve this warning by removing the "fallbackAlt" prop or changing it to fallbackAlt="". For more details, see ${devMsg("alt-must-be-an-empty-string")}`);
221
- }
222
- }
223
- if (prismicH__namespace.isFilled.imageThumbnail(field)) {
224
- const src = buildURL(field.url, imgixParams);
225
- return /* @__PURE__ */ React__namespace.createElement(Image__default["default"], {
226
- src,
227
- width: layout === "fill" ? void 0 : field.dimensions.width,
228
- height: layout === "fill" ? void 0 : field.dimensions.height,
229
- alt: alt != null ? alt : field.alt || fallbackAlt,
230
- loader: imgixLoader,
231
- layout,
232
- ...restProps
233
- });
234
- } else {
235
- return null;
236
- }
237
- };
238
-
239
- exports.PrismicNextImage = PrismicNextImage;
240
- exports.PrismicPreview = PrismicPreview;
241
- exports.enableAutoPreviews = enableAutoPreviews;
242
- exports.exitPreview = exitPreview;
243
- exports.redirectToPreviewURL = redirectToPreviewURL;
244
- exports.setPreviewData = setPreviewData;
package/dist/index.js DELETED
@@ -1,210 +0,0 @@
1
- import * as prismic from '@prismicio/client';
2
- import * as React from 'react';
3
- import { PrismicToolbar } from '@prismicio/react';
4
- import { useRouter } from 'next/router';
5
- import Image from 'next/image';
6
- import * as prismicH from '@prismicio/helpers';
7
-
8
- function setPreviewData({ req, res }) {
9
- const ref = req.query.token || req.cookies[prismic.cookie.preview];
10
- if (ref) {
11
- res.setPreviewData({ ref });
12
- }
13
- }
14
-
15
- function exitPreview(config) {
16
- config.res.clearPreviewData();
17
- config.res.json({ success: true });
18
- }
19
-
20
- const readValue = (value) => {
21
- return value.replace(/%3B/g, ";");
22
- };
23
- const getCookie = (name, cookieJar) => {
24
- const cookies = cookieJar.split("; ");
25
- for (const cookie of cookies) {
26
- const parts = cookie.split("=");
27
- const thisName = readValue(parts[0]).replace(/%3D/g, "=");
28
- if (thisName === name) {
29
- const value = parts.slice(1).join("=");
30
- return readValue(value);
31
- }
32
- }
33
- };
34
-
35
- const getPreviewCookieRepositoryName = (previewCookie) => {
36
- return (decodeURIComponent(previewCookie).match(/"(.+).prismic.io"/) || [])[1];
37
- };
38
-
39
- function PrismicPreview({
40
- repositoryName,
41
- children,
42
- updatePreviewURL = "/api/preview",
43
- exitPreviewURL = "/api/exit-preview"
44
- }) {
45
- const router = useRouter();
46
- const resolvedUpdatePreviewURL = router.basePath + updatePreviewURL;
47
- const resolvedExitPreviewURL = router.basePath + exitPreviewURL;
48
- React.useEffect(() => {
49
- const startPreviewMode = async () => {
50
- const res = await globalThis.fetch(resolvedUpdatePreviewURL);
51
- if (res.ok) {
52
- globalThis.location.reload();
53
- } else {
54
- console.error(`[<PrismicPreview>] Failed to start or update Preview Mode using the "${resolvedUpdatePreviewURL}" API endpoint. Does it exist?`);
55
- }
56
- };
57
- const handlePrismicPreviewUpdate = async (event) => {
58
- event.preventDefault();
59
- await startPreviewMode();
60
- };
61
- const handlePrismicPreviewEnd = async (event) => {
62
- event.preventDefault();
63
- const res = await globalThis.fetch(resolvedExitPreviewURL);
64
- if (res.ok) {
65
- globalThis.location.reload();
66
- } else {
67
- console.error(`[<PrismicPreview>] Failed to exit Preview Mode using the "${resolvedExitPreviewURL}" API endpoint. Does it exist?`);
68
- }
69
- };
70
- if (router.isPreview) {
71
- window.addEventListener("prismicPreviewUpdate", handlePrismicPreviewUpdate);
72
- window.addEventListener("prismicPreviewEnd", handlePrismicPreviewEnd);
73
- } else {
74
- const prismicPreviewCookie = getCookie(prismic.cookie.preview, globalThis.document.cookie);
75
- if (prismicPreviewCookie) {
76
- const locationIsDescendantOfBasePath = window.location.href.startsWith(window.location.origin + router.basePath);
77
- const prismicPreviewCookieRepositoryName = getPreviewCookieRepositoryName(prismicPreviewCookie);
78
- if (locationIsDescendantOfBasePath && prismicPreviewCookieRepositoryName === repositoryName) {
79
- startPreviewMode();
80
- }
81
- }
82
- }
83
- return () => {
84
- window.removeEventListener("prismicPreviewUpdate", handlePrismicPreviewUpdate);
85
- window.removeEventListener("prismicPreviewEnd", handlePrismicPreviewEnd);
86
- };
87
- }, [
88
- repositoryName,
89
- resolvedExitPreviewURL,
90
- resolvedUpdatePreviewURL,
91
- router.isPreview,
92
- router.basePath
93
- ]);
94
- return /* @__PURE__ */ React.createElement(React.Fragment, null, children, /* @__PURE__ */ React.createElement(PrismicToolbar, {
95
- repositoryName
96
- }));
97
- }
98
-
99
- const isPrismicNextPreviewData = (previewData) => {
100
- return typeof previewData === "object" && "ref" in previewData;
101
- };
102
- const enableAutoPreviews = (config) => {
103
- if ("previewData" in config && config.previewData) {
104
- const { previewData } = config;
105
- if (isPrismicNextPreviewData(previewData) && previewData.ref) {
106
- config.client.queryContentFromRef(previewData.ref);
107
- }
108
- } else if ("req" in config && config.req) {
109
- config.client.enableAutoPreviewsFromReq(config.req);
110
- }
111
- };
112
-
113
- const isPrismicNextQuery = (query) => {
114
- return typeof query.documentId === "string" && typeof query.token === "string";
115
- };
116
- async function redirectToPreviewURL(config) {
117
- const defaultURL = config.defaultURL || "/";
118
- const basePath = config.basePath || "";
119
- if (isPrismicNextQuery(config.req.query)) {
120
- const previewUrl = await config.client.resolvePreviewURL({
121
- linkResolver: config.linkResolver,
122
- defaultURL,
123
- documentID: config.req.query.documentId,
124
- previewToken: config.req.query.token
125
- });
126
- config.res.redirect(basePath + previewUrl);
127
- return;
128
- }
129
- config.res.redirect(basePath + defaultURL);
130
- }
131
-
132
- const camelCaseToParamCase = (input) => {
133
- return input.replace(/[A-Z]/g, (match) => {
134
- return `-${match.toLowerCase()}`;
135
- });
136
- };
137
- const buildURL = (url, params) => {
138
- const instance = new URL(url);
139
- for (const camelCasedParamKey in params) {
140
- const paramKey = camelCaseToParamCase(camelCasedParamKey);
141
- const paramValue = params[camelCasedParamKey];
142
- if (paramValue === void 0) {
143
- instance.searchParams.delete(paramKey);
144
- } else if (Array.isArray(paramValue)) {
145
- instance.searchParams.set(paramKey, paramValue.join(","));
146
- } else {
147
- instance.searchParams.set(paramKey, `${paramValue}`);
148
- }
149
- }
150
- const s = instance.searchParams.get("s");
151
- if (s) {
152
- instance.searchParams.delete("s");
153
- instance.searchParams.append("s", s);
154
- }
155
- return instance.toString();
156
- };
157
-
158
- const __PRODUCTION__ = process.env.NODE_ENV === "production";
159
-
160
- var version = "0.1.3";
161
-
162
- const devMsg = (slug) => {
163
- return `https://prismic.dev/msg/next/v${version}/${slug}`;
164
- };
165
-
166
- const imgixLoader = (args) => {
167
- const url = new URL(args.src);
168
- const params = {
169
- fit: url.searchParams.get("fit") || "max",
170
- w: args.width,
171
- h: void 0
172
- };
173
- if (args.quality) {
174
- params.q = args.quality;
175
- }
176
- return buildURL(args.src, params);
177
- };
178
- const PrismicNextImage = ({
179
- field,
180
- imgixParams = {},
181
- alt,
182
- fallbackAlt,
183
- layout,
184
- ...restProps
185
- }) => {
186
- if (!__PRODUCTION__) {
187
- if (typeof alt === "string" && alt !== "") {
188
- console.warn(`[PrismicNextImage] The "alt" prop can only be used to declare an image as decorative by passing an empty string (alt="") but was provided a non-empty string. You can resolve this warning by removing the "alt" prop or changing it to alt="". For more details, see ${devMsg("alt-must-be-an-empty-string")}`);
189
- }
190
- if (typeof fallbackAlt === "string" && fallbackAlt !== "") {
191
- console.warn(`[PrismicNextImage] The "fallbackAlt" prop can only be used to declare an image as decorative by passing an empty string (fallbackAlt="") but was provided a non-empty string. You can resolve this warning by removing the "fallbackAlt" prop or changing it to fallbackAlt="". For more details, see ${devMsg("alt-must-be-an-empty-string")}`);
192
- }
193
- }
194
- if (prismicH.isFilled.imageThumbnail(field)) {
195
- const src = buildURL(field.url, imgixParams);
196
- return /* @__PURE__ */ React.createElement(Image, {
197
- src,
198
- width: layout === "fill" ? void 0 : field.dimensions.width,
199
- height: layout === "fill" ? void 0 : field.dimensions.height,
200
- alt: alt != null ? alt : field.alt || fallbackAlt,
201
- loader: imgixLoader,
202
- layout,
203
- ...restProps
204
- });
205
- } else {
206
- return null;
207
- }
208
- };
209
-
210
- export { PrismicNextImage, PrismicPreview, enableAutoPreviews, exitPreview, redirectToPreviewURL, setPreviewData };