1
0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-24 21:15:51 +01:00

feat: convert project to typescript (#1374)

* chore: test

* chore: add

* chore: more progress

* chore: progress in migration, fix prettier parser

* chore: reduce tsc errors

* chore: refactor storage utils types

* chore: refactor utils types

* chore: refactor local storage types

* chore: refactor config utils types

* chore: refactor tsc types

* refactor: apply eslint fix, tabs etc

* chore: fix lint errors

* test: update unit test conf to typescript setup

few test refactored to typescript

* chore: enable more unit test

migrate to typescript

* chore: migrate storage test to tsc

* chore: migrate up storage test to tsc

* refactor: enable plugin and auth test

* chore: migrate plugin loader test

* chore: update dependencies

* chore: migrate functional test to typescript

* chore: add codecove

* chore: update express

* chore: downgrade puppeteer

The latest version does not seems to work properly fine.

* chore: update dependencies
This commit is contained in:
Juan Picado @jotadeveloper 2019-07-16 08:40:01 +02:00 committed by GitHub
parent b453681082
commit 66f4197236
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
208 changed files with 2753 additions and 55621 deletions

@ -1,3 +1,3 @@
{ {
"presets": [["@verdaccio", {"flow": true}]] "presets": [["@verdaccio", {"typescript": true}]]
} }

@ -16,3 +16,4 @@ Dockerfile
*.jpg *.jpg
*.sh *.sh
test/unit/partials/ test/unit/partials/
types/custom.d.ts

@ -1,58 +1,13 @@
{ {
"plugins": [
"babel",
"flowtype",
"jest",
"verdaccio",
"jsx-a11y"
],
"extends": [ "extends": [
"eslint:recommended", "@verdaccio"
"google",
"plugin:flowtype/recommended",
"plugin:jest/recommended",
"plugin:prettier/recommended",
"plugin:verdaccio/recommended",
"plugin:jsx-a11y/recommended"
], ],
"parser": "babel-eslint",
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 7,
"ecmaFeatures": {
"impliedStrict": true,
"jsx": true
}
},
"env": {
"browser": true,
"node": true,
"es6": true,
"jest": true
},
"globals": {
"__APP_VERSION__": true
},
"rules": { "rules": {
"babel/no-invalid-this": 1, "@typescript-eslint/no-var-requires": ["warn"],
"prettier/prettier": ["error", null, "@prettier"], "@typescript-eslint/no-use-before-define": 0,
"semi": ["error"], "@typescript-eslint/array-type": ["warn"],
"comma-dangle": ["error"], "@typescript-eslint/no-explicit-any": 0,
"camelcase": 0, "@typescript-eslint/indent": 0,
"no-useless-escape": ["error"], "@typescript-eslint/interface-name-prefix": 0
"no-invalid-this": 0,
"handle-callback-err": ["error"],
"no-fallthrough": ["error"],
"no-new-require": ["error"],
"max-len": ["error", 160],
"require-jsdoc": 0,
"valid-jsdoc": 0,
"prefer-spread": 1,
"prefer-rest-params": 1,
"linebreak-style": 0,
"quote-props":["error", "as-needed"],
"verdaccio/jsx-no-style": ["warn"],
"verdaccio/jsx-spread": ["warn"],
"jest/expect-expect": 0
} }
} }

@ -1,25 +0,0 @@
[ignore]
.*/node_modules/.*
.*/test/**/*.json
.*/static/.*
.*/test/unit/partials/.*
.*/.nyc_output/.*
.*/coverage/.*
.*/.vscode/.*
.*/build/.*
.*/docs/.*
.*/scripts/.*
.*/assets/.*
.*/bin/.*
.*/systemd/.*
.*/website/.*
.*/wiki/.*
.*/docs/.*
.*/tools/.*
[libs]
node_modules/@verdaccio/types/lib/
[options]
suppress_comment= \\(.\\|\n\\)*\\$FlowFixMe
module.ignore_non_literal_requires=true

@ -8,5 +8,5 @@
"jsxBracketSameLine": true, "jsxBracketSameLine": true,
"trailingComma": "es5", "trailingComma": "es5",
"semi": true, "semi": true,
"parser": "flow" "parser": "typescript"
} }

4
debug/bootstrap.js vendored

@ -1,4 +1,6 @@
// this file aims to help local debugging with hot transpilation // this file aims to help local debugging with hot transpilation
// it requires BABEL_ENV=registry set as env variable // it requires BABEL_ENV=registry set as env variable
require('@babel/register')(); require('@babel/register')({
extensions: [".ts", ".js"]
});
require('../src/lib/cli'); require('../src/lib/cli');

@ -1,38 +0,0 @@
// flow-typed signature: ce23ecafd4a8df99e8eab3d7417dea83
// flow-typed version: <<STUB>>/@material-ui/core/Avatar_v3.1.0/flow_v0.81.0
/**
* This is an autogenerated libdef stub for:
*
* '@material-ui/core/Avatar'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module '@material-ui/core/Avatar' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module '@material-ui/core/Avatar/Avatar' {
declare module.exports: any;
}
// Filename aliases
declare module '@material-ui/core/Avatar/Avatar.js' {
declare module.exports: $Exports<'@material-ui/core/Avatar/Avatar'>;
}
declare module '@material-ui/core/Avatar/index' {
declare module.exports: $Exports<'@material-ui/core/Avatar'>;
}
declare module '@material-ui/core/Avatar/index.js' {
declare module.exports: $Exports<'@material-ui/core/Avatar'>;
}

@ -1,38 +0,0 @@
// flow-typed signature: bc8a4aaaeb1e738c5006d06072a9b064
// flow-typed version: <<STUB>>/@material-ui/core/InputAdornment_v3.1.0/flow_v0.81.0
/**
* This is an autogenerated libdef stub for:
*
* '@material-ui/core/InputAdornment'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module '@material-ui/core/InputAdornment' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module '@material-ui/core/InputAdornment/InputAdornment' {
declare module.exports: any;
}
// Filename aliases
declare module '@material-ui/core/InputAdornment/index' {
declare module.exports: $Exports<'@material-ui/core/InputAdornment'>;
}
declare module '@material-ui/core/InputAdornment/index.js' {
declare module.exports: $Exports<'@material-ui/core/InputAdornment'>;
}
declare module '@material-ui/core/InputAdornment/InputAdornment.js' {
declare module.exports: $Exports<'@material-ui/core/InputAdornment/InputAdornment'>;
}

@ -1,38 +0,0 @@
// flow-typed signature: fd8dc668544eb744d5267a667187804b
// flow-typed version: <<STUB>>/@material-ui/core/MenuItem_v3.1.0/flow_v0.81.0
/**
* This is an autogenerated libdef stub for:
*
* '@material-ui/core/MenuItem'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module '@material-ui/core/MenuItem' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module '@material-ui/core/MenuItem/MenuItem' {
declare module.exports: any;
}
// Filename aliases
declare module '@material-ui/core/MenuItem/index' {
declare module.exports: $Exports<'@material-ui/core/MenuItem'>;
}
declare module '@material-ui/core/MenuItem/index.js' {
declare module.exports: $Exports<'@material-ui/core/MenuItem'>;
}
declare module '@material-ui/core/MenuItem/MenuItem.js' {
declare module.exports: $Exports<'@material-ui/core/MenuItem/MenuItem'>;
}

@ -1,38 +0,0 @@
// flow-typed signature: 1ac90635766a00f883f3d21d79c9f12e
// flow-typed version: <<STUB>>/@material-ui/core/Paper_v3.1.0/flow_v0.81.0
/**
* This is an autogenerated libdef stub for:
*
* '@material-ui/core/Paper'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module '@material-ui/core/Paper' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module '@material-ui/core/Paper/Paper' {
declare module.exports: any;
}
// Filename aliases
declare module '@material-ui/core/Paper/index' {
declare module.exports: $Exports<'@material-ui/core/Paper'>;
}
declare module '@material-ui/core/Paper/index.js' {
declare module.exports: $Exports<'@material-ui/core/Paper'>;
}
declare module '@material-ui/core/Paper/Paper.js' {
declare module.exports: $Exports<'@material-ui/core/Paper/Paper'>;
}

@ -1,38 +0,0 @@
// flow-typed signature: 864619754dd206242d851f1d47ddb63f
// flow-typed version: <<STUB>>/@material-ui/core/TextField_v3.0.1/flow_v0.81.0
/**
* This is an autogenerated libdef stub for:
*
* '@material-ui/core/TextField'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module '@material-ui/core/TextField' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module '@material-ui/core/TextField/TextField' {
declare module.exports: any;
}
// Filename aliases
declare module '@material-ui/core/TextField/index' {
declare module.exports: $Exports<'@material-ui/core/TextField'>;
}
declare module '@material-ui/core/TextField/index.js' {
declare module.exports: $Exports<'@material-ui/core/TextField'>;
}
declare module '@material-ui/core/TextField/TextField.js' {
declare module.exports: $Exports<'@material-ui/core/TextField/TextField'>;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,199 +0,0 @@
// flow-typed signature: 12a8262920099086254f18882b49d862
// flow-typed version: <<STUB>>/JSONStream_v1.3.2/flow_v0.64.0
/**
* This is an autogenerated libdef stub for:
*
* 'JSONStream'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'JSONStream' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'JSONStream/bin' {
declare module.exports: any;
}
declare module 'JSONStream/examples/all_docs' {
declare module.exports: any;
}
declare module 'JSONStream/test/bool' {
declare module.exports: any;
}
declare module 'JSONStream/test/browser' {
declare module.exports: any;
}
declare module 'JSONStream/test/destroy_missing' {
declare module.exports: any;
}
declare module 'JSONStream/test/disabled/doubledot1' {
declare module.exports: any;
}
declare module 'JSONStream/test/disabled/doubledot2' {
declare module.exports: any;
}
declare module 'JSONStream/test/empty' {
declare module.exports: any;
}
declare module 'JSONStream/test/error_contents' {
declare module.exports: any;
}
declare module 'JSONStream/test/fn' {
declare module.exports: any;
}
declare module 'JSONStream/test/gen' {
declare module.exports: any;
}
declare module 'JSONStream/test/header_footer' {
declare module.exports: any;
}
declare module 'JSONStream/test/issues' {
declare module.exports: any;
}
declare module 'JSONStream/test/keys' {
declare module.exports: any;
}
declare module 'JSONStream/test/map' {
declare module.exports: any;
}
declare module 'JSONStream/test/multiple_objects_error' {
declare module.exports: any;
}
declare module 'JSONStream/test/multiple_objects' {
declare module.exports: any;
}
declare module 'JSONStream/test/null' {
declare module.exports: any;
}
declare module 'JSONStream/test/parsejson' {
declare module.exports: any;
}
declare module 'JSONStream/test/stringify_object' {
declare module.exports: any;
}
declare module 'JSONStream/test/stringify' {
declare module.exports: any;
}
declare module 'JSONStream/test/test' {
declare module.exports: any;
}
declare module 'JSONStream/test/test2' {
declare module.exports: any;
}
declare module 'JSONStream/test/two-ways' {
declare module.exports: any;
}
// Filename aliases
declare module 'JSONStream/bin.js' {
declare module.exports: $Exports<'JSONStream/bin'>;
}
declare module 'JSONStream/examples/all_docs.js' {
declare module.exports: $Exports<'JSONStream/examples/all_docs'>;
}
declare module 'JSONStream/index' {
declare module.exports: $Exports<'JSONStream'>;
}
declare module 'JSONStream/index.js' {
declare module.exports: $Exports<'JSONStream'>;
}
declare module 'JSONStream/test/bool.js' {
declare module.exports: $Exports<'JSONStream/test/bool'>;
}
declare module 'JSONStream/test/browser.js' {
declare module.exports: $Exports<'JSONStream/test/browser'>;
}
declare module 'JSONStream/test/destroy_missing.js' {
declare module.exports: $Exports<'JSONStream/test/destroy_missing'>;
}
declare module 'JSONStream/test/disabled/doubledot1.js' {
declare module.exports: $Exports<'JSONStream/test/disabled/doubledot1'>;
}
declare module 'JSONStream/test/disabled/doubledot2.js' {
declare module.exports: $Exports<'JSONStream/test/disabled/doubledot2'>;
}
declare module 'JSONStream/test/empty.js' {
declare module.exports: $Exports<'JSONStream/test/empty'>;
}
declare module 'JSONStream/test/error_contents.js' {
declare module.exports: $Exports<'JSONStream/test/error_contents'>;
}
declare module 'JSONStream/test/fn.js' {
declare module.exports: $Exports<'JSONStream/test/fn'>;
}
declare module 'JSONStream/test/gen.js' {
declare module.exports: $Exports<'JSONStream/test/gen'>;
}
declare module 'JSONStream/test/header_footer.js' {
declare module.exports: $Exports<'JSONStream/test/header_footer'>;
}
declare module 'JSONStream/test/issues.js' {
declare module.exports: $Exports<'JSONStream/test/issues'>;
}
declare module 'JSONStream/test/keys.js' {
declare module.exports: $Exports<'JSONStream/test/keys'>;
}
declare module 'JSONStream/test/map.js' {
declare module.exports: $Exports<'JSONStream/test/map'>;
}
declare module 'JSONStream/test/multiple_objects_error.js' {
declare module.exports: $Exports<'JSONStream/test/multiple_objects_error'>;
}
declare module 'JSONStream/test/multiple_objects.js' {
declare module.exports: $Exports<'JSONStream/test/multiple_objects'>;
}
declare module 'JSONStream/test/null.js' {
declare module.exports: $Exports<'JSONStream/test/null'>;
}
declare module 'JSONStream/test/parsejson.js' {
declare module.exports: $Exports<'JSONStream/test/parsejson'>;
}
declare module 'JSONStream/test/stringify_object.js' {
declare module.exports: $Exports<'JSONStream/test/stringify_object'>;
}
declare module 'JSONStream/test/stringify.js' {
declare module.exports: $Exports<'JSONStream/test/stringify'>;
}
declare module 'JSONStream/test/test.js' {
declare module.exports: $Exports<'JSONStream/test/test'>;
}
declare module 'JSONStream/test/test2.js' {
declare module.exports: $Exports<'JSONStream/test/test2'>;
}
declare module 'JSONStream/test/two-ways.js' {
declare module.exports: $Exports<'JSONStream/test/two-ways'>;
}

@ -1,67 +0,0 @@
// flow-typed signature: b7109b7e394ff03ed211118d5af4cff8
// flow-typed version: <<STUB>>/asciidoctor.js_v1.5.6/flow_v0.69.0
/**
* This is an autogenerated libdef stub for:
*
* 'asciidoctor.js'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'asciidoctor.js' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'asciidoctor.js/dist/asciidoctor' {
declare module.exports: any;
}
declare module 'asciidoctor.js/dist/asciidoctor.min' {
declare module.exports: any;
}
declare module 'asciidoctor.js/dist/browser/asciidoctor' {
declare module.exports: any;
}
declare module 'asciidoctor.js/dist/nashorn/asciidoctor' {
declare module.exports: any;
}
declare module 'asciidoctor.js/dist/node/asciidoctor' {
declare module.exports: any;
}
declare module 'asciidoctor.js/dist/umd/asciidoctor' {
declare module.exports: any;
}
// Filename aliases
declare module 'asciidoctor.js/dist/asciidoctor.js' {
declare module.exports: $Exports<'asciidoctor.js/dist/asciidoctor'>;
}
declare module 'asciidoctor.js/dist/asciidoctor.min.js' {
declare module.exports: $Exports<'asciidoctor.js/dist/asciidoctor.min'>;
}
declare module 'asciidoctor.js/dist/browser/asciidoctor.js' {
declare module.exports: $Exports<'asciidoctor.js/dist/browser/asciidoctor'>;
}
declare module 'asciidoctor.js/dist/nashorn/asciidoctor.js' {
declare module.exports: $Exports<'asciidoctor.js/dist/nashorn/asciidoctor'>;
}
declare module 'asciidoctor.js/dist/node/asciidoctor.js' {
declare module.exports: $Exports<'asciidoctor.js/dist/node/asciidoctor'>;
}
declare module 'asciidoctor.js/dist/umd/asciidoctor.js' {
declare module.exports: $Exports<'asciidoctor.js/dist/umd/asciidoctor'>;
}

@ -1,913 +0,0 @@
// flow-typed signature: 9f4aa70155d93ad082ea38137cded473
// flow-typed version: <<STUB>>/async_v2.6.0/flow_v0.64.0
/**
* This is an autogenerated libdef stub for:
*
* 'async'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'async' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'async/all' {
declare module.exports: any;
}
declare module 'async/allLimit' {
declare module.exports: any;
}
declare module 'async/allSeries' {
declare module.exports: any;
}
declare module 'async/any' {
declare module.exports: any;
}
declare module 'async/anyLimit' {
declare module.exports: any;
}
declare module 'async/anySeries' {
declare module.exports: any;
}
declare module 'async/apply' {
declare module.exports: any;
}
declare module 'async/applyEach' {
declare module.exports: any;
}
declare module 'async/applyEachSeries' {
declare module.exports: any;
}
declare module 'async/asyncify' {
declare module.exports: any;
}
declare module 'async/auto' {
declare module.exports: any;
}
declare module 'async/autoInject' {
declare module.exports: any;
}
declare module 'async/cargo' {
declare module.exports: any;
}
declare module 'async/compose' {
declare module.exports: any;
}
declare module 'async/concat' {
declare module.exports: any;
}
declare module 'async/concatLimit' {
declare module.exports: any;
}
declare module 'async/concatSeries' {
declare module.exports: any;
}
declare module 'async/constant' {
declare module.exports: any;
}
declare module 'async/detect' {
declare module.exports: any;
}
declare module 'async/detectLimit' {
declare module.exports: any;
}
declare module 'async/detectSeries' {
declare module.exports: any;
}
declare module 'async/dir' {
declare module.exports: any;
}
declare module 'async/dist/async' {
declare module.exports: any;
}
declare module 'async/dist/async.min' {
declare module.exports: any;
}
declare module 'async/doDuring' {
declare module.exports: any;
}
declare module 'async/doUntil' {
declare module.exports: any;
}
declare module 'async/doWhilst' {
declare module.exports: any;
}
declare module 'async/during' {
declare module.exports: any;
}
declare module 'async/each' {
declare module.exports: any;
}
declare module 'async/eachLimit' {
declare module.exports: any;
}
declare module 'async/eachOf' {
declare module.exports: any;
}
declare module 'async/eachOfLimit' {
declare module.exports: any;
}
declare module 'async/eachOfSeries' {
declare module.exports: any;
}
declare module 'async/eachSeries' {
declare module.exports: any;
}
declare module 'async/ensureAsync' {
declare module.exports: any;
}
declare module 'async/every' {
declare module.exports: any;
}
declare module 'async/everyLimit' {
declare module.exports: any;
}
declare module 'async/everySeries' {
declare module.exports: any;
}
declare module 'async/filter' {
declare module.exports: any;
}
declare module 'async/filterLimit' {
declare module.exports: any;
}
declare module 'async/filterSeries' {
declare module.exports: any;
}
declare module 'async/find' {
declare module.exports: any;
}
declare module 'async/findLimit' {
declare module.exports: any;
}
declare module 'async/findSeries' {
declare module.exports: any;
}
declare module 'async/foldl' {
declare module.exports: any;
}
declare module 'async/foldr' {
declare module.exports: any;
}
declare module 'async/forEach' {
declare module.exports: any;
}
declare module 'async/forEachLimit' {
declare module.exports: any;
}
declare module 'async/forEachOf' {
declare module.exports: any;
}
declare module 'async/forEachOfLimit' {
declare module.exports: any;
}
declare module 'async/forEachOfSeries' {
declare module.exports: any;
}
declare module 'async/forEachSeries' {
declare module.exports: any;
}
declare module 'async/forever' {
declare module.exports: any;
}
declare module 'async/groupBy' {
declare module.exports: any;
}
declare module 'async/groupByLimit' {
declare module.exports: any;
}
declare module 'async/groupBySeries' {
declare module.exports: any;
}
declare module 'async/inject' {
declare module.exports: any;
}
declare module 'async/internal/applyEach' {
declare module.exports: any;
}
declare module 'async/internal/breakLoop' {
declare module.exports: any;
}
declare module 'async/internal/consoleFunc' {
declare module.exports: any;
}
declare module 'async/internal/createTester' {
declare module.exports: any;
}
declare module 'async/internal/doLimit' {
declare module.exports: any;
}
declare module 'async/internal/doParallel' {
declare module.exports: any;
}
declare module 'async/internal/doParallelLimit' {
declare module.exports: any;
}
declare module 'async/internal/DoublyLinkedList' {
declare module.exports: any;
}
declare module 'async/internal/eachOfLimit' {
declare module.exports: any;
}
declare module 'async/internal/filter' {
declare module.exports: any;
}
declare module 'async/internal/findGetResult' {
declare module.exports: any;
}
declare module 'async/internal/getIterator' {
declare module.exports: any;
}
declare module 'async/internal/initialParams' {
declare module.exports: any;
}
declare module 'async/internal/iterator' {
declare module.exports: any;
}
declare module 'async/internal/map' {
declare module.exports: any;
}
declare module 'async/internal/notId' {
declare module.exports: any;
}
declare module 'async/internal/once' {
declare module.exports: any;
}
declare module 'async/internal/onlyOnce' {
declare module.exports: any;
}
declare module 'async/internal/parallel' {
declare module.exports: any;
}
declare module 'async/internal/queue' {
declare module.exports: any;
}
declare module 'async/internal/reject' {
declare module.exports: any;
}
declare module 'async/internal/setImmediate' {
declare module.exports: any;
}
declare module 'async/internal/slice' {
declare module.exports: any;
}
declare module 'async/internal/withoutIndex' {
declare module.exports: any;
}
declare module 'async/internal/wrapAsync' {
declare module.exports: any;
}
declare module 'async/log' {
declare module.exports: any;
}
declare module 'async/map' {
declare module.exports: any;
}
declare module 'async/mapLimit' {
declare module.exports: any;
}
declare module 'async/mapSeries' {
declare module.exports: any;
}
declare module 'async/mapValues' {
declare module.exports: any;
}
declare module 'async/mapValuesLimit' {
declare module.exports: any;
}
declare module 'async/mapValuesSeries' {
declare module.exports: any;
}
declare module 'async/memoize' {
declare module.exports: any;
}
declare module 'async/nextTick' {
declare module.exports: any;
}
declare module 'async/parallel' {
declare module.exports: any;
}
declare module 'async/parallelLimit' {
declare module.exports: any;
}
declare module 'async/priorityQueue' {
declare module.exports: any;
}
declare module 'async/queue' {
declare module.exports: any;
}
declare module 'async/race' {
declare module.exports: any;
}
declare module 'async/reduce' {
declare module.exports: any;
}
declare module 'async/reduceRight' {
declare module.exports: any;
}
declare module 'async/reflect' {
declare module.exports: any;
}
declare module 'async/reflectAll' {
declare module.exports: any;
}
declare module 'async/reject' {
declare module.exports: any;
}
declare module 'async/rejectLimit' {
declare module.exports: any;
}
declare module 'async/rejectSeries' {
declare module.exports: any;
}
declare module 'async/retry' {
declare module.exports: any;
}
declare module 'async/retryable' {
declare module.exports: any;
}
declare module 'async/select' {
declare module.exports: any;
}
declare module 'async/selectLimit' {
declare module.exports: any;
}
declare module 'async/selectSeries' {
declare module.exports: any;
}
declare module 'async/seq' {
declare module.exports: any;
}
declare module 'async/series' {
declare module.exports: any;
}
declare module 'async/setImmediate' {
declare module.exports: any;
}
declare module 'async/some' {
declare module.exports: any;
}
declare module 'async/someLimit' {
declare module.exports: any;
}
declare module 'async/someSeries' {
declare module.exports: any;
}
declare module 'async/sortBy' {
declare module.exports: any;
}
declare module 'async/timeout' {
declare module.exports: any;
}
declare module 'async/times' {
declare module.exports: any;
}
declare module 'async/timesLimit' {
declare module.exports: any;
}
declare module 'async/timesSeries' {
declare module.exports: any;
}
declare module 'async/transform' {
declare module.exports: any;
}
declare module 'async/tryEach' {
declare module.exports: any;
}
declare module 'async/unmemoize' {
declare module.exports: any;
}
declare module 'async/until' {
declare module.exports: any;
}
declare module 'async/waterfall' {
declare module.exports: any;
}
declare module 'async/whilst' {
declare module.exports: any;
}
declare module 'async/wrapSync' {
declare module.exports: any;
}
// Filename aliases
declare module 'async/all.js' {
declare module.exports: $Exports<'async/all'>;
}
declare module 'async/allLimit.js' {
declare module.exports: $Exports<'async/allLimit'>;
}
declare module 'async/allSeries.js' {
declare module.exports: $Exports<'async/allSeries'>;
}
declare module 'async/any.js' {
declare module.exports: $Exports<'async/any'>;
}
declare module 'async/anyLimit.js' {
declare module.exports: $Exports<'async/anyLimit'>;
}
declare module 'async/anySeries.js' {
declare module.exports: $Exports<'async/anySeries'>;
}
declare module 'async/apply.js' {
declare module.exports: $Exports<'async/apply'>;
}
declare module 'async/applyEach.js' {
declare module.exports: $Exports<'async/applyEach'>;
}
declare module 'async/applyEachSeries.js' {
declare module.exports: $Exports<'async/applyEachSeries'>;
}
declare module 'async/asyncify.js' {
declare module.exports: $Exports<'async/asyncify'>;
}
declare module 'async/auto.js' {
declare module.exports: $Exports<'async/auto'>;
}
declare module 'async/autoInject.js' {
declare module.exports: $Exports<'async/autoInject'>;
}
declare module 'async/cargo.js' {
declare module.exports: $Exports<'async/cargo'>;
}
declare module 'async/compose.js' {
declare module.exports: $Exports<'async/compose'>;
}
declare module 'async/concat.js' {
declare module.exports: $Exports<'async/concat'>;
}
declare module 'async/concatLimit.js' {
declare module.exports: $Exports<'async/concatLimit'>;
}
declare module 'async/concatSeries.js' {
declare module.exports: $Exports<'async/concatSeries'>;
}
declare module 'async/constant.js' {
declare module.exports: $Exports<'async/constant'>;
}
declare module 'async/detect.js' {
declare module.exports: $Exports<'async/detect'>;
}
declare module 'async/detectLimit.js' {
declare module.exports: $Exports<'async/detectLimit'>;
}
declare module 'async/detectSeries.js' {
declare module.exports: $Exports<'async/detectSeries'>;
}
declare module 'async/dir.js' {
declare module.exports: $Exports<'async/dir'>;
}
declare module 'async/dist/async.js' {
declare module.exports: $Exports<'async/dist/async'>;
}
declare module 'async/dist/async.min.js' {
declare module.exports: $Exports<'async/dist/async.min'>;
}
declare module 'async/doDuring.js' {
declare module.exports: $Exports<'async/doDuring'>;
}
declare module 'async/doUntil.js' {
declare module.exports: $Exports<'async/doUntil'>;
}
declare module 'async/doWhilst.js' {
declare module.exports: $Exports<'async/doWhilst'>;
}
declare module 'async/during.js' {
declare module.exports: $Exports<'async/during'>;
}
declare module 'async/each.js' {
declare module.exports: $Exports<'async/each'>;
}
declare module 'async/eachLimit.js' {
declare module.exports: $Exports<'async/eachLimit'>;
}
declare module 'async/eachOf.js' {
declare module.exports: $Exports<'async/eachOf'>;
}
declare module 'async/eachOfLimit.js' {
declare module.exports: $Exports<'async/eachOfLimit'>;
}
declare module 'async/eachOfSeries.js' {
declare module.exports: $Exports<'async/eachOfSeries'>;
}
declare module 'async/eachSeries.js' {
declare module.exports: $Exports<'async/eachSeries'>;
}
declare module 'async/ensureAsync.js' {
declare module.exports: $Exports<'async/ensureAsync'>;
}
declare module 'async/every.js' {
declare module.exports: $Exports<'async/every'>;
}
declare module 'async/everyLimit.js' {
declare module.exports: $Exports<'async/everyLimit'>;
}
declare module 'async/everySeries.js' {
declare module.exports: $Exports<'async/everySeries'>;
}
declare module 'async/filter.js' {
declare module.exports: $Exports<'async/filter'>;
}
declare module 'async/filterLimit.js' {
declare module.exports: $Exports<'async/filterLimit'>;
}
declare module 'async/filterSeries.js' {
declare module.exports: $Exports<'async/filterSeries'>;
}
declare module 'async/find.js' {
declare module.exports: $Exports<'async/find'>;
}
declare module 'async/findLimit.js' {
declare module.exports: $Exports<'async/findLimit'>;
}
declare module 'async/findSeries.js' {
declare module.exports: $Exports<'async/findSeries'>;
}
declare module 'async/foldl.js' {
declare module.exports: $Exports<'async/foldl'>;
}
declare module 'async/foldr.js' {
declare module.exports: $Exports<'async/foldr'>;
}
declare module 'async/forEach.js' {
declare module.exports: $Exports<'async/forEach'>;
}
declare module 'async/forEachLimit.js' {
declare module.exports: $Exports<'async/forEachLimit'>;
}
declare module 'async/forEachOf.js' {
declare module.exports: $Exports<'async/forEachOf'>;
}
declare module 'async/forEachOfLimit.js' {
declare module.exports: $Exports<'async/forEachOfLimit'>;
}
declare module 'async/forEachOfSeries.js' {
declare module.exports: $Exports<'async/forEachOfSeries'>;
}
declare module 'async/forEachSeries.js' {
declare module.exports: $Exports<'async/forEachSeries'>;
}
declare module 'async/forever.js' {
declare module.exports: $Exports<'async/forever'>;
}
declare module 'async/groupBy.js' {
declare module.exports: $Exports<'async/groupBy'>;
}
declare module 'async/groupByLimit.js' {
declare module.exports: $Exports<'async/groupByLimit'>;
}
declare module 'async/groupBySeries.js' {
declare module.exports: $Exports<'async/groupBySeries'>;
}
declare module 'async/index' {
declare module.exports: $Exports<'async'>;
}
declare module 'async/index.js' {
declare module.exports: $Exports<'async'>;
}
declare module 'async/inject.js' {
declare module.exports: $Exports<'async/inject'>;
}
declare module 'async/internal/applyEach.js' {
declare module.exports: $Exports<'async/internal/applyEach'>;
}
declare module 'async/internal/breakLoop.js' {
declare module.exports: $Exports<'async/internal/breakLoop'>;
}
declare module 'async/internal/consoleFunc.js' {
declare module.exports: $Exports<'async/internal/consoleFunc'>;
}
declare module 'async/internal/createTester.js' {
declare module.exports: $Exports<'async/internal/createTester'>;
}
declare module 'async/internal/doLimit.js' {
declare module.exports: $Exports<'async/internal/doLimit'>;
}
declare module 'async/internal/doParallel.js' {
declare module.exports: $Exports<'async/internal/doParallel'>;
}
declare module 'async/internal/doParallelLimit.js' {
declare module.exports: $Exports<'async/internal/doParallelLimit'>;
}
declare module 'async/internal/DoublyLinkedList.js' {
declare module.exports: $Exports<'async/internal/DoublyLinkedList'>;
}
declare module 'async/internal/eachOfLimit.js' {
declare module.exports: $Exports<'async/internal/eachOfLimit'>;
}
declare module 'async/internal/filter.js' {
declare module.exports: $Exports<'async/internal/filter'>;
}
declare module 'async/internal/findGetResult.js' {
declare module.exports: $Exports<'async/internal/findGetResult'>;
}
declare module 'async/internal/getIterator.js' {
declare module.exports: $Exports<'async/internal/getIterator'>;
}
declare module 'async/internal/initialParams.js' {
declare module.exports: $Exports<'async/internal/initialParams'>;
}
declare module 'async/internal/iterator.js' {
declare module.exports: $Exports<'async/internal/iterator'>;
}
declare module 'async/internal/map.js' {
declare module.exports: $Exports<'async/internal/map'>;
}
declare module 'async/internal/notId.js' {
declare module.exports: $Exports<'async/internal/notId'>;
}
declare module 'async/internal/once.js' {
declare module.exports: $Exports<'async/internal/once'>;
}
declare module 'async/internal/onlyOnce.js' {
declare module.exports: $Exports<'async/internal/onlyOnce'>;
}
declare module 'async/internal/parallel.js' {
declare module.exports: $Exports<'async/internal/parallel'>;
}
declare module 'async/internal/queue.js' {
declare module.exports: $Exports<'async/internal/queue'>;
}
declare module 'async/internal/reject.js' {
declare module.exports: $Exports<'async/internal/reject'>;
}
declare module 'async/internal/setImmediate.js' {
declare module.exports: $Exports<'async/internal/setImmediate'>;
}
declare module 'async/internal/slice.js' {
declare module.exports: $Exports<'async/internal/slice'>;
}
declare module 'async/internal/withoutIndex.js' {
declare module.exports: $Exports<'async/internal/withoutIndex'>;
}
declare module 'async/internal/wrapAsync.js' {
declare module.exports: $Exports<'async/internal/wrapAsync'>;
}
declare module 'async/log.js' {
declare module.exports: $Exports<'async/log'>;
}
declare module 'async/map.js' {
declare module.exports: $Exports<'async/map'>;
}
declare module 'async/mapLimit.js' {
declare module.exports: $Exports<'async/mapLimit'>;
}
declare module 'async/mapSeries.js' {
declare module.exports: $Exports<'async/mapSeries'>;
}
declare module 'async/mapValues.js' {
declare module.exports: $Exports<'async/mapValues'>;
}
declare module 'async/mapValuesLimit.js' {
declare module.exports: $Exports<'async/mapValuesLimit'>;
}
declare module 'async/mapValuesSeries.js' {
declare module.exports: $Exports<'async/mapValuesSeries'>;
}
declare module 'async/memoize.js' {
declare module.exports: $Exports<'async/memoize'>;
}
declare module 'async/nextTick.js' {
declare module.exports: $Exports<'async/nextTick'>;
}
declare module 'async/parallel.js' {
declare module.exports: $Exports<'async/parallel'>;
}
declare module 'async/parallelLimit.js' {
declare module.exports: $Exports<'async/parallelLimit'>;
}
declare module 'async/priorityQueue.js' {
declare module.exports: $Exports<'async/priorityQueue'>;
}
declare module 'async/queue.js' {
declare module.exports: $Exports<'async/queue'>;
}
declare module 'async/race.js' {
declare module.exports: $Exports<'async/race'>;
}
declare module 'async/reduce.js' {
declare module.exports: $Exports<'async/reduce'>;
}
declare module 'async/reduceRight.js' {
declare module.exports: $Exports<'async/reduceRight'>;
}
declare module 'async/reflect.js' {
declare module.exports: $Exports<'async/reflect'>;
}
declare module 'async/reflectAll.js' {
declare module.exports: $Exports<'async/reflectAll'>;
}
declare module 'async/reject.js' {
declare module.exports: $Exports<'async/reject'>;
}
declare module 'async/rejectLimit.js' {
declare module.exports: $Exports<'async/rejectLimit'>;
}
declare module 'async/rejectSeries.js' {
declare module.exports: $Exports<'async/rejectSeries'>;
}
declare module 'async/retry.js' {
declare module.exports: $Exports<'async/retry'>;
}
declare module 'async/retryable.js' {
declare module.exports: $Exports<'async/retryable'>;
}
declare module 'async/select.js' {
declare module.exports: $Exports<'async/select'>;
}
declare module 'async/selectLimit.js' {
declare module.exports: $Exports<'async/selectLimit'>;
}
declare module 'async/selectSeries.js' {
declare module.exports: $Exports<'async/selectSeries'>;
}
declare module 'async/seq.js' {
declare module.exports: $Exports<'async/seq'>;
}
declare module 'async/series.js' {
declare module.exports: $Exports<'async/series'>;
}
declare module 'async/setImmediate.js' {
declare module.exports: $Exports<'async/setImmediate'>;
}
declare module 'async/some.js' {
declare module.exports: $Exports<'async/some'>;
}
declare module 'async/someLimit.js' {
declare module.exports: $Exports<'async/someLimit'>;
}
declare module 'async/someSeries.js' {
declare module.exports: $Exports<'async/someSeries'>;
}
declare module 'async/sortBy.js' {
declare module.exports: $Exports<'async/sortBy'>;
}
declare module 'async/timeout.js' {
declare module.exports: $Exports<'async/timeout'>;
}
declare module 'async/times.js' {
declare module.exports: $Exports<'async/times'>;
}
declare module 'async/timesLimit.js' {
declare module.exports: $Exports<'async/timesLimit'>;
}
declare module 'async/timesSeries.js' {
declare module.exports: $Exports<'async/timesSeries'>;
}
declare module 'async/transform.js' {
declare module.exports: $Exports<'async/transform'>;
}
declare module 'async/tryEach.js' {
declare module.exports: $Exports<'async/tryEach'>;
}
declare module 'async/unmemoize.js' {
declare module.exports: $Exports<'async/unmemoize'>;
}
declare module 'async/until.js' {
declare module.exports: $Exports<'async/until'>;
}
declare module 'async/waterfall.js' {
declare module.exports: $Exports<'async/waterfall'>;
}
declare module 'async/whilst.js' {
declare module.exports: $Exports<'async/whilst'>;
}
declare module 'async/wrapSync.js' {
declare module.exports: $Exports<'async/wrapSync'>;
}

@ -1,33 +0,0 @@
// flow-typed signature: f4ce515b9395f4f0279d388b18ef59b5
// flow-typed version: <<STUB>>/autosuggest-highlight/match_v3.1.1/flow_v0.81.0
/**
* This is an autogenerated libdef stub for:
*
* 'autosuggest-highlight/match'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'autosuggest-highlight/match' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
// Filename aliases
declare module 'autosuggest-highlight/match/index' {
declare module.exports: $Exports<'autosuggest-highlight/match'>;
}
declare module 'autosuggest-highlight/match/index.js' {
declare module.exports: $Exports<'autosuggest-highlight/match'>;
}

@ -1,33 +0,0 @@
// flow-typed signature: 7df3e3914baffd57187e87617a708990
// flow-typed version: <<STUB>>/autosuggest-highlight/parse_v3.1.1/flow_v0.81.0
/**
* This is an autogenerated libdef stub for:
*
* 'autosuggest-highlight/parse'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'autosuggest-highlight/parse' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
// Filename aliases
declare module 'autosuggest-highlight/parse/index' {
declare module.exports: $Exports<'autosuggest-highlight/parse'>;
}
declare module 'autosuggest-highlight/parse/index.js' {
declare module.exports: $Exports<'autosuggest-highlight/parse'>;
}

@ -1,46 +0,0 @@
// flow-typed signature: bac0ee66e0653772d037dc47b51a5e1f
// flow-typed version: da30fe6876/body-parser_v1.x.x/flow_>=v0.25.x
import type { Middleware, $Request, $Response } from "express";
declare type bodyParser$Options = {
inflate?: boolean,
limit?: number | string,
type?: string | string[] | ((req: $Request) => any),
verify?: (
req: $Request,
res: $Response,
buf: Buffer,
encoding: string
) => void
};
declare type bodyParser$OptionsText = bodyParser$Options & {
reviver?: (key: string, value: any) => any,
strict?: boolean
};
declare type bodyParser$OptionsJson = bodyParser$Options & {
reviver?: (key: string, value: any) => any,
strict?: boolean
};
declare type bodyParser$OptionsUrlencoded = bodyParser$Options & {
extended?: boolean,
parameterLimit?: number
};
declare module "body-parser" {
declare type Options = bodyParser$Options;
declare type OptionsText = bodyParser$OptionsText;
declare type OptionsJson = bodyParser$OptionsJson;
declare type OptionsUrlencoded = bodyParser$OptionsUrlencoded;
declare function json(options?: OptionsJson): Middleware;
declare function raw(options?: Options): Middleware;
declare function text(options?: OptionsText): Middleware;
declare function urlencoded(options?: OptionsUrlencoded): Middleware;
}

@ -1,156 +0,0 @@
// flow-typed signature: b3827b7e37fa457f58d7a6656d830369
// flow-typed version: da30fe6876/bunyan_v1.x.x/flow_>=v0.25.x
declare module "bunyan" {
declare var TRACE: 10;
declare var DEBUG: 20;
declare var INFO: 30;
declare var WARN: 40;
declare var ERROR: 50;
declare var FATAL: 60;
declare type BunyanLogLevels =
| 60 // fatal
| 50 // error
| 40 // warn
| 30 // info
| 20 // debug
| 10; // info
declare type BunyanRecord = {
v: number,
level: BunyanLogLevels,
name: string,
hostname: string,
pid: string,
time: Date,
msg: string,
src: string,
err?: {
message: string,
name: string,
code: any,
signal: any,
stack: string
},
[key: string]: any
};
declare type Writable = {
write(rec: BunyanRecord): void
};
declare class Logger extends events$EventEmitter {
constructor(options: LoggerOptions): any;
addStream(stream: Stream): void;
addSerializers(serializers: Serializers): void;
child(opts?: LoggerOptions, simple?: boolean): Logger;
reopenFileStreams(): void;
level(): string | number;
level(value: number | string): void;
levels(name: number | string, value: number | string): void;
trace(...params: Array<void>): boolean;
trace(error: Error, format?: any, ...params: Array<any>): void;
trace(buffer: Buffer, format?: any, ...params: Array<any>): void;
trace(obj: Object, format?: any, ...params: Array<any>): void;
trace(format: string, ...params: Array<any>): void;
debug(...params: Array<void>): boolean;
debug(error: Error, format?: any, ...params: Array<any>): void;
debug(buffer: Buffer, format?: any, ...params: Array<any>): void;
debug(obj: Object, format?: any, ...params: Array<any>): void;
debug(format: string, ...params: Array<any>): void;
info(...params: Array<void>): boolean;
info(error: Error, format?: any, ...params: Array<any>): void;
info(buffer: Buffer, format?: any, ...params: Array<any>): void;
info(obj: Object, format?: any, ...params: Array<any>): void;
info(format: string, ...params: Array<any>): void;
warn(...params: Array<void>): boolean;
warn(error: Error, format?: any, ...params: Array<any>): void;
warn(buffer: Buffer, format?: any, ...params: Array<any>): void;
warn(obj: Object, format?: any, ...params: Array<any>): void;
warn(format: string, ...params: Array<any>): void;
error(...params: Array<void>): boolean;
error(error: Error, format?: any, ...params: Array<any>): void;
error(buffer: Buffer, format?: any, ...params: Array<any>): void;
error(obj: Object, format?: any, ...params: Array<any>): void;
error(format: string, ...params: Array<any>): void;
fatal(...params: Array<void>): boolean;
fatal(error: Error, format?: any, ...params: Array<any>): void;
fatal(buffer: Buffer, format?: any, ...params: Array<any>): void;
fatal(obj: Object, format?: any, ...params: Array<any>): void;
fatal(format: string, ...params: Array<any>): void;
static stdSerializers: {
req: (
req: http$ClientRequest
) => {
method: string,
url: string,
headers: mixed,
remoteAddress: string,
remotePort: number
},
res: (
res: http$IncomingMessage
) => { statusCode: number, header: string },
err: (
err: Error
) => {
message: string,
name: string,
stack: string,
code: string,
signal: string
}
};
}
declare interface LoggerOptions {
streams?: Array<Stream>;
level?: BunyanLogLevels | string;
stream?: stream$Writable;
serializers?: Serializers;
src?: boolean;
}
declare type Serializers = {
[key: string]: (input: any) => mixed
};
declare type Stream = {
type?: string,
level?: number | string,
path?: string,
stream?: stream$Writable | tty$WriteStream | Stream | Writable,
closeOnExit?: boolean,
period?: string,
count?: number
};
declare var stdSerializers: Serializers;
declare function resolveLevel(value: number | string): number;
declare function createLogger(
options: LoggerOptions & { name: string }
): Logger;
declare class RingBuffer extends events$EventEmitter {
constructor(options: RingBufferOptions): any;
writable: boolean;
records: Array<any>;
write(record: BunyanRecord): void;
end(record?: any): void;
destroy(): void;
destroySoon(): void;
}
declare interface RingBufferOptions {
limit: number;
}
declare function safeCycles(): (key: string, value: any) => any;
declare class ConsoleRawStream {
write(rec: BunyanRecord): void;
}
declare var levelFromName: {
trace: typeof TRACE,
debug: typeof DEBUG,
info: typeof INFO,
warn: typeof WARN,
error: typeof ERROR,
fatal: typeof FATAL
};
declare var nameFromLevel: {
[key: BunyanLogLevels]: string
};
declare var VERSION: string;
declare var LOG_VERSION: string;
}

@ -1,281 +0,0 @@
// flow-typed signature: 9a1fb3feac221b50aab621209bf8ca9c
// flow-typed version: 94e9f7e0a4/commander_v2.x.x/flow_>=v0.28.x
declare module "commander" {
declare class Command extends events$EventEmitter {
/**
* Initialize a new `Command`.
*
* @param {String} name
* @api public
*/
constructor(name?: string): Command;
/**
* Add command `name`.
*
* The `.action()` callback is invoked when the
* command `name` is specified via __ARGV__,
* and the remaining arguments are applied to the
* function for access.
*
* When the `name` is "*" an un-matched command
* will be passed as the first arg, followed by
* the rest of __ARGV__ remaining.
*
* Examples:
*
* program
* .version('0.0.1')
* .option('-C, --chdir <path>', 'change the working directory')
* .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
* .option('-T, --no-tests', 'ignore test hook')
*
* program
* .command('setup')
* .description('run remote setup commands')
* .action(function(){
* console.log('setup');
* });
*
* program
* .command('exec <cmd>')
* .description('run the given remote command')
* .action(function(cmd){
* console.log('exec "%s"', cmd);
* });
*
* program
* .command('*')
* .description('deploy the given env')
* .action(function(env){
* console.log('deploying "%s"', env);
* });
*
* program.parse(process.argv);
*
* @param {String} name
* @param {String} [desc]
* @param {Mixed} [opts]
* @return {Command} the new command
* @api public
*/
command(
name: string,
desc?: string,
opts?: { isDefault: boolean, noHelp: boolean }
): Command;
/**
* Parse expected `args`.
*
* For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`.
*
* @param {Array} args
* @return {Command} for chaining
* @api public
*/
parseExpectedArgs(args: Array<string>): this;
/**
* Register callback `fn` for the command.
*
* Examples:
*
* program
* .command('help')
* .description('display verbose help')
* .action(function(){
* // output help here
* });
*
* @param {Function} fn
* @return {Command} for chaining
* @api public
*/
action(fn: (...args: Array<any>) => mixed): this;
/**
* Define option with `flags`, `description` and optional
* coercion `fn`.
*
* The `flags` string should contain both the short and long flags,
* separated by comma, a pipe or space. The following are all valid
* all will output this way when `--help` is used.
*
* "-p, --pepper"
* "-p|--pepper"
* "-p --pepper"
*
* Examples:
*
* // simple boolean defaulting to false
* program.option('-p, --pepper', 'add pepper');
*
* --pepper
* program.pepper
* // => Boolean
*
* // simple boolean defaulting to true
* program.option('-C, --no-cheese', 'remove cheese');
*
* program.cheese
* // => true
*
* --no-cheese
* program.cheese
* // => false
*
* // required argument
* program.option('-C, --chdir <path>', 'change the working directory');
*
* --chdir /tmp
* program.chdir
* // => "/tmp"
*
* // optional argument
* program.option('-c, --cheese [type]', 'add cheese [marble]');
*
* @param {String} flags
* @param {String} description
* @param {Function|Mixed} fn or default
* @param {Mixed} defaultValue
* @return {Command} for chaining
* @api public
*/
option(flags: string, description?: string, fn?: ((val: any, memo: any) => mixed) | RegExp, defaultValue?: mixed): this;
option(flags: string, description?: string, defaultValue?: mixed): this;
/**
* Allow unknown options on the command line.
*
* @param {Boolean} arg if `true` or omitted, no error will be thrown
* for unknown options.
* @api public
*/
allowUnknownOption(arg?: boolean): this;
/**
* Parse `argv`, settings options and invoking commands when defined.
*
* @param {Array} argv
* @return {Command} for chaining
* @api public
*/
parse(argv: Array<string>): this;
/**
* Parse options from `argv` returning `argv`
* void of these options.
*
* @param {Array} argv
* @return {Array}
* @api public
*/
parseOptions(argv: Array<string>): { args: Array<string>, unknown: Array<string> };
/**
* Define argument syntax for the top-level command.
*
* @api public
*/
arguments(desc: string): this;
/**
* Return an object containing options as key-value pairs
*
* @return {Object}
* @api public
*/
opts(): { [key: string]: any };
/**
* Set the program version to `str`.
*
* This method auto-registers the "-V, --version" flag
* which will print the version number when passed.
*
* @param {String} str
* @param {String} flags
* @return {Command} for chaining
* @api public
*/
version(str: string, flags?: string): this;
/**
* Set the description to `str`.
*
* @param {String} str
* @return {String|Command}
* @api public
*/
description(str: string): this;
description(): string;
/**
* Set an alias for the command
*
* @param {String} alias
* @return {String|Command}
* @api public
*/
alias(alias: string): this;
alias(): string;
/**
* Set / get the command usage `str`.
*
* @param {String} str
* @return {String|Command}
* @api public
*/
usage(str: string): this;
usage(): string;
/**
* Get the name of the command
*
* @param {String} name
* @return {String|Command}
* @api public
*/
name(): string;
/**
* Output help information for this command
*
* @api public
*/
outputHelp(): void;
/**
* Output help information and exit.
*
* @api public
*/
help(): void;
}
declare class Option {
/**
* Initialize a new `Option` with the given `flags` and `description`.
*
* @param {String} flags
* @param {String} description
* @api public
*/
constructor(flags: string, description?: string): Option;
flags: string;
required: boolean;
optional: boolean;
bool: boolean;
short?: string;
long: string;
description: string;
}
declare module.exports: Command & {
Command: Command,
Option: Option
};
}

@ -1,33 +0,0 @@
// flow-typed signature: 80c21b4a25778a0faefd532204b78050
// flow-typed version: <<STUB>>/compression_v1.7.2/flow_v0.67.1
/**
* This is an autogenerated libdef stub for:
*
* 'compression'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'compression' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
// Filename aliases
declare module 'compression/index' {
declare module.exports: $Exports<'compression'>;
}
declare module 'compression/index.js' {
declare module.exports: $Exports<'compression'>;
}

@ -1,33 +0,0 @@
// flow-typed signature: dd32612579acfe0d3fb825468a81fc4a
// flow-typed version: <<STUB>>/cookies_v0.7.1/flow_v0.64.0
/**
* This is an autogenerated libdef stub for:
*
* 'cookies'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'cookies' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
// Filename aliases
declare module 'cookies/index' {
declare module.exports: $Exports<'cookies'>;
}
declare module 'cookies/index.js' {
declare module.exports: $Exports<'cookies'>;
}

@ -1,88 +0,0 @@
// flow-typed signature: d369e8a6411b1ce4fcd5339b6d41e441
// flow-typed version: <<STUB>>/cors_v2.8.4/flow_v0.67.1
/**
* This is an autogenerated libdef stub for:
*
* 'cors'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'cors' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'cors/lib/index' {
declare module.exports: any;
}
declare module 'cors/test/basic-auth' {
declare module.exports: any;
}
declare module 'cors/test/body-events' {
declare module.exports: any;
}
declare module 'cors/test/cors' {
declare module.exports: any;
}
declare module 'cors/test/error-response' {
declare module.exports: any;
}
declare module 'cors/test/example-app' {
declare module.exports: any;
}
declare module 'cors/test/issue-2' {
declare module.exports: any;
}
declare module 'cors/test/issue-31' {
declare module.exports: any;
}
declare module 'cors/test/support/env' {
declare module.exports: any;
}
// Filename aliases
declare module 'cors/lib/index.js' {
declare module.exports: $Exports<'cors/lib/index'>;
}
declare module 'cors/test/basic-auth.js' {
declare module.exports: $Exports<'cors/test/basic-auth'>;
}
declare module 'cors/test/body-events.js' {
declare module.exports: $Exports<'cors/test/body-events'>;
}
declare module 'cors/test/cors.js' {
declare module.exports: $Exports<'cors/test/cors'>;
}
declare module 'cors/test/error-response.js' {
declare module.exports: $Exports<'cors/test/error-response'>;
}
declare module 'cors/test/example-app.js' {
declare module.exports: $Exports<'cors/test/example-app'>;
}
declare module 'cors/test/issue-2.js' {
declare module.exports: $Exports<'cors/test/issue-2'>;
}
declare module 'cors/test/issue-31.js' {
declare module.exports: $Exports<'cors/test/issue-31'>;
}
declare module 'cors/test/support/env.js' {
declare module.exports: $Exports<'cors/test/support/env'>;
}

@ -1,127 +0,0 @@
// flow-typed signature: 02db3523747059d89e87d4dec6873edf
// flow-typed version: 62a0c60689/enzyme_v3.x.x/flow_>=v0.53.x
import * as React from "react";
declare module "enzyme" {
declare type PredicateFunction<T: Wrapper> = (
wrapper: T,
index: number
) => boolean;
declare type NodeOrNodes = React.Node | Array<React.Node>;
declare type EnzymeSelector = string | Class<React.Component<*, *>> | Object;
// CheerioWrapper is a type alias for an actual cheerio instance
// TODO: Reference correct type from cheerio's type declarations
declare type CheerioWrapper = any;
declare class Wrapper {
find(selector: EnzymeSelector): this,
findWhere(predicate: PredicateFunction<this>): this,
filter(selector: EnzymeSelector): this,
filterWhere(predicate: PredicateFunction<this>): this,
hostNodes(): this,
contains(nodeOrNodes: NodeOrNodes): boolean,
containsMatchingElement(node: React.Node): boolean,
containsAllMatchingElements(nodes: NodeOrNodes): boolean,
containsAnyMatchingElements(nodes: NodeOrNodes): boolean,
dive(option?: { context?: Object }): this,
exists(): boolean,
isEmptyRender(): boolean,
matchesElement(node: React.Node): boolean,
hasClass(className: string): boolean,
is(selector: EnzymeSelector): boolean,
isEmpty(): boolean,
not(selector: EnzymeSelector): this,
children(selector?: EnzymeSelector): this,
childAt(index: number): this,
parents(selector?: EnzymeSelector): this,
parent(): this,
closest(selector: EnzymeSelector): this,
render(): CheerioWrapper,
unmount(): this,
text(): string,
html(): string,
get(index: number): React.Node,
getNodes(): Array<React.Node>,
getDOMNode(): HTMLElement | HTMLInputElement,
at(index: number): this,
first(): this,
last(): this,
state(key?: string): any,
context(key?: string): any,
props(): Object,
prop(key: string): any,
key(): string,
simulate(event: string, ...args: Array<any>): this,
setState(state: {}, callback?: Function): this,
setProps(props: {}): this,
setContext(context: Object): this,
instance(): React.Component<*, *>,
update(): this,
debug(): string,
type(): string | Function | null,
name(): string,
forEach(fn: (node: this, index: number) => mixed): this,
map<T>(fn: (node: this, index: number) => T): Array<T>,
reduce<T>(
fn: (value: T, node: this, index: number) => T,
initialValue?: T
): Array<T>,
reduceRight<T>(
fn: (value: T, node: this, index: number) => T,
initialValue?: T
): Array<T>,
some(selector: EnzymeSelector): boolean,
someWhere(predicate: PredicateFunction<this>): boolean,
every(selector: EnzymeSelector): boolean,
everyWhere(predicate: PredicateFunction<this>): boolean,
length: number
}
declare class ReactWrapper extends Wrapper {
constructor(nodes: NodeOrNodes, root: any, options?: ?Object): ReactWrapper,
mount(): this,
ref(refName: string): this,
detach(): void
}
declare class ShallowWrapper extends Wrapper {
constructor(
nodes: NodeOrNodes,
root: any,
options?: ?Object
): ShallowWrapper,
equals(node: React.Node): boolean,
shallow(options?: { context?: Object }): ShallowWrapper
}
declare function shallow(
node: React.Node,
options?: { context?: Object, disableLifecycleMethods?: boolean }
): ShallowWrapper;
declare function mount(
node: React.Node,
options?: {
context?: Object,
attachTo?: HTMLElement,
childContextTypes?: Object
}
): ReactWrapper;
declare function render(
node: React.Node,
options?: { context?: Object }
): CheerioWrapper;
declare module.exports: {
configure(options: {
Adapter?: any,
disableLifecycleMethods?: boolean
}): void,
render: typeof render,
mount: typeof mount,
shallow: typeof shallow,
ShallowWrapper: typeof ShallowWrapper,
ReactWrapper: typeof ReactWrapper
};
}

@ -1,304 +0,0 @@
// flow-typed signature: cc24a4e737d9dfb8e1381c3bd4ebaa65
// flow-typed version: d11eab7bb5/express_v4.16.x/flow_>=v0.32.x
import type { Server } from "http";
import type { Socket } from "net";
declare type express$RouterOptions = {
caseSensitive?: boolean,
mergeParams?: boolean,
strict?: boolean
};
declare class express$RequestResponseBase {
app: express$Application;
get(field: string): string | void;
}
declare type express$RequestParams = {
[param: string]: string
};
declare class express$Request extends http$IncomingMessage mixins express$RequestResponseBase {
baseUrl: string;
body: mixed;
cookies: { [cookie: string]: string };
connection: Socket;
fresh: boolean;
hostname: string;
ip: string;
ips: Array<string>;
method: string;
originalUrl: string;
params: express$RequestParams;
path: string;
protocol: "https" | "http";
query: { [name: string]: string | Array<string> };
route: string;
secure: boolean;
signedCookies: { [signedCookie: string]: string };
stale: boolean;
subdomains: Array<string>;
xhr: boolean;
accepts(types: string): string | false;
accepts(types: Array<string>): string | false;
acceptsCharsets(...charsets: Array<string>): string | false;
acceptsEncodings(...encoding: Array<string>): string | false;
acceptsLanguages(...lang: Array<string>): string | false;
header(field: string): string | void;
is(type: string): boolean;
param(name: string, defaultValue?: string): string | void;
}
declare type express$CookieOptions = {
domain?: string,
encode?: (value: string) => string,
expires?: Date,
httpOnly?: boolean,
maxAge?: number,
path?: string,
secure?: boolean,
signed?: boolean
};
declare type express$Path = string | RegExp;
declare type express$RenderCallback = (
err: Error | null,
html?: string
) => mixed;
declare type express$SendFileOptions = {
maxAge?: number,
root?: string,
lastModified?: boolean,
headers?: { [name: string]: string },
dotfiles?: "allow" | "deny" | "ignore"
};
declare class express$Response extends http$ServerResponse mixins express$RequestResponseBase {
headersSent: boolean;
locals: { [name: string]: mixed };
append(field: string, value?: string): this;
attachment(filename?: string): this;
cookie(name: string, value: string, options?: express$CookieOptions): this;
clearCookie(name: string, options?: express$CookieOptions): this;
download(
path: string,
filename?: string,
callback?: (err?: ?Error) => void
): this;
format(typesObject: { [type: string]: Function }): this;
json(body?: mixed): this;
jsonp(body?: mixed): this;
links(links: { [name: string]: string }): this;
location(path: string): this;
redirect(url: string, ...args: Array<void>): this;
redirect(status: number, url: string, ...args: Array<void>): this;
render(
view: string,
locals?: { [name: string]: mixed },
callback?: express$RenderCallback
): this;
send(body?: mixed): this;
sendFile(
path: string,
options?: express$SendFileOptions,
callback?: (err?: ?Error) => mixed
): this;
sendStatus(statusCode: number): this;
header(field: string, value?: string): this;
header(headers: { [name: string]: string }): this;
set(field: string, value?: string | string[]): this;
set(headers: { [name: string]: string }): this;
status(statusCode: number): this;
type(type: string): this;
vary(field: string): this;
req: express$Request;
}
declare type express$NextFunction = (err?: ?Error | "route") => mixed;
declare type express$Middleware =
| ((
req: $Subtype<express$Request>,
res: express$Response,
next: express$NextFunction
) => mixed)
| ((
error: Error,
req: $Subtype<express$Request>,
res: express$Response,
next: express$NextFunction
) => mixed);
declare interface express$RouteMethodType<T> {
(middleware: express$Middleware): T;
(...middleware: Array<express$Middleware>): T;
(
path: express$Path | express$Path[],
...middleware: Array<express$Middleware>
): T;
}
declare class express$Route {
all: express$RouteMethodType<this>;
get: express$RouteMethodType<this>;
post: express$RouteMethodType<this>;
put: express$RouteMethodType<this>;
head: express$RouteMethodType<this>;
delete: express$RouteMethodType<this>;
options: express$RouteMethodType<this>;
trace: express$RouteMethodType<this>;
copy: express$RouteMethodType<this>;
lock: express$RouteMethodType<this>;
mkcol: express$RouteMethodType<this>;
move: express$RouteMethodType<this>;
purge: express$RouteMethodType<this>;
propfind: express$RouteMethodType<this>;
proppatch: express$RouteMethodType<this>;
unlock: express$RouteMethodType<this>;
report: express$RouteMethodType<this>;
mkactivity: express$RouteMethodType<this>;
checkout: express$RouteMethodType<this>;
merge: express$RouteMethodType<this>;
// @TODO Missing 'm-search' but get flow illegal name error.
notify: express$RouteMethodType<this>;
subscribe: express$RouteMethodType<this>;
unsubscribe: express$RouteMethodType<this>;
patch: express$RouteMethodType<this>;
search: express$RouteMethodType<this>;
connect: express$RouteMethodType<this>;
}
declare class express$Router extends express$Route {
constructor(options?: express$RouterOptions): void;
route(path: string): express$Route;
static (options?: express$RouterOptions): express$Router;
use(middleware: express$Middleware): this;
use(...middleware: Array<express$Middleware>): this;
use(
path: express$Path | express$Path[],
...middleware: Array<express$Middleware>
): this;
use(path: string, router: express$Router): this;
handle(
req: http$IncomingMessage,
res: http$ServerResponse,
next: express$NextFunction
): void;
param(
param: string,
callback: (
req: $Subtype<express$Request>,
res: express$Response,
next: express$NextFunction,
id: string
) => mixed
): void;
(
req: http$IncomingMessage,
res: http$ServerResponse,
next?: ?express$NextFunction
): void;
}
/*
With flow-bin ^0.59, express app.listen() is deemed to return any and fails flow type coverage.
Which is ironic because https://github.com/facebook/flow/blob/master/Changelog.md#misc-2 (release notes for 0.59)
says "Improves typings for Node.js HTTP server listen() function." See that? IMPROVES!
To work around this issue, we changed Server to ?Server here, so that our invocations of express.listen() will
not be deemed to lack type coverage.
*/
declare class express$Application extends express$Router mixins events$EventEmitter {
constructor(): void;
locals: { [name: string]: mixed };
mountpath: string;
listen(
port: number,
hostname?: string,
backlog?: number,
callback?: (err?: ?Error) => mixed
): ?Server;
listen(
port: number,
hostname?: string,
callback?: (err?: ?Error) => mixed
): ?Server;
listen(port: number, callback?: (err?: ?Error) => mixed): ?Server;
listen(path: string, callback?: (err?: ?Error) => mixed): ?Server;
listen(handle: Object, callback?: (err?: ?Error) => mixed): ?Server;
disable(name: string): void;
disabled(name: string): boolean;
enable(name: string): express$Application;
enabled(name: string): boolean;
engine(name: string, callback: Function): void;
/**
* Mixed will not be taken as a value option. Issue around using the GET http method name and the get for settings.
*/
// get(name: string): mixed;
set(name: string, value: mixed): mixed;
render(
name: string,
optionsOrFunction: { [name: string]: mixed },
callback: express$RenderCallback
): void;
handle(
req: http$IncomingMessage,
res: http$ServerResponse,
next?: ?express$NextFunction
): void;
// callable signature is not inherited
(
req: http$IncomingMessage,
res: http$ServerResponse,
next?: ?express$NextFunction
): void;
}
declare type JsonOptions = {
inflate?: boolean,
limit?: string | number,
reviver?: (key: string, value: mixed) => mixed,
strict?: boolean,
type?: string | Array<string> | ((req: express$Request) => boolean),
verify?: (
req: express$Request,
res: express$Response,
buf: Buffer,
encoding: string
) => mixed
};
declare type express$UrlEncodedOptions = {
extended?: boolean,
inflate?: boolean,
limit?: string | number,
parameterLimit?: number,
type?: string | Array<string> | ((req: express$Request) => boolean),
verify?: (
req: express$Request,
res: express$Response,
buf: Buffer,
encoding: string
) => mixed,
}
declare module "express" {
declare export type RouterOptions = express$RouterOptions;
declare export type CookieOptions = express$CookieOptions;
declare export type Middleware = express$Middleware;
declare export type NextFunction = express$NextFunction;
declare export type RequestParams = express$RequestParams;
declare export type $Response = express$Response;
declare export type $Request = express$Request;
declare export type $Application = express$Application;
declare module.exports: {
(): express$Application, // If you try to call like a function, it will use this signature
json: (opts: ?JsonOptions) => express$Middleware,
static: (root: string, options?: Object) => express$Middleware, // `static` property on the function
Router: typeof express$Router, // `Router` property on the function
urlencoded: (opts: ?express$UrlEncodedOptions) => express$Middleware,
};
}

@ -1,6 +0,0 @@
// flow-typed signature: 6a5610678d4b01e13bbfbbc62bdaf583
// flow-typed version: 3817bc6980/flow-bin_v0.x.x/flow_>=v0.25.x
declare module "flow-bin" {
declare module.exports: string;
}

@ -1,18 +0,0 @@
// flow-typed signature: cda964a8fd1ee8efbd11f88eb4c5c4df
// flow-typed version: <<STUB>>/github-markdown-css_v2.10.0/flow_v0.81.0
/**
* This is an autogenerated libdef stub for:
*
* 'github-markdown-css'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'github-markdown-css' {
declare module.exports: any;
}

@ -1,59 +0,0 @@
// flow-typed signature: 573c576fe34eb3c3c65dd7a9c90a46d2
// flow-typed version: b43dff3e0e/http-errors_v1.x.x/flow_>=v0.25.x
declare module 'http-errors' {
declare class SpecialHttpError extends HttpError {
constructor(): SpecialHttpError;
}
declare class HttpError extends Error {
expose: bool;
message: string;
status: number;
statusCode: number;
}
declare module.exports: {
(status?: number, message?: string, props?: Object): HttpError;
HttpError: typeof HttpError;
BadRequest: typeof SpecialHttpError;
Unauthorized: typeof SpecialHttpError;
PaymentRequired: typeof SpecialHttpError;
Forbidden: typeof SpecialHttpError;
NotFound: typeof SpecialHttpError;
MethodNotAllowed: typeof SpecialHttpError;
NotAcceptable: typeof SpecialHttpError;
ProxyAuthenticationRequired: typeof SpecialHttpError;
RequestTimeout: typeof SpecialHttpError;
Conflict: typeof SpecialHttpError;
Gone: typeof SpecialHttpError;
LengthRequired: typeof SpecialHttpError;
PreconditionFailed: typeof SpecialHttpError;
PayloadTooLarge: typeof SpecialHttpError;
URITooLong: typeof SpecialHttpError;
UnsupportedMediaType: typeof SpecialHttpError;
RangeNotStatisfiable: typeof SpecialHttpError;
ExpectationFailed: typeof SpecialHttpError;
ImATeapot: typeof SpecialHttpError;
MisdirectedRequest: typeof SpecialHttpError;
UnprocessableEntity: typeof SpecialHttpError;
Locked: typeof SpecialHttpError;
FailedDependency: typeof SpecialHttpError;
UnorderedCollection: typeof SpecialHttpError;
UpgradeRequired: typeof SpecialHttpError;
PreconditionRequired: typeof SpecialHttpError;
TooManyRequests: typeof SpecialHttpError;
RequestHeaderFieldsTooLarge: typeof SpecialHttpError;
UnavailableForLegalReasons: typeof SpecialHttpError;
InternalServerError: typeof SpecialHttpError;
NotImplemented: typeof SpecialHttpError;
BadGateway: typeof SpecialHttpError;
ServiceUnavailable: typeof SpecialHttpError;
GatewayTimeout: typeof SpecialHttpError;
HTTPVersionNotSupported: typeof SpecialHttpError;
VariantAlsoNegotiates: typeof SpecialHttpError;
InsufficientStorage: typeof SpecialHttpError;
LoopDetected: typeof SpecialHttpError;
BandwidthLimitExceeded: typeof SpecialHttpError;
NotExtended: typeof SpecialHttpError;
NetworkAuthenticationRequired: typeof SpecialHttpError;
}
}

@ -1,32 +0,0 @@
// flow-typed signature: 76121323ae40fcb28bee1398717ee06c
// flow-typed version: <<STUB>>/jest-environment-node_v22.x.x/flow_v0.69.0
/**
* This is an autogenerated libdef stub for:
*
* 'jest-environment-node'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'jest-environment-node' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'jest-environment-node/build/index' {
declare module.exports: any;
}
// Filename aliases
declare module 'jest-environment-node/build/index.js' {
declare module.exports: $Exports<'jest-environment-node/build/index'>;
}

File diff suppressed because it is too large Load Diff

@ -1,255 +0,0 @@
// flow-typed signature: 10998829754884cf0b6f5fe169611a08
// flow-typed version: <<STUB>>/js-yaml_v3.10.0/flow_v0.64.0
/**
* This is an autogenerated libdef stub for:
*
* 'js-yaml'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'js-yaml' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'js-yaml/bin/js-yaml' {
declare module.exports: any;
}
declare module 'js-yaml/dist/js-yaml' {
declare module.exports: any;
}
declare module 'js-yaml/dist/js-yaml.min' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/common' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/dumper' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/exception' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/loader' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/mark' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/schema' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/schema/core' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/schema/default_full' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/schema/default_safe' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/schema/failsafe' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/schema/json' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/binary' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/bool' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/float' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/int' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/js/function' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/js/regexp' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/js/undefined' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/map' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/merge' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/null' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/omap' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/pairs' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/seq' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/set' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/str' {
declare module.exports: any;
}
declare module 'js-yaml/lib/js-yaml/type/timestamp' {
declare module.exports: any;
}
// Filename aliases
declare module 'js-yaml/bin/js-yaml.js' {
declare module.exports: $Exports<'js-yaml/bin/js-yaml'>;
}
declare module 'js-yaml/dist/js-yaml.js' {
declare module.exports: $Exports<'js-yaml/dist/js-yaml'>;
}
declare module 'js-yaml/dist/js-yaml.min.js' {
declare module.exports: $Exports<'js-yaml/dist/js-yaml.min'>;
}
declare module 'js-yaml/index' {
declare module.exports: $Exports<'js-yaml'>;
}
declare module 'js-yaml/index.js' {
declare module.exports: $Exports<'js-yaml'>;
}
declare module 'js-yaml/lib/js-yaml.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml'>;
}
declare module 'js-yaml/lib/js-yaml/common.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/common'>;
}
declare module 'js-yaml/lib/js-yaml/dumper.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/dumper'>;
}
declare module 'js-yaml/lib/js-yaml/exception.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/exception'>;
}
declare module 'js-yaml/lib/js-yaml/loader.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/loader'>;
}
declare module 'js-yaml/lib/js-yaml/mark.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/mark'>;
}
declare module 'js-yaml/lib/js-yaml/schema.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/schema'>;
}
declare module 'js-yaml/lib/js-yaml/schema/core.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/schema/core'>;
}
declare module 'js-yaml/lib/js-yaml/schema/default_full.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/schema/default_full'>;
}
declare module 'js-yaml/lib/js-yaml/schema/default_safe.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/schema/default_safe'>;
}
declare module 'js-yaml/lib/js-yaml/schema/failsafe.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/schema/failsafe'>;
}
declare module 'js-yaml/lib/js-yaml/schema/json.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/schema/json'>;
}
declare module 'js-yaml/lib/js-yaml/type.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type'>;
}
declare module 'js-yaml/lib/js-yaml/type/binary.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/binary'>;
}
declare module 'js-yaml/lib/js-yaml/type/bool.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/bool'>;
}
declare module 'js-yaml/lib/js-yaml/type/float.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/float'>;
}
declare module 'js-yaml/lib/js-yaml/type/int.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/int'>;
}
declare module 'js-yaml/lib/js-yaml/type/js/function.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/js/function'>;
}
declare module 'js-yaml/lib/js-yaml/type/js/regexp.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/js/regexp'>;
}
declare module 'js-yaml/lib/js-yaml/type/js/undefined.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/js/undefined'>;
}
declare module 'js-yaml/lib/js-yaml/type/map.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/map'>;
}
declare module 'js-yaml/lib/js-yaml/type/merge.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/merge'>;
}
declare module 'js-yaml/lib/js-yaml/type/null.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/null'>;
}
declare module 'js-yaml/lib/js-yaml/type/omap.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/omap'>;
}
declare module 'js-yaml/lib/js-yaml/type/pairs.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/pairs'>;
}
declare module 'js-yaml/lib/js-yaml/type/seq.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/seq'>;
}
declare module 'js-yaml/lib/js-yaml/type/set.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/set'>;
}
declare module 'js-yaml/lib/js-yaml/type/str.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/str'>;
}
declare module 'js-yaml/lib/js-yaml/type/timestamp.js' {
declare module.exports: $Exports<'js-yaml/lib/js-yaml/type/timestamp'>;
}

@ -1,80 +0,0 @@
// flow-typed signature: 4ec026fce9b8a945dbac93217027085d
// flow-typed version: <<STUB>>/jsonwebtoken_v8.1.1/flow_v0.64.0
/**
* This is an autogenerated libdef stub for:
*
* 'jsonwebtoken'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'jsonwebtoken' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'jsonwebtoken/decode' {
declare module.exports: any;
}
declare module 'jsonwebtoken/lib/JsonWebTokenError' {
declare module.exports: any;
}
declare module 'jsonwebtoken/lib/NotBeforeError' {
declare module.exports: any;
}
declare module 'jsonwebtoken/lib/timespan' {
declare module.exports: any;
}
declare module 'jsonwebtoken/lib/TokenExpiredError' {
declare module.exports: any;
}
declare module 'jsonwebtoken/sign' {
declare module.exports: any;
}
declare module 'jsonwebtoken/verify' {
declare module.exports: any;
}
// Filename aliases
declare module 'jsonwebtoken/decode.js' {
declare module.exports: $Exports<'jsonwebtoken/decode'>;
}
declare module 'jsonwebtoken/index' {
declare module.exports: $Exports<'jsonwebtoken'>;
}
declare module 'jsonwebtoken/index.js' {
declare module.exports: $Exports<'jsonwebtoken'>;
}
declare module 'jsonwebtoken/lib/JsonWebTokenError.js' {
declare module.exports: $Exports<'jsonwebtoken/lib/JsonWebTokenError'>;
}
declare module 'jsonwebtoken/lib/NotBeforeError.js' {
declare module.exports: $Exports<'jsonwebtoken/lib/NotBeforeError'>;
}
declare module 'jsonwebtoken/lib/timespan.js' {
declare module.exports: $Exports<'jsonwebtoken/lib/timespan'>;
}
declare module 'jsonwebtoken/lib/TokenExpiredError.js' {
declare module.exports: $Exports<'jsonwebtoken/lib/TokenExpiredError'>;
}
declare module 'jsonwebtoken/sign.js' {
declare module.exports: $Exports<'jsonwebtoken/sign'>;
}
declare module 'jsonwebtoken/verify.js' {
declare module.exports: $Exports<'jsonwebtoken/verify'>;
}

@ -1,33 +0,0 @@
// flow-typed signature: 27250091946c7286334b6d8e332b126f
// flow-typed version: <<STUB>>/kleur_v3.0.3/flow_v0.81.0
/**
* This is an autogenerated libdef stub for:
*
* 'kleur'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'kleur' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
// Filename aliases
declare module 'kleur/index' {
declare module.exports: $Exports<'kleur'>;
}
declare module 'kleur/index.js' {
declare module.exports: $Exports<'kleur'>;
}

File diff suppressed because it is too large Load Diff

@ -1,74 +0,0 @@
// flow-typed signature: f588bf5982dc1140e97108be62b860db
// flow-typed version: <<STUB>>/lunr-mutable-indexes_v2.3.1/flow_v0.77.0
/**
* This is an autogenerated libdef stub for:
*
* 'lunr-mutable-indexes'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'lunr-mutable-indexes' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'lunr-mutable-indexes/lib/lunr_mutable' {
declare module.exports: any;
}
declare module 'lunr-mutable-indexes/lib/mutable_builder' {
declare module.exports: any;
}
declare module 'lunr-mutable-indexes/lib/mutable_index' {
declare module.exports: any;
}
declare module 'lunr-mutable-indexes/lunr-mutable' {
declare module.exports: any;
}
declare module 'lunr-mutable-indexes/test/mutable_serialization_test' {
declare module.exports: any;
}
declare module 'lunr-mutable-indexes/test/mutable_sugar_test' {
declare module.exports: any;
}
declare module 'lunr-mutable-indexes/test/mutable_test' {
declare module.exports: any;
}
// Filename aliases
declare module 'lunr-mutable-indexes/lib/lunr_mutable.js' {
declare module.exports: $Exports<'lunr-mutable-indexes/lib/lunr_mutable'>;
}
declare module 'lunr-mutable-indexes/lib/mutable_builder.js' {
declare module.exports: $Exports<'lunr-mutable-indexes/lib/mutable_builder'>;
}
declare module 'lunr-mutable-indexes/lib/mutable_index.js' {
declare module.exports: $Exports<'lunr-mutable-indexes/lib/mutable_index'>;
}
declare module 'lunr-mutable-indexes/lunr-mutable.js' {
declare module.exports: $Exports<'lunr-mutable-indexes/lunr-mutable'>;
}
declare module 'lunr-mutable-indexes/test/mutable_serialization_test.js' {
declare module.exports: $Exports<'lunr-mutable-indexes/test/mutable_serialization_test'>;
}
declare module 'lunr-mutable-indexes/test/mutable_sugar_test.js' {
declare module.exports: $Exports<'lunr-mutable-indexes/test/mutable_sugar_test'>;
}
declare module 'lunr-mutable-indexes/test/mutable_test.js' {
declare module.exports: $Exports<'lunr-mutable-indexes/test/mutable_test'>;
}

@ -1,163 +0,0 @@
// flow-typed signature: 85ea5a515c42c00188d893614f410655
// flow-typed version: 72fe9c1b53/marked_v0.3.x/flow_>=v0.28.x
type marked$AlignFlag = 'left' | 'right' | 'center'
type marked$NodeCallback<T> = (e: ?Error, d: ?T) => void
class marked$Renderer {
options: marked$MarkedOptions;
code: (c: string, l: string) => string;
blockquote: (q: string) => string;
html: (h: string) => string;
heading: (t: string, l: number) => string;
hr: () => string;
list: (b: string, o: boolean) => string;
listitem: (t: string) => string;
paragraph: (t: string) => string;
table: (h: string, b: string) => string;
tablerow: (c: string) => string;
tablecell: (c: string, f: ?marked$AlignFlag) => string;
heading: (t: string, l: number) => string;
strong: (t: string) => string;
em: (t: string) => string;
codespan: (c: string) => string;
br: () => string;
del: (t: string) => string;
link: (h: string, ti: string, te: string) => string;
image: (h: string, ti: string, te: string) => string;
text: (t: string) => string;
constructor(o?: marked$MarkedOptions): marked$Renderer {
return this;
}
}
type marked$HighlightFunction =
((c: string, l: string, cb: marked$NodeCallback<string>) => void)
| ((c: string, cb: marked$NodeCallback<string>) => void)
| ((c: string, l?: string) => string)
type marked$MarkedOptions = {
highlight?: marked$HighlightFunction;
renderer?: marked$Renderer;
gfm?: boolean;
tables?: boolean;
breaks?: boolean;
pedantic?: boolean;
sanitize?: boolean;
smartLists?: boolean;
smartypants?: boolean;
}
/*
* marked$Tokens
*/
type marked$Space = { type: 'space'; }
type marked$Code = { type: 'code'; text: string; lang?: string; }
type marked$Heading = { type: 'heading'; depth: number; text: string; }
type marked$Table = { type: 'table'; header: string; align: Array<marked$AlignFlag> ; cells: Array<Array<string>> }
type marked$Hr = { type: 'hr'; }
type marked$BlockquoteStart = { type: 'blockquote_start' }
type marked$BlockquoteEnd = { type: 'blockquote_end' }
type marked$ListStart = { type: 'list_start' }
type marked$ListEnd = { type: 'list_end' }
type marked$Paragraph = { type: 'paragraph'; pre: boolean; text: string; }
type marked$Html = { type: 'paragraph'; pre: boolean; text: string; }
type marked$Text = { type: 'text'; text: string; }
type marked$Token =
marked$Space
| marked$Code
| marked$Heading
| marked$Table
| marked$Hr
| marked$BlockquoteStart
| marked$BlockquoteEnd
| marked$ListStart
| marked$ListEnd
| marked$Paragraph
| marked$Html
| marked$Text
type marked$Link = {
title: ?string;
href: string;
}
type marked$Tokens = { links: Array<marked$Link> } & Array<marked$Token>;
type marked$NoopRule = {
(i: mixed): void;
exec: (i: mixed) => void;
}
type marked$Rule = RegExp | marked$NoopRule
type marked$lex = (t: string) => marked$Tokens;
class marked$Lexer {
static lexer: (t: string, o?: marked$MarkedOptions) => marked$Tokens;
static rules: { [key: string]: marked$Rule };
rules: { [key: string]: marked$Rule };
lex: marked$lex;
tokens: marked$Tokens;
options: marked$MarkedOptions;
constructor(o?: marked$MarkedOptions): marked$Lexer {
return this;
}
}
class marked$Parser {
static parse: (t: marked$Tokens, o?: marked$MarkedOptions) => string;
parse: (t: marked$Tokens) => string;
next: () => marked$Token;
peek: () => marked$Token;
parsemarked$Text: () => string;
tok: () => string;
tokens: marked$Tokens;
token: ?marked$Token;
options: marked$MarkedOptions;
renderer: marked$Renderer;
constructor(o?: marked$MarkedOptions): marked$Parser {
return this;
}
}
class marked$InlineLexer {
static rules: Array<marked$Rule>;
static output: (s: string, l: Array<marked$Link>, o?: marked$MarkedOptions) => string;
output: (s: string) => string;
outputmarked$Link: (c: Array<string>, l: marked$Link) => string;
smartypants: (t: string) => string;
mangle: (t: string) => string;
options: marked$MarkedOptions;
links: Array<marked$Link>;
rules: Array<marked$Rule>;
renderer: marked$Renderer;
constructor(l: Array<marked$Link>, o?: marked$MarkedOptions): marked$InlineLexer {
return this;
}
}
type marked$Marked = {
(md: string, o: marked$MarkedOptions, cb: marked$NodeCallback<string>): void;
(md: string, cb: marked$NodeCallback<string>): void;
(md: string, o?: marked$MarkedOptions): string;
setOptions: (o: marked$MarkedOptions) => void;
defaults: marked$MarkedOptions;
Parser: typeof marked$Parser;
parser: typeof marked$Parser.parse;
Lexer: typeof marked$Lexer;
lexer: typeof marked$Lexer.lexer;
InlineLexer: typeof marked$InlineLexer;
inlinelexer: marked$InlineLexer.output;
Renderer: typeof marked$Renderer;
parse: marked$Marked;
}
declare module marked {
declare export default marked$Marked;
}

@ -1,66 +0,0 @@
// flow-typed signature: 56b4e33a3df0ef57946fd42834d344b8
// flow-typed version: <<STUB>>/mime_v2.2.0/flow_v0.67.1
/**
* This is an autogenerated libdef stub for:
*
* 'mime'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'mime' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'mime/cli' {
declare module.exports: any;
}
declare module 'mime/lite' {
declare module.exports: any;
}
declare module 'mime/Mime' {
declare module.exports: any;
}
declare module 'mime/src/build' {
declare module.exports: any;
}
declare module 'mime/src/test' {
declare module.exports: any;
}
// Filename aliases
declare module 'mime/cli.js' {
declare module.exports: $Exports<'mime/cli'>;
}
declare module 'mime/index' {
declare module.exports: $Exports<'mime'>;
}
declare module 'mime/index.js' {
declare module.exports: $Exports<'mime'>;
}
declare module 'mime/lite.js' {
declare module.exports: $Exports<'mime/lite'>;
}
declare module 'mime/Mime.js' {
declare module.exports: $Exports<'mime/Mime'>;
}
declare module 'mime/src/build.js' {
declare module.exports: $Exports<'mime/src/build'>;
}
declare module 'mime/src/test.js' {
declare module.exports: $Exports<'mime/src/test'>;
}

@ -1,53 +0,0 @@
// flow-typed signature: bc0af4a44bb8631039f713b1afba6988
// flow-typed version: d42cbef63c/minimatch_v3.x.x/flow_>=v0.25.x
type $npm$minimatch$Options = {
debug?: boolean,
nobrace?: boolean,
noglobstar?: boolean,
dot?: boolean,
noext?: boolean,
nocase?: boolean,
nonull?: boolean,
matchBase?: boolean,
nocomment?: boolean,
nonegate?: boolean,
flipNegate?: boolean
};
declare module "minimatch" {
declare class Minimatch {
constructor(pattern: string, options?: $npm$minimatch$Options): Minimatch,
set: Array<Array<string | RegExp>>,
regexp: null | RegExp, // null until .makeRe() is called
negate: boolean,
comment: boolean,
empty: boolean,
makeRe(): RegExp | false,
match(name: string): boolean,
matchOne(
fileArray: Array<string>,
patternArray: Array<string>,
partial?: boolean
): boolean
}
declare class MinimatchModule {
Minimatch: Class<Minimatch>,
(name: string, pattern: string, options?: $npm$minimatch$Options): boolean,
filter(
pattern: string,
options?: $npm$minimatch$Options
): (value: string) => boolean,
match(
list: Array<string>,
pattern: string,
options?: $npm$minimatch$Options
): Array<string>
}
declare module.exports: MinimatchModule;
}

@ -1,13 +0,0 @@
// flow-typed signature: 82aa0feffc2bbd64dce3bec492f5d601
// flow-typed version: 3315d89a00/mkdirp_v0.5.x/flow_>=v0.25.0
declare module 'mkdirp' {
declare type Options = number | { mode?: number; fs?: mixed };
declare type Callback = (err: ?Error, path: ?string) => void;
declare module.exports: {
(path: string, options?: Options | Callback, callback?: Callback): void;
sync(path: string, options?: Options): void;
};
}

@ -1,109 +0,0 @@
// flow-typed signature: 0c37b93b28df38b46c7edb9bc9d278ad
// flow-typed version: <<STUB>>/node-mocks-http_v1.6.7/flow_v0.64.0
/**
* This is an autogenerated libdef stub for:
*
* 'node-mocks-http'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'node-mocks-http' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'node-mocks-http/lib/express/mock-application' {
declare module.exports: any;
}
declare module 'node-mocks-http/lib/express/mock-express' {
declare module.exports: any;
}
declare module 'node-mocks-http/lib/express/mock-request' {
declare module.exports: any;
}
declare module 'node-mocks-http/lib/express/utils/define-getter' {
declare module.exports: any;
}
declare module 'node-mocks-http/lib/http-mock' {
declare module.exports: any;
}
declare module 'node-mocks-http/lib/mockEventEmitter' {
declare module.exports: any;
}
declare module 'node-mocks-http/lib/mockRequest' {
declare module.exports: any;
}
declare module 'node-mocks-http/lib/mockResponse' {
declare module.exports: any;
}
declare module 'node-mocks-http/lib/mockWritableStream' {
declare module.exports: any;
}
declare module 'node-mocks-http/lib/node/_http_incoming' {
declare module.exports: any;
}
declare module 'node-mocks-http/lib/node/_http_server' {
declare module.exports: any;
}
declare module 'node-mocks-http/lib/node/http' {
declare module.exports: any;
}
// Filename aliases
declare module 'node-mocks-http/lib/express/mock-application.js' {
declare module.exports: $Exports<'node-mocks-http/lib/express/mock-application'>;
}
declare module 'node-mocks-http/lib/express/mock-express.js' {
declare module.exports: $Exports<'node-mocks-http/lib/express/mock-express'>;
}
declare module 'node-mocks-http/lib/express/mock-request.js' {
declare module.exports: $Exports<'node-mocks-http/lib/express/mock-request'>;
}
declare module 'node-mocks-http/lib/express/utils/define-getter.js' {
declare module.exports: $Exports<'node-mocks-http/lib/express/utils/define-getter'>;
}
declare module 'node-mocks-http/lib/http-mock.js' {
declare module.exports: $Exports<'node-mocks-http/lib/http-mock'>;
}
declare module 'node-mocks-http/lib/mockEventEmitter.js' {
declare module.exports: $Exports<'node-mocks-http/lib/mockEventEmitter'>;
}
declare module 'node-mocks-http/lib/mockRequest.js' {
declare module.exports: $Exports<'node-mocks-http/lib/mockRequest'>;
}
declare module 'node-mocks-http/lib/mockResponse.js' {
declare module.exports: $Exports<'node-mocks-http/lib/mockResponse'>;
}
declare module 'node-mocks-http/lib/mockWritableStream.js' {
declare module.exports: $Exports<'node-mocks-http/lib/mockWritableStream'>;
}
declare module 'node-mocks-http/lib/node/_http_incoming.js' {
declare module.exports: $Exports<'node-mocks-http/lib/node/_http_incoming'>;
}
declare module 'node-mocks-http/lib/node/_http_server.js' {
declare module.exports: $Exports<'node-mocks-http/lib/node/_http_server'>;
}
declare module 'node-mocks-http/lib/node/http.js' {
declare module.exports: $Exports<'node-mocks-http/lib/node/http'>;
}

@ -1,9 +0,0 @@
// flow-typed signature: b0a8c8851219a1c2a933509d842e0bc8
// flow-typed version: 4a2d036a51/normalize.css_v7.x.x/flow_>=v0.34.x
// normalize.css may be imported for side-effects,
// e.g. to force webpack to bundle it alongside CSS modules
declare module "normalize.css" {
declare export default empty
}

@ -1,81 +0,0 @@
// flow-typed signature: 5ea2cb6aa83979de9573ab3e3723be3f
// flow-typed version: <<STUB>>/pkginfo_v0.4.1/flow_v0.67.1
/**
* This is an autogenerated libdef stub for:
*
* 'pkginfo'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'pkginfo' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'pkginfo/examples/all-properties' {
declare module.exports: any;
}
declare module 'pkginfo/examples/array-argument' {
declare module.exports: any;
}
declare module 'pkginfo/examples/multiple-properties' {
declare module.exports: any;
}
declare module 'pkginfo/examples/object-argument' {
declare module.exports: any;
}
declare module 'pkginfo/examples/single-property' {
declare module.exports: any;
}
declare module 'pkginfo/examples/target-dir' {
declare module.exports: any;
}
declare module 'pkginfo/lib/pkginfo' {
declare module.exports: any;
}
declare module 'pkginfo/test/pkginfo-test' {
declare module.exports: any;
}
// Filename aliases
declare module 'pkginfo/examples/all-properties.js' {
declare module.exports: $Exports<'pkginfo/examples/all-properties'>;
}
declare module 'pkginfo/examples/array-argument.js' {
declare module.exports: $Exports<'pkginfo/examples/array-argument'>;
}
declare module 'pkginfo/examples/multiple-properties.js' {
declare module.exports: $Exports<'pkginfo/examples/multiple-properties'>;
}
declare module 'pkginfo/examples/object-argument.js' {
declare module.exports: $Exports<'pkginfo/examples/object-argument'>;
}
declare module 'pkginfo/examples/single-property.js' {
declare module.exports: $Exports<'pkginfo/examples/single-property'>;
}
declare module 'pkginfo/examples/target-dir.js' {
declare module.exports: $Exports<'pkginfo/examples/target-dir'>;
}
declare module 'pkginfo/lib/pkginfo.js' {
declare module.exports: $Exports<'pkginfo/lib/pkginfo'>;
}
declare module 'pkginfo/test/pkginfo-test.js' {
declare module.exports: $Exports<'pkginfo/test/pkginfo-test'>;
}

@ -1,690 +0,0 @@
// flow-typed signature: 269daa88cf96222ec337ad11f33aeff0
// flow-typed version: <<STUB>>/polished_v2.3.0/flow_v0.81.0
/**
* This is an autogenerated libdef stub for:
*
* 'polished'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'polished' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'polished/babel.config' {
declare module.exports: any;
}
declare module 'polished/dist/polished.es' {
declare module.exports: any;
}
declare module 'polished/dist/polished' {
declare module.exports: any;
}
declare module 'polished/dist/polished.min' {
declare module.exports: any;
}
declare module 'polished/docs/assets/anchor' {
declare module.exports: any;
}
declare module 'polished/docs/assets/docs' {
declare module.exports: any;
}
declare module 'polished/docs/assets/highlight.pack' {
declare module.exports: any;
}
declare module 'polished/docs/assets/polished' {
declare module.exports: any;
}
declare module 'polished/docs/assets/script' {
declare module.exports: any;
}
declare module 'polished/lib/color/adjustHue' {
declare module.exports: any;
}
declare module 'polished/lib/color/complement' {
declare module.exports: any;
}
declare module 'polished/lib/color/darken' {
declare module.exports: any;
}
declare module 'polished/lib/color/desaturate' {
declare module.exports: any;
}
declare module 'polished/lib/color/getLuminance' {
declare module.exports: any;
}
declare module 'polished/lib/color/grayscale' {
declare module.exports: any;
}
declare module 'polished/lib/color/hsl' {
declare module.exports: any;
}
declare module 'polished/lib/color/hsla' {
declare module.exports: any;
}
declare module 'polished/lib/color/invert' {
declare module.exports: any;
}
declare module 'polished/lib/color/lighten' {
declare module.exports: any;
}
declare module 'polished/lib/color/mix' {
declare module.exports: any;
}
declare module 'polished/lib/color/opacify' {
declare module.exports: any;
}
declare module 'polished/lib/color/parseToHsl' {
declare module.exports: any;
}
declare module 'polished/lib/color/parseToRgb' {
declare module.exports: any;
}
declare module 'polished/lib/color/readableColor' {
declare module.exports: any;
}
declare module 'polished/lib/color/rgb' {
declare module.exports: any;
}
declare module 'polished/lib/color/rgba' {
declare module.exports: any;
}
declare module 'polished/lib/color/saturate' {
declare module.exports: any;
}
declare module 'polished/lib/color/setHue' {
declare module.exports: any;
}
declare module 'polished/lib/color/setLightness' {
declare module.exports: any;
}
declare module 'polished/lib/color/setSaturation' {
declare module.exports: any;
}
declare module 'polished/lib/color/shade' {
declare module.exports: any;
}
declare module 'polished/lib/color/tint' {
declare module.exports: any;
}
declare module 'polished/lib/color/toColorString' {
declare module.exports: any;
}
declare module 'polished/lib/color/transparentize' {
declare module.exports: any;
}
declare module 'polished/lib/helpers/directionalProperty' {
declare module.exports: any;
}
declare module 'polished/lib/helpers/em' {
declare module.exports: any;
}
declare module 'polished/lib/helpers/getValueAndUnit' {
declare module.exports: any;
}
declare module 'polished/lib/helpers/modularScale' {
declare module.exports: any;
}
declare module 'polished/lib/helpers/rem' {
declare module.exports: any;
}
declare module 'polished/lib/helpers/stripUnit' {
declare module.exports: any;
}
declare module 'polished/lib/index' {
declare module.exports: any;
}
declare module 'polished/lib/internalHelpers/_capitalizeString' {
declare module.exports: any;
}
declare module 'polished/lib/internalHelpers/_curry' {
declare module.exports: any;
}
declare module 'polished/lib/internalHelpers/_endsWith' {
declare module.exports: any;
}
declare module 'polished/lib/internalHelpers/_guard' {
declare module.exports: any;
}
declare module 'polished/lib/internalHelpers/_hslToHex' {
declare module.exports: any;
}
declare module 'polished/lib/internalHelpers/_hslToRgb' {
declare module.exports: any;
}
declare module 'polished/lib/internalHelpers/_nameToHex' {
declare module.exports: any;
}
declare module 'polished/lib/internalHelpers/_numberToHex' {
declare module.exports: any;
}
declare module 'polished/lib/internalHelpers/_pxto' {
declare module.exports: any;
}
declare module 'polished/lib/internalHelpers/_reduceHexValue' {
declare module.exports: any;
}
declare module 'polished/lib/internalHelpers/_rgbToHsl' {
declare module.exports: any;
}
declare module 'polished/lib/internalHelpers/_statefulSelectors' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/between' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/clearFix' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/cover' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/ellipsis' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/fluidRange' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/fontFace' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/hideText' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/hideVisually' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/hiDPI' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/normalize' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/placeholder' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/radialGradient' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/retinaImage' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/selection' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/timingFunctions' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/triangle' {
declare module.exports: any;
}
declare module 'polished/lib/mixins/wordWrap' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/animation' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/backgroundImages' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/backgrounds' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/border' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/borderColor' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/borderRadius' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/borderStyle' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/borderWidth' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/buttons' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/margin' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/padding' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/position' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/size' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/textInputs' {
declare module.exports: any;
}
declare module 'polished/lib/shorthands/transitions' {
declare module.exports: any;
}
declare module 'polished/lib/types/color' {
declare module.exports: any;
}
declare module 'polished/lib/types/fluidRangeConfiguration' {
declare module.exports: any;
}
declare module 'polished/lib/types/fontFaceConfiguration' {
declare module.exports: any;
}
declare module 'polished/lib/types/interactionState' {
declare module.exports: any;
}
declare module 'polished/lib/types/modularScaleRatio' {
declare module.exports: any;
}
declare module 'polished/lib/types/radialGradientConfiguration' {
declare module.exports: any;
}
declare module 'polished/lib/types/sideKeyword' {
declare module.exports: any;
}
declare module 'polished/lib/types/style' {
declare module.exports: any;
}
declare module 'polished/lib/types/timingFunction' {
declare module.exports: any;
}
declare module 'polished/lib/types/triangleConfiguration' {
declare module.exports: any;
}
// Filename aliases
declare module 'polished/babel.config.js' {
declare module.exports: $Exports<'polished/babel.config'>;
}
declare module 'polished/dist/polished.es.js' {
declare module.exports: $Exports<'polished/dist/polished.es'>;
}
declare module 'polished/dist/polished.js' {
declare module.exports: $Exports<'polished/dist/polished'>;
}
declare module 'polished/dist/polished.min.js' {
declare module.exports: $Exports<'polished/dist/polished.min'>;
}
declare module 'polished/docs/assets/anchor.js' {
declare module.exports: $Exports<'polished/docs/assets/anchor'>;
}
declare module 'polished/docs/assets/docs.js' {
declare module.exports: $Exports<'polished/docs/assets/docs'>;
}
declare module 'polished/docs/assets/highlight.pack.js' {
declare module.exports: $Exports<'polished/docs/assets/highlight.pack'>;
}
declare module 'polished/docs/assets/polished.js' {
declare module.exports: $Exports<'polished/docs/assets/polished'>;
}
declare module 'polished/docs/assets/script.js' {
declare module.exports: $Exports<'polished/docs/assets/script'>;
}
declare module 'polished/lib/color/adjustHue.js' {
declare module.exports: $Exports<'polished/lib/color/adjustHue'>;
}
declare module 'polished/lib/color/complement.js' {
declare module.exports: $Exports<'polished/lib/color/complement'>;
}
declare module 'polished/lib/color/darken.js' {
declare module.exports: $Exports<'polished/lib/color/darken'>;
}
declare module 'polished/lib/color/desaturate.js' {
declare module.exports: $Exports<'polished/lib/color/desaturate'>;
}
declare module 'polished/lib/color/getLuminance.js' {
declare module.exports: $Exports<'polished/lib/color/getLuminance'>;
}
declare module 'polished/lib/color/grayscale.js' {
declare module.exports: $Exports<'polished/lib/color/grayscale'>;
}
declare module 'polished/lib/color/hsl.js' {
declare module.exports: $Exports<'polished/lib/color/hsl'>;
}
declare module 'polished/lib/color/hsla.js' {
declare module.exports: $Exports<'polished/lib/color/hsla'>;
}
declare module 'polished/lib/color/invert.js' {
declare module.exports: $Exports<'polished/lib/color/invert'>;
}
declare module 'polished/lib/color/lighten.js' {
declare module.exports: $Exports<'polished/lib/color/lighten'>;
}
declare module 'polished/lib/color/mix.js' {
declare module.exports: $Exports<'polished/lib/color/mix'>;
}
declare module 'polished/lib/color/opacify.js' {
declare module.exports: $Exports<'polished/lib/color/opacify'>;
}
declare module 'polished/lib/color/parseToHsl.js' {
declare module.exports: $Exports<'polished/lib/color/parseToHsl'>;
}
declare module 'polished/lib/color/parseToRgb.js' {
declare module.exports: $Exports<'polished/lib/color/parseToRgb'>;
}
declare module 'polished/lib/color/readableColor.js' {
declare module.exports: $Exports<'polished/lib/color/readableColor'>;
}
declare module 'polished/lib/color/rgb.js' {
declare module.exports: $Exports<'polished/lib/color/rgb'>;
}
declare module 'polished/lib/color/rgba.js' {
declare module.exports: $Exports<'polished/lib/color/rgba'>;
}
declare module 'polished/lib/color/saturate.js' {
declare module.exports: $Exports<'polished/lib/color/saturate'>;
}
declare module 'polished/lib/color/setHue.js' {
declare module.exports: $Exports<'polished/lib/color/setHue'>;
}
declare module 'polished/lib/color/setLightness.js' {
declare module.exports: $Exports<'polished/lib/color/setLightness'>;
}
declare module 'polished/lib/color/setSaturation.js' {
declare module.exports: $Exports<'polished/lib/color/setSaturation'>;
}
declare module 'polished/lib/color/shade.js' {
declare module.exports: $Exports<'polished/lib/color/shade'>;
}
declare module 'polished/lib/color/tint.js' {
declare module.exports: $Exports<'polished/lib/color/tint'>;
}
declare module 'polished/lib/color/toColorString.js' {
declare module.exports: $Exports<'polished/lib/color/toColorString'>;
}
declare module 'polished/lib/color/transparentize.js' {
declare module.exports: $Exports<'polished/lib/color/transparentize'>;
}
declare module 'polished/lib/helpers/directionalProperty.js' {
declare module.exports: $Exports<'polished/lib/helpers/directionalProperty'>;
}
declare module 'polished/lib/helpers/em.js' {
declare module.exports: $Exports<'polished/lib/helpers/em'>;
}
declare module 'polished/lib/helpers/getValueAndUnit.js' {
declare module.exports: $Exports<'polished/lib/helpers/getValueAndUnit'>;
}
declare module 'polished/lib/helpers/modularScale.js' {
declare module.exports: $Exports<'polished/lib/helpers/modularScale'>;
}
declare module 'polished/lib/helpers/rem.js' {
declare module.exports: $Exports<'polished/lib/helpers/rem'>;
}
declare module 'polished/lib/helpers/stripUnit.js' {
declare module.exports: $Exports<'polished/lib/helpers/stripUnit'>;
}
declare module 'polished/lib/index.js' {
declare module.exports: $Exports<'polished/lib/index'>;
}
declare module 'polished/lib/internalHelpers/_capitalizeString.js' {
declare module.exports: $Exports<'polished/lib/internalHelpers/_capitalizeString'>;
}
declare module 'polished/lib/internalHelpers/_curry.js' {
declare module.exports: $Exports<'polished/lib/internalHelpers/_curry'>;
}
declare module 'polished/lib/internalHelpers/_endsWith.js' {
declare module.exports: $Exports<'polished/lib/internalHelpers/_endsWith'>;
}
declare module 'polished/lib/internalHelpers/_guard.js' {
declare module.exports: $Exports<'polished/lib/internalHelpers/_guard'>;
}
declare module 'polished/lib/internalHelpers/_hslToHex.js' {
declare module.exports: $Exports<'polished/lib/internalHelpers/_hslToHex'>;
}
declare module 'polished/lib/internalHelpers/_hslToRgb.js' {
declare module.exports: $Exports<'polished/lib/internalHelpers/_hslToRgb'>;
}
declare module 'polished/lib/internalHelpers/_nameToHex.js' {
declare module.exports: $Exports<'polished/lib/internalHelpers/_nameToHex'>;
}
declare module 'polished/lib/internalHelpers/_numberToHex.js' {
declare module.exports: $Exports<'polished/lib/internalHelpers/_numberToHex'>;
}
declare module 'polished/lib/internalHelpers/_pxto.js' {
declare module.exports: $Exports<'polished/lib/internalHelpers/_pxto'>;
}
declare module 'polished/lib/internalHelpers/_reduceHexValue.js' {
declare module.exports: $Exports<'polished/lib/internalHelpers/_reduceHexValue'>;
}
declare module 'polished/lib/internalHelpers/_rgbToHsl.js' {
declare module.exports: $Exports<'polished/lib/internalHelpers/_rgbToHsl'>;
}
declare module 'polished/lib/internalHelpers/_statefulSelectors.js' {
declare module.exports: $Exports<'polished/lib/internalHelpers/_statefulSelectors'>;
}
declare module 'polished/lib/mixins/between.js' {
declare module.exports: $Exports<'polished/lib/mixins/between'>;
}
declare module 'polished/lib/mixins/clearFix.js' {
declare module.exports: $Exports<'polished/lib/mixins/clearFix'>;
}
declare module 'polished/lib/mixins/cover.js' {
declare module.exports: $Exports<'polished/lib/mixins/cover'>;
}
declare module 'polished/lib/mixins/ellipsis.js' {
declare module.exports: $Exports<'polished/lib/mixins/ellipsis'>;
}
declare module 'polished/lib/mixins/fluidRange.js' {
declare module.exports: $Exports<'polished/lib/mixins/fluidRange'>;
}
declare module 'polished/lib/mixins/fontFace.js' {
declare module.exports: $Exports<'polished/lib/mixins/fontFace'>;
}
declare module 'polished/lib/mixins/hideText.js' {
declare module.exports: $Exports<'polished/lib/mixins/hideText'>;
}
declare module 'polished/lib/mixins/hideVisually.js' {
declare module.exports: $Exports<'polished/lib/mixins/hideVisually'>;
}
declare module 'polished/lib/mixins/hiDPI.js' {
declare module.exports: $Exports<'polished/lib/mixins/hiDPI'>;
}
declare module 'polished/lib/mixins/normalize.js' {
declare module.exports: $Exports<'polished/lib/mixins/normalize'>;
}
declare module 'polished/lib/mixins/placeholder.js' {
declare module.exports: $Exports<'polished/lib/mixins/placeholder'>;
}
declare module 'polished/lib/mixins/radialGradient.js' {
declare module.exports: $Exports<'polished/lib/mixins/radialGradient'>;
}
declare module 'polished/lib/mixins/retinaImage.js' {
declare module.exports: $Exports<'polished/lib/mixins/retinaImage'>;
}
declare module 'polished/lib/mixins/selection.js' {
declare module.exports: $Exports<'polished/lib/mixins/selection'>;
}
declare module 'polished/lib/mixins/timingFunctions.js' {
declare module.exports: $Exports<'polished/lib/mixins/timingFunctions'>;
}
declare module 'polished/lib/mixins/triangle.js' {
declare module.exports: $Exports<'polished/lib/mixins/triangle'>;
}
declare module 'polished/lib/mixins/wordWrap.js' {
declare module.exports: $Exports<'polished/lib/mixins/wordWrap'>;
}
declare module 'polished/lib/shorthands/animation.js' {
declare module.exports: $Exports<'polished/lib/shorthands/animation'>;
}
declare module 'polished/lib/shorthands/backgroundImages.js' {
declare module.exports: $Exports<'polished/lib/shorthands/backgroundImages'>;
}
declare module 'polished/lib/shorthands/backgrounds.js' {
declare module.exports: $Exports<'polished/lib/shorthands/backgrounds'>;
}
declare module 'polished/lib/shorthands/border.js' {
declare module.exports: $Exports<'polished/lib/shorthands/border'>;
}
declare module 'polished/lib/shorthands/borderColor.js' {
declare module.exports: $Exports<'polished/lib/shorthands/borderColor'>;
}
declare module 'polished/lib/shorthands/borderRadius.js' {
declare module.exports: $Exports<'polished/lib/shorthands/borderRadius'>;
}
declare module 'polished/lib/shorthands/borderStyle.js' {
declare module.exports: $Exports<'polished/lib/shorthands/borderStyle'>;
}
declare module 'polished/lib/shorthands/borderWidth.js' {
declare module.exports: $Exports<'polished/lib/shorthands/borderWidth'>;
}
declare module 'polished/lib/shorthands/buttons.js' {
declare module.exports: $Exports<'polished/lib/shorthands/buttons'>;
}
declare module 'polished/lib/shorthands/margin.js' {
declare module.exports: $Exports<'polished/lib/shorthands/margin'>;
}
declare module 'polished/lib/shorthands/padding.js' {
declare module.exports: $Exports<'polished/lib/shorthands/padding'>;
}
declare module 'polished/lib/shorthands/position.js' {
declare module.exports: $Exports<'polished/lib/shorthands/position'>;
}
declare module 'polished/lib/shorthands/size.js' {
declare module.exports: $Exports<'polished/lib/shorthands/size'>;
}
declare module 'polished/lib/shorthands/textInputs.js' {
declare module.exports: $Exports<'polished/lib/shorthands/textInputs'>;
}
declare module 'polished/lib/shorthands/transitions.js' {
declare module.exports: $Exports<'polished/lib/shorthands/transitions'>;
}
declare module 'polished/lib/types/color.js' {
declare module.exports: $Exports<'polished/lib/types/color'>;
}
declare module 'polished/lib/types/fluidRangeConfiguration.js' {
declare module.exports: $Exports<'polished/lib/types/fluidRangeConfiguration'>;
}
declare module 'polished/lib/types/fontFaceConfiguration.js' {
declare module.exports: $Exports<'polished/lib/types/fontFaceConfiguration'>;
}
declare module 'polished/lib/types/interactionState.js' {
declare module.exports: $Exports<'polished/lib/types/interactionState'>;
}
declare module 'polished/lib/types/modularScaleRatio.js' {
declare module.exports: $Exports<'polished/lib/types/modularScaleRatio'>;
}
declare module 'polished/lib/types/radialGradientConfiguration.js' {
declare module.exports: $Exports<'polished/lib/types/radialGradientConfiguration'>;
}
declare module 'polished/lib/types/sideKeyword.js' {
declare module.exports: $Exports<'polished/lib/types/sideKeyword'>;
}
declare module 'polished/lib/types/style.js' {
declare module.exports: $Exports<'polished/lib/types/style'>;
}
declare module 'polished/lib/types/timingFunction.js' {
declare module.exports: $Exports<'polished/lib/types/timingFunction'>;
}
declare module 'polished/lib/types/triangleConfiguration.js' {
declare module.exports: $Exports<'polished/lib/types/triangleConfiguration'>;
}

@ -1,34 +0,0 @@
// flow-typed signature: 3eaa1f24c7397b78a7481992d2cddcb2
// flow-typed version: a1a20d4928/prop-types_v15.x.x/flow_>=v0.41.x
type $npm$propTypes$ReactPropsCheckType = (
props: any,
propName: string,
componentName: string,
href?: string) => ?Error;
declare module 'prop-types' {
declare var array: React$PropType$Primitive<Array<any>>;
declare var bool: React$PropType$Primitive<boolean>;
declare var func: React$PropType$Primitive<Function>;
declare var number: React$PropType$Primitive<number>;
declare var object: React$PropType$Primitive<Object>;
declare var string: React$PropType$Primitive<string>;
declare var any: React$PropType$Primitive<any>;
declare var arrayOf: React$PropType$ArrayOf;
declare var element: React$PropType$Primitive<any>; /* TODO */
declare var instanceOf: React$PropType$InstanceOf;
declare var node: React$PropType$Primitive<any>; /* TODO */
declare var objectOf: React$PropType$ObjectOf;
declare var oneOf: React$PropType$OneOf;
declare var oneOfType: React$PropType$OneOfType;
declare var shape: React$PropType$Shape;
declare function checkPropTypes<V>(
propTypes: $Subtype<{[_: $Keys<V>]: $npm$propTypes$ReactPropsCheckType}>,
values: V,
location: string,
componentName: string,
getStack: ?(() => ?string)
) : void;
}

@ -1,60 +0,0 @@
// flow-typed signature: 844045a071365b8f4e9d7d1aac302959
// flow-typed version: <<STUB>>/react-autosuggest_v9.4.2/flow_v0.81.0
/**
* This is an autogenerated libdef stub for:
*
* 'react-autosuggest'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'react-autosuggest' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'react-autosuggest/dist/Autosuggest' {
declare module.exports: any;
}
declare module 'react-autosuggest/dist/index' {
declare module.exports: any;
}
declare module 'react-autosuggest/dist/standalone/autosuggest' {
declare module.exports: any;
}
declare module 'react-autosuggest/dist/standalone/autosuggest.min' {
declare module.exports: any;
}
declare module 'react-autosuggest/dist/theme' {
declare module.exports: any;
}
// Filename aliases
declare module 'react-autosuggest/dist/Autosuggest.js' {
declare module.exports: $Exports<'react-autosuggest/dist/Autosuggest'>;
}
declare module 'react-autosuggest/dist/index.js' {
declare module.exports: $Exports<'react-autosuggest/dist/index'>;
}
declare module 'react-autosuggest/dist/standalone/autosuggest.js' {
declare module.exports: $Exports<'react-autosuggest/dist/standalone/autosuggest'>;
}
declare module 'react-autosuggest/dist/standalone/autosuggest.min.js' {
declare module.exports: $Exports<'react-autosuggest/dist/standalone/autosuggest.min'>;
}
declare module 'react-autosuggest/dist/theme.js' {
declare module.exports: $Exports<'react-autosuggest/dist/theme'>;
}

@ -1,60 +0,0 @@
// flow-typed signature: 70c6c9c1a5de74b9254304a0f8d6f61e
// flow-typed version: <<STUB>>/react-emotion_v9.x.x/flow_v0.77.0
/**
* This is an autogenerated libdef stub for:
*
* 'react-emotion'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'react-emotion' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'react-emotion/dist/emotion.umd.min' {
declare module.exports: any;
}
declare module 'react-emotion/dist/index.cjs' {
declare module.exports: any;
}
declare module 'react-emotion/dist/index.esm' {
declare module.exports: any;
}
declare module 'react-emotion/macro' {
declare module.exports: any;
}
declare module 'react-emotion/src/index' {
declare module.exports: any;
}
// Filename aliases
declare module 'react-emotion/dist/emotion.umd.min.js' {
declare module.exports: $Exports<'react-emotion/dist/emotion.umd.min'>;
}
declare module 'react-emotion/dist/index.cjs.js' {
declare module.exports: $Exports<'react-emotion/dist/index.cjs'>;
}
declare module 'react-emotion/dist/index.esm.js' {
declare module.exports: $Exports<'react-emotion/dist/index.esm'>;
}
declare module 'react-emotion/macro.js' {
declare module.exports: $Exports<'react-emotion/macro'>;
}
declare module 'react-emotion/src/index.js' {
declare module.exports: $Exports<'react-emotion/src/index'>;
}

@ -1,158 +0,0 @@
// flow-typed signature: 7ef7e99bfa7953a438470755d51dc345
// flow-typed version: 107feb8c45/react-router-dom_v4.x.x/flow_>=v0.53.x
declare module "react-router-dom" {
declare export class BrowserRouter extends React$Component<{
basename?: string,
forceRefresh?: boolean,
getUserConfirmation?: GetUserConfirmation,
keyLength?: number,
children?: React$Node
}> {}
declare export class HashRouter extends React$Component<{
basename?: string,
getUserConfirmation?: GetUserConfirmation,
hashType?: "slash" | "noslash" | "hashbang",
children?: React$Node
}> {}
declare export class Link extends React$Component<{
to: string | LocationShape,
replace?: boolean,
children?: React$Node
}> {}
declare export class NavLink extends React$Component<{
to: string | LocationShape,
activeClassName?: string,
className?: string,
activeStyle?: Object,
style?: Object,
isActive?: (match: Match, location: Location) => boolean,
children?: React$Node,
exact?: boolean,
strict?: boolean
}> {}
// NOTE: Below are duplicated from react-router. If updating these, please
// update the react-router and react-router-native types as well.
declare export type Location = {
pathname: string,
search: string,
hash: string,
state?: any,
key?: string
};
declare export type LocationShape = {
pathname?: string,
search?: string,
hash?: string,
state?: any
};
declare export type HistoryAction = "PUSH" | "REPLACE" | "POP";
declare export type RouterHistory = {
length: number,
location: Location,
action: HistoryAction,
listen(
callback: (location: Location, action: HistoryAction) => void
): () => void,
push(path: string | LocationShape, state?: any): void,
replace(path: string | LocationShape, state?: any): void,
go(n: number): void,
goBack(): void,
goForward(): void,
canGo?: (n: number) => boolean,
block(
callback: (location: Location, action: HistoryAction) => boolean
): void,
// createMemoryHistory
index?: number,
entries?: Array<Location>
};
declare export type Match = {
params: { [key: string]: ?string },
isExact: boolean,
path: string,
url: string
};
declare export type ContextRouter = {|
history: RouterHistory,
location: Location,
match: Match
|};
declare export type GetUserConfirmation = (
message: string,
callback: (confirmed: boolean) => void
) => void;
declare type StaticRouterContext = {
url?: string
};
declare export class StaticRouter extends React$Component<{
basename?: string,
location?: string | Location,
context: StaticRouterContext,
children?: React$Node
}> {}
declare export class MemoryRouter extends React$Component<{
initialEntries?: Array<LocationShape | string>,
initialIndex?: number,
getUserConfirmation?: GetUserConfirmation,
keyLength?: number,
children?: React$Node
}> {}
declare export class Router extends React$Component<{
history: RouterHistory,
children?: React$Node
}> {}
declare export class Prompt extends React$Component<{
message: string | ((location: Location) => string | boolean),
when?: boolean
}> {}
declare export class Redirect extends React$Component<{
to: string | LocationShape,
push?: boolean
}> {}
declare export class Route extends React$Component<{
component?: React$ComponentType<*>,
render?: (router: ContextRouter) => React$Node,
children?: React$ComponentType<ContextRouter> | React$Node,
path?: string,
exact?: boolean,
strict?: boolean
}> {}
declare export class Switch extends React$Component<{
children?: React$Node
}> {}
declare export function withRouter<P>(
Component: React$ComponentType<{| ...ContextRouter, ...P |}>
): React$ComponentType<P>;
declare type MatchPathOptions = {
path?: string,
exact?: boolean,
sensitive?: boolean,
strict?: boolean
};
declare export function matchPath(
pathname: string,
options?: MatchPathOptions | string
): null | Match;
}

@ -1,199 +0,0 @@
// flow-typed signature: 4fb3dfe55b5d1711432e74df5fa80adc
// flow-typed version: <<STUB>>/react-router_v4.3.1/flow_v0.81.0
/**
* This is an autogenerated libdef stub for:
*
* 'react-router'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'react-router' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'react-router/es/generatePath' {
declare module.exports: any;
}
declare module 'react-router/es/index' {
declare module.exports: any;
}
declare module 'react-router/es/matchPath' {
declare module.exports: any;
}
declare module 'react-router/es/MemoryRouter' {
declare module.exports: any;
}
declare module 'react-router/es/Prompt' {
declare module.exports: any;
}
declare module 'react-router/es/Redirect' {
declare module.exports: any;
}
declare module 'react-router/es/Route' {
declare module.exports: any;
}
declare module 'react-router/es/Router' {
declare module.exports: any;
}
declare module 'react-router/es/RouterContext' {
declare module.exports: any;
}
declare module 'react-router/es/StaticRouter' {
declare module.exports: any;
}
declare module 'react-router/es/Switch' {
declare module.exports: any;
}
declare module 'react-router/es/withRouter' {
declare module.exports: any;
}
declare module 'react-router/generatePath' {
declare module.exports: any;
}
declare module 'react-router/matchPath' {
declare module.exports: any;
}
declare module 'react-router/MemoryRouter' {
declare module.exports: any;
}
declare module 'react-router/Prompt' {
declare module.exports: any;
}
declare module 'react-router/Redirect' {
declare module.exports: any;
}
declare module 'react-router/Route' {
declare module.exports: any;
}
declare module 'react-router/Router' {
declare module.exports: any;
}
declare module 'react-router/StaticRouter' {
declare module.exports: any;
}
declare module 'react-router/Switch' {
declare module.exports: any;
}
declare module 'react-router/umd/react-router' {
declare module.exports: any;
}
declare module 'react-router/umd/react-router.min' {
declare module.exports: any;
}
declare module 'react-router/withRouter' {
declare module.exports: any;
}
// Filename aliases
declare module 'react-router/es/generatePath.js' {
declare module.exports: $Exports<'react-router/es/generatePath'>;
}
declare module 'react-router/es/index.js' {
declare module.exports: $Exports<'react-router/es/index'>;
}
declare module 'react-router/es/matchPath.js' {
declare module.exports: $Exports<'react-router/es/matchPath'>;
}
declare module 'react-router/es/MemoryRouter.js' {
declare module.exports: $Exports<'react-router/es/MemoryRouter'>;
}
declare module 'react-router/es/Prompt.js' {
declare module.exports: $Exports<'react-router/es/Prompt'>;
}
declare module 'react-router/es/Redirect.js' {
declare module.exports: $Exports<'react-router/es/Redirect'>;
}
declare module 'react-router/es/Route.js' {
declare module.exports: $Exports<'react-router/es/Route'>;
}
declare module 'react-router/es/Router.js' {
declare module.exports: $Exports<'react-router/es/Router'>;
}
declare module 'react-router/es/RouterContext.js' {
declare module.exports: $Exports<'react-router/es/RouterContext'>;
}
declare module 'react-router/es/StaticRouter.js' {
declare module.exports: $Exports<'react-router/es/StaticRouter'>;
}
declare module 'react-router/es/Switch.js' {
declare module.exports: $Exports<'react-router/es/Switch'>;
}
declare module 'react-router/es/withRouter.js' {
declare module.exports: $Exports<'react-router/es/withRouter'>;
}
declare module 'react-router/generatePath.js' {
declare module.exports: $Exports<'react-router/generatePath'>;
}
declare module 'react-router/index' {
declare module.exports: $Exports<'react-router'>;
}
declare module 'react-router/index.js' {
declare module.exports: $Exports<'react-router'>;
}
declare module 'react-router/matchPath.js' {
declare module.exports: $Exports<'react-router/matchPath'>;
}
declare module 'react-router/MemoryRouter.js' {
declare module.exports: $Exports<'react-router/MemoryRouter'>;
}
declare module 'react-router/Prompt.js' {
declare module.exports: $Exports<'react-router/Prompt'>;
}
declare module 'react-router/Redirect.js' {
declare module.exports: $Exports<'react-router/Redirect'>;
}
declare module 'react-router/Route.js' {
declare module.exports: $Exports<'react-router/Route'>;
}
declare module 'react-router/Router.js' {
declare module.exports: $Exports<'react-router/Router'>;
}
declare module 'react-router/StaticRouter.js' {
declare module.exports: $Exports<'react-router/StaticRouter'>;
}
declare module 'react-router/Switch.js' {
declare module.exports: $Exports<'react-router/Switch'>;
}
declare module 'react-router/umd/react-router.js' {
declare module.exports: $Exports<'react-router/umd/react-router'>;
}
declare module 'react-router/umd/react-router.min.js' {
declare module.exports: $Exports<'react-router/umd/react-router.min'>;
}
declare module 'react-router/withRouter.js' {
declare module.exports: $Exports<'react-router/withRouter'>;
}

@ -1,108 +0,0 @@
// flow-typed signature: fce684fdcdf9c74363f2c0bf136dbf88
// flow-typed version: <<STUB>>/request_v2.83.0/flow_v0.64.0
/**
* This is an autogenerated libdef stub for:
*
* 'request'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'request' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'request/lib/auth' {
declare module.exports: any;
}
declare module 'request/lib/cookies' {
declare module.exports: any;
}
declare module 'request/lib/getProxyFromURI' {
declare module.exports: any;
}
declare module 'request/lib/har' {
declare module.exports: any;
}
declare module 'request/lib/helpers' {
declare module.exports: any;
}
declare module 'request/lib/multipart' {
declare module.exports: any;
}
declare module 'request/lib/oauth' {
declare module.exports: any;
}
declare module 'request/lib/querystring' {
declare module.exports: any;
}
declare module 'request/lib/redirect' {
declare module.exports: any;
}
declare module 'request/lib/tunnel' {
declare module.exports: any;
}
declare module 'request/request' {
declare module.exports: any;
}
// Filename aliases
declare module 'request/index' {
declare module.exports: $Exports<'request'>;
}
declare module 'request/index.js' {
declare module.exports: $Exports<'request'>;
}
declare module 'request/lib/auth.js' {
declare module.exports: $Exports<'request/lib/auth'>;
}
declare module 'request/lib/cookies.js' {
declare module.exports: $Exports<'request/lib/cookies'>;
}
declare module 'request/lib/getProxyFromURI.js' {
declare module.exports: $Exports<'request/lib/getProxyFromURI'>;
}
declare module 'request/lib/har.js' {
declare module.exports: $Exports<'request/lib/har'>;
}
declare module 'request/lib/helpers.js' {
declare module.exports: $Exports<'request/lib/helpers'>;
}
declare module 'request/lib/multipart.js' {
declare module.exports: $Exports<'request/lib/multipart'>;
}
declare module 'request/lib/oauth.js' {
declare module.exports: $Exports<'request/lib/oauth'>;
}
declare module 'request/lib/querystring.js' {
declare module.exports: $Exports<'request/lib/querystring'>;
}
declare module 'request/lib/redirect.js' {
declare module.exports: $Exports<'request/lib/redirect'>;
}
declare module 'request/lib/tunnel.js' {
declare module.exports: $Exports<'request/lib/tunnel'>;
}
declare module 'request/request.js' {
declare module.exports: $Exports<'request/request'>;
}

@ -1,18 +0,0 @@
// flow-typed signature: 1dff23447d5e18f5ac2b05aaec7cfb74
// flow-typed version: a453e98ea2/rimraf_v2.x.x/flow_>=v0.25.0
declare module 'rimraf' {
declare type Options = {
maxBusyTries?: number,
emfileWait?: number,
glob?: boolean,
disableGlob?: boolean
};
declare type Callback = (err: ?Error, path: ?string) => void;
declare module.exports: {
(f: string, opts?: Options | Callback, callback?: Callback): void;
sync(path: string, opts?: Options): void;
};
}

@ -1,198 +0,0 @@
// flow-typed signature: dc381ee55406f66b7272c6343db0834b
// flow-typed version: da30fe6876/semver_v5.1.x/flow_>=v0.25.x
declare module "semver" {
declare type Release =
| "major"
| "premajor"
| "minor"
| "preminor"
| "patch"
| "prepatch"
| "prerelease";
// The supported comparators are taken from the source here:
// https://github.com/npm/node-semver/blob/8bd070b550db2646362c9883c8d008d32f66a234/semver.js#L623
declare type Operator =
| "==="
| "!=="
| "=="
| "="
| "" // Not sure why you would want this, but whatever.
| "!="
| ">"
| ">="
| "<"
| "<=";
declare class SemVer {
build: Array<string>;
loose: ?boolean;
major: number;
minor: number;
patch: number;
prerelease: Array<string | number>;
raw: string;
version: string;
constructor(version: string | SemVer, loose?: boolean): SemVer;
compare(other: string | SemVer): -1 | 0 | 1;
compareMain(other: string | SemVer): -1 | 0 | 1;
comparePre(other: string | SemVer): -1 | 0 | 1;
format(): string;
inc(release: Release, identifier: string): this;
}
declare class Comparator {
loose?: boolean;
operator: Operator;
semver: SemVer;
value: string;
constructor(comp: string | Comparator, loose?: boolean): Comparator;
parse(comp: string): void;
test(version: string): boolean;
}
declare class Range {
loose: ?boolean;
raw: string;
set: Array<Array<Comparator>>;
constructor(range: string | Range, loose?: boolean): Range;
format(): string;
parseRange(range: string): Array<Comparator>;
test(version: string): boolean;
toString(): string;
}
declare var SEMVER_SPEC_VERSION: string;
declare var re: Array<RegExp>;
declare var src: Array<string>;
// Functions
declare function valid(v: string | SemVer, loose?: boolean): string | null;
declare function clean(v: string | SemVer, loose?: boolean): string | null;
declare function inc(
v: string | SemVer,
release: Release,
loose?: boolean,
identifier?: string
): string | null;
declare function inc(
v: string | SemVer,
release: Release,
identifier: string
): string | null;
declare function major(v: string | SemVer, loose?: boolean): number;
declare function minor(v: string | SemVer, loose?: boolean): number;
declare function patch(v: string | SemVer, loose?: boolean): number;
// Comparison
declare function gt(
v1: string | SemVer,
v2: string | SemVer,
loose?: boolean
): boolean;
declare function gte(
v1: string | SemVer,
v2: string | SemVer,
loose?: boolean
): boolean;
declare function lt(
v1: string | SemVer,
v2: string | SemVer,
loose?: boolean
): boolean;
declare function lte(
v1: string | SemVer,
v2: string | SemVer,
loose?: boolean
): boolean;
declare function eq(
v1: string | SemVer,
v2: string | SemVer,
loose?: boolean
): boolean;
declare function neq(
v1: string | SemVer,
v2: string | SemVer,
loose?: boolean
): boolean;
declare function cmp(
v1: string | SemVer,
comparator: Operator,
v2: string | SemVer,
loose?: boolean
): boolean;
declare function compare(
v1: string | SemVer,
v2: string | SemVer,
loose?: boolean
): -1 | 0 | 1;
declare function rcompare(
v1: string | SemVer,
v2: string | SemVer,
loose?: boolean
): -1 | 0 | 1;
declare function compareLoose(
v1: string | SemVer,
v2: string | SemVer
): -1 | 0 | 1;
declare function diff(v1: string | SemVer, v2: string | SemVer): ?Release;
declare function sort(
list: Array<string | SemVer>,
loose?: boolean
): Array<string | SemVer>;
declare function rsort(
list: Array<string | SemVer>,
loose?: boolean
): Array<string | SemVer>;
declare function compareIdentifiers(
v1: string | SemVer,
v2: string | SemVer
): -1 | 0 | 1;
declare function rcompareIdentifiers(
v1: string | SemVer,
v2: string | SemVer
): -1 | 0 | 1;
// Ranges
declare function validRange(
range: string | Range,
loose?: boolean
): string | null;
declare function satisfies(
version: string | SemVer,
range: string | Range,
loose?: boolean
): boolean;
declare function maxSatisfying(
versions: Array<string | SemVer>,
range: string | Range,
loose?: boolean
): string | SemVer | null;
declare function gtr(
version: string | SemVer,
range: string | Range,
loose?: boolean
): boolean;
declare function ltr(
version: string | SemVer,
range: string | Range,
loose?: boolean
): boolean;
declare function outside(
version: string | SemVer,
range: string | Range,
hilo: ">" | "<",
loose?: boolean
): boolean;
// Not explicitly documented, or deprecated
declare function parse(version: string, loose?: boolean): ?SemVer;
declare function toComparators(
range: string | Range,
loose?: boolean
): Array<Array<string>>;
}

@ -1,52 +0,0 @@
// flow-typed signature: 92c970084ff90673c82c72604aa26f27
// flow-typed version: <<STUB>>/supertest_v3.x.x/flow_v0.69.0
/**
* This is an autogenerated libdef stub for:
*
* 'supertest'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'supertest' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'supertest/lib/agent' {
declare module.exports: any;
}
declare module 'supertest/lib/test' {
declare module.exports: any;
}
declare module 'supertest/test/supertest' {
declare module.exports: any;
}
// Filename aliases
declare module 'supertest/index' {
declare module.exports: $Exports<'supertest'>;
}
declare module 'supertest/index.js' {
declare module.exports: $Exports<'supertest'>;
}
declare module 'supertest/lib/agent.js' {
declare module.exports: $Exports<'supertest/lib/agent'>;
}
declare module 'supertest/lib/test.js' {
declare module.exports: $Exports<'supertest/lib/test'>;
}
declare module 'supertest/test/supertest.js' {
declare module.exports: $Exports<'supertest/test/supertest'>;
}

@ -4,10 +4,14 @@ module.exports = {
name: 'verdaccio-unit-jest', name: 'verdaccio-unit-jest',
verbose: true, verbose: true,
collectCoverage: true, collectCoverage: true,
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
testURL: 'http://localhost', testURL: 'http://localhost',
testRegex: '(test/unit.*\\.spec)\\.js', testRegex: '(test/unit.*\\.spec)\\.ts',
// Some unit tests rely on data folders that look like packages. This confuses jest-hast-map // Some unit tests rely on data folders that look like packages. This confuses jest-hast-map
// when it tries to scan for package.json files. // when it tries to scan for package.json files.
transform: {
'^.+\\.(js|jsx|ts|tsx)$': 'babel-jest'
},
modulePathIgnorePatterns: [ modulePathIgnorePatterns: [
'<rootDir>/test/unit/partials/mock-store/.*/package.json', '<rootDir>/test/unit/partials/mock-store/.*/package.json',
'<rootDir>/test/functional/store/.*/package.json', '<rootDir>/test/functional/store/.*/package.json',

@ -15,6 +15,7 @@
"verdaccio": "./bin/verdaccio" "verdaccio": "./bin/verdaccio"
}, },
"dependencies": { "dependencies": {
"@verdaccio/commons-api": "0.1.2",
"@verdaccio/local-storage": "2.2.1", "@verdaccio/local-storage": "2.2.1",
"@verdaccio/readme": "1.0.4", "@verdaccio/readme": "1.0.4",
"@verdaccio/streams": "2.0.0", "@verdaccio/streams": "2.0.0",
@ -27,15 +28,14 @@
"compression": "1.7.4", "compression": "1.7.4",
"cookies": "0.7.3", "cookies": "0.7.3",
"cors": "2.8.5", "cors": "2.8.5",
"dayjs": "1.8.14", "dayjs": "1.8.15",
"envinfo": "7.3.1", "envinfo": "7.3.1",
"express": "4.16.4", "express": "4.17.1",
"handlebars": "4.1.2", "handlebars": "4.1.2",
"http-errors": "1.7.3",
"js-yaml": "3.13.1", "js-yaml": "3.13.1",
"jsonwebtoken": "8.5.1", "jsonwebtoken": "8.5.1",
"kleur": "3.0.3", "kleur": "3.0.3",
"lodash": "4.17.11", "lodash": "4.17.14",
"lunr-mutable-indexes": "2.3.2", "lunr-mutable-indexes": "2.3.2",
"marked": "0.7.0", "marked": "0.7.0",
"mime": "2.4.4", "mime": "2.4.4",
@ -52,35 +52,37 @@
"@commitlint/cli": "8.0.0", "@commitlint/cli": "8.0.0",
"@commitlint/config-conventional": "8.0.0", "@commitlint/config-conventional": "8.0.0",
"@octokit/rest": "16.28.2", "@octokit/rest": "16.28.2",
"@types/async": "3.0.0",
"@types/bunyan": "1.8.6",
"@types/express": "4.17.0",
"@types/handlebars": "4.1.0",
"@types/http-errors": "1.6.1",
"@types/jest": "24.0.15",
"@types/lodash": "4.14.136",
"@types/mime": "2.0.1",
"@types/minimatch": "3.0.3",
"@types/node": "12.6.2",
"@types/request": "2.48.2",
"@typescript-eslint/eslint-plugin": "1.12.0",
"@verdaccio/babel-preset": "0.2.1", "@verdaccio/babel-preset": "0.2.1",
"@verdaccio/types": "5.0.2", "@verdaccio/eslint-config": "0.0.1",
"codecov": "3.3.0", "@verdaccio/types": "5.2.2",
"codecov": "3.5.0",
"cross-env": "5.2.0", "cross-env": "5.2.0",
"eslint": "5.16.0", "eslint": "5.16.0",
"eslint-config-google": "0.12.0",
"eslint-config-prettier": "4.2.0",
"eslint-plugin-babel": "5.3.0",
"eslint-plugin-flowtype": "3.6.1",
"eslint-plugin-import": "2.17.2",
"eslint-plugin-jest": "22.5.1",
"eslint-plugin-jsx-a11y": "6.2.1",
"eslint-plugin-prettier": "3.0.1",
"eslint-plugin-verdaccio": "0.0.5",
"flow-bin": "0.81.0",
"flow-runtime": "0.17.0",
"get-stdin": "7.0.0", "get-stdin": "7.0.0",
"husky": "2.1.0", "husky": "2.7.0",
"in-publish": "2.0.0", "in-publish": "2.0.0",
"jest": "24.8.0", "jest": "24.8.0",
"jest-environment-node": "24.8.0", "jest-environment-node": "24.8.0",
"lint-staged": "8.1.5", "lint-staged": "8.2.1",
"nock": "10.0.6", "nock": "10.0.6",
"prettier": "1.17.0",
"puppeteer": "1.8.0", "puppeteer": "1.8.0",
"rimraf": "2.6.3", "rimraf": "2.6.3",
"standard-version": "6.0.1", "standard-version": "6.0.1",
"supertest": "4.0.2", "supertest": "4.0.2",
"verdaccio-auth-memory": "0.0.4", "typescript": "3.5.3",
"verdaccio-auth-memory": "1.1.5",
"verdaccio-memory": "2.0.0" "verdaccio-memory": "2.0.0"
}, },
"keywords": [ "keywords": [
@ -97,7 +99,8 @@
"scripts": { "scripts": {
"release": "standard-version -a -s", "release": "standard-version -a -s",
"prepublish": "in-publish && npm run code:build || not-in-publish", "prepublish": "in-publish && npm run code:build || not-in-publish",
"flow": "flow check", "type-check": "tsc --noEmit",
"type-check:watch": "npm run type-check -- --watch",
"pretest": "npm run code:build", "pretest": "npm run code:build",
"test": "npm run test:unit", "test": "npm run test:unit",
"test:clean": "npx jest --clearCache", "test:clean": "npx jest --clearCache",
@ -107,12 +110,13 @@
"test:all": "npm run test && npm run test:functional && npm run test:e2e", "test:all": "npm run test && npm run test:functional && npm run test:e2e",
"pre:ci": "npm run lint", "pre:ci": "npm run lint",
"coverage:publish": "codecov", "coverage:publish": "codecov",
"lint": "npm run flow && npm run lint:js", "lint": "npm run type-check && npm run lint:ts",
"lint:js": "eslint .", "lint:ts": "eslint . --ext .js,.ts",
"dev:start": "cross-env BABEL_ENV=registry babel-node src/lib/cli", "format": "prettier --single-quote --trailing-comma none --write \"{src,test}/**/*.ts\"",
"code:build": "cross-env BABEL_ENV=registry babel src/ --out-dir build/ --copy-files", "dev:start": "cross-env BABEL_ENV=registry babel-node --extensions \".ts,.tsx\" src/lib/cli",
"code:docker-build": "cross-env BABEL_ENV=registry-docker babel src/ --out-dir build/ --copy-files", "code:build": "cross-env BABEL_ENV=registry babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\" --source-maps inline",
"build:docker": "docker build -t verdaccio . --no-cache" "code:docker-build": "cross-env BABEL_ENV=registry-docker babel src/ --out-dir build/ --copy-files --extensions \".ts,.tsx\"",
"build:docker": "docker build -t verdaccio/verdaccio:local . --no-cache"
}, },
"engines": { "engines": {
"node": ">=8", "node": ">=8",

@ -1,15 +1,10 @@
/**
* @prettier
* @flow
*/
import _ from 'lodash'; import _ from 'lodash';
import type { $Application } from 'express'; import { Application } from 'express';
import type { $ResponseExtend, $RequestExtend, $NextFunctionVer } from '../../../types'; import { $ResponseExtend, $RequestExtend, $NextFunctionVer } from '../../../types';
export default (app: $Application, selfPath: string) => { export default (app: Application, selfPath: string): void => {
// Hook for tests only // Hook for tests only
app.get('/-/_debug', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { app.get('/-/_debug', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
const doGarbabeCollector = _.isNil(global.gc) === false; const doGarbabeCollector = _.isNil(global.gc) === false;
if (doGarbabeCollector) { if (doGarbabeCollector) {
@ -18,6 +13,7 @@ export default (app: $Application, selfPath: string) => {
next({ next({
pid: process.pid, pid: process.pid,
// @ts-ignore
main: process.mainModule.filename, main: process.mainModule.filename,
conf: selfPath, conf: selfPath,
mem: process.memoryUsage(), mem: process.memoryUsage(),

@ -1,25 +1,22 @@
/**
* @prettier
* @flow
*/
import mime from 'mime'; import mime from 'mime';
import _ from 'lodash'; import _ from 'lodash';
import { media, allow } from '../../middleware'; import { media, allow } from '../../middleware';
import type { Router } from 'express'; import{ Router } from 'express';
import type { IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler } from '../../../../types'; import{ IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler } from '../../../../types';
import { API_MESSAGE, HTTP_STATUS, DIST_TAGS } from '../../../lib/constants'; import { API_MESSAGE, HTTP_STATUS, DIST_TAGS } from '../../../lib/constants';
import { VerdaccioError } from '@verdaccio/commons-api';
import { Package } from '@verdaccio/types';
export default function(route: Router, auth: IAuth, storage: IStorageHandler) { export default function(route: Router, auth: IAuth, storage: IStorageHandler): void {
const can = allow(auth); const can = allow(auth);
const tag_package_version = function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { const tag_package_version = function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): $NextFunctionVer {
if (_.isString(req.body) === false) { if (_.isString(req.body) === false) {
return next('route'); return next('route');
} }
const tags = {}; const tags = {};
tags[req.params.tag] = req.body; tags[req.params.tag] = req.body;
storage.mergeTags(req.params.package, tags, function(err) { storage.mergeTags(req.params.package, tags, function(err: Error): $NextFunctionVer {
if (err) { if (err) {
return next(err); return next(err);
} }
@ -35,10 +32,10 @@ export default function(route: Router, auth: IAuth, storage: IStorageHandler) {
route.put('/-/package/:package/dist-tags/:tag', can('publish'), media(mime.getType('json')), tag_package_version); route.put('/-/package/:package/dist-tags/:tag', can('publish'), media(mime.getType('json')), tag_package_version);
route.delete('/-/package/:package/dist-tags/:tag', can('publish'), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { route.delete('/-/package/:package/dist-tags/:tag', can('publish'), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
const tags = {}; const tags = {};
tags[req.params.tag] = null; tags[req.params.tag] = null;
storage.mergeTags(req.params.package, tags, function(err) { storage.mergeTags(req.params.package, tags, function(err: VerdaccioError): $NextFunctionVer {
if (err) { if (err) {
return next(err); return next(err);
} }
@ -49,12 +46,12 @@ export default function(route: Router, auth: IAuth, storage: IStorageHandler) {
}); });
}); });
route.get('/-/package/:package/dist-tags', can('access'), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { route.get('/-/package/:package/dist-tags', can('access'), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
storage.getPackage({ storage.getPackage({
name: req.params.package, name: req.params.package,
uplinksLook: true, uplinksLook: true,
req, req,
callback: function(err, info) { callback: function(err: VerdaccioError, info: Package): $NextFunctionVer {
if (err) { if (err) {
return next(err); return next(err);
} }
@ -64,8 +61,8 @@ export default function(route: Router, auth: IAuth, storage: IStorageHandler) {
}); });
}); });
route.post('/-/package/:package/dist-tags', can('publish'), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { route.post('/-/package/:package/dist-tags', can('publish'), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
storage.mergeTags(req.params.package, req.body, function(err) { storage.mergeTags(req.params.package, req.body, function(err: VerdaccioError): $NextFunctionVer {
if (err) { if (err) {
return next(err); return next(err);
} }

@ -1,23 +1,19 @@
/**
* @prettier
* @flow
*/
import _ from 'lodash'; import _ from 'lodash';
import { allow } from '../../middleware'; import { allow } from '../../middleware';
import { convertDistRemoteToLocalTarballUrls, getVersion, ErrorCode } from '../../../lib/utils'; import { convertDistRemoteToLocalTarballUrls, getVersion, ErrorCode } from '../../../lib/utils';
import { HEADERS, DIST_TAGS, API_ERROR } from '../../../lib/constants'; import { HEADERS, DIST_TAGS, API_ERROR } from '../../../lib/constants';
import type { Router } from 'express'; import { Router } from 'express';
import type { Config } from '@verdaccio/types'; import { Config, Package } from '@verdaccio/types';
import type { IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler } from '../../../../types'; import { IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler } from '../../../../types';
const downloadStream = (packageName: string, filename: string, storage: any, req: $RequestExtend, res: $ResponseExtend) => { const downloadStream = (packageName: string, filename: string, storage: any, req: $RequestExtend, res: $ResponseExtend): void => {
const stream = storage.getTarball(packageName, filename); const stream = storage.getTarball(packageName, filename);
stream.on('content-length', function(content) { stream.on('content-length', function(content): void {
res.header('Content-Length', content); res.header('Content-Length', content);
}); });
stream.on('error', function(err) {
stream.on('error', function(err): void {
return res.report_error(err); return res.report_error(err);
}); });
@ -25,11 +21,11 @@ const downloadStream = (packageName: string, filename: string, storage: any, req
stream.pipe(res); stream.pipe(res);
}; };
export default function(route: Router, auth: IAuth, storage: IStorageHandler, config: Config) { export default function(route: Router, auth: IAuth, storage: IStorageHandler, config: Config): void {
const can = allow(auth); const can = allow(auth);
// TODO: anonymous user? // TODO: anonymous user?
route.get('/:package/:version?', can('access'), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { route.get('/:package/:version?', can('access'), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
const getPackageMetaCallback = function(err, metadata) { const getPackageMetaCallback = function(err, metadata: Package): void {
if (err) { if (err) {
return next(err); return next(err);
} }
@ -65,13 +61,13 @@ export default function(route: Router, auth: IAuth, storage: IStorageHandler, co
}); });
}); });
route.get('/:scopedPackage/-/:scope/:filename', can('access'), function(req: $RequestExtend, res: $ResponseExtend) { route.get('/:scopedPackage/-/:scope/:filename', can('access'), function(req: $RequestExtend, res: $ResponseExtend): void {
const { scopedPackage, filename } = req.params; const { scopedPackage, filename } = req.params;
downloadStream(scopedPackage, filename, storage, req, res); downloadStream(scopedPackage, filename, storage, req, res);
}); });
route.get('/:package/-/:filename', can('access'), function(req: $RequestExtend, res: $ResponseExtend) { route.get('/:package/-/:filename', can('access'), function(req: $RequestExtend, res: $ResponseExtend): void {
downloadStream(req.params.package, req.params.filename, storage, req, res); downloadStream(req.params.package, req.params.filename, storage, req, res);
}); });
} }

@ -3,8 +3,8 @@
* @flow * @flow
*/ */
import type { Router } from 'express'; import { Router } from 'express';
import type { $RequestExtend, $ResponseExtend, $NextFunctionVer } from '../../../../types'; import { $RequestExtend, $ResponseExtend, $NextFunctionVer } from '../../../../types';
export default function(route: Router) { export default function(route: Router) {
route.get('/-/ping', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { route.get('/-/ping', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {

@ -1,8 +1,3 @@
/**
* @prettier
* @flow
*/
import _ from 'lodash'; import _ from 'lodash';
import Path from 'path'; import Path from 'path';
import mime from 'mime'; import mime from 'mime';
@ -13,10 +8,10 @@ import { media, expectJson, allow } from '../../middleware';
import { notify } from '../../../lib/notify'; import { notify } from '../../../lib/notify';
import star from './star'; import star from './star';
import type { Router } from 'express'; import { Router } from 'express';
import type { Config, Callback, MergeTags, Version } from '@verdaccio/types'; import { Config, Callback, MergeTags, Version, Package } from '@verdaccio/types';
import type { IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler } from '../../../../types'; import { IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler } from '../../../../types';
import logger from '../../../lib/logger'; import { logger } from '../../../lib/logger';
export default function publish(router: Router, auth: IAuth, storage: IStorageHandler, config: Config) { export default function publish(router: Router, auth: IAuth, storage: IStorageHandler, config: Config) {
const can = allow(auth); const can = allow(auth);
@ -76,7 +71,7 @@ export function publishPackage(storage: IStorageHandler, config: Config) {
}; };
const afterChange = function(error, okMessage, metadata) { const afterChange = function(error, okMessage, metadata) {
const metadataCopy = { ...metadata }; const metadataCopy: Package = { ...metadata };
const { _attachments, versions } = metadataCopy; const { _attachments, versions } = metadataCopy;
// old npm behavior, if there is no attachments // old npm behavior, if there is no attachments
@ -129,7 +124,7 @@ export function publishPackage(storage: IStorageHandler, config: Config) {
try { try {
await notify(metadataCopy, config, req.remote_user, `${metadataCopy.name}@${versionToPublish}`); await notify(metadataCopy, config, req.remote_user, `${metadataCopy.name}@${versionToPublish}`);
} catch (error) { } catch (error) {
logger.logger.error({ error }, 'notify batch service has failed: @{error}'); logger.error({ error }, 'notify batch service has failed: @{error}');
} }
res.status(HTTP_STATUS.CREATED); res.status(HTTP_STATUS.CREATED);

@ -1,64 +1,64 @@
// @flow // @flow
import { USERS, HTTP_STATUS } from '../../../lib/constants'; import { USERS, HTTP_STATUS } from '../../../lib/constants';
import type {$Response} from 'express'; import {Response} from 'express';
import type {$RequestExtend, $NextFunctionVer, IStorageHandler} from '../../../../types'; import {$RequestExtend, $NextFunctionVer, IStorageHandler} from '../../../../types';
import _ from 'lodash'; import _ from 'lodash';
export default function(storage: IStorageHandler) { export default function(storage: IStorageHandler) {
const validateInputs = (newUsers, localUsers, username, isStar) => { const validateInputs = (newUsers, localUsers, username, isStar) => {
const isExistlocalUsers = _.isNil(localUsers[username]) === false; const isExistlocalUsers = _.isNil(localUsers[username]) === false;
if (isStar && isExistlocalUsers && localUsers[username]) { if (isStar && isExistlocalUsers && localUsers[username]) {
return true; return true;
} else if (!isStar && isExistlocalUsers) { } else if (!isStar && isExistlocalUsers) {
return false; return false;
} else if (!isStar && !isExistlocalUsers) { } else if (!isStar && !isExistlocalUsers) {
return true; return true;
} else { } else {
return false; return false;
} }
}; };
return (req: $RequestExtend, res: $Response, next: $NextFunctionVer): void => { return (req: $RequestExtend, res: Response, next: $NextFunctionVer): void => {
const name = req.params.package; const name = req.params.package;
const afterChangePackage = function(err) { const afterChangePackage = function(err?: Error) {
if (err) { if (err) {
return next(err); return next(err);
} }
res.status(HTTP_STATUS.OK); res.status(HTTP_STATUS.OK);
next({ next({
success: true, success: true,
}); });
}; };
storage.getPackage({ storage.getPackage({
name, name,
req, req,
callback: function(err, info) { callback: function(err, info) {
if (err) { if (err) {
return next(err); return next(err);
} }
const newStarUser = req.body[USERS]; const newStarUser = req.body[USERS];
const remoteUsername = req.remote_user.name; const remoteUsername = req.remote_user.name;
const localStarUsers = info[USERS]; const localStarUsers = info[USERS];
// Check is star or unstar // Check is star or unstar
const isStar = Object.keys(newStarUser).includes(remoteUsername); const isStar = Object.keys(newStarUser).includes(remoteUsername);
if (_.isNil(localStarUsers) === false && validateInputs(newStarUser, localStarUsers, remoteUsername, isStar)) { if (_.isNil(localStarUsers) === false && validateInputs(newStarUser, localStarUsers, remoteUsername, isStar)) {
return afterChangePackage(); return afterChangePackage();
} }
const users = isStar ? { const users = isStar ? {
...localStarUsers, ...localStarUsers,
[remoteUsername]: true, [remoteUsername]: true,
} : _.reduce(localStarUsers, (users, value, key) => { } : _.reduce(localStarUsers, (users, value, key) => {
if (key !== remoteUsername) { if (key !== remoteUsername) {
users[key] = value; users[key] = value;
} }
return users; return users;
}, {}); }, {});
storage.changePackage(name, { ...info, users}, req.body._rev, function(err) { storage.changePackage(name, { ...info, users}, req.body._rev, function(err) {
afterChangePackage(err); afterChangePackage(err);
}); });
}, },
}); });
}; };
} }

@ -1,32 +0,0 @@
/**
* @prettier
* @flow
*/
import { USERS, HTTP_STATUS } from '../../../lib/constants';
import type { $Response, Router } from 'express';
import type { $RequestExtend, $NextFunctionVer, IStorageHandler } from '../../../../types';
import type { Package } from '@verdaccio/types';
export default function(route: Router, storage: IStorageHandler) {
route.get(
'/-/_view/starredByUser',
(req: $RequestExtend, res: $Response, next: $NextFunctionVer): void => {
const remoteUsername = req.remote_user.name;
storage.getLocalDatabase((err, localPackages: Package[]) => {
if (err) {
return next(err);
}
const filteredPackages = localPackages.filter(localPackage =>
localPackage[USERS] ? Object.keys(localPackage[USERS]).indexOf(remoteUsername) >= 0 : false
);
res.status(HTTP_STATUS.OK);
next({
rows: filteredPackages.map(filteredPackage => ({
value: filteredPackage.name,
})),
});
});
}
);
}

@ -0,0 +1,37 @@
/**
* @prettier
*/
import _ from 'lodash';
import { USERS, HTTP_STATUS } from '../../../lib/constants';
import { Response, Router } from 'express';
import { $RequestExtend, $NextFunctionVer, IStorageHandler } from '../../../../types';
import { Package } from '@verdaccio/types';
type Packages = Package[];
export default function(route: Router, storage: IStorageHandler) {
route.get(
'/-/_view/starredByUser',
(req: $RequestExtend, res: Response, next: $NextFunctionVer): void => {
const remoteUsername = req.remote_user.name;
storage.getLocalDatabase((err, localPackages: Packages) => {
if (err) {
return next(err);
}
const filteredPackages: Packages = localPackages.filter((localPackage: Package) =>
localPackage[USERS] ? _.keys(localPackage[USERS]).indexOf(remoteUsername) >= 0 : false
);
res.status(HTTP_STATUS.OK);
next({
rows: filteredPackages.map((filteredPackage: Package) => ({
value: filteredPackage.name,
})),
});
});
}
);
}

@ -1,36 +1,31 @@
/**
* @prettier
* @flow
*/
import _ from 'lodash'; import _ from 'lodash';
import Cookies from 'cookies'; import Cookies from 'cookies';
import { ErrorCode } from '../../../lib/utils'; import { ErrorCode } from '../../../lib/utils';
import { API_ERROR, API_MESSAGE, HTTP_STATUS } from '../../../lib/constants'; import { API_ERROR, API_MESSAGE, HTTP_STATUS } from '../../../lib/constants';
import { createRemoteUser, createSessionToken, getApiToken, getAuthenticatedMessage, validatePassword } from '../../../lib/auth-utils'; import { createRemoteUser, createSessionToken, getApiToken, getAuthenticatedMessage, validatePassword } from '../../../lib/auth-utils';
import logger from '../../../lib/logger'; import { logger } from '../../../lib/logger';
import type { Config, RemoteUser } from '@verdaccio/types'; import { Config, RemoteUser } from '@verdaccio/types';
import type { $Response, Router } from 'express'; import { Response, Router } from 'express';
import type { $RequestExtend, $ResponseExtend, $NextFunctionVer, IAuth } from '../../../../types'; import { $RequestExtend, $ResponseExtend, $NextFunctionVer, IAuth } from '../../../../types';
export default function(route: Router, auth: IAuth, config: Config) { export default function(route: Router, auth: IAuth, config: Config): void {
route.get('/-/user/:org_couchdb_user', function(req: $RequestExtend, res: $Response, next: $NextFunctionVer) { route.get('/-/user/:org_couchdb_user', function(req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
res.status(HTTP_STATUS.OK); res.status(HTTP_STATUS.OK);
next({ next({
ok: getAuthenticatedMessage(req.remote_user.name), ok: getAuthenticatedMessage(req.remote_user.name),
}); });
}); });
route.put('/-/user/:org_couchdb_user/:_rev?/:revision?', function(req: $RequestExtend, res: $Response, next: $NextFunctionVer) { route.put('/-/user/:org_couchdb_user/:_rev?/:revision?', function(req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
const { name, password } = req.body; const { name, password } = req.body;
const remoteName = req.remote_user.name; const remoteName = req.remote_user.name;
if (_.isNil(remoteName) === false && _.isNil(name) === false && remoteName === name) { if (_.isNil(remoteName) === false && _.isNil(name) === false && remoteName === name) {
auth.authenticate(name, password, async function callbackAuthenticate(err, groups) { auth.authenticate(name, password, async function callbackAuthenticate(err, groups): Promise<void> {
if (err) { if (err) {
logger.logger.trace({ name, err }, 'authenticating for user @{username} failed. Error: @{err.message}'); logger.trace({ name, err }, 'authenticating for user @{username} failed. Error: @{err.message}');
return next(ErrorCode.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.BAD_USERNAME_PASSWORD)); return next(ErrorCode.getCode(HTTP_STATUS.UNAUTHORIZED, API_ERROR.BAD_USERNAME_PASSWORD));
} }
@ -50,7 +45,7 @@ export default function(route: Router, auth: IAuth, config: Config) {
return next(ErrorCode.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.PASSWORD_SHORT())); return next(ErrorCode.getCode(HTTP_STATUS.BAD_REQUEST, API_ERROR.PASSWORD_SHORT()));
} }
auth.add_user(name, password, async function(err, user) { auth.add_user(name, password, async function(err, user): Promise<void> {
if (err) { if (err) {
if (err.status >= HTTP_STATUS.BAD_REQUEST && err.status < HTTP_STATUS.INTERNAL_ERROR) { if (err.status >= HTTP_STATUS.BAD_REQUEST && err.status < HTTP_STATUS.INTERNAL_ERROR) {
// With npm registering is the same as logging in, // With npm registering is the same as logging in,
@ -73,7 +68,7 @@ export default function(route: Router, auth: IAuth, config: Config) {
} }
}); });
route.delete('/-/user/token/*', function(req: $RequestExtend, res: $Response, next: $NextFunctionVer) { route.delete('/-/user/token/*', function(req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
res.status(HTTP_STATUS.OK); res.status(HTTP_STATUS.OK);
next({ next({
ok: API_MESSAGE.LOGGED_OUT, ok: API_MESSAGE.LOGGED_OUT,
@ -82,7 +77,7 @@ export default function(route: Router, auth: IAuth, config: Config) {
// placeholder 'cause npm require to be authenticated to publish // placeholder 'cause npm require to be authenticated to publish
// we do not do any real authentication yet // we do not do any real authentication yet
route.post('/_session', Cookies.express(), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { route.post('/_session', Cookies.express(), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
res.cookies.set('AuthSession', String(Math.random()), createSessionToken()); res.cookies.set('AuthSession', String(Math.random()), createSessionToken());
next({ next({

@ -1,30 +1,37 @@
/**
* @prettier
*/
// @flow
import _ from 'lodash'; import _ from 'lodash';
import { API_ERROR, APP_ERROR, HTTP_STATUS, SUPPORT_ERRORS } from '../../../../lib/constants'; import { API_ERROR, APP_ERROR, HTTP_STATUS, SUPPORT_ERRORS } from '../../../../lib/constants';
import { ErrorCode } from '../../../../lib/utils'; import { ErrorCode } from '../../../../lib/utils';
import { validatePassword } from '../../../../lib/auth-utils'; import { validatePassword } from '../../../../lib/auth-utils';
import type { $Response, Router } from 'express'; import { Response, Router } from 'express';
import type { $NextFunctionVer, $RequestExtend, IAuth } from '../../../../../types'; import { $NextFunctionVer, $RequestExtend, IAuth } from '../../../../../types';
export default function(route: Router, auth: IAuth) { export interface Profile {
const buildProfile = name => ({ tfa: boolean;
tfa: false, name: string;
name, email: string;
email: '', email_verified: boolean;
email_verified: false, created: string;
created: '', updated: string;
updated: '', cidr_whitelist: string[] | null;
cidr_whitelist: null, fullname: string;
fullname: '', }
});
route.get('/-/npm/v1/user', function(req: $RequestExtend, res: $Response, next: $NextFunctionVer) { export default function(route: Router, auth: IAuth): void {
function buildProfile(name: string): Profile {
return {
tfa: false,
name,
email: '',
email_verified: false,
created: '',
updated: '',
cidr_whitelist: null,
fullname: '',
};
}
route.get('/-/npm/v1/user', function(req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
if (_.isNil(req.remote_user.name) === false) { if (_.isNil(req.remote_user.name) === false) {
return next(buildProfile(req.remote_user.name)); return next(buildProfile(req.remote_user.name));
} }
@ -35,7 +42,7 @@ export default function(route: Router, auth: IAuth) {
}); });
}); });
route.post('/-/npm/v1/user', function(req: $RequestExtend, res: $Response, next: $NextFunctionVer) { route.post('/-/npm/v1/user', function(req: $RequestExtend, res: Response, next: $NextFunctionVer): void {
if (_.isNil(req.remote_user.name)) { if (_.isNil(req.remote_user.name)) {
res.status(HTTP_STATUS.UNAUTHORIZED); res.status(HTTP_STATUS.UNAUTHORIZED);
return next({ return next({
@ -53,17 +60,22 @@ export default function(route: Router, auth: IAuth) {
/* eslint new-cap:off */ /* eslint new-cap:off */
} }
auth.changePassword(name, password.old, password.new, (err, isUpdated) => { auth.changePassword(
if (_.isNull(err) === false) { name,
return next(ErrorCode.getCode(err.status, err.message) || ErrorCode.getConflict(err.message)); password.old,
} password.new,
(err, isUpdated): $NextFunctionVer => {
if (_.isNull(err) === false) {
return next(ErrorCode.getCode(err.status, err.message) || ErrorCode.getConflict(err.message));
}
if (isUpdated) { if (isUpdated) {
return next(buildProfile(req.remote_user.name)); return next(buildProfile(req.remote_user.name));
} else { } else {
return next(ErrorCode.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR)); return next(ErrorCode.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));
}
} }
}); );
} else if (_.isNil(tfa) === false) { } else if (_.isNil(tfa) === false) {
return next(ErrorCode.getCode(HTTP_STATUS.SERVICE_UNAVAILABLE, SUPPORT_ERRORS.TFA_DISABLED)); return next(ErrorCode.getCode(HTTP_STATUS.SERVICE_UNAVAILABLE, SUPPORT_ERRORS.TFA_DISABLED));
} else { } else {

@ -1,27 +0,0 @@
/**
* @prettier
* @flow
*/
import type { $Response, Router } from 'express';
import type { $RequestExtend, $NextFunctionVer } from '../../../../types';
export default function(route: Router) {
route.get(
'/whoami',
(req: $RequestExtend, res: $Response, next: $NextFunctionVer): void => {
if (req.headers.referer === 'whoami') {
next({ username: req.remote_user.name });
} else {
next('route');
}
}
);
route.get(
'/-/whoami',
(req: $RequestExtend, res: $Response, next: $NextFunctionVer): mixed => {
next({ username: req.remote_user.name });
}
);
}

@ -0,0 +1,22 @@
import { Response, Router } from 'express';
import { $RequestExtend, $NextFunctionVer } from '../../../../types';
export default function(route: Router): void {
route.get(
'/whoami',
(req: $RequestExtend, res: Response, next: $NextFunctionVer): void => {
if (req.headers.referer === 'whoami') {
next({ username: req.remote_user.name });
} else {
next('route');
}
}
);
route.get(
'/-/whoami',
(req: $RequestExtend, res: Response, next: $NextFunctionVer): any => {
next({ username: req.remote_user.name });
}
);
}

@ -3,8 +3,8 @@
* @flow * @flow
*/ */
import type { IAuth, IStorageHandler } from '../../../types'; import { IAuth, IStorageHandler } from '../../../types';
import type { Config } from '@verdaccio/types'; import { Config } from '@verdaccio/types';
import express from 'express'; import express from 'express';
import bodyParser from 'body-parser'; import bodyParser from 'body-parser';

@ -1,12 +1,8 @@
/**
* @prettier
* @flow
*/
import _ from 'lodash'; import _ from 'lodash';
import express from 'express'; import express, { Application } from 'express';
import compression from 'compression'; import compression from 'compression';
import cors from 'cors'; import cors from 'cors';
import { HttpError } from 'http-errors';
import Storage from '../lib/storage'; import Storage from '../lib/storage';
import loadPlugin from '../lib/plugin-loader'; import loadPlugin from '../lib/plugin-loader';
import hookDebug from './debug'; import hookDebug from './debug';
@ -17,16 +13,14 @@ import { API_ERROR, HTTP_STATUS } from '../lib/constants';
import AppConfig from '../lib/config'; import AppConfig from '../lib/config';
import webAPI from './web/api'; import webAPI from './web/api';
import web from './web'; import web from './web';
import { $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler, IAuth } from '../../types';
import type { $Application } from 'express'; import { Config as IConfig, IPluginMiddleware, IPluginStorageFilter } from '@verdaccio/types';
import type { $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler, IAuth } from '../../types';
import type { Config as IConfig, IPluginMiddleware, IPluginStorageFilter } from '@verdaccio/types';
import { setup, logger } from '../lib/logger'; import { setup, logger } from '../lib/logger';
import { log, final, errorReportingMiddleware } from './middleware'; import { log, final, errorReportingMiddleware } from './middleware';
const defineAPI = function(config: IConfig, storage: IStorageHandler) { const defineAPI = function(config: IConfig, storage: IStorageHandler): any {
const auth: IAuth = new Auth(config); const auth: IAuth = new Auth(config);
const app: $Application = express(); const app: Application = express();
// run in production mode by default, just in case // run in production mode by default, just in case
// it shouldn't make any difference anyway // it shouldn't make any difference anyway
app.set('env', process.env.NODE_ENV || 'production'); app.set('env', process.env.NODE_ENV || 'production');
@ -35,14 +29,14 @@ const defineAPI = function(config: IConfig, storage: IStorageHandler) {
// Router setup // Router setup
app.use(log); app.use(log);
app.use(errorReportingMiddleware); app.use(errorReportingMiddleware);
app.use(function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { app.use(function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
res.setHeader('X-Powered-By', config.user_agent); res.setHeader('X-Powered-By', config.user_agent);
next(); next();
}); });
app.use(compression()); app.use(compression());
app.get('/favicon.ico', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { app.get('/favicon.ico', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
req.url = '/-/static/favicon.png'; req.url = '/-/static/favicon.png';
next(); next();
}); });
@ -57,10 +51,11 @@ const defineAPI = function(config: IConfig, storage: IStorageHandler) {
config: config, config: config,
logger: logger, logger: logger,
}; };
const plugins = loadPlugin(config, config.middlewares, plugin_params, function(plugin: IPluginMiddleware) {
const plugins: IPluginMiddleware<IConfig>[] = loadPlugin(config, config.middlewares, plugin_params, function(plugin: IPluginMiddleware<IConfig>) {
return plugin.register_middlewares; return plugin.register_middlewares;
}); });
plugins.forEach(plugin => { plugins.forEach((plugin: IPluginMiddleware<IConfig>) => {
plugin.register_middlewares(app, auth, storage); plugin.register_middlewares(app, auth, storage);
}); });
@ -82,7 +77,7 @@ const defineAPI = function(config: IConfig, storage: IStorageHandler) {
next(ErrorCode.getNotFound(API_ERROR.FILE_NOT_FOUND)); next(ErrorCode.getNotFound(API_ERROR.FILE_NOT_FOUND));
}); });
app.use(function(err, req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { app.use(function(err: HttpError, req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
if (_.isError(err)) { if (_.isError(err)) {
if (err.code === 'ECONNABORT' && res.statusCode === HTTP_STATUS.NOT_MODIFIED) { if (err.code === 'ECONNABORT' && res.statusCode === HTTP_STATUS.NOT_MODIFIED) {
return next(); return next();
@ -104,7 +99,7 @@ const defineAPI = function(config: IConfig, storage: IStorageHandler) {
return app; return app;
}; };
export default (async function(configHash: any) { export default (async function(configHash: any): Promise<any> {
setup(configHash.logs); setup(configHash.logs);
const config: IConfig = new AppConfig(_.cloneDeep(configHash)); const config: IConfig = new AppConfig(_.cloneDeep(configHash));
// register middleware plugins // register middleware plugins
@ -112,7 +107,7 @@ export default (async function(configHash: any) {
config: config, config: config,
logger: logger, logger: logger,
}; };
const filters = loadPlugin(config, config.filters || {}, plugin_params, (plugin: IPluginStorageFilter) => plugin.filter_metadata); const filters = loadPlugin(config, config.filters || {}, plugin_params, (plugin: IPluginStorageFilter<IConfig>) => plugin.filter_metadata);
const storage: IStorageHandler = new Storage(config); const storage: IStorageHandler = new Storage(config);
// waits until init calls have been initialized // waits until init calls have been initialized
await storage.init(config, filters); await storage.init(config, filters);

@ -8,12 +8,13 @@ import _ from 'lodash';
import { validateName as utilValidateName, validatePackage as utilValidatePackage, getVersionFromTarball, isObject, ErrorCode } from '../lib/utils'; import { validateName as utilValidateName, validatePackage as utilValidatePackage, getVersionFromTarball, isObject, ErrorCode } from '../lib/utils';
import { API_ERROR, HEADER_TYPE, HEADERS, HTTP_STATUS, TOKEN_BASIC, TOKEN_BEARER } from '../lib/constants'; import { API_ERROR, HEADER_TYPE, HEADERS, HTTP_STATUS, TOKEN_BASIC, TOKEN_BEARER } from '../lib/constants';
import { stringToMD5 } from '../lib/crypto-utils'; import { stringToMD5 } from '../lib/crypto-utils';
import type { $ResponseExtend, $RequestExtend, $NextFunctionVer, IAuth } from '../../types'; import { $ResponseExtend, $RequestExtend, $NextFunctionVer, IAuth } from '../../types';
import type { Config } from '@verdaccio/types'; import { Config, Package } from '@verdaccio/types';
import { logger } from '../lib/logger'; import { logger } from '../lib/logger';
import { VerdaccioError } from '@verdaccio/commons-api';
export function match(regexp: RegExp) { export function match(regexp: RegExp): any {
return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer, value: string) { return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer, value: string): void {
if (regexp.exec(value)) { if (regexp.exec(value)) {
next(); next();
} else { } else {
@ -22,7 +23,7 @@ export function match(regexp: RegExp) {
}; };
} }
export function setSecurityWebHeaders(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { export function setSecurityWebHeaders(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
// disable loading in frames (clickjacking, etc.) // disable loading in frames (clickjacking, etc.)
res.header(HEADERS.FRAMES_OPTIONS, 'deny'); res.header(HEADERS.FRAMES_OPTIONS, 'deny');
// avoid stablish connections outside of domain // avoid stablish connections outside of domain
@ -36,7 +37,7 @@ export function setSecurityWebHeaders(req: $RequestExtend, res: $ResponseExtend,
// flow: express does not match properly // flow: express does not match properly
// flow info https://github.com/flowtype/flow-typed/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+express // flow info https://github.com/flowtype/flow-typed/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+express
export function validateName(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer, value: string, name: string) { export function validateName(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer, value: string, name: string): void {
if (value.charAt(0) === '-') { if (value.charAt(0) === '-') {
// special case in couchdb usually // special case in couchdb usually
next('route'); next('route');
@ -49,7 +50,7 @@ export function validateName(req: $RequestExtend, res: $ResponseExtend, next: $N
// flow: express does not match properly // flow: express does not match properly
// flow info https://github.com/flowtype/flow-typed/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+express // flow info https://github.com/flowtype/flow-typed/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+express
export function validatePackage(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer, value: string, name: string) { export function validatePackage(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer, value: string, name: string): void {
if (value.charAt(0) === '-') { if (value.charAt(0) === '-') {
// special case in couchdb usually // special case in couchdb usually
next('route'); next('route');
@ -60,8 +61,8 @@ export function validatePackage(req: $RequestExtend, res: $ResponseExtend, next:
} }
} }
export function media(expect: string) { export function media(expect: string | null): any {
return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
if (req.headers[HEADER_TYPE.CONTENT_TYPE] !== expect) { if (req.headers[HEADER_TYPE.CONTENT_TYPE] !== expect) {
next(ErrorCode.getCode(HTTP_STATUS.UNSUPPORTED_MEDIA, 'wrong content-type, expect: ' + expect + ', got: ' + req.headers[HEADER_TYPE.CONTENT_TYPE])); next(ErrorCode.getCode(HTTP_STATUS.UNSUPPORTED_MEDIA, 'wrong content-type, expect: ' + expect + ', got: ' + req.headers[HEADER_TYPE.CONTENT_TYPE]));
} else { } else {
@ -70,7 +71,7 @@ export function media(expect: string) {
}; };
} }
export function encodeScopePackage(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { export function encodeScopePackage(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
if (req.url.indexOf('@') !== -1) { if (req.url.indexOf('@') !== -1) {
// e.g.: /@org/pkg/1.2.3 -> /@org%2Fpkg/1.2.3, /@org%2Fpkg/1.2.3 -> /@org%2Fpkg/1.2.3 // e.g.: /@org/pkg/1.2.3 -> /@org%2Fpkg/1.2.3, /@org%2Fpkg/1.2.3 -> /@org%2Fpkg/1.2.3
req.url = req.url.replace(/^(\/@[^\/%]+)\/(?!$)/, '$1%2F'); req.url = req.url.replace(/^(\/@[^\/%]+)\/(?!$)/, '$1%2F');
@ -78,15 +79,15 @@ export function encodeScopePackage(req: $RequestExtend, res: $ResponseExtend, ne
next(); next();
} }
export function expectJson(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { export function expectJson(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
if (!isObject(req.body)) { if (!isObject(req.body)) {
return next(ErrorCode.getBadRequest("can't parse incoming json")); return next(ErrorCode.getBadRequest("can't parse incoming json"));
} }
next(); next();
} }
export function antiLoop(config: Config) { export function antiLoop(config: Config): Function {
return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
if (req.headers.via != null) { if (req.headers.via != null) {
const arr = req.headers.via.split(','); const arr = req.headers.via.split(',');
@ -101,15 +102,15 @@ export function antiLoop(config: Config) {
}; };
} }
export function allow(auth: IAuth) { export function allow(auth: IAuth): Function {
return function(action: string) { return function(action: string): Function {
return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
req.pause(); req.pause();
const packageName = req.params.scope ? `@${req.params.scope}/${req.params.package}` : req.params.package; const packageName = req.params.scope ? `@${req.params.scope}/${req.params.package}` : req.params.package;
const packageVersion = req.params.filename ? getVersionFromTarball(req.params.filename) : undefined; const packageVersion = req.params.filename ? getVersionFromTarball(req.params.filename) : undefined;
// $FlowFixMe // $FlowFixMe
auth['allow_' + action]({ packageName, packageVersion }, req.remote_user, function(error, allowed) { auth['allow_' + action]({ packageName, packageVersion }, req.remote_user, function(error, allowed): void {
req.resume(); req.resume();
if (error) { if (error) {
next(error); next(error);
@ -125,7 +126,13 @@ export function allow(auth: IAuth) {
}; };
} }
export function final(body: any, req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { export interface MiddlewareError {
error: string;
}
export type FinalBody = Package | MiddlewareError | string;
export function final(body: FinalBody, req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
if (res.statusCode === HTTP_STATUS.UNAUTHORIZED && !res.getHeader(HEADERS.WWW_AUTH)) { if (res.statusCode === HTTP_STATUS.UNAUTHORIZED && !res.getHeader(HEADERS.WWW_AUTH)) {
// they say it's required for 401, so... // they say it's required for 401, so...
res.header(HEADERS.WWW_AUTH, `${TOKEN_BASIC}, ${TOKEN_BEARER}`); res.header(HEADERS.WWW_AUTH, `${TOKEN_BASIC}, ${TOKEN_BEARER}`);
@ -138,15 +145,15 @@ export function final(body: any, req: $RequestExtend, res: $ResponseExtend, next
} }
if (typeof body === 'object' && _.isNil(body) === false) { if (typeof body === 'object' && _.isNil(body) === false) {
if (typeof body.error === 'string') { if (typeof (body as MiddlewareError).error === 'string') {
res._verdaccio_error = body.error; res._verdaccio_error = (body as MiddlewareError).error;
} }
body = JSON.stringify(body, undefined, ' ') + '\n'; body = JSON.stringify(body, undefined, ' ') + '\n';
} }
// don't send etags with errors // don't send etags with errors
if (!res.statusCode || (res.statusCode >= 200 && res.statusCode < 300)) { if (!res.statusCode || (res.statusCode >= HTTP_STATUS.OK && res.statusCode < HTTP_STATUS.MULTIPLE_CHOICES)) {
res.header(HEADERS.ETAG, '"' + stringToMD5(body) + '"'); res.header(HEADERS.ETAG, '"' + stringToMD5(body as string) + '"');
} }
} else { } else {
// send(null), send(204), etc. // send(null), send(204), etc.
@ -168,7 +175,7 @@ export function final(body: any, req: $RequestExtend, res: $ResponseExtend, next
res.send(body); res.send(body);
} }
export function log(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { export function log(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
// logger // logger
req.log = logger.child({ sub: 'in' }); req.log = logger.child({ sub: 'in' });
@ -195,19 +202,22 @@ export function log(req: $RequestExtend, res: $ResponseExtend, next: $NextFuncti
} }
let bytesin = 0; let bytesin = 0;
req.on('data', function(chunk) { req.on('data', function(chunk): void {
bytesin += chunk.length; bytesin += chunk.length;
}); });
let bytesout = 0; let bytesout = 0;
const _write = res.write; const _write = res.write;
res.write = function(buf) { // FIXME: res.write should return boolean
// @ts-ignore
res.write = function(buf): boolean {
bytesout += buf.length; bytesout += buf.length;
/* eslint prefer-rest-params: "off" */ /* eslint prefer-rest-params: "off" */
// @ts-ignore
_write.apply(res, arguments); _write.apply(res, arguments);
}; };
const log = function() { const log = function(): void {
const forwardedFor = req.headers['x-forwarded-for']; const forwardedFor = req.headers['x-forwarded-for'];
const remoteAddress = req.connection.remoteAddress; const remoteAddress = req.connection.remoteAddress;
const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress; const remoteIP = forwardedFor ? `${forwardedFor} via ${remoteAddress}` : remoteAddress;
@ -240,16 +250,17 @@ export function log(req: $RequestExtend, res: $ResponseExtend, next: $NextFuncti
req.originalUrl = req.url; req.originalUrl = req.url;
}; };
req.on('close', function() { req.on('close', function(): void {
log(); log();
}); });
const _end = res.end; const _end = res.end;
res.end = function(buf) { res.end = function(buf): void {
if (buf) { if (buf) {
bytesout += buf.length; bytesout += buf.length;
} }
/* eslint prefer-rest-params: "off" */ /* eslint prefer-rest-params: "off" */
// @ts-ignore
_end.apply(res, arguments); _end.apply(res, arguments);
log(); log();
}; };
@ -257,10 +268,10 @@ export function log(req: $RequestExtend, res: $ResponseExtend, next: $NextFuncti
} }
// Middleware // Middleware
export function errorReportingMiddleware(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { export function errorReportingMiddleware(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
res.report_error = res.report_error =
res.report_error || res.report_error ||
function(err) { function(err: VerdaccioError): void {
if (err.status && err.status >= HTTP_STATUS.BAD_REQUEST && err.status < 600) { if (err.status && err.status >= HTTP_STATUS.BAD_REQUEST && err.status < 600) {
if (_.isNil(res.headersSent) === false) { if (_.isNil(res.headersSent) === false) {
res.status(err.status); res.status(err.status);

@ -1,8 +1,3 @@
/**
* @prettier
* @flow
*/
import { Router } from 'express'; import { Router } from 'express';
import bodyParser from 'body-parser'; import bodyParser from 'body-parser';
import addUserAuthApi from './endpoint/user'; import addUserAuthApi from './endpoint/user';
@ -11,15 +6,15 @@ import addSearchWebApi from './endpoint/search';
import Search from '../../lib/search'; import Search from '../../lib/search';
import { match, validateName, validatePackage, setSecurityWebHeaders } from '../middleware'; import { match, validateName, validatePackage, setSecurityWebHeaders } from '../middleware';
import type { Config } from '@verdaccio/types'; import { Config } from '@verdaccio/types';
import type { IAuth, IStorageHandler } from '../../../types'; import { IAuth, IStorageHandler } from '../../../types';
const route = Router(); /* eslint new-cap: 0 */ const route = Router(); /* eslint new-cap: 0 */
/* /*
This file include all verdaccio only API(Web UI), for npm API please see ../endpoint/ This file include all verdaccio only API(Web UI), for npm API please see ../endpoint/
*/ */
export default function(config: Config, auth: IAuth, storage: IStorageHandler) { export default function(config: Config, auth: IAuth, storage: IStorageHandler): Router {
Search.configureStorage(storage); Search.configureStorage(storage);
// validate all of these params as a package name // validate all of these params as a package name

@ -1,48 +1,52 @@
/**
* @prettier
* @flow
*/
import _ from 'lodash'; import _ from 'lodash';
import { addScope, addGravatarSupport, deleteProperties, sortByName, parseReadme, formatAuthor, convertDistRemoteToLocalTarballUrls } from '../../../lib/utils'; import { addScope, addGravatarSupport, deleteProperties, sortByName, parseReadme, formatAuthor, convertDistRemoteToLocalTarballUrls } from '../../../lib/utils';
import { allow } from '../../middleware'; import { allow } from '../../middleware';
import { DIST_TAGS, HEADER_TYPE, HEADERS, HTTP_STATUS } from '../../../lib/constants'; import { DIST_TAGS, HEADER_TYPE, HEADERS, HTTP_STATUS } from '../../../lib/constants';
import { generateGravatarUrl } from '../../../utils/user'; import { generateGravatarUrl } from '../../../utils/user';
import logger from '../../../lib/logger'; import { logger } from '../../../lib/logger';
import type { Router } from 'express'; import { Router } from 'express';
import type { IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler, $SidebarPackage } from '../../../../types'; import { IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler, $SidebarPackage } from '../../../../types';
import type { Config } from '@verdaccio/types'; import { Config, Package } from '@verdaccio/types';
const getOrder = (order = 'asc') => { const getOrder = (order = 'asc') => {
return order === 'asc'; return order === 'asc';
}; };
function addPackageWebApi(route: Router, storage: IStorageHandler, auth: IAuth, config: Config) { export type PackcageAuthor = Package & { author: any };
function addPackageWebApi(route: Router, storage: IStorageHandler, auth: IAuth, config: Config): void {
const can = allow(auth); const can = allow(auth);
const checkAllow = (name, remoteUser) => const checkAllow = (name, remoteUser): Promise<boolean> =>
new Promise((resolve, reject) => { new Promise(
try { (resolve, reject): void => {
auth.allow_access({ packageName: name }, remoteUser, (err, allowed) => { try {
if (err) { auth.allow_access(
resolve(false); { packageName: name },
} else { remoteUser,
resolve(allowed); (err, allowed): void => {
} if (err) {
}); resolve(false);
} catch (err) { } else {
reject(err); resolve(allowed);
}
}
);
} catch (err) {
reject(err);
}
} }
}); );
// Get list of all visible package // Get list of all visible package
route.get('/packages', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { route.get('/packages', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
storage.getLocalDatabase(async function(err, packages) { storage.getLocalDatabase(async function(err, packages): Promise<void> {
if (err) { if (err) {
throw err; throw err;
} }
async function processPermissionsPackages(packages = []) { async function processPermissionsPackages(packages: PackcageAuthor[] = []): Promise<any> {
const permissions = []; const permissions: PackcageAuthor[] = [];
const packgesCopy = packages.slice(); const packgesCopy = packages.slice();
for (const pkg of packgesCopy) { for (const pkg of packgesCopy) {
const pkgCopy = { ...pkg }; const pkgCopy = { ...pkg };
@ -64,7 +68,7 @@ function addPackageWebApi(route: Router, storage: IStorageHandler, auth: IAuth,
} }
const { web } = config; const { web } = config;
// $FlowFixMe // @ts-ignore
const order: boolean = config.web ? getOrder(web.sort_packages) : true; const order: boolean = config.web ? getOrder(web.sort_packages) : true;
next(sortByName(await processPermissionsPackages(packages), order)); next(sortByName(await processPermissionsPackages(packages), order));
@ -72,14 +76,14 @@ function addPackageWebApi(route: Router, storage: IStorageHandler, auth: IAuth,
}); });
// Get package readme // Get package readme
route.get('/package/readme/(@:scope/)?:package/:version?', can('access'), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { route.get('/package/readme/(@:scope/)?:package/:version?', can('access'), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
const packageName = req.params.scope ? addScope(req.params.scope, req.params.package) : req.params.package; const packageName = req.params.scope ? addScope(req.params.scope, req.params.package) : req.params.package;
storage.getPackage({ storage.getPackage({
name: packageName, name: packageName,
uplinksLook: true, uplinksLook: true,
req, req,
callback: function(err, info) { callback: function(err, info): void {
if (err) { if (err) {
return next(err); return next(err);
} }
@ -90,7 +94,7 @@ function addPackageWebApi(route: Router, storage: IStorageHandler, auth: IAuth,
}); });
}); });
route.get('/sidebar/(@:scope/)?:package', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { route.get('/sidebar/(@:scope/)?:package', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
const packageName: string = req.params.scope ? addScope(req.params.scope, req.params.package) : req.params.package; const packageName: string = req.params.scope ? addScope(req.params.scope, req.params.package) : req.params.package;
storage.getPackage({ storage.getPackage({
@ -98,7 +102,7 @@ function addPackageWebApi(route: Router, storage: IStorageHandler, auth: IAuth,
uplinksLook: true, uplinksLook: true,
keepUpLinkData: true, keepUpLinkData: true,
req, req,
callback: function(err: Error, info: $SidebarPackage) { callback: function(err: Error, info: $SidebarPackage): void {
if (_.isNil(err)) { if (_.isNil(err)) {
let sideBarInfo: any = _.clone(info); let sideBarInfo: any = _.clone(info);
sideBarInfo.versions = convertDistRemoteToLocalTarballUrls(info, req, config.url_prefix).versions; sideBarInfo.versions = convertDistRemoteToLocalTarballUrls(info, req, config.url_prefix).versions;

@ -5,22 +5,24 @@
import Search from '../../../lib/search'; import Search from '../../../lib/search';
import { DIST_TAGS } from '../../../lib/constants'; import { DIST_TAGS } from '../../../lib/constants';
import type { Router } from 'express'; import { Router } from 'express';
import type { IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler } from '../../../../types'; import { IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler } from '../../../../types';
import { Package } from '@verdaccio/types';
function addSearchWebApi(route: Router, storage: IStorageHandler, auth: IAuth) { function addSearchWebApi(route: Router, storage: IStorageHandler, auth: IAuth): void {
// Search package // Search package
route.get('/search/:anything', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) { route.get('/search/:anything', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
const results: any = Search.query(req.params.anything); const results: any = Search.query(req.params.anything);
const packages = []; // FUTURE: figure out here the correct type
const packages: any[] = [];
const getPackageInfo = function(i) { const getPackageInfo = function(i): void {
storage.getPackage({ storage.getPackage({
name: results[i].ref, name: results[i].ref,
uplinksLook: false, uplinksLook: false,
callback: (err, entry) => { callback: (err, entry: Package): void => {
if (!err && entry) { if (!err && entry) {
auth.allow_access({ packageName: entry.name }, req.remote_user, function(err, allowed) { auth.allow_access({ packageName: entry.name }, req.remote_user, function(err, allowed): void {
if (err || !allowed) { if (err || !allowed) {
return; return;
} }

@ -1,63 +0,0 @@
/**
* @prettier
* @flow
*/
import _ from 'lodash';
import { API_ERROR, APP_ERROR, HTTP_STATUS } from '../../../lib/constants';
import type { Router } from 'express';
import type { Config, RemoteUser, JWTSignOptions } from '@verdaccio/types';
import type { IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer } from '../../../../types';
import { ErrorCode } from '../../../lib/utils';
import { getSecurity, validatePassword } from '../../../lib/auth-utils';
function addUserAuthApi(route: Router, auth: IAuth, config: Config) {
route.post('/login', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
const { username, password } = req.body;
auth.authenticate(username, password, async (err, user: RemoteUser) => {
if (err) {
const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;
next(ErrorCode.getCode(errorCode, err.message));
} else {
req.remote_user = user;
const jWTSignOptions: JWTSignOptions = getSecurity(config).web.sign;
next({
token: await auth.jwtEncrypt(user, jWTSignOptions),
username: req.remote_user.name,
});
}
});
});
route.put('/reset_password', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
if (_.isNil(req.remote_user.name)) {
res.status(HTTP_STATUS.UNAUTHORIZED);
return next({
// FUTURE: update to a more meaningful message
message: API_ERROR.MUST_BE_LOGGED,
});
}
const { password } = req.body;
const { name } = req.remote_user;
if (validatePassword(password.new) === false) {
auth.changePassword(name, password.old, password.new, (err, isUpdated) => {
if (_.isNil(err) && isUpdated) {
next({
ok: true,
});
} else {
return next(ErrorCode.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));
}
});
} else {
return next(ErrorCode.getCode(HTTP_STATUS.BAD_REQUEST, APP_ERROR.PASSWORD_VALIDATION));
}
});
}
export default addUserAuthApi;

@ -0,0 +1,72 @@
/**
* @prettier
* @flow
*/
import _ from 'lodash';
import { API_ERROR, APP_ERROR, HTTP_STATUS } from '../../../lib/constants';
import { Router, Response, Request } from 'express';
import { Config, RemoteUser, JWTSignOptions } from '@verdaccio/types';
import { IAuth, $NextFunctionVer } from '../../../../types';
import { ErrorCode } from '../../../lib/utils';
import { getSecurity, validatePassword } from '../../../lib/auth-utils';
function addUserAuthApi(route: Router, auth: IAuth, config: Config): void {
route.post('/login', function(req: Request, res: Response, next: $NextFunctionVer): void {
const { username, password } = req.body;
auth.authenticate(
username,
password,
async (err, user: RemoteUser): Promise<void> => {
if (err) {
const errorCode = err.message ? HTTP_STATUS.UNAUTHORIZED : HTTP_STATUS.INTERNAL_ERROR;
next(ErrorCode.getCode(errorCode, err.message));
} else {
req.remote_user = user;
const jWTSignOptions: JWTSignOptions = getSecurity(config).web.sign;
next({
token: await auth.jwtEncrypt(user, jWTSignOptions),
username: req.remote_user.name,
});
}
}
);
});
route.put('/reset_password', function(req: Request, res: Response, next: $NextFunctionVer): void {
if (_.isNil(req.remote_user.name)) {
res.status(HTTP_STATUS.UNAUTHORIZED);
return next({
// FUTURE: update to a more meaningful message
message: API_ERROR.MUST_BE_LOGGED,
});
}
const { password } = req.body;
const { name } = req.remote_user;
if (validatePassword(password.new) === false) {
auth.changePassword(
name as string,
password.old,
password.new,
(err, isUpdated): void => {
if (_.isNil(err) && isUpdated) {
next({
ok: true,
});
} else {
return next(ErrorCode.getInternalError(API_ERROR.INTERNAL_SERVER_ERROR));
}
}
);
} else {
return next(ErrorCode.getCode(HTTP_STATUS.BAD_REQUEST, APP_ERROR.PASSWORD_VALIDATION));
}
});
}
export default addUserAuthApi;

@ -43,7 +43,7 @@ const sendFileCallback = next => err => {
} }
}; };
module.exports = function(config, auth, storage) { export default function(config, auth, storage) {
Search.configureStorage(storage); Search.configureStorage(storage);
/* eslint new-cap:off */ /* eslint new-cap:off */
const router = express.Router(); const router = express.Router();
@ -109,4 +109,4 @@ module.exports = function(config, auth, storage) {
}); });
return router; return router;
}; }

@ -1,6 +1,5 @@
/** /**
* @prettier * @prettier
* @flow
*/ */
const path = require('path'); const path = require('path');

@ -1,5 +1,6 @@
{ {
"rules": { "rules": {
"no-useless-escape": 0 "no-useless-escape": 0,
"@typescript-eslint/no-non-null-assertion": 0
} }
} }

@ -1,17 +1,12 @@
/**
* @prettier
* @flow
*/
import _ from 'lodash'; import _ from 'lodash';
import { convertPayloadToBase64, ErrorCode } from './utils'; import { convertPayloadToBase64, ErrorCode } from './utils';
import { API_ERROR, HTTP_STATUS, ROLES, TIME_EXPIRATION_7D, TOKEN_BASIC, TOKEN_BEARER, CHARACTER_ENCODING, DEFAULT_MIN_LIMIT_PASSWORD } from './constants'; import { API_ERROR, HTTP_STATUS, ROLES, TIME_EXPIRATION_7D, TOKEN_BASIC, TOKEN_BEARER, DEFAULT_MIN_LIMIT_PASSWORD } from './constants';
import type { RemoteUser, Package, Callback, Config, Security, APITokenOptions, JWTOptions } from '@verdaccio/types'; import { RemoteUser, Package, Callback, Config, Security, APITokenOptions, JWTOptions, IPluginAuth } from '@verdaccio/types';
import type { CookieSessionToken, IAuthWebUI, AuthMiddlewarePayload, AuthTokenHeader, BasicPayload } from '../../types'; import { CookieSessionToken, IAuthWebUI, AuthMiddlewarePayload, AuthTokenHeader, BasicPayload } from '../../types';
import { aesDecrypt, verifyPayload } from './crypto-utils'; import { aesDecrypt, verifyPayload } from './crypto-utils';
export function validatePassword(password: string, minLength: number = DEFAULT_MIN_LIMIT_PASSWORD) { export function validatePassword(password: string, minLength: number = DEFAULT_MIN_LIMIT_PASSWORD): boolean {
return typeof password === 'string' && password.length >= minLength; return typeof password === 'string' && password.length >= minLength;
} }
@ -19,7 +14,7 @@ export function validatePassword(password: string, minLength: number = DEFAULT_M
* Create a RemoteUser object * Create a RemoteUser object
* @return {Object} { name: xx, pluginGroups: [], real_groups: [] } * @return {Object} { name: xx, pluginGroups: [], real_groups: [] }
*/ */
export function createRemoteUser(name: string, pluginGroups: Array<string>): RemoteUser { export function createRemoteUser(name: string, pluginGroups: string[]): RemoteUser {
const isGroupValid: boolean = Array.isArray(pluginGroups); const isGroupValid: boolean = Array.isArray(pluginGroups);
const groups = (isGroupValid ? pluginGroups : []).concat([ROLES.$ALL, ROLES.$AUTH, ROLES.DEPRECATED_ALL, ROLES.DEPRECATED_AUTH, ROLES.ALL]); const groups = (isGroupValid ? pluginGroups : []).concat([ROLES.$ALL, ROLES.$AUTH, ROLES.DEPRECATED_ALL, ROLES.DEPRECATED_AUTH, ROLES.ALL]);
@ -43,8 +38,8 @@ export function createAnonymousRemoteUser(): RemoteUser {
}; };
} }
export function allow_action(action: string) { export function allow_action(action: string): Function {
return function(user: RemoteUser, pkg: Package, callback: Callback) { return function(user: RemoteUser, pkg: Package, callback: Callback): void {
const { name, groups } = user; const { name, groups } = user;
const hasPermission = pkg[action].some(group => name === group || groups.includes(group)); const hasPermission = pkg[action].some(group => name === group || groups.includes(group));
@ -60,9 +55,9 @@ export function allow_action(action: string) {
}; };
} }
export function handleSpecialUnpublish() { export function handleSpecialUnpublish(): any {
return function(user: RemoteUser, pkg: Package, callback: Callback) { return function(user: RemoteUser, pkg: Package, callback: Callback): void {
const action: string = 'unpublish'; const action = 'unpublish';
const hasSupport: boolean = _.isNil(pkg[action]) === false ? pkg[action] : false; const hasSupport: boolean = _.isNil(pkg[action]) === false ? pkg[action] : false;
if (hasSupport === false) { if (hasSupport === false) {
@ -73,17 +68,20 @@ export function handleSpecialUnpublish() {
}; };
} }
export function getDefaultPlugins() { export function getDefaultPlugins(): IPluginAuth<Config> {
return { return {
authenticate(user: string, password: string, cb: Callback) { authenticate(user: string, password: string, cb: Callback): void {
cb(ErrorCode.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD)); cb(ErrorCode.getForbidden(API_ERROR.BAD_USERNAME_PASSWORD));
}, },
add_user(user: string, password: string, cb: Callback) { add_user(user: string, password: string, cb: Callback): void {
return cb(ErrorCode.getConflict(API_ERROR.BAD_USERNAME_PASSWORD)); return cb(ErrorCode.getConflict(API_ERROR.BAD_USERNAME_PASSWORD));
}, },
// FIXME: allow_action and allow_publish should be in the @verdaccio/types
// @ts-ignore
allow_access: allow_action('access'), allow_access: allow_action('access'),
// @ts-ignore
allow_publish: allow_action('publish'), allow_publish: allow_action('publish'),
allow_unpublish: handleSpecialUnpublish(), allow_unpublish: handleSpecialUnpublish(),
}; };
@ -100,6 +98,7 @@ export function createSessionToken(): CookieSessionToken {
const defaultWebTokenOptions: JWTOptions = { const defaultWebTokenOptions: JWTOptions = {
sign: { sign: {
// The expiration token for the website is 7 days
expiresIn: TIME_EXPIRATION_7D, expiresIn: TIME_EXPIRATION_7D,
}, },
verify: {}, verify: {},
@ -107,15 +106,14 @@ const defaultWebTokenOptions: JWTOptions = {
const defaultApiTokenConf: APITokenOptions = { const defaultApiTokenConf: APITokenOptions = {
legacy: true, legacy: true,
sign: {}, };
export const defaultSecurity: Security = {
web: defaultWebTokenOptions,
api: defaultApiTokenConf,
}; };
export function getSecurity(config: Config): Security { export function getSecurity(config: Config): Security {
const defaultSecurity: Security = {
web: defaultWebTokenOptions,
api: defaultApiTokenConf,
};
if (_.isNil(config.security) === false) { if (_.isNil(config.security) === false) {
return _.merge(defaultSecurity, config.security); return _.merge(defaultSecurity, config.security);
} }
@ -127,8 +125,8 @@ export function getAuthenticatedMessage(user: string): string {
return `you are authenticated as '${user}'`; return `you are authenticated as '${user}'`;
} }
export function buildUserBuffer(name: string, password: string) { export function buildUserBuffer(name: string, password: string): Buffer {
return Buffer.from(`${name}:${password}`, CHARACTER_ENCODING.UTF8); return Buffer.from(`${name}:${password}`, 'utf8');
} }
export function isAESLegacy(security: Security): boolean { export function isAESLegacy(security: Security): boolean {
@ -142,8 +140,8 @@ export async function getApiToken(auth: IAuthWebUI, config: Config, remoteUser:
if (isAESLegacy(security)) { if (isAESLegacy(security)) {
// fallback all goes to AES encryption // fallback all goes to AES encryption
return await new Promise(resolve => { return await new Promise((resolve): void => {
resolve(auth.aesEncrypt(buildUserBuffer((remoteUser: any).name, aesPassword)).toString('base64')); resolve(auth.aesEncrypt(buildUserBuffer(remoteUser.name as string, aesPassword)).toString('base64'));
}); });
} else { } else {
// i am wiling to use here _.isNil but flow does not like it yet. // i am wiling to use here _.isNil but flow does not like it yet.
@ -152,8 +150,8 @@ export async function getApiToken(auth: IAuthWebUI, config: Config, remoteUser:
if (jwt && jwt.sign) { if (jwt && jwt.sign) {
return await auth.jwtEncrypt(remoteUser, jwt.sign); return await auth.jwtEncrypt(remoteUser, jwt.sign);
} else { } else {
return await new Promise(resolve => { return await new Promise((resolve): void => {
resolve(auth.aesEncrypt(buildUserBuffer((remoteUser: any).name, aesPassword)).toString('base64')); resolve(auth.aesEncrypt(buildUserBuffer(remoteUser.name as string, aesPassword)).toString('base64'));
}); });
} }
} }
@ -194,11 +192,11 @@ export function parseAESCredentials(authorizationHeader: string, secret: string)
} }
} }
export const expireReasons: Array<string> = ['JsonWebTokenError', 'TokenExpiredError']; export const expireReasons: string[] = ['JsonWebTokenError', 'TokenExpiredError'];
export function verifyJWTPayload(token: string, secret: string): RemoteUser { export function verifyJWTPayload(token: string, secret: string): RemoteUser {
try { try {
const payload: RemoteUser = (verifyPayload(token, secret): RemoteUser); const payload: RemoteUser = verifyPayload(token, secret);
return payload; return payload;
} catch (error) { } catch (error) {

@ -1,9 +1,5 @@
/**
* @prettier
* @flow
*/
import _ from 'lodash'; import _ from 'lodash';
import { VerdaccioError } from '@verdaccio/commons-api';
import { API_ERROR, SUPPORT_ERRORS, TOKEN_BASIC, TOKEN_BEARER } from './constants'; import { API_ERROR, SUPPORT_ERRORS, TOKEN_BASIC, TOKEN_BEARER } from './constants';
import loadPlugin from '../lib/plugin-loader'; import loadPlugin from '../lib/plugin-loader';
@ -23,19 +19,20 @@ import {
import { convertPayloadToBase64, ErrorCode } from './utils'; import { convertPayloadToBase64, ErrorCode } from './utils';
import { getMatchedPackagesSpec } from './config-utils'; import { getMatchedPackagesSpec } from './config-utils';
import type { Config, Logger, Callback, IPluginAuth, RemoteUser, JWTSignOptions, Security, AuthPluginPackage } from '@verdaccio/types'; import { Config, Logger, Callback, IPluginAuth, RemoteUser, JWTSignOptions, Security, AuthPluginPackage } from '@verdaccio/types';
import type { $Response, NextFunction } from 'express'; import { NextFunction } from 'express';
import type { $RequestExtend, IAuth } from '../../types'; import { $RequestExtend, $ResponseExtend, IAuth, AESPayload } from '../../types';
/* eslint-disable @typescript-eslint/no-var-requires */
const LoggerApi = require('./logger'); const LoggerApi = require('./logger');
class Auth implements IAuth { class Auth implements IAuth {
config: Config; public config: Config;
logger: Logger; public logger: Logger;
secret: string; public secret: string;
plugins: Array<any>; public plugins: IPluginAuth<Config>[];
constructor(config: Config) { public constructor(config: Config) {
this.config = config; this.config = config;
this.logger = LoggerApi.logger.child({ sub: 'auth' }); this.logger = LoggerApi.logger.child({ sub: 'auth' });
this.secret = config.secret; this.secret = config.secret;
@ -43,24 +40,30 @@ class Auth implements IAuth {
this._applyDefaultPlugins(); this._applyDefaultPlugins();
} }
_loadPlugin(config: Config) { private _loadPlugin(config: Config): IPluginAuth<Config>[] {
const pluginOptions = { const pluginOptions = {
config, config,
logger: this.logger, logger: this.logger,
}; };
return loadPlugin(config, config.auth, pluginOptions, (plugin: IPluginAuth) => { return loadPlugin<IPluginAuth<Config>>(
const { authenticate, allow_access, allow_publish } = plugin; config,
config.auth,
pluginOptions,
(plugin: IPluginAuth<Config>): boolean => {
const { authenticate, allow_access, allow_publish } = plugin;
return authenticate || allow_access || allow_publish; // @ts-ignore
}); return authenticate || allow_access || allow_publish;
}
);
} }
_applyDefaultPlugins() { private _applyDefaultPlugins(): void {
this.plugins.push(getDefaultPlugins()); this.plugins.push(getDefaultPlugins());
} }
changePassword(username: string, password: string, newPassword: string, cb: Callback) { public changePassword(username: string, password: string, newPassword: string, cb: Callback): void {
const validPlugins = _.filter(this.plugins, plugin => _.isFunction(plugin.changePassword)); const validPlugins = _.filter(this.plugins, plugin => _.isFunction(plugin.changePassword));
if (_.isEmpty(validPlugins)) { if (_.isEmpty(validPlugins)) {
@ -69,34 +72,39 @@ class Auth implements IAuth {
for (const plugin of validPlugins) { for (const plugin of validPlugins) {
this.logger.trace({ username }, 'updating password for @{username}'); this.logger.trace({ username }, 'updating password for @{username}');
plugin.changePassword(username, password, newPassword, (err, profile) => { plugin.changePassword(
if (err) { username,
this.logger.error( password,
{ username, err }, newPassword,
`An error has been produced (err, profile): void => {
if (err) {
this.logger.error(
{ username, err },
`An error has been produced
updating the password for @{username}. Error: @{err.message}` updating the password for @{username}. Error: @{err.message}`
); );
return cb(err); return cb(err);
} }
this.logger.trace({ username }, 'updated password for @{username} was successful'); this.logger.trace({ username }, 'updated password for @{username} was successful');
return cb(null, profile); return cb(null, profile);
}); }
);
} }
} }
authenticate(username: string, password: string, cb: Callback) { public authenticate(username: string, password: string, cb: Callback): void {
const plugins = this.plugins.slice(0); const plugins = this.plugins.slice(0);
const self = this; const self = this;
(function next() { (function next(): void {
const plugin = plugins.shift(); const plugin = plugins.shift() as IPluginAuth<Config>;
if (_.isFunction(plugin.authenticate) === false) { if (_.isFunction(plugin.authenticate) === false) {
return next(); return next();
} }
self.logger.trace({ username }, 'authenticating @{username}'); self.logger.trace({ username }, 'authenticating @{username}');
plugin.authenticate(username, password, function(err, groups) { plugin.authenticate(username, password, function(err, groups): void {
if (err) { if (err) {
self.logger.trace({ username, err }, 'authenticating for user @{username} failed. Error: @{err.message}'); self.logger.trace({ username, err }, 'authenticating for user @{username} failed. Error: @{err.message}');
return cb(err); return cb(err);
@ -127,13 +135,13 @@ class Auth implements IAuth {
})(); })();
} }
add_user(user: string, password: string, cb: Callback) { public add_user(user: string, password: string, cb: Callback): void {
const self = this; const self = this;
const plugins = this.plugins.slice(0); const plugins = this.plugins.slice(0);
this.logger.trace({ user }, 'add user @{user}'); this.logger.trace({ user }, 'add user @{user}');
(function next() { (function next(): void {
const plugin = plugins.shift(); const plugin = plugins.shift() as IPluginAuth<Config>;
let method = 'adduser'; let method = 'adduser';
if (_.isFunction(plugin[method]) === false) { if (_.isFunction(plugin[method]) === false) {
method = 'add_user'; method = 'add_user';
@ -142,7 +150,7 @@ class Auth implements IAuth {
next(); next();
} else { } else {
// p.add_user() execution // p.add_user() execution
plugin[method](user, password, function(err, ok) { plugin[method](user, password, function(err, ok): void {
if (err) { if (err) {
self.logger.trace({ user, err }, 'the user @{user} could not being added. Error: @{err}'); self.logger.trace({ user, err }, 'the user @{user} could not being added. Error: @{err}');
return cb(err); return cb(err);
@ -160,21 +168,20 @@ class Auth implements IAuth {
/** /**
* Allow user to access a package. * Allow user to access a package.
*/ */
allow_access({ packageName, packageVersion }: AuthPluginPackage, user: RemoteUser, callback: Callback) { public allow_access({ packageName, packageVersion }: AuthPluginPackage, user: RemoteUser, callback: Callback): void {
const plugins = this.plugins.slice(0); const plugins = this.plugins.slice(0);
// $FlowFixMe
const pkg = Object.assign({ name: packageName, version: packageVersion }, getMatchedPackagesSpec(packageName, this.config.packages)); const pkg = Object.assign({ name: packageName, version: packageVersion }, getMatchedPackagesSpec(packageName, this.config.packages));
const self = this; const self = this;
this.logger.trace({ packageName }, 'allow access for @{packageName}'); this.logger.trace({ packageName }, 'allow access for @{packageName}');
(function next() { (function next(): void {
const plugin = plugins.shift(); const plugin: IPluginAuth<Config> = plugins.shift() as IPluginAuth<Config>;
if (_.isFunction(plugin.allow_access) === false) { if (_.isNil(plugin) || _.isFunction(plugin.allow_access) === false) {
return next(); return next();
} }
plugin.allow_access(user, pkg, function(err, ok: boolean) { plugin.allow_access!(user, pkg, function(err, ok: boolean): void {
if (err) { if (err) {
self.logger.trace({ packageName, err }, 'forbidden access for @{packageName}. Error: @{err.message}'); self.logger.trace({ packageName, err }, 'forbidden access for @{packageName}. Error: @{err.message}');
return callback(err); return callback(err);
@ -190,31 +197,35 @@ class Auth implements IAuth {
})(); })();
} }
allow_unpublish({ packageName, packageVersion }: AuthPluginPackage, user: string, callback: Callback) { public allow_unpublish({ packageName, packageVersion }: AuthPluginPackage, user: RemoteUser, callback: Callback): void {
// $FlowFixMe
const pkg = Object.assign({ name: packageName, version: packageVersion }, getMatchedPackagesSpec(packageName, this.config.packages)); const pkg = Object.assign({ name: packageName, version: packageVersion }, getMatchedPackagesSpec(packageName, this.config.packages));
this.logger.trace({ packageName }, 'allow unpublish for @{packageName}'); this.logger.trace({ packageName }, 'allow unpublish for @{packageName}');
for (const plugin of this.plugins) { for (const plugin of this.plugins) {
if (_.isFunction(plugin.allow_unpublish) === false) { if (_.isNil(plugin) || _.isFunction(plugin.allow_unpublish) === false) {
continue; continue;
} else { } else {
plugin.allow_unpublish(user, pkg, (err, ok: boolean) => { plugin.allow_unpublish!(
if (err) { user,
this.logger.trace({ packageName }, 'forbidden publish for @{packageName}, it will fallback on unpublish permissions'); pkg,
return callback(err); (err, ok: boolean): void => {
} if (err) {
this.logger.trace({ packageName }, 'forbidden publish for @{packageName}, it will fallback on unpublish permissions');
return callback(err);
}
if (_.isNil(ok) === true) { if (_.isNil(ok) === true) {
this.logger.trace({ packageName }, 'we bypass unpublish for @{packageName}, publish will handle the access'); this.logger.trace({ packageName }, 'we bypass unpublish for @{packageName}, publish will handle the access');
return this.allow_publish(...arguments); // @ts-ignore
} return this.allow_publish(...arguments);
}
if (ok) { if (ok) {
this.logger.trace({ packageName }, 'allowed unpublish for @{packageName}'); this.logger.trace({ packageName }, 'allowed unpublish for @{packageName}');
return callback(null, ok); return callback(null, ok);
}
} }
}); );
} }
} }
} }
@ -222,36 +233,43 @@ class Auth implements IAuth {
/** /**
* Allow user to publish a package. * Allow user to publish a package.
*/ */
allow_publish({ packageName, packageVersion }: AuthPluginPackage, user: string, callback: Callback) { public allow_publish({ packageName, packageVersion }: AuthPluginPackage, user: RemoteUser, callback: Callback): void {
const plugins = this.plugins.slice(0); const plugins = this.plugins.slice(0);
const self = this; const self = this;
// $FlowFixMe
const pkg = Object.assign({ name: packageName, version: packageVersion }, getMatchedPackagesSpec(packageName, this.config.packages)); const pkg = Object.assign({ name: packageName, version: packageVersion }, getMatchedPackagesSpec(packageName, this.config.packages));
this.logger.trace({ packageName }, 'allow publish for @{packageName}'); this.logger.trace({ packageName, plugins: this.plugins.length }, 'allow publish for @{packageName} init | plugins: @{plugins}');
(function next() { (function next(): void {
const plugin = plugins.shift(); const plugin = plugins.shift();
if (_.isFunction(plugin.allow_publish) === false) { if (_.isNil(plugin) || _.isFunction(plugin.allow_publish) === false) {
self.logger.trace({ packageName }, 'allow publish for @{packageName} plugin does not implement allow_publish');
return next(); return next();
} }
plugin.allow_publish(user, pkg, (err, ok: boolean) => { // @ts-ignore
if (err) { plugin.allow_publish(
self.logger.trace({ packageName }, 'forbidden publish for @{packageName}'); user,
return callback(err); pkg,
} (err: VerdaccioError, ok: boolean): void => {
if (_.isNil(err) === false && _.isError(err)) {
self.logger.trace({ packageName }, 'forbidden publish for @{packageName}');
return callback(err);
}
if (ok) { if (ok) {
self.logger.trace({ packageName }, 'allowed publish for @{packageName}'); self.logger.trace({ packageName }, 'allowed publish for @{packageName}');
return callback(null, ok); return callback(null, ok);
}
self.logger.trace({ packageName }, 'allow publish skip validation for @{packageName}');
next(); // cb(null, false) causes next plugin to roll
} }
next(); // cb(null, false) causes next plugin to roll );
});
})(); })();
} }
apiJWTmiddleware() { public apiJWTmiddleware(): Function {
const plugins = this.plugins.slice(0); const plugins = this.plugins.slice(0);
const helpers = { createAnonymousRemoteUser, createRemoteUser }; const helpers = { createAnonymousRemoteUser, createRemoteUser };
for (const plugin of plugins) { for (const plugin of plugins) {
@ -260,10 +278,10 @@ class Auth implements IAuth {
} }
} }
return (req: $RequestExtend, res: $Response, _next: NextFunction) => { return (req: $RequestExtend, res: $ResponseExtend, _next: NextFunction): void => {
req.pause(); req.pause();
const next = function(err) { const next = function(err: VerdaccioError | void): void {
req.resume(); req.resume();
// uncomment this to reject users with bad auth headers // uncomment this to reject users with bad auth headers
// return _next.apply(null, arguments) // return _next.apply(null, arguments)
@ -305,21 +323,25 @@ class Auth implements IAuth {
}; };
} }
_handleJWTAPIMiddleware(req: $RequestExtend, security: Security, secret: string, authorization: string, next: Function) { private _handleJWTAPIMiddleware(req: $RequestExtend, security: Security, secret: string, authorization: string, next: Function): void {
const { scheme, token } = parseAuthTokenHeader(authorization); const { scheme, token } = parseAuthTokenHeader(authorization);
if (scheme.toUpperCase() === TOKEN_BASIC.toUpperCase()) { if (scheme.toUpperCase() === TOKEN_BASIC.toUpperCase()) {
// this should happen when client tries to login with an existing user // this should happen when client tries to login with an existing user
const credentials = convertPayloadToBase64(token).toString(); const credentials = convertPayloadToBase64(token).toString();
const { user, password } = (parseBasicPayload(credentials): any); const { user, password } = parseBasicPayload(credentials) as AESPayload;
this.authenticate(user, password, (err, user) => { this.authenticate(
if (!err) { user,
req.remote_user = user; password,
next(); (err, user): void => {
} else { if (!err) {
req.remote_user = createAnonymousRemoteUser(); req.remote_user = user;
next(err); next();
} else {
req.remote_user = createAnonymousRemoteUser();
next(err);
}
} }
}); );
} else { } else {
// jwt handler // jwt handler
const credentials: any = getMiddlewareCredentials(security, secret, authorization); const credentials: any = getMiddlewareCredentials(security, secret, authorization);
@ -334,40 +356,44 @@ class Auth implements IAuth {
} }
} }
_handleAESMiddleware(req: $RequestExtend, security: Security, secret: string, authorization: string, next: Function) { private _handleAESMiddleware(req: $RequestExtend, security: Security, secret: string, authorization: string, next: Function): void {
const credentials: any = getMiddlewareCredentials(security, secret, authorization); const credentials: any = getMiddlewareCredentials(security, secret, authorization);
if (credentials) { if (credentials) {
const { user, password } = credentials; const { user, password } = credentials;
this.authenticate(user, password, (err, user) => { this.authenticate(
if (!err) { user,
req.remote_user = user; password,
next(); (err, user): void => {
} else { if (!err) {
req.remote_user = createAnonymousRemoteUser(); req.remote_user = user;
next(err); next();
} else {
req.remote_user = createAnonymousRemoteUser();
next(err);
}
} }
}); );
} else { } else {
// we force npm client to ask again with basic authentication // we force npm client to ask again with basic authentication
return next(ErrorCode.getBadRequest(API_ERROR.BAD_AUTH_HEADER)); return next(ErrorCode.getBadRequest(API_ERROR.BAD_AUTH_HEADER));
} }
} }
_isRemoteUserMissing(remote_user: RemoteUser): boolean { private _isRemoteUserMissing(remote_user: RemoteUser): boolean {
return _.isUndefined(remote_user) === false && _.isUndefined(remote_user.name) === false; return _.isUndefined(remote_user) === false && _.isUndefined(remote_user.name) === false;
} }
/** /**
* JWT middleware for WebUI * JWT middleware for WebUI
*/ */
webUIJWTmiddleware() { public webUIJWTmiddleware(): Function {
return (req: $RequestExtend, res: $Response, _next: NextFunction) => { return (req: $RequestExtend, res: $ResponseExtend, _next: NextFunction): void => {
if (this._isRemoteUserMissing(req.remote_user)) { if (this._isRemoteUserMissing(req.remote_user)) {
return _next(); return _next();
} }
req.pause(); req.pause();
const next = err => { const next = (err: VerdaccioError | void): void => {
req.resume(); req.resume();
if (err) { if (err) {
// req.remote_user.error = err.message; // req.remote_user.error = err.message;
@ -410,7 +436,7 @@ class Auth implements IAuth {
}; };
} }
async jwtEncrypt(user: RemoteUser, signOptions: JWTSignOptions): string { public async jwtEncrypt(user: RemoteUser, signOptions: JWTSignOptions): Promise<string> {
const { real_groups, name, groups } = user; const { real_groups, name, groups } = user;
const realGroupsValidated = _.isNil(real_groups) ? [] : real_groups; const realGroupsValidated = _.isNil(real_groups) ? [] : real_groups;
const groupedGroups = _.isNil(groups) ? real_groups : groups.concat(realGroupsValidated); const groupedGroups = _.isNil(groups) ? real_groups : groups.concat(realGroupsValidated);
@ -422,14 +448,13 @@ class Auth implements IAuth {
const token: string = await signPayload(payload, this.secret, signOptions); const token: string = await signPayload(payload, this.secret, signOptions);
// $FlowFixMe
return token; return token;
} }
/** /**
* Encrypt a string. * Encrypt a string.
*/ */
aesEncrypt(buf: Buffer): Buffer { public aesEncrypt(buf: Buffer): Buffer {
return aesEncrypt(buf, this.secret); return aesEncrypt(buf, this.secret);
} }
} }

@ -1,6 +1,5 @@
/** /**
* @prettier * @prettier
* @flow
*/ */
import { assign, isObject, isFunction } from 'lodash'; import { assign, isObject, isFunction } from 'lodash';
@ -8,14 +7,13 @@ import URL from 'url';
import fs from 'fs'; import fs from 'fs';
import http from 'http'; import http from 'http';
import https from 'https'; import https from 'https';
// $FlowFixMe
import constants from 'constants'; import constants from 'constants';
import endPointAPI from '../api/index'; import endPointAPI from '../api/index';
import { getListListenAddresses, resolveConfigPath } from './cli/utils'; import { getListListenAddresses, resolveConfigPath } from './cli/utils';
import { API_ERROR, certPem, csrPem, keyPem } from './constants'; import { API_ERROR, certPem, csrPem, keyPem } from './constants';
import type { Callback } from '@verdaccio/types'; import { Callback } from '@verdaccio/types';
import type { $Application } from 'express'; import { Application } from 'express';
const logger = require('./logger'); const logger = require('./logger');
@ -27,36 +25,38 @@ const logger = require('./logger');
* @param {String} pkgVersion * @param {String} pkgVersion
* @param {String} pkgName * @param {String} pkgName
*/ */
function startVerdaccio(config: any, cliListen: string, configPath: string, pkgVersion: string, pkgName: string, callback: Callback) { function startVerdaccio(config: any, cliListen: string, configPath: string, pkgVersion: string, pkgName: string, callback: Callback): void {
if (isObject(config) === false) { if (isObject(config) === false) {
throw new Error(API_ERROR.CONFIG_BAD_FORMAT); throw new Error(API_ERROR.CONFIG_BAD_FORMAT);
} }
endPointAPI(config).then(app => { endPointAPI(config).then(
const addresses = getListListenAddresses(cliListen, config.listen); (app): void => {
const addresses = getListListenAddresses(cliListen, config.listen);
addresses.forEach(function(addr) { addresses.forEach(function(addr): void {
let webServer; let webServer;
if (addr.proto === 'https') { if (addr.proto === 'https') {
// https must either have key cert and ca or a pfx and (optionally) a passphrase // https must either have key cert and ca or a pfx and (optionally) a passphrase
if (!config.https || !((config.https.key && config.https.cert && config.https.ca) || config.https.pfx)) { if (!config.https || !((config.https.key && config.https.cert && config.https.ca) || config.https.pfx)) {
logHTTPSWarning(configPath); logHTTPSWarning(configPath);
}
webServer = handleHTTPS(app, configPath, config);
} else {
// http
webServer = http.createServer(app);
} }
if (config.server && typeof config.server.keepAliveTimeout !== 'undefined' && config.server.keepAliveTimeout !== 'null') {
// library definition for node is not up to date (doesn't contain recent 8.0 changes)
webServer.keepAliveTimeout = config.server.keepAliveTimeout * 1000;
}
unlinkAddressPath(addr);
webServer = handleHTTPS(app, configPath, config); callback(webServer, addr, pkgName, pkgVersion);
} else { });
// http }
webServer = http.createServer(app); );
}
if (config.server && typeof config.server.keepAliveTimeout !== 'undefined' && config.server.keepAliveTimeout !== 'null') {
// $FlowFixMe library definition for node is not up to date (doesn't contain recent 8.0 changes)
webServer.keepAliveTimeout = config.server.keepAliveTimeout * 1000;
}
unlinkAddressPath(addr);
callback(webServer, addr, pkgName, pkgVersion);
});
});
} }
function unlinkAddressPath(addr) { function unlinkAddressPath(addr) {
@ -120,18 +120,21 @@ function handleHTTPS(app, configPath, config) {
} }
} }
function listenDefaultCallback(webServer: $Application, addr: any, pkgName: string, pkgVersion: string) { function listenDefaultCallback(webServer: Application, addr: any, pkgName: string, pkgVersion: string): void {
webServer webServer
.listen(addr.port || addr.path, addr.host, () => { .listen(
// send a message for tests addr.port || addr.path,
if (isFunction(process.send)) { addr.host,
process.send({ (): void => {
verdaccio_started: true, // send a message for tests
}); if (isFunction(process.send)) {
process.send({
verdaccio_started: true,
});
}
} }
}) )
// $FlowFixMe .on('error', function(err): void {
.on('error', function(err) {
logger.logger.fatal({ err: err }, 'cannot create server: @{err.message}'); logger.logger.fatal({ err: err }, 'cannot create server: @{err.message}');
process.exit(2); process.exit(2);
}); });

@ -22,8 +22,8 @@ if (process.getuid && process.getuid() === 0) {
const MIN_NODE_VERSION = '6.9.0'; const MIN_NODE_VERSION = '6.9.0';
if (semver.satisfies(process.version, `>=${MIN_NODE_VERSION}`) === false) { if (semver.satisfies(process.version, `>=${MIN_NODE_VERSION}`) === false) {
global.console.error(bgRed(`Verdaccio requires at least Node.js ${MIN_NODE_VERSION} or higher, please upgrade your Node.js distribution`)); global.console.error(bgRed(`Verdaccio requires at least Node.js ${MIN_NODE_VERSION} or higher, please upgrade your Node.js distribution`));
process.exit(1); process.exit(1);
} }
process.title = 'verdaccio'; process.title = 'verdaccio';
@ -96,8 +96,8 @@ if (commander.info) {
process.on('uncaughtException', function(err) { process.on('uncaughtException', function(err) {
logger.logger.fatal( { logger.logger.fatal( {
err: err, err: err,
}, },
'uncaught exception, please report this\n@{err.stack}' ); 'uncaught exception, please report this\n@{err.stack}' );
process.exit(255); process.exit(255);
}); });

@ -25,7 +25,7 @@ export const resolveConfigPath = function(storageLocation: string, file: string)
- localhost:5557 - localhost:5557
@return {Array} @return {Array}
*/ */
export function getListListenAddresses(argListen: string, configListen: mixed) { export function getListListenAddresses(argListen: string, configListen: any) {
// command line || config file || default // command line || config file || default
let addresses; let addresses;
if (argListen) { if (argListen) {

@ -6,7 +6,7 @@
import fs from 'fs'; import fs from 'fs';
import _ from 'lodash'; import _ from 'lodash';
import Path from 'path'; import Path from 'path';
import logger from './logger'; import { logger } from './logger';
import mkdirp from 'mkdirp'; import mkdirp from 'mkdirp';
import { folderExists, fileExists } from './utils'; import { folderExists, fileExists } from './utils';
@ -57,7 +57,7 @@ function readDefaultConfig() {
function createConfigFolder(configLocation) { function createConfigFolder(configLocation) {
mkdirp.sync(Path.dirname(configLocation.path)); mkdirp.sync(Path.dirname(configLocation.path));
logger.logger.info({ file: configLocation.path }, 'Creating default config file in @{file}'); logger.info({ file: configLocation.path }, 'Creating default config file in @{file}');
} }
function updateStorageLinks(configLocation, defaultConfig) { function updateStorageLinks(configLocation, defaultConfig) {

@ -9,8 +9,8 @@ import minimatch from 'minimatch';
import { ErrorCode } from './utils'; import { ErrorCode } from './utils';
import type { PackageList, UpLinksConfList } from '@verdaccio/types'; import { PackageList, UpLinksConfList } from '@verdaccio/types';
import type { MatchedPackage } from '../../types'; import { MatchedPackage, LegacyPackageList } from '../../types';
const BLACKLIST = { const BLACKLIST = {
all: true, all: true,
@ -24,7 +24,7 @@ const BLACKLIST = {
* Normalize user list. * Normalize user list.
* @return {Array} * @return {Array}
*/ */
export function normalizeUserList(oldFormat: any, newFormat: any) { export function normalizeUserList(oldFormat: any, newFormat: any): any {
const result = []; const result = [];
/* eslint prefer-rest-params: "off" */ /* eslint prefer-rest-params: "off" */
@ -35,8 +35,10 @@ export function normalizeUserList(oldFormat: any, newFormat: any) {
// if it's a string, split it to array // if it's a string, split it to array
if (_.isString(arguments[i])) { if (_.isString(arguments[i])) {
// @ts-ignore
result.push(arguments[i].split(/\s+/)); result.push(arguments[i].split(/\s+/));
} else if (Array.isArray(arguments[i])) { } else if (Array.isArray(arguments[i])) {
// @ts-ignore
result.push(arguments[i]); result.push(arguments[i]);
} else { } else {
throw ErrorCode.getInternalError('CONFIG: bad package acl (array or string expected): ' + JSON.stringify(arguments[i])); throw ErrorCode.getInternalError('CONFIG: bad package acl (array or string expected): ' + JSON.stringify(arguments[i]));
@ -45,7 +47,7 @@ export function normalizeUserList(oldFormat: any, newFormat: any) {
return _.flatten(result); return _.flatten(result);
} }
export function uplinkSanityCheck(uplinks: UpLinksConfList, users: any = BLACKLIST) { export function uplinkSanityCheck(uplinks: UpLinksConfList, users: any = BLACKLIST): UpLinksConfList {
const newUplinks = _.clone(uplinks); const newUplinks = _.clone(uplinks);
let newUsers = _.clone(users); let newUsers = _.clone(users);
@ -61,7 +63,7 @@ export function uplinkSanityCheck(uplinks: UpLinksConfList, users: any = BLACKLI
return newUplinks; return newUplinks;
} }
export function sanityCheckNames(item: string, users: any) { export function sanityCheckNames(item: string, users: any): any {
assert(item !== 'all' && item !== 'owner' && item !== 'anonymous' && item !== 'undefined' && item !== 'none', 'CONFIG: reserved uplink name: ' + item); assert(item !== 'all' && item !== 'owner' && item !== 'anonymous' && item !== 'undefined' && item !== 'none', 'CONFIG: reserved uplink name: ' + item);
assert(!item.match(/\s/), 'CONFIG: invalid uplink name: ' + item); assert(!item.match(/\s/), 'CONFIG: invalid uplink name: ' + item);
assert(_.isNil(users[item]), 'CONFIG: duplicate uplink name: ' + item); assert(_.isNil(users[item]), 'CONFIG: duplicate uplink name: ' + item);
@ -70,7 +72,7 @@ export function sanityCheckNames(item: string, users: any) {
return users; return users;
} }
export function sanityCheckUplinksProps(configUpLinks: any) { export function sanityCheckUplinksProps(configUpLinks: UpLinksConfList): UpLinksConfList {
const uplinks = _.clone(configUpLinks); const uplinks = _.clone(configUpLinks);
for (const uplink in uplinks) { for (const uplink in uplinks) {
@ -88,7 +90,7 @@ export function sanityCheckUplinksProps(configUpLinks: any) {
* Check whether an uplink can proxy * Check whether an uplink can proxy
*/ */
export function hasProxyTo(pkg: string, upLink: string, packages: PackageList): boolean { export function hasProxyTo(pkg: string, upLink: string, packages: PackageList): boolean {
const matchedPkg: MatchedPackage = (getMatchedPackagesSpec(pkg, packages): MatchedPackage); const matchedPkg: MatchedPackage = getMatchedPackagesSpec(pkg, packages);
const proxyList = typeof matchedPkg !== 'undefined' ? matchedPkg.proxy : []; const proxyList = typeof matchedPkg !== 'undefined' ? matchedPkg.proxy : [];
if (proxyList) { if (proxyList) {
return proxyList.some(curr => upLink === curr); return proxyList.some(curr => upLink === curr);
@ -99,7 +101,6 @@ export function hasProxyTo(pkg: string, upLink: string, packages: PackageList):
export function getMatchedPackagesSpec(pkgName: string, packages: PackageList): MatchedPackage { export function getMatchedPackagesSpec(pkgName: string, packages: PackageList): MatchedPackage {
for (const i in packages) { for (const i in packages) {
// $FlowFixMe
if (minimatch.makeRe(i).exec(pkgName)) { if (minimatch.makeRe(i).exec(pkgName)) {
return packages[i]; return packages[i];
} }
@ -107,8 +108,8 @@ export function getMatchedPackagesSpec(pkgName: string, packages: PackageList):
return; return;
} }
export function normalisePackageAccess(packages: PackageList): PackageList { export function normalisePackageAccess(packages: LegacyPackageList): LegacyPackageList {
const normalizedPkgs: PackageList = { ...packages }; const normalizedPkgs: LegacyPackageList = { ...packages };
// add a default rule for all packages to make writing plugins easier // add a default rule for all packages to make writing plugins easier
if (_.isNil(normalizedPkgs['**'])) { if (_.isNil(normalizedPkgs['**'])) {
normalizedPkgs['**'] = { access: [], publish: [], proxy: [] }; normalizedPkgs['**'] = { access: [], publish: [], proxy: [] };
@ -124,7 +125,6 @@ export function normalisePackageAccess(packages: PackageList): PackageList {
normalizedPkgs[pkg].proxy = normalizeUserList(packages[pkg].proxy_access, packages[pkg].proxy); normalizedPkgs[pkg].proxy = normalizeUserList(packages[pkg].proxy_access, packages[pkg].proxy);
delete normalizedPkgs[pkg].proxy_access; delete normalizedPkgs[pkg].proxy_access;
// if unpublish is not defined, we set to false to fallback in publish access // if unpublish is not defined, we set to false to fallback in publish access
// $FlowFixMe
normalizedPkgs[pkg].unpublish = _.isUndefined(packages[pkg].unpublish) ? false : normalizeUserList([], packages[pkg].unpublish); normalizedPkgs[pkg].unpublish = _.isUndefined(packages[pkg].unpublish) ? false : normalizeUserList([], packages[pkg].unpublish);
} }
} }

@ -1,8 +1,3 @@
/**
* @prettier
* @flow
*/
import _ from 'lodash'; import _ from 'lodash';
import assert from 'assert'; import assert from 'assert';
@ -11,9 +6,9 @@ import { getMatchedPackagesSpec, normalisePackageAccess, sanityCheckUplinksProps
import { getUserAgent, isObject } from './utils'; import { getUserAgent, isObject } from './utils';
import { APP_ERROR } from './constants'; import { APP_ERROR } from './constants';
import type { PackageList, Config as AppConfig, Security, Logger } from '@verdaccio/types'; import { PackageList, Config as AppConfig, Security, Logger } from '@verdaccio/types';
import type { MatchedPackage, StartUpConfig } from '../../types'; import { MatchedPackage, StartUpConfig } from '../../types';
const LoggerApi = require('./logger'); const LoggerApi = require('./logger');
const strategicConfigProps = ['uplinks', 'packages']; const strategicConfigProps = ['uplinks', 'packages'];
@ -23,21 +18,21 @@ const allowedEnvConfig = ['http_proxy', 'https_proxy', 'no_proxy'];
* Coordinates the application configuration * Coordinates the application configuration
*/ */
class Config implements AppConfig { class Config implements AppConfig {
logger: Logger; public logger: Logger;
user_agent: string; public user_agent: string;
secret: string; // @ts-ignore
uplinks: any; public secret: string;
packages: PackageList; public uplinks: any;
users: any; public packages: PackageList;
server_id: string; public users: any;
self_path: string; public server_id: string;
storage: string | void; public self_path: string;
plugins: string | void; public storage: string | void;
security: Security; public plugins: string | void;
$key: any; // @ts-ignore
$value: any; public security: Security;
constructor(config: StartUpConfig) { public constructor(config: StartUpConfig) {
const self = this; const self = this;
this.logger = LoggerApi.logger; this.logger = LoggerApi.logger;
this.self_path = config.self_path; this.self_path = config.self_path;
@ -50,6 +45,7 @@ class Config implements AppConfig {
} }
} }
// @ts-ignore
if (_.isNil(this.user_agent)) { if (_.isNil(this.user_agent)) {
this.user_agent = getUserAgent(); this.user_agent = getUserAgent();
} }
@ -58,7 +54,7 @@ class Config implements AppConfig {
assert(_.isObject(config), APP_ERROR.CONFIG_NOT_VALID); assert(_.isObject(config), APP_ERROR.CONFIG_NOT_VALID);
// sanity check for strategic config properties // sanity check for strategic config properties
strategicConfigProps.forEach(function(x) { strategicConfigProps.forEach(function(x): void {
if (self[x] == null) { if (self[x] == null) {
self[x] = {}; self[x] = {};
} }
@ -76,13 +72,16 @@ class Config implements AppConfig {
this.packages = normalisePackageAccess(self.packages); this.packages = normalisePackageAccess(self.packages);
// loading these from ENV if aren't in config // loading these from ENV if aren't in config
allowedEnvConfig.forEach(envConf => { allowedEnvConfig.forEach(
if (!(envConf in self)) { (envConf): void => {
self[envConf] = process.env[envConf] || process.env[envConf.toUpperCase()]; if (!(envConf in self)) {
self[envConf] = process.env[envConf] || process.env[envConf.toUpperCase()];
}
} }
}); );
// unique identifier of self server (or a cluster), used to avoid loops // unique identifier of self server (or a cluster), used to avoid loops
// @ts-ignore
if (!this.server_id) { if (!this.server_id) {
this.server_id = generateRandomHexString(6); this.server_id = generateRandomHexString(6);
} }
@ -91,14 +90,14 @@ class Config implements AppConfig {
/** /**
* Check for package spec * Check for package spec
*/ */
getMatchedPackagesSpec(pkgName: string): MatchedPackage { public getMatchedPackagesSpec(pkgName: string): MatchedPackage {
return getMatchedPackagesSpec(pkgName, this.packages); return getMatchedPackagesSpec(pkgName, this.packages);
} }
/** /**
* Store or create whether receive a secret key * Store or create whether receive a secret key
*/ */
checkSecretKey(secret: string): string { public checkSecretKey(secret: string): string {
if (_.isString(secret) && _.isEmpty(secret) === false) { if (_.isString(secret) && _.isEmpty(secret) === false) {
this.secret = secret; this.secret = secret;
return secret; return secret;

@ -4,14 +4,14 @@
// @flow // @flow
export const DEFAULT_PORT: string = '4873'; export const DEFAULT_PORT = '4873';
export const DEFAULT_PROTOCOL: string = 'http'; export const DEFAULT_PROTOCOL = 'http';
export const DEFAULT_DOMAIN: string = 'localhost'; export const DEFAULT_DOMAIN = 'localhost';
export const TIME_EXPIRATION_24H: string = '24h'; export const TIME_EXPIRATION_24H = '24h';
export const TIME_EXPIRATION_7D: string = '7d'; export const TIME_EXPIRATION_7D = '7d';
export const DIST_TAGS = 'dist-tags'; export const DIST_TAGS = 'dist-tags';
export const USERS = 'users'; export const USERS = 'users';
export const DEFAULT_MIN_LIMIT_PASSWORD: number = 3; export const DEFAULT_MIN_LIMIT_PASSWORD = 3;
export const DEFAULT_USER = 'Anonymous'; export const DEFAULT_USER = 'Anonymous';
export const keyPem = 'verdaccio-key.pem'; export const keyPem = 'verdaccio-key.pem';

@ -6,7 +6,7 @@
import { createDecipher, createCipher, createHash, pseudoRandomBytes } from 'crypto'; import { createDecipher, createCipher, createHash, pseudoRandomBytes } from 'crypto';
import jwt from 'jsonwebtoken'; import jwt from 'jsonwebtoken';
import type { JWTSignOptions, RemoteUser } from '@verdaccio/types'; import { JWTSignOptions, RemoteUser } from '@verdaccio/types';
export const defaultAlgorithm = 'aes192'; export const defaultAlgorithm = 'aes192';
export const defaultTarballHashAlgorithm = 'sha1'; export const defaultTarballHashAlgorithm = 'sha1';
@ -44,7 +44,7 @@ export function createTarballHash() {
* @param {Object} data * @param {Object} data
* @return {String} * @return {String}
*/ */
export function stringToMD5(data: Buffer | string) { export function stringToMD5(data: Buffer | string): string {
return createHash('md5') return createHash('md5')
.update(data) .update(data)
.digest('hex'); .digest('hex');

@ -1,8 +1,3 @@
/**
* @prettier
* @flow
*/
import assert from 'assert'; import assert from 'assert';
import UrlNode from 'url'; import UrlNode from 'url';
import _ from 'lodash'; import _ from 'lodash';
@ -14,33 +9,34 @@ import { prepareSearchPackage } from './storage-utils';
import loadPlugin from '../lib/plugin-loader'; import loadPlugin from '../lib/plugin-loader';
import LocalDatabase from '@verdaccio/local-storage'; import LocalDatabase from '@verdaccio/local-storage';
import { UploadTarball, ReadTarball } from '@verdaccio/streams'; import { UploadTarball, ReadTarball } from '@verdaccio/streams';
import type { Package, Config, MergeTags, Version, DistFile, Callback, Logger } from '@verdaccio/types'; import { Package, Config, IUploadTarball, IReadTarball, MergeTags, Version, DistFile, Callback, Logger, ILocalData, IPackageStorage, Author } from '@verdaccio/types';
import type { ILocalData, IPackageStorage } from '@verdaccio/local-storage'; import { IStorage, StringValue } from '../../types';
import type { IUploadTarball, IReadTarball } from '@verdaccio/streams'; import { VerdaccioError } from '@verdaccio/commons-api';
import type { IStorage, StringValue } from '../../types';
/** /**
* Implements Storage interface (same for storage.js, local-storage.js, up-storage.js). * Implements Storage interface (same for storage.js, local-storage.js, up-storage.js).
*/ */
class LocalStorage implements IStorage { class LocalStorage implements IStorage {
config: Config; public config: Config;
localData: ILocalData; public localData: ILocalData<Config>;
logger: Logger; public logger: Logger;
constructor(config: Config, logger: Logger) { public constructor(config: Config, logger: Logger) {
this.logger = logger.child({ sub: 'fs' }); this.logger = logger.child({ sub: 'fs' });
this.config = config; this.config = config;
this.localData = this._loadStorage(config, logger); this.localData = this._loadStorage(config, logger);
} }
addPackage(name: string, pkg: Package, callback: Callback) { public addPackage(name: string, pkg: Package, callback: Callback): void {
const storage: any = this._getLocalStorage(name); const storage: any = this._getLocalStorage(name);
if (_.isNil(storage)) { if (_.isNil(storage)) {
return callback(ErrorCode.getNotFound('this package cannot be added')); return callback(ErrorCode.getNotFound('this package cannot be added'));
} }
storage.createPackage(name, generatePackageTemplate(name), err => { storage.createPackage(name, generatePackageTemplate(name), (err: VerdaccioError): void => {
// FIXME: it will be fixed here https://github.com/verdaccio/verdaccio/pull/1360
// @ts-ignore
if (_.isNull(err) === false && err.code === STORAGE.FILE_EXIST_ERROR) { if (_.isNull(err) === false && err.code === STORAGE.FILE_EXIST_ERROR) {
return callback(ErrorCode.getConflict()); return callback(ErrorCode.getConflict());
} }
@ -60,14 +56,14 @@ class LocalStorage implements IStorage {
* @param {*} callback * @param {*} callback
* @return {Function} * @return {Function}
*/ */
removePackage(name: string, callback: Callback) { public removePackage(name: string, callback: Callback): void {
const storage: any = this._getLocalStorage(name); const storage: any = this._getLocalStorage(name);
if (_.isNil(storage)) { if (_.isNil(storage)) {
return callback(ErrorCode.getNotFound()); return callback(ErrorCode.getNotFound());
} }
storage.readPackage(name, (err, data) => { storage.readPackage(name, (err, data: Package): void => {
if (_.isNil(err) === false) { if (_.isNil(err) === false) {
if (err.code === STORAGE.NO_SUCH_FILE_ERROR) { if (err.code === STORAGE.NO_SUCH_FILE_ERROR) {
return callback(ErrorCode.getNotFound()); return callback(ErrorCode.getNotFound());
@ -78,13 +74,13 @@ class LocalStorage implements IStorage {
data = normalizePackage(data); data = normalizePackage(data);
this.localData.remove(name, removeFailed => { this.localData.remove(name, (removeFailed: Error): void => {
if (removeFailed) { if (removeFailed) {
// This will happen when database is locked // This will happen when database is locked
return callback(ErrorCode.getBadData(removeFailed.message)); return callback(ErrorCode.getBadData(removeFailed.message));
} }
storage.deletePackage(STORAGE.PACKAGE_FILE_NAME, err => { storage.deletePackage(STORAGE.PACKAGE_FILE_NAME, (err): void => {
if (err) { if (err) {
return callback(err); return callback(err);
} }
@ -102,8 +98,8 @@ class LocalStorage implements IStorage {
* @param {*} packageInfo * @param {*} packageInfo
* @param {*} callback * @param {*} callback
*/ */
updateVersions(name: string, packageInfo: Package, callback: Callback) { public updateVersions(name: string, packageInfo: Package, callback: Callback): void {
this._readCreatePackage(name, (err, packageLocalJson) => { this._readCreatePackage(name, (err, packageLocalJson): void => {
if (err) { if (err) {
return callback(err); return callback(err);
} }
@ -121,7 +117,7 @@ class LocalStorage implements IStorage {
// we don't keep readme for package versions, // we don't keep readme for package versions,
// only one readme per package // only one readme per package
version = cleanUpReadme(version); version = cleanUpReadme(version);
version.contributors = normalizeContributors(version.contributors); version.contributors = normalizeContributors(version.contributors as Author[]);
change = true; change = true;
packageLocalJson.versions[versionId] = version; packageLocalJson.versions[versionId] = version;
@ -176,7 +172,7 @@ class LocalStorage implements IStorage {
if (change) { if (change) {
this.logger.debug({ name }, 'updating package @{name} info'); this.logger.debug({ name }, 'updating package @{name} info');
this._writePackage(name, packageLocalJson, function(err) { this._writePackage(name, packageLocalJson, function(err): void {
callback(err, packageLocalJson); callback(err, packageLocalJson);
}); });
} else { } else {
@ -193,16 +189,16 @@ class LocalStorage implements IStorage {
* @param {*} tag * @param {*} tag
* @param {*} callback * @param {*} callback
*/ */
addVersion(name: string, version: string, metadata: Version, tag: StringValue, callback: Callback) { public addVersion(name: string, version: string, metadata: Version, tag: StringValue, callback: Callback): void {
this._updatePackage( this._updatePackage(
name, name,
(data, cb) => { (data, cb: Callback): void => {
// keep only one readme per package // keep only one readme per package
data.readme = metadata.readme; data.readme = metadata.readme;
// TODO: lodash remove // TODO: lodash remove
metadata = cleanUpReadme(metadata); metadata = cleanUpReadme(metadata);
metadata.contributors = normalizeContributors(metadata.contributors); metadata.contributors = normalizeContributors(metadata.contributors as Author[]);
const hasVersion = data.versions[version] != null; const hasVersion = data.versions[version] != null;
if (hasVersion) { if (hasVersion) {
@ -242,7 +238,7 @@ class LocalStorage implements IStorage {
data.versions[version] = metadata; data.versions[version] = metadata;
tagVersion(data, version, tag); tagVersion(data, version, tag);
this.localData.add(name, addFailed => { this.localData.add(name, (addFailed): void => {
if (addFailed) { if (addFailed) {
return cb(ErrorCode.getBadData(addFailed.message)); return cb(ErrorCode.getBadData(addFailed.message));
} }
@ -260,12 +256,12 @@ class LocalStorage implements IStorage {
* @param {*} tags * @param {*} tags
* @param {*} callback * @param {*} callback
*/ */
mergeTags(pkgName: string, tags: MergeTags, callback: Callback) { public mergeTags(pkgName: string, tags: MergeTags, callback: Callback): void {
this._updatePackage( this._updatePackage(
pkgName, pkgName,
(data, cb) => { (data, cb): void => {
/* eslint guard-for-in: 0 */ /* eslint guard-for-in: 0 */
for (const tag: string in tags) { for (const tag in tags) {
// this handle dist-tag rm command // this handle dist-tag rm command
if (_.isNull(tags[tag])) { if (_.isNull(tags[tag])) {
delete data[DIST_TAGS][tag]; delete data[DIST_TAGS][tag];
@ -289,7 +285,7 @@ class LocalStorage implements IStorage {
* @return {String} * @return {String}
* @private * @private
*/ */
_getVersionNotFound() { private _getVersionNotFound(): VerdaccioError {
return ErrorCode.getNotFound(API_ERROR.VERSION_NOT_EXIST); return ErrorCode.getNotFound(API_ERROR.VERSION_NOT_EXIST);
} }
@ -298,7 +294,7 @@ class LocalStorage implements IStorage {
* @return {String} * @return {String}
* @private * @private
*/ */
_getFileNotAvailable() { private _getFileNotAvailable(): VerdaccioError {
return ErrorCode.getNotFound('no such file available'); return ErrorCode.getNotFound('no such file available');
} }
@ -311,14 +307,14 @@ class LocalStorage implements IStorage {
* @param {*} callback * @param {*} callback
* @return {Function} * @return {Function}
*/ */
changePackage(name: string, incomingPkg: Package, revision?: string, callback: Callback) { public changePackage(name: string, incomingPkg: Package, revision: string | void, callback: Callback): void {
if (!isObject(incomingPkg.versions) || !isObject(incomingPkg[DIST_TAGS])) { if (!isObject(incomingPkg.versions) || !isObject(incomingPkg[DIST_TAGS])) {
return callback(ErrorCode.getBadData()); return callback(ErrorCode.getBadData());
} }
this._updatePackage( this._updatePackage(
name, name,
(localData, cb) => { (localData, cb): void => {
for (const version in localData.versions) { for (const version in localData.versions) {
if (_.isNil(incomingPkg.versions[version])) { if (_.isNil(incomingPkg.versions[version])) {
this.logger.info({ name: name, version: version }, 'unpublishing @{name}@@{version}'); this.logger.info({ name: name, version: version }, 'unpublishing @{name}@@{version}');
@ -338,7 +334,7 @@ class LocalStorage implements IStorage {
localData[DIST_TAGS] = incomingPkg[DIST_TAGS]; localData[DIST_TAGS] = incomingPkg[DIST_TAGS];
cb(); cb();
}, },
function(err) { function(err): void {
if (err) { if (err) {
return callback(err); return callback(err);
} }
@ -353,12 +349,12 @@ class LocalStorage implements IStorage {
* @param {*} revision * @param {*} revision
* @param {*} callback * @param {*} callback
*/ */
removeTarball(name: string, filename: string, revision: string, callback: Callback) { public removeTarball(name: string, filename: string, revision: string, callback: Callback): void {
assert(validateName(filename)); assert(validateName(filename));
this._updatePackage( this._updatePackage(
name, name,
(data, cb) => { (data, cb): void => {
if (data._attachments[filename]) { if (data._attachments[filename]) {
delete data._attachments[filename]; delete data._attachments[filename];
cb(); cb();
@ -366,7 +362,7 @@ class LocalStorage implements IStorage {
cb(this._getFileNotAvailable()); cb(this._getFileNotAvailable());
} }
}, },
err => { (err: VerdaccioError): void => {
if (err) { if (err) {
return callback(err); return callback(err);
} }
@ -385,35 +381,37 @@ class LocalStorage implements IStorage {
* @param {String} filename * @param {String} filename
* @return {Stream} * @return {Stream}
*/ */
addTarball(name: string, filename: string) { public addTarball(name: string, filename: string): IUploadTarball {
assert(validateName(filename)); assert(validateName(filename));
let length = 0; let length = 0;
const shaOneHash = createTarballHash(); const shaOneHash = createTarballHash();
const uploadStream: IUploadTarball = new UploadTarball(); const uploadStream: IUploadTarball = new UploadTarball({});
const _transform = uploadStream._transform; const _transform = uploadStream._transform;
const storage = this._getLocalStorage(name); const storage = this._getLocalStorage(name);
(uploadStream: any).abort = function() {}; uploadStream.abort = function(): void {};
(uploadStream: any).done = function() {}; uploadStream.done = function(): void {};
uploadStream._transform = function(data, ...args) { uploadStream._transform = function(data, ...args): void {
shaOneHash.update(data); shaOneHash.update(data);
// measure the length for validation reasons // measure the length for validation reasons
length += data.length; length += data.length;
const appliedData = [data, ...args]; const appliedData = [data, ...args];
// FIXME: not sure about this approach, tsc complains
// @ts-ignore
_transform.apply(uploadStream, appliedData); _transform.apply(uploadStream, appliedData);
}; };
if (name === '__proto__') { if (name === '__proto__') {
process.nextTick(() => { process.nextTick((): void => {
uploadStream.emit('error', ErrorCode.getForbidden()); uploadStream.emit('error', ErrorCode.getForbidden());
}); });
return uploadStream; return uploadStream;
} }
if (!storage) { if (!storage) {
process.nextTick(() => { process.nextTick((): void => {
uploadStream.emit('error', "can't upload this package"); uploadStream.emit('error', "can't upload this package");
}); });
return uploadStream; return uploadStream;
@ -421,13 +419,15 @@ class LocalStorage implements IStorage {
const writeStream: IUploadTarball = storage.writeTarball(filename); const writeStream: IUploadTarball = storage.writeTarball(filename);
writeStream.on('error', err => { writeStream.on('error', (err: VerdaccioError): void => {
// @ts-ignore
if (err.code === STORAGE.FILE_EXIST_ERROR) { if (err.code === STORAGE.FILE_EXIST_ERROR) {
uploadStream.emit('error', ErrorCode.getConflict()); uploadStream.emit('error', ErrorCode.getConflict());
uploadStream.abort(); uploadStream.abort();
// @ts-ignore
} else if (err.code === STORAGE.NO_SUCH_FILE_ERROR) { } else if (err.code === STORAGE.NO_SUCH_FILE_ERROR) {
// check if package exists to throw an appropriate message // check if package exists to throw an appropriate message
this.getPackageMetadata(name, function(_err, res) { this.getPackageMetadata(name, function(_err: VerdaccioError, _res: Package): void {
if (_err) { if (_err) {
uploadStream.emit('error', _err); uploadStream.emit('error', _err);
} else { } else {
@ -439,21 +439,21 @@ class LocalStorage implements IStorage {
} }
}); });
writeStream.on('open', function() { writeStream.on('open', function(): void {
// re-emitting open because it's handled in storage.js // re-emitting open because it's handled in storage.js
uploadStream.emit('open'); uploadStream.emit('open');
}); });
writeStream.on('success', () => { writeStream.on('success', (): void => {
this._updatePackage( this._updatePackage(
name, name,
function updater(data, cb) { function updater(data, cb): void {
data._attachments[filename] = { data._attachments[filename] = {
shasum: shaOneHash.digest('hex'), shasum: shaOneHash.digest('hex'),
}; };
cb(); cb();
}, },
function(err) { function(err): void {
if (err) { if (err) {
uploadStream.emit('error', err); uploadStream.emit('error', err);
} else { } else {
@ -463,11 +463,11 @@ class LocalStorage implements IStorage {
); );
}); });
(uploadStream: any).abort = function() { uploadStream.abort = function(): void {
writeStream.abort(); writeStream.abort();
}; };
(uploadStream: any).done = function() { uploadStream.done = function(): void {
if (!length) { if (!length) {
uploadStream.emit('error', ErrorCode.getBadData('refusing to accept zero-length file')); uploadStream.emit('error', ErrorCode.getBadData('refusing to accept zero-length file'));
writeStream.abort(); writeStream.abort();
@ -487,7 +487,7 @@ class LocalStorage implements IStorage {
* @param {*} filename * @param {*} filename
* @return {ReadTarball} * @return {ReadTarball}
*/ */
getTarball(name: string, filename: string): IReadTarball { public getTarball(name: string, filename: string): IReadTarball {
assert(validateName(filename)); assert(validateName(filename));
const storage: IPackageStorage = this._getLocalStorage(name); const storage: IPackageStorage = this._getLocalStorage(name);
@ -504,10 +504,10 @@ class LocalStorage implements IStorage {
* @private * @private
* @return {ReadTarball} * @return {ReadTarball}
*/ */
_createFailureStreamResponse(): IReadTarball { private _createFailureStreamResponse(): IReadTarball {
const stream: IReadTarball = new ReadTarball(); const stream: IReadTarball = new ReadTarball({});
process.nextTick(() => { process.nextTick((): void => {
stream.emit('error', this._getFileNotAvailable()); stream.emit('error', this._getFileNotAvailable());
}); });
return stream; return stream;
@ -520,18 +520,19 @@ class LocalStorage implements IStorage {
* @private * @private
* @return {ReadTarball} * @return {ReadTarball}
*/ */
_streamSuccessReadTarBall(storage: any, filename: string): IReadTarball { private _streamSuccessReadTarBall(storage: any, filename: string): IReadTarball {
const stream: IReadTarball = new ReadTarball(); const stream: IReadTarball = new ReadTarball({});
const readTarballStream = storage.readTarball(filename); const readTarballStream = storage.readTarball(filename);
const e404 = ErrorCode.getNotFound; const e404 = ErrorCode.getNotFound;
(stream: any).abort = function() { stream.abort = function(): void {
if (_.isNil(readTarballStream) === false) { if (_.isNil(readTarballStream) === false) {
readTarballStream.abort(); readTarballStream.abort();
} }
}; };
readTarballStream.on('error', function(err) { readTarballStream.on('error', function(err: VerdaccioError): void {
// @ts-ignore
if (err && err.code === STORAGE.NO_SUCH_FILE_ERROR) { if (err && err.code === STORAGE.NO_SUCH_FILE_ERROR) {
stream.emit('error', e404('no such file available')); stream.emit('error', e404('no such file available'));
} else { } else {
@ -539,11 +540,11 @@ class LocalStorage implements IStorage {
} }
}); });
readTarballStream.on('content-length', function(v) { readTarballStream.on('content-length', function(content): void {
stream.emit('content-length', v); stream.emit('content-length', content);
}); });
readTarballStream.on('open', function() { readTarballStream.on('open', function(): void {
// re-emitting open because it's handled in storage.js // re-emitting open because it's handled in storage.js
stream.emit('open'); stream.emit('open');
readTarballStream.pipe(stream); readTarballStream.pipe(stream);
@ -558,7 +559,7 @@ class LocalStorage implements IStorage {
* @param {*} callback * @param {*} callback
* @return {Function} * @return {Function}
*/ */
getPackageMetadata(name: string, callback?: Callback = () => {}): void { public getPackageMetadata(name: string, callback: Callback = (): void => {}): void {
const storage: IPackageStorage = this._getLocalStorage(name); const storage: IPackageStorage = this._getLocalStorage(name);
if (_.isNil(storage)) { if (_.isNil(storage)) {
return callback(ErrorCode.getNotFound()); return callback(ErrorCode.getNotFound());
@ -573,13 +574,13 @@ class LocalStorage implements IStorage {
* @param {*} options * @param {*} options
* @return {Function} * @return {Function}
*/ */
search(startKey: string, options: any) { public search(startKey: string, options: any): IReadTarball {
const stream = new ReadTarball({ objectMode: true }); const stream = new ReadTarball({ objectMode: true });
this._searchEachPackage( this._searchEachPackage(
(item, cb) => { (item, cb): void => {
if (item.time > parseInt(startKey, 10)) { if (item.time > parseInt(startKey, 10)) {
this.getPackageMetadata(item.name, (err: Error, data: Package) => { this.getPackageMetadata(item.name, (err: VerdaccioError, data: Package): void => {
if (err) { if (err) {
return cb(err); return cb(err);
} }
@ -594,9 +595,10 @@ class LocalStorage implements IStorage {
cb(); cb();
} }
}, },
function onEnd(err) { function onEnd(err): void {
if (err) { if (err) {
return stream.emit('error', err); stream.emit('error', err);
return;
} }
stream.end(); stream.end();
} }
@ -610,7 +612,7 @@ class LocalStorage implements IStorage {
* @param {Object} pkgName package name. * @param {Object} pkgName package name.
* @return {Object} * @return {Object}
*/ */
_getLocalStorage(pkgName: string): IPackageStorage { private _getLocalStorage(pkgName: string): IPackageStorage {
return this.localData.getPackageStorage(pkgName); return this.localData.getPackageStorage(pkgName);
} }
@ -619,8 +621,8 @@ class LocalStorage implements IStorage {
* @param {Object} storage * @param {Object} storage
* @param {Function} callback * @param {Function} callback
*/ */
_readPackage(name: string, storage: any, callback: Callback) { private _readPackage(name: string, storage: any, callback: Callback): void {
storage.readPackage(name, (err, result) => { storage.readPackage(name, (err, result): void => {
if (err) { if (err) {
if (err.code === STORAGE.NO_SUCH_FILE_ERROR) { if (err.code === STORAGE.NO_SUCH_FILE_ERROR) {
return callback(ErrorCode.getNotFound()); return callback(ErrorCode.getNotFound());
@ -638,7 +640,7 @@ class LocalStorage implements IStorage {
* @param {*} onPackage * @param {*} onPackage
* @param {*} onEnd * @param {*} onEnd
*/ */
_searchEachPackage(onPackage: Callback, onEnd: Callback) { private _searchEachPackage(onPackage: Callback, onEnd: Callback): void {
// save wait whether plugin still do not support search functionality // save wait whether plugin still do not support search functionality
if (_.isNil(this.localData.search)) { if (_.isNil(this.localData.search)) {
this.logger.warn('plugin search not implemented yet'); this.logger.warn('plugin search not implemented yet');
@ -654,13 +656,14 @@ class LocalStorage implements IStorage {
* @param {*} callback * @param {*} callback
* @return {Function} * @return {Function}
*/ */
_readCreatePackage(pkgName: string, callback: Callback) { private _readCreatePackage(pkgName: string, callback: Callback): void {
const storage: any = this._getLocalStorage(pkgName); const storage: any = this._getLocalStorage(pkgName);
if (_.isNil(storage)) { if (_.isNil(storage)) {
return this._createNewPackage(pkgName, callback); this._createNewPackage(pkgName, callback);
return;
} }
storage.readPackage(pkgName, (err, data) => { storage.readPackage(pkgName, (err, data): void => {
// TODO: race condition // TODO: race condition
if (_.isNil(err) === false) { if (_.isNil(err) === false) {
if (err.code === STORAGE.NO_SUCH_FILE_ERROR) { if (err.code === STORAGE.NO_SUCH_FILE_ERROR) {
@ -674,7 +677,7 @@ class LocalStorage implements IStorage {
}); });
} }
_createNewPackage(name: string, callback: Callback): Callback { private _createNewPackage(name: string, callback: Callback): Callback {
return callback(null, normalizePackage(generatePackageTemplate(name))); return callback(null, normalizePackage(generatePackageTemplate(name)));
} }
@ -685,7 +688,7 @@ class LocalStorage implements IStorage {
* @param {*} message * @param {*} message
* @return {Object} Error instance * @return {Object} Error instance
*/ */
_internalError(err: string, file: string, message: string) { private _internalError(err: string, file: string, message: string): VerdaccioError {
this.logger.error({ err: err, file: file }, `${message} @{file}: @{!err.message}`); this.logger.error({ err: err, file: file }, `${message} @{file}: @{!err.message}`);
return ErrorCode.getInternalError(); return ErrorCode.getInternalError();
@ -697,7 +700,7 @@ class LocalStorage implements IStorage {
* @param {*} callback callback that gets invoked after it's all updated * @param {*} callback callback that gets invoked after it's all updated
* @return {Function} * @return {Function}
*/ */
_updatePackage(name: string, updateHandler: Callback, callback: Callback) { private _updatePackage(name: string, updateHandler: Callback, callback: Callback): void {
const storage: IPackageStorage = this._getLocalStorage(name); const storage: IPackageStorage = this._getLocalStorage(name);
if (!storage) { if (!storage) {
@ -714,7 +717,7 @@ class LocalStorage implements IStorage {
* @param {*} callback * @param {*} callback
* @return {Function} * @return {Function}
*/ */
_writePackage(name: string, json: Package, callback: Callback) { private _writePackage(name: string, json: Package, callback: Callback): void {
const storage: any = this._getLocalStorage(name); const storage: any = this._getLocalStorage(name);
if (_.isNil(storage)) { if (_.isNil(storage)) {
return callback(); return callback();
@ -722,7 +725,7 @@ class LocalStorage implements IStorage {
storage.savePackage(name, this._setDefaultRevision(json), callback); storage.savePackage(name, this._setDefaultRevision(json), callback);
} }
_setDefaultRevision(json: Package) { private _setDefaultRevision(json: Package): Package {
// calculate revision from couch db // calculate revision from couch db
if (_.isString(json._rev) === false) { if (_.isString(json._rev) === false) {
json._rev = STORAGE.DEFAULT_REVISION; json._rev = STORAGE.DEFAULT_REVISION;
@ -736,21 +739,21 @@ class LocalStorage implements IStorage {
return json; return json;
} }
_deleteAttachments(storage: any, attachments: string[], callback: Callback): void { private _deleteAttachments(storage: any, attachments: string[], callback: Callback): void {
const unlinkNext = function(cb) { const unlinkNext = function(cb): void {
if (_.isEmpty(attachments)) { if (_.isEmpty(attachments)) {
return cb(); return cb();
} }
const attachment = attachments.shift(); const attachment = attachments.shift();
storage.deletePackage(attachment, function() { storage.deletePackage(attachment, function(): void {
unlinkNext(cb); unlinkNext(cb);
}); });
}; };
unlinkNext(function() { unlinkNext(function(): void {
// try to unlink the directory, but ignore errors because it can fail // try to unlink the directory, but ignore errors because it can fail
storage.removePackage(function(err) { storage.removePackage(function(err): void {
callback(err); callback(err);
}); });
}); });
@ -762,7 +765,7 @@ class LocalStorage implements IStorage {
* @param {String} upLinkKey registry key * @param {String} upLinkKey registry key
* @private * @private
*/ */
_updateUplinkToRemoteProtocol(hash: DistFile, upLinkKey: string): void { private _updateUplinkToRemoteProtocol(hash: DistFile, upLinkKey: string): void {
// if we got this information from a known registry, // if we got this information from a known registry,
// use the same protocol for the tarball // use the same protocol for the tarball
// //
@ -777,34 +780,35 @@ class LocalStorage implements IStorage {
} }
} }
async getSecret(config: Config) { public async getSecret(config: Config): Promise<void> {
const secretKey = await this.localData.getSecret(); const secretKey = await this.localData.getSecret();
return this.localData.setSecret(config.checkSecretKey(secretKey)); return this.localData.setSecret(config.checkSecretKey(secretKey));
} }
_loadStorage(config: Config, logger: Logger): ILocalData { private _loadStorage(config: Config, logger: Logger): ILocalData<Config> {
const Storage = this._loadStorePlugin(); const Storage = this._loadStorePlugin();
if (_.isNil(Storage)) { if (_.isNil(Storage)) {
assert(this.config.storage, 'CONFIG: storage path not defined'); assert(this.config.storage, 'CONFIG: storage path not defined');
return new LocalDatabase(this.config, logger); return new LocalDatabase(this.config, logger);
} else { } else {
return Storage; return Storage as ILocalData<Config>;
} }
} }
_loadStorePlugin(): ILocalData { private _loadStorePlugin(): ILocalData<Config> | void {
const plugin_params = { const plugin_params = {
config: this.config, config: this.config,
logger: this.logger, logger: this.logger,
}; };
return _.head( const plugins: ILocalData<Config>[] = loadPlugin<ILocalData<Config>>(this.config, this.config.store, plugin_params, (plugin): ILocalData<Config> => {
loadPlugin(this.config, this.config.store, plugin_params, plugin => { return plugin.getPackageStorage;
return plugin.getPackageStorage; });
})
);
return _.head(plugins);
} }
} }

@ -1,6 +1,5 @@
/** /* eslint-disable */
* @prettier
*/
import { isObject } from './utils'; import { isObject } from './utils';
const cluster = require('cluster'); const cluster = require('cluster');
@ -47,6 +46,8 @@ class VerdaccioRotatingFileStream extends Logger.RotatingFileStream {
} }
} }
let logger;
/** /**
* Setup the Buyan logger * Setup the Buyan logger
* @param {*} logs list of log configuration * @param {*} logs list of log configuration
@ -74,6 +75,7 @@ function setup(logs) {
} }
const stream = new VerdaccioRotatingFileStream( const stream = new VerdaccioRotatingFileStream(
// @ts-ignore
_.merge( _.merge(
{}, {},
// Defaults can be found here: https://github.com/trentm/node-bunyan#stream-type-rotating-file // Defaults can be found here: https://github.com/trentm/node-bunyan#stream-type-rotating-file
@ -83,8 +85,11 @@ function setup(logs) {
); );
streams.push({ streams.push({
// @ts-ignore
type: 'raw', type: 'raw',
// @ts-ignore
level, level,
// @ts-ignore
stream, stream,
}); });
} else { } else {
@ -124,15 +129,18 @@ function setup(logs) {
} }
streams.push({ streams.push({
// @ts-ignore
type: 'raw', type: 'raw',
// @ts-ignore
level, level,
// @ts-ignore
stream: stream, stream: stream,
}); });
} }
}); });
// buyan default configuration // buyan default configuration
const logger = new Logger({ logger = new Logger({
name: pkgJSON.name, name: pkgJSON.name,
streams: streams, streams: streams,
serializers: { serializers: {
@ -145,8 +153,6 @@ function setup(logs) {
process.on('SIGUSR2', function() { process.on('SIGUSR2', function() {
Logger.reopenFileStreams(); Logger.reopenFileStreams();
}); });
module.exports.logger = logger;
} }
// adopted from socket.io // adopted from socket.io
@ -253,4 +259,4 @@ function print(type, msg, obj, colors) {
} }
} }
module.exports.setup = setup; export { setup, logger };

@ -7,7 +7,7 @@ import semver from 'semver';
import _ from 'lodash'; import _ from 'lodash';
import { DIST_TAGS } from './constants'; import { DIST_TAGS } from './constants';
import type { Package } from '@verdaccio/types'; import { Package } from '@verdaccio/types';
/** /**
* Function gets a local info and an info from uplinks and tries to merge it * Function gets a local info and an info from uplinks and tries to merge it

@ -1,72 +0,0 @@
/**
* @prettier
*/
import Handlebars from 'handlebars';
import _ from 'lodash';
import { notifyRequest } from './notify-request';
export function handleNotify(metadata, notifyEntry, publisherInfo, publishedPackage) {
let regex;
if (metadata.name && notifyEntry.packagePattern) {
regex = new RegExp(notifyEntry.packagePattern, notifyEntry.packagePatternFlags || '');
if (!regex.test(metadata.name)) {
return;
}
}
const template = Handlebars.compile(notifyEntry.content);
// don't override 'publisher' if package.json already has that
if (!metadata.publisher) {
metadata = { ...metadata, publishedPackage, publisher: publisherInfo };
}
const content = template(metadata);
const options = {
body: content,
};
// provides fallback support, it's accept an Object {} and Array of {}
if (notifyEntry.headers && _.isArray(notifyEntry.headers)) {
const header = {};
notifyEntry.headers.map(function(item) {
if (Object.is(item, item)) {
for (const key in item) {
if (item.hasOwnProperty(key)) {
header[key] = item[key];
}
}
}
});
options.headers = header;
} else if (Object.is(notifyEntry.headers, notifyEntry.headers)) {
options.headers = notifyEntry.headers;
}
options.method = notifyEntry.method;
if (notifyEntry.endpoint) {
options.url = notifyEntry.endpoint;
}
return notifyRequest(options, content);
}
export function sendNotification(metadata, key, ...moreMedatata) {
return handleNotify(metadata, key, ...moreMedatata);
}
export function notify(metadata, config, ...moreMedatata) {
if (config.notify) {
if (config.notify.content) {
return sendNotification(metadata, config.notify, ...moreMedatata);
} else {
// multiple notifications endpoints PR #108
return Promise.all(_.map(config.notify, key => sendNotification(metadata, key, ...moreMedatata)));
}
}
return Promise.resolve();
}

77
src/lib/notify/index.ts Normal file

@ -0,0 +1,77 @@
import Handlebars from 'handlebars';
import _ from 'lodash';
import { notifyRequest } from './notify-request';
import { OptionsWithUrl } from 'request';
import { Config, Package, RemoteUser } from '@verdaccio/types';
type TemplateMetadata = Package & { publishedPackage: string };
export function handleNotify(metadata: Package, notifyEntry, remoteUser: RemoteUser, publishedPackage: string): Promise<any> | void {
let regex;
if (metadata.name && notifyEntry.packagePattern) {
regex = new RegExp(notifyEntry.packagePattern, notifyEntry.packagePatternFlags || '');
if (!regex.test(metadata.name)) {
return;
}
}
const template: HandlebarsTemplateDelegate = Handlebars.compile(notifyEntry.content);
// don't override 'publisher' if package.json already has that
/* eslint no-unused-vars: 0 */
/* eslint @typescript-eslint/no-unused-vars: 0 */
// @ts-ignore
if (_.isNil(metadata.publisher)) {
// @ts-ignore
metadata = { ...metadata, publishedPackage, publisher: { name: remoteUser.name as string } };
}
const content: string = template(metadata);
const options: OptionsWithUrl = {
body: content,
url: '',
};
// provides fallback support, it's accept an Object {} and Array of {}
if (notifyEntry.headers && _.isArray(notifyEntry.headers)) {
const header = {};
notifyEntry.headers.map(function(item): void {
if (Object.is(item, item)) {
for (const key in item) {
if (item.hasOwnProperty(key)) {
header[key] = item[key];
}
}
}
});
options.headers = header;
} else if (Object.is(notifyEntry.headers, notifyEntry.headers)) {
options.headers = notifyEntry.headers;
}
options.method = notifyEntry.method;
if (notifyEntry.endpoint) {
options.url = notifyEntry.endpoint;
}
return notifyRequest(options, content);
}
export function sendNotification(metadata: Package, notify: Notification, remoteUser: RemoteUser, publishedPackage: string): Promise<any> {
return handleNotify(metadata, notify, remoteUser, publishedPackage) as Promise<any>;
}
export function notify(metadata: Package, config: Config, remoteUser: RemoteUser, publishedPackage: string): Promise<any> | void {
if (config.notify) {
if (config.notify.content) {
return sendNotification(metadata, (config.notify as unknown) as Notification, remoteUser, publishedPackage);
} else {
// multiple notifications endpoints PR #108
return Promise.all(_.map(config.notify, key => sendNotification(metadata, key, remoteUser, publishedPackage)));
}
}
return Promise.resolve();
}

@ -1,27 +0,0 @@
/**
* @prettier
*/
import isNil from 'lodash/isNil';
import logger from '../logger';
import request from 'request';
import { HTTP_STATUS } from '../constants';
export function notifyRequest(options, content) {
return new Promise((resolve, reject) => {
request(options, function(err, response, body) {
if (err || response.statusCode >= HTTP_STATUS.BAD_REQUEST) {
const errorMessage = isNil(err) ? response.body : err.message;
logger.logger.error({ errorMessage }, 'notify service has thrown an error: @{errorMessage}');
reject(errorMessage);
} else {
logger.logger.info({ content }, 'A notification has been shipped: @{content}');
if (isNil(body) === false) {
logger.logger.debug({ body }, ' body: @{body}');
resolve(body);
}
reject(Error('body is missing'));
}
});
});
}

@ -0,0 +1,25 @@
import isNil from 'lodash/isNil';
import { logger } from '../logger';
import request, { RequiredUriUrl } from 'request';
import { HTTP_STATUS } from '../constants';
export function notifyRequest(options: RequiredUriUrl, content): Promise<any | Error> {
return new Promise(
(resolve, reject): void => {
request(options, function(err, response, body): void {
if (err || response.statusCode >= HTTP_STATUS.BAD_REQUEST) {
const errorMessage = isNil(err) ? response.body : err.message;
logger.error({ errorMessage }, 'notify service has thrown an error: @{errorMessage}');
reject(errorMessage);
} else {
logger.info({ content }, 'A notification has been shipped: @{content}');
if (isNil(body) === false) {
logger.debug({ body }, ' body: @{body}');
resolve(body);
}
reject(Error('body is missing'));
}
});
}
);
}

@ -1,116 +0,0 @@
/**
* @prettier
* @flow
*/
import Path from 'path';
import _ from 'lodash';
import logger from './logger';
import type { Config } from '@verdaccio/types';
import { MODULE_NOT_FOUND } from './constants';
/**
* Requires a module.
* @param {*} path the module's path
* @return {Object}
*/
function tryLoad(path: string) {
try {
return require(path);
} catch (err) {
if (err.code === MODULE_NOT_FOUND) {
return null;
}
throw err;
}
}
function mergeConfig(appConfig, pluginConfig) {
return _.merge(appConfig, pluginConfig);
}
function isValid(plugin) {
return _.isFunction(plugin) || _.isFunction(plugin.default);
}
function isES6(plugin) {
return Object.keys(plugin).includes('default');
}
/**
* Load a plugin following the rules
* - First try to load from the internal directory plugins (which will disappear soon or later).
* - A second attempt from the external plugin directory
* - A third attempt from node_modules, in case to have multiple match as for instance verdaccio-ldap
* and sinopia-ldap. All verdaccio prefix will have preferences.
* @param {*} config a reference of the configuration settings
* @param {*} pluginConfigs
* @param {*} params a set of params to initialize the plugin
* @param {*} sanityCheck callback that check the shape that should fulfill the plugin
* @return {Array} list of plugins
*/
export default function loadPlugin<T>(config: Config, pluginConfigs: any = {}, params: any, sanityCheck: Function, prefix: string = 'verdaccio'): T[] {
return Object.keys(pluginConfigs).map((pluginId: string) => {
let plugin;
const localPlugin = Path.resolve(__dirname + '/../plugins', pluginId);
// try local plugins first
plugin = tryLoad(localPlugin);
// try the external plugin directory
if (plugin === null && config.plugins) {
const pluginDir = config.plugins;
const externalFilePlugin = Path.resolve(pluginDir, pluginId);
plugin = tryLoad(externalFilePlugin);
// npm package
if (plugin === null && pluginId.match(/^[^\.\/]/)) {
plugin = tryLoad(Path.resolve(pluginDir, `${prefix}-${pluginId}`));
// compatibility for old sinopia plugins
if (!plugin) {
plugin = tryLoad(Path.resolve(pluginDir, `sinopia-${pluginId}`));
}
}
}
// npm package
if (plugin === null && pluginId.match(/^[^\.\/]/)) {
plugin = tryLoad(`${prefix}-${pluginId}`);
// compatibility for old sinopia plugins
if (!plugin) {
plugin = tryLoad(`sinopia-${pluginId}`);
}
}
if (plugin === null) {
plugin = tryLoad(pluginId);
}
// relative to config path
if (plugin === null && pluginId.match(/^\.\.?($|\/)/)) {
plugin = tryLoad(Path.resolve(Path.dirname(config.self_path), pluginId));
}
if (plugin === null) {
logger.logger.error({ content: pluginId }, 'plugin not found. try npm install verdaccio-@{content}');
throw Error(`
${prefix}-${pluginId} plugin not found. try "npm install ${prefix}-${pluginId}"`);
}
if (!isValid(plugin)) {
logger.logger.error({ content: pluginId }, "@{content} doesn't look like a valid plugin");
throw Error(`"${pluginId}" is not a valid plugin`);
}
/* eslint new-cap:off */
plugin = isES6(plugin) ? new plugin.default(mergeConfig(config, pluginConfigs[pluginId]), params) : plugin(pluginConfigs[pluginId], params);
/* eslint new-cap:off */
if (plugin === null || !sanityCheck(plugin)) {
logger.logger.error({ content: pluginId }, "@{content} doesn't look like a valid plugin");
throw Error(`"${pluginId}" is not a valid plugin`);
}
logger.logger.warn({ content: `${prefix}-${pluginId}` }, 'Plugin successfully loaded: @{content}');
return plugin;
});
}

127
src/lib/plugin-loader.ts Normal file

@ -0,0 +1,127 @@
import Path from 'path';
import _ from 'lodash';
import { logger } from './logger';
import { Config, IPlugin } from '@verdaccio/types';
import { MODULE_NOT_FOUND } from './constants';
/**
* Requires a module.
* @param {*} path the module's path
* @return {Object}
*/
function tryLoad(path: string): any {
try {
return require(path);
} catch (err) {
if (err.code === MODULE_NOT_FOUND) {
return null;
}
throw err;
}
}
function mergeConfig(appConfig, pluginConfig): Config {
return _.merge(appConfig, pluginConfig);
}
function isValid(plugin): boolean {
return _.isFunction(plugin) || _.isFunction(plugin.default);
}
function isES6(plugin): boolean {
return Object.keys(plugin).includes('default');
}
// export type PluginGeneric<R, T extends IPlugin<R> = ;
/**
* Load a plugin following the rules
* - First try to load from the internal directory plugins (which will disappear soon or later).
* - A second attempt from the external plugin directory
* - A third attempt from node_modules, in case to have multiple match as for instance verdaccio-ldap
* and sinopia-ldap. All verdaccio prefix will have preferences.
* @param {*} config a reference of the configuration settings
* @param {*} pluginConfigs
* @param {*} params a set of params to initialize the plugin
* @param {*} sanityCheck callback that check the shape that should fulfill the plugin
* @return {Array} list of plugins
*/
export default function loadPlugin<T extends IPlugin<T>>(
config: Config,
pluginConfigs: any = {},
params: any,
sanityCheck: any,
prefix: string = 'verdaccio'
): any[] {
return Object.keys(pluginConfigs).map(
(pluginId: string): IPlugin<T> => {
let plugin;
const localPlugin = Path.resolve(__dirname + '/../plugins', pluginId);
// try local plugins first
plugin = tryLoad(localPlugin);
// try the external plugin directory
if (plugin === null && config.plugins) {
const pluginDir = config.plugins;
const externalFilePlugin = Path.resolve(pluginDir, pluginId);
plugin = tryLoad(externalFilePlugin);
// npm package
if (plugin === null && pluginId.match(/^[^\.\/]/)) {
plugin = tryLoad(Path.resolve(pluginDir, `${prefix}-${pluginId}`));
// compatibility for old sinopia plugins
if (!plugin) {
plugin = tryLoad(Path.resolve(pluginDir, `sinopia-${pluginId}`));
}
}
}
// npm package
if (plugin === null && pluginId.match(/^[^\.\/]/)) {
plugin = tryLoad(`${prefix}-${pluginId}`);
// compatibility for old sinopia plugins
if (!plugin) {
plugin = tryLoad(`sinopia-${pluginId}`);
}
}
if (plugin === null) {
plugin = tryLoad(pluginId);
}
// relative to config path
if (plugin === null && pluginId.match(/^\.\.?($|\/)/)) {
plugin = tryLoad(Path.resolve(Path.dirname(config.self_path), pluginId));
}
if (plugin === null) {
logger.error({ content: pluginId, prefix }, 'plugin not found. try npm install @{prefix}-@{content}');
throw Error(`
${prefix}-${pluginId} plugin not found. try "npm install ${prefix}-${pluginId}"`);
}
if (!isValid(plugin)) {
logger.error({ content: pluginId }, "@{prefix}-@{content} plugin does not have the right code structure");
throw Error(`"${pluginId}" plugin does not have the right code structure`);
}
/* eslint new-cap:off */
try {
plugin = isES6(plugin) ? new plugin.default(mergeConfig(config, pluginConfigs[pluginId]), params) : plugin(pluginConfigs[pluginId], params);
} catch (error) {
plugin = null;
logger.error({ error, pluginId }, "error loading a plugin @{pluginId}: @{error}");
}
/* eslint new-cap:off */
if (plugin === null || !sanityCheck(plugin)) {
logger.error({ content: pluginId, prefix }, "@{prefix}-@{content} doesn't look like a valid plugin");
throw Error(`sanity check has failed, "${pluginId}" is not a valid plugin`);
}
logger.warn({ content: pluginId, prefix }, 'Plugin successfully loaded: @{prefix}-@{content}');
return plugin;
}
);
}

Some files were not shown because too many files have changed in this diff Show More