Improve JSDoc types and add eslint-plugin-jsdoc
Standardized JSDoc type annotations across the codebase, replacing 'Object' with 'object' and refining function signatures for better type safety. Added and configured eslint-plugin-jsdoc for enhanced documentation linting, and updated ESLint settings to include adapters and new JSDoc rules. Updated dependencies to include eslint-plugin-jsdoc and related packages.
This commit is contained in:
1 parent
bfec1d2d9e
commit
07f5f35972
18 files changed
+295
-102
No files matched your search
+2
-1
@@ -2,7 +2,8 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = tab
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
@@ -16,25 +16,22 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* eslint-disable no-undef, no-unused-vars */
|
||||
|
||||
|
||||
import { handleRequest } from '../src/index.js';
|
||||
|
||||
/**
|
||||
* 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 {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 {Function} [context.waitUntil] - Background task extension (Netlify)
|
||||
* @param {object} [context.env] - Environment variables (Netlify)
|
||||
* @param {(promise: Promise<unknown>) => void} [context.waitUntil] - Background task extension (Netlify)
|
||||
* @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)
|
||||
@@ -70,7 +67,7 @@ export default async function handler(request, context) {
|
||||
const ctx = {
|
||||
waitUntil: isNetlify && context.waitUntil
|
||||
? (promise) => context.waitUntil(promise)
|
||||
: (promise) => {
|
||||
: (_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');
|
||||
|
||||
@@ -25,10 +25,8 @@ import { handleRequest } from './src/index.js';
|
||||
*
|
||||
* 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))
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* eslint-disable no-undef */
|
||||
|
||||
|
||||
import { handleRequest } from '../src/index.js';
|
||||
|
||||
@@ -31,21 +31,18 @@ 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 {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 {Function} context.waitUntil - Extend function execution for background tasks
|
||||
* @param {Function} context.next - Call next middleware in chain (not used here)
|
||||
* @param {Object} context.data - Shared data between functions
|
||||
* @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
|
||||
* @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"
|
||||
@@ -58,7 +55,7 @@ export async function onRequest(context) {
|
||||
|
||||
// Create a minimal ExecutionContext-like object for compatibility
|
||||
const ctx = {
|
||||
waitUntil: waitUntil,
|
||||
waitUntil,
|
||||
passThroughOnException: () => {
|
||||
// Pages doesn't support passThroughOnException, so this is a no-op
|
||||
console.warn('passThroughOnException is not supported in Pages Functions');
|
||||
|
||||
+39
-1
@@ -1,10 +1,12 @@
|
||||
import js from '@eslint/js';
|
||||
import prettierConfig from 'eslint-config-prettier';
|
||||
import jsdoc from 'eslint-plugin-jsdoc';
|
||||
|
||||
export default [
|
||||
js.configs.recommended,
|
||||
jsdoc.configs['flat/recommended'],
|
||||
{
|
||||
files: ['src/**/*.js', 'test/**/*.js'],
|
||||
files: ['src/**/*.js', 'test/**/*.js', 'adapters/**/*.js'],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2022,
|
||||
sourceType: 'module',
|
||||
@@ -33,6 +35,7 @@ export default [
|
||||
TextDecoder: 'readonly',
|
||||
performance: 'readonly',
|
||||
globalThis: 'readonly',
|
||||
process: 'readonly',
|
||||
|
||||
// Vitest globals
|
||||
describe: 'readonly',
|
||||
@@ -45,7 +48,42 @@ export default [
|
||||
vi: 'readonly'
|
||||
}
|
||||
},
|
||||
settings: {
|
||||
jsdoc: {
|
||||
mode: 'typescript',
|
||||
tagNamePreference: {
|
||||
returns: 'returns'
|
||||
}
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
// JSDoc rules overrides
|
||||
'jsdoc/require-description': 'warn',
|
||||
'jsdoc/require-returns': 'off', // Often redundant if return type is void or obvious
|
||||
'jsdoc/require-param-description': 'off', // Names are often self-explanatory
|
||||
'jsdoc/no-undefined-types': [
|
||||
'warn',
|
||||
{
|
||||
definedTypes: [
|
||||
'ExecutionContext',
|
||||
'Cache',
|
||||
'RequestInit',
|
||||
'Request',
|
||||
'Response',
|
||||
'Headers',
|
||||
'URL',
|
||||
'URLSearchParams',
|
||||
'AbortController',
|
||||
'AbortSignal',
|
||||
'ReadableStream',
|
||||
'WritableStream',
|
||||
'TransformStream',
|
||||
'TextEncoder',
|
||||
'TextDecoder'
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
// Code quality rules
|
||||
'no-unused-vars': [
|
||||
'error',
|
||||
|
||||
Generated
+213
-12
@@ -16,6 +16,7 @@
|
||||
"@cloudflare/workers-types": "^4.20251205.0",
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-jsdoc": "^61.5.0",
|
||||
"prettier": "^3.7.4",
|
||||
"typescript": "^5.9.3",
|
||||
"vitest": "^3.1.4",
|
||||
@@ -188,6 +189,33 @@
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@es-joy/jsdoccomment": {
|
||||
"version": "0.76.0",
|
||||
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.76.0.tgz",
|
||||
"integrity": "sha512-g+RihtzFgGTx2WYCuTHbdOXJeAlGnROws0TeALx9ow/ZmOROOZkVg5wp/B44n0WJgI4SQFP1eWM2iRPlU2Y14w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.8",
|
||||
"@typescript-eslint/types": "^8.46.0",
|
||||
"comment-parser": "1.4.1",
|
||||
"esquery": "^1.6.0",
|
||||
"jsdoc-type-pratt-parser": "~6.10.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@es-joy/resolve.exports": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@es-joy/resolve.exports/-/resolve.exports-1.2.0.tgz",
|
||||
"integrity": "sha512-Q9hjxWI5xBM+qW2enxfe8wDKdFWMfd0Z29k5ZJnuBqD/CasY5Zryj09aCA6owbGATWz+39p5uIdaHXpopOcG8g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz",
|
||||
@@ -1584,6 +1612,19 @@
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@sindresorhus/base62": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/base62/-/base62-1.0.0.tgz",
|
||||
"integrity": "sha512-TeheYy0ILzBEI/CO55CP6zJCSdSWeRtGnHy8U8dWSUH4I68iqTsy7HkMktR4xakThc9jotkPQUXT4ITdbV7cHA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@sindresorhus/is": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.0.2.tgz",
|
||||
@@ -1635,6 +1676,20 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "8.49.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.49.0.tgz",
|
||||
"integrity": "sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/expect": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz",
|
||||
@@ -1698,7 +1753,6 @@
|
||||
"integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@vitest/utils": "3.2.4",
|
||||
"pathe": "^2.0.3",
|
||||
@@ -1714,7 +1768,6 @@
|
||||
"integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@vitest/pretty-format": "3.2.4",
|
||||
"magic-string": "^0.30.17",
|
||||
@@ -1771,7 +1824,6 @@
|
||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -1832,6 +1884,16 @@
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/are-docs-informative": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz",
|
||||
"integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
@@ -2062,6 +2124,16 @@
|
||||
"simple-swizzle": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/comment-parser": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
|
||||
"integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@@ -2327,7 +2399,6 @@
|
||||
"integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.8.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
@@ -2398,6 +2469,35 @@
|
||||
"eslint": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-jsdoc": {
|
||||
"version": "61.5.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-61.5.0.tgz",
|
||||
"integrity": "sha512-PR81eOGq4S7diVnV9xzFSBE4CDENRQGP0Lckkek8AdHtbj+6Bm0cItwlFnxsLFriJHspiE3mpu8U20eODyToIg==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@es-joy/jsdoccomment": "~0.76.0",
|
||||
"@es-joy/resolve.exports": "1.2.0",
|
||||
"are-docs-informative": "^0.0.2",
|
||||
"comment-parser": "1.4.1",
|
||||
"debug": "^4.4.3",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"espree": "^10.4.0",
|
||||
"esquery": "^1.6.0",
|
||||
"html-entities": "^2.6.0",
|
||||
"object-deep-merge": "^2.0.0",
|
||||
"parse-imports-exports": "^0.2.4",
|
||||
"semver": "^7.7.3",
|
||||
"spdx-expression-parse": "^4.0.0",
|
||||
"to-valid-identifier": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.11.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-scope": {
|
||||
"version": "8.4.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
|
||||
@@ -2846,6 +2946,23 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/html-entities": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz",
|
||||
"integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/mdevils"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://patreon.com/mdevils"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
|
||||
@@ -2997,6 +3114,16 @@
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/jsdoc-type-pratt-parser": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-6.10.0.tgz",
|
||||
"integrity": "sha512-+LexoTRyYui5iOhJGn13N9ZazL23nAHGkXsa1p/C8yeq79WRfLBag6ZZ0FQG2aRoc9yfo59JT9EYCQonOkHKkQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/json-buffer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
@@ -3264,6 +3391,13 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/object-deep-merge": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/object-deep-merge/-/object-deep-merge-2.0.0.tgz",
|
||||
"integrity": "sha512-3DC3UMpeffLTHiuXSy/UG4NOIYTLlY9u3V82+djSCLYClWobZiS4ivYzpIUWrRY/nfsJ8cWsKyG3QfyLePmhvg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/object-inspect": {
|
||||
"version": "1.13.4",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||
@@ -3360,6 +3494,23 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-imports-exports": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/parse-imports-exports/-/parse-imports-exports-0.2.4.tgz",
|
||||
"integrity": "sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"parse-statements": "1.0.11"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-statements": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/parse-statements/-/parse-statements-1.0.11.tgz",
|
||||
"integrity": "sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
@@ -3429,7 +3580,6 @@
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -3554,6 +3704,19 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/reserved-identifiers": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/reserved-identifiers/-/reserved-identifiers-1.2.0.tgz",
|
||||
"integrity": "sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-from": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||
@@ -3628,9 +3791,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.7.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
|
||||
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
@@ -3845,6 +4008,31 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/spdx-exceptions": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
|
||||
"integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
|
||||
"dev": true,
|
||||
"license": "CC-BY-3.0"
|
||||
},
|
||||
"node_modules/spdx-expression-parse": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
|
||||
"integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"spdx-exceptions": "^2.1.0",
|
||||
"spdx-license-ids": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/spdx-license-ids": {
|
||||
"version": "3.0.22",
|
||||
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz",
|
||||
"integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==",
|
||||
"dev": true,
|
||||
"license": "CC0-1.0"
|
||||
},
|
||||
"node_modules/stackback": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
|
||||
@@ -3979,6 +4167,23 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/to-valid-identifier": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-valid-identifier/-/to-valid-identifier-1.0.0.tgz",
|
||||
"integrity": "sha512-41wJyvKep3yT2tyPqX/4blcfybknGB4D+oETKLs7Q76UiPqRpUJK3hr1nxelyYO0PHKVzJwlu0aCeEAsGI6rpw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sindresorhus/base62": "^1.0.0",
|
||||
"reserved-identifiers": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
@@ -4053,7 +4258,6 @@
|
||||
"integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"pathe": "^2.0.3"
|
||||
}
|
||||
@@ -4092,7 +4296,6 @@
|
||||
"integrity": "sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"fdir": "^6.5.0",
|
||||
@@ -4191,7 +4394,6 @@
|
||||
"integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/chai": "^5.2.2",
|
||||
"@vitest/expect": "3.2.4",
|
||||
@@ -4309,7 +4511,6 @@
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"workerd": "bin/workerd"
|
||||
},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"@cloudflare/workers-types": "^4.20251205.0",
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-jsdoc": "^61.5.0",
|
||||
"prettier": "^3.7.4",
|
||||
"typescript": "^5.9.3",
|
||||
"vitest": "^3.1.4",
|
||||
|
||||
+13
-25
@@ -20,12 +20,10 @@ import { PLATFORMS } from './platforms.js';
|
||||
|
||||
/**
|
||||
* Security-related configuration options for request validation and CORS.
|
||||
*
|
||||
* @typedef {Object} SecurityConfig
|
||||
* @typedef {object} SecurityConfig
|
||||
* @property {string[]} ALLOWED_METHODS - List of allowed HTTP methods for incoming requests
|
||||
* @property {string[]} ALLOWED_ORIGINS - List of allowed CORS origins (use ['*'] for all origins)
|
||||
* @property {number} MAX_PATH_LENGTH - Maximum allowed URL path length in characters
|
||||
*
|
||||
* @example
|
||||
* // Default security config
|
||||
* const security = {
|
||||
@@ -33,7 +31,6 @@ import { PLATFORMS } from './platforms.js';
|
||||
* ALLOWED_ORIGINS: ['*'],
|
||||
* MAX_PATH_LENGTH: 2048
|
||||
* };
|
||||
*
|
||||
* @example
|
||||
* // Custom security config with restricted origins
|
||||
* const security = {
|
||||
@@ -49,15 +46,13 @@ import { PLATFORMS } from './platforms.js';
|
||||
* This configuration controls timeout behavior, retry logic, caching, security policies,
|
||||
* and platform URL mappings. All values can be overridden via environment variables
|
||||
* in Cloudflare Workers.
|
||||
*
|
||||
* @typedef {Object} ApplicationConfig
|
||||
* @typedef {object} ApplicationConfig
|
||||
* @property {number} TIMEOUT_SECONDS - Request timeout in seconds (default: 30)
|
||||
* @property {number} MAX_RETRIES - Maximum number of retry attempts for failed requests (default: 3)
|
||||
* @property {number} RETRY_DELAY_MS - Delay between retry attempts in milliseconds (default: 1000)
|
||||
* @property {number} CACHE_DURATION - Cache duration in seconds for successful responses (default: 1800)
|
||||
* @property {SecurityConfig} SECURITY - Security-related configurations
|
||||
* @property {Object.<string, string>} PLATFORMS - Platform-specific base URL mappings
|
||||
*
|
||||
* @property {{ [key: string]: string }} PLATFORMS - Platform-specific base URL mappings
|
||||
* @example
|
||||
* // Default configuration
|
||||
* const config = {
|
||||
@@ -72,7 +67,6 @@ import { PLATFORMS } from './platforms.js';
|
||||
* },
|
||||
* PLATFORMS: { gh: 'https://github.com', ... }
|
||||
* };
|
||||
*
|
||||
* @example
|
||||
* // Configuration with environment overrides
|
||||
* const env = {
|
||||
@@ -99,16 +93,13 @@ import { PLATFORMS } from './platforms.js';
|
||||
* - `ALLOWED_METHODS` - Comma-separated HTTP methods (default: 'GET,HEAD')
|
||||
* - `ALLOWED_ORIGINS` - Comma-separated CORS origins (default: '*')
|
||||
* - `MAX_PATH_LENGTH` - Override max path length (default: 2048)
|
||||
*
|
||||
* @param {Record<string, any>} env - Environment variables from Cloudflare Workers env object
|
||||
* @param {Record<string, unknown>} env - Environment variables from Cloudflare Workers env object
|
||||
* @returns {ApplicationConfig} Complete application configuration with applied overrides
|
||||
*
|
||||
* @example
|
||||
* // Create config with defaults (no environment variables)
|
||||
* const config = createConfig();
|
||||
* console.log(config.TIMEOUT_SECONDS); // 30
|
||||
* console.log(config.CACHE_DURATION); // 1800
|
||||
*
|
||||
* @example
|
||||
* // Create config with environment overrides
|
||||
* const env = {
|
||||
@@ -122,7 +113,6 @@ import { PLATFORMS } from './platforms.js';
|
||||
* console.log(config.MAX_RETRIES); // 5
|
||||
* console.log(config.CACHE_DURATION); // 3600 (1 hour)
|
||||
* console.log(config.SECURITY.ALLOWED_METHODS); // ['GET', 'HEAD', 'POST', 'PUT']
|
||||
*
|
||||
* @example
|
||||
* // Invalid environment values fallback to defaults
|
||||
* const env = {
|
||||
@@ -132,7 +122,6 @@ import { PLATFORMS } from './platforms.js';
|
||||
* const config = createConfig(env);
|
||||
* console.log(config.TIMEOUT_SECONDS); // 30 (default)
|
||||
* console.log(config.MAX_RETRIES); // 3 (default)
|
||||
*
|
||||
* @example
|
||||
* // Custom CORS origins
|
||||
* const env = {
|
||||
@@ -144,14 +133,16 @@ import { PLATFORMS } from './platforms.js';
|
||||
*/
|
||||
export function createConfig(env = {}) {
|
||||
return {
|
||||
TIMEOUT_SECONDS: parseInt(env.TIMEOUT_SECONDS, 10) || 30,
|
||||
MAX_RETRIES: parseInt(env.MAX_RETRIES, 10) || 3,
|
||||
RETRY_DELAY_MS: parseInt(env.RETRY_DELAY_MS, 10) || 1000,
|
||||
CACHE_DURATION: parseInt(env.CACHE_DURATION, 10) || 1800, // 30 minutes
|
||||
TIMEOUT_SECONDS: parseInt(String(env.TIMEOUT_SECONDS), 10) || 30,
|
||||
MAX_RETRIES: parseInt(String(env.MAX_RETRIES), 10) || 3,
|
||||
RETRY_DELAY_MS: parseInt(String(env.RETRY_DELAY_MS), 10) || 1000,
|
||||
CACHE_DURATION: parseInt(String(env.CACHE_DURATION), 10) || 1800, // 30 minutes
|
||||
SECURITY: {
|
||||
ALLOWED_METHODS: env.ALLOWED_METHODS ? env.ALLOWED_METHODS.split(',') : ['GET', 'HEAD'],
|
||||
ALLOWED_ORIGINS: env.ALLOWED_ORIGINS ? env.ALLOWED_ORIGINS.split(',') : ['*'],
|
||||
MAX_PATH_LENGTH: parseInt(env.MAX_PATH_LENGTH, 10) || 2048
|
||||
ALLOWED_METHODS:
|
||||
typeof env.ALLOWED_METHODS === 'string' ? env.ALLOWED_METHODS.split(',') : ['GET', 'HEAD'],
|
||||
ALLOWED_ORIGINS:
|
||||
typeof env.ALLOWED_ORIGINS === 'string' ? env.ALLOWED_ORIGINS.split(',') : ['*'],
|
||||
MAX_PATH_LENGTH: parseInt(String(env.MAX_PATH_LENGTH), 10) || 2048
|
||||
},
|
||||
PLATFORMS
|
||||
};
|
||||
@@ -163,14 +154,11 @@ export function createConfig(env = {}) {
|
||||
* This is a pre-instantiated configuration object using default values with no
|
||||
* environment overrides. In production (Cloudflare Workers), you should use
|
||||
* `createConfig(env)` instead to allow runtime configuration.
|
||||
*
|
||||
* @type {ApplicationConfig}
|
||||
*
|
||||
* @example
|
||||
* // Import default config
|
||||
* import { CONFIG } from './config/index.js';
|
||||
* console.log(CONFIG.TIMEOUT_SECONDS); // 30
|
||||
*
|
||||
* @example
|
||||
* // Check platform availability
|
||||
* if (CONFIG.PLATFORMS.npm) {
|
||||
|
||||
+1
-13
@@ -115,17 +115,13 @@
|
||||
* - `cr-suse` - SUSE Registry
|
||||
* - `cr-opensuse` - openSUSE Registry
|
||||
* - `cr-gitpod` - Gitpod Registry
|
||||
*
|
||||
* @type {Object.<string, string>}
|
||||
*
|
||||
* @type {{ [key: string]: string }}
|
||||
* @example
|
||||
* // Access GitHub base URL
|
||||
* const githubUrl = PLATFORMS.gh; // 'https://github.com'
|
||||
*
|
||||
* @example
|
||||
* // Access OpenAI API base URL
|
||||
* const openaiUrl = PLATFORMS['ip-openai']; // 'https://api.openai.com'
|
||||
*
|
||||
* @example
|
||||
* // Check if platform exists
|
||||
* if (PLATFORMS.npm) {
|
||||
@@ -248,41 +244,33 @@ export const SORTED_PLATFORMS = Object.keys(PLATFORMS).sort((a, b) => {
|
||||
*
|
||||
* The function handles special cases for platforms that require API path prefixes or
|
||||
* URL structure modifications to match their upstream API conventions.
|
||||
*
|
||||
* @param {string} path - The original request path including platform prefix (e.g., '/gh/user/repo')
|
||||
* @param {string} platformKey - The platform key from PLATFORMS object (e.g., 'gh', 'crates', 'npm')
|
||||
* @returns {string} The transformed path ready for upstream request
|
||||
*
|
||||
* @example
|
||||
* // Basic transformation - strips platform prefix
|
||||
* transformPath('/gh/torvalds/linux', 'gh')
|
||||
* // Returns: '/torvalds/linux'
|
||||
*
|
||||
* @example
|
||||
* // crates.io API transformation - adds API prefix
|
||||
* transformPath('/crates/serde/1.0.0/download', 'crates')
|
||||
* // Returns: '/api/v1/crates/serde/1.0.0/download'
|
||||
*
|
||||
* @example
|
||||
* // crates.io search endpoint
|
||||
* transformPath('/crates/?q=tokio', 'crates')
|
||||
* // Returns: '/api/v1/crates?q=tokio'
|
||||
*
|
||||
* @example
|
||||
* // Jenkins update center transformation
|
||||
* transformPath('/jenkins/update-center.json', 'jenkins')
|
||||
* // Returns: '/current/update-center.json'
|
||||
*
|
||||
* @example
|
||||
* // Homebrew API paths (pass-through)
|
||||
* transformPath('/homebrew/api/formula/git.json', 'homebrew-api')
|
||||
* // Returns: '/formula/git.json'
|
||||
*
|
||||
* @example
|
||||
* // Unknown platform (no transformation)
|
||||
* transformPath('/unknown/path', 'nonexistent')
|
||||
* // Returns: '/unknown/path'
|
||||
*
|
||||
* @example
|
||||
* // Multi-part platform key (hyphens converted to slashes)
|
||||
* transformPath('/ip/openai/v1/chat/completions', 'ip-openai')
|
||||
|
||||
+5
-5
@@ -24,9 +24,8 @@ import { isDockerRequest, validateRequest } from './utils/validation.js';
|
||||
|
||||
/**
|
||||
* Main request handler with comprehensive caching, retry logic, and security measures.
|
||||
*
|
||||
* @param {Request} request - The incoming HTTP request
|
||||
* @param {Object} env - Cloudflare Workers environment variables for runtime config overrides
|
||||
* @param {object} env - Cloudflare Workers environment variables for runtime config overrides
|
||||
* @param {ExecutionContext} ctx - Cloudflare Workers execution context for background tasks
|
||||
* @returns {Promise<Response>} The HTTP response with appropriate headers and body
|
||||
*/
|
||||
@@ -130,8 +129,8 @@ async function handleRequest(request, env, ctx) {
|
||||
/** @type {Cache | null} */
|
||||
// @ts-ignore - Cloudflare Workers cache API
|
||||
const cache =
|
||||
typeof caches !== 'undefined' && /** @type {any} */ (caches).default
|
||||
? /** @type {any} */ (caches).default
|
||||
typeof caches !== 'undefined' && /** @type {any} */ (caches).default // eslint-disable-line jsdoc/reject-any-type
|
||||
? /** @type {any} */ (caches).default // eslint-disable-line jsdoc/reject-any-type
|
||||
: null;
|
||||
|
||||
if (cache && !isGit && !isGitLFS && !isDocker && !isAI) {
|
||||
@@ -602,8 +601,9 @@ async function handleRequest(request, env, ctx) {
|
||||
|
||||
export default {
|
||||
/**
|
||||
* Main Worker entry point.
|
||||
* @param {Request} request
|
||||
* @param {Object} env
|
||||
* @param {object} env
|
||||
* @param {ExecutionContext} ctx
|
||||
*/
|
||||
fetch(request, env, ctx) {
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
* - AI provider path prefix (/ip/{provider}/...)
|
||||
* - Common AI API endpoints (chat, completions, embeddings, etc.)
|
||||
* - AI-specific URL patterns with JSON POST requests
|
||||
*
|
||||
* @param {Request} request - The incoming request object
|
||||
* @param {URL} url - Parsed URL object
|
||||
* @returns {boolean} True if this is an AI inference request
|
||||
@@ -74,7 +73,6 @@ export function isAIInferenceRequest(request, url) {
|
||||
* Configures headers for AI protocol requests.
|
||||
*
|
||||
* Sets Content-Type and User-Agent headers for AI inference requests.
|
||||
*
|
||||
* @param {Headers} headers - The headers object to modify
|
||||
* @param {Request} request - The original request
|
||||
*/
|
||||
|
||||
@@ -28,7 +28,6 @@ import { createErrorResponse } from '../utils/security.js';
|
||||
*
|
||||
* Extracts authentication realm and service information from the Bearer
|
||||
* authentication challenge header returned by container registries.
|
||||
*
|
||||
* @param {string} authenticateStr - The WWW-Authenticate header value
|
||||
* @returns {{realm: string, service: string}} Parsed authentication info with realm URL and service name
|
||||
* @throws {Error} If the header format is invalid or missing required fields
|
||||
@@ -53,7 +52,6 @@ export function parseAuthenticate(authenticateStr) {
|
||||
*
|
||||
* Requests a Bearer token from the registry's authentication service,
|
||||
* optionally including scope (repository permissions) and authorization credentials.
|
||||
*
|
||||
* @param {{realm: string, service: string}} wwwAuthenticate - Authentication info from WWW-Authenticate header
|
||||
* @param {string} scope - The scope for the token (e.g., "repository:library/nginx:pull")
|
||||
* @param {string} authorization - Authorization header value (optional, for authenticated access)
|
||||
@@ -79,7 +77,6 @@ export async function fetchToken(wwwAuthenticate, scope, authorization) {
|
||||
*
|
||||
* Generates a Docker/OCI registry-compliant 401 response with a WWW-Authenticate
|
||||
* header that directs clients to the token authentication endpoint.
|
||||
*
|
||||
* @param {URL} url - Request URL used to construct authentication realm
|
||||
* @returns {Response} Unauthorized response with WWW-Authenticate header
|
||||
*/
|
||||
@@ -96,7 +93,6 @@ export function responseUnauthorized(url) {
|
||||
* Handles the special /v2/auth endpoint for Docker authentication.
|
||||
*
|
||||
* Proxies generation of auth tokens by negotiating with the upstream registry.
|
||||
*
|
||||
* @param {Request} request - The incoming request
|
||||
* @param {URL} url - The parsed URL
|
||||
* @param {import('../config/index.js').ApplicationConfig} config - App configuration
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
* - Git User-Agent headers
|
||||
* - Git service query parameters
|
||||
* - Git-specific Content-Type headers
|
||||
*
|
||||
* @param {Request} request - The incoming request object
|
||||
* @param {URL} url - Parsed URL object
|
||||
* @returns {boolean} True if this is a Git operation
|
||||
@@ -72,7 +71,6 @@ export function isGitRequest(request, url) {
|
||||
* - LFS object storage paths (SHA-256 hash patterns)
|
||||
* - Git LFS Accept/Content-Type headers
|
||||
* - Git LFS User-Agent
|
||||
*
|
||||
* @param {Request} request - The incoming request object
|
||||
* @param {URL} url - Parsed URL object
|
||||
* @returns {boolean} True if this is a Git LFS operation
|
||||
@@ -116,7 +114,6 @@ export function isGitLFSRequest(request, url) {
|
||||
* Configures headers for Git protocol requests.
|
||||
*
|
||||
* Sets User-Agent and Content-Type headers required by Git and Git LFS protocols.
|
||||
*
|
||||
* @param {Headers} headers - The headers object to modify
|
||||
* @param {Request} request - The original request
|
||||
* @param {URL} url - The parsed URL
|
||||
|
||||
@@ -45,7 +45,6 @@ export class PerformanceMonitor {
|
||||
*
|
||||
* Records the elapsed time (in milliseconds) since the monitor was created.
|
||||
* If a mark with the same name already exists, logs a warning and overwrites it.
|
||||
*
|
||||
* @param {string} name - The name of the timing mark (e.g., 'cache_hit', 'attempt_0', 'success')
|
||||
*/
|
||||
mark(name) {
|
||||
@@ -60,8 +59,7 @@ export class PerformanceMonitor {
|
||||
*
|
||||
* Converts the internal Map of timing marks to a JavaScript object suitable for
|
||||
* JSON serialization and inclusion in response headers.
|
||||
*
|
||||
* @returns {Object.<string, number>} Object containing name-timestamp pairs in milliseconds
|
||||
* @returns {{ [key: string]: number }} Object containing name-timestamp pairs in milliseconds
|
||||
*/
|
||||
getMetrics() {
|
||||
return Object.fromEntries(this.marks.entries());
|
||||
@@ -76,7 +74,6 @@ export class PerformanceMonitor {
|
||||
* headers are included.
|
||||
*
|
||||
* **Note:** This header is only added to non-protocol responses (not Git/Docker/AI).
|
||||
*
|
||||
* @param {Response} response - The original response object
|
||||
* @param {PerformanceMonitor} monitor - Performance monitor instance with collected metrics
|
||||
* @returns {Response} New response with added performance and security headers
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
* - Referrer-Policy (referrer information control)
|
||||
* - Content-Security-Policy (resource loading restrictions)
|
||||
* - Permissions-Policy (privacy-invasive feature restrictions)
|
||||
*
|
||||
* @param {Headers} headers - Headers object to modify (mutates in place)
|
||||
* @returns {Headers} Modified headers object (same reference)
|
||||
*/
|
||||
@@ -49,7 +48,6 @@ export function addSecurityHeaders(headers) {
|
||||
*
|
||||
* Generates an HTTP error response with appropriate content type and security headers.
|
||||
* Can return either plain text or detailed JSON error format.
|
||||
*
|
||||
* @param {string} message - Error message to display
|
||||
* @param {number} status - HTTP status code (e.g., 400, 404, 500)
|
||||
* @param {boolean} includeDetails - Whether to include detailed JSON error information
|
||||
|
||||
@@ -33,7 +33,6 @@ import { isGitLFSRequest, isGitRequest } from '../protocols/git.js';
|
||||
* - Registry API endpoints (/v2/...)
|
||||
* - Docker-specific User-Agent headers
|
||||
* - Docker/OCI manifest Accept headers
|
||||
*
|
||||
* @param {Request} request - The incoming request object
|
||||
* @param {URL} url - Parsed URL object
|
||||
* @returns {boolean} True if this is a container registry operation
|
||||
@@ -85,7 +84,6 @@ export { isAIInferenceRequest, isGitLFSRequest, isGitRequest };
|
||||
* Different protocols have different allowed methods:
|
||||
* - Regular requests: GET, HEAD (configurable via SECURITY.ALLOWED_METHODS)
|
||||
* - Git/LFS/Docker/AI: GET, HEAD, POST, PUT, PATCH
|
||||
*
|
||||
* @param {Request} request - The incoming request object
|
||||
* @param {URL} url - Parsed URL object
|
||||
* @param {import('../config/index.js').ApplicationConfig} config - Configuration object
|
||||
|
||||
@@ -18,9 +18,9 @@ export class PerformanceTestHelper {
|
||||
|
||||
/**
|
||||
* Measure execution time of an async function
|
||||
* @param {Function} fn - Async function to measure
|
||||
* @param {() => Promise<unknown>} fn - Async function to measure
|
||||
* @param {string} name - Measurement name
|
||||
* @returns {Promise<any>} Function result
|
||||
* @returns {Promise<unknown>} Function result
|
||||
*/
|
||||
async measure(fn, name = 'operation') {
|
||||
const start = performance.now();
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/**
|
||||
* Create a mock request with default options
|
||||
* @param {string} url - Request URL
|
||||
* @param {Object} options - Request options
|
||||
* @param {object} options - Request options
|
||||
* @returns {Request} Mock request object
|
||||
*/
|
||||
export function createMockRequest(url, options = {}) {
|
||||
@@ -23,7 +23,7 @@ export function createMockRequest(url, options = {}) {
|
||||
/**
|
||||
* Create a mock response with default options
|
||||
* @param {string} body - Response body
|
||||
* @param {Object} options - Response options
|
||||
* @param {object} options - Response options
|
||||
* @returns {Response} Mock response object
|
||||
*/
|
||||
export function createMockResponse(body = 'OK', options = {}) {
|
||||
@@ -80,7 +80,7 @@ export function createDockerRequest(url, options = {}) {
|
||||
/**
|
||||
* Mock fetch function for testing
|
||||
* @param {string} url - Request URL
|
||||
* @param {Object} _options - Fetch options
|
||||
* @param {object} _options - Fetch options
|
||||
* @returns {Promise<Response>} Mock response
|
||||
*/
|
||||
export function mockFetch(url, _options = {}) {
|
||||
@@ -101,7 +101,7 @@ export function mockFetch(url, _options = {}) {
|
||||
* Create a mock npm registry response
|
||||
* @param {string} packageName - Package name
|
||||
* @param {string} version - Package version
|
||||
* @returns {Object} Mock npm registry response
|
||||
* @returns {object} Mock npm registry response
|
||||
*/
|
||||
export function createMockNpmRegistryResponse(packageName, version = '1.0.0') {
|
||||
return {
|
||||
|
||||
Reference in new issue
Block a user