@djangocfg/nextjs 2.1.471 → 2.1.474
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/dist/config/index.d.mts +36 -0
- package/dist/config/index.mjs +71 -34
- package/dist/config/index.mjs.map +1 -1
- package/dist/index.mjs +71 -34
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
- package/src/config/createNextConfig.ts +129 -40
package/dist/index.mjs
CHANGED
|
@@ -14,7 +14,7 @@ var require_package = __commonJS({
|
|
|
14
14
|
"package.json"(exports, module) {
|
|
15
15
|
module.exports = {
|
|
16
16
|
name: "@djangocfg/nextjs",
|
|
17
|
-
version: "2.1.
|
|
17
|
+
version: "2.1.474",
|
|
18
18
|
description: "Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config",
|
|
19
19
|
keywords: [
|
|
20
20
|
"nextjs",
|
|
@@ -1670,45 +1670,81 @@ function createBaseNextConfig(options = {}) {
|
|
|
1670
1670
|
];
|
|
1671
1671
|
const hasIframeAllowlist = !!options.allowIframeFrom && options.allowIframeFrom.length > 0;
|
|
1672
1672
|
const frameAncestors = hasIframeAllowlist ? options.allowIframeFrom.includes("*") ? "*" : `'self' ${options.allowIframeFrom.join(" ")}` : "'none'";
|
|
1673
|
+
const cspDisabled = options.csp === false;
|
|
1674
|
+
const cspExtra = typeof options.csp === "object" ? options.csp : void 0;
|
|
1673
1675
|
const stripeScript = options.stripe ? " https://js.stripe.com" : "";
|
|
1674
1676
|
const stripeConnect = options.stripe ? " https://api.stripe.com" : "";
|
|
1675
1677
|
const stripeFrame = options.stripe ? " https://js.stripe.com https://checkout.stripe.com" : "";
|
|
1676
|
-
const
|
|
1677
|
-
const
|
|
1678
|
-
const
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1678
|
+
const extraScript = cspExtra?.scriptSrc?.length ? " " + cspExtra.scriptSrc.join(" ") : "";
|
|
1679
|
+
const extraConnect = cspExtra?.connectSrc?.length ? " " + cspExtra.connectSrc.join(" ") : "";
|
|
1680
|
+
const extraFrame = cspExtra?.frameSrc?.length ? " " + cspExtra.frameSrc.join(" ") : "";
|
|
1681
|
+
const extraImg = cspExtra?.imgSrc?.length ? " " + cspExtra.imgSrc.join(" ") : "";
|
|
1682
|
+
const extraFont = cspExtra?.fontSrc?.length ? " " + cspExtra.fontSrc.join(" ") : "";
|
|
1683
|
+
const connectSrc = isDev ? `connect-src 'self' http: https: ws: wss:${stripeConnect}${extraConnect}` : `connect-src 'self' https: wss:${stripeConnect}${extraConnect}`;
|
|
1684
|
+
const imgSrc = isDev ? `img-src 'self' data: blob: http: https:${extraImg}` : `img-src 'self' data: blob: https:${extraImg}`;
|
|
1685
|
+
if (!cspDisabled) {
|
|
1686
|
+
const cspDirectives = [
|
|
1687
|
+
"default-src 'self'",
|
|
1688
|
+
// Next.js requires inline + eval for its runtime/HMR. Tighten to nonces later.
|
|
1689
|
+
`script-src 'self' 'unsafe-inline' 'unsafe-eval'${stripeScript}${extraScript}`,
|
|
1690
|
+
"style-src 'self' 'unsafe-inline'",
|
|
1691
|
+
imgSrc,
|
|
1692
|
+
`font-src 'self' data:${extraFont}`,
|
|
1693
|
+
// API/websocket calls go cross-origin to Django/Centrifugo.
|
|
1694
|
+
connectSrc,
|
|
1695
|
+
// Stripe Elements/Checkout and any app-declared trusted origins
|
|
1696
|
+
// (options.csp.frameSrc) mount iframes; add their hosts when enabled.
|
|
1697
|
+
`frame-src 'self'${stripeFrame}${extraFrame}`,
|
|
1698
|
+
"object-src 'none'",
|
|
1699
|
+
"base-uri 'self'",
|
|
1700
|
+
"form-action 'self'",
|
|
1701
|
+
`frame-ancestors ${frameAncestors}`
|
|
1702
|
+
];
|
|
1703
|
+
headers.push({
|
|
1704
|
+
source: "/:path*",
|
|
1705
|
+
headers: [
|
|
1706
|
+
{ key: "X-Content-Type-Options", value: "nosniff" },
|
|
1707
|
+
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
|
|
1708
|
+
{ key: "Content-Security-Policy", value: cspDirectives.join("; ") },
|
|
1709
|
+
// X-Frame-Options for older browsers. Omitted when a wildcard iframe
|
|
1710
|
+
// allowlist is set (browsers then rely on CSP frame-ancestors).
|
|
1711
|
+
...hasIframeAllowlist && options.allowIframeFrom.includes("*") ? [] : [{ key: "X-Frame-Options", value: hasIframeAllowlist ? "SAMEORIGIN" : "DENY" }]
|
|
1712
|
+
]
|
|
1713
|
+
});
|
|
1714
|
+
} else {
|
|
1715
|
+
headers.push({
|
|
1716
|
+
source: "/:path*",
|
|
1717
|
+
headers: [
|
|
1718
|
+
{ key: "X-Content-Type-Options", value: "nosniff" },
|
|
1719
|
+
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
|
|
1720
|
+
...hasIframeAllowlist && options.allowIframeFrom.includes("*") ? [] : [{ key: "X-Frame-Options", value: hasIframeAllowlist ? "SAMEORIGIN" : "DENY" }]
|
|
1721
|
+
]
|
|
1722
|
+
});
|
|
1723
|
+
}
|
|
1705
1724
|
const userHeaders = options.headers ? await options.headers() : [];
|
|
1706
1725
|
return [...headers, ...userHeaders];
|
|
1707
1726
|
},
|
|
1708
|
-
// Rewrites
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1727
|
+
// Rewrites — first-party analytics ingest proxy, then user rewrites.
|
|
1728
|
+
//
|
|
1729
|
+
// @djangocfg/analytics POSTs to a RELATIVE /cfg/analytics/collect/ so the beacon
|
|
1730
|
+
// stays same-origin (sendBeacon is unreliable cross-origin). On a split-domain
|
|
1731
|
+
// deploy (Next on one host, Django on `apiUrl`) that same-origin path has no
|
|
1732
|
+
// route here, so every beacon 404s and nothing is ingested — unless we proxy it.
|
|
1733
|
+
// Same-domain and static builds keep apiUrl empty and need no proxy.
|
|
1734
|
+
...apiUrl && !isStaticBuild || options.rewrites ? {
|
|
1735
|
+
async rewrites() {
|
|
1736
|
+
const analyticsProxy = apiUrl && !isStaticBuild ? [{ source: "/cfg/analytics/:path*", destination: `${apiUrl}/cfg/analytics/:path*` }] : [];
|
|
1737
|
+
const user = options.rewrites ? await options.rewrites() : [];
|
|
1738
|
+
if (Array.isArray(user)) {
|
|
1739
|
+
return { beforeFiles: analyticsProxy, afterFiles: user, fallback: [] };
|
|
1740
|
+
}
|
|
1741
|
+
return {
|
|
1742
|
+
beforeFiles: [...analyticsProxy, ...user?.beforeFiles ?? []],
|
|
1743
|
+
afterFiles: user?.afterFiles ?? [],
|
|
1744
|
+
fallback: user?.fallback ?? []
|
|
1745
|
+
};
|
|
1746
|
+
}
|
|
1747
|
+
} : {},
|
|
1712
1748
|
// Redirects for URL normalization
|
|
1713
1749
|
// Fixes "Failed to construct 'URL': Invalid URL" error with double slashes
|
|
1714
1750
|
async redirects() {
|
|
@@ -1806,6 +1842,7 @@ function createBaseNextConfig(options = {}) {
|
|
|
1806
1842
|
allowIframeFrom,
|
|
1807
1843
|
dpop,
|
|
1808
1844
|
stripe,
|
|
1845
|
+
csp,
|
|
1809
1846
|
...nextConfigOptions
|
|
1810
1847
|
} = options;
|
|
1811
1848
|
let finalConfig = deepMerge(baseConfig, nextConfigOptions);
|