@opennextjs/aws 3.5.6 → 3.5.7

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.
@@ -1,6 +1,16 @@
1
1
  import type { TagCacheMetaFile } from "../types/cache.js";
2
2
  import * as buildHelper from "./helper.js";
3
- export declare function createStaticAssets(options: buildHelper.BuildOptions): void;
3
+ /**
4
+ * Copy the static assets to the output folder
5
+ *
6
+ * WARNING: `useBasePath` should be set to `false` when the output file is used.
7
+ *
8
+ * @param options OpenNext build options
9
+ * @param useBasePath whether to copy files into the to Next.js configured basePath
10
+ */
11
+ export declare function createStaticAssets(options: buildHelper.BuildOptions, { useBasePath }?: {
12
+ useBasePath?: boolean | undefined;
13
+ }): void;
4
14
  /**
5
15
  * Create the cache assets.
6
16
  *
@@ -1,16 +1,31 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { loadConfig } from "../adapters/config/util.js";
3
4
  import logger from "../logger.js";
4
5
  import { isBinaryContentType } from "../utils/binary.js";
5
6
  import * as buildHelper from "./helper.js";
6
- export function createStaticAssets(options) {
7
+ /**
8
+ * Copy the static assets to the output folder
9
+ *
10
+ * WARNING: `useBasePath` should be set to `false` when the output file is used.
11
+ *
12
+ * @param options OpenNext build options
13
+ * @param useBasePath whether to copy files into the to Next.js configured basePath
14
+ */
15
+ export function createStaticAssets(options, { useBasePath = false } = {}) {
7
16
  logger.info("Bundling static assets...");
8
17
  const { appBuildOutputPath, appPublicPath, outputDir, appPath } = options;
18
+ const NextConfig = loadConfig(path.join(appBuildOutputPath, ".next"));
19
+ const basePath = useBasePath ? (NextConfig.basePath ?? "") : "";
9
20
  // Create output folder
10
- const outputPath = path.join(outputDir, "assets");
21
+ const outputPath = path.join(outputDir, "assets", basePath);
11
22
  fs.mkdirSync(outputPath, { recursive: true });
12
23
  /**
13
- * Next.js outputs assets into multiple files. Copy into the same directory.
24
+ * Next.js outputs assets into multiple files.
25
+ *
26
+ * Copy into the same directory:
27
+ * - `.open-next/assets` when `useBasePath` is `false`
28
+ * - `.open-next/assets/basePath` when `useBasePath` is `true`
14
29
  *
15
30
  * Copy over:
16
31
  * - .next/BUILD_ID => BUILD_ID
@@ -15,6 +15,7 @@ import * as buildHelper from "./helper.js";
15
15
  import { installDependencies } from "./installDeps.js";
16
16
  import { applyCodePatches } from "./patch/codePatcher.js";
17
17
  import { patchEnvVars, patchFetchCacheForISR, patchFetchCacheSetMissingWaitUntil, patchNextServer, patchUnstableCacheForISR, } from "./patch/patches/index.js";
18
+ import { patchBackgroundRevalidation } from "./patch/patches/patchBackgroundRevalidation.js";
18
19
  export async function createServerBundle(options, codeCustomization) {
19
20
  const { config } = options;
20
21
  const foundRoutes = new Set();
@@ -121,6 +122,7 @@ async function generateBundle(name, options, fnOptions, codeCustomization) {
121
122
  patchUnstableCacheForISR,
122
123
  patchNextServer,
123
124
  patchEnvVars,
125
+ patchBackgroundRevalidation,
124
126
  ...additionalCodePatches,
125
127
  ]);
126
128
  // Build Lambda code
@@ -146,6 +148,7 @@ async function generateBundle(name, options, fnOptions, codeCustomization) {
146
148
  ...(disableNextPrebundledReact ? ["applyNextjsPrebundledReact"] : []),
147
149
  ...(disableRouting ? ["withRouting"] : []),
148
150
  ...(isAfter142 ? ["patchAsyncStorage"] : []),
151
+ ...(isAfter141 ? ["appendPrefetch"] : []),
149
152
  ],
150
153
  }),
151
154
  openNextReplacementPlugin({
@@ -0,0 +1,11 @@
1
+ export declare const rule = "\nrule:\n kind: binary_expression\n all:\n - has:\n kind: unary_expression\n regex: \"!cachedResponse.isStale\"\n - has:\n kind: member_expression\n regex: \"context.isPrefetch\"\nfix:\n 'true'";
2
+ export declare const patchBackgroundRevalidation: {
3
+ name: string;
4
+ patches: {
5
+ versions: ">=14.1.0";
6
+ field: {
7
+ pathFilter: RegExp;
8
+ patchCode: import("../codePatcher.js").PatchCodeFn;
9
+ };
10
+ }[];
11
+ };
@@ -0,0 +1,27 @@
1
+ import { getCrossPlatformPathRegex } from "../../../utils/regex.js";
2
+ import { createPatchCode } from "../astCodePatcher.js";
3
+ export const rule = `
4
+ rule:
5
+ kind: binary_expression
6
+ all:
7
+ - has:
8
+ kind: unary_expression
9
+ regex: "!cachedResponse.isStale"
10
+ - has:
11
+ kind: member_expression
12
+ regex: "context.isPrefetch"
13
+ fix:
14
+ 'true'`;
15
+ export const patchBackgroundRevalidation = {
16
+ name: "patchBackgroundRevalidation",
17
+ patches: [
18
+ {
19
+ // TODO: test for earlier versions of Next
20
+ versions: ">=14.1.0",
21
+ field: {
22
+ pathFilter: getCrossPlatformPathRegex("server/response-cache/index.js"),
23
+ patchCode: createPatchCode(rule),
24
+ },
25
+ },
26
+ ],
27
+ };
@@ -115,7 +115,12 @@ export async function openNextHandler(internalEvent, options) {
115
115
  // 1. We could just let the revalidation go as normal, but due to race conditions the revalidation will be unreliable
116
116
  // 2. We could alter the lastModified time of our cache to make next believe that the cache is fresh, but this could cause issues with stale data since the cdn will cache the stale data as if it was fresh
117
117
  // 3. OUR CHOICE: We could pass a purpose prefetch header to the serverless function to make next believe that the request is a prefetch request and not trigger revalidation (This could potentially break in the future if next changes the behavior of prefetch requests)
118
- headers: { ...headers, purpose: "prefetch" },
118
+ headers: {
119
+ ...headers,
120
+ //#override appendPrefetch
121
+ purpose: "prefetch",
122
+ //#endOverride
123
+ },
119
124
  body: preprocessedEvent.body,
120
125
  remoteAddress: preprocessedEvent.remoteAddress,
121
126
  };
@@ -71,13 +71,15 @@ export async function handleMiddleware(internalEvent, initialSearch, middlewareL
71
71
  const responseHeaders = result.headers;
72
72
  const reqHeaders = {};
73
73
  const resHeaders = {};
74
- responseHeaders.delete("x-middleware-override-headers");
75
- /* Next will set the header `x-middleware-set-cookie` when you `set-cookie` in the middleware.
76
- * We can delete it here since it will be set in `set-cookie` aswell. Next removes this header in the response themselves.
77
- * `x-middleware-next` is set when you invoke `NextResponse.next()`. We can delete it here aswell.
78
- */
79
- responseHeaders.delete("x-middleware-set-cookie");
80
- responseHeaders.delete("x-middleware-next");
74
+ // These are internal headers used by Next.js, we don't want to expose them to the client
75
+ const filteredHeaders = [
76
+ "x-middleware-override-headers",
77
+ "x-middleware-set-cookie",
78
+ "x-middleware-next",
79
+ "x-middleware-rewrite",
80
+ // We need to drop `content-encoding` because it will be decoded
81
+ "content-encoding",
82
+ ];
81
83
  const xMiddlewareKey = "x-middleware-request-";
82
84
  responseHeaders.forEach((value, key) => {
83
85
  if (key.startsWith(xMiddlewareKey)) {
@@ -85,6 +87,8 @@ export async function handleMiddleware(internalEvent, initialSearch, middlewareL
85
87
  reqHeaders[k] = value;
86
88
  }
87
89
  else {
90
+ if (filteredHeaders.includes(key.toLowerCase()))
91
+ return;
88
92
  if (key.toLowerCase() === "set-cookie") {
89
93
  resHeaders[key] = resHeaders[key]
90
94
  ? [...resHeaders[key], value]
@@ -95,20 +99,6 @@ export async function handleMiddleware(internalEvent, initialSearch, middlewareL
95
99
  }
96
100
  }
97
101
  });
98
- // If the middleware returned a Redirect, we set the `Location` header with
99
- // the redirected url and end the response.
100
- if (statusCode >= 300 && statusCode < 400) {
101
- resHeaders.location =
102
- responseHeaders.get("location") ?? resHeaders.location;
103
- // res.setHeader("Location", location);
104
- return {
105
- body: emptyReadableStream(),
106
- type: internalEvent.type,
107
- statusCode: statusCode,
108
- headers: resHeaders,
109
- isBase64Encoded: false,
110
- };
111
- }
112
102
  // If the middleware returned a Rewrite, set the `url` to the pathname of the rewrite
113
103
  // NOTE: the header was added to `req` from above
114
104
  const rewriteUrl = responseHeaders.get("x-middleware-rewrite");
@@ -134,11 +124,11 @@ export async function handleMiddleware(internalEvent, initialSearch, middlewareL
134
124
  });
135
125
  }
136
126
  }
137
- // If the middleware returned a `NextResponse`, pipe the body to res. This will return
138
- // the body immediately to the client.
139
- if (result.body) {
127
+ // If the middleware wants to directly return a response (i.e. not using `NextResponse.next()` or `NextResponse.rewrite()`)
128
+ // we return the response directly
129
+ if (!rewriteUrl && !responseHeaders.get("x-middleware-next")) {
140
130
  // transfer response body to res
141
- const body = result.body;
131
+ const body = result.body ?? emptyReadableStream();
142
132
  return {
143
133
  type: internalEvent.type,
144
134
  statusCode: statusCode,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "access": "public"
4
4
  },
5
5
  "name": "@opennextjs/aws",
6
- "version": "3.5.6",
6
+ "version": "3.5.7",
7
7
  "bin": {
8
8
  "open-next": "./dist/index.js"
9
9
  },