@opennextjs/aws 3.9.13 → 3.9.15

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,3 +1,10 @@
1
+ /**
2
+ * Copies a file and ensures the destination is writable.
3
+ * This is necessary because copyFileSync preserves file permissions,
4
+ * and source files may be read-only (e.g., in Bazel's node_modules).
5
+ * Without this, subsequent patches would fail with EACCES errors.
6
+ */
7
+ export declare function copyFileAndMakeOwnerWritable(src: string, dest: string): void;
1
8
  export declare function isExcluded(srcPath: string): boolean;
2
9
  interface CopyTracedFilesOptions {
3
10
  buildOutputPath: string;
@@ -1,11 +1,25 @@
1
1
  import url from "node:url";
2
- import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, statSync, symlinkSync, writeFileSync, } from "node:fs";
2
+ import { chmodSync, copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, readdirSync, readlinkSync, statSync, symlinkSync, writeFileSync, } from "node:fs";
3
3
  import path from "node:path";
4
4
  import { loadAppPathsManifest, loadBuildId, loadConfig, loadFunctionsConfigManifest, loadMiddlewareManifest, loadPagesManifest, loadPrerenderManifest, } from "../adapters/config/util.js";
5
5
  import { getCrossPlatformPathRegex } from "../utils/regex.js";
6
6
  import logger from "../logger.js";
7
7
  import { INSTRUMENTATION_TRACE_FILE, MIDDLEWARE_TRACE_FILE, } from "./constant.js";
8
8
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
9
+ /**
10
+ * Copies a file and ensures the destination is writable.
11
+ * This is necessary because copyFileSync preserves file permissions,
12
+ * and source files may be read-only (e.g., in Bazel's node_modules).
13
+ * Without this, subsequent patches would fail with EACCES errors.
14
+ */
15
+ export function copyFileAndMakeOwnerWritable(src, dest) {
16
+ copyFileSync(src, dest);
17
+ // Ensure the copied file is writable (add owner write permission)
18
+ const stats = statSync(dest);
19
+ if (!(stats.mode & 0o200)) {
20
+ chmodSync(dest, stats.mode | 0o200);
21
+ }
22
+ }
9
23
  //TODO: we need to figure which packages we could safely remove
10
24
  const EXCLUDED_PACKAGES = [
11
25
  "caniuse-lite",
@@ -29,7 +43,7 @@ export function isExcluded(srcPath) {
29
43
  function copyPatchFile(outputDir) {
30
44
  const patchFile = path.join(__dirname, "patch", "patchedAsyncStorage.js");
31
45
  const outputPatchFile = path.join(outputDir, "patchedAsyncStorage.cjs");
32
- copyFileSync(patchFile, outputPatchFile);
46
+ copyFileAndMakeOwnerWritable(patchFile, outputPatchFile);
33
47
  }
34
48
  export function getManifests(nextDir) {
35
49
  return {
@@ -138,13 +152,13 @@ File ${serverPath} does not exist
138
152
  // Check for instrumentation trace file
139
153
  if (existsSync(path.join(dotNextDir, INSTRUMENTATION_TRACE_FILE))) {
140
154
  // We still need to copy the nft.json file so that computeCopyFilesForPage doesn't throw
141
- copyFileSync(path.join(dotNextDir, INSTRUMENTATION_TRACE_FILE), path.join(standaloneNextDir, INSTRUMENTATION_TRACE_FILE));
155
+ copyFileAndMakeOwnerWritable(path.join(dotNextDir, INSTRUMENTATION_TRACE_FILE), path.join(standaloneNextDir, INSTRUMENTATION_TRACE_FILE));
142
156
  computeCopyFilesForPage("instrumentation");
143
157
  logger.debug("Adding instrumentation trace files");
144
158
  }
145
159
  if (existsSync(path.join(dotNextDir, MIDDLEWARE_TRACE_FILE))) {
146
160
  // We still need to copy the nft.json file so that computeCopyFilesForPage doesn't throw
147
- copyFileSync(path.join(dotNextDir, MIDDLEWARE_TRACE_FILE), path.join(standaloneNextDir, MIDDLEWARE_TRACE_FILE));
161
+ copyFileAndMakeOwnerWritable(path.join(dotNextDir, MIDDLEWARE_TRACE_FILE), path.join(standaloneNextDir, MIDDLEWARE_TRACE_FILE));
148
162
  computeCopyFilesForPage("middleware");
149
163
  logger.debug("Adding node middleware trace files");
150
164
  }
@@ -207,7 +221,7 @@ File ${serverPath} does not exist
207
221
  // where some files listed in the .nft.json might not be present in the standalone folder
208
222
  // TODO: investigate that further - is it expected?
209
223
  try {
210
- copyFileSync(from, to);
224
+ copyFileAndMakeOwnerWritable(from, to);
211
225
  }
212
226
  catch (e) {
213
227
  logger.debug("Error copying file:", e);
@@ -218,7 +232,7 @@ File ${serverPath} does not exist
218
232
  readdirSync(standaloneNextDir)
219
233
  .filter((fileOrDir) => !statSync(path.join(standaloneNextDir, fileOrDir)).isDirectory())
220
234
  .forEach((file) => {
221
- copyFileSync(path.join(standaloneNextDir, file), path.join(outputNextDir, file));
235
+ copyFileAndMakeOwnerWritable(path.join(standaloneNextDir, file), path.join(outputNextDir, file));
222
236
  tracedFiles.push(path.join(outputNextDir, file));
223
237
  });
224
238
  // We then need to copy all the files at the root of server
@@ -227,7 +241,7 @@ File ${serverPath} does not exist
227
241
  .filter((fileOrDir) => !statSync(path.join(standaloneServerDir, fileOrDir)).isDirectory())
228
242
  .filter((file) => file !== "server.js")
229
243
  .forEach((file) => {
230
- copyFileSync(path.join(standaloneServerDir, file), path.join(path.join(outputNextDir, "server"), file));
244
+ copyFileAndMakeOwnerWritable(path.join(standaloneServerDir, file), path.join(path.join(outputNextDir, "server"), file));
231
245
  tracedFiles.push(path.join(outputNextDir, "server", file));
232
246
  });
233
247
  // Copy patch file
@@ -245,7 +259,7 @@ File ${serverPath} does not exist
245
259
  mkdirSync(path.dirname(path.join(outputNextDir, filePath)), {
246
260
  recursive: true,
247
261
  });
248
- copyFileSync(path.join(standaloneNextDir, filePath), path.join(outputNextDir, filePath));
262
+ copyFileAndMakeOwnerWritable(path.join(standaloneNextDir, filePath), path.join(outputNextDir, filePath));
249
263
  }
250
264
  };
251
265
  const manifests = getManifests(standaloneNextDir);
@@ -1,6 +1,7 @@
1
1
  import type { CodePatcher } from "../codePatcher.js";
2
2
  export declare const disablePreloadingRule = "\nrule:\n kind: statement_block\n inside:\n kind: if_statement\n any:\n - has:\n kind: member_expression\n pattern: this.nextConfig.experimental.preloadEntriesOnStart\n stopBy: end\n - has:\n kind: binary_expression\n pattern: appDocumentPreloading === true\n stopBy: end\nfix:\n '{}'\n";
3
3
  export declare const removeMiddlewareManifestRule = "\nrule:\n kind: statement_block\n inside:\n kind: method_definition\n has:\n kind: property_identifier\n regex: ^getMiddlewareManifest$\nfix:\n '{return null;}'\n";
4
+ export declare const emptyHandleNextImageRequestRule = "\nrule:\n kind: assignment_expression\n pattern: this.handleNextImageRequest = $VALUE\n inside:\n kind: method_definition\n stopBy: end\n has:\n kind: property_identifier\n regex: ^constructor$\n inside:\n kind: class_body\nfix:\n this.handleNextImageRequest = async (req, res, parsedUrl) => false\n";
4
5
  /**
5
6
  * Swaps the body for a throwing implementation
6
7
  *
@@ -30,6 +30,23 @@ rule:
30
30
  fix:
31
31
  '{return null;}'
32
32
  `;
33
+ // Make `handleNextImageRequest` a no-op to avoid pulling `sharp`
34
+ // Apply to Next 14, 15, and 16
35
+ export const emptyHandleNextImageRequestRule = `
36
+ rule:
37
+ kind: assignment_expression
38
+ pattern: this.handleNextImageRequest = $VALUE
39
+ inside:
40
+ kind: method_definition
41
+ stopBy: end
42
+ has:
43
+ kind: property_identifier
44
+ regex: ^constructor$
45
+ inside:
46
+ kind: class_body
47
+ fix:
48
+ this.handleNextImageRequest = async (req, res, parsedUrl) => false
49
+ `;
33
50
  /**
34
51
  * Swaps the body for a throwing implementation
35
52
  *
@@ -81,6 +98,12 @@ export const patchNextServer = {
81
98
  contentFilter: /imageOptimizer\(/,
82
99
  patchCode: createPatchCode(createEmptyBodyRule("imageOptimizer")),
83
100
  },
101
+ // Make `handleNextImageRequest` a no-op to avoid pulling `sharp` - unused in OpenNext
102
+ {
103
+ pathFilter,
104
+ contentFilter: /handleNextImageRequest/,
105
+ patchCode: createPatchCode(emptyHandleNextImageRequestRule),
106
+ },
84
107
  // Disable Next background preloading done at creation of `NextServer`
85
108
  {
86
109
  versions: ">=14.0.0",
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "access": "public"
4
4
  },
5
5
  "name": "@opennextjs/aws",
6
- "version": "3.9.13",
6
+ "version": "3.9.15",
7
7
  "bin": {
8
8
  "open-next": "./dist/index.js"
9
9
  },
@@ -33,7 +33,7 @@
33
33
  "README.md"
34
34
  ],
35
35
  "dependencies": {
36
- "@ast-grep/napi": "^0.40.0",
36
+ "@ast-grep/napi": "^0.40.5",
37
37
  "@aws-sdk/client-cloudfront": "3.398.0",
38
38
  "@aws-sdk/client-dynamodb": "^3.398.0",
39
39
  "@aws-sdk/client-lambda": "^3.398.0",