1 Commits
Author SHA1 Message Date
github-actions[bot] de0a4af326 Convert Workers to Functions
Auto-converted from main branch commit 6e316f7ba6dc5540fbcd7ee263769140b5f391a7

Runtime files only (documentation, tests, and dev configs excluded).
2026-08-18 03:32:46 +00:00
8 changed files with 245 additions and 120 deletions

No files matched your search

+115
View File
@@ -0,0 +1,115 @@
/**
* 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'
};
+71
View File
@@ -0,0 +1,71 @@
/**
* 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 };
-70
View File
@@ -1,70 +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 {{
* 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);
}
+6
View File
@@ -0,0 +1,6 @@
[[edge_functions]]
function = "edge-handler"
path = "/*"
[build]
publish = "."
+22
View File
@@ -0,0 +1,22 @@
/**
* 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';
+9 -45
View File
@@ -1,50 +1,14 @@
{
"devDependencies": {
"@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"
"private": false,
"scripts": {
"dev": "vercel dev",
"deploy": "vercel --prod",
"vercel-build": "echo 'No build step required'"
},
"dependencies": {},
"devDependencies": {
"@vercel/node": "^3.0.0"
}
}
+22
View File
@@ -0,0 +1,22 @@
{
"$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"
}
]
}
]
}
-5
View File
@@ -1,5 +0,0 @@
#:schema node_modules/wrangler/config-schema.json
name = "xget"
pages_build_output_dir = "."
compatibility_date = "2024-10-22"
compatibility_flags = ["nodejs_compat"]