next
Version:
The React Framework
458 lines (457 loc) • 19 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
clearAllModuleContexts: null,
clearModuleContext: null,
edgeSandboxNextRequestContext: null,
getModuleContext: null,
requestStore: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
clearAllModuleContexts: function() {
return clearAllModuleContexts;
},
clearModuleContext: function() {
return clearModuleContext;
},
edgeSandboxNextRequestContext: function() {
return edgeSandboxNextRequestContext;
},
getModuleContext: function() {
return getModuleContext;
},
requestStore: function() {
return requestStore;
}
});
const _async_hooks = require("async_hooks");
const _constants = require("../../../shared/lib/constants");
const _edgeruntime = require("next/dist/compiled/edge-runtime");
const _fs = require("fs");
const _utils = require("../utils");
const _pick = require("../../../lib/pick");
const _fetchinlineassets = require("./fetch-inline-assets");
const _vm = require("vm");
const _nodebuffer = /*#__PURE__*/ _interop_require_default(require("node:buffer"));
const _nodeevents = /*#__PURE__*/ _interop_require_default(require("node:events"));
const _nodeassert = /*#__PURE__*/ _interop_require_default(require("node:assert"));
const _nodeutil = /*#__PURE__*/ _interop_require_default(require("node:util"));
const _nodeasync_hooks = /*#__PURE__*/ _interop_require_default(require("node:async_hooks"));
const _resourcemanagers = require("./resource-managers");
const _builtinrequestcontext = require("../../after/builtin-request-context");
const _patcherrorinspect = require("../../patch-error-inspect");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
let getServerError;
let decorateServerError;
if (process.env.NODE_ENV === 'development') {
const middleware = require('../../../client/components/react-dev-overlay/server/middleware-webpack');
getServerError = middleware.getServerError;
decorateServerError = require('../../../shared/lib/error-source').decorateServerError;
} else {
getServerError = (error, _)=>error;
decorateServerError = (_, __)=>{};
}
/**
* A Map of cached module contexts indexed by the module name. It allows
* to have a different cache scoped per module name or depending on the
* provided module key on creation.
*/ const moduleContexts = new Map();
const pendingModuleCaches = new Map();
async function clearAllModuleContexts() {
_resourcemanagers.intervalsManager.removeAll();
_resourcemanagers.timeoutsManager.removeAll();
moduleContexts.clear();
pendingModuleCaches.clear();
}
async function clearModuleContext(path) {
_resourcemanagers.intervalsManager.removeAll();
_resourcemanagers.timeoutsManager.removeAll();
const handleContext = (key, cache, context)=>{
if (cache == null ? void 0 : cache.paths.has(path)) {
context.delete(key);
}
};
for (const [key, cache] of moduleContexts){
handleContext(key, cache, moduleContexts);
}
for (const [key, cache] of pendingModuleCaches){
handleContext(key, await cache, pendingModuleCaches);
}
}
async function loadWasm(wasm) {
const modules = {};
await Promise.all(wasm.map(async (binding)=>{
const module1 = await WebAssembly.compile(await _fs.promises.readFile(binding.filePath));
modules[binding.name] = module1;
}));
return modules;
}
function buildEnvironmentVariablesFrom(injectedEnvironments) {
const pairs = Object.keys(process.env).map((key)=>[
key,
process.env[key]
]);
const env = Object.fromEntries(pairs);
for (const key of Object.keys(injectedEnvironments)){
env[key] = injectedEnvironments[key];
}
env.NEXT_RUNTIME = 'edge';
return env;
}
function throwUnsupportedAPIError(name) {
const error = Object.defineProperty(new Error(`A Node.js API is used (${name}) which is not supported in the Edge Runtime.
Learn more: https://nextjs.org/docs/api-reference/edge-runtime`), "__NEXT_ERROR_CODE", {
value: "E97",
enumerable: false,
configurable: true
});
decorateServerError(error, _constants.COMPILER_NAMES.edgeServer);
throw error;
}
function createProcessPolyfill(env) {
const processPolyfill = {
env: buildEnvironmentVariablesFrom(env)
};
const overriddenValue = {};
for (const key of Object.keys(process)){
if (key === 'env') continue;
Object.defineProperty(processPolyfill, key, {
get () {
if (overriddenValue[key] !== undefined) {
return overriddenValue[key];
}
if (typeof process[key] === 'function') {
return ()=>throwUnsupportedAPIError(`process.${key}`);
}
return undefined;
},
set (value) {
overriddenValue[key] = value;
},
enumerable: false
});
}
return processPolyfill;
}
function addStub(context, name) {
Object.defineProperty(context, name, {
get () {
return function() {
throwUnsupportedAPIError(name);
};
},
enumerable: false
});
}
function getDecorateUnhandledError(runtime) {
const EdgeRuntimeError = runtime.evaluate(`Error`);
return (error)=>{
if (error instanceof EdgeRuntimeError) {
decorateServerError(error, _constants.COMPILER_NAMES.edgeServer);
}
};
}
function getDecorateUnhandledRejection(runtime) {
const EdgeRuntimeError = runtime.evaluate(`Error`);
return (rejected)=>{
if (rejected.reason instanceof EdgeRuntimeError) {
decorateServerError(rejected.reason, _constants.COMPILER_NAMES.edgeServer);
}
};
}
const NativeModuleMap = (()=>{
const mods = {
'node:buffer': (0, _pick.pick)(_nodebuffer.default, [
'constants',
'kMaxLength',
'kStringMaxLength',
'Buffer',
'SlowBuffer'
]),
'node:events': (0, _pick.pick)(_nodeevents.default, [
'EventEmitter',
'captureRejectionSymbol',
'defaultMaxListeners',
'errorMonitor',
'listenerCount',
'on',
'once'
]),
'node:async_hooks': (0, _pick.pick)(_nodeasync_hooks.default, [
'AsyncLocalStorage',
'AsyncResource'
]),
'node:assert': (0, _pick.pick)(_nodeassert.default, [
'AssertionError',
'deepEqual',
'deepStrictEqual',
'doesNotMatch',
'doesNotReject',
'doesNotThrow',
'equal',
'fail',
'ifError',
'match',
'notDeepEqual',
'notDeepStrictEqual',
'notEqual',
'notStrictEqual',
'ok',
'rejects',
'strict',
'strictEqual',
'throws'
]),
'node:util': (0, _pick.pick)(_nodeutil.default, [
'_extend',
'callbackify',
'format',
'inherits',
'promisify',
'types'
])
};
return new Map(Object.entries(mods));
})();
const requestStore = new _async_hooks.AsyncLocalStorage();
const edgeSandboxNextRequestContext = (0, _builtinrequestcontext.createLocalRequestContext)();
/**
* Create a module cache specific for the provided parameters. It includes
* a runtime context, require cache and paths cache.
*/ async function createModuleContext(options) {
const warnedEvals = new Set();
const warnedWasmCodegens = new Set();
const { edgeFunctionEntry } = options;
const wasm = await loadWasm(edgeFunctionEntry.wasm ?? []);
const runtime = new _edgeruntime.EdgeRuntime({
codeGeneration: process.env.NODE_ENV !== 'production' ? {
strings: true,
wasm: true
} : undefined,
extend: (context)=>{
context.process = createProcessPolyfill(edgeFunctionEntry.env);
Object.defineProperty(context, 'require', {
enumerable: false,
value: (id)=>{
const value = NativeModuleMap.get(id);
if (!value) {
throw Object.defineProperty(new TypeError('Native module not found: ' + id), "__NEXT_ERROR_CODE", {
value: "E546",
enumerable: false,
configurable: true
});
}
return value;
}
});
if (process.env.NODE_ENV !== 'production') {
context.__next_log_error__ = function(err) {
options.onError(err);
};
}
context.__next_eval__ = function __next_eval__(fn) {
const key = fn.toString();
if (!warnedEvals.has(key)) {
const warning = getServerError(Object.defineProperty(new Error(`Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Edge Runtime
Learn More: https://nextjs.org/docs/messages/edge-dynamic-code-evaluation`), "__NEXT_ERROR_CODE", {
value: "E149",
enumerable: false,
configurable: true
}), _constants.COMPILER_NAMES.edgeServer);
warning.name = 'DynamicCodeEvaluationWarning';
Error.captureStackTrace(warning, __next_eval__);
warnedEvals.add(key);
options.onWarning(warning);
}
return fn();
};
context.__next_webassembly_compile__ = function __next_webassembly_compile__(fn) {
const key = fn.toString();
if (!warnedWasmCodegens.has(key)) {
const warning = getServerError(Object.defineProperty(new Error(`Dynamic WASM code generation (e. g. 'WebAssembly.compile') not allowed in Edge Runtime.
Learn More: https://nextjs.org/docs/messages/edge-dynamic-code-evaluation`), "__NEXT_ERROR_CODE", {
value: "E184",
enumerable: false,
configurable: true
}), _constants.COMPILER_NAMES.edgeServer);
warning.name = 'DynamicWasmCodeGenerationWarning';
Error.captureStackTrace(warning, __next_webassembly_compile__);
warnedWasmCodegens.add(key);
options.onWarning(warning);
}
return fn();
};
context.__next_webassembly_instantiate__ = async function __next_webassembly_instantiate__(fn) {
const result = await fn();
// If a buffer is given, WebAssembly.instantiate returns an object
// containing both a module and an instance while it returns only an
// instance if a WASM module is given. Utilize the fact to determine
// if the WASM code generation happens.
//
// https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate#primary_overload_%E2%80%94_taking_wasm_binary_code
const instantiatedFromBuffer = result.hasOwnProperty('module');
const key = fn.toString();
if (instantiatedFromBuffer && !warnedWasmCodegens.has(key)) {
const warning = getServerError(Object.defineProperty(new Error(`Dynamic WASM code generation ('WebAssembly.instantiate' with a buffer parameter) not allowed in Edge Runtime.
Learn More: https://nextjs.org/docs/messages/edge-dynamic-code-evaluation`), "__NEXT_ERROR_CODE", {
value: "E40",
enumerable: false,
configurable: true
}), _constants.COMPILER_NAMES.edgeServer);
warning.name = 'DynamicWasmCodeGenerationWarning';
Error.captureStackTrace(warning, __next_webassembly_instantiate__);
warnedWasmCodegens.add(key);
options.onWarning(warning);
}
return result;
};
const __fetch = context.fetch;
context.fetch = async (input, init = {})=>{
const callingError = Object.defineProperty(new Error('[internal]'), "__NEXT_ERROR_CODE", {
value: "E5",
enumerable: false,
configurable: true
});
const assetResponse = await (0, _fetchinlineassets.fetchInlineAsset)({
input,
assets: options.edgeFunctionEntry.assets,
distDir: options.distDir,
context
});
if (assetResponse) {
return assetResponse;
}
init.headers = new Headers(init.headers ?? {});
if (!init.headers.has('user-agent')) {
init.headers.set(`user-agent`, `Next.js Middleware`);
}
const response = typeof input === 'object' && 'url' in input ? __fetch(input.url, {
...(0, _pick.pick)(input, [
'method',
'body',
'cache',
'credentials',
'integrity',
'keepalive',
'mode',
'redirect',
'referrer',
'referrerPolicy',
'signal'
]),
...init,
headers: {
...Object.fromEntries(input.headers),
...Object.fromEntries(init.headers)
}
}) : __fetch(String(input), init);
return await response.catch((err)=>{
callingError.message = err.message;
err.stack = callingError.stack;
throw err;
});
};
const __Request = context.Request;
context.Request = class extends __Request {
constructor(input, init){
const url = typeof input !== 'string' && 'url' in input ? input.url : String(input);
(0, _utils.validateURL)(url);
super(url, init);
this.next = init == null ? void 0 : init.next;
}
};
const __redirect = context.Response.redirect.bind(context.Response);
context.Response.redirect = (...args)=>{
(0, _utils.validateURL)(args[0]);
return __redirect(...args);
};
for (const name of _constants.EDGE_UNSUPPORTED_NODE_APIS){
addStub(context, name);
}
Object.assign(context, wasm);
context.performance = performance;
context.AsyncLocalStorage = _async_hooks.AsyncLocalStorage;
// @ts-ignore the timeouts have weird types in the edge runtime
context.setInterval = (...args)=>_resourcemanagers.intervalsManager.add(args);
// @ts-ignore the timeouts have weird types in the edge runtime
context.clearInterval = (interval)=>_resourcemanagers.intervalsManager.remove(interval);
// @ts-ignore the timeouts have weird types in the edge runtime
context.setTimeout = (...args)=>_resourcemanagers.timeoutsManager.add(args);
// @ts-ignore the timeouts have weird types in the edge runtime
context.clearTimeout = (timeout)=>_resourcemanagers.timeoutsManager.remove(timeout);
// Duplicated from packages/next/src/server/after/builtin-request-context.ts
// because we need to use the sandboxed `Symbol.for`, not the one from the outside
const NEXT_REQUEST_CONTEXT_SYMBOL = context.Symbol.for('@next/request-context');
Object.defineProperty(context, NEXT_REQUEST_CONTEXT_SYMBOL, {
enumerable: false,
value: edgeSandboxNextRequestContext
});
return context;
}
});
const decorateUnhandledError = getDecorateUnhandledError(runtime);
runtime.context.addEventListener('error', decorateUnhandledError);
const decorateUnhandledRejection = getDecorateUnhandledRejection(runtime);
runtime.context.addEventListener('unhandledrejection', decorateUnhandledRejection);
(0, _patcherrorinspect.patchErrorInspectEdgeLite)(runtime.context.Error);
// An Error from within the Edge Runtime could also bubble up into the Node.js process.
// For example, uncaught errors are handled in the Node.js runtime.
(0, _patcherrorinspect.patchErrorInspectNodeJS)(runtime.context.Error);
return {
runtime,
paths: new Map(),
warnedEvals: new Set()
};
}
function getModuleContextShared(options) {
let deferredModuleContext = pendingModuleCaches.get(options.moduleName);
if (!deferredModuleContext) {
deferredModuleContext = createModuleContext(options);
pendingModuleCaches.set(options.moduleName, deferredModuleContext);
}
return deferredModuleContext;
}
async function getModuleContext(options) {
let lazyModuleContext;
if (options.useCache) {
lazyModuleContext = moduleContexts.get(options.moduleName) || await getModuleContextShared(options);
}
if (!lazyModuleContext) {
lazyModuleContext = await createModuleContext(options);
moduleContexts.set(options.moduleName, lazyModuleContext);
}
const moduleContext = lazyModuleContext;
const evaluateInContext = (filepath)=>{
if (!moduleContext.paths.has(filepath)) {
const content = (0, _fs.readFileSync)(filepath, 'utf-8');
try {
(0, _vm.runInContext)(content, moduleContext.runtime.context, {
filename: filepath
});
moduleContext.paths.set(filepath, content);
} catch (error) {
if (options.useCache) {
moduleContext == null ? void 0 : moduleContext.paths.delete(filepath);
}
throw error;
}
}
};
return {
...moduleContext,
evaluateInContext
};
}
//# sourceMappingURL=context.js.map
;