@elysiajs/cors
Advanced tools
Comparing version 1.1.0-exp.1 to 1.1.0-rc.0
@@ -6,9 +6,111 @@ import { Elysia } from 'elysia'; | ||
interface CORSConfig { | ||
/** | ||
* Disable AOT (Ahead of Time) compilation for plugin instance | ||
* | ||
* @default true | ||
*/ | ||
aot?: boolean; | ||
/** | ||
* @default `true` | ||
* | ||
* Assign the **Access-Control-Allow-Origin** header. | ||
* | ||
* Value can be one of the following: | ||
* - `string` - String of origin which will be directly assign to `Access-Control-Allow-Origin` | ||
* | ||
* - `boolean` - If set to true, `Access-Control-Allow-Origin` will be set to `*` (accept all origin) | ||
* | ||
* - `RegExp` - Pattern to use to test with request's url, will accept origin if matched. | ||
* | ||
* - `Function` - Custom logic to validate origin acceptance or not. will accept origin if `true` is returned. | ||
* - Function will accepts `Context` just like `Handler` | ||
* | ||
* ```typescript | ||
* // ? Example usage | ||
* app.use(cors, { | ||
* origin: ({ request, headers }) => true | ||
* }) | ||
* | ||
* // Type Definition | ||
* type CORSOriginFn = (context: Context) => boolean | void | ||
* ``` | ||
* | ||
* - `Array<string | RegExp | Function>` - Will try to find truthy value of all options above. Will accept request if one is `true`. | ||
*/ | ||
origin?: Origin | boolean | Origin[]; | ||
/** | ||
* @default `*` | ||
* | ||
* Assign **Access-Control-Allow-Methods** header. | ||
* | ||
* Value can be one of the following: | ||
* Accept: | ||
* - `undefined | null | ''` - Ignore all methods. | ||
* | ||
* - `*` - Accept all methods. | ||
* | ||
* - `HTTPMethod` - Will be directly set to **Access-Control-Allow-Methods**. | ||
* - Expects either a single method or a comma-delimited string (eg: 'GET, PUT, POST') | ||
* | ||
* - `HTTPMethod[]` - Allow multiple HTTP methods. | ||
* - eg: ['GET', 'PUT', 'POST'] | ||
*/ | ||
methods?: boolean | undefined | null | '' | '*' | MaybeArray<HTTPMethod | (string & {})>; | ||
/** | ||
* @default `*` | ||
* | ||
* Assign **Access-Control-Allow-Headers** header. | ||
* | ||
* Allow incoming request with the specified headers. | ||
* | ||
* Value can be one of the following: | ||
* - `string` | ||
* - Expects either a single method or a comma-delimited string (eg: 'Content-Type, Authorization'). | ||
* | ||
* - `string[]` - Allow multiple HTTP methods. | ||
* - eg: ['Content-Type', 'Authorization'] | ||
*/ | ||
allowedHeaders?: true | string | string[]; | ||
/** | ||
* @default `*` | ||
* | ||
* Assign **Access-Control-Expose-Headers** header. | ||
* | ||
* Return the specified headers to request in CORS mode. | ||
* | ||
* Value can be one of the following: | ||
* - `string` | ||
* - Expects either a single method or a comma-delimited string (eg: 'Content-Type, 'X-Powered-By'). | ||
* | ||
* - `string[]` - Allow multiple HTTP methods. | ||
* - eg: ['Content-Type', 'X-Powered-By'] | ||
*/ | ||
exposeHeaders?: true | string | string[]; | ||
/** | ||
* @default `true` | ||
* | ||
* Assign **Access-Control-Allow-Credentials** header. | ||
* | ||
* Allow incoming requests to send `credentials` header. | ||
* | ||
* - `boolean` - Available if set to `true`. | ||
*/ | ||
credentials?: boolean; | ||
/** | ||
* @default `5` | ||
* | ||
* Assign **Access-Control-Max-Age** header. | ||
* | ||
* Allow incoming requests to send `credentials` header. | ||
* | ||
* - `number` - Duration in seconds to indicates how long the results of a preflight request can be cached. | ||
*/ | ||
maxAge?: number; | ||
/** | ||
* @default `true` | ||
* | ||
* Add `[OPTIONS] /*` handler to handle preflight request which response with `HTTP 204` and CORS hints. | ||
* | ||
* - `boolean` - Available if set to `true`. | ||
*/ | ||
preflight?: boolean; | ||
@@ -27,2 +129,3 @@ } | ||
macro: {}; | ||
macroFn: {}; | ||
}, {}, { | ||
@@ -29,0 +132,0 @@ derive: {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.cors = void 0; | ||
const elysia_1 = require("elysia"); | ||
const isBun = typeof new Headers()?.toJSON === 'function'; | ||
const processHeaders = (headers) => { | ||
if (isBun) | ||
return Object.keys(headers.toJSON()).join(', '); | ||
let keys = ''; | ||
headers.forEach((_, key) => { | ||
keys += key + ', '; | ||
}); | ||
if (keys) | ||
keys = keys.slice(0, -1); | ||
return keys; | ||
var __defProp = Object.defineProperty; | ||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
var __getOwnPropNames = Object.getOwnPropertyNames; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
var __export = (target, all) => { | ||
for (var name in all) | ||
__defProp(target, name, { get: all[name], enumerable: true }); | ||
}; | ||
const processOrigin = (origin, request, from) => { | ||
if (Array.isArray(origin)) | ||
return origin.some((o) => processOrigin(o, request, from)); | ||
switch (typeof origin) { | ||
case 'string': | ||
if (origin.indexOf('://') === -1) | ||
return from.includes(origin); | ||
return origin === from; | ||
case 'function': | ||
return origin(request) === true; | ||
case 'object': | ||
if (origin instanceof RegExp) | ||
return origin.test(from); | ||
var __copyProps = (to, from, except, desc) => { | ||
if (from && typeof from === "object" || typeof from === "function") { | ||
for (let key of __getOwnPropNames(from)) | ||
if (!__hasOwnProp.call(to, key) && key !== except) | ||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
} | ||
return to; | ||
}; | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
// src/index.ts | ||
var src_exports = {}; | ||
__export(src_exports, { | ||
cors: () => cors, | ||
default: () => src_default | ||
}); | ||
module.exports = __toCommonJS(src_exports); | ||
var import_elysia = require("elysia"); | ||
var isBun = typeof new Headers()?.toJSON === "function"; | ||
var processHeaders = (headers) => { | ||
if (isBun) return Object.keys(headers.toJSON()).join(", "); | ||
let keys = ""; | ||
headers.forEach((_, key) => { | ||
keys += key + ", "; | ||
}); | ||
if (keys) keys = keys.slice(0, -1); | ||
return keys; | ||
}; | ||
var processOrigin = (origin, request, from) => { | ||
if (Array.isArray(origin)) | ||
return origin.some((o) => processOrigin(o, request, from)); | ||
switch (typeof origin) { | ||
case "string": | ||
if (origin.indexOf("://") === -1) return from.includes(origin); | ||
return origin === from; | ||
case "function": | ||
return origin(request) === true; | ||
case "object": | ||
if (origin instanceof RegExp) return origin.test(from); | ||
} | ||
return false; | ||
}; | ||
var cors = (config) => { | ||
let { | ||
aot = true, | ||
origin = true, | ||
methods = true, | ||
allowedHeaders = true, | ||
exposeHeaders = true, | ||
credentials = true, | ||
maxAge = 5, | ||
preflight = true | ||
} = config ?? {}; | ||
if (Array.isArray(allowedHeaders)) | ||
allowedHeaders = allowedHeaders.join(", "); | ||
if (Array.isArray(exposeHeaders)) exposeHeaders = exposeHeaders.join(", "); | ||
const origins = typeof origin === "boolean" ? void 0 : Array.isArray(origin) ? origin : [origin]; | ||
const app = new import_elysia.Elysia({ | ||
name: "@elysiajs/cors", | ||
seed: config, | ||
aot | ||
}); | ||
const anyOrigin = origins?.some((o) => o === "*"); | ||
const handleOrigin = (set, request) => { | ||
if (origin === true) { | ||
set.headers.vary = "*"; | ||
set.headers["access-control-allow-origin"] = request.headers.get("Origin") || "*"; | ||
return; | ||
} | ||
return false; | ||
}; | ||
const cors = (config) => { | ||
let { aot = true, origin = true, methods = true, allowedHeaders = true, exposeHeaders = true, credentials = true, maxAge = 5, preflight = true } = config ?? {}; | ||
if (Array.isArray(allowedHeaders)) | ||
allowedHeaders = allowedHeaders.join(', '); | ||
if (Array.isArray(exposeHeaders)) | ||
exposeHeaders = exposeHeaders.join(', '); | ||
const origins = typeof origin === 'boolean' | ||
? undefined | ||
: Array.isArray(origin) | ||
? origin | ||
: [origin]; | ||
const app = new elysia_1.Elysia({ | ||
name: '@elysiajs/cors', | ||
seed: config, | ||
aot | ||
}); | ||
const anyOrigin = origins?.some((o) => o === '*'); | ||
const handleOrigin = (set, request) => { | ||
if (origin === true) { | ||
set.headers.vary = '*'; | ||
set.headers['access-control-allow-origin'] = | ||
request.headers.get('Origin') || '*'; | ||
return; | ||
if (anyOrigin) { | ||
set.headers.vary = "*"; | ||
set.headers["access-control-allow-origin"] = "*"; | ||
return; | ||
} | ||
if (!origins?.length) return; | ||
const headers = []; | ||
if (origins.length) { | ||
const from = request.headers.get("Origin") ?? ""; | ||
for (let i = 0; i < origins.length; i++) { | ||
const value = processOrigin(origins[i], request, from); | ||
if (value === true) { | ||
set.headers.vary = origin ? "Origin" : "*"; | ||
set.headers["access-control-allow-origin"] = from || "*"; | ||
return; | ||
} | ||
if (anyOrigin) { | ||
set.headers.vary = '*'; | ||
set.headers['access-control-allow-origin'] = '*'; | ||
return; | ||
} | ||
if (!origins?.length) | ||
return; | ||
const headers = []; | ||
if (origins.length) { | ||
const from = request.headers.get('Origin') ?? ''; | ||
for (let i = 0; i < origins.length; i++) { | ||
const value = processOrigin(origins[i], request, from); | ||
if (value === true) { | ||
set.headers.vary = origin ? 'Origin' : '*'; | ||
set.headers['access-control-allow-origin'] = from || '*'; | ||
return; | ||
} | ||
if (value) | ||
headers.push(value); | ||
} | ||
} | ||
set.headers.vary = 'Origin'; | ||
if (headers.length) | ||
set.headers['access-control-allow-origin'] = headers.join(', '); | ||
}; | ||
const handleMethod = (set, method) => { | ||
if (!method) | ||
return; | ||
if (methods === true) | ||
return (set.headers['access-control-allow-methods'] = method ?? '*'); | ||
if (methods === false || !methods?.length) | ||
return; | ||
if (methods === '*') | ||
return (set.headers['access-control-allow-methods'] = '*'); | ||
if (!Array.isArray(methods)) | ||
return (set.headers['access-control-allow-methods'] = methods); | ||
set.headers['access-control-allow-methods'] = methods.join(', '); | ||
}; | ||
const defaultHeaders = {}; | ||
if (typeof exposeHeaders === 'string') | ||
defaultHeaders['access-control-expose-headers'] = exposeHeaders; | ||
if (typeof allowedHeaders === 'string') | ||
defaultHeaders['access-control-allow-headers'] = allowedHeaders; | ||
if (credentials === true) | ||
defaultHeaders['access-control-allow-credentials'] = 'true'; | ||
app.headers(defaultHeaders); | ||
function handleOption({ set, request }) { | ||
handleOrigin(set, request); | ||
handleMethod(set, request.headers.get('access-control-request-method')); | ||
if (allowedHeaders === true || exposeHeaders === true) { | ||
const headers = processHeaders(request.headers); | ||
if (allowedHeaders === true) | ||
set.headers['access-control-allow-headers'] = headers; | ||
if (exposeHeaders === true) | ||
set.headers['access-control-expose-headers'] = headers; | ||
} | ||
if (maxAge) | ||
set.headers['access-control-max-age'] = maxAge.toString(); | ||
return new Response(null, { | ||
status: 204 | ||
}); | ||
if (value) headers.push(value); | ||
} | ||
} | ||
if (preflight) | ||
app.options('/', handleOption).options('/*', handleOption); | ||
return app.onRequest(function processCors({ set, request }) { | ||
handleOrigin(set, request); | ||
handleMethod(set, request.method); | ||
if (allowedHeaders === true || exposeHeaders === true) { | ||
const headers = processHeaders(request.headers); | ||
if (allowedHeaders === true) | ||
set.headers['access-control-allow-headers'] = headers; | ||
if (exposeHeaders === true) | ||
set.headers['access-control-expose-headers'] = headers; | ||
} | ||
set.headers.vary = "Origin"; | ||
if (headers.length) | ||
set.headers["access-control-allow-origin"] = headers.join(", "); | ||
}; | ||
const handleMethod = (set, method) => { | ||
if (!method) return; | ||
if (methods === true) | ||
return set.headers["access-control-allow-methods"] = method ?? "*"; | ||
if (methods === false || !methods?.length) return; | ||
if (methods === "*") | ||
return set.headers["access-control-allow-methods"] = "*"; | ||
if (!Array.isArray(methods)) | ||
return set.headers["access-control-allow-methods"] = methods; | ||
set.headers["access-control-allow-methods"] = methods.join(", "); | ||
}; | ||
const defaultHeaders = {}; | ||
if (typeof exposeHeaders === "string") | ||
defaultHeaders["access-control-expose-headers"] = exposeHeaders; | ||
if (typeof allowedHeaders === "string") | ||
defaultHeaders["access-control-allow-headers"] = allowedHeaders; | ||
if (credentials === true) | ||
defaultHeaders["access-control-allow-credentials"] = "true"; | ||
app.headers(defaultHeaders); | ||
function handleOption({ set, request }) { | ||
handleOrigin(set, request); | ||
handleMethod(set, request.headers.get("access-control-request-method")); | ||
if (allowedHeaders === true || exposeHeaders === true) { | ||
const headers = processHeaders(request.headers); | ||
if (allowedHeaders === true) | ||
set.headers["access-control-allow-headers"] = headers; | ||
if (exposeHeaders === true) | ||
set.headers["access-control-expose-headers"] = headers; | ||
} | ||
if (maxAge) set.headers["access-control-max-age"] = maxAge.toString(); | ||
return new Response(null, { | ||
status: 200 | ||
}); | ||
} | ||
if (preflight) app.options("/", handleOption).options("/*", handleOption); | ||
return app.onRequest(function processCors({ set, request }) { | ||
handleOrigin(set, request); | ||
handleMethod(set, request.method); | ||
if (allowedHeaders === true || exposeHeaders === true) { | ||
const headers = processHeaders(request.headers); | ||
if (allowedHeaders === true) | ||
set.headers["access-control-allow-headers"] = headers; | ||
if (exposeHeaders === true) | ||
set.headers["access-control-expose-headers"] = headers; | ||
} | ||
}); | ||
}; | ||
exports.cors = cors; | ||
exports.default = exports.cors; | ||
var src_default = cors; | ||
// Annotate the CommonJS export names for ESM import in node: | ||
0 && (module.exports = { | ||
cors | ||
}); |
@@ -6,9 +6,111 @@ import { Elysia } from 'elysia'; | ||
interface CORSConfig { | ||
/** | ||
* Disable AOT (Ahead of Time) compilation for plugin instance | ||
* | ||
* @default true | ||
*/ | ||
aot?: boolean; | ||
/** | ||
* @default `true` | ||
* | ||
* Assign the **Access-Control-Allow-Origin** header. | ||
* | ||
* Value can be one of the following: | ||
* - `string` - String of origin which will be directly assign to `Access-Control-Allow-Origin` | ||
* | ||
* - `boolean` - If set to true, `Access-Control-Allow-Origin` will be set to `*` (accept all origin) | ||
* | ||
* - `RegExp` - Pattern to use to test with request's url, will accept origin if matched. | ||
* | ||
* - `Function` - Custom logic to validate origin acceptance or not. will accept origin if `true` is returned. | ||
* - Function will accepts `Context` just like `Handler` | ||
* | ||
* ```typescript | ||
* // ? Example usage | ||
* app.use(cors, { | ||
* origin: ({ request, headers }) => true | ||
* }) | ||
* | ||
* // Type Definition | ||
* type CORSOriginFn = (context: Context) => boolean | void | ||
* ``` | ||
* | ||
* - `Array<string | RegExp | Function>` - Will try to find truthy value of all options above. Will accept request if one is `true`. | ||
*/ | ||
origin?: Origin | boolean | Origin[]; | ||
/** | ||
* @default `*` | ||
* | ||
* Assign **Access-Control-Allow-Methods** header. | ||
* | ||
* Value can be one of the following: | ||
* Accept: | ||
* - `undefined | null | ''` - Ignore all methods. | ||
* | ||
* - `*` - Accept all methods. | ||
* | ||
* - `HTTPMethod` - Will be directly set to **Access-Control-Allow-Methods**. | ||
* - Expects either a single method or a comma-delimited string (eg: 'GET, PUT, POST') | ||
* | ||
* - `HTTPMethod[]` - Allow multiple HTTP methods. | ||
* - eg: ['GET', 'PUT', 'POST'] | ||
*/ | ||
methods?: boolean | undefined | null | '' | '*' | MaybeArray<HTTPMethod | (string & {})>; | ||
/** | ||
* @default `*` | ||
* | ||
* Assign **Access-Control-Allow-Headers** header. | ||
* | ||
* Allow incoming request with the specified headers. | ||
* | ||
* Value can be one of the following: | ||
* - `string` | ||
* - Expects either a single method or a comma-delimited string (eg: 'Content-Type, Authorization'). | ||
* | ||
* - `string[]` - Allow multiple HTTP methods. | ||
* - eg: ['Content-Type', 'Authorization'] | ||
*/ | ||
allowedHeaders?: true | string | string[]; | ||
/** | ||
* @default `*` | ||
* | ||
* Assign **Access-Control-Expose-Headers** header. | ||
* | ||
* Return the specified headers to request in CORS mode. | ||
* | ||
* Value can be one of the following: | ||
* - `string` | ||
* - Expects either a single method or a comma-delimited string (eg: 'Content-Type, 'X-Powered-By'). | ||
* | ||
* - `string[]` - Allow multiple HTTP methods. | ||
* - eg: ['Content-Type', 'X-Powered-By'] | ||
*/ | ||
exposeHeaders?: true | string | string[]; | ||
/** | ||
* @default `true` | ||
* | ||
* Assign **Access-Control-Allow-Credentials** header. | ||
* | ||
* Allow incoming requests to send `credentials` header. | ||
* | ||
* - `boolean` - Available if set to `true`. | ||
*/ | ||
credentials?: boolean; | ||
/** | ||
* @default `5` | ||
* | ||
* Assign **Access-Control-Max-Age** header. | ||
* | ||
* Allow incoming requests to send `credentials` header. | ||
* | ||
* - `number` - Duration in seconds to indicates how long the results of a preflight request can be cached. | ||
*/ | ||
maxAge?: number; | ||
/** | ||
* @default `true` | ||
* | ||
* Add `[OPTIONS] /*` handler to handle preflight request which response with `HTTP 204` and CORS hints. | ||
* | ||
* - `boolean` - Available if set to `true`. | ||
*/ | ||
preflight?: boolean; | ||
@@ -27,2 +129,3 @@ } | ||
macro: {}; | ||
macroFn: {}; | ||
}, {}, { | ||
@@ -29,0 +132,0 @@ derive: {}; |
{ | ||
"name": "@elysiajs/cors", | ||
"version": "1.1.0-exp.1", | ||
"description": "Plugin for Elysia that for Cross Origin Requests (CORs)", | ||
"author": { | ||
"name": "saltyAom", | ||
"url": "https://github.com/SaltyAom", | ||
"email": "saltyaom@gmail.com" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/elysiajs/elysia-cors" | ||
}, | ||
"main": "./dist/cjs/index.js", | ||
"module": "./dist/index.js", | ||
"types": "./dist/index.d.ts", | ||
"exports": { | ||
"bun": "./dist/index.js", | ||
"node": "./dist/cjs/index.js", | ||
"require": "./dist/cjs/index.js", | ||
"import": "./dist/index.js", | ||
"default": "./dist/cjs/index.js", | ||
"types": "./dist/index.d.ts" | ||
}, | ||
"homepage": "https://github.com/elysiajs/elysia-cors", | ||
"keywords": [ | ||
"elysia", | ||
"cors" | ||
], | ||
"license": "MIT", | ||
"scripts": { | ||
"dev": "bun run --watch example/index.ts", | ||
"test": "bun test && npm run test:node", | ||
"test:node": "npm install --prefix ./test/node/cjs/ && npm install --prefix ./test/node/esm/ && node ./test/node/cjs/index.js && node ./test/node/esm/index.js", | ||
"build": "rimraf dist && tsc --project tsconfig.esm.json && tsc --project tsconfig.cjs.json", | ||
"release": "npm run build && npm run test && npm publish --access public" | ||
}, | ||
"devDependencies": { | ||
"@types/bun": "^1.0.4", | ||
"@types/node": "^18.11.7", | ||
"elysia": "1.1.0-exp.26", | ||
"eslint": "^8.26.0", | ||
"rimraf": "^3.0.2", | ||
"typescript": "^5.4.3" | ||
}, | ||
"peerDependencies": { | ||
"elysia": ">= 1.1.0-exp.26" | ||
} | ||
} | ||
"name": "@elysiajs/cors", | ||
"version": "1.1.0-rc.0", | ||
"description": "Plugin for Elysia that for Cross Origin Requests (CORs)", | ||
"author": { | ||
"name": "saltyAom", | ||
"url": "https://github.com/SaltyAom", | ||
"email": "saltyaom@gmail.com" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/elysiajs/elysia-cors" | ||
}, | ||
"main": "./dist/cjs/index.js", | ||
"module": "./dist/index.mjs", | ||
"types": "./dist/index.d.ts", | ||
"exports": { | ||
"./package.json": "./package.json", | ||
".": { | ||
"types": "./dist/index.d.ts", | ||
"import": "./dist/index.mjs", | ||
"require": "./dist/cjs/index.js" | ||
} | ||
}, | ||
"homepage": "https://github.com/elysiajs/elysia-cors", | ||
"keywords": [ | ||
"elysia", | ||
"cors" | ||
], | ||
"license": "MIT", | ||
"scripts": { | ||
"dev": "bun run --watch example/index.ts", | ||
"test": "bun test && npm run test:node", | ||
"test:node": "npm install --prefix ./test/node/cjs/ && npm install --prefix ./test/node/esm/ && node ./test/node/cjs/index.js && node ./test/node/esm/index.js", | ||
"build": "bun build.ts", | ||
"release": "npm run build && npm run test && npm publish --access public" | ||
}, | ||
"devDependencies": { | ||
"@types/bun": "1.1.6", | ||
"elysia": ">= 1.1.0-rc.2", | ||
"eslint": "9.6.0", | ||
"tsup": "^8.1.0", | ||
"typescript": "^5.5.3" | ||
}, | ||
"peerDependencies": { | ||
"elysia": ">= 1.1.0-rc.2" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
24607
5
558