Files
Fluxup_PAP/node_modules/expo-server/build/mjs/runtime/index.js
2026-03-10 16:18:05 +00:00

123 lines
4.6 KiB
JavaScript

import { errorToResponse } from './error';
import { scopeRef } from './scope';
import { importMetaRegistry } from '../utils/importMetaRegistry';
function setupRuntime() {
try {
Object.defineProperty(globalThis, 'origin', {
enumerable: true,
configurable: true,
get() {
// NOTE(@kitten): By convention, this property must be a string, and runtimes typically
// choose to stringify "null" when the value is not available
return scopeRef.current?.getStore()?.origin ?? 'null';
},
});
}
catch { }
try {
Object.defineProperty(globalThis, '__ExpoImportMetaRegistry', {
enumerable: true,
configurable: true,
get() {
return importMetaRegistry;
},
});
}
catch { }
}
export function createRequestScope(scopeDefinition, makeRequestAPISetup) {
setupRuntime();
// NOTE(@kitten): For long-running servers, this will always be a noop. It therefore
// makes sense for us to provide a default that doesn't do anything.
function defaultWaitUntil(promise) {
promise.finally(() => { });
}
return async (run, ...args) => {
// Initialize the scope definition which is used to isolate the runtime API between
// requests. The implementation of scopes differs per runtime, and is only initialized
// once the first request is received
scopeRef.current = scopeDefinition;
const setup = makeRequestAPISetup(...args);
const { waitUntil = defaultWaitUntil } = setup;
const deferredTasks = [];
const responseHeadersUpdates = [];
const scope = {
...setup,
origin: setup.origin,
environment: setup.environment,
requestHeaders: setup.requestHeaders,
waitUntil,
deferTask: setup.deferTask,
setResponseHeaders(updateHeaders) {
responseHeadersUpdates.push(updateHeaders);
},
};
if (!scope.deferTask) {
scope.deferTask = function deferTask(fn) {
deferredTasks.push(fn);
};
}
let result;
try {
result =
scopeRef.current != null
? await scopeRef.current.run(scope, () => run(...args))
: await run(...args);
}
catch (error) {
if (error != null && error instanceof Response && !error.bodyUsed) {
result = error;
}
else if (error != null && error instanceof Error && 'status' in error) {
return errorToResponse(error);
}
else {
throw error;
}
}
// Recreate the response with mutable headers, since the original response
// may have an immutable headers guard (like from `Response.redirect()`)
result = new Response(result.body, {
...result,
status: result.status,
statusText: result.statusText,
headers: result.headers,
// Cloudflare-specific response properties
cf: result.cf,
webSocket: result.webSocket,
});
deferredTasks.forEach((fn) => {
const maybePromise = fn();
if (maybePromise != null)
waitUntil(maybePromise);
});
for (const updateHeaders of responseHeadersUpdates) {
let headers = result.headers;
if (typeof updateHeaders === 'function') {
headers = updateHeaders(result.headers) || headers;
}
else if (updateHeaders instanceof Headers) {
headers = updateHeaders;
}
else if (typeof updateHeaders === 'object' && updateHeaders) {
for (const headerName in updateHeaders) {
if (Array.isArray(updateHeaders[headerName])) {
for (const headerValue of updateHeaders[headerName]) {
headers.append(headerName, headerValue);
}
}
else if (updateHeaders[headerName] != null) {
headers.set(headerName, updateHeaders[headerName]);
}
}
}
if (headers !== result.headers) {
for (const [headerName, headerValue] of headers) {
result.headers.set(headerName, headerValue);
}
}
}
return result;
};
}
//# sourceMappingURL=index.js.map