Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a75b645f77 |
No files matched your search
-115
@@ -1,115 +0,0 @@
|
||||
/**
|
||||
* Xget - High-performance acceleration engine for developer resources
|
||||
* Copyright (C) Xi Xu
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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 {FunctionAdapterContext} [context] - Platform-specific context (Netlify only)
|
||||
* @returns {Promise<Response>} Standard Web API Response
|
||||
* @example
|
||||
* // Netlify invokes with context
|
||||
* handler(request, { geo: {...}, ip: '1.2.3.4', env: {...}, waitUntil: fn })
|
||||
* @example
|
||||
* // Vercel invokes without context
|
||||
* handler(request)
|
||||
*/
|
||||
export default async function handler(request, context) {
|
||||
const runtimeContext = context || /** @type {FunctionAdapterContext} */ ({});
|
||||
|
||||
// Detect runtime environment
|
||||
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 = runtimeContext.env || {};
|
||||
} else if (typeof process !== 'undefined' && process.env) {
|
||||
// Vercel or Node.js environment
|
||||
envSource = process.env;
|
||||
} else {
|
||||
// Fallback for other environments
|
||||
envSource = {};
|
||||
}
|
||||
|
||||
const env = {
|
||||
TIMEOUT_SECONDS: envSource.TIMEOUT_SECONDS,
|
||||
MAX_RETRIES: envSource.MAX_RETRIES,
|
||||
RETRY_DELAY_MS: envSource.RETRY_DELAY_MS,
|
||||
CACHE_DURATION: envSource.CACHE_DURATION,
|
||||
ALLOWED_METHODS: envSource.ALLOWED_METHODS,
|
||||
ALLOWED_ORIGINS: envSource.ALLOWED_ORIGINS,
|
||||
MAX_PATH_LENGTH: envSource.MAX_PATH_LENGTH
|
||||
};
|
||||
|
||||
// Create normalized execution context
|
||||
const waitUntil = isNetlify && runtimeContext.waitUntil ? runtimeContext.waitUntil : null;
|
||||
const ctx = {
|
||||
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');
|
||||
},
|
||||
passThroughOnException: () => {
|
||||
// Not supported on either platform in this context
|
||||
console.warn('passThroughOnException is not universally supported');
|
||||
}
|
||||
};
|
||||
|
||||
// Delegate to the main request handler
|
||||
return handleRequest(request, env, ctx);
|
||||
}
|
||||
|
||||
// Vercel Edge Runtime configuration (ignored by Netlify)
|
||||
export const config = {
|
||||
runtime: 'edge'
|
||||
};
|
||||
@@ -1,71 +0,0 @@
|
||||
/**
|
||||
* Xget - High-performance acceleration engine for developer resources
|
||||
* Copyright (C) Xi Xu
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* eslint-disable no-undef */
|
||||
|
||||
import { handleRequest } from './src/app/handle-request.js';
|
||||
|
||||
/**
|
||||
* Deno Deploy handler.
|
||||
*
|
||||
* This is the entry point for Deno Deploy deployments. It uses the
|
||||
* standard Deno.serve() API to handle incoming HTTP requests.
|
||||
* @param {Request} request - Standard Web API Request object
|
||||
* @returns {Promise<Response>} Standard Web API Response
|
||||
* @example
|
||||
* // Deno Deploy invokes automatically:
|
||||
* // Deno.serve((request) => handler(request))
|
||||
*/
|
||||
async function handler(request) {
|
||||
// Extract environment variables from Deno.env
|
||||
const env = {
|
||||
TIMEOUT_SECONDS: Deno.env.get('TIMEOUT_SECONDS'),
|
||||
MAX_RETRIES: Deno.env.get('MAX_RETRIES'),
|
||||
RETRY_DELAY_MS: Deno.env.get('RETRY_DELAY_MS'),
|
||||
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')
|
||||
};
|
||||
|
||||
// Create minimal ExecutionContext-like object
|
||||
// Deno Deploy doesn't support waitUntil, so cache writes are synchronous
|
||||
const ctx = {
|
||||
waitUntil: (
|
||||
/** @type {Promise<unknown>} */
|
||||
promise
|
||||
) => {
|
||||
void promise;
|
||||
// No-op on Deno: background tasks not supported
|
||||
console.warn('waitUntil is not supported in Deno Deploy');
|
||||
},
|
||||
passThroughOnException: () => {
|
||||
console.warn('passThroughOnException is not supported in Deno Deploy');
|
||||
}
|
||||
};
|
||||
|
||||
// Delegate to the main request handler
|
||||
return handleRequest(request, env, ctx);
|
||||
}
|
||||
|
||||
// Start the server only when executing inside Deno.
|
||||
if (typeof Deno !== 'undefined' && typeof Deno.serve === 'function') {
|
||||
Deno.serve(handler);
|
||||
}
|
||||
|
||||
export { handler };
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Xget - High-performance acceleration engine for developer resources
|
||||
* Copyright (C) Xi Xu
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { handleRequest } from '../src/app/handle-request.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.
|
||||
*
|
||||
* This catch-all route handler processes all incoming requests to the Xget
|
||||
* acceleration engine. It delegates request processing to the main handleRequest
|
||||
* function from the Workers code, maintaining full compatibility with the
|
||||
* existing implementation.
|
||||
*
|
||||
* 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 {PagesFunctionContext} context - Pages Function context
|
||||
* @returns {Promise<Response>} The HTTP response to return to the client
|
||||
* @example
|
||||
* // This is called automatically by Pages
|
||||
* // Runtime invokes: onRequest(context)
|
||||
* // Returns: Response with package data
|
||||
* @example
|
||||
* // Environment variables usage
|
||||
* // wrangler.toml: [vars] TIMEOUT_SECONDS = "60"
|
||||
* // context.env contains: { TIMEOUT_SECONDS: "60" }
|
||||
* // handleRequest uses createConfig(env) to override defaults
|
||||
*/
|
||||
export async function onRequest(context) {
|
||||
// Extract request, env, and create an execution context compatible with Workers
|
||||
const { request, env, waitUntil } = context;
|
||||
|
||||
// Create a minimal ExecutionContext-like object for compatibility
|
||||
const ctx = {
|
||||
waitUntil,
|
||||
passThroughOnException: () => {
|
||||
// Pages doesn't support passThroughOnException, so this is a no-op
|
||||
console.warn('passThroughOnException is not supported in Pages Functions');
|
||||
}
|
||||
};
|
||||
|
||||
// Delegate to the main request handler
|
||||
return handleRequest(request, env, ctx);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
[[edge_functions]]
|
||||
function = "edge-handler"
|
||||
path = "/*"
|
||||
|
||||
[build]
|
||||
publish = "."
|
||||
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Xget - High-performance acceleration engine for developer resources
|
||||
* Copyright (C) Xi Xu
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Netlify Edge Function entry point.
|
||||
*
|
||||
* This file serves as a redirect to the edge function handler
|
||||
* located at /api/index.js. Both Netlify and Vercel can use the same
|
||||
* handler code, with platform detection handling the differences.
|
||||
*
|
||||
* Netlify requires edge functions to be in netlify/edge-functions/,
|
||||
* while Vercel uses /api/ directory. This approach maintains a single
|
||||
* source of truth at /api/index.js.
|
||||
*/
|
||||
export { config, default } from '../../api/index.js';
|
||||
+46
-10
@@ -1,14 +1,50 @@
|
||||
{
|
||||
"name": "xget",
|
||||
"type": "module",
|
||||
"private": false,
|
||||
"scripts": {
|
||||
"dev": "vercel dev",
|
||||
"deploy": "vercel --prod",
|
||||
"vercel-build": "echo 'No build step required'"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@vercel/node": "^3.0.0"
|
||||
"@cloudflare/vitest-pool-workers": "^0.21.3",
|
||||
"@cloudflare/workers-types": "^5.20260804.1",
|
||||
"@commitlint/cli": "^21.2.1",
|
||||
"@commitlint/config-conventional": "^21.2.0",
|
||||
"@eslint/js": "^10.0.1",
|
||||
"@types/node": "^26.1.2",
|
||||
"@vitest/coverage-istanbul": "^4.1.10",
|
||||
"eslint": "^10.8.0",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-jsdoc": "^64.1.0",
|
||||
"istanbul-lib-coverage": "^3.2.2",
|
||||
"istanbul-lib-report": "^3.0.1",
|
||||
"istanbul-reports": "^3.2.0",
|
||||
"prettier": "^3.9.6",
|
||||
"simple-git-hooks": "^2.13.1",
|
||||
"typescript": "^7.0.2",
|
||||
"vitest": "^4.1.10",
|
||||
"wrangler": "^4.110.0"
|
||||
},
|
||||
"name": "xget",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"commitlint": "commitlint --last --verbose",
|
||||
"commitmsg": "commitlint --edit",
|
||||
"deploy": "wrangler pages deploy .",
|
||||
"dev": "wrangler dev",
|
||||
"format": "prettier --write src/ test/ *.js *.json",
|
||||
"format:check": "prettier --check src/ test/ *.js *.json",
|
||||
"lint": "eslint src/ test/ adapters/",
|
||||
"lint:fix": "eslint src/ test/ adapters/ --fix",
|
||||
"prepare": "simple-git-hooks",
|
||||
"start": "wrangler pages dev .",
|
||||
"test": "vitest",
|
||||
"test:coverage": "vitest run --config vitest.coverage.config.js --coverage",
|
||||
"test:run": "vitest run",
|
||||
"test:ui": "vitest --ui",
|
||||
"test:watch": "vitest --watch",
|
||||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"simple-git-hooks": {
|
||||
"commit-msg": "npx commitlint --edit $1"
|
||||
},
|
||||
"type": "module",
|
||||
"overrides": {
|
||||
"esbuild": "0.28.1"
|
||||
}
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"$schema": "https://openapi.vercel.sh/vercel.json",
|
||||
"name": "xget",
|
||||
"version": 2,
|
||||
"rewrites": [
|
||||
{
|
||||
"source": "/(.*)",
|
||||
"destination": "/api/index.js"
|
||||
}
|
||||
],
|
||||
"headers": [
|
||||
{
|
||||
"source": "/(.*)",
|
||||
"headers": [
|
||||
{
|
||||
"key": "X-Powered-By",
|
||||
"value": "Xget/Vercel"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#:schema node_modules/wrangler/config-schema.json
|
||||
name = "xget"
|
||||
pages_build_output_dir = "."
|
||||
compatibility_date = "2024-10-22"
|
||||
compatibility_flags = ["nodejs_compat"]
|
||||
Reference in new issue
Block a user