refactor(core): modularize request pipeline
This commit is contained in:
1 parent
b86be36d67
commit
1b67fd2ff1
36 files changed
+2047
-1271
No files matched your search
@@ -16,18 +16,33 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { handleRequest } from '../../../src/app/handle-request.js';
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* ALLOWED_METHODS?: string,
|
||||
* ALLOWED_ORIGINS?: string,
|
||||
* CACHE_DURATION?: string,
|
||||
* MAX_PATH_LENGTH?: string,
|
||||
* MAX_RETRIES?: string,
|
||||
* RETRY_DELAY_MS?: string,
|
||||
* TIMEOUT_SECONDS?: string
|
||||
* }} RuntimeEnv
|
||||
*/
|
||||
|
||||
import { handleRequest } from '../src/index.js';
|
||||
/**
|
||||
* @typedef {{
|
||||
* env?: RuntimeEnv,
|
||||
* geo?: unknown,
|
||||
* ip?: string,
|
||||
* waitUntil?: (promise: Promise<unknown>) => void
|
||||
* }} FunctionAdapterContext
|
||||
*/
|
||||
|
||||
/**
|
||||
* Edge Function handler.
|
||||
* @param {Request} request - Standard Web API Request object
|
||||
* @param {object} [context] - Platform-specific context (Netlify only)
|
||||
* @param {object} [context.geo] - Geolocation data (Netlify)
|
||||
* @param {string} [context.ip] - Client IP address (Netlify)
|
||||
* @param {object} [context.env] - Environment variables (Netlify)
|
||||
* @param {(promise: Promise<unknown>) => void} [context.waitUntil] - Background task extension (Netlify)
|
||||
* @param {FunctionAdapterContext} [context] - Platform-specific context (Netlify only)
|
||||
* @returns {Promise<Response>} Standard Web API Response
|
||||
* @example
|
||||
* // Netlify invokes with context
|
||||
@@ -37,14 +52,17 @@ import { handleRequest } from '../src/index.js';
|
||||
* handler(request)
|
||||
*/
|
||||
export default async function handler(request, context) {
|
||||
const runtimeContext = context || /** @type {FunctionAdapterContext} */ ({});
|
||||
|
||||
// Detect runtime environment
|
||||
const isNetlify = context && (context.geo !== undefined || context.ip !== undefined);
|
||||
const isNetlify = runtimeContext.geo !== undefined || runtimeContext.ip !== undefined;
|
||||
|
||||
// Normalize environment variables
|
||||
// Netlify provides context.env, Vercel Edge uses globalThis
|
||||
/** @type {RuntimeEnv} */
|
||||
let envSource;
|
||||
if (isNetlify) {
|
||||
envSource = context.env || {};
|
||||
envSource = runtimeContext.env || {};
|
||||
} else if (typeof process !== 'undefined' && process.env) {
|
||||
// Vercel or Node.js environment
|
||||
envSource = process.env;
|
||||
@@ -60,14 +78,23 @@ export default async function handler(request, context) {
|
||||
CACHE_DURATION: envSource.CACHE_DURATION,
|
||||
ALLOWED_METHODS: envSource.ALLOWED_METHODS,
|
||||
ALLOWED_ORIGINS: envSource.ALLOWED_ORIGINS,
|
||||
MAX_PATH_LENGTH: envSource.MAX_PATH_LENGTH,
|
||||
MAX_PATH_LENGTH: envSource.MAX_PATH_LENGTH
|
||||
};
|
||||
|
||||
// Create normalized execution context
|
||||
const waitUntil = isNetlify && runtimeContext.waitUntil ? runtimeContext.waitUntil : null;
|
||||
const ctx = {
|
||||
waitUntil: isNetlify && context.waitUntil
|
||||
? (promise) => context.waitUntil(promise)
|
||||
: (_promise) => {
|
||||
waitUntil: waitUntil
|
||||
? /**
|
||||
* Forwards background work in runtimes that support waitUntil.
|
||||
* @param {Promise<unknown>} promise
|
||||
*/
|
||||
promise => waitUntil(promise)
|
||||
: (
|
||||
/** @type {Promise<unknown>} */
|
||||
_promise
|
||||
) => {
|
||||
void _promise;
|
||||
// No-op on Vercel: background tasks not supported
|
||||
// Cache writes will run synchronously instead
|
||||
console.warn('waitUntil is not supported in Vercel Edge Runtime');
|
||||
@@ -84,5 +111,5 @@ export default async function handler(request, context) {
|
||||
|
||||
// Vercel Edge Runtime configuration (ignored by Netlify)
|
||||
export const config = {
|
||||
runtime: 'edge',
|
||||
runtime: 'edge'
|
||||
};
|
||||
@@ -16,9 +16,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* eslint-disable no-undef, no-unused-vars */
|
||||
/* eslint-disable no-undef */
|
||||
|
||||
import { handleRequest } from './src/index.js';
|
||||
import { handleRequest } from '../../src/app/handle-request.js';
|
||||
|
||||
/**
|
||||
* Deno Deploy handler.
|
||||
@@ -40,13 +40,17 @@ async function handler(request) {
|
||||
CACHE_DURATION: Deno.env.get('CACHE_DURATION'),
|
||||
ALLOWED_METHODS: Deno.env.get('ALLOWED_METHODS'),
|
||||
ALLOWED_ORIGINS: Deno.env.get('ALLOWED_ORIGINS'),
|
||||
MAX_PATH_LENGTH: Deno.env.get('MAX_PATH_LENGTH'),
|
||||
MAX_PATH_LENGTH: Deno.env.get('MAX_PATH_LENGTH')
|
||||
};
|
||||
|
||||
// Create minimal ExecutionContext-like object
|
||||
// Deno Deploy doesn't support waitUntil, so cache writes are synchronous
|
||||
const ctx = {
|
||||
waitUntil: (promise) => {
|
||||
waitUntil: (
|
||||
/** @type {Promise<unknown>} */
|
||||
promise
|
||||
) => {
|
||||
void promise;
|
||||
// No-op on Deno: background tasks not supported
|
||||
console.warn('waitUntil is not supported in Deno Deploy');
|
||||
},
|
||||
@@ -59,5 +63,9 @@ async function handler(request) {
|
||||
return handleRequest(request, env, ctx);
|
||||
}
|
||||
|
||||
// Start the server
|
||||
Deno.serve(handler);
|
||||
// Start the server only when executing inside Deno.
|
||||
if (typeof Deno !== 'undefined' && typeof Deno.serve === 'function') {
|
||||
Deno.serve(handler);
|
||||
}
|
||||
|
||||
export { handler };
|
||||
@@ -16,9 +16,18 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { handleRequest } from '../../../src/app/handle-request.js';
|
||||
|
||||
|
||||
import { handleRequest } from '../src/index.js';
|
||||
/**
|
||||
* @typedef {{
|
||||
* request: Request,
|
||||
* env: Record<string, unknown>,
|
||||
* params: object,
|
||||
* waitUntil: (promise: Promise<unknown>) => void,
|
||||
* next: () => Promise<Response>,
|
||||
* data: object
|
||||
* }} PagesFunctionContext
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pages Function handler for all routes.
|
||||
@@ -31,13 +40,7 @@ import { handleRequest } from '../src/index.js';
|
||||
* The [[path]] syntax in the filename creates a catch-all route that matches
|
||||
* any path, allowing this single function to handle all requests to the Pages
|
||||
* application.
|
||||
* @param {object} context - Pages Function context
|
||||
* @param {Request} context.request - The incoming HTTP request
|
||||
* @param {object} context.env - Environment variables and bindings (KV, secrets, etc.)
|
||||
* @param {object} context.params - Route parameters (path segments from [[path]])
|
||||
* @param {(promise: Promise<unknown>) => void} context.waitUntil - Extend function execution for background tasks
|
||||
* @param {() => Promise<Response>} context.next - Call next middleware in chain (not used here)
|
||||
* @param {object} context.data - Shared data between functions
|
||||
* @param {PagesFunctionContext} context - Pages Function context
|
||||
* @returns {Promise<Response>} The HTTP response to return to the client
|
||||
* @example
|
||||
* // This is called automatically by Pages
|
||||
|
||||
Reference in new issue
Block a user