mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-30 22:34:10 -05:00
refactor: annotate files with flow
This commit is contained in:
parent
6b19c819ed
commit
59a53e1919
17 changed files with 332 additions and 69 deletions
33
flow-typed/npm/compression_vx.x.x.js
vendored
Normal file
33
flow-typed/npm/compression_vx.x.x.js
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// 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'>;
|
||||||
|
}
|
88
flow-typed/npm/cors_vx.x.x.js
vendored
Normal file
88
flow-typed/npm/cors_vx.x.x.js
vendored
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
// 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'>;
|
||||||
|
}
|
81
flow-typed/npm/pkginfo_vx.x.x.js
vendored
Normal file
81
flow-typed/npm/pkginfo_vx.x.x.js
vendored
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
// 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'>;
|
||||||
|
}
|
|
@ -50,7 +50,7 @@
|
||||||
"@commitlint/cli": "6.1.3",
|
"@commitlint/cli": "6.1.3",
|
||||||
"@commitlint/config-conventional": "6.1.3",
|
"@commitlint/config-conventional": "6.1.3",
|
||||||
"@commitlint/travis-cli": "6.1.3",
|
"@commitlint/travis-cli": "6.1.3",
|
||||||
"@verdaccio/types": "2.0.0",
|
"@verdaccio/types": "2.0.1",
|
||||||
"axios": "0.18.0",
|
"axios": "0.18.0",
|
||||||
"babel-cli": "6.26.0",
|
"babel-cli": "6.26.0",
|
||||||
"babel-core": "6.26.0",
|
"babel-core": "6.26.0",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import type {IAuth, IStorage} from '../../../types';
|
import type {IAuth, IStorageHandler} from '../../../types';
|
||||||
import type {Config} from '@verdaccio/types';
|
import type {Config} from '@verdaccio/types';
|
||||||
|
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
|
@ -15,14 +15,16 @@ import pkg from './api/package';
|
||||||
|
|
||||||
const {match, validate_name, validatePackage, encodeScopePackage, anti_loop} = require('../middleware');
|
const {match, validate_name, validatePackage, encodeScopePackage, anti_loop} = require('../middleware');
|
||||||
|
|
||||||
export default function(config: Config, auth: IAuth, storage: IStorage) {
|
export default function(config: Config, auth: IAuth, storage: IStorageHandler) {
|
||||||
/* eslint new-cap:off */
|
/* eslint new-cap:off */
|
||||||
const app = express.Router();
|
const app = express.Router();
|
||||||
/* eslint new-cap:off */
|
/* eslint new-cap:off */
|
||||||
|
|
||||||
// validate all of these params as a package name
|
// validate all of these params as a package name
|
||||||
// this might be too harsh, so ask if it causes trouble
|
// this might be too harsh, so ask if it causes trouble
|
||||||
|
// $FlowFixMe
|
||||||
app.param('package', validatePackage);
|
app.param('package', validatePackage);
|
||||||
|
// $FlowFixMe
|
||||||
app.param('filename', validate_name);
|
app.param('filename', validate_name);
|
||||||
app.param('tag', validate_name);
|
app.param('tag', validate_name);
|
||||||
app.param('version', validate_name);
|
app.param('version', validate_name);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import Error from 'http-errors';
|
import Error from 'http-errors';
|
||||||
import compression from 'compression';
|
import compression from 'compression';
|
||||||
|
@ -9,18 +11,22 @@ import hookDebug from './debug';
|
||||||
import Auth from '../lib/auth';
|
import Auth from '../lib/auth';
|
||||||
import apiEndpoint from './endpoint';
|
import apiEndpoint from './endpoint';
|
||||||
|
|
||||||
const Logger = require('../lib/logger');
|
import type {$Application} from 'express';
|
||||||
|
import type {$ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler, IAuth} from '../../types';
|
||||||
|
import type {Config as IConfig} from '@verdaccio/types';
|
||||||
|
|
||||||
|
const LoggerApp = require('../lib/logger');
|
||||||
const Config = require('../lib/config');
|
const Config = require('../lib/config');
|
||||||
const Middleware = require('./middleware');
|
const Middleware = require('./middleware');
|
||||||
const Cats = require('../lib/status-cats');
|
const Cats = require('../lib/status-cats');
|
||||||
|
|
||||||
export default function(configHash) {
|
export default function(configHash: any) {
|
||||||
// Config
|
// Config
|
||||||
Logger.setup(configHash.logs);
|
LoggerApp.setup(configHash.logs);
|
||||||
const config = new Config(configHash);
|
const config: IConfig = new Config(configHash);
|
||||||
const storage = new Storage(config);
|
const storage: IStorageHandler = new Storage(config);
|
||||||
const auth = new Auth(config);
|
const auth: IAuth = new Auth(config);
|
||||||
const app = 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');
|
||||||
|
@ -29,14 +35,14 @@ export default function(configHash) {
|
||||||
// Router setup
|
// Router setup
|
||||||
app.use(Middleware.log);
|
app.use(Middleware.log);
|
||||||
app.use(Middleware.errorReportingMiddleware);
|
app.use(Middleware.errorReportingMiddleware);
|
||||||
app.use(function(req, res, next) {
|
app.use(function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
res.setHeader('X-Powered-By', config.user_agent);
|
res.setHeader('X-Powered-By', config.user_agent);
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
app.use(Cats.middleware);
|
app.use(Cats.middleware);
|
||||||
app.use(compression());
|
app.use(compression());
|
||||||
|
|
||||||
app.get('/favicon.ico', function(req, res, next) {
|
app.get('/favicon.ico', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
req.url = '/-/static/favicon.png';
|
req.url = '/-/static/favicon.png';
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
@ -49,7 +55,7 @@ export default function(configHash) {
|
||||||
// register middleware plugins
|
// register middleware plugins
|
||||||
const plugin_params = {
|
const plugin_params = {
|
||||||
config: config,
|
config: config,
|
||||||
logger: Logger.logger,
|
logger: LoggerApp.logger,
|
||||||
};
|
};
|
||||||
const plugins = loadPlugin(config, config.middlewares, plugin_params, function(plugin) {
|
const plugins = loadPlugin(config, config.middlewares, plugin_params, function(plugin) {
|
||||||
return plugin.register_middlewares;
|
return plugin.register_middlewares;
|
||||||
|
@ -66,17 +72,17 @@ export default function(configHash) {
|
||||||
app.use('/', require('./web')(config, auth, storage));
|
app.use('/', require('./web')(config, auth, storage));
|
||||||
app.use('/-/verdaccio/', require('./web/api')(config, auth, storage));
|
app.use('/-/verdaccio/', require('./web/api')(config, auth, storage));
|
||||||
} else {
|
} else {
|
||||||
app.get('/', function(req, res, next) {
|
app.get('/', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
next(Error[404]('Web interface is disabled in the config file'));
|
next(Error[404]('Web interface is disabled in the config file'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Catch 404
|
// Catch 404
|
||||||
app.get('/*', function(req, res, next) {
|
app.get('/*', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
next(Error[404]('File not found'));
|
next(Error[404]('File not found'));
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(function(err, req, res, next) {
|
app.use(function(err, req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
if (_.isError(err)) {
|
if (_.isError(err)) {
|
||||||
if (err.code === 'ECONNABORT' && res.statusCode === 304) {
|
if (err.code === 'ECONNABORT' && res.statusCode === 304) {
|
||||||
return next();
|
return next();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import {
|
import {
|
||||||
|
@ -5,11 +7,13 @@ import {
|
||||||
validate_package as utilValidatePackage,
|
validate_package as utilValidatePackage,
|
||||||
isObject,
|
isObject,
|
||||||
ErrorCode} from '../lib/utils';
|
ErrorCode} from '../lib/utils';
|
||||||
|
import type {$ResponseExtend, $RequestExtend, $NextFunctionVer, IAuth} from '../../types';
|
||||||
|
import type {Config} from '@verdaccio/types';
|
||||||
|
|
||||||
const Logger = require('../lib/logger');
|
const Logger = require('../lib/logger');
|
||||||
|
|
||||||
export function match(regexp) {
|
export function match(regexp: RegExp) {
|
||||||
return function(req, res, next, value) {
|
return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer, value: string) {
|
||||||
if (regexp.exec(value)) {
|
if (regexp.exec(value)) {
|
||||||
next();
|
next();
|
||||||
} else {
|
} else {
|
||||||
|
@ -18,13 +22,15 @@ export function match(regexp) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function securityIframe(req, res, next) {
|
export function securityIframe(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
// disable loading in frames (clickjacking, etc.)
|
// disable loading in frames (clickjacking, etc.)
|
||||||
res.header('X-Frame-Options', 'deny');
|
res.header('X-Frame-Options', 'deny');
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validate_name(req, res, next, value, name) {
|
// 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
|
||||||
|
export function validate_name(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer, value: string, name: string) {
|
||||||
if (value.charAt(0) === '-') {
|
if (value.charAt(0) === '-') {
|
||||||
// special case in couchdb usually
|
// special case in couchdb usually
|
||||||
next('route');
|
next('route');
|
||||||
|
@ -35,7 +41,9 @@ export function validate_name(req, res, next, value, name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validatePackage(req, res, next, value, name) {
|
// 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
|
||||||
|
export function validatePackage(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer, value: string, name: string) {
|
||||||
if (value.charAt(0) === '-') {
|
if (value.charAt(0) === '-') {
|
||||||
// special case in couchdb usually
|
// special case in couchdb usually
|
||||||
next('route');
|
next('route');
|
||||||
|
@ -46,8 +54,8 @@ export function validatePackage(req, res, next, value, name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function media(expect) {
|
export function media(expect: string) {
|
||||||
return function(req, res, next) {
|
return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
if (req.headers['content-type'] !== expect) {
|
if (req.headers['content-type'] !== expect) {
|
||||||
next( ErrorCode.getCode(415, 'wrong content-type, expect: ' + expect
|
next( ErrorCode.getCode(415, 'wrong content-type, expect: ' + expect
|
||||||
+ ', got: '+req.headers['content-type']) );
|
+ ', got: '+req.headers['content-type']) );
|
||||||
|
@ -57,7 +65,7 @@ export function media(expect) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function encodeScopePackage(req, res, next) {
|
export function encodeScopePackage(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
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');
|
||||||
|
@ -65,15 +73,15 @@ export function encodeScopePackage(req, res, next) {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function expect_json(req, res, next) {
|
export function expect_json(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
if (!isObject(req.body)) {
|
if (!isObject(req.body)) {
|
||||||
return next( ErrorCode.get400('can\'t parse incoming json') );
|
return next( ErrorCode.get400('can\'t parse incoming json') );
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function anti_loop(config) {
|
export function anti_loop(config: Config) {
|
||||||
return function(req, res, next) {
|
return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
if (req.headers.via != null) {
|
if (req.headers.via != null) {
|
||||||
let arr = req.headers.via.split(',');
|
let arr = req.headers.via.split(',');
|
||||||
|
|
||||||
|
@ -100,15 +108,15 @@ function md5sum(data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function allow(auth) {
|
export function allow(auth: IAuth) {
|
||||||
return function(action) {
|
return function(action: string) {
|
||||||
return function(req, res, next) {
|
return function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
req.pause();
|
req.pause();
|
||||||
let packageName = req.params.package;
|
let packageName = req.params.package;
|
||||||
if (req.params.scope) {
|
if (req.params.scope) {
|
||||||
packageName = `@${req.params.scope}/${packageName}`;
|
packageName = `@${req.params.scope}/${packageName}`;
|
||||||
}
|
}
|
||||||
|
// $FlowFixMe
|
||||||
auth['allow_' + action](packageName, req.remote_user, function(error, allowed) {
|
auth['allow_' + action](packageName, req.remote_user, function(error, allowed) {
|
||||||
req.resume();
|
req.resume();
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -125,7 +133,7 @@ export function allow(auth) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function final(body, req, res, next) {
|
export function final(body: any, req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
if (res.statusCode === 401 && !res.getHeader('WWW-Authenticate')) {
|
if (res.statusCode === 401 && !res.getHeader('WWW-Authenticate')) {
|
||||||
// they say it's required for 401, so...
|
// they say it's required for 401, so...
|
||||||
res.header('WWW-Authenticate', 'Basic, Bearer');
|
res.header('WWW-Authenticate', 'Basic, Bearer');
|
||||||
|
@ -168,7 +176,7 @@ export function allow(auth) {
|
||||||
res.send(body);
|
res.send(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function log(req, res, next) {
|
export function log(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
// logger
|
// logger
|
||||||
req.log = Logger.logger.child({sub: 'in'});
|
req.log = Logger.logger.child({sub: 'in'});
|
||||||
|
|
||||||
|
@ -239,7 +247,7 @@ export function log(req, res, next) {
|
||||||
};
|
};
|
||||||
|
|
||||||
req.on('close', function() {
|
req.on('close', function() {
|
||||||
log(true);
|
log();
|
||||||
});
|
});
|
||||||
|
|
||||||
const _end = res.end;
|
const _end = res.end;
|
||||||
|
@ -255,7 +263,7 @@ export function log(req, res, next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Middleware
|
// Middleware
|
||||||
export function errorReportingMiddleware(req, res, next) {
|
export function errorReportingMiddleware(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
res.report_error = res.report_error || function(err) {
|
res.report_error = res.report_error || function(err) {
|
||||||
if (err.status && err.status >= 400 && err.status < 600) {
|
if (err.status && err.status >= 400 && err.status < 600) {
|
||||||
if (_.isNil(res.headersSent) === false) {
|
if (_.isNil(res.headersSent) === false) {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// @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';
|
||||||
|
@ -6,20 +8,25 @@ import addSearchWebApi from './endpoint/search';
|
||||||
|
|
||||||
import Search from '../../lib/search';
|
import Search from '../../lib/search';
|
||||||
import {match, validate_name, validatePackage, securityIframe} from '../middleware';
|
import {match, validate_name, validatePackage, securityIframe} from '../middleware';
|
||||||
|
import type {Config} from '@verdaccio/types';
|
||||||
|
import type {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/
|
||||||
*/
|
*/
|
||||||
module.exports = function(config, auth, storage) {
|
module.exports = function(config: Config, auth: IAuth, storage: IStorageHandler) {
|
||||||
|
|
||||||
Search.configureStorage(storage);
|
Search.configureStorage(storage);
|
||||||
|
|
||||||
// validate all of these params as a package name
|
// validate all of these params as a package name
|
||||||
// this might be too harsh, so ask if it causes trouble
|
// this might be too harsh, so ask if it causes trouble
|
||||||
|
// $FlowFixMe
|
||||||
route.param('package', validatePackage);
|
route.param('package', validatePackage);
|
||||||
|
// $FlowFixMe
|
||||||
route.param('filename', validate_name);
|
route.param('filename', validate_name);
|
||||||
|
// $FlowFixMe
|
||||||
route.param('version', validate_name);
|
route.param('version', validate_name);
|
||||||
route.param('anything', match(/.*/));
|
route.param('anything', match(/.*/));
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,25 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import {addScope, addGravatarSupport, deleteProperties, sortByName, DIST_TAGS} from '../../../lib/utils';
|
import {addScope, addGravatarSupport, deleteProperties, sortByName, DIST_TAGS} from '../../../lib/utils';
|
||||||
import {allow} from '../../middleware';
|
import {allow} from '../../middleware';
|
||||||
import async from 'async';
|
import async from 'async';
|
||||||
import marked from 'marked';
|
import marked from 'marked';
|
||||||
|
import type {Router} from 'express';
|
||||||
|
import type {
|
||||||
|
IAuth,
|
||||||
|
$ResponseExtend,
|
||||||
|
$RequestExtend,
|
||||||
|
$NextFunctionVer,
|
||||||
|
IStorageHandler,
|
||||||
|
$SidebarPackage} from '../../../../types';
|
||||||
|
|
||||||
function addPackageWebApi(route, storage, auth) {
|
|
||||||
|
function addPackageWebApi(route: Router, storage: IStorageHandler, auth: IAuth) {
|
||||||
const can = allow(auth);
|
const can = allow(auth);
|
||||||
|
|
||||||
// Get list of all visible package
|
// Get list of all visible package
|
||||||
route.get('/packages', function(req, res, next) {
|
route.get('/packages', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
storage.getLocalDatabase(function(err, packages) {
|
storage.getLocalDatabase(function(err, packages) {
|
||||||
if (err) {
|
if (err) {
|
||||||
// that function shouldn't produce any
|
// that function shouldn't produce any
|
||||||
|
@ -40,7 +51,8 @@ function addPackageWebApi(route, storage, auth) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get package readme
|
// Get package readme
|
||||||
route.get('/package/readme/(@:scope/)?:package/:version?', can('access'), function(req, res, next) {
|
route.get('/package/readme/(@:scope/)?:package/:version?', can('access'),
|
||||||
|
function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
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({
|
||||||
|
@ -57,18 +69,21 @@ function addPackageWebApi(route, storage, auth) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
route.get('/sidebar/(@:scope/)?:package', function(req, res, next) {
|
route.get('/sidebar/(@:scope/)?:package',
|
||||||
const packageName = req.params.scope ? addScope(req.params.scope, req.params.package) : req.params.package;
|
function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
|
const packageName: string = req.params.scope ? addScope(req.params.scope, req.params.package) : req.params.package;
|
||||||
|
|
||||||
storage.getPackage({
|
storage.getPackage({
|
||||||
name: packageName,
|
name: packageName,
|
||||||
keepUpLinkData: true,
|
keepUpLinkData: true,
|
||||||
req,
|
req,
|
||||||
callback: function(err, info) {
|
callback: function(err: Error, info: $SidebarPackage) {
|
||||||
if (_.isNil(err)) {
|
if (_.isNil(err)) {
|
||||||
info.latest = info.versions[info[DIST_TAGS].latest];
|
const sideBarInfo: any = _.clone(info);
|
||||||
info = deleteProperties(['readme', 'versions'], info);
|
sideBarInfo.latest = info.versions[info[DIST_TAGS].latest];
|
||||||
info = addGravatarSupport(info);
|
|
||||||
|
info = deleteProperties(['readme', 'versions'], sideBarInfo);
|
||||||
|
info = addGravatarSupport(sideBarInfo);
|
||||||
next(info);
|
next(info);
|
||||||
} else {
|
} else {
|
||||||
res.status(404);
|
res.status(404);
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
import Search from '../../../lib/search';
|
import Search from '../../../lib/search';
|
||||||
import {DIST_TAGS} from '../../../lib/utils';
|
import {DIST_TAGS} from '../../../lib/utils';
|
||||||
|
import type {Router} from 'express';
|
||||||
|
import type {IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer, IStorageHandler} from '../../../../types';
|
||||||
|
|
||||||
function addSearchWebApi(route, storage, auth) {
|
function addSearchWebApi(route: Router, storage: IStorageHandler, auth: IAuth) {
|
||||||
// Search package
|
// Search package
|
||||||
route.get('/search/:anything', function(req, res, next) {
|
route.get('/search/:anything', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
const results = Search.query(req.params.anything);
|
const results = Search.query(req.params.anything);
|
||||||
const packages = [];
|
const packages = [];
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
import HTTPError from 'http-errors';
|
import HTTPError from 'http-errors';
|
||||||
|
import type {Config} from '@verdaccio/types';
|
||||||
|
import type {Router} from 'express';
|
||||||
|
import type {IAuth, $ResponseExtend, $RequestExtend, $NextFunctionVer} from '../../../../types';
|
||||||
import {combineBaseUrl, getWebProtocol} from '../../../lib/utils';
|
import {combineBaseUrl, getWebProtocol} from '../../../lib/utils';
|
||||||
|
|
||||||
function addUserAuthApi(route, auth, config) {
|
function addUserAuthApi(route: Router, auth: IAuth, config: Config) {
|
||||||
route.post('/login', function(req, res, next) {
|
route.post('/login', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
auth.authenticate(req.body.username, req.body.password, (err, user) => {
|
auth.authenticate(req.body.username, req.body.password, (err, user) => {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
req.remote_user = user;
|
req.remote_user = user;
|
||||||
|
@ -17,7 +22,7 @@ function addUserAuthApi(route, auth, config) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
route.post('/-/logout', function(req, res, next) {
|
route.post('/-/logout', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer) {
|
||||||
const base = combineBaseUrl(getWebProtocol(req), req.get('host'), config.url_prefix);
|
const base = combineBaseUrl(getWebProtocol(req), req.get('host'), config.url_prefix);
|
||||||
|
|
||||||
res.cookies.set('token', '');
|
res.cookies.set('token', '');
|
||||||
|
|
13
src/lib/bootstrap.js
vendored
13
src/lib/bootstrap.js
vendored
|
@ -1,13 +1,19 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
import {assign, isObject, isFunction} from 'lodash';
|
import {assign, isObject, isFunction} from 'lodash';
|
||||||
import Path from 'path';
|
import Path from 'path';
|
||||||
import URL from 'url';
|
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 server from '../api/index';
|
import server from '../api/index';
|
||||||
import {parse_address} from './utils';
|
import {parse_address} from './utils';
|
||||||
|
|
||||||
|
import type {Callback} from '@verdaccio/types';
|
||||||
|
import type {$Application} from 'express';
|
||||||
|
|
||||||
const logger = require('./logger');
|
const logger = require('./logger');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,7 +27,7 @@ const logger = require('./logger');
|
||||||
- localhost:5557
|
- localhost:5557
|
||||||
@return {Array}
|
@return {Array}
|
||||||
*/
|
*/
|
||||||
export function getListListenAddresses(argListen, configListen) {
|
export function getListListenAddresses(argListen: string, configListen: mixed) {
|
||||||
// command line || config file || default
|
// command line || config file || default
|
||||||
let addresses;
|
let addresses;
|
||||||
if (argListen) {
|
if (argListen) {
|
||||||
|
@ -57,7 +63,7 @@ export function getListListenAddresses(argListen, configListen) {
|
||||||
* @param {String} pkgVersion
|
* @param {String} pkgVersion
|
||||||
* @param {String} pkgName
|
* @param {String} pkgName
|
||||||
*/
|
*/
|
||||||
function startVerdaccio(config, cliListen, configPath, pkgVersion, pkgName, callback) {
|
function startVerdaccio(config: any, cliListen: string, configPath: string, pkgVersion: string, pkgName: string, callback: Callback) {
|
||||||
if (isObject(config) === false) {
|
if (isObject(config) === false) {
|
||||||
throw new Error('config file must be an object');
|
throw new Error('config file must be an object');
|
||||||
}
|
}
|
||||||
|
@ -143,7 +149,7 @@ function handleHTTPS(app, configPath, config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function listenDefaultCallback(webServer, addr, pkgName, pkgVersion) {
|
function listenDefaultCallback(webServer: $Application, addr: any, pkgName: string, pkgVersion: string) {
|
||||||
webServer.listen(addr.port || addr.path, addr.host, () => {
|
webServer.listen(addr.port || addr.path, addr.host, () => {
|
||||||
// send a message for tests
|
// send a message for tests
|
||||||
if (isFunction(process.send)) {
|
if (isFunction(process.send)) {
|
||||||
|
@ -151,6 +157,7 @@ function listenDefaultCallback(webServer, addr, pkgName, pkgVersion) {
|
||||||
verdaccio_started: true,
|
verdaccio_started: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// $FlowFixMe
|
||||||
}).on('error', function(err) {
|
}).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);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import Path from 'path';
|
import Path from 'path';
|
||||||
|
@ -16,7 +18,7 @@ const pkgJSON = require('../../package.json');
|
||||||
* Find and get the first config file that match.
|
* Find and get the first config file that match.
|
||||||
* @return {String} the config file path
|
* @return {String} the config file path
|
||||||
*/
|
*/
|
||||||
function findConfigFile(configPath) {
|
function findConfigFile(configPath: any) {
|
||||||
if (_.isNil(configPath) === false) {
|
if (_.isNil(configPath) === false) {
|
||||||
return Path.resolve(configPath);
|
return Path.resolve(configPath);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +29,7 @@ function findConfigFile(configPath) {
|
||||||
throw new Error('no configuration files can be proccesed');
|
throw new Error('no configuration files can be proccesed');
|
||||||
}
|
}
|
||||||
|
|
||||||
const primaryConf = _.find(configPaths, (configLocation) => fileExists(configLocation.path));
|
const primaryConf: any = _.find(configPaths, (configLocation: any) => fileExists(configLocation.path));
|
||||||
if (_.isNil(primaryConf) === false) {
|
if (_.isNil(primaryConf) === false) {
|
||||||
return primaryConf.path;
|
return primaryConf.path;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +37,7 @@ function findConfigFile(configPath) {
|
||||||
return createConfigFile(_.head(configPaths)).path;
|
return createConfigFile(_.head(configPaths)).path;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createConfigFile(configLocation) {
|
function createConfigFile(configLocation: any) {
|
||||||
createConfigFolder(configLocation);
|
createConfigFolder(configLocation);
|
||||||
|
|
||||||
const defaultConfig = updateStorageLinks(configLocation, readDefaultConfig());
|
const defaultConfig = updateStorageLinks(configLocation, readDefaultConfig());
|
||||||
|
@ -61,6 +63,7 @@ function updateStorageLinks(configLocation, defaultConfig) {
|
||||||
|
|
||||||
// $XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored,
|
// $XDG_DATA_HOME defines the base directory relative to which user specific data files should be stored,
|
||||||
// If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used.
|
// If $XDG_DATA_HOME is either not set or empty, a default equal to $HOME/.local/share should be used.
|
||||||
|
// $FlowFixMe
|
||||||
let dataDir = process.env.XDG_DATA_HOME || Path.join(process.env.HOME, '.local', 'share');
|
let dataDir = process.env.XDG_DATA_HOME || Path.join(process.env.HOME, '.local', 'share');
|
||||||
if (folder_exists(dataDir)) {
|
if (folder_exists(dataDir)) {
|
||||||
dataDir = Path.resolve(Path.join(dataDir, pkgJSON.name, 'storage'));
|
dataDir = Path.resolve(Path.join(dataDir, pkgJSON.name, 'storage'));
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
/* eslint prefer-rest-params: "off" */
|
|
||||||
/* eslint prefer-spread: "off" */
|
|
||||||
|
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const Error = require('http-errors');
|
const Error = require('http-errors');
|
||||||
|
@ -21,6 +18,7 @@ function flatten(array) {
|
||||||
let result = [];
|
let result = [];
|
||||||
for (let i=0; i<array.length; i++) {
|
for (let i=0; i<array.length; i++) {
|
||||||
if (Array.isArray(array[i])) {
|
if (Array.isArray(array[i])) {
|
||||||
|
/* eslint prefer-spread: "off" */
|
||||||
result.push.apply(result, flatten(array[i]));
|
result.push.apply(result, flatten(array[i]));
|
||||||
} else {
|
} else {
|
||||||
result.push(array[i]);
|
result.push(array[i]);
|
||||||
|
@ -114,6 +112,7 @@ class Config {
|
||||||
*/
|
*/
|
||||||
function normalize_userlist() {
|
function normalize_userlist() {
|
||||||
let result = [];
|
let result = [];
|
||||||
|
/* eslint prefer-rest-params: "off" */
|
||||||
|
|
||||||
for (let i=0; i<arguments.length; i++) {
|
for (let i=0; i<arguments.length; i++) {
|
||||||
if (arguments[i] == null) continue;
|
if (arguments[i] == null) continue;
|
||||||
|
|
|
@ -399,24 +399,24 @@ function addScope(scope: string, packageName: string) {
|
||||||
return `@${scope}/${packageName}`;
|
return `@${scope}/${packageName}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteProperties(propertiesToDelete: Array<string>, packageInfo: Package) {
|
function deleteProperties(propertiesToDelete: Array<string>, objectItem: any) {
|
||||||
_.forEach(propertiesToDelete, (property) => {
|
_.forEach(propertiesToDelete, (property) => {
|
||||||
delete packageInfo[property];
|
delete objectItem[property];
|
||||||
});
|
});
|
||||||
|
|
||||||
return packageInfo;
|
return objectItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addGravatarSupport(info: any) {
|
function addGravatarSupport(pkgInfo: any) {
|
||||||
if (_.isString(_.get(info, 'latest.author.email'))) {
|
if (_.isString(_.get(pkgInfo, 'latest.author.email'))) {
|
||||||
info.latest.author.avatar = generateGravatarUrl(info.latest.author.email);
|
pkgInfo.latest.author.avatar = generateGravatarUrl(pkgInfo.latest.author.email);
|
||||||
} else {
|
} else {
|
||||||
// _.get can't guarantee author property exist
|
// _.get can't guarantee author property exist
|
||||||
_.set(info, 'latest.author.avatar', generateGravatarUrl());
|
_.set(pkgInfo, 'latest.author.avatar', generateGravatarUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_.get(info, 'latest.contributors.length', 0) > 0) {
|
if (_.get(pkgInfo, 'latest.contributors.length', 0) > 0) {
|
||||||
info.latest.contributors = _.map(info.latest.contributors, (contributor) => {
|
pkgInfo.latest.contributors = _.map(pkgInfo.latest.contributors, (contributor) => {
|
||||||
if (_.isString(contributor.email)) {
|
if (_.isString(contributor.email)) {
|
||||||
contributor.avatar = generateGravatarUrl(contributor.email);
|
contributor.avatar = generateGravatarUrl(contributor.email);
|
||||||
} else {
|
} else {
|
||||||
|
@ -428,7 +428,7 @@ function addGravatarSupport(info: any) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return pkgInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -23,6 +23,10 @@ export interface IAuth {
|
||||||
plugins: Array<any>;
|
plugins: Array<any>;
|
||||||
aes_encrypt(buf: Buffer): Buffer;
|
aes_encrypt(buf: Buffer): Buffer;
|
||||||
basic_middleware(): $NextFunctionVer;
|
basic_middleware(): $NextFunctionVer;
|
||||||
|
jwtMiddleware(): $NextFunctionVer;
|
||||||
|
authenticate(user: string, password: string, cb: Callback): void;
|
||||||
|
allow_access(packageName: string, user: string, callback: Callback): void;
|
||||||
|
issue_token(user: string, time: string): string;
|
||||||
add_user(user: string, password: string, cb: Callback): any;
|
add_user(user: string, password: string, cb: Callback): any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,3 +113,4 @@ export interface IStorage {
|
||||||
export type $RequestExtend = $Request & {remote_user?: any}
|
export type $RequestExtend = $Request & {remote_user?: any}
|
||||||
export type $ResponseExtend = $Response & {cookies?: any}
|
export type $ResponseExtend = $Response & {cookies?: any}
|
||||||
export type $NextFunctionVer = NextFunction & mixed;
|
export type $NextFunctionVer = NextFunction & mixed;
|
||||||
|
export type $SidebarPackage = Package & {latest: mixed}
|
||||||
|
|
BIN
yarn.lock
BIN
yarn.lock
Binary file not shown.
Loading…
Reference in a new issue