Skip to content

Commit

Permalink
feat(basics): eslint, prettier, husky, commitlint, lint-staged, eslin…
Browse files Browse the repository at this point in the history
…t plugins, etc
  • Loading branch information
diegoulloao committed Sep 17, 2022
0 parents commit 694d952
Show file tree
Hide file tree
Showing 13 changed files with 388 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
root = true

[*]
indent_style = tab
indent_size = 2
end_of_line = lf
insert_final_newline = true
17 changes: 17 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"extends": [
"eslint:recommended",
"prettier",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended"
],
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"env": {
"node": true
},
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-non-null-assertion": "off"
}
}
212 changes: 212 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
# Created by https://www.toptal.com/developers/gitignore/api/macos,node,vercel,yarn,git
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,node,vercel,yarn,git

### Git ###
# Created by git for backups. To disable backups in Git:
# $ git config --global mergetool.keepBackup false
*.orig

# Created by git when using merge tools for conflicts
*.BACKUP.*
*.BASE.*
*.LOCAL.*
*.REMOTE.*
*_BACKUP_*.txt
*_BASE_*.txt
*_LOCAL_*.txt
*_REMOTE_*.txt

### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### macOS Patch ###
# iCloud generated files
*.icloud

### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

### Node Patch ###
# Serverless Webpack directories
.webpack/

# Optional stylelint cache

# SvelteKit build / generate output
.svelte-kit

### Vercel ###
.vercel

### yarn ###
# https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored

.yarn/*
!.yarn/releases
!.yarn/patches
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
yarn.lock

# if you are NOT using Zero-installs, then:
# comment the following lines
!.yarn/cache

# and uncomment the following lines
# .pnp.*

# End of https://www.toptal.com/developers/gitignore/api/macos,node,vercel,yarn,git
Expand Down
4 changes: 4 additions & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx --no -- commitlint --edit ""
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged
5 changes: 5 additions & 0 deletions .lintstagedrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"*.{ts,js}": [
"yarn lint:fix"
]
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# vercel-cors
3 changes: 3 additions & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
}
37 changes: 37 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "vercel-cors",
"version": "1.0.0",
"description": "Simple CORS module for vercel serverless functions",
"main": "src/main.js",
"scripts": {
"build": "tsc --build",
"lint": "eslint . --cache",
"lint:fix": "eslint . --cache --fix",
"prepare": "husky install"
},
"keywords": [
"cors",
"vercel",
"simple",
"serverless",
"functions"
],
"author": "diegoulloao",
"license": "MIT",
"devDependencies": {
"husky": "^8.0.1",
"typescript": "^4.8.3",
"@commitlint/cli": "^17.1.2",
"@commitlint/config-conventional": "^17.1.0",
"@typescript-eslint/eslint-plugin": "^5.37.0",
"@typescript-eslint/parser": "^5.37.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint": "^8.23.1",
"lint-staged": "^13.0.3",
"prettier": "^2.7.1"
},
"dependencies": {
"@vercel/node": "^2.5.14"
}
}
5 changes: 5 additions & 0 deletions prettier.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
singleQuote: true,
semi: false,
printWidth: 120,
}
67 changes: 67 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import type { VercelRequest, VercelResponse, VercelApiHandler } from '@vercel/node'
import type { CorsOptions } from 'types'

export const defaults: CorsOptions = {
origin: '*',
headers: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept'],
methods: ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'UPDATE', 'OPTIONS', 'DELETE'],
expose: [],
maxAge: undefined,
credentials: false,
}

export default (options: Partial<CorsOptions>) => {
options = { ...defaults, ...options }

return (handler: VercelApiHandler): VercelApiHandler => {
return function (req: VercelRequest, res: VercelResponse) {
if (typeof options.origin === 'boolean' && options.origin === false) {
return res.status(403).end('not allowed')
}

if (options.origin !== '*' && req.headers.origin === undefined) {
return res.status(403).end('unknown origin')
}

if (typeof options.origin === 'string') {
if (options.origin === '*' || options.origin === req.headers.origin) {
res.setHeader('Access-Control-Allow-Origin', options.origin)
}
} else if (options.origin instanceof RegExp) {
if (options.origin.test(req.headers.origin as string)) {
res.setHeader('Access-Control-Allow-Origin', req.headers.origin as string)
}
} else {
const allowedOrigin: boolean = (options.origin as Array<string | RegExp>).some((h: RegExp | string) =>
typeof h === 'string' ? h === req.headers.origin : h.test(req.headers.origin as string)
)

if (allowedOrigin) {
res.setHeader('Access-Control-Allow-Origin', req.headers.origin as string)
}
}

res.setHeader('Access-Control-Allow-Headers', options.headers!.join(', '))
res.setHeader('Access-Control-Allow-Credentials', options.credentials!.toString())
res.setHeader('Access-Control-Allow-Methods', options.methods!.join(', '))

if (options.expose!.length) {
res.setHeader('Access-Control-Expose-Methods', options.methods!.join(', '))
}

if (!isNaN(options.maxAge!)) {
res.setHeader('Access-Control-Max-Age', options.maxAge!)
}

if (options.origin === '*' || (Array.isArray(options.origin) && options.origin.length > 1)) {
res.setHeader('Vary', 'Origin')
}

if (req.method === 'OPTIONS') {
return res.status(200).json({ body: 'OK' })
}

return handler.apply(this, [req, res])
}
}
}
10 changes: 10 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
type HttpMethods = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'UPDATE' | 'DELETE' | 'OPTIONS'

export interface CorsOptions {
origin: string | RegExp | boolean | Array<string | RegExp>
headers: string[]
methods: HttpMethods[]
expose: string[]
maxAge: number | undefined
credentials: boolean
}
Loading

0 comments on commit 694d952

Please sign in to comment.