Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/long-items-poke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@opennextjs/cloudflare": patch
---

remove `eval` calls introduced by `depd` wrapped functions

Some dependencies of Next.js (`raw-body` and `send`) use `depd` to deprecate some of their functions,
`depd` uses `eval` to generate a deprecated version of such functions, this causes `eval` warnings in
the terminal even if these functions are never called, the changes here by patching the depd `wrapfunction`
function so that it still retains the same type of behavior but without using `eval`
2 changes: 2 additions & 0 deletions packages/cloudflare/src/cli/build/bundle-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { inlineFindDir } from "./patches/plugins/find-dir.js";
import { patchLoadInstrumentation } from "./patches/plugins/load-instrumentation.js";
import { inlineLoadManifest } from "./patches/plugins/load-manifest.js";
import { handleOptionalDependencies } from "./patches/plugins/optional-deps.js";
import { patchDepdDeprecations } from "./patches/plugins/patch-depd-deprecations.js";
import { fixRequire } from "./patches/plugins/require.js";
import { shimRequireHook } from "./patches/plugins/require-hook.js";
import { inlineRequirePage } from "./patches/plugins/require-page.js";
Expand Down Expand Up @@ -97,6 +98,7 @@ export async function bundleServer(buildOpts: BuildOptions): Promise<void> {
inlineFindDir(updater, buildOpts),
inlineLoadManifest(updater, buildOpts),
inlineBuildId(updater),
patchDepdDeprecations(updater),
// Apply updater updaters, must be the last plugin
updater.plugin,
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { describe, expect, test } from "vitest";

import { patchCode } from "../ast/util.js";
import { rule } from "./patch-depd-deprecations.js";

describe("patchDepdDeprecations", () => {
test("patch", () => {
const code = `
function prepareObjectStackTrace(e,t){
return t
}
function wrapfunction(fn,message){
if(typeof fn!=="function"){
throw new TypeError("argument fn must be a function")
}
var args=createArgumentsString(fn.length);
var deprecate=this;
var stack=getStack();
var site=callSiteLocation(stack[1]);
site.name=fn.name;
var deprecatedfn=eval("(function ("+args+") {\\n"+'"use strict"\\n'+"log.call(deprecate, message, site)\\n"+"return fn.apply(this, arguments)\\n"+"})");
return deprecatedfn;
}`;

expect(patchCode(code, rule)).toMatchInlineSnapshot(`
"function prepareObjectStackTrace(e,t){
return t
}
function wrapfunction(fn, message) { if(typeof fn !== 'function') throw new Error("argument fn must be a function"); return (...args) => { console.warn(message); return fn(...args); } }"
`);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { patchCode } from "../ast/util.js";
import type { ContentUpdater } from "./content-updater.js";

/**
* Some dependencies of Next.js use depd to deprecate some of their functions, depd uses `eval` to generate
* a deprecated version of such functions, this causes `eval` warnings in the terminal even if these functions
* are never called, this function fixes that by patching the depd `wrapfunction` function so that it still
* retains the same type of behavior but without using `eval`
*/
export function patchDepdDeprecations(updater: ContentUpdater) {
return updater.updateContent(
"patch-depd-deprecations",
{ filter: /\.(js|mjs|cjs|jsx|ts|tsx)$/, contentFilter: /argument fn must be a function/ },
({ contents }) => patchCode(contents, rule)
);
}

export const rule = `
rule:
kind: function_declaration
pattern: function wrapfunction($FN, $MESSAGE) { $$$ }
all:
- has:
kind: variable_declarator
stopBy: end
has:
field: name
pattern: deprecatedfn
- has:
kind: call_expression
stopBy: end
has:
kind: identifier
pattern: eval
fix:
function wrapfunction($FN, $MESSAGE) {
if(typeof $FN !== 'function') throw new Error("argument fn must be a function");
return (...args) => {
console.warn($MESSAGE);
return $FN(...args);
}
}
`;