@elysiajs/cors
Advanced tools
Comparing version 0.7.0 to 0.7.1
/// <reference types="bun-types" /> | ||
import type { Elysia } from 'elysia'; | ||
import { Elysia } from 'elysia'; | ||
type Origin = string | RegExp | ((request: Request) => boolean | void); | ||
@@ -14,3 +14,3 @@ export type HTTPMethod = 'ACL' | 'BIND' | 'CHECKOUT' | 'CONNECT' | 'COPY' | 'DELETE' | 'GET' | 'HEAD' | 'LINK' | 'LOCK' | 'M-SEARCH' | 'MERGE' | 'MKACTIVITY' | 'MKCALENDAR' | 'MKCOL' | 'MOVE' | 'NOTIFY' | 'OPTIONS' | 'PATCH' | 'POST' | 'PROPFIND' | 'PROPPATCH' | 'PURGE' | 'PUT' | 'REBIND' | 'REPORT' | 'SEARCH' | 'SOURCE' | 'SUBSCRIBE' | 'TRACE' | 'UNBIND' | 'UNLINK' | 'UNLOCK' | 'UNSUBSCRIBE'; | ||
} | ||
export declare const cors: ({ origin, methods, allowedHeaders, exposedHeaders, credentials, maxAge, preflight }?: CORSConfig) => (app: Elysia) => Elysia<"", { | ||
export declare const cors: (config?: CORSConfig) => Elysia<"", { | ||
request: {}; | ||
@@ -17,0 +17,0 @@ store: {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.cors = void 0; | ||
const cors = ({ origin = true, methods = '*', allowedHeaders = '*', exposedHeaders = '*', credentials = false, maxAge = 5, preflight = true } = { | ||
const elysia_1 = require("elysia"); | ||
const cors = (config = { | ||
origin: true, | ||
@@ -12,3 +13,8 @@ methods: '*', | ||
preflight: true | ||
}) => (app) => { | ||
}) => { | ||
const { origin = true, methods = '*', allowedHeaders = '*', exposedHeaders = '*', credentials = false, maxAge = 5, preflight = true } = config; | ||
const app = new elysia_1.Elysia({ | ||
name: '@elysiajs/cors', | ||
seed: config | ||
}); | ||
const origins = typeof origin === 'boolean' | ||
@@ -22,8 +28,10 @@ ? undefined | ||
case 'string': | ||
return origin; | ||
const protocolStart = from.indexOf('://'); | ||
if (protocolStart === -1) | ||
return false; | ||
return origin === from.slice(protocolStart + 3); | ||
case 'function': | ||
return origin(request); | ||
case 'object': | ||
if (origin.test(from)) | ||
return true; | ||
return origin.test(from); | ||
} | ||
@@ -30,0 +38,0 @@ }; |
/// <reference types="bun-types" /> | ||
import type { Elysia } from 'elysia'; | ||
import { Elysia } from 'elysia'; | ||
type Origin = string | RegExp | ((request: Request) => boolean | void); | ||
@@ -14,3 +14,3 @@ export type HTTPMethod = 'ACL' | 'BIND' | 'CHECKOUT' | 'CONNECT' | 'COPY' | 'DELETE' | 'GET' | 'HEAD' | 'LINK' | 'LOCK' | 'M-SEARCH' | 'MERGE' | 'MKACTIVITY' | 'MKCALENDAR' | 'MKCOL' | 'MOVE' | 'NOTIFY' | 'OPTIONS' | 'PATCH' | 'POST' | 'PROPFIND' | 'PROPPATCH' | 'PURGE' | 'PUT' | 'REBIND' | 'REPORT' | 'SEARCH' | 'SOURCE' | 'SUBSCRIBE' | 'TRACE' | 'UNBIND' | 'UNLINK' | 'UNLOCK' | 'UNSUBSCRIBE'; | ||
} | ||
export declare const cors: ({ origin, methods, allowedHeaders, exposedHeaders, credentials, maxAge, preflight }?: CORSConfig) => (app: Elysia) => Elysia<"", { | ||
export declare const cors: (config?: CORSConfig) => Elysia<"", { | ||
request: {}; | ||
@@ -17,0 +17,0 @@ store: {}; |
@@ -1,2 +0,3 @@ | ||
export const cors = ({ origin = true, methods = '*', allowedHeaders = '*', exposedHeaders = '*', credentials = false, maxAge = 5, preflight = true } = { | ||
import { Elysia } from 'elysia'; | ||
export const cors = (config = { | ||
origin: true, | ||
@@ -9,3 +10,8 @@ methods: '*', | ||
preflight: true | ||
}) => (app) => { | ||
}) => { | ||
const { origin = true, methods = '*', allowedHeaders = '*', exposedHeaders = '*', credentials = false, maxAge = 5, preflight = true } = config; | ||
const app = new Elysia({ | ||
name: '@elysiajs/cors', | ||
seed: config | ||
}); | ||
const origins = typeof origin === 'boolean' | ||
@@ -19,8 +25,10 @@ ? undefined | ||
case 'string': | ||
return origin; | ||
const protocolStart = from.indexOf('://'); | ||
if (protocolStart === -1) | ||
return false; | ||
return origin === from.slice(protocolStart + 3); | ||
case 'function': | ||
return origin(request); | ||
case 'object': | ||
if (origin.test(from)) | ||
return true; | ||
return origin.test(from); | ||
} | ||
@@ -27,0 +35,0 @@ }; |
{ | ||
"name": "@elysiajs/cors", | ||
"version": "0.7.0", | ||
"version": "0.7.1", | ||
"description": "Plugin for Elysia that for Cross Origin Requests (CORs)", | ||
@@ -29,3 +29,3 @@ "author": { | ||
"scripts": { | ||
"dev": "bun run --hot example/index.ts", | ||
"dev": "bun run --watch example/index.ts", | ||
"test": "bun test && npm run test:node", | ||
@@ -38,7 +38,7 @@ "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", | ||
"@types/node": "^18.11.7", | ||
"bun-types": "^0.5.7", | ||
"elysia": "0.7.0", | ||
"bun-types": "^1.0.2", | ||
"elysia": "^0.7.15", | ||
"eslint": "^8.26.0", | ||
"rimraf": "^3.0.2", | ||
"typescript": "^5.0.4" | ||
"typescript": "^5.2.2" | ||
}, | ||
@@ -48,2 +48,2 @@ "peerDependencies": { | ||
} | ||
} | ||
} |
236
src/index.ts
@@ -1,2 +0,2 @@ | ||
import type { Elysia, Handler, Context } from 'elysia' | ||
import { Elysia, Handler, Context } from 'elysia' | ||
@@ -150,133 +150,121 @@ import { isAbsolute } from 'path' | ||
export const cors = | ||
( | ||
{ | ||
origin = true, | ||
methods = '*', | ||
allowedHeaders = '*', | ||
exposedHeaders = '*', | ||
credentials = false, | ||
maxAge = 5, | ||
preflight = true | ||
}: CORSConfig = { | ||
origin: true, | ||
methods: '*', | ||
allowedHeaders: '*', | ||
exposedHeaders: '*', | ||
credentials: false, | ||
maxAge: 5, | ||
preflight: true | ||
} | ||
) => | ||
(app: Elysia) => { | ||
const origins = | ||
typeof origin === 'boolean' | ||
? undefined | ||
: Array.isArray(origin) | ||
? origin | ||
: [origin] | ||
export const cors = ( | ||
config: CORSConfig = { | ||
origin: true, | ||
methods: '*', | ||
allowedHeaders: '*', | ||
exposedHeaders: '*', | ||
credentials: false, | ||
maxAge: 5, | ||
preflight: true | ||
} | ||
) => { | ||
const { | ||
origin = true, | ||
methods = '*', | ||
allowedHeaders = '*', | ||
exposedHeaders = '*', | ||
credentials = false, | ||
maxAge = 5, | ||
preflight = true | ||
} = config | ||
const processOrigin = ( | ||
origin: Origin, | ||
request: Request, | ||
from: string | ||
) => { | ||
switch (typeof origin) { | ||
case 'string': | ||
return origin | ||
const app = new Elysia({ | ||
name: '@elysiajs/cors', | ||
seed: config | ||
}) | ||
case 'function': | ||
return origin(request) | ||
const origins = | ||
typeof origin === 'boolean' | ||
? undefined | ||
: Array.isArray(origin) | ||
? origin | ||
: [origin] | ||
case 'object': | ||
if (origin.test(from)) return true | ||
} | ||
const processOrigin = (origin: Origin, request: Request, from: string) => { | ||
switch (typeof origin) { | ||
case 'string': | ||
const protocolStart = from.indexOf('://') | ||
// Malform URL, invalid protocol | ||
if (protocolStart === -1) return false | ||
return origin === from.slice(protocolStart + 3) | ||
case 'function': | ||
return origin(request) | ||
case 'object': | ||
return origin.test(from) | ||
} | ||
} | ||
const handleOrigin = (set: Context['set'], request: Request) => { | ||
// origin === `true` means any origin | ||
if (origin === true) { | ||
set.headers['Vary'] = '*' | ||
set.headers['Access-Control-Allow-Origin'] = '*' | ||
const handleOrigin = (set: Context['set'], request: Request) => { | ||
// origin === `true` means any origin | ||
if (origin === true) { | ||
set.headers['Vary'] = '*' | ||
set.headers['Access-Control-Allow-Origin'] = '*' | ||
return | ||
} | ||
return | ||
} | ||
if (!origins?.length) return | ||
if (!origins?.length) return | ||
const headers: string[] = [] | ||
const headers: string[] = [] | ||
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'] = | ||
request.headers.get('Origin') ?? '*' | ||
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'] = | ||
request.headers.get('Origin') ?? '*' | ||
return | ||
} | ||
return | ||
} | ||
// value can be string (truthy value) but not `true` | ||
if (value) headers.push(value) | ||
} | ||
// value can be string (truthy value) but not `true` | ||
if (value) headers.push(value) | ||
} | ||
set.headers['Vary'] = 'Origin' | ||
set.headers['Access-Control-Allow-Origin'] = headers.join(', ') | ||
} | ||
const handleMethod = (set: Context['set']) => { | ||
if (!methods?.length) return | ||
set.headers['Vary'] = 'Origin' | ||
set.headers['Access-Control-Allow-Origin'] = headers.join(', ') | ||
} | ||
if (methods === '*') | ||
return (set.headers['Access-Control-Allow-Methods'] = '*') | ||
const handleMethod = (set: Context['set']) => { | ||
if (!methods?.length) return | ||
if (!Array.isArray(methods)) | ||
return (set.headers['Access-Control-Allow-Methods'] = methods) | ||
if (methods === '*') | ||
return (set.headers['Access-Control-Allow-Methods'] = '*') | ||
set.headers['Access-Control-Allow-Methods'] = methods.join(', ') | ||
} | ||
if (!Array.isArray(methods)) | ||
return (set.headers['Access-Control-Allow-Methods'] = methods) | ||
if (preflight) | ||
app.options('/', ({ set, request }) => { | ||
handleOrigin(set as any, request) | ||
handleMethod(set) | ||
set.headers['Access-Control-Allow-Methods'] = methods.join(', ') | ||
} | ||
if (exposedHeaders.length) | ||
set.headers['Access-Control-Allow-Headers'] = | ||
typeof allowedHeaders === 'string' | ||
? allowedHeaders | ||
: allowedHeaders.join(', ') | ||
if (preflight) | ||
app.options('/', ({ set, request }) => { | ||
handleOrigin(set as any, request) | ||
handleMethod(set) | ||
if (maxAge) | ||
set.headers['Access-Control-Max-Age'] = maxAge.toString() | ||
if (exposedHeaders.length) | ||
set.headers['Access-Control-Allow-Headers'] = | ||
typeof allowedHeaders === 'string' | ||
? allowedHeaders | ||
: allowedHeaders.join(', ') | ||
return new Response('', { | ||
status: 204 | ||
}) | ||
}).options('/*', ({ set, request }) => { | ||
handleOrigin(set as any, request) | ||
handleMethod(set) | ||
if (maxAge) | ||
set.headers['Access-Control-Max-Age'] = maxAge.toString() | ||
if (exposedHeaders.length) | ||
set.headers['Access-Control-Allow-Headers'] = | ||
typeof allowedHeaders === 'string' | ||
? allowedHeaders | ||
: allowedHeaders.join(', ') | ||
if (maxAge) | ||
set.headers['Access-Control-Max-Age'] = maxAge.toString() | ||
return new Response('', { | ||
status: 204 | ||
}) | ||
return new Response('', { | ||
status: 204 | ||
}) | ||
return app.onRequest(({ set, request }) => { | ||
handleOrigin(set, request) | ||
}).options('/*', ({ set, request }) => { | ||
handleOrigin(set as any, request) | ||
handleMethod(set) | ||
if (allowedHeaders.length) | ||
if (exposedHeaders.length) | ||
set.headers['Access-Control-Allow-Headers'] = | ||
@@ -287,13 +275,31 @@ typeof allowedHeaders === 'string' | ||
if (exposedHeaders.length) | ||
set.headers['Access-Control-Exposed-Headers'] = | ||
typeof exposedHeaders === 'string' | ||
? exposedHeaders | ||
: exposedHeaders.join(', ') | ||
if (maxAge) | ||
set.headers['Access-Control-Max-Age'] = maxAge.toString() | ||
if (credentials) | ||
set.headers['Access-Control-Allow-Credentials'] = 'true' | ||
return new Response('', { | ||
status: 204 | ||
}) | ||
}) | ||
} | ||
return app.onRequest(({ set, request }) => { | ||
handleOrigin(set, request) | ||
handleMethod(set) | ||
if (allowedHeaders.length) | ||
set.headers['Access-Control-Allow-Headers'] = | ||
typeof allowedHeaders === 'string' | ||
? allowedHeaders | ||
: allowedHeaders.join(', ') | ||
if (exposedHeaders.length) | ||
set.headers['Access-Control-Exposed-Headers'] = | ||
typeof exposedHeaders === 'string' | ||
? exposedHeaders | ||
: exposedHeaders.join(', ') | ||
if (credentials) | ||
set.headers['Access-Control-Allow-Credentials'] = 'true' | ||
}) | ||
} | ||
export default cors |
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
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
25776
10
543