-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit a1d56b7
Showing
15 changed files
with
4,389 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
version: 2 | ||
jobs: | ||
build: | ||
docker: | ||
- image: node | ||
steps: | ||
- checkout | ||
- run: | ||
name: Install dependencies | ||
command: | | ||
yarn | ||
- run: | ||
name: Run Prettier | ||
command: | | ||
yarn prettier:check | ||
- run: | ||
name: Build | ||
command: | | ||
yarn tsc --noEmit | ||
- run: | ||
name: Run tests | ||
command: | | ||
yarn test | ||
workflows: | ||
version: 2 | ||
build: | ||
jobs: | ||
- build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
### https://raw.github.com/github/gitignore/72190ee30bd1e2ccc233222341435adacb7a6500/Node.gitignore | ||
|
||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# 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 | ||
|
||
# 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/ | ||
|
||
# TypeScript v1 declaration files | ||
typings/ | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional eslint cache | ||
.eslintcache | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Output of 'npm pack' | ||
*.tgz | ||
|
||
# Yarn Integrity file | ||
.yarn-integrity | ||
|
||
# dotenv environment variables file | ||
.env | ||
|
||
# parcel-bundler cache (https://parceljs.org/) | ||
.cache | ||
|
||
# next.js build output | ||
.next | ||
|
||
# nuxt.js build output | ||
.nuxt | ||
|
||
# vuepress build output | ||
.vuepress/dist | ||
|
||
# Serverless directories | ||
.serverless | ||
|
||
/src/**/*.js | ||
|
||
lib/* | ||
!.keep |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.keep |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
parser: typescript | ||
printWidth: 120 | ||
singleQuote: true | ||
tabWidth: 4 | ||
trailingComma: all |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# koa-path-canonicalizer | ||
|
||
[![npm version](https://img.shields.io/npm/v/koa-path-canonicalizer.svg?style=flat-square)](https://www.npmjs.com/package/koa-path-canonicalizer) | ||
[![CircleCI](https://circleci.com/gh/herp-inc/koa-path-canonicalizer.svg?style=shield)](https://circleci.com/gh/herp-inc/koa-path-canonicalizer) | ||
|
||
A Koa middleware to redirect to canonicalized path | ||
|
||
## Installation | ||
|
||
```console | ||
$ yarn add koa-path-canonicalizer | ||
``` | ||
|
||
## Usage | ||
|
||
```javascript | ||
const Koa = require('koa'); | ||
const { pathCanonicalizer } = require('koa-path-canonicalizer'); | ||
|
||
const app = new Koa(); | ||
|
||
app.use(pathCanonicalizer()); | ||
``` | ||
|
||
## License | ||
|
||
The MIT License (MIT) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/bin/sh -eu | ||
|
||
yarn install | ||
rm -rf ./lib/* | ||
yarn tsc -d --outDir ./lib | ||
cp .npmignore package.json README.md ./lib |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module.exports = { | ||
moduleFileExtensions: ['js', 'json', 'jsx', 'node', 'ts', 'tsx'], | ||
testRegex: '(\\.|/)(test|spec)\\.tsx?$', | ||
transform: { | ||
'^.+\\.tsx?$': 'ts-jest', | ||
}, | ||
}; |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"name": "koa-path-canonicalizer", | ||
"version": "0.1.0", | ||
"description": "A Koa middleware to redirect to canonicalized path", | ||
"main": "index.js", | ||
"repository": "https://github.com/herp-inc/koa-path-canonicalizer.git", | ||
"author": "Ryota Kameoka <ryota.kameoka@herp.co.jp>", | ||
"license": "MIT", | ||
"typings": "index.d.ts", | ||
"devDependencies": { | ||
"@types/jest": "^23.3.4", | ||
"@types/koa": "^2.0.46", | ||
"@types/node": "^10.11.5", | ||
"@types/supertest": "^2.0.6", | ||
"jest": "^23.6.0", | ||
"koa": "^2.5.3", | ||
"prettier": "^1.14.3", | ||
"supertest": "^3.3.0", | ||
"ts-jest": "^23.10.4", | ||
"typescript": "^3.1.1" | ||
}, | ||
"scripts": { | ||
"prerelease": "./bin/prerelease.sh", | ||
"prettier:check": "prettier --list-different src/**/*.ts", | ||
"prettier:format": "prettier --write src/**/*.ts", | ||
"test": "jest" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { canonicalize } from './canonicalize'; | ||
|
||
describe(canonicalize, () => { | ||
it('returns null when the given path is /', () => { | ||
expect(canonicalize('/')).toBeNull(); | ||
}); | ||
|
||
it('returns / when the given path is //', () => { | ||
expect(canonicalize('//')).toBe('/'); | ||
}); | ||
|
||
it('returns null when the given path is already canonical', () => { | ||
expect(canonicalize('/api/v1/users/42')).toBeNull(); | ||
}); | ||
|
||
it('eliminates trailing slashes', () => { | ||
expect(canonicalize('/api/v1/users/42/')).toBe('/api/v1/users/42'); | ||
expect(canonicalize('/api/v1/users/42//')).toBe('/api/v1/users/42'); | ||
expect(canonicalize('/api/v1/users/42///')).toBe('/api/v1/users/42'); | ||
}); | ||
|
||
it('folds multiple slashes into one', () => { | ||
expect(canonicalize('//api/v1/users/42')).toBe('/api/v1/users/42'); | ||
expect(canonicalize('/api/v1//users//42')).toBe('/api/v1/users/42'); | ||
expect(canonicalize('/api/v1///users///42')).toBe('/api/v1/users/42'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
const SLASHES = new RegExp('//+', 'g'); | ||
|
||
/** | ||
* Canonicalize the given path. Returns null if the given path is already canonical. | ||
* @param path | ||
*/ | ||
export function canonicalize(path: string): string | null { | ||
if (path === '/') { | ||
return null; | ||
} | ||
|
||
let newPath = path; | ||
|
||
if (newPath.includes('//')) { | ||
newPath = newPath.replace(SLASHES, '/'); | ||
} | ||
|
||
if (newPath !== '/' && newPath.endsWith('/')) { | ||
newPath = newPath.slice(0, -1); | ||
} | ||
|
||
return newPath === path ? null : newPath; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import * as Koa from 'koa'; | ||
import { Server } from 'http'; | ||
import * as request from 'supertest'; | ||
|
||
import { pathCanonicalizer } from './'; | ||
|
||
describe(pathCanonicalizer, () => { | ||
let app: Koa; | ||
let server: Server; | ||
|
||
beforeAll(() => { | ||
app = new Koa(); | ||
app.use(pathCanonicalizer()); | ||
app.use(async (ctx, next) => { | ||
if (ctx.path === '/' || ctx.path === '/api/v1/users/42') { | ||
ctx.status = 200; | ||
ctx.body = 'Hello, world!'; | ||
await next(); | ||
} | ||
}); | ||
|
||
server = app.listen(); | ||
}); | ||
|
||
afterAll(() => server.close()); | ||
|
||
const get = (path: string) => request(server).get(path); | ||
|
||
describe('when the path is canonical', () => { | ||
describe('/', () => { | ||
it('returns 200', async () => { | ||
const res = await get('/'); | ||
expect(res.status).toBe(200); | ||
}); | ||
}); | ||
|
||
describe('/api/v1/users/42', () => { | ||
it('returns 200', async () => { | ||
const res = await get('/api/v1/users/42'); | ||
expect(res.status).toBe(200); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('when the path is non-canonical', () => { | ||
describe('//', () => { | ||
it('redirects to /', async () => { | ||
const res = await get('//'); | ||
expect(res.status).toBe(302); | ||
expect(res.header['location']).toBe('/'); | ||
}); | ||
}); | ||
|
||
describe('//api////v1/users////42', () => { | ||
it('redirects to /api/v1/users/42', async () => { | ||
const res = await get('//api////v1/users////42'); | ||
expect(res.status).toBe(302); | ||
expect(res.header['location']).toBe('/api/v1/users/42'); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { Middleware, Context } from 'koa'; | ||
|
||
import { canonicalize } from './canonicalize'; | ||
|
||
/** | ||
* A Koa middleware to redirect to canonicalized path | ||
*/ | ||
export function pathCanonicalizer(): Middleware { | ||
return async function(ctx: Context, next: () => Promise<void>): Promise<void> { | ||
const newPath = canonicalize(ctx.path); | ||
|
||
if (newPath === null) { | ||
await next(); | ||
} else { | ||
ctx.redirect(newPath); | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"compilerOptions": { | ||
"module": "commonjs", | ||
"noFallthroughCasesInSwitch": true, | ||
"noImplicitReturns": true, | ||
"noUnusedLocals": true, | ||
"noUnusedParameters": true, | ||
"strict": true, | ||
"target": "esnext" | ||
}, | ||
"exclude": [ | ||
"./src/**/*.test.ts" | ||
] | ||
} |
Oops, something went wrong.