aboutsummaryrefslogtreecommitdiff
path: root/node_modules/@shellscape
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/@shellscape')
-rw-r--r--node_modules/@shellscape/koa-send/History.md127
-rw-r--r--node_modules/@shellscape/koa-send/Readme.md105
-rw-r--r--node_modules/@shellscape/koa-send/index.js175
-rw-r--r--node_modules/@shellscape/koa-send/legacy/index.js190
-rw-r--r--node_modules/@shellscape/koa-send/package.json55
-rw-r--r--node_modules/@shellscape/koa-static/History.md113
-rw-r--r--node_modules/@shellscape/koa-static/Readme.md86
-rw-r--r--node_modules/@shellscape/koa-static/index.js73
-rw-r--r--node_modules/@shellscape/koa-static/legacy/index.js92
-rw-r--r--node_modules/@shellscape/koa-static/package.json53
10 files changed, 1069 insertions, 0 deletions
diff --git a/node_modules/@shellscape/koa-send/History.md b/node_modules/@shellscape/koa-send/History.md
new file mode 100644
index 00000000..52be81eb
--- /dev/null
+++ b/node_modules/@shellscape/koa-send/History.md
@@ -0,0 +1,127 @@
+
+4.1.2 / 2017-12-14
+==================
+
+ * Fix issue with dots in path when using extensions array (#92)
+
+4.1.1 / 2017-09-25
+==================
+
+ * Fix brotli support, closes #83
+ * Fix tests
+
+4.1.0 / 2017-04-26
+==================
+
+ * Add support for Cache-Control: immutable with a new "immutable" option
+ * Added serving of brotli versions of files
+
+4.0.0 / 2017-04-09
+==================
+
+ * throw error if file not exists, closes #43
+ * remove co, use async function
+ * bump deps
+
+3.3.0 / 2017-01-10
+==================
+
+ * add extensions option
+ * bump deps
+
+3.2.0 / 2016-03-23
+==================
+
+ * add setHeaders option
+
+3.1.1 / 2016-03-04
+==================
+
+ * bump deps
+ * simplify scripts
+
+3.1.0 / 2015-10-24
+==================
+
+ * return a promise instead of a generator
+ * fix: split path by path.sep instead of slash
+ * fix: strip root correctly on windows
+ * tests: resolve paths for windows
+
+3.0.1 / 2015-10-23
+==================
+
+ * fix stats info when path does not finish with slash and format is enabled, closes #34
+
+3.0.0 / 2015-10-21
+==================
+
+ * bump deps
+ * format option defaults to true
+ * fix: enable format only index exists
+ * simplify the declarations of `format`, `gzip`
+
+2.0.1 / 2015-10-14
+==================
+
+ * fix judgement of trailing slash
+
+2.0.0 / 2015-10-14
+==================
+
+ * serve directories without a trailing slash, closes #27
+ * when .hidden option is set, also check hidden directories, closes #17
+ * bump deps: mz@2, mocha@2, koa@1
+ * use resolve-path, closes #9
+ * gzip version of file should not be automatically sent
+ * fix test: gzip.json.gz is not valid json data
+
+1.3.1 / 2014-09-08
+==================
+
+ * add .maxAge alias
+
+1.3.0 / 2014-09-07
+==================
+
+ * add automatically check and serve `.gz` files
+ * remove `finished` dependency
+ * refactor with `mz`
+
+1.2.3 / 2014-02-11
+==================
+
+ * fix malicious path in windows
+ * update finished
+ * make assert message better
+
+1.2.2 / 2014-01-07
+==================
+
+ * fix: ignore directories instead of crashing koa
+
+1.2.1 / 2014-01-02
+==================
+
+ * add `content-length` header
+
+1.2.0 / 2013-12-27
+==================
+
+ * add `maxage` option
+
+1.1.2 / 2013-12-22
+==================
+
+ * replace deprecated ctx.error() with ctx.throw()
+
+1.1.1 / 2013-12-20
+==================
+
+ * use: on-socket-error
+
+1.1.0 / 2013-12-19
+==================
+
+ * add: `send` now returns the file path if sent
+ * add: destroy streams on socket errors to prevent fd leaks
diff --git a/node_modules/@shellscape/koa-send/Readme.md b/node_modules/@shellscape/koa-send/Readme.md
new file mode 100644
index 00000000..eb92ee84
--- /dev/null
+++ b/node_modules/@shellscape/koa-send/Readme.md
@@ -0,0 +1,105 @@
+
+# koa-send
+
+[![NPM version][npm-image]][npm-url]
+[![Build status][travis-image]][travis-url]
+[![Test coverage][coveralls-image]][coveralls-url]
+[![Dependency Status][david-image]][david-url]
+[![License][license-image]][license-url]
+[![Downloads][downloads-image]][downloads-url]
+
+ Static file serving middleware.
+
+## Installation
+
+```js
+$ npm install koa-send
+```
+
+## Options
+
+ - `maxage` Browser cache max-age in milliseconds. (defaults to `0`)
+ - `immutable` Tell the browser the resource is immutable and can be cached indefinitely. (defaults to `false`)
+ - `hidden` Allow transfer of hidden files. (defaults to `false`)
+ - [`root`](#root-path) Root directory to restrict file access.
+ - `index` Name of the index file to serve automatically when visiting the root location. (defaults to none)
+ - `gzip` Try to serve the gzipped version of a file automatically when `gzip` is supported by a client and if the requested file with `.gz` extension exists. (defaults to `true`).
+ - `brotli` Try to serve the brotli version of a file automatically when `brotli` is supported by a client and if the requested file with `.br` extension exists. (defaults to `true`).
+ - `format` If not `false` (defaults to `true`), format the path to serve static file servers and not require a trailing slash for directories, so that you can do both `/directory` and `/directory/`.
+ - [`setHeaders`](#setheaders) Function to set custom headers on response.
+ - `extensions` Try to match extensions from passed array to search for file when no extension is sufficed in URL. First found is served. (defaults to `false`)
+
+### Root path
+
+ Note that `root` is required, defaults to `''` and will be resolved,
+ removing the leading `/` to make the path relative and this
+ path must not contain "..", protecting developers from
+ concatenating user input. If you plan on serving files based on
+ user input supply a `root` directory from which to serve from.
+
+ For example to serve files from `./public`:
+
+```js
+app.use(async (ctx) => {
+ await send(ctx, ctx.path, { root: __dirname + '/public' });
+})
+```
+
+ To serve developer specified files:
+
+```js
+app.use(async (ctx) => {
+ await send(ctx, 'path/to/my.js');
+})
+```
+
+### setHeaders
+
+The function is called as `fn(res, path, stats)`, where the arguments are:
+* `res`: the response object
+* `path`: the resolved file path that is being sent
+* `stats`: the stats object of the file that is being sent.
+
+You should only use the `setHeaders` option when you wish to edit the `Cache-Control` or `Last-Modified` headers, because doing it before is useless (it's overwritten by `send`), and doing it after is too late because the headers are already sent.
+
+If you want to edit any other header, simply set them before calling `send`.
+
+## Example
+
+```js
+const send = require('koa-send');
+const Koa = require('koa');
+const app = new Koa();
+
+// $ GET /package.json
+// $ GET /
+
+app.use(async (ctx) => {
+ if ('/' == ctx.path) return ctx.body = 'Try GET /package.json';
+ await send(ctx, ctx.path);
+})
+
+app.listen(3000);
+console.log('listening on port 3000');
+```
+
+## License
+
+ MIT
+
+[npm-image]: https://img.shields.io/npm/v/koa-send.svg?style=flat-square
+[npm-url]: https://npmjs.org/package/koa-send
+[github-tag]: http://img.shields.io/github/tag/koajs/send.svg?style=flat-square
+[github-url]: https://github.com/koajs/send/tags
+[travis-image]: https://img.shields.io/travis/koajs/send.svg?style=flat-square
+[travis-url]: https://travis-ci.org/koajs/send
+[coveralls-image]: https://img.shields.io/coveralls/koajs/send.svg?style=flat-square
+[coveralls-url]: https://coveralls.io/r/koajs/send?branch=master
+[david-image]: http://img.shields.io/david/koajs/send.svg?style=flat-square
+[david-url]: https://david-dm.org/koajs/send
+[license-image]: http://img.shields.io/npm/l/koa-send.svg?style=flat-square
+[license-url]: LICENSE
+[downloads-image]: http://img.shields.io/npm/dm/koa-send.svg?style=flat-square
+[downloads-url]: https://npmjs.org/package/koa-send
+[gittip-image]: https://img.shields.io/gittip/jonathanong.svg?style=flat-square
+[gittip-url]: https://www.gittip.com/jonathanong/
diff --git a/node_modules/@shellscape/koa-send/index.js b/node_modules/@shellscape/koa-send/index.js
new file mode 100644
index 00000000..8d87a045
--- /dev/null
+++ b/node_modules/@shellscape/koa-send/index.js
@@ -0,0 +1,175 @@
+/**
+ * Module dependencies.
+ */
+
+const debug = require('debug')('koa-send')
+const resolvePath = require('resolve-path')
+const createError = require('http-errors')
+const assert = require('assert')
+const fs = require('mz/fs')
+
+const {
+ normalize,
+ basename,
+ extname,
+ resolve,
+ parse,
+ sep
+} = require('path')
+
+/**
+ * Expose `send()`.
+ */
+
+module.exports = send
+
+/**
+ * Send file at `path` with the
+ * given `options` to the koa `ctx`.
+ *
+ * @param {Context} ctx
+ * @param {String} path
+ * @param {Object} [opts]
+ * @return {Function}
+ * @api public
+ */
+
+async function send (ctx, path, opts = {}) {
+ assert(ctx, 'koa context required')
+ assert(path, 'pathname required')
+
+ // options
+ debug('send "%s" %j', path, opts)
+ const root = opts.root ? normalize(resolve(opts.root)) : ''
+ const trailingSlash = path[path.length - 1] === '/'
+ path = path.substr(parse(path).root.length)
+ const index = opts.index
+ const maxage = opts.maxage || opts.maxAge || 0
+ const immutable = opts.immutable || false
+ const hidden = opts.hidden || false
+ const format = opts.format !== false
+ const extensions = Array.isArray(opts.extensions) ? opts.extensions : false
+ const brotli = opts.brotli !== false
+ const gzip = opts.gzip !== false
+ const setHeaders = opts.setHeaders
+
+ if (setHeaders && typeof setHeaders !== 'function') {
+ throw new TypeError('option setHeaders must be function')
+ }
+
+ // normalize path
+ path = decode(path)
+
+ if (path === -1) return ctx.throw(400, 'failed to decode')
+
+ // index file support
+ if (index && trailingSlash) path += index
+
+ path = resolvePath(root, path)
+
+ // hidden file support, ignore
+ if (!hidden && isHidden(root, path)) return
+
+ let encodingExt = ''
+ // serve brotli file when possible otherwise gzipped file when possible
+ if (ctx.acceptsEncodings('br', 'identity') === 'br' && brotli && (await fs.exists(path + '.br'))) {
+ path = path + '.br'
+ ctx.set('Content-Encoding', 'br')
+ ctx.res.removeHeader('Content-Length')
+ encodingExt = '.br'
+ } else if (ctx.acceptsEncodings('gzip', 'identity') === 'gzip' && gzip && (await fs.exists(path + '.gz'))) {
+ path = path + '.gz'
+ ctx.set('Content-Encoding', 'gzip')
+ ctx.res.removeHeader('Content-Length')
+ encodingExt = '.gz'
+ }
+
+ if (extensions && !/\.[^/]*$/.exec(path)) {
+ const list = [].concat(extensions)
+ for (let i = 0; i < list.length; i++) {
+ let ext = list[i]
+ if (typeof ext !== 'string') {
+ throw new TypeError('option extensions must be array of strings or false')
+ }
+ if (!/^\./.exec(ext)) ext = '.' + ext
+ if (await fs.exists(path + ext)) {
+ path = path + ext
+ break
+ }
+ }
+ }
+
+ // stat
+ let stats
+ try {
+ stats = await fs.stat(path)
+
+ // Format the path to serve static file servers
+ // and not require a trailing slash for directories,
+ // so that you can do both `/directory` and `/directory/`
+ if (stats.isDirectory()) {
+ if (format && index) {
+ path += '/' + index
+ stats = await fs.stat(path)
+ } else {
+ return
+ }
+ }
+ } catch (err) {
+ const notfound = ['ENOENT', 'ENAMETOOLONG', 'ENOTDIR']
+ if (notfound.includes(err.code)) {
+ throw createError(404, err)
+ }
+ err.status = 500
+ throw err
+ }
+
+ if (setHeaders) setHeaders(ctx.res, path, stats)
+
+ // stream
+ ctx.set('Content-Length', stats.size)
+ if (!ctx.response.get('Last-Modified')) ctx.set('Last-Modified', stats.mtime.toUTCString())
+ if (!ctx.response.get('Cache-Control')) {
+ const directives = ['max-age=' + (maxage / 1000 | 0)]
+ if (immutable) {
+ directives.push('immutable')
+ }
+ ctx.set('Cache-Control', directives.join(','))
+ }
+ ctx.type = type(path, encodingExt)
+ ctx.body = fs.createReadStream(path)
+
+ return path
+}
+
+/**
+ * Check if it's hidden.
+ */
+
+function isHidden (root, path) {
+ path = path.substr(root.length).split(sep)
+ for (let i = 0; i < path.length; i++) {
+ if (path[i][0] === '.') return true
+ }
+ return false
+}
+
+/**
+ * File type.
+ */
+
+function type (file, ext) {
+ return ext !== '' ? extname(basename(file, ext)) : extname(file)
+}
+
+/**
+ * Decode `path`.
+ */
+
+function decode (path) {
+ try {
+ return decodeURIComponent(path)
+ } catch (err) {
+ return -1
+ }
+}
diff --git a/node_modules/@shellscape/koa-send/legacy/index.js b/node_modules/@shellscape/koa-send/legacy/index.js
new file mode 100644
index 00000000..043c1dd6
--- /dev/null
+++ b/node_modules/@shellscape/koa-send/legacy/index.js
@@ -0,0 +1,190 @@
+function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _next(value) { step("next", value); } function _throw(err) { step("throw", err); } _next(); }); }; }
+
+/**
+ * Module dependencies.
+ */
+const debug = require('debug')('koa-send');
+
+const resolvePath = require('resolve-path');
+
+const createError = require('http-errors');
+
+const assert = require('assert');
+
+const fs = require('mz/fs');
+
+const {
+ normalize,
+ basename,
+ extname,
+ resolve,
+ parse,
+ sep
+} = require('path');
+/**
+ * Expose `send()`.
+ */
+
+
+module.exports = send;
+/**
+ * Send file at `path` with the
+ * given `options` to the koa `ctx`.
+ *
+ * @param {Context} ctx
+ * @param {String} path
+ * @param {Object} [opts]
+ * @return {Function}
+ * @api public
+ */
+
+function send(_x, _x2) {
+ return _send.apply(this, arguments);
+}
+/**
+ * Check if it's hidden.
+ */
+
+
+function _send() {
+ _send = _asyncToGenerator(function* (ctx, path, opts = {}) {
+ assert(ctx, 'koa context required');
+ assert(path, 'pathname required'); // options
+
+ debug('send "%s" %j', path, opts);
+ const root = opts.root ? normalize(resolve(opts.root)) : '';
+ const trailingSlash = path[path.length - 1] === '/';
+ path = path.substr(parse(path).root.length);
+ const index = opts.index;
+ const maxage = opts.maxage || opts.maxAge || 0;
+ const immutable = opts.immutable || false;
+ const hidden = opts.hidden || false;
+ const format = opts.format !== false;
+ const extensions = Array.isArray(opts.extensions) ? opts.extensions : false;
+ const brotli = opts.brotli !== false;
+ const gzip = opts.gzip !== false;
+ const setHeaders = opts.setHeaders;
+
+ if (setHeaders && typeof setHeaders !== 'function') {
+ throw new TypeError('option setHeaders must be function');
+ } // normalize path
+
+
+ path = decode(path);
+ if (path === -1) return ctx.throw(400, 'failed to decode'); // index file support
+
+ if (index && trailingSlash) path += index;
+ path = resolvePath(root, path); // hidden file support, ignore
+
+ if (!hidden && isHidden(root, path)) return;
+ let encodingExt = ''; // serve brotli file when possible otherwise gzipped file when possible
+
+ if (ctx.acceptsEncodings('br', 'identity') === 'br' && brotli && (yield fs.exists(path + '.br'))) {
+ path = path + '.br';
+ ctx.set('Content-Encoding', 'br');
+ ctx.res.removeHeader('Content-Length');
+ encodingExt = '.br';
+ } else if (ctx.acceptsEncodings('gzip', 'identity') === 'gzip' && gzip && (yield fs.exists(path + '.gz'))) {
+ path = path + '.gz';
+ ctx.set('Content-Encoding', 'gzip');
+ ctx.res.removeHeader('Content-Length');
+ encodingExt = '.gz';
+ }
+
+ if (extensions && !/\.[^/]*$/.exec(path)) {
+ const list = [].concat(extensions);
+
+ for (let i = 0; i < list.length; i++) {
+ let ext = list[i];
+
+ if (typeof ext !== 'string') {
+ throw new TypeError('option extensions must be array of strings or false');
+ }
+
+ if (!/^\./.exec(ext)) ext = '.' + ext;
+
+ if (yield fs.exists(path + ext)) {
+ path = path + ext;
+ break;
+ }
+ }
+ } // stat
+
+
+ let stats;
+
+ try {
+ stats = yield fs.stat(path); // Format the path to serve static file servers
+ // and not require a trailing slash for directories,
+ // so that you can do both `/directory` and `/directory/`
+
+ if (stats.isDirectory()) {
+ if (format && index) {
+ path += '/' + index;
+ stats = yield fs.stat(path);
+ } else {
+ return;
+ }
+ }
+ } catch (err) {
+ const notfound = ['ENOENT', 'ENAMETOOLONG', 'ENOTDIR'];
+
+ if (notfound.includes(err.code)) {
+ throw createError(404, err);
+ }
+
+ err.status = 500;
+ throw err;
+ }
+
+ if (setHeaders) setHeaders(ctx.res, path, stats); // stream
+
+ ctx.set('Content-Length', stats.size);
+ if (!ctx.response.get('Last-Modified')) ctx.set('Last-Modified', stats.mtime.toUTCString());
+
+ if (!ctx.response.get('Cache-Control')) {
+ const directives = ['max-age=' + (maxage / 1000 | 0)];
+
+ if (immutable) {
+ directives.push('immutable');
+ }
+
+ ctx.set('Cache-Control', directives.join(','));
+ }
+
+ ctx.type = type(path, encodingExt);
+ ctx.body = fs.createReadStream(path);
+ return path;
+ });
+ return _send.apply(this, arguments);
+}
+
+function isHidden(root, path) {
+ path = path.substr(root.length).split(sep);
+
+ for (let i = 0; i < path.length; i++) {
+ if (path[i][0] === '.') return true;
+ }
+
+ return false;
+}
+/**
+ * File type.
+ */
+
+
+function type(file, ext) {
+ return ext !== '' ? extname(basename(file, ext)) : extname(file);
+}
+/**
+ * Decode `path`.
+ */
+
+
+function decode(path) {
+ try {
+ return decodeURIComponent(path);
+ } catch (err) {
+ return -1;
+ }
+}
diff --git a/node_modules/@shellscape/koa-send/package.json b/node_modules/@shellscape/koa-send/package.json
new file mode 100644
index 00000000..825bb6ee
--- /dev/null
+++ b/node_modules/@shellscape/koa-send/package.json
@@ -0,0 +1,55 @@
+{
+ "name": "@shellscape/koa-send",
+ "description": "Transfer static files",
+ "repository": "shellscape/koa-send",
+ "version": "4.1.3",
+ "keywords": [
+ "koa",
+ "file",
+ "static",
+ "sendfile"
+ ],
+ "files": [
+ "index.js",
+ "legacy/index.js"
+ ],
+ "publishConfig": {
+ "access": "public"
+ },
+ "devDependencies": {
+ "@babel/cli": "^7.0.0-beta.39",
+ "@babel/core": "^7.0.0-beta.39",
+ "@babel/polyfill": "^7.0.0-beta.39",
+ "@babel/preset-env": "^7.0.0-beta.39",
+ "@babel/register": "^7.0.0-beta.39",
+ "eslint": "^3.19.0",
+ "eslint-config-standard": "^10.2.1",
+ "eslint-plugin-import": "^2.2.0",
+ "eslint-plugin-node": "^4.2.2",
+ "eslint-plugin-promise": "^3.5.0",
+ "eslint-plugin-standard": "^3.0.1",
+ "iltorb": "^1.2.1",
+ "istanbul": "0",
+ "koa": "2",
+ "mocha": "3",
+ "should": "11",
+ "supertest": "3"
+ },
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^2.6.3",
+ "http-errors": "^1.6.1",
+ "mz": "^2.6.0",
+ "resolve-path": "^1.3.3"
+ },
+ "scripts": {
+ "lint": "eslint --fix .",
+ "prepublishOnly": "babel index.js --out-file legacy/index.js",
+ "test": "npm run prepublishOnly && mocha --require should --reporter spec",
+ "test-cov": "istanbul cover ./node_modules/.bin/_mocha -- --require should",
+ "test-travis": "istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- --require should"
+ },
+ "engines": {
+ "node": ">= 6.11.0"
+ }
+}
diff --git a/node_modules/@shellscape/koa-static/History.md b/node_modules/@shellscape/koa-static/History.md
new file mode 100644
index 00000000..f5dbcab1
--- /dev/null
+++ b/node_modules/@shellscape/koa-static/History.md
@@ -0,0 +1,113 @@
+
+4.0.2 / 2017-11-16
+==================
+
+* Fix: `serve` mutates `opts` argument so it cannot be reused (#117)
+
+4.0.1 / 2017-07-09
+==================
+
+ * Fix: throw error if error status not 404
+ * fix `index: false` bug if path is directory
+
+4.0.0 / 2017-07-03
+==================
+
+ * upgrade to koa-send@4
+ * use async function
+
+3.0.0 / 2016-03-24
+==================
+
+ * support koa 2.x
+ * travis: test node@4+
+
+2.0.0 / 2016-01-07
+==================
+
+ * bump koa-send@~3.1.0
+
+1.5.2 / 2015-11-03
+==================
+
+ * Fix: default index could be disabled. Closes #41
+
+1.5.1 / 2015-10-14
+==================
+
+ * Fix v1.4.x → 1.5.0 broken. Closes #53
+
+1.5.0 / 2015-10-14
+==================
+
+ * update koa-send@2
+ * update devDeps
+
+1.4.9 / 2015-02-03
+==================
+
+ * only support GET and HEAD requests
+
+1.4.8 / 2014-12-17
+==================
+
+ * support root = `.`
+
+1.4.7 / 2014-09-07
+==================
+
+ * update koa-send
+
+1.4.5 / 2014-05-05
+==================
+
+ * Fix response already handled logic - Koajs now defaults status == 404. See koajs/koa#269
+
+1.4.4 / 2014-05-04
+==================
+
+ * Add two missing semicolons. Closes #24
+ * Use bash syntax highlighting for install command. Closes #23
+ * named generator function to help debugging. Closes #20
+
+1.4.3 / 2014-02-11
+==================
+
+ * update koa-send
+
+1.4.2 / 2014-01-07
+==================
+
+ * update koa-send
+
+1.4.1 / 2013-12-30
+==================
+
+ * fix for koa 0.2.1. Closes #12
+
+1.4.0 / 2013-12-20
+==================
+
+ * add: defer option - semi-breaking change
+
+1.3.0 / 2013-12-11
+==================
+
+ * refactor to use koa-send
+ * rename maxAge -> maxage
+ * fix: don't bother responding if response already "handled"
+
+1.2.0 / 2013-09-14
+==================
+
+ * add Last-Modified. Closes #5
+
+1.1.1 / 2013-09-13
+==================
+
+ * fix upstream responses
+
+1.1.0 / 2013-09-13
+==================
+
+ * rewrite without send
diff --git a/node_modules/@shellscape/koa-static/Readme.md b/node_modules/@shellscape/koa-static/Readme.md
new file mode 100644
index 00000000..16c32eaa
--- /dev/null
+++ b/node_modules/@shellscape/koa-static/Readme.md
@@ -0,0 +1,86 @@
+# koa-static
+
+[![NPM version][npm-image]][npm-url]
+[![Build status][travis-image]][travis-url]
+[![Test coverage][coveralls-image]][coveralls-url]
+[![Dependency Status][david-image]][david-url]
+[![License][license-image]][license-url]
+[![Downloads][downloads-image]][downloads-url]
+
+ Koa static file serving middleware, wrapper for [`koa-send`](https://github.com/koajs/send).
+
+## Installation
+
+```bash
+$ npm install koa-static
+```
+
+## API
+
+```js
+const Koa = require('koa');
+const app = new Koa();
+app.use(require('koa-static')(root, opts));
+```
+
+* `root` root directory string. nothing above this root directory can be served
+* `opts` options object.
+
+### Options
+
+ - `maxage` Browser cache max-age in milliseconds. defaults to 0
+ - `hidden` Allow transfer of hidden files. defaults to false
+ - `index` Default file name, defaults to 'index.html'
+ - `defer` If true, serves after `return next()`, allowing any downstream middleware to respond first.
+ - `gzip` Try to serve the gzipped version of a file automatically when gzip is supported by a client and if the requested file with .gz extension exists. defaults to true.
+ - `br` Try to serve the brotli version of a file automatically when brotli is supported by a client and if the requested file with .br extension exists (note, that brotli is only accepted over https). defaults to true.
+ - [setHeaders](https://github.com/koajs/send#setheaders) Function to set custom headers on response.
+ - `extensions` Try to match extensions from passed array to search for file when no extension is sufficed in URL. First found is served. (defaults to `false`)
+
+## Example
+
+```js
+const serve = require('koa-static');
+const Koa = require('koa');
+const app = new Koa();
+
+// $ GET /package.json
+app.use(serve('.'));
+
+// $ GET /hello.txt
+app.use(serve('test/fixtures'));
+
+// or use absolute paths
+app.use(serve(__dirname + '/test/fixtures'));
+
+app.listen(3000);
+
+console.log('listening on port 3000');
+```
+
+### See also
+
+ - [koajs/conditional-get](https://github.com/koajs/conditional-get) Conditional GET support for koa
+ - [koajs/compress](https://github.com/koajs/compress) Compress middleware for koa
+ - [koajs/mount](https://github.com/koajs/mount) Mount `koa-static` to a specific path
+
+## License
+
+ MIT
+
+[npm-image]: https://img.shields.io/npm/v/koa-static.svg?style=flat-square
+[npm-url]: https://npmjs.org/package/koa-static
+[github-tag]: http://img.shields.io/github/tag/koajs/static.svg?style=flat-square
+[github-url]: https://github.com/koajs/static/tags
+[travis-image]: https://img.shields.io/travis/koajs/static.svg?style=flat-square
+[travis-url]: https://travis-ci.org/koajs/static
+[coveralls-image]: https://img.shields.io/coveralls/koajs/static.svg?style=flat-square
+[coveralls-url]: https://coveralls.io/r/koajs/static?branch=master
+[david-image]: http://img.shields.io/david/koajs/static.svg?style=flat-square
+[david-url]: https://david-dm.org/koajs/static
+[license-image]: http://img.shields.io/npm/l/koa-static.svg?style=flat-square
+[license-url]: LICENSE
+[downloads-image]: http://img.shields.io/npm/dm/koa-static.svg?style=flat-square
+[downloads-url]: https://npmjs.org/package/koa-static
+[gittip-image]: https://img.shields.io/gittip/jonathanong.svg?style=flat-square
+[gittip-url]: https://www.gittip.com/jonathanong/
diff --git a/node_modules/@shellscape/koa-static/index.js b/node_modules/@shellscape/koa-static/index.js
new file mode 100644
index 00000000..02355ef0
--- /dev/null
+++ b/node_modules/@shellscape/koa-static/index.js
@@ -0,0 +1,73 @@
+
+'use strict'
+
+/**
+ * Module dependencies.
+ */
+
+const debug = require('debug')('koa-static')
+const { resolve } = require('path')
+const assert = require('assert')
+const send = require('koa-send')
+
+/**
+ * Expose `serve()`.
+ */
+
+module.exports = serve
+
+/**
+ * Serve static files from `root`.
+ *
+ * @param {String} root
+ * @param {Object} [opts]
+ * @return {Function}
+ * @api public
+ */
+
+function serve (root, opts) {
+ opts = Object.assign({}, opts)
+
+ assert(root, 'root directory is required to serve files')
+
+ // options
+ debug('static "%s" %j', root, opts)
+ opts.root = resolve(root)
+ if (opts.index !== false) opts.index = opts.index || 'index.html'
+
+ if (!opts.defer) {
+ return async function serve (ctx, next) {
+ let done = false
+
+ if (ctx.method === 'HEAD' || ctx.method === 'GET') {
+ try {
+ done = await send(ctx, ctx.path, opts)
+ } catch (err) {
+ if (err.status !== 404) {
+ throw err
+ }
+ }
+ }
+
+ if (!done) {
+ await next()
+ }
+ }
+ }
+
+ return async function serve (ctx, next) {
+ await next()
+
+ if (ctx.method !== 'HEAD' && ctx.method !== 'GET') return
+ // response is already handled
+ if (ctx.body != null || ctx.status !== 404) return // eslint-disable-line
+
+ try {
+ await send(ctx, ctx.path, opts)
+ } catch (err) {
+ if (err.status !== 404) {
+ throw err
+ }
+ }
+ }
+}
diff --git a/node_modules/@shellscape/koa-static/legacy/index.js b/node_modules/@shellscape/koa-static/legacy/index.js
new file mode 100644
index 00000000..fe21365b
--- /dev/null
+++ b/node_modules/@shellscape/koa-static/legacy/index.js
@@ -0,0 +1,92 @@
+'use strict';
+/**
+ * Module dependencies.
+ */
+
+function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _next(value) { step("next", value); } function _throw(err) { step("throw", err); } _next(); }); }; }
+
+const debug = require('debug')('koa-static');
+
+const {
+ resolve
+} = require('path');
+
+const assert = require('assert');
+
+const send = require("@shellscape/koa-send/legacy");
+/**
+ * Expose `serve()`.
+ */
+
+
+module.exports = serve;
+/**
+ * Serve static files from `root`.
+ *
+ * @param {String} root
+ * @param {Object} [opts]
+ * @return {Function}
+ * @api public
+ */
+
+function serve(root, opts) {
+ opts = Object.assign({}, opts);
+ assert(root, 'root directory is required to serve files'); // options
+
+ debug('static "%s" %j', root, opts);
+ opts.root = resolve(root);
+ if (opts.index !== false) opts.index = opts.index || 'index.html';
+
+ if (!opts.defer) {
+ return (
+ /*#__PURE__*/
+ function () {
+ var _serve = _asyncToGenerator(function* (ctx, next) {
+ let done = false;
+
+ if (ctx.method === 'HEAD' || ctx.method === 'GET') {
+ try {
+ done = yield send(ctx, ctx.path, opts);
+ } catch (err) {
+ if (err.status !== 404) {
+ throw err;
+ }
+ }
+ }
+
+ if (!done) {
+ yield next();
+ }
+ });
+
+ return function serve(_x, _x2) {
+ return _serve.apply(this, arguments);
+ };
+ }()
+ );
+ }
+
+ return (
+ /*#__PURE__*/
+ function () {
+ var _serve2 = _asyncToGenerator(function* (ctx, next) {
+ yield next();
+ if (ctx.method !== 'HEAD' && ctx.method !== 'GET') return; // response is already handled
+
+ if (ctx.body != null || ctx.status !== 404) return; // eslint-disable-line
+
+ try {
+ yield send(ctx, ctx.path, opts);
+ } catch (err) {
+ if (err.status !== 404) {
+ throw err;
+ }
+ }
+ });
+
+ return function serve(_x3, _x4) {
+ return _serve2.apply(this, arguments);
+ };
+ }()
+ );
+}
diff --git a/node_modules/@shellscape/koa-static/package.json b/node_modules/@shellscape/koa-static/package.json
new file mode 100644
index 00000000..24a4d5b9
--- /dev/null
+++ b/node_modules/@shellscape/koa-static/package.json
@@ -0,0 +1,53 @@
+{
+ "name": "@shellscape/koa-static",
+ "description": "Static file serving middleware for koa",
+ "repository": "shellscape/koa-static",
+ "version": "4.0.5",
+ "keywords": [
+ "koa",
+ "middleware",
+ "file",
+ "static",
+ "sendfile"
+ ],
+ "files": [
+ "index.js",
+ "legacy/index.js"
+ ],
+ "publishConfig": {
+ "access": "public"
+ },
+ "devDependencies": {
+ "@babel/cli": "^7.0.0-beta.39",
+ "@babel/core": "^7.0.0-beta.39",
+ "@babel/polyfill": "^7.0.0-beta.39",
+ "@babel/preset-env": "^7.0.0-beta.39",
+ "@babel/register": "^7.0.0-beta.39",
+ "babel-plugin-module-resolver": "^3.0.0",
+ "eslint": "^4.1.1",
+ "eslint-config-standard": "^10.2.1",
+ "eslint-plugin-import": "^2.6.1",
+ "eslint-plugin-node": "^5.1.0",
+ "eslint-plugin-promise": "^3.5.0",
+ "eslint-plugin-standard": "^3.0.1",
+ "istanbul": "^0.4.5",
+ "koa": "^2.3.0",
+ "mocha": "^3.4.2",
+ "supertest": "^3.0.0"
+ },
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^2.6.8",
+ "@shellscape/koa-send": "^4.1.0"
+ },
+ "scripts": {
+ "lint": "eslint --fix .",
+ "prepublishOnly": "babel index.js --out-file legacy/index.js",
+ "test": "npm run prepublishOnly && mocha --harmony --reporter spec",
+ "test-cov": "node --harmony ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha",
+ "test-travis": "node --harmony ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha --report lcovonly"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+}