@webiny/website-builder-nextjs 0.0.0-unstable.e6f0dc8ca7 → 0.0.0-unstable.e9333b3f0b
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/DocumentRenderer.js +12 -12
- package/DocumentRenderer.js.map +1 -1
- package/editorComponents/Image.d.ts +2 -10
- package/editorComponents/Image.js +75 -83
- package/editorComponents/Image.js.map +1 -1
- package/editorComponents/Image.manifest.js +38 -38
- package/editorComponents/Image.manifest.js.map +1 -1
- package/index.js +5 -9
- package/index.js.map +1 -1
- package/middleware.d.ts +44 -0
- package/middleware.js +59 -0
- package/middleware.js.map +1 -0
- package/package.json +14 -12
- package/webpack.js +38 -50
- package/webpack.js.map +1 -1
package/DocumentRenderer.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { DocumentRenderer
|
|
1
|
+
import react from "react";
|
|
2
|
+
import { DocumentRenderer } from "@webiny/website-builder-react";
|
|
3
3
|
import { Image } from "./editorComponents/Image.manifest.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}, children);
|
|
4
|
+
const DocumentRenderer_DocumentRenderer = ({ document, components, children })=>{
|
|
5
|
+
const allComponents = [
|
|
6
|
+
Image,
|
|
7
|
+
...components
|
|
8
|
+
];
|
|
9
|
+
return /*#__PURE__*/ react.createElement(DocumentRenderer, {
|
|
10
|
+
document: document,
|
|
11
|
+
components: allComponents
|
|
12
|
+
}, children);
|
|
14
13
|
};
|
|
14
|
+
export { DocumentRenderer_DocumentRenderer as DocumentRenderer };
|
|
15
15
|
|
|
16
16
|
//# sourceMappingURL=DocumentRenderer.js.map
|
package/DocumentRenderer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"DocumentRenderer.js","sources":["../src/DocumentRenderer.tsx"],"sourcesContent":["import React from \"react\";\nimport { DocumentRenderer as BaseDocumentRenderer } from \"@webiny/website-builder-react\";\nimport { Image } from \"~/editorComponents/Image.manifest.js\";\n\nexport type DocumentRendererProps = React.ComponentProps<typeof BaseDocumentRenderer>;\n\nexport const DocumentRenderer = ({ document, components, children }: DocumentRendererProps) => {\n const allComponents = [Image, ...components];\n return (\n <BaseDocumentRenderer document={document} components={allComponents}>\n {children}\n </BaseDocumentRenderer>\n );\n};\n"],"names":["DocumentRenderer","document","components","children","allComponents","Image","BaseDocumentRenderer"],"mappings":";;;AAMO,MAAMA,oCAAmB,CAAC,EAAEC,QAAQ,EAAEC,UAAU,EAAEC,QAAQ,EAAyB;IACtF,MAAMC,gBAAgB;QAACC;WAAUH;KAAW;IAC5C,OAAO,WAAP,GACI,oBAACI,kBAAoBA;QAAC,UAAUL;QAAU,YAAYG;OACjDD;AAGb"}
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type { ComponentProps } from "@webiny/website-builder-react";
|
|
2
|
+
import type { ComponentProps, Asset } from "@webiny/website-builder-react";
|
|
3
3
|
type ImageProps = ComponentProps<{
|
|
4
4
|
title: string;
|
|
5
5
|
altText: string;
|
|
6
6
|
highPriority: boolean;
|
|
7
|
-
image:
|
|
8
|
-
id: string;
|
|
9
|
-
name: string;
|
|
10
|
-
size: number;
|
|
11
|
-
mimeType: string;
|
|
12
|
-
src: string;
|
|
13
|
-
width: number;
|
|
14
|
-
height: number;
|
|
15
|
-
};
|
|
7
|
+
image: Asset;
|
|
16
8
|
}>;
|
|
17
9
|
export declare const ImageComponent: (props: ImageProps) => React.JSX.Element;
|
|
18
10
|
export {};
|
|
@@ -1,89 +1,81 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import react from "react";
|
|
2
|
+
import next_image from "next/image";
|
|
3
|
+
import { getAssetUrl, getImageDimensions, getImageSrcSet, normalizeToAsset } from "@webiny/website-builder-react";
|
|
4
|
+
const ImageComponent = (props)=>{
|
|
5
|
+
const { title = "", altText, image, highPriority } = props.inputs;
|
|
6
|
+
const asset = normalizeToAsset(image);
|
|
7
|
+
if (!asset?.src) return /*#__PURE__*/ react.createElement(ImagePlaceholder, {
|
|
8
|
+
style: props.styles
|
|
8
9
|
});
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
const alt = altText || asset.image?.alt || "";
|
|
11
|
+
if (asset.src.endsWith(".svg")) return /*#__PURE__*/ react.createElement("object", {
|
|
12
|
+
style: {
|
|
13
|
+
maxWidth: "100%",
|
|
14
|
+
...props.styles
|
|
15
|
+
},
|
|
16
|
+
title: title,
|
|
17
|
+
data: asset.src
|
|
15
18
|
});
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const loader = ({ width })=>getAssetUrl(asset, {
|
|
20
|
+
width,
|
|
21
|
+
format: "auto"
|
|
22
|
+
});
|
|
23
|
+
const { width, height } = getImageDimensions(asset);
|
|
24
|
+
const style = {
|
|
25
|
+
maxWidth: "100%",
|
|
26
|
+
height: "auto",
|
|
27
|
+
...props.styles
|
|
28
|
+
};
|
|
29
|
+
if (!width || !height) {
|
|
30
|
+
const { src, srcSet } = getImageSrcSet(asset, {
|
|
31
|
+
format: "auto",
|
|
32
|
+
cssWidth: props.styles?.width
|
|
33
|
+
});
|
|
34
|
+
return /*#__PURE__*/ react.createElement("img", {
|
|
35
|
+
src: src,
|
|
36
|
+
srcSet: srcSet,
|
|
37
|
+
sizes: "100vw",
|
|
38
|
+
alt: alt,
|
|
39
|
+
title: title || void 0,
|
|
40
|
+
loading: highPriority ? "eager" : "lazy",
|
|
41
|
+
style: style
|
|
42
|
+
});
|
|
21
43
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
src,
|
|
34
|
-
width
|
|
35
|
-
}) => `${src}?width=${width}`
|
|
36
|
-
}));
|
|
37
|
-
};
|
|
38
|
-
const ImagePlaceholder = ({
|
|
39
|
-
style
|
|
40
|
-
}) => {
|
|
41
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
42
|
-
style: {
|
|
43
|
-
display: "flex",
|
|
44
|
-
height: "200px",
|
|
45
|
-
backgroundColor: "#f4f4f4",
|
|
46
|
-
justifyContent: "center",
|
|
47
|
-
alignItems: "center",
|
|
48
|
-
fill: "#ffffff",
|
|
49
|
-
...style
|
|
50
|
-
}
|
|
51
|
-
}, /*#__PURE__*/React.createElement("svg", {
|
|
52
|
-
style: {
|
|
53
|
-
width: "70px",
|
|
54
|
-
height: "70px",
|
|
55
|
-
filter: "drop-shadow(rgba(0, 0, 0, 0.16) 0px 1px 0px)"
|
|
56
|
-
},
|
|
57
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
58
|
-
height: "24px",
|
|
59
|
-
viewBox: "0 -960 960 960",
|
|
60
|
-
width: "24px"
|
|
61
|
-
}, /*#__PURE__*/React.createElement("path", {
|
|
62
|
-
d: "M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm40-80h480L570-480 450-320l-90-120-120 160Zm-40 80v-560 560Z"
|
|
63
|
-
})));
|
|
64
|
-
};
|
|
65
|
-
const useImage = ({
|
|
66
|
-
inputs,
|
|
67
|
-
styles
|
|
68
|
-
}) => {
|
|
69
|
-
const {
|
|
70
|
-
title = "",
|
|
71
|
-
altText,
|
|
72
|
-
image
|
|
73
|
-
} = inputs;
|
|
74
|
-
const src = image?.src;
|
|
75
|
-
const tag = src && src.endsWith(".svg") ? "object" : "img";
|
|
76
|
-
const imageStyles = {
|
|
77
|
-
maxWidth: "100%",
|
|
78
|
-
...styles
|
|
79
|
-
};
|
|
80
|
-
return {
|
|
81
|
-
altText,
|
|
82
|
-
src: inputs.image?.src,
|
|
83
|
-
styles: imageStyles,
|
|
84
|
-
tag,
|
|
85
|
-
title
|
|
86
|
-
};
|
|
44
|
+
return /*#__PURE__*/ react.createElement(next_image, {
|
|
45
|
+
src: asset.src,
|
|
46
|
+
loader: loader,
|
|
47
|
+
alt: alt,
|
|
48
|
+
title: title || void 0,
|
|
49
|
+
width: width,
|
|
50
|
+
height: height,
|
|
51
|
+
sizes: "100vw",
|
|
52
|
+
priority: highPriority,
|
|
53
|
+
style: style
|
|
54
|
+
});
|
|
87
55
|
};
|
|
56
|
+
const ImagePlaceholder = ({ style })=>/*#__PURE__*/ react.createElement("div", {
|
|
57
|
+
style: {
|
|
58
|
+
display: "flex",
|
|
59
|
+
height: "200px",
|
|
60
|
+
backgroundColor: "#f4f4f4",
|
|
61
|
+
justifyContent: "center",
|
|
62
|
+
alignItems: "center",
|
|
63
|
+
fill: "#ffffff",
|
|
64
|
+
...style
|
|
65
|
+
}
|
|
66
|
+
}, /*#__PURE__*/ react.createElement("svg", {
|
|
67
|
+
style: {
|
|
68
|
+
width: "70px",
|
|
69
|
+
height: "70px",
|
|
70
|
+
filter: "drop-shadow(rgba(0, 0, 0, 0.16) 0px 1px 0px)"
|
|
71
|
+
},
|
|
72
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
73
|
+
height: "24px",
|
|
74
|
+
viewBox: "0 -960 960 960",
|
|
75
|
+
width: "24px"
|
|
76
|
+
}, /*#__PURE__*/ react.createElement("path", {
|
|
77
|
+
d: "M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm40-80h480L570-480 450-320l-90-120-120 160Zm-40 80v-560 560Z"
|
|
78
|
+
})));
|
|
79
|
+
export { ImageComponent };
|
|
88
80
|
|
|
89
81
|
//# sourceMappingURL=Image.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"editorComponents/Image.js","sources":["../../src/editorComponents/Image.tsx"],"sourcesContent":["import React from \"react\";\nimport NextImage from \"next/image\";\nimport type { ComponentProps, CssProperties, Asset } from \"@webiny/website-builder-react\";\nimport {\n getAssetUrl,\n getImageDimensions,\n getImageSrcSet,\n normalizeToAsset\n} from \"@webiny/website-builder-react\";\n\ntype ImageProps = ComponentProps<{\n title: string;\n altText: string;\n highPriority: boolean;\n // Accepts the unified asset shape or a legacy value (existing pages).\n image: Asset;\n}>;\n\nexport const ImageComponent = (props: ImageProps) => {\n const { title = \"\", altText, image, highPriority } = props.inputs;\n const asset = normalizeToAsset(image);\n\n if (!asset?.src) {\n return <ImagePlaceholder style={props.styles} />;\n }\n\n const alt = altText || asset.image?.alt || \"\";\n\n // SVGs are vector — nothing to crop, resize, or re-encode.\n if (asset.src.endsWith(\".svg\")) {\n return (\n <object style={{ maxWidth: \"100%\", ...props.styles }} title={title} data={asset.src} />\n );\n }\n\n // The delivery bakes the per-usage crop (`?crop`), resizes (`?width`), and serves\n // a modern format negotiated from Accept (`?format=auto`). We hand `next/image` a\n // loader that builds that URL, and it drives the responsive `srcSet`.\n const loader = ({ width }: { width: number }) => getAssetUrl(asset, { width, format: \"auto\" });\n\n // Intrinsic size of the *delivered* (cropped) image, so next/image lays out at\n // the correct aspect ratio. Falls back to a plain <img> when dimensions are\n // unknown (next/image requires width + height unless `fill`).\n const { width, height } = getImageDimensions(asset);\n\n const style: CssProperties = { maxWidth: \"100%\", height: \"auto\", ...props.styles };\n\n if (!width || !height) {\n // No intrinsic size to lay out with — fall back to a plain <img>, still\n // responsive via the SDK's framework-agnostic srcSet (crop/format baked in).\n const { src, srcSet } = getImageSrcSet(asset, {\n format: \"auto\",\n cssWidth: props.styles?.width\n });\n // eslint-disable-next-line @next/next/no-img-element\n return (\n <img\n src={src}\n srcSet={srcSet}\n sizes=\"100vw\"\n alt={alt}\n title={title || undefined}\n loading={highPriority ? \"eager\" : \"lazy\"}\n style={style}\n />\n );\n }\n\n return (\n <NextImage\n src={asset.src}\n loader={loader}\n alt={alt}\n title={title || undefined}\n width={width}\n height={height}\n sizes={\"100vw\"}\n priority={highPriority}\n style={style}\n />\n );\n};\n\nconst ImagePlaceholder = ({ style }: { style: CssProperties }) => {\n return (\n <div\n style={{\n display: \"flex\",\n height: \"200px\",\n backgroundColor: \"#f4f4f4\",\n justifyContent: \"center\",\n alignItems: \"center\",\n fill: \"#ffffff\",\n ...style\n }}\n >\n <svg\n style={{\n width: \"70px\",\n height: \"70px\",\n filter: \"drop-shadow(rgba(0, 0, 0, 0.16) 0px 1px 0px)\"\n }}\n xmlns=\"http://www.w3.org/2000/svg\"\n height=\"24px\"\n viewBox=\"0 -960 960 960\"\n width=\"24px\"\n >\n <path d=\"M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm40-80h480L570-480 450-320l-90-120-120 160Zm-40 80v-560 560Z\" />\n </svg>\n </div>\n );\n};\n"],"names":["ImageComponent","props","title","altText","image","highPriority","asset","normalizeToAsset","ImagePlaceholder","alt","loader","width","getAssetUrl","height","getImageDimensions","style","src","srcSet","getImageSrcSet","undefined","NextImage"],"mappings":";;;AAkBO,MAAMA,iBAAiB,CAACC;IAC3B,MAAM,EAAEC,QAAQ,EAAE,EAAEC,OAAO,EAAEC,KAAK,EAAEC,YAAY,EAAE,GAAGJ,MAAM,MAAM;IACjE,MAAMK,QAAQC,iBAAiBH;IAE/B,IAAI,CAACE,OAAO,KACR,OAAO,WAAP,GAAO,oBAACE,kBAAgBA;QAAC,OAAOP,MAAM,MAAM;;IAGhD,MAAMQ,MAAMN,WAAWG,MAAM,KAAK,EAAE,OAAO;IAG3C,IAAIA,MAAM,GAAG,CAAC,QAAQ,CAAC,SACnB,OAAO,WAAP,GACI,oBAAC;QAAO,OAAO;YAAE,UAAU;YAAQ,GAAGL,MAAM,MAAM;QAAC;QAAG,OAAOC;QAAO,MAAMI,MAAM,GAAG;;IAO3F,MAAMI,SAAS,CAAC,EAAEC,KAAK,EAAqB,GAAKC,YAAYN,OAAO;YAAEK;YAAO,QAAQ;QAAO;IAK5F,MAAM,EAAEA,KAAK,EAAEE,MAAM,EAAE,GAAGC,mBAAmBR;IAE7C,MAAMS,QAAuB;QAAE,UAAU;QAAQ,QAAQ;QAAQ,GAAGd,MAAM,MAAM;IAAC;IAEjF,IAAI,CAACU,SAAS,CAACE,QAAQ;QAGnB,MAAM,EAAEG,GAAG,EAAEC,MAAM,EAAE,GAAGC,eAAeZ,OAAO;YAC1C,QAAQ;YACR,UAAUL,MAAM,MAAM,EAAE;QAC5B;QAEA,OAAO,WAAP,GACI,oBAAC;YACG,KAAKe;YACL,QAAQC;YACR,OAAM;YACN,KAAKR;YACL,OAAOP,SAASiB;YAChB,SAASd,eAAe,UAAU;YAClC,OAAOU;;IAGnB;IAEA,OAAO,WAAP,GACI,oBAACK,YAASA;QACN,KAAKd,MAAM,GAAG;QACd,QAAQI;QACR,KAAKD;QACL,OAAOP,SAASiB;QAChB,OAAOR;QACP,QAAQE;QACR,OAAO;QACP,UAAUR;QACV,OAAOU;;AAGnB;AAEA,MAAMP,mBAAmB,CAAC,EAAEO,KAAK,EAA4B,GAClD,WAAP,GACI,oBAAC;QACG,OAAO;YACH,SAAS;YACT,QAAQ;YACR,iBAAiB;YACjB,gBAAgB;YAChB,YAAY;YACZ,MAAM;YACN,GAAGA,KAAK;QACZ;qBAEA,oBAAC;QACG,OAAO;YACH,OAAO;YACP,QAAQ;YACR,QAAQ;QACZ;QACA,OAAM;QACN,QAAO;QACP,SAAQ;QACR,OAAM;qBAEN,oBAAC;QAAK,GAAE"}
|
|
@@ -1,45 +1,45 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
|
|
3
|
-
import { createFileInput, createTextInput, createBooleanInput, createComponent } from "@webiny/website-builder-react";
|
|
2
|
+
import { createBooleanInput, createComponent, createFileInput, createTextInput } from "@webiny/website-builder-react";
|
|
4
3
|
import { ImageComponent } from "./Image.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
4
|
+
const Image = createComponent(ImageComponent, {
|
|
5
|
+
name: "Webiny/Image",
|
|
6
|
+
label: "Image",
|
|
7
|
+
group: "basic",
|
|
8
|
+
image: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm40-80h480L570-480 450-320l-90-120-120 160Zm-40 80v-560 560Z"/></svg>',
|
|
9
|
+
autoApplyStyles: false,
|
|
10
|
+
inputs: {
|
|
11
|
+
image: createFileInput({
|
|
12
|
+
label: "Image",
|
|
13
|
+
allowedFileTypes: [
|
|
14
|
+
"image/*"
|
|
15
|
+
],
|
|
16
|
+
onChange: ({ inputs })=>{
|
|
17
|
+
if (inputs.image) {
|
|
18
|
+
inputs.title = inputs.image.name;
|
|
19
|
+
inputs.altText = inputs.image.name;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}),
|
|
23
|
+
title: createTextInput({
|
|
24
|
+
label: "Title",
|
|
25
|
+
description: "Title of the image"
|
|
26
|
+
}),
|
|
27
|
+
altText: createTextInput({
|
|
28
|
+
label: "Alternate Text",
|
|
29
|
+
description: "Shown when the user has disabled images"
|
|
30
|
+
}),
|
|
31
|
+
highPriority: createBooleanInput({
|
|
32
|
+
label: "High Priority",
|
|
33
|
+
description: "Prioritize this image loading over other images on the page",
|
|
34
|
+
defaultValue: false
|
|
35
|
+
})
|
|
36
|
+
},
|
|
37
|
+
defaults: {
|
|
38
|
+
styles: {
|
|
39
|
+
width: "100%"
|
|
21
40
|
}
|
|
22
|
-
}
|
|
23
|
-
}),
|
|
24
|
-
title: createTextInput({
|
|
25
|
-
label: "Title",
|
|
26
|
-
description: "Title of the image"
|
|
27
|
-
}),
|
|
28
|
-
altText: createTextInput({
|
|
29
|
-
label: "Alternate Text",
|
|
30
|
-
description: "Shown when the user has disabled images"
|
|
31
|
-
}),
|
|
32
|
-
highPriority: createBooleanInput({
|
|
33
|
-
label: "High Priority",
|
|
34
|
-
description: "Prioritize this image loading over other images on the page",
|
|
35
|
-
defaultValue: false
|
|
36
|
-
})
|
|
37
|
-
},
|
|
38
|
-
defaults: {
|
|
39
|
-
styles: {
|
|
40
|
-
width: "100%"
|
|
41
41
|
}
|
|
42
|
-
}
|
|
43
42
|
});
|
|
43
|
+
export { Image };
|
|
44
44
|
|
|
45
45
|
//# sourceMappingURL=Image.manifest.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"editorComponents/Image.manifest.js","sources":["../../src/editorComponents/Image.manifest.ts"],"sourcesContent":["\"use client\";\nimport {\n createFileInput,\n createTextInput,\n createBooleanInput,\n createComponent\n} from \"@webiny/website-builder-react\";\nimport { ImageComponent } from \"./Image.js\";\n\nexport const Image = createComponent(ImageComponent, {\n name: \"Webiny/Image\",\n label: \"Image\",\n group: \"basic\",\n image: `<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"><path d=\"M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm40-80h480L570-480 450-320l-90-120-120 160Zm-40 80v-560 560Z\"/></svg>`,\n autoApplyStyles: false,\n inputs: {\n image: createFileInput({\n label: \"Image\",\n allowedFileTypes: [\"image/*\"],\n onChange: ({ inputs }) => {\n if (inputs.image) {\n inputs.title = inputs.image.name;\n inputs.altText = inputs.image.name;\n }\n }\n }),\n title: createTextInput({\n label: \"Title\",\n description: \"Title of the image\"\n }),\n altText: createTextInput({\n label: \"Alternate Text\",\n description: \"Shown when the user has disabled images\"\n }),\n highPriority: createBooleanInput({\n label: \"High Priority\",\n description: \"Prioritize this image loading over other images on the page\",\n defaultValue: false\n })\n },\n defaults: {\n styles: {\n width: \"100%\"\n }\n }\n});\n"],"names":["Image","createComponent","ImageComponent","createFileInput","inputs","createTextInput","createBooleanInput"],"mappings":";;;AASO,MAAMA,QAAQC,gBAAgBC,gBAAgB;IACjD,MAAM;IACN,OAAO;IACP,OAAO;IACP,OAAO;IACP,iBAAiB;IACjB,QAAQ;QACJ,OAAOC,gBAAgB;YACnB,OAAO;YACP,kBAAkB;gBAAC;aAAU;YAC7B,UAAU,CAAC,EAAEC,MAAM,EAAE;gBACjB,IAAIA,OAAO,KAAK,EAAE;oBACdA,OAAO,KAAK,GAAGA,OAAO,KAAK,CAAC,IAAI;oBAChCA,OAAO,OAAO,GAAGA,OAAO,KAAK,CAAC,IAAI;gBACtC;YACJ;QACJ;QACA,OAAOC,gBAAgB;YACnB,OAAO;YACP,aAAa;QACjB;QACA,SAASA,gBAAgB;YACrB,OAAO;YACP,aAAa;QACjB;QACA,cAAcC,mBAAmB;YAC7B,OAAO;YACP,aAAa;YACb,cAAc;QAClB;IACJ;IACA,UAAU;QACN,QAAQ;YACJ,OAAO;QACX;IACJ;AACJ"}
|
package/index.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
export * from "@webiny/website-builder-react";
|
|
2
|
-
export { DocumentRenderer } from "./DocumentRenderer.js";
|
|
3
1
|
import { setHeadersProvider } from "@webiny/website-builder-react";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
headers
|
|
9
|
-
} = await import("next/headers.js");
|
|
10
|
-
return await headers();
|
|
2
|
+
export * from "@webiny/website-builder-react";
|
|
3
|
+
setHeadersProvider(async ()=>{
|
|
4
|
+
const { headers } = await import("next/headers.js");
|
|
5
|
+
return await headers();
|
|
11
6
|
});
|
|
7
|
+
export { DocumentRenderer } from "./DocumentRenderer.js";
|
|
12
8
|
|
|
13
9
|
//# sourceMappingURL=index.js.map
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["export * from \"@webiny/website-builder-react\";\nexport { DocumentRenderer } from \"./DocumentRenderer.js\";\n\nimport { setHeadersProvider } from \"@webiny/website-builder-react\";\n\nsetHeadersProvider(async () => {\n // Settings @ts-expect-error breaks the build if the dependency is installed in the repo.\n // @ts-ignore This is a peer dependency.\n const { headers } = await import(\"next/headers.js\");\n return await headers();\n});\n"],"names":["setHeadersProvider","headers"],"mappings":";;AAKAA,mBAAmB;IAGf,MAAM,EAAEC,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC;IACjC,OAAO,MAAMA;AACjB"}
|
package/middleware.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js middleware for Website Builder.
|
|
3
|
+
*
|
|
4
|
+
* Handles the two request-time concerns an app would otherwise hand-write:
|
|
5
|
+
* - **Preview / draft mode** — routes `?wb.preview`/`?wb.editing` requests through the draft-mode
|
|
6
|
+
* route and disables caching while previewing; exits preview when the flag is gone.
|
|
7
|
+
* - **A/B visitor cookie** — sets a stable, PII-free `wb_ab_vid` cookie so variant bucketing is
|
|
8
|
+
* deterministic across visits.
|
|
9
|
+
*
|
|
10
|
+
* `next` is a peer dependency and is imported dynamically so building this package never requires
|
|
11
|
+
* it. Drop into a project as:
|
|
12
|
+
*
|
|
13
|
+
* // middleware.ts
|
|
14
|
+
* export { middleware, config } from "@webiny/website-builder-nextjs/middleware";
|
|
15
|
+
*/
|
|
16
|
+
interface MiddlewareRequest {
|
|
17
|
+
url: string;
|
|
18
|
+
nextUrl: {
|
|
19
|
+
searchParams: URLSearchParams;
|
|
20
|
+
pathname: string;
|
|
21
|
+
};
|
|
22
|
+
headers: Headers;
|
|
23
|
+
cookies: {
|
|
24
|
+
get(name: string): {
|
|
25
|
+
value: string;
|
|
26
|
+
} | undefined;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export interface WebsiteBuilderMiddlewareOptions {
|
|
30
|
+
/** Route that enables Next.js draft mode for preview. Defaults to `/api/preview`. */
|
|
31
|
+
previewRoute?: string;
|
|
32
|
+
/** A/B bucketing cookie name. Defaults to `wb_ab_vid`. */
|
|
33
|
+
visitorCookieName?: string;
|
|
34
|
+
/** A/B bucketing cookie max-age in seconds. Defaults to one year. */
|
|
35
|
+
visitorCookieMaxAge?: number;
|
|
36
|
+
}
|
|
37
|
+
export declare function createWebsiteBuilderMiddleware(options?: WebsiteBuilderMiddlewareOptions): (request: MiddlewareRequest) => Promise<import("next/server").NextResponse<unknown>>;
|
|
38
|
+
/** Turnkey middleware with default options. */
|
|
39
|
+
export declare const middleware: (request: MiddlewareRequest) => Promise<import("next/server").NextResponse<unknown>>;
|
|
40
|
+
/** Default matcher: everything except Next internals, API routes, and static assets. */
|
|
41
|
+
export declare const config: {
|
|
42
|
+
matcher: string[];
|
|
43
|
+
};
|
|
44
|
+
export {};
|
package/middleware.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const DEFAULT_PREVIEW_ROUTE = "/api/preview";
|
|
2
|
+
const DRAFT_MODE_COOKIE = "__prerender_bypass";
|
|
3
|
+
const DEFAULT_VISITOR_COOKIE = "wb_ab_vid";
|
|
4
|
+
const ONE_YEAR_SECONDS = 31536000;
|
|
5
|
+
function createWebsiteBuilderMiddleware(options = {}) {
|
|
6
|
+
const previewRoute = options.previewRoute ?? DEFAULT_PREVIEW_ROUTE;
|
|
7
|
+
const cookieName = options.visitorCookieName ?? DEFAULT_VISITOR_COOKIE;
|
|
8
|
+
const cookieMaxAge = options.visitorCookieMaxAge ?? ONE_YEAR_SECONDS;
|
|
9
|
+
return async function(request) {
|
|
10
|
+
const { NextResponse } = await import("next/server");
|
|
11
|
+
const { searchParams } = request.nextUrl;
|
|
12
|
+
const previewRequested = "true" === searchParams.get("wb.preview") || "true" === searchParams.get("wb.editing");
|
|
13
|
+
const requestHeaders = new Headers(request.headers);
|
|
14
|
+
requestHeaders.set("X-Tenant", searchParams.get("wb.tenant") ?? "root");
|
|
15
|
+
const previewEnabled = Boolean(request.cookies.get(DRAFT_MODE_COOKIE));
|
|
16
|
+
if (previewRequested) {
|
|
17
|
+
if (previewEnabled) {
|
|
18
|
+
const response = NextResponse.next({
|
|
19
|
+
request: {
|
|
20
|
+
headers: requestHeaders
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
response.headers.set("X-Preview-Params", searchParams.toString());
|
|
24
|
+
response.headers.set("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
|
|
25
|
+
response.headers.set("Pragma", "no-cache");
|
|
26
|
+
response.headers.set("Expires", "0");
|
|
27
|
+
return response;
|
|
28
|
+
}
|
|
29
|
+
const url = new URL(request.url);
|
|
30
|
+
url.pathname = previewRoute;
|
|
31
|
+
return NextResponse.redirect(url);
|
|
32
|
+
}
|
|
33
|
+
if (previewEnabled) {
|
|
34
|
+
const response = NextResponse.redirect(request.url);
|
|
35
|
+
response.cookies.delete(DRAFT_MODE_COOKIE);
|
|
36
|
+
return response;
|
|
37
|
+
}
|
|
38
|
+
const response = NextResponse.next({
|
|
39
|
+
request: {
|
|
40
|
+
headers: requestHeaders
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
if (!request.cookies.get(cookieName)) response.cookies.set(cookieName, crypto.randomUUID(), {
|
|
44
|
+
maxAge: cookieMaxAge,
|
|
45
|
+
path: "/",
|
|
46
|
+
sameSite: "lax"
|
|
47
|
+
});
|
|
48
|
+
return response;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const middleware_middleware = createWebsiteBuilderMiddleware();
|
|
52
|
+
const config = {
|
|
53
|
+
matcher: [
|
|
54
|
+
"/((?!_next|api|static|favicon.ico|.well-known).*)"
|
|
55
|
+
]
|
|
56
|
+
};
|
|
57
|
+
export { config, createWebsiteBuilderMiddleware, middleware_middleware as middleware };
|
|
58
|
+
|
|
59
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sources":["../src/middleware.ts"],"sourcesContent":["/**\n * Next.js middleware for Website Builder.\n *\n * Handles the two request-time concerns an app would otherwise hand-write:\n * - **Preview / draft mode** — routes `?wb.preview`/`?wb.editing` requests through the draft-mode\n * route and disables caching while previewing; exits preview when the flag is gone.\n * - **A/B visitor cookie** — sets a stable, PII-free `wb_ab_vid` cookie so variant bucketing is\n * deterministic across visits.\n *\n * `next` is a peer dependency and is imported dynamically so building this package never requires\n * it. Drop into a project as:\n *\n * // middleware.ts\n * export { middleware, config } from \"@webiny/website-builder-nextjs/middleware\";\n */\n\nconst DEFAULT_PREVIEW_ROUTE = \"/api/preview\";\n\n/**\n * The cookie Next.js carries draft mode in.\n *\n * Read directly, because `draftMode()` does not report enabled state in middleware — it is for\n * Server Components and Route Handlers. Asking it here returns `isEnabled: false` whether the cookie\n * is present or not, which made the hand-off below unconditional: every preview request redirected\n * to the draft-mode route, which enabled draft mode and redirected back, forever. Measured at 50\n * redirects before the client gave up.\n *\n * The name is Next's internal one and is the price of doing this in middleware at all. If a future\n * Next supports `draftMode()` here, this goes back to asking.\n */\nconst DRAFT_MODE_COOKIE = \"__prerender_bypass\";\nconst DEFAULT_VISITOR_COOKIE = \"wb_ab_vid\";\nconst ONE_YEAR_SECONDS = 60 * 60 * 24 * 365;\n\n// Minimal structural view of NextRequest — avoids a static `next` type import.\ninterface MiddlewareRequest {\n url: string;\n nextUrl: { searchParams: URLSearchParams; pathname: string };\n headers: Headers;\n cookies: { get(name: string): { value: string } | undefined };\n}\n\nexport interface WebsiteBuilderMiddlewareOptions {\n /** Route that enables Next.js draft mode for preview. Defaults to `/api/preview`. */\n previewRoute?: string;\n /** A/B bucketing cookie name. Defaults to `wb_ab_vid`. */\n visitorCookieName?: string;\n /** A/B bucketing cookie max-age in seconds. Defaults to one year. */\n visitorCookieMaxAge?: number;\n}\n\nexport function createWebsiteBuilderMiddleware(options: WebsiteBuilderMiddlewareOptions = {}) {\n const previewRoute = options.previewRoute ?? DEFAULT_PREVIEW_ROUTE;\n const cookieName = options.visitorCookieName ?? DEFAULT_VISITOR_COOKIE;\n const cookieMaxAge = options.visitorCookieMaxAge ?? ONE_YEAR_SECONDS;\n\n return async function middleware(request: MiddlewareRequest) {\n // @ts-ignore Peer dependency, resolved from the host app.\n const { NextResponse } = await import(\"next/server\");\n\n const { searchParams } = request.nextUrl;\n const previewRequested =\n searchParams.get(\"wb.preview\") === \"true\" || searchParams.get(\"wb.editing\") === \"true\";\n\n // Forward the tenant so downstream reads resolve against the right tenant.\n const requestHeaders = new Headers(request.headers);\n requestHeaders.set(\"X-Tenant\", searchParams.get(\"wb.tenant\") ?? \"root\");\n\n const previewEnabled = Boolean(request.cookies.get(DRAFT_MODE_COOKIE));\n\n if (previewRequested) {\n if (previewEnabled) {\n // Already in draft mode — pass the preview params through and disable caching.\n const response = NextResponse.next({ request: { headers: requestHeaders } });\n response.headers.set(\"X-Preview-Params\", searchParams.toString());\n response.headers.set(\n \"Cache-Control\",\n \"no-store, no-cache, must-revalidate, proxy-revalidate\"\n );\n response.headers.set(\"Pragma\", \"no-cache\");\n response.headers.set(\"Expires\", \"0\");\n return response;\n }\n // Not in draft mode yet — hand off to the route that enables it, keeping all params.\n const url = new URL(request.url);\n url.pathname = previewRoute;\n return NextResponse.redirect(url);\n }\n\n if (previewEnabled) {\n /*\n * Preview flag gone but draft mode still on — exit preview.\n *\n * By clearing the cookie on the response rather than calling `previewMode.disable()`,\n * which is unavailable here for the same reason `isEnabled` is. Clearing it before the\n * redirect matters: the redirected request must not arrive still carrying it, or this\n * branch fires again and becomes its own loop.\n */\n const response = NextResponse.redirect(request.url);\n response.cookies.delete(DRAFT_MODE_COOKIE);\n return response;\n }\n\n const response = NextResponse.next({ request: { headers: requestHeaders } });\n\n // Stable visitor id for deterministic A/B bucketing (functional cookie, no PII). Remove or\n // gate this if your consent policy requires opt-in — bucketing still works per-request\n // without it, just not stably across visits.\n if (!request.cookies.get(cookieName)) {\n response.cookies.set(cookieName, crypto.randomUUID(), {\n maxAge: cookieMaxAge,\n path: \"/\",\n sameSite: \"lax\"\n });\n }\n\n return response;\n };\n}\n\n/** Turnkey middleware with default options. */\nexport const middleware = createWebsiteBuilderMiddleware();\n\n/** Default matcher: everything except Next internals, API routes, and static assets. */\nexport const config = {\n matcher: [\"/((?!_next|api|static|favicon.ico|.well-known).*)\"]\n};\n"],"names":["DEFAULT_PREVIEW_ROUTE","DRAFT_MODE_COOKIE","DEFAULT_VISITOR_COOKIE","ONE_YEAR_SECONDS","createWebsiteBuilderMiddleware","options","previewRoute","cookieName","cookieMaxAge","request","NextResponse","searchParams","previewRequested","requestHeaders","Headers","previewEnabled","Boolean","response","url","URL","crypto","middleware","config"],"mappings":"AAgBA,MAAMA,wBAAwB;AAc9B,MAAMC,oBAAoB;AAC1B,MAAMC,yBAAyB;AAC/B,MAAMC,mBAAmB;AAmBlB,SAASC,+BAA+BC,UAA2C,CAAC,CAAC;IACxF,MAAMC,eAAeD,QAAQ,YAAY,IAAIL;IAC7C,MAAMO,aAAaF,QAAQ,iBAAiB,IAAIH;IAChD,MAAMM,eAAeH,QAAQ,mBAAmB,IAAIF;IAEpD,OAAO,eAA0BM,OAA0B;QAEvD,MAAM,EAAEC,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC;QAEtC,MAAM,EAAEC,YAAY,EAAE,GAAGF,QAAQ,OAAO;QACxC,MAAMG,mBACFD,AAAmC,WAAnCA,aAAa,GAAG,CAAC,iBAA4BA,AAAmC,WAAnCA,aAAa,GAAG,CAAC;QAGlE,MAAME,iBAAiB,IAAIC,QAAQL,QAAQ,OAAO;QAClDI,eAAe,GAAG,CAAC,YAAYF,aAAa,GAAG,CAAC,gBAAgB;QAEhE,MAAMI,iBAAiBC,QAAQP,QAAQ,OAAO,CAAC,GAAG,CAACR;QAEnD,IAAIW,kBAAkB;YAClB,IAAIG,gBAAgB;gBAEhB,MAAME,WAAWP,aAAa,IAAI,CAAC;oBAAE,SAAS;wBAAE,SAASG;oBAAe;gBAAE;gBAC1EI,SAAS,OAAO,CAAC,GAAG,CAAC,oBAAoBN,aAAa,QAAQ;gBAC9DM,SAAS,OAAO,CAAC,GAAG,CAChB,iBACA;gBAEJA,SAAS,OAAO,CAAC,GAAG,CAAC,UAAU;gBAC/BA,SAAS,OAAO,CAAC,GAAG,CAAC,WAAW;gBAChC,OAAOA;YACX;YAEA,MAAMC,MAAM,IAAIC,IAAIV,QAAQ,GAAG;YAC/BS,IAAI,QAAQ,GAAGZ;YACf,OAAOI,aAAa,QAAQ,CAACQ;QACjC;QAEA,IAAIH,gBAAgB;YAShB,MAAME,WAAWP,aAAa,QAAQ,CAACD,QAAQ,GAAG;YAClDQ,SAAS,OAAO,CAAC,MAAM,CAAChB;YACxB,OAAOgB;QACX;QAEA,MAAMA,WAAWP,aAAa,IAAI,CAAC;YAAE,SAAS;gBAAE,SAASG;YAAe;QAAE;QAK1E,IAAI,CAACJ,QAAQ,OAAO,CAAC,GAAG,CAACF,aACrBU,SAAS,OAAO,CAAC,GAAG,CAACV,YAAYa,OAAO,UAAU,IAAI;YAClD,QAAQZ;YACR,MAAM;YACN,UAAU;QACd;QAGJ,OAAOS;IACX;AACJ;AAGO,MAAMI,wBAAajB;AAGnB,MAAMkB,SAAS;IAClB,SAAS;QAAC;KAAoD;AAClE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/website-builder-nextjs",
|
|
3
|
-
"version": "0.0.0-unstable.
|
|
3
|
+
"version": "0.0.0-unstable.e9333b3f0b",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"exports": {
|
|
10
10
|
".": "./index.js",
|
|
11
|
+
"./middleware": "./middleware.js",
|
|
11
12
|
"./webpack": "./webpack.js"
|
|
12
13
|
},
|
|
13
14
|
"description": "A Next.js integration SDK for Webiny Website Builder.",
|
|
@@ -18,23 +19,22 @@
|
|
|
18
19
|
],
|
|
19
20
|
"license": "MIT",
|
|
20
21
|
"dependencies": {
|
|
21
|
-
"@webiny/website-builder-react": "0.0.0-unstable.
|
|
22
|
-
"postcss": "8.5.
|
|
23
|
-
"postcss-import": "
|
|
22
|
+
"@webiny/website-builder-react": "0.0.0-unstable.e9333b3f0b",
|
|
23
|
+
"postcss": "8.5.26",
|
|
24
|
+
"postcss-import": "17.0.0"
|
|
24
25
|
},
|
|
25
26
|
"devDependencies": {
|
|
26
27
|
"@types/postcss-import": "14.0.3",
|
|
27
|
-
"@webiny/build-tools": "0.0.0-unstable.
|
|
28
|
-
"typescript": "
|
|
29
|
-
"vitest": "4.1.
|
|
30
|
-
"webpack": "5.
|
|
28
|
+
"@webiny/build-tools": "0.0.0-unstable.e9333b3f0b",
|
|
29
|
+
"typescript": "7.0.2",
|
|
30
|
+
"vitest": "4.1.11",
|
|
31
|
+
"webpack": "5.109.2"
|
|
31
32
|
},
|
|
32
33
|
"peerDependencies": {
|
|
33
|
-
"next": "16.
|
|
34
|
+
"next": ">=15.0.0 <16.0.0"
|
|
34
35
|
},
|
|
35
36
|
"publishConfig": {
|
|
36
|
-
"access": "public"
|
|
37
|
-
"directory": "dist"
|
|
37
|
+
"access": "public"
|
|
38
38
|
},
|
|
39
39
|
"adio": {
|
|
40
40
|
"ignore": {
|
|
@@ -45,5 +45,7 @@
|
|
|
45
45
|
]
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
|
-
"
|
|
48
|
+
"webiny": {
|
|
49
|
+
"publishFrom": "dist"
|
|
50
|
+
}
|
|
49
51
|
}
|
package/webpack.js
CHANGED
|
@@ -1,56 +1,44 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import postcss from "postcss";
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const result = await postcss([postcssImport()]).process(raw, {
|
|
13
|
-
from: entry
|
|
14
|
-
});
|
|
15
|
-
return result.css;
|
|
3
|
+
import postcss_import from "postcss-import";
|
|
4
|
+
const buildThemeCss = async (entry)=>{
|
|
5
|
+
const raw = fs.readFileSync(entry, "utf8");
|
|
6
|
+
const result = await postcss([
|
|
7
|
+
postcss_import()
|
|
8
|
+
]).process(raw, {
|
|
9
|
+
from: entry
|
|
10
|
+
});
|
|
11
|
+
return result.css;
|
|
16
12
|
};
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
return plugins;
|
|
50
|
-
};
|
|
51
|
-
return {
|
|
52
|
-
getPlugins
|
|
53
|
-
};
|
|
13
|
+
const injectThemeCss = async (entry, variableName)=>{
|
|
14
|
+
const defineKey = variableName ?? "__THEME_CSS__";
|
|
15
|
+
const initialCss = await buildThemeCss(entry);
|
|
16
|
+
let definePlugin;
|
|
17
|
+
const getPlugins = (context)=>{
|
|
18
|
+
const { dev, webpack } = context;
|
|
19
|
+
if (!definePlugin) definePlugin = new webpack.DefinePlugin({
|
|
20
|
+
[defineKey]: JSON.stringify(initialCss)
|
|
21
|
+
});
|
|
22
|
+
const plugins = [
|
|
23
|
+
definePlugin
|
|
24
|
+
];
|
|
25
|
+
if (dev) plugins.push({
|
|
26
|
+
apply (compiler) {
|
|
27
|
+
compiler.hooks.afterCompile.tapPromise("WatchThemeCss", async (compilation)=>{
|
|
28
|
+
compilation.fileDependencies.add(entry);
|
|
29
|
+
});
|
|
30
|
+
compiler.hooks.beforeCompile.tapPromise("UpdateThemeCss", async ()=>{
|
|
31
|
+
const cssValue = await buildThemeCss(entry);
|
|
32
|
+
definePlugin.definitions[defineKey] = JSON.stringify(cssValue);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return plugins;
|
|
37
|
+
};
|
|
38
|
+
return {
|
|
39
|
+
getPlugins
|
|
40
|
+
};
|
|
54
41
|
};
|
|
42
|
+
export { injectThemeCss };
|
|
55
43
|
|
|
56
44
|
//# sourceMappingURL=webpack.js.map
|
package/webpack.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"webpack.js","sources":["../src/webpack.ts"],"sourcesContent":["import fs from \"fs\";\nimport type { WebpackPluginInstance } from \"webpack\";\nimport type { AcceptedPlugin } from \"postcss\";\nimport postcss from \"postcss\";\nimport postcssImport from \"postcss-import\";\nimport type { NextConfig } from \"next\";\n\n// We're inferring the type from Next's config type.\ntype WebpackConfigContext = Parameters<NonNullable<NextConfig[\"webpack\"]>>[1];\n\nconst buildThemeCss = async (entry: string) => {\n // Read CSS entry file.\n const raw = fs.readFileSync(entry, \"utf8\");\n\n // Inline local imports.\n const result = await postcss([postcssImport() as AcceptedPlugin]).process(raw, {\n from: entry\n });\n\n return result.css;\n};\n\nexport const injectThemeCss = async (entry: string, variableName?: string) => {\n const defineKey = variableName ?? \"__THEME_CSS__\";\n\n const initialCss = await buildThemeCss(entry);\n\n // Inject as a global constant available in your app.\n let definePlugin: WebpackPluginInstance;\n\n const getPlugins = (context: WebpackConfigContext) => {\n const { dev, webpack } = context;\n\n if (!definePlugin) {\n definePlugin = new webpack.DefinePlugin({ [defineKey]: JSON.stringify(initialCss) });\n }\n\n const plugins: WebpackPluginInstance[] = [definePlugin];\n\n if (dev) {\n // Watch for changes and update plugin definitions\n plugins.push({\n apply(compiler) {\n compiler.hooks.afterCompile.tapPromise(\"WatchThemeCss\", async compilation => {\n compilation.fileDependencies.add(entry);\n });\n\n compiler.hooks.beforeCompile.tapPromise(\"UpdateThemeCss\", async () => {\n const cssValue = await buildThemeCss(entry);\n // Update the definitions on our specific plugin\n definePlugin.definitions[defineKey] = JSON.stringify(cssValue);\n });\n }\n });\n }\n\n return plugins;\n };\n\n return { getPlugins };\n};\n"],"names":["buildThemeCss","entry","raw","fs","result","postcss","postcssImport","injectThemeCss","variableName","defineKey","initialCss","definePlugin","getPlugins","context","dev","webpack","JSON","plugins","compiler","compilation","cssValue"],"mappings":";;;AAUA,MAAMA,gBAAgB,OAAOC;IAEzB,MAAMC,MAAMC,GAAG,YAAY,CAACF,OAAO;IAGnC,MAAMG,SAAS,MAAMC,QAAQ;QAACC;KAAkC,EAAE,OAAO,CAACJ,KAAK;QAC3E,MAAMD;IACV;IAEA,OAAOG,OAAO,GAAG;AACrB;AAEO,MAAMG,iBAAiB,OAAON,OAAeO;IAChD,MAAMC,YAAYD,gBAAgB;IAElC,MAAME,aAAa,MAAMV,cAAcC;IAGvC,IAAIU;IAEJ,MAAMC,aAAa,CAACC;QAChB,MAAM,EAAEC,GAAG,EAAEC,OAAO,EAAE,GAAGF;QAEzB,IAAI,CAACF,cACDA,eAAe,IAAII,QAAQ,YAAY,CAAC;YAAE,CAACN,UAAU,EAAEO,KAAK,SAAS,CAACN;QAAY;QAGtF,MAAMO,UAAmC;YAACN;SAAa;QAEvD,IAAIG,KAEAG,QAAQ,IAAI,CAAC;YACT,OAAMC,QAAQ;gBACVA,SAAS,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,iBAAiB,OAAMC;oBAC1DA,YAAY,gBAAgB,CAAC,GAAG,CAAClB;gBACrC;gBAEAiB,SAAS,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,kBAAkB;oBACtD,MAAME,WAAW,MAAMpB,cAAcC;oBAErCU,aAAa,WAAW,CAACF,UAAU,GAAGO,KAAK,SAAS,CAACI;gBACzD;YACJ;QACJ;QAGJ,OAAOH;IACX;IAEA,OAAO;QAAEL;IAAW;AACxB"}
|