New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@axah/koa

Package Overview
Dependencies
Maintainers
8
Versions
159
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@axah/koa - npm Package Compare versions

Comparing version 1.5.1 to 2.1.0

lib/create-api-method/auth/index.d.ts

62

lib/create-api-method/auth/index.js
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "__esModule", { value: true });
function createAuth(
// eslint-disable-next-line @typescript-eslint/ban-types
headers) {
const userRoleHeader = headers['cp-axa-user-role'];
const userIdHeader = headers['cp-axa-user-id'];
if (!userRoleHeader) {
throw new Error('Missing cp-axa-user-role header');
}
if (!userIdHeader) {
throw new Error('Missing cp-axa-user-id header');
}
const userRoles = userRoleHeader
.split(',')
.map((r) => r.trim())
.filter((r) => r);
if (userRoles.length === 0) {
throw new Error('Empty cp-axa-user-role header');
}
return {
userId: userIdHeader,
userRoles,
hasRole(...roles) {
return roles.some((role) => userRoles.indexOf(role) !== -1);
},
};
}
exports.default = createAuth;
// eslint-disable-next-line import/no-unused-modules
function createAuth(headers) {
const userRoleHeader = headers['cp-axa-user-role'];
const userIdHeader = headers['cp-axa-user-id'];
if (!userRoleHeader) {
throw new Error('Missing cp-axa-user-role header');
}
if (!userIdHeader) {
throw new Error('Missing cp-axa-user-id header');
}
const userRoles = userRoleHeader.split(',').map(r => r.trim()).filter(r => r);
if (userRoles.length === 0) {
throw new Error('Empty cp-axa-user-role header');
}
return {
userId: userIdHeader,
userRoles,
hasRole(...roles) {
return roles.some(role => userRoles.indexOf(role) !== -1);
}
};
}
//# sourceMappingURL=index.js.map
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const koa_body_1 = __importDefault(require("koa-body"));
const http_status_codes_1 = require("http-status-codes");
const auth_1 = __importDefault(require("./auth"));
function createApiMethod({ allowedRoles, body: bodyValidator, query: queryValidator, params: paramsValidator, files: allowFiles = false, }, executor) {
const parseBody = koa_body_1.default({
json: true,
multipart: allowFiles,
urlencoded: false,
text: false,
formLimit: '20mb',
});
return async (ctx, next) => {
// 1. Check authentication
let auth;
try {
auth = auth_1.default(ctx.req.headers);
}
catch (e) {
ctx.log.error(e, 'Failed to collect auth information');
ctx.status = http_status_codes_1.StatusCodes.FORBIDDEN;
ctx.body = { error: http_status_codes_1.ReasonPhrases.FORBIDDEN };
return;
}
if (!auth.hasRole(...allowedRoles)) {
ctx.log.error('User %s (%j) tried to access %s %s but does not have one of the required roles %j', auth.userId, auth.userRoles, ctx.method, ctx.path, allowedRoles);
ctx.status = http_status_codes_1.StatusCodes.FORBIDDEN;
ctx.body = { error: http_status_codes_1.ReasonPhrases.FORBIDDEN };
return;
}
// 2. parse body
// eslint-disable-next-line @typescript-eslint/no-empty-function
await parseBody(ctx, async () => { });
// 2b. validate body
let bodyValidationResult;
try {
bodyValidationResult = bodyValidator.parse(Object.assign(Object.assign({}, ctx.request.body), (allowFiles ? ctx.request.files : {})));
}
catch (e) {
ctx.log.error(e, 'body is invalid');
ctx.status = http_status_codes_1.StatusCodes.NOT_ACCEPTABLE;
ctx.body = { error: 'body is invalid' };
return;
}
let paramsValidationResult;
try {
paramsValidationResult = paramsValidator.parse(ctx.params || {});
}
catch (e) {
ctx.log.error(e, 'param is invalid');
ctx.status = http_status_codes_1.StatusCodes.NOT_ACCEPTABLE;
ctx.body = { error: 'params is invalid' };
return;
}
let queryValidationResult;
try {
queryValidationResult = queryValidator.parse(ctx.query || {});
}
catch (e) {
ctx.log.error(e, 'query is invalid');
ctx.status = http_status_codes_1.StatusCodes.NOT_ACCEPTABLE;
ctx.body = { error: 'query is invalid' };
return;
}
await executor({
body: bodyValidationResult,
params: paramsValidationResult,
query: queryValidationResult,
auth,
ctx,
next,
});
};
}
exports.default = createApiMethod;
var _koaBody = _interopRequireDefault(require("koa-body"));
var _httpStatus = _interopRequireDefault(require("http-status"));
var _auth = _interopRequireDefault(require("./auth"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function createApiMethod({
allowedRoles,
body: bodyValidator,
query: queryValidator,
params: paramsValidator,
files: allowFiles = false
}, executor) {
const parseBody = (0, _koaBody.default)({
json: true,
multipart: allowFiles,
urlencoded: false,
text: false,
formLimit: '20mb'
});
return async (ctx, next) => {
// 1. Check authentication
let auth;
try {
auth = (0, _auth.default)(ctx.req.headers);
} catch (e) {
// $FlowFixMe ctx.log is not typed in koa...
ctx.log.error(e, 'Failed to collect auth information');
ctx.status = _httpStatus.default.FORBIDDEN;
ctx.body = {
error: 'FORBIDDEN'
};
return;
}
if (!auth.hasRole(...allowedRoles)) {
// $FlowFixMe ctx.log is not typed in koa...
ctx.log.error('User %s (%j) tried to access %s %s but does not have one of the required roles %j', auth.userId, auth.userRoles, ctx.method, ctx.path, allowedRoles);
ctx.status = _httpStatus.default.FORBIDDEN;
ctx.body = {
error: 'FORBIDDEN'
};
return;
} // 2. parse body
await parseBody(ctx, async () => {}); // 2b. validate body
const bodyValidationResult = bodyValidator.validate({ ...ctx.request.body,
...(allowFiles ? ctx.request.files : {})
});
if (bodyValidationResult.state === 'invalid') {
// $FlowFixMe ctx.log is not typed in koa...
ctx.log.error('Request body is invalid: %j', bodyValidationResult);
ctx.status = _httpStatus.default.NOT_ACCEPTABLE;
ctx.body = {
error: 'body is invalid'
};
return;
} // 3. validate path params
const paramsValidationResult = paramsValidator.validate(ctx.params || {});
if (paramsValidationResult.state === 'invalid') {
// $FlowFixMe ctx.log is not typed in koa...
ctx.log.error('param is invalid: %j', paramsValidationResult);
ctx.status = _httpStatus.default.NOT_ACCEPTABLE;
ctx.body = {
error: 'params is invalid'
};
return;
}
const queryValidationResult = queryValidator.validate(ctx.query || {});
if (queryValidationResult.state === 'invalid') {
// $FlowFixMe ctx.log is not typed in koa...
ctx.log.error('query is invalid: %j', queryValidationResult);
ctx.status = _httpStatus.default.NOT_ACCEPTABLE;
ctx.body = {
error: 'query is invalid'
};
return;
}
await executor({
body: bodyValidationResult.value,
params: paramsValidationResult.value,
query: queryValidationResult.value,
auth,
ctx,
next
});
};
}
//# sourceMappingURL=index.js.map
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = errorHandler;
var _httpStatus = _interopRequireDefault(require("http-status"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
Object.defineProperty(exports, "__esModule", { value: true });
const http_status_codes_1 = require("http-status-codes");
async function errorHandler(ctx, next) {
try {
await next();
if (!ctx.status) {
// $FlowFixMe ctx.log is not typed in koa...
ctx.log.error('No status set for request %s', ctx.path);
try {
await next();
if (!ctx.status) {
ctx.log.error('No status set for request %s', ctx.path);
}
if (typeof ctx.body === 'undefined') {
ctx.log.warn('No body set for request %s', ctx.path);
}
}
if (typeof ctx.body === 'undefined') {
// $FlowFixMe ctx.log is not typed in koa...
ctx.log.warn('No body set for request %s', ctx.path);
catch (e) {
// no logging of errors required as the log middleware already does so...
ctx.status = http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR;
ctx.body = { error: http_status_codes_1.ReasonPhrases.INTERNAL_SERVER_ERROR };
if (process.env.NODE_ENV !== 'production') {
ctx.body.stack = e.stack;
}
}
} catch (e) {
// no logging of errors required as the log middleware already does so...
ctx.status = _httpStatus.default.INTERNAL_SERVER_ERROR;
ctx.body = {
error: 'INTERNAL_SERVER_ERROR'
};
if (process.env.NODE_ENV !== 'production') {
// $FlowFixMe
ctx.body.stack = e.stack;
}
}
}
}
exports.default = errorHandler;
//# sourceMappingURL=error-handler.js.map
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
Object.defineProperty(exports, "errorHandler", {
enumerable: true,
get: function () {
return _errorHandler.default;
}
});
Object.defineProperty(exports, "log", {
enumerable: true,
get: function () {
return _log.default;
}
});
Object.defineProperty(exports, "validate", {
enumerable: true,
get: function () {
return _validate.default;
}
});
Object.defineProperty(exports, "createApiMethod", {
enumerable: true,
get: function () {
return _createApiMethod.default;
}
});
Object.defineProperty(exports, "createValidator", {
enumerable: true,
get: function () {
return _createValidator.default;
}
});
Object.defineProperty(exports, "createOptionalValidator", {
enumerable: true,
get: function () {
return _createValidator.createOptionalValidator;
}
});
Object.defineProperty(exports, "redact", {
enumerable: true,
get: function () {
return _redact.default;
}
});
var _errorHandler = _interopRequireDefault(require("./error-handler"));
var _log = _interopRequireDefault(require("./log"));
var _validate = _interopRequireDefault(require("./create-api-method/validate"));
var _createApiMethod = _interopRequireDefault(require("./create-api-method"));
var _createValidator = _interopRequireWildcard(require("./create-api-method/validate/create-validator"));
var _redact = _interopRequireDefault(require("./redact"));
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.redact = exports.createApiMethod = exports.validate = exports.log = exports.errorHandler = void 0;
var error_handler_1 = require("./error-handler");
Object.defineProperty(exports, "errorHandler", { enumerable: true, get: function () { return __importDefault(error_handler_1).default; } });
var log_1 = require("./log");
Object.defineProperty(exports, "log", { enumerable: true, get: function () { return __importDefault(log_1).default; } });
exports.validate = __importStar(require("zod"));
var create_api_method_1 = require("./create-api-method");
Object.defineProperty(exports, "createApiMethod", { enumerable: true, get: function () { return __importDefault(create_api_method_1).default; } });
var redact_1 = require("./redact");
Object.defineProperty(exports, "redact", { enumerable: true, get: function () { return __importDefault(redact_1).default; } });
//# sourceMappingURL=index.js.map
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = createLogMiddleware;
var _v = _interopRequireDefault(require("uuid/v4"));
var _pino = require("pino");
var _log = require("@axah/log");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
Object.defineProperty(exports, "__esModule", { value: true });
const uuid_1 = require("uuid");
const pino_1 = require("pino");
const log_1 = require("@axah/log");
function parseJwt(token) {
if (!token) {
return null;
}
const payloadB64Url = token.split('.')[1];
const payloadB64 = payloadB64Url.replace(/-/g, '+').replace(/_/g, '/');
return JSON.parse(Buffer.from(payloadB64, 'base64').toString('utf8'));
if (!token) {
return null;
}
const payloadB64Url = token.split('.')[1];
const payloadB64 = payloadB64Url.replace(/-/g, '+').replace(/_/g, '/');
return JSON.parse(Buffer.from(payloadB64, 'base64').toString('utf8'));
}
function parseMessageIdFromHeaders(headers) {
// cp-uuid from our loved CP
return headers['cp-uuid'] // x-axa-msgid from ESG (API Gateway, for services)
|| headers['x-axa-msgid'] // requestcorrelator from WAF (Web Application Firewall, for frontends)
|| headers.requestcorrelator // custom uuid when nothing else is present
|| `custom-${(0, _v.default)()}`;
// cp-uuid from our loved CP
return (headers['cp-uuid'] ||
// x-axa-msgid from ESG (API Gateway, for services)
headers['x-axa-msgid'] ||
// requestcorrelator from WAF (Web Application Firewall, for frontends)
headers.requestcorrelator ||
// custom uuid when nothing else is present
`custom-${uuid_1.v4()}`);
}
function parseInitialMessageIdFromHeaders(headers) {
// x-axa-initialmsgid from ESG (API Gateway, for services)
return headers['x-axa-initialmsgid'];
// x-axa-initialmsgid from ESG (API Gateway, for services)
return headers['x-axa-initialmsgid'];
}
function parseSessionIdFromHeaders(headers) {
// clientcorrelator from WAF (Web Application Firewall, for frontends)
return headers.clientcorrelator;
// clientcorrelator from WAF (Web Application Firewall, for frontends)
return headers.clientcorrelator;
}
function parseAuthenticationInfoFromJwt(jwt) {
const tokenPayload = parseJwt(jwt);
return tokenPayload && {
// x-axa-context V1 and MAAM AT V1 used to have a { value: string } object as sub,
// V2s have a string sub
user: typeof tokenPayload.sub === 'object' && tokenPayload.sub !== null ? tokenPayload.sub.value : tokenPayload.sub,
initialUser: typeof tokenPayload.initialSub === 'object' && tokenPayload.initialSub !== null ? tokenPayload.initialSub.value : tokenPayload.initialSub,
client: // client_id of x-axa-context v2 & MAAM v2
tokenPayload.client_id // initialSub of x-axa-context v1
|| tokenPayload.initialClientId // aud of MAAM access token v1
// NOTE: aud in MAAM v2 could be an array, but MAAM v2 as a client_id (preferred, see above)
|| tokenPayload.aud
};
const tokenPayload = parseJwt(jwt);
return (tokenPayload && {
// x-axa-context V1 and MAAM AT V1 used to have a { value: string } object as sub,
// V2s have a string sub
user: typeof tokenPayload.sub === 'object' && tokenPayload.sub !== null
? tokenPayload.sub.value
: tokenPayload.sub,
initialUser: typeof tokenPayload.initialSub === 'object' &&
tokenPayload.initialSub !== null
? tokenPayload.initialSub.value
: tokenPayload.initialSub,
client:
// client_id of x-axa-context v2 & MAAM v2
tokenPayload.client_id ||
// initialSub of x-axa-context v1
tokenPayload.initialClientId ||
// aud of MAAM access token v1
// NOTE: aud in MAAM v2 could be an array, but MAAM v2 as a client_id (preferred, see above)
tokenPayload.aud,
});
}
function parseAuthenticationInfoFromHeaders(headers) {
// cp-axa-user-id / -role from our beloved api-gateway
if (headers['cp-axa-user-id']) {
return {
user: headers['cp-axa-user-id'],
role: headers['cp-axa-user-role']
};
} // authorization header (e.g. frontend inside WebView)
if (headers.authorization && headers.authorization.startsWith('Bearer ')) {
return parseAuthenticationInfoFromJwt(headers.authorization.substr(8));
} // x-axa-context from our beloved ESG
if (headers['x-axa-context']) {
return parseAuthenticationInfoFromJwt(headers['x-axa-context']);
}
return {};
// cp-axa-user-id / -role from our beloved api-gateway
if (headers['cp-axa-user-id']) {
return {
user: headers['cp-axa-user-id'],
role: headers['cp-axa-user-role'],
};
}
// authorization header (e.g. frontend inside WebView)
if (headers.authorization && headers.authorization.startsWith('Bearer ')) {
return parseAuthenticationInfoFromJwt(headers.authorization.substr(8));
}
// x-axa-context from our beloved ESG
if (headers['x-axa-context']) {
return parseAuthenticationInfoFromJwt(headers['x-axa-context']);
}
return {};
}
function parseMdcFromHeaders(logger, headers) {
const messageId = parseMessageIdFromHeaders(headers);
const initialMessageId = parseInitialMessageIdFromHeaders(headers);
const sessionId = parseSessionIdFromHeaders(headers);
let authInfo;
try {
authInfo = parseAuthenticationInfoFromHeaders(headers);
} catch (e) {
logger.error(e, 'Failed to parse auth info from headers');
authInfo = {};
}
return {
messageId,
initialMessageId,
sessionId,
...authInfo
};
const messageId = parseMessageIdFromHeaders(headers);
const initialMessageId = parseInitialMessageIdFromHeaders(headers);
const sessionId = parseSessionIdFromHeaders(headers);
let authInfo;
try {
authInfo = parseAuthenticationInfoFromHeaders(headers);
}
catch (e) {
logger.error(e, 'Failed to parse auth info from headers');
authInfo = {};
}
return Object.assign({ messageId,
initialMessageId,
sessionId }, authInfo);
}
function createLogMiddleware(logger, logRequests = true) {
return async function middleware(ctx, next) {
const mdc = parseMdcFromHeaders(logger, ctx.req.headers);
return (0, _log.runWithMdc)(mdc, async () => {
// $FlowFixMe non-standard properties...
const logDoNotUse = ctx.log = ctx.req.log = ctx.res.log = ctx.request.log = ctx.response.log = logger; // eslint-disable-line no-multi-assign, max-len
const startTime = Date.now();
const requestLogger = logDoNotUse.child({
// $FlowFixMe flow doesn't like the pino typings too much... -.-"
serializers: _pino.stdSerializers
});
try {
await next();
const responseTime = Date.now() - startTime;
if (logRequests) {
requestLogger.info({
responseTime,
res: ctx.res,
req: ctx.req
}, 'Request to %s finished in %dms with status %s', ctx.path, responseTime, ctx.status);
}
} catch (e) {
const responseTime = Date.now() - startTime;
requestLogger.error({
responseTime,
res: ctx.res,
req: ctx.req,
err: e
}, 'Request to %s threw after %dms', ctx.path, responseTime); // re-throw here to let somebody else handle the error
throw e;
}
});
};
}
return async function middleware(ctx, next) {
const mdc = parseMdcFromHeaders(logger, ctx.req.headers);
return log_1.runWithMdc(mdc, async () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const logDoNotUse = (ctx.log = ctx.req.log = ctx.res.log = ctx.request.log = ctx.response.log = logger); // eslint-disable-line no-multi-assign, max-len
const startTime = Date.now();
const requestLogger = logDoNotUse.child({
// $FlowFixMe flow doesn't like the pino typings too much... -.-"
serializers: pino_1.stdSerializers,
});
try {
await next();
const responseTime = Date.now() - startTime;
if (logRequests) {
requestLogger.info({
responseTime,
res: ctx.res,
req: ctx.req,
}, 'Request to %s finished in %dms with status %s', ctx.path, responseTime, ctx.status);
}
}
catch (e) {
const responseTime = Date.now() - startTime;
requestLogger.error({
responseTime,
res: ctx.res,
req: ctx.req,
err: e,
}, 'Request to %s threw after %dms', ctx.path, responseTime);
// re-throw here to let somebody else handle the error
throw e;
}
});
};
}
exports.default = createLogMiddleware;
//# sourceMappingURL=log.js.map
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _default = {
paths: ['req.headers', 'res.headers'],
censor: headers => Object.keys(headers).reduce((accum, key) => {
switch (key) {
case 'set-cookie':
case 'cookie':
case 'authorization':
case 'x-axa-context':
accum[key] = 'redacted'; // eslint-disable-line no-param-reassign
break;
default:
accum[key] = headers[key];
// eslint-disable-line no-param-reassign
}
return accum;
}, {})
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = {
paths: ['req.headers', 'res.headers'],
censor: (headers) => Object.keys(headers).reduce((accum, key) => {
switch (key) {
case 'set-cookie':
case 'cookie':
case 'authorization':
case 'x-axa-context':
// eslint-disable-next-line no-param-reassign
accum[key] = 'redacted';
break;
default:
// eslint-disable-next-line no-param-reassign
accum[key] = headers[key];
}
return accum;
}, {}),
};
exports.default = _default;
//# sourceMappingURL=redact.js.map
{
"name": "@axah/koa",
"version": "1.5.1",
"version": "2.1.0",
"main": "lib/index.js",

@@ -10,4 +10,4 @@ "license": "UNLICENSED",

"scripts": {
"dev": "nodemon -w src -e js --exec yarn build",
"lint": "eslint . && flow check",
"dev": "nodemon -w src -e ts --exec yarn build",
"lint": " tsc --noEmit && eslint .",
"prepublishOnly": "yarn build",

@@ -17,32 +17,36 @@ "build": "yarn lint && yarn test && yarn clean && npm-run-all -p build:*",

"clean": "rimraf lib",
"build:babel": "babel src/ -d lib/ --ignore '**/*.test.js,**/__mocks__/**'",
"build:flow": "flow-copy-source -i '**/*.test.js' -i '**/__mocks__/**' src lib/",
"build:typescript": "tsc --build tsconfig.build.json",
"test": "jest",
"ci": "yarn build && yarn flow stop"
"ci": "yarn build"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@babel/preset-flow": "^7.9.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.8.0",
"eslint-config-airbnb-base": "^14.1.0",
"eslint-plugin-flowtype": "^4.7.0",
"eslint-plugin-import": "^2.20.2",
"flow-bin": "0.123.0",
"flow-copy-source": "^2.0.9",
"flow-typed": "^3.1.0",
"jest": "^25.5.0",
"koa": "^2.11.0",
"nodemon": "^2.0.3",
"@shopify/jest-koa-mocks": "^2.2.3",
"@types/jest": "^26.0.13",
"@types/koa": "^2.11.4",
"@types/node": "^14.10.1",
"@types/pino": "^6.3.2",
"@types/uuid": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^4.1.0",
"@typescript-eslint/parser": "^4.1.0",
"eslint": "^7.9.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-prettier": "^3.1.4",
"flowgen": "^1.11.0",
"jest": "^26.4.2",
"koa": "^2.13.0",
"nodemon": "^2.0.4",
"npm-run-all": "^4.1.5",
"pino": "^5.17.0"
"pino": "^6.7.0",
"prettier": "^2.1.1",
"ts-jest": "^26.3.0",
"typescript": "^4.0.2"
},
"dependencies": {
"@axah/log": "^1.1.0",
"http-status": "^1.4.2",
"koa-body": "^4.1.1",
"uuid": "^3.4.0",
"valid-url": "^1.0.9"
"http-status-codes": "^2.1.4",
"koa-body": "^4.2.0",
"uuid": "^8.3.1",
"zod": "2.0.0-beta.5"
},

@@ -49,0 +53,0 @@ "peerDependencies": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc