@thomas.f/prnext 0.1.0-alpha.1

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.
Files changed (211) hide show
  1. package/README.md +54 -0
  2. package/build/action-exports.mjs +107 -0
  3. package/build/actions.mjs +214 -0
  4. package/build/app-config.mjs +138 -0
  5. package/build/app-routing.mjs +119 -0
  6. package/build/app-static.mjs +158 -0
  7. package/build/app.mjs +536 -0
  8. package/build/cache-components.mjs +91 -0
  9. package/build/cache-handlers.mjs +54 -0
  10. package/build/check.mjs +40 -0
  11. package/build/compiler.mjs +222 -0
  12. package/build/config.mjs +193 -0
  13. package/build/css-modules.mjs +114 -0
  14. package/build/custom-routes.mjs +363 -0
  15. package/build/dev-worker.mjs +18 -0
  16. package/build/dev.mjs +76 -0
  17. package/build/directory-cache.mjs +29 -0
  18. package/build/dynamic.mjs +125 -0
  19. package/build/edge.mjs +141 -0
  20. package/build/font-data.LICENSE.txt +25 -0
  21. package/build/font-data.json +1 -0
  22. package/build/font-files.mjs +221 -0
  23. package/build/fonts.mjs +131 -0
  24. package/build/framework-imports.mjs +17 -0
  25. package/build/i18n.mjs +39 -0
  26. package/build/images-config.mjs +62 -0
  27. package/build/images.mjs +86 -0
  28. package/build/incremental.mjs +76 -0
  29. package/build/index.mjs +356 -0
  30. package/build/loader-cache.mjs +69 -0
  31. package/build/metadata-images.mjs +72 -0
  32. package/build/metadata-routes.mjs +77 -0
  33. package/build/middleware.mjs +231 -0
  34. package/build/migrate.mjs +289 -0
  35. package/build/module-resolution.mjs +78 -0
  36. package/build/native-discovery.mjs +134 -0
  37. package/build/native-packages.mjs +105 -0
  38. package/build/npm-packages.mjs +110 -0
  39. package/build/og.mjs +14 -0
  40. package/build/page-extensions.mjs +12 -0
  41. package/build/passthrough-loader.cjs +4 -0
  42. package/build/precompress.mjs +122 -0
  43. package/build/scan.mjs +178 -0
  44. package/build/script-workers.mjs +25 -0
  45. package/build/server-actions-config.mjs +27 -0
  46. package/build/source-maps.mjs +34 -0
  47. package/build/standalone-config.mjs +19 -0
  48. package/build/standalone-runner.mjs +21 -0
  49. package/build/standalone-worker.mjs +5 -0
  50. package/build/standalone.mjs +240 -0
  51. package/build/static-export.mjs +93 -0
  52. package/build/styles.mjs +174 -0
  53. package/build/transform-cache.mjs +50 -0
  54. package/build/transform.mjs +155 -0
  55. package/build/turbopack-conditions.mjs +59 -0
  56. package/build/webpack-bridge.cjs +3 -0
  57. package/build/webpack-graph.mjs +256 -0
  58. package/build/webpack-loader.cjs +9 -0
  59. package/cli.mjs +210 -0
  60. package/compat/app-client-page.cjs +32 -0
  61. package/compat/app-context.cjs +40 -0
  62. package/compat/app-context.d.cts +20 -0
  63. package/compat/app-dynamic.cjs +34 -0
  64. package/compat/app-error-boundary.cjs +53 -0
  65. package/compat/app-global-error-boundary.cjs +34 -0
  66. package/compat/app-layout-context.cjs +27 -0
  67. package/compat/app-navigation-boundary.cjs +47 -0
  68. package/compat/app.cjs +33 -0
  69. package/compat/app.d.cts +9 -0
  70. package/compat/cache-handlers.cjs +223 -0
  71. package/compat/cache-life.cjs +34 -0
  72. package/compat/cache.cjs +99 -0
  73. package/compat/cache.d.cts +36 -0
  74. package/compat/compat/router.d.cts +2 -0
  75. package/compat/compat-router.cjs +7 -0
  76. package/compat/constants.cjs +8 -0
  77. package/compat/constants.d.cts +7 -0
  78. package/compat/cookies.cjs +129 -0
  79. package/compat/data-cache.cjs +389 -0
  80. package/compat/dist/shared/lib/app-router-context.shared-runtime.d.cts +3 -0
  81. package/compat/dist/shared/lib/router-context.d.cts +1 -0
  82. package/compat/dist/shared/lib/router-context.shared-runtime.d.cts +3 -0
  83. package/compat/document.cjs +73 -0
  84. package/compat/document.d.cts +41 -0
  85. package/compat/draft.cjs +28 -0
  86. package/compat/dynamic-bailout.cjs +13 -0
  87. package/compat/dynamic.cjs +119 -0
  88. package/compat/dynamic.d.cts +32 -0
  89. package/compat/error.cjs +36 -0
  90. package/compat/error.d.cts +15 -0
  91. package/compat/fetch.d.cts +10 -0
  92. package/compat/font/google.d.cts +1 -0
  93. package/compat/font/local.d.cts +2 -0
  94. package/compat/font-google.cjs +2 -0
  95. package/compat/font-google.d.cts +1944 -0
  96. package/compat/font-local.cjs +5 -0
  97. package/compat/font-local.d.cts +3 -0
  98. package/compat/font-types.d.cts +25 -0
  99. package/compat/head.cjs +180 -0
  100. package/compat/head.d.cts +3 -0
  101. package/compat/headers.cjs +89 -0
  102. package/compat/headers.d.cts +26 -0
  103. package/compat/image-config.cjs +3 -0
  104. package/compat/image-imports.d.ts +12 -0
  105. package/compat/image-shared.cjs +62 -0
  106. package/compat/image.cjs +64 -0
  107. package/compat/image.d.cts +35 -0
  108. package/compat/incremental-cache.cjs +186 -0
  109. package/compat/index.d.ts +159 -0
  110. package/compat/instant-samples.cjs +39 -0
  111. package/compat/instant.cjs +13 -0
  112. package/compat/link.cjs +68 -0
  113. package/compat/link.d.cts +17 -0
  114. package/compat/locale.cjs +30 -0
  115. package/compat/metadata.d.cts +77 -0
  116. package/compat/navigation-controls.cjs +27 -0
  117. package/compat/navigation-server.cjs +25 -0
  118. package/compat/navigation.cjs +52 -0
  119. package/compat/navigation.d.cts +28 -0
  120. package/compat/next-app-router-context.cjs +6 -0
  121. package/compat/next-router-context.cjs +3 -0
  122. package/compat/og.cjs +32 -0
  123. package/compat/og.d.cts +1 -0
  124. package/compat/paths.cjs +33 -0
  125. package/compat/preview.cjs +41 -0
  126. package/compat/rewrite.cjs +41 -0
  127. package/compat/route-request.cjs +64 -0
  128. package/compat/router.cjs +137 -0
  129. package/compat/router.d.cts +58 -0
  130. package/compat/script-context.cjs +5 -0
  131. package/compat/script-loader.cjs +135 -0
  132. package/compat/script.cjs +69 -0
  133. package/compat/script.d.cts +17 -0
  134. package/compat/server-primitives.cjs +109 -0
  135. package/compat/server.cjs +13 -0
  136. package/compat/server.d.cts +37 -0
  137. package/compat/static-generation.cjs +108 -0
  138. package/compat/use-cache.cjs +129 -0
  139. package/index.mjs +1 -0
  140. package/native/platforms.json +6 -0
  141. package/native/resolve.mjs +81 -0
  142. package/package.json +127 -0
  143. package/release/verify.mjs +59 -0
  144. package/runtime/action-client.mjs +19 -0
  145. package/runtime/action-crypto.mjs +138 -0
  146. package/runtime/action-reference.mjs +2 -0
  147. package/runtime/action-server.mjs +161 -0
  148. package/runtime/action-ssr.mjs +5 -0
  149. package/runtime/api.mjs +326 -0
  150. package/runtime/app-client.mjs +539 -0
  151. package/runtime/app-content.mjs +8 -0
  152. package/runtime/app-errors.mjs +12 -0
  153. package/runtime/app-instant.mjs +30 -0
  154. package/runtime/app-metadata.mjs +410 -0
  155. package/runtime/app-partial-model.mjs +228 -0
  156. package/runtime/app-partial.mjs +130 -0
  157. package/runtime/app-prefetch.mjs +34 -0
  158. package/runtime/app-recovery.mjs +87 -0
  159. package/runtime/app-render.mjs +544 -0
  160. package/runtime/app-routing-access.mjs +143 -0
  161. package/runtime/app-routing-context.mjs +35 -0
  162. package/runtime/app-routing-state.mjs +61 -0
  163. package/runtime/app-routing.mjs +323 -0
  164. package/runtime/app-segments.mjs +22 -0
  165. package/runtime/app-static-params.mjs +120 -0
  166. package/runtime/app-static.mjs +86 -0
  167. package/runtime/app-stream-channel.mjs +92 -0
  168. package/runtime/app-stream-html.mjs +279 -0
  169. package/runtime/build-directory.mjs +48 -0
  170. package/runtime/cache-arguments.mjs +33 -0
  171. package/runtime/cache-components-rsc.mjs +64 -0
  172. package/runtime/cache-request.mjs +23 -0
  173. package/runtime/client-navigation.mjs +40 -0
  174. package/runtime/dev-client.mjs +129 -0
  175. package/runtime/dev-file-changes.mjs +110 -0
  176. package/runtime/document.mjs +96 -0
  177. package/runtime/edge.mjs +105 -0
  178. package/runtime/env.mjs +68 -0
  179. package/runtime/fetch-cache.mjs +379 -0
  180. package/runtime/font-preload.mjs +4 -0
  181. package/runtime/http.mjs +190 -0
  182. package/runtime/incremental-cache.mjs +83 -0
  183. package/runtime/metadata-route.mjs +83 -0
  184. package/runtime/middleware.mjs +186 -0
  185. package/runtime/module-loader.mjs +21 -0
  186. package/runtime/navigation.mjs +16 -0
  187. package/runtime/og-loader.mjs +17 -0
  188. package/runtime/pages-client.mjs +197 -0
  189. package/runtime/pages-error-props.mjs +6 -0
  190. package/runtime/pages-errors.mjs +85 -0
  191. package/runtime/pages-initial-props.mjs +43 -0
  192. package/runtime/pages-navigation.mjs +565 -0
  193. package/runtime/pages-paths.mjs +80 -0
  194. package/runtime/pages-revalidate.mjs +33 -0
  195. package/runtime/partial-artifact-cache.mjs +37 -0
  196. package/runtime/partial-template.mjs +174 -0
  197. package/runtime/profile.mjs +9 -0
  198. package/runtime/profiles.json +47 -0
  199. package/runtime/render.mjs +304 -0
  200. package/runtime/request-transport.mjs +41 -0
  201. package/runtime/request-work.mjs +7 -0
  202. package/runtime/route-static.mjs +117 -0
  203. package/runtime/rsc-worker.mjs +426 -0
  204. package/runtime/script-html.mjs +61 -0
  205. package/runtime/stream-select.mjs +25 -0
  206. package/runtime/stream-utils.mjs +127 -0
  207. package/runtime/transport.mjs +108 -0
  208. package/runtime/watch-project.mjs +130 -0
  209. package/runtime/worker-artifacts.mjs +22 -0
  210. package/runtime/worker-metadata.mjs +31 -0
  211. package/runtime/worker.mjs +197 -0
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+
3
+ const controls = require('./navigation-controls.cjs');
4
+ const { currentRequest } = require('./headers.cjs');
5
+ function clientHook(name) {
6
+ return function () { throw new Error(`${name} is a Client Component hook. Add "use client" to the component that calls it.`); };
7
+ }
8
+ module.exports.useRouter = clientHook('useRouter');
9
+ module.exports.usePathname = clientHook('usePathname');
10
+ module.exports.useSearchParams = clientHook('useSearchParams');
11
+ module.exports.useParams = clientHook('useParams');
12
+ module.exports.useSelectedLayoutSegment = clientHook('useSelectedLayoutSegment');
13
+ module.exports.useSelectedLayoutSegments = clientHook('useSelectedLayoutSegments');
14
+ module.exports.redirect = function redirect(url, type) {
15
+ if (type == null) {
16
+ let action = false;
17
+ try { action = Boolean(currentRequest().action); } catch { /* Calls outside a request keep the render default. */ }
18
+ type = action ? controls.RedirectType.push : controls.RedirectType.replace;
19
+ }
20
+ return controls.redirect(url, type);
21
+ };
22
+ module.exports.permanentRedirect = controls.permanentRedirect;
23
+ module.exports.notFound = controls.notFound;
24
+ module.exports.RedirectType = controls.RedirectType;
25
+ module.exports.unstable_rethrow = controls.unstable_rethrow;
@@ -0,0 +1,52 @@
1
+ 'use strict';
2
+
3
+ const controls = require('./navigation-controls.cjs');
4
+
5
+ // Server Components may import redirect/notFound. Load the client context only
6
+ // when a client hook actually runs, since React's server build has no contexts.
7
+ function context() {
8
+ const React = require('react');
9
+ const { AppRouterContext } = require('./app-context.cjs');
10
+ const value = React.useContext(AppRouterContext);
11
+ if (!value) throw new Error('App Router hooks must be used inside the PRNext App Router');
12
+ return value;
13
+ }
14
+
15
+ function useRouter() { return context().router; }
16
+ function usePathname() { return context().pathname; }
17
+ function useSearchParams() { return context().searchParams; }
18
+ function useParams() { return context().params; }
19
+ function useSelectedLayoutSegments(parallelRoutesKey = 'children') {
20
+ const React = require('react');
21
+ const { AppRouterContext } = require('./app-context.cjs');
22
+ // Generic PPR cannot publish segment names whose params are still unknown.
23
+ // The provider's getter postpones this hook only during that build phase.
24
+ void React.useContext(AppRouterContext)?.params;
25
+ const { LayoutContext } = require('./app-layout-context.cjs');
26
+ const segments = React.useContext(LayoutContext);
27
+ return segments[parallelRoutesKey] || [];
28
+ }
29
+ function useSelectedLayoutSegment(parallelRoutesKey = 'children') {
30
+ const segments = useSelectedLayoutSegments(parallelRoutesKey);
31
+ return (parallelRoutesKey === 'children' ? segments[0] : segments.at(-1)) ?? null;
32
+ }
33
+
34
+ class ReadonlyURLSearchParams extends URLSearchParams {
35
+ append() { throw new TypeError('ReadonlyURLSearchParams cannot be modified'); }
36
+ delete() { throw new TypeError('ReadonlyURLSearchParams cannot be modified'); }
37
+ set() { throw new TypeError('ReadonlyURLSearchParams cannot be modified'); }
38
+ sort() { throw new TypeError('ReadonlyURLSearchParams cannot be modified'); }
39
+ }
40
+
41
+ module.exports.useRouter = useRouter;
42
+ module.exports.usePathname = usePathname;
43
+ module.exports.useSearchParams = useSearchParams;
44
+ module.exports.useParams = useParams;
45
+ module.exports.useSelectedLayoutSegment = useSelectedLayoutSegment;
46
+ module.exports.useSelectedLayoutSegments = useSelectedLayoutSegments;
47
+ module.exports.ReadonlyURLSearchParams = ReadonlyURLSearchParams;
48
+ module.exports.redirect = controls.redirect;
49
+ module.exports.permanentRedirect = controls.permanentRedirect;
50
+ module.exports.notFound = controls.notFound;
51
+ module.exports.RedirectType = controls.RedirectType;
52
+ module.exports.unstable_rethrow = controls.unstable_rethrow;
@@ -0,0 +1,28 @@
1
+ export interface NavigateOptions { scroll?: boolean }
2
+ export interface PrefetchOptions { onInvalidate?: () => void }
3
+ export interface AppRouterInstance {
4
+ push(href: string, options?: NavigateOptions): void;
5
+ replace(href: string, options?: NavigateOptions): void;
6
+ refresh(): void;
7
+ back(): void;
8
+ forward(): void;
9
+ prefetch(href: string, options?: PrefetchOptions): void;
10
+ }
11
+ export class ReadonlyURLSearchParams extends URLSearchParams {
12
+ append(): never;
13
+ delete(): never;
14
+ set(): never;
15
+ sort(): never;
16
+ }
17
+ export function useRouter(): AppRouterInstance;
18
+ export function usePathname(): string;
19
+ export function useSearchParams(): ReadonlyURLSearchParams;
20
+ export function useParams<T extends Record<string, string | string[]> = Record<string, string | string[]>>(): T;
21
+ export function useSelectedLayoutSegment(parallelRoutesKey?: string): string | null;
22
+ export function useSelectedLayoutSegments(parallelRoutesKey?: string): string[];
23
+ export const RedirectType: Readonly<{ push: 'push'; replace: 'replace' }>;
24
+ export type RedirectType = 'push' | 'replace';
25
+ export function redirect(url: string, type?: RedirectType): never;
26
+ export function permanentRedirect(url: string, type?: RedirectType): never;
27
+ export function notFound(): never;
28
+ export function unstable_rethrow(error: unknown): void;
@@ -0,0 +1,6 @@
1
+ 'use client';
2
+ 'use strict';
3
+ const React = require('react');
4
+ const AppRouterContext = React.createContext(null);
5
+ AppRouterContext.displayName = 'AppRouterContext';
6
+ exports.AppRouterContext = AppRouterContext;
@@ -0,0 +1,3 @@
1
+ 'use client';
2
+ 'use strict';
3
+ exports.RouterContext = require('./router.cjs').RouterContext;
package/compat/og.cjs ADDED
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+ let implementation;
3
+ function renderer() {
4
+ return implementation ||= import('../runtime/og/index.node.mjs').catch(error => {
5
+ if (error.code !== 'ERR_MODULE_NOT_FOUND') throw error;
6
+ return import('../runtime/og-loader.mjs').then(module => module.loadImageRenderer());
7
+ });
8
+ }
9
+ class ImageResponse extends Response {
10
+ constructor(element, options = {}) {
11
+ const headers = new Headers(options.headers);
12
+ if (!headers.has('content-type')) headers.set('content-type', 'image/png');
13
+ if (!headers.has('cache-control')) headers.set('cache-control', process.env.NODE_ENV === 'development' ? 'no-cache, no-store' : 'public, immutable, no-transform, max-age=31536000');
14
+ let reader;
15
+ let cancelled = false;
16
+ super(new ReadableStream({
17
+ async start(controller) {
18
+ try {
19
+ const { ImageResponse: Render } = await renderer();
20
+ if (cancelled) return;
21
+ reader = new Render(element, options).body.getReader();
22
+ } catch (error) { controller.error(error); }
23
+ },
24
+ async pull(controller) {
25
+ try { const chunk = await reader.read(); if (chunk.done) controller.close(); else controller.enqueue(chunk.value); }
26
+ catch (error) { controller.error(error); }
27
+ },
28
+ cancel(reason) { cancelled = true; return reader?.cancel(reason); },
29
+ }), { status: options.status, statusText: options.statusText, headers });
30
+ }
31
+ }
32
+ module.exports = { ImageResponse };
@@ -0,0 +1 @@
1
+ export { ImageResponse, type ImageResponseOptions } from '@vercel/og';
@@ -0,0 +1,33 @@
1
+ 'use strict';
2
+
3
+ function normalizeBasePath(value = '') {
4
+ if (typeof value !== 'string' || (value && (!value.startsWith('/') || value.endsWith('/') || /[?#\\\s\x00-\x1f\x7f-\uffff]/.test(value) || /%(?![\da-f]{2})/i.test(value) || value.split('/').some((part, index) => index && (!part || part === '.' || part === '..'))))) {
5
+ throw new TypeError('basePath must be empty or an absolute path without a trailing slash, query or fragment');
6
+ }
7
+ return value;
8
+ }
9
+ function hasBasePath(path, basePath = '') {
10
+ const pathname = String(path).split(/[?#]/, 1)[0];
11
+ return !basePath || pathname === basePath || pathname.startsWith(`${basePath}/`);
12
+ }
13
+ function addBasePath(path, basePath = '') {
14
+ return basePath && String(path).startsWith('/') ? `${basePath}${path}` : path;
15
+ }
16
+ function removeBasePath(path, basePath = '') {
17
+ if (!basePath || !hasBasePath(path, basePath)) return path;
18
+ const rest = path.slice(basePath.length);
19
+ return !rest || rest[0] === '?' || rest[0] === '#' ? `/${rest}` : rest;
20
+ }
21
+ function assetBase(basePath = '', assetPrefix = '') {
22
+ return `${(assetPrefix || basePath).replace(/\/$/, '')}/_prnext/assets`;
23
+ }
24
+ // Same client policy as Next: extension URLs stay slashless. The native
25
+ // redirect layer additionally excludes .well-known paths.
26
+ function normalizeTrailingSlash(path, { trailingSlash = false, skipTrailingSlashRedirect = false } = {}) {
27
+ if (!String(path).startsWith('/') || String(path).startsWith('//') || skipTrailingSlashRedirect) return path;
28
+ const match = /^([^?#]*)(.*)$/.exec(path);
29
+ const pathname = match[1], rest = match[2];
30
+ const trimmed = pathname.endsWith('/') ? pathname.slice(0, -1) || '/' : pathname;
31
+ return (trailingSlash && !/\.[^/]+\/?$/.test(pathname) ? (pathname.endsWith('/') ? pathname : pathname + '/') : trimmed) + rest;
32
+ }
33
+ module.exports = { normalizeTrailingSlash, normalizeBasePath, hasBasePath, addBasePath, removeBasePath, assetBase };
@@ -0,0 +1,41 @@
1
+ 'use strict';
2
+ const { parseCookieHeader } = require('./cookies.cjs');
3
+ const { isDraftRequest, previewId, draftCookie, cookieHeader } = require('./draft.cjs');
4
+ const NAME = '__next_preview_data';
5
+ function key(input) {
6
+ const value = input.previewModeEncryptionKey || input.manifest?.previewModeEncryptionKey;
7
+ if (typeof value !== 'string' || !/^[a-f0-9]{64}$/.test(value)) throw new Error('Preview Mode requires a build with an encryption key');
8
+ return Buffer.from(value, 'hex');
9
+ }
10
+ function readPreviewData(input) {
11
+ if (!isDraftRequest(input)) return false;
12
+ const token = parseCookieHeader(cookieHeader(input.headers)).get(NAME)?.value;
13
+ if (!token) return {};
14
+ if (token.length > 2048 || !/^[A-Za-z0-9_-]+$/.test(token)) return false;
15
+ try {
16
+ const { createDecipheriv } = require('node:crypto');
17
+ const data = Buffer.from(token, 'base64url');
18
+ if (data.toString('base64url') !== token) return false;
19
+ if (data.length < 29) return false;
20
+ const cipher = createDecipheriv('aes-256-gcm', key(input), data.subarray(0, 12));
21
+ cipher.setAAD(Buffer.from(previewId(input))); cipher.setAuthTag(data.subarray(12, 28));
22
+ const payload = JSON.parse(Buffer.concat([cipher.update(data.subarray(28)), cipher.final()]).toString());
23
+ if (payload.v !== 1 || !Object.hasOwn(payload, 'data') || (payload.expires !== null && (!Number.isFinite(payload.expires) || payload.expires <= Date.now()))) return false;
24
+ return payload.data;
25
+ } catch { return false; }
26
+ }
27
+ function previewCookies(input, data, { maxAge, path = '/' } = {}) {
28
+ if (typeof path !== 'string' || !path.startsWith('/') || /[;\r\n\0]/.test(path)) throw new TypeError('Preview cookie path must be an absolute cookie path');
29
+ if (maxAge !== undefined && (!Number.isSafeInteger(maxAge) || maxAge < 0 || maxAge > 2147483647)) throw new TypeError('Preview maxAge must be a nonnegative integer number of seconds');
30
+ const json = JSON.stringify({ v: 1, data, expires: maxAge === undefined ? null : Date.now() + maxAge * 1000 });
31
+ if (data === undefined || Buffer.byteLength(json) > 2048) throw new TypeError('Preview data must be JSON serializable and fit in its 2 KiB cookie');
32
+ const { randomBytes, createCipheriv } = require('node:crypto');
33
+ const iv = randomBytes(12), cipher = createCipheriv('aes-256-gcm', key(input), iv);
34
+ cipher.setAAD(Buffer.from(previewId(input)));
35
+ const body = Buffer.concat([cipher.update(json), cipher.final()]);
36
+ const value = Buffer.concat([iv, cipher.getAuthTag(), body]).toString('base64url');
37
+ if (value.length > 2048) throw new TypeError('Encrypted preview data exceeds its 2 KiB cookie');
38
+ const bypass = { ...draftCookie(input, true, { path }), ...(maxAge === undefined ? {} : { maxAge }) };
39
+ return [bypass, { ...bypass, name: NAME, value }];
40
+ }
41
+ module.exports = { NAME, readPreviewData, previewCookies };
@@ -0,0 +1,41 @@
1
+ 'use strict';
2
+
3
+ function parseRewrite(source) {
4
+ if (!source) return undefined;
5
+ if (source.length > 256 * 1024) throw new Error('Rewrite metadata exceeds the response limit');
6
+ const value = JSON.parse(source);
7
+ if (!value || typeof value.url !== 'string' || !value.url.startsWith('/') || value.url.startsWith('//') ||
8
+ !value.params || typeof value.params !== 'object' || Array.isArray(value.params)) {
9
+ throw new Error('Invalid rewrite metadata');
10
+ }
11
+ for (const parameter of Object.values(value.params)) {
12
+ if (typeof parameter !== 'string' && !(Array.isArray(parameter) && parameter.every(item => typeof item === 'string'))) {
13
+ throw new Error('Invalid rewrite parameter');
14
+ }
15
+ }
16
+ return value;
17
+ }
18
+
19
+ function readRewriteMarker(document) {
20
+ const marker = document.getElementById('__PRNEXT_REWRITE__');
21
+ if (!marker) return undefined;
22
+ const value = parseRewrite(marker.textContent);
23
+ marker.remove();
24
+ return value;
25
+ }
26
+
27
+ function readRewriteHeader(response) {
28
+ const value = response.headers.get('x-prnext-rewrite');
29
+ return value ? parseRewrite(decodeURIComponent(value)) : undefined;
30
+ }
31
+
32
+ function rewriteQuery(rewrite) {
33
+ const query = Object.create(null);
34
+ for (const [key, value] of new URL(rewrite.url, 'http://prnext.local').searchParams) {
35
+ if (Object.hasOwn(query, key)) query[key] = [...(Array.isArray(query[key]) ? query[key] : [query[key]]), value];
36
+ else query[key] = value;
37
+ }
38
+ return Object.assign(query, rewrite.params);
39
+ }
40
+
41
+ module.exports = { parseRewrite, readRewriteMarker, readRewriteHeader, rewriteQuery };
@@ -0,0 +1,64 @@
1
+ 'use strict';
2
+ const { NextRequest, NextURL } = require('./server.cjs');
3
+ const { CookieStore } = require('./cookies.cjs');
4
+ const { inCacheScope } = require('./data-cache.cjs');
5
+ const { dynamicUsage, forceStaticRender } = require('./static-generation.cjs');
6
+
7
+ const requestData = new Set(['headers', 'cookies', 'url', 'body', 'blob', 'json', 'text', 'arrayBuffer', 'formData', 'bytes']);
8
+ const urlData = new Set(['search', 'searchParams', 'url', 'href', 'origin', 'toJSON', 'toString']);
9
+
10
+ function reflect(target, property) {
11
+ const value = Reflect.get(target, property, target);
12
+ return typeof value === 'function' ? value.bind(target) : value;
13
+ }
14
+
15
+ function proxyRouteRequest(request, context) {
16
+ const force = forceStaticRender(context);
17
+ const dynamic = expression => {
18
+ if (inCacheScope()) throw new Error(`${expression} cannot be accessed inside unstable_cache; read it outside and pass the required values as arguments`);
19
+ dynamicUsage(expression, context);
20
+ };
21
+ const emptyHeaders = new Proxy(new Headers(), { get(target, property) {
22
+ if (['set', 'append', 'delete'].includes(property)) return () => { throw new Error('Request headers are read-only in force-static routes'); };
23
+ return reflect(target, property);
24
+ } });
25
+ const emptyCookies = new CookieStore('');
26
+ function proxyUrl(url) {
27
+ const searchParams = new URLSearchParams();
28
+ let proxy;
29
+ proxy = new Proxy(url, { get(target, property) {
30
+ if (property === 'clone') return () => proxyUrl(target.clone());
31
+ if (force) {
32
+ if (property === 'search') return '';
33
+ if (property === 'searchParams') return searchParams;
34
+ if (property === 'url') return undefined;
35
+ if (property === 'href') {
36
+ const canonical = new URL(target.href);
37
+ canonical.host = 'localhost:3000'; canonical.protocol = 'http:'; canonical.search = '';
38
+ return canonical.href;
39
+ }
40
+ if (property === 'toString' || property === 'toJSON') return () => proxy.href;
41
+ } else if (urlData.has(property)) dynamic(`nextUrl.${property}`);
42
+ return reflect(target, property);
43
+ }, set(target, property, value) {
44
+ // Native URL accessors use private slots, so mutations on a cloned
45
+ // nextUrl must use the real URL as their receiver as well as reads.
46
+ return Reflect.set(target, property, value, target);
47
+ } });
48
+ return proxy;
49
+ }
50
+ const nextUrl = proxyUrl(request.nextUrl);
51
+ return new Proxy(request, { get(target, property) {
52
+ if (property === 'nextUrl') return nextUrl;
53
+ if (property === 'clone') return () => proxyRouteRequest(new NextRequest(target.clone(), { nextConfig: target.nextUrl._nextConfig }), context);
54
+ if (force) {
55
+ if (property === 'headers') return emptyHeaders;
56
+ if (property === 'cookies') return emptyCookies;
57
+ if (property === 'url') return nextUrl.href;
58
+ if (property === 'geo' || property === 'ip') return undefined;
59
+ } else if (requestData.has(property)) dynamic(`request.${property}`);
60
+ return reflect(target, property);
61
+ } });
62
+ }
63
+
64
+ module.exports = { proxyRouteRequest };
@@ -0,0 +1,137 @@
1
+ 'use strict';
2
+
3
+ const React = require('react');
4
+ const { rewriteQuery } = require('./rewrite.cjs');
5
+ const { removeBasePath } = require('./paths.cjs');
6
+ const { localePath } = require('./locale.cjs');
7
+ const RouterContext = React.createContext(null);
8
+
9
+ function formatUrl(value) {
10
+ if (typeof value === 'string') return value;
11
+ if (!value || typeof value !== 'object') throw new TypeError('Expected a URL string or object');
12
+ let pathname = value.pathname || '';
13
+ const query = new URLSearchParams(typeof value.query === 'string' ? value.query : undefined);
14
+ for (const [name, values] of Object.entries(typeof value.query === 'object' && value.query || {})) {
15
+ for (const item of Array.isArray(values) ? values : [values]) {
16
+ if (item !== undefined && item !== null) query.append(name, String(item));
17
+ }
18
+ }
19
+ // Interpolate dynamic route names when a URL object is supplied.
20
+ pathname = pathname.replace(/\[\[\.\.\.([^\]]+)\]\]|\[\.\.\.([^\]]+)\]|\[([^\]]+)\]/g, (match, optional, catchall, single) => {
21
+ const name = optional || catchall || single;
22
+ const raw = typeof value.query === 'string' ? (query.has(name) ? query.getAll(name) : undefined) : value.query?.[name];
23
+ if (raw === undefined) return optional ? '' : match;
24
+ query.delete(name);
25
+ return (Array.isArray(raw) ? raw : [raw]).map(item => encodeURIComponent(String(item))).join('/');
26
+ });
27
+ const search = (value.search != null ? String(value.search).replace(/^\?/, '') : query.toString()).replace(/#/g, '%23');
28
+ const hash = value.hash ? `#${String(value.hash).replace(/^#/, '')}` : '';
29
+ let protocol = value.protocol || '';
30
+ if (protocol && !protocol.endsWith(':')) protocol += ':';
31
+ let host = value.host || '';
32
+ if (!host && value.hostname) {
33
+ host = value.hostname.includes(':') && !value.hostname.startsWith('[') ? `[${value.hostname}]` : value.hostname;
34
+ if (value.port) host += `:${value.port}`;
35
+ }
36
+ if (value.auth && host) host = `${encodeURIComponent(value.auth).replace(/%3A/i, ':')}@${host}`;
37
+ const slashes = value.slashes || (host && (!protocol || /^(?:https?|ftp|gopher|file):$/.test(protocol)));
38
+ if (slashes && pathname && !pathname.startsWith('/')) pathname = `/${pathname}`;
39
+ pathname = pathname.replace(/[?#]/g, encodeURIComponent);
40
+ return `${protocol}${slashes ? '//' : ''}${host}${pathname}${search ? `?${search}` : ''}${hash}`;
41
+ }
42
+
43
+ const handlers = new Map();
44
+ const events = {
45
+ on(type, callback) { const list = handlers.get(type) || []; list.push(callback); handlers.set(type, list); },
46
+ off(type, callback) { const list = handlers.get(type); if (!list) return; const index = list.indexOf(callback); if (index !== -1) list.splice(index, 1); if (!list.length) handlers.delete(type); },
47
+ emit(type, ...args) { for (const callback of [...(handlers.get(type) || [])]) callback(...args); },
48
+ };
49
+ let controller;
50
+ function installPagesRouter(value) { controller = value; }
51
+ function navigate(url, as, options, replace) {
52
+ if (typeof window === 'undefined') throw new Error('Router navigation is only available in the browser');
53
+ if (controller) return controller.navigate(url, as, { ...options, replace });
54
+ const target = new URL(formatUrl(as || url), window.location.href);
55
+ if (!['http:', 'https:'].includes(target.protocol)) throw new Error('Unsupported navigation protocol');
56
+ window.location[replace ? 'replace' : 'assign'](target.href);
57
+ return Promise.resolve(true);
58
+ }
59
+ const methods = {
60
+ push: (url, as, options) => navigate(url, as, options, false),
61
+ replace: (url, as, options) => navigate(url, as, options, true),
62
+ reload: () => { if (typeof window !== 'undefined') window.location.reload(); },
63
+ back: () => { if (typeof window !== 'undefined') { controller?.saveScroll(); window.history.back(); } },
64
+ forward: () => { if (typeof window !== 'undefined') { controller?.saveScroll(); window.history.forward(); } },
65
+ prefetch: (url, as, options) => controller ? controller.prefetch(url, as, options) : Promise.resolve(),
66
+ beforePopState: callback => { if (controller) controller.beforePopState(callback); },
67
+ };
68
+ function makeRouter(snapshot) {
69
+ return { pathname: '/', query: {}, asPath: '/', basePath: '', isReady: true, isFallback: false, isPreview: false,
70
+ ...snapshot, route: snapshot.pathname || '/', ...methods, events };
71
+ }
72
+
73
+ function withRouteParams(query, router) {
74
+ for (const segment of String(router?.pathname || '').split('/')) {
75
+ const match = /^\[(?:\[)?(?:\.\.\.)?([^\]]+)\]\]?$/.exec(segment);
76
+ if (match && router?.query && Object.hasOwn(router.query, match[1])) {
77
+ Object.defineProperty(query, match[1], { value: router.query[match[1]], enumerable: true, configurable: true, writable: true });
78
+ }
79
+ }
80
+ return query;
81
+ }
82
+
83
+ function RouterProvider({ router, children, managed = false }) {
84
+ const [location, setLocation] = React.useState(null);
85
+ React.useEffect(() => {
86
+ if (managed) return;
87
+ const refresh = () => {
88
+ const url = new URL(window.location.href);
89
+ const query = router?.rewrite ? rewriteQuery(router.rewrite) : Object.create(null);
90
+ if (!router?.rewrite) for (const [key, value] of url.searchParams) {
91
+ if (Object.hasOwn(query, key)) query[key] = [...(Array.isArray(query[key]) ? query[key] : [query[key]]), value];
92
+ else query[key] = value;
93
+ }
94
+ withRouteParams(query, router);
95
+ setLocation({ query, asPath: `${localePath(removeBasePath(url.pathname, router?.basePath || ''), router?.i18n).pathname}${url.search}${url.hash}` });
96
+ };
97
+ refresh();
98
+ window.addEventListener('hashchange', refresh);
99
+ window.addEventListener('popstate', refresh);
100
+ return () => { window.removeEventListener('hashchange', refresh); window.removeEventListener('popstate', refresh); };
101
+ }, [router, managed]);
102
+ // A fallback data update introduces route params before the location effect reruns.
103
+ // Keep those params in the same render as the new props and isFallback:false.
104
+ const value = React.useMemo(() => makeRouter({ ...router, ...(managed ? {} : location),
105
+ ...(!managed && location ? { query: withRouteParams({ ...location.query }, router) } : {}),
106
+ }), [router, location, managed]);
107
+ return React.createElement(RouterContext.Provider, { value }, children);
108
+ }
109
+
110
+ function useRouter() {
111
+ const value = React.useContext(RouterContext);
112
+ if (!value) throw new Error('useRouter must be used inside the PRNext router provider');
113
+ return value;
114
+ }
115
+
116
+ function withRouter(Component) {
117
+ function WithRouter(props) { return React.createElement(Component, { ...props, router: useRouter() }); }
118
+ WithRouter.displayName = `withRouter(${Component.displayName || Component.name || 'Component'})`;
119
+ return WithRouter;
120
+ }
121
+
122
+ const singleton = { ...methods, events };
123
+ for (const field of ['route', 'pathname', 'query', 'asPath', 'basePath', 'isReady', 'isFallback', 'isPreview', 'locale', 'locales', 'defaultLocale', 'domainLocales', 'isLocaleDomain']) {
124
+ Object.defineProperty(singleton, field, { enumerable: true, get() {
125
+ if (!controller) throw new Error('No router instance found. Use next/router in the browser or useRouter inside a page.');
126
+ return makeRouter(controller.snapshot())[field];
127
+ } });
128
+ }
129
+ module.exports = singleton;
130
+ module.exports.default = singleton;
131
+ module.exports.RouterProvider = RouterProvider;
132
+ module.exports.RouterContext = RouterContext;
133
+ module.exports.useRouter = useRouter;
134
+ module.exports.withRouter = withRouter;
135
+ module.exports.formatUrl = formatUrl;
136
+ module.exports.makeRouter = makeRouter;
137
+ module.exports.installPagesRouter = installPagesRouter;
@@ -0,0 +1,58 @@
1
+ import type { ComponentType, ReactNode, ReactElement } from 'react';
2
+ export interface UrlObject {
3
+ auth?: string | null;
4
+ host?: string | null;
5
+ hostname?: string | null;
6
+ href?: string | null;
7
+ path?: string | null;
8
+ pathname?: string | null;
9
+ port?: string | number | null;
10
+ protocol?: string | null;
11
+ slashes?: boolean | null;
12
+ query?: string | Record<string, string | number | boolean | Array<string | number | boolean> | null | undefined> | null;
13
+ search?: string | null;
14
+ hash?: string | null;
15
+ }
16
+ export interface RouterSnapshot {
17
+ locale?: string;
18
+ locales?: string[];
19
+ defaultLocale?: string;
20
+ domainLocales?: NonNullable<import('./index.js').NextConfig['i18n']>['domains'];
21
+ isLocaleDomain?: boolean;
22
+ pathname: string;
23
+ query: Record<string, string | string[] | undefined>;
24
+ asPath: string;
25
+ isReady?: boolean;
26
+ isFallback?: boolean;
27
+ isPreview?: boolean;
28
+ basePath?: string;
29
+ }
30
+ export interface PRNextRouter extends RouterSnapshot {
31
+ route: string;
32
+ isReady: boolean;
33
+ isFallback: boolean;
34
+ isPreview: boolean;
35
+ basePath: string;
36
+ push(url: string | UrlObject, as?: string | UrlObject, options?: { scroll?: boolean; shallow?: boolean; locale?: string | false }): Promise<boolean>;
37
+ replace(url: string | UrlObject, as?: string | UrlObject, options?: { scroll?: boolean; shallow?: boolean; locale?: string | false }): Promise<boolean>;
38
+ prefetch(url: string | UrlObject, as?: string | UrlObject, options?: { priority?: boolean; locale?: string | false }): Promise<void>;
39
+ beforePopState(callback: (state: { url: string; as: string; options: { shallow?: boolean; scroll?: boolean } }) => boolean): void;
40
+ events: RouterEvents;
41
+ reload(): void;
42
+ back(): void;
43
+ forward(): void;
44
+ }
45
+ export type RouterEvent = 'routeChangeStart' | 'beforeHistoryChange' | 'routeChangeComplete' | 'routeChangeError' | 'hashChangeStart' | 'hashChangeComplete';
46
+ export interface RouterEvents {
47
+ on(type: RouterEvent, callback: (...args: any[]) => void): void;
48
+ off(type: RouterEvent, callback: (...args: any[]) => void): void;
49
+ emit(type: RouterEvent, ...args: any[]): void;
50
+ }
51
+ export type NextRouter = PRNextRouter;
52
+ export function useRouter(): PRNextRouter;
53
+ export function RouterProvider(props: { router: RouterSnapshot; children?: ReactNode; managed?: boolean }): ReactElement;
54
+ export function withRouter<Props extends { router: PRNextRouter }>(Component: ComponentType<Props>): ComponentType<Omit<Props, 'router'>>;
55
+ export function formatUrl(url: string | UrlObject): string;
56
+ export function makeRouter(snapshot: RouterSnapshot): PRNextRouter;
57
+ declare const router: PRNextRouter;
58
+ export default router;
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ const React = require('react');
4
+
5
+ module.exports.ScriptContext = React.createContext({});