This commit is contained in:
2026-03-03 15:23:00 +00:00
parent 5e3726de39
commit 8e223bfbec
3689 changed files with 955330 additions and 1011 deletions

View File

@@ -0,0 +1,104 @@
const methods = require('methods');
const deprecate = require('depd')('express');
const app = {};
const trustProxyDefaultSymbol = '@@symbol:trust_proxy_default';
app.init = function init() {
this.cache = {};
this.settings = {};
this.engines = {};
this.defaultConfiguration();
};
app.defaultConfiguration = function defaultConfiguration() {
this.enable('x-powered-by');
this.set('etag', 'weak');
const env = process.env.NODE_ENV || 'development';
this.set('env', env);
this.set('query parser', 'extended');
this.set('subdomain offset', 2);
this.set('trust proxy', false);
Object.defineProperty(this.settings, trustProxyDefaultSymbol, {
configurable: true,
value: true
});
this.locals = Object.create(null);
this.mountpath = '/';
this.locals.settings = this.settings;
this.set('jsonp callback name', 'callback');
if (env === 'production') {
this.enable('view cache');
}
Object.defineProperty(this, 'router', {
get() {
throw new Error(
"'app.router' is deprecated!\nPlease see the 3.x to 4.x migration guide for details on how to update your app."
);
}
});
};
app.lazyrouter = () => {};
app.handle = () => {};
app.route = () => {};
app.render = () => {};
app.listen = () => {};
app.use = function use() {
return this;
};
app.engine = function engine() {
return this;
};
app.param = function param() {
return this;
};
app.set = function set(setting, val) {
if (arguments.length === 1) {
return this.settings[setting];
}
this.settings[setting] = val;
return this;
};
app.path = function path() {
return '';
};
app.enabled = function enabled(setting) {
return !!this.set(setting);
};
app.disabled = function disabled(setting) {
return !this.set(setting);
};
app.enable = function enable(setting) {
return this.set(setting, true);
};
app.disable = function disable(setting) {
return this.set(setting, false);
};
methods.forEach((method) => {
app[method] = function httpMethod() {
return this;
};
});
app.all = function all() {
return this;
};
app.del = deprecate.function(app.delete, 'app.del: Use app.delete instead');
module.exports = app;

View File

@@ -0,0 +1,35 @@
const { EventEmitter } = require('events');
const mixin = require('merge-descriptors');
const application = require('./mock-application');
const request = require('./mock-request');
const response = require('../mockResponse');
const expressResponse = {
createResponse: response.createResponse
};
function createApplication() {
const app = function () {};
mixin(app, EventEmitter.prototype, false);
mixin(app, application, false);
app.request = {
__proto__: request,
app
};
app.response = {
__proto__: expressResponse.createResponse(),
app
};
app.init();
return app;
}
module.exports = createApplication;
module.exports.application = application;
module.exports.request = request;
module.exports.response = expressResponse;

View File

@@ -0,0 +1,170 @@
const accepts = require('accepts');
const typeis = require('type-is');
const parseRange = require('range-parser');
const parse = require('parseurl');
const { isIP } = require('net');
const fresh = require('fresh');
const http = require('http');
const defineGetter = require('./utils/define-getter');
const req = {
__proto__: http.IncomingMessage.prototype
};
req.header = function header(name) {
const headerName = name.toLowerCase();
switch (headerName) {
case 'referer':
case 'referrer':
return this.headers.referrer || this.headers.referer;
default:
return this.headers[headerName];
}
};
req.get = req.header;
req.accepts = function acceptTypes(...args) {
const accept = accepts(this);
return accept.types(...args);
};
req.acceptsEncodings = function acceptsEncodings(...args) {
const accept = accepts(this);
return accept.encodings(...args);
};
req.acceptsEncoding = req.acceptsEncodings;
req.acceptsCharsets = function acceptsCharsets(...args) {
const accept = accepts(this);
return accept.charsets(...args);
};
req.acceptsCharset = req.acceptsCharsets;
req.acceptsLanguages = function acceptsLanguages(...args) {
const accept = accepts(this);
return accept.languages(...args);
};
req.acceptsLanguage = req.acceptsLanguages;
req.range = function getRange(size) {
const range = this.get('Range');
if (!range) {
return undefined;
}
return parseRange(size, range);
};
req.param = function param(name, defaultValue) {
const params = this.params || {};
const body = this.body || {};
const query = this.query || {};
if (params[name] !== null && {}.hasOwnProperty.call(params, name)) {
return params[name];
}
if (body[name] !== null) {
return body[name];
}
if (query[name] !== null) {
return query[name];
}
return defaultValue;
};
req.is = function is(...args) {
let types = args;
if (Array.isArray(args[0])) {
types = args[0];
}
return typeis(this, types);
};
defineGetter(req, 'protocol', function protocol() {
let { proto } = this.options;
proto = this.get('X-Forwarded-Proto') || proto;
return proto.split(/\s*,\s*/)[0];
});
defineGetter(req, 'secure', function secure() {
return this.protocol === 'https';
});
defineGetter(req, 'ip', function ip() {
return this.options.ip || '127.0.0.1';
});
defineGetter(req, 'ips', function ips() {
return [this.ip];
});
defineGetter(req, 'subdomains', function subdomains() {
const { hostname } = this;
if (!hostname) {
return [];
}
const offset = this.app.get('subdomain offset');
const domains = !isIP(hostname) ? hostname.split('.').reverse() : [hostname];
return domains.slice(offset);
});
defineGetter(req, 'path', function path() {
return parse(this).pathname;
});
defineGetter(req, 'hostname', function hostname() {
let host = this.get('X-Forwarded-Host');
if (!host) {
host = this.get('Host');
}
if (!host) {
return undefined;
}
const offset = host[0] === '[' ? host.indexOf(']') + 1 : 0;
const index = host.indexOf(':', offset);
return index < 0 ? host.substring(0, index) : host;
});
defineGetter(req, 'host', function host() {
return this.hostname;
});
defineGetter(req, 'fresh', function isFresh() {
const { method } = this;
const { statusCode } = this.res;
if (method !== 'GET' && method !== 'HEAD') {
return false;
}
if ((statusCode >= 200 && statusCode < 300) || statusCode === 304) {
return fresh(this.headers, this.res._headers || {});
}
return false;
});
defineGetter(req, 'stale', function stale() {
return !this.fresh;
});
defineGetter(req, 'xhr', function xhr() {
const val = this.get('X-Requested-With') || '';
return val.toLowerCase() === 'xmlhttprequest';
});
module.exports = req;

View File

@@ -0,0 +1,9 @@
function defineGetter(obj, name, getter) {
Object.defineProperty(obj, name, {
configurable: true,
enumerable: true,
get: getter
});
}
module.exports = defineGetter;

137
node_modules/node-mocks-http/lib/headers.js generated vendored Normal file
View File

@@ -0,0 +1,137 @@
/**
* This file implements the Web API Headers interface
* (https://developer.mozilla.org/en-US/docs/Web/API/Headers)
* while maintaining compatibility with Express.js style header access.
*/
const utils = require('./utils');
const REFERER_HEADER_NAMES = ['referer', 'referrer'];
/**
* Get a header value from the headers object.
* Because headers can be set in multiple ways, their names can be uppercased and lowercased.
*
* @param {Object} headers
* @param {string} name
* @returns
*/
function getHeaderValue(headers, name) {
const lowerName = name.toLowerCase();
return headers[
Object.keys(headers).find((key) => {
const lowerKey = key.toLowerCase();
return (
lowerKey === lowerName ||
(REFERER_HEADER_NAMES.includes(lowerKey) && REFERER_HEADER_NAMES.includes(lowerName))
);
})
];
}
/**
* Creates a Headers object that implements both Express.js style access
* and the Web API Headers interface
*
* @param {Object} headers - Initial headers object
* @returns {HeaderWebAPI} - A proxy that implements the HeaderWebAPI interface
*/
function createHeaders(headers = {}) {
return new Proxy(utils.convertKeysToLowerCase(headers), {
get(target, prop) {
// Handle Headers interface methods
switch (prop) {
case 'get':
return (name) => getHeaderValue(target, name);
case 'getAll':
return (name) => {
const value = getHeaderValue(target, name);
if (!value) {
return [];
}
return Array.isArray(value) ? value : [value];
};
case 'has':
return (name) => getHeaderValue(target, name) !== undefined;
case 'set':
return (name, value) => {
// eslint-disable-next-line no-param-reassign
target[name.toLowerCase()] = value;
};
case 'append':
return (name, value) => {
const lowerName = name.toLowerCase();
if (lowerName in target) {
const existingValue = target[lowerName];
if (Array.isArray(existingValue)) {
existingValue.push(value);
} else {
// eslint-disable-next-line no-param-reassign
target[lowerName] = [existingValue, value];
}
} else {
// eslint-disable-next-line no-param-reassign
target[lowerName] = value;
}
};
case 'delete':
return (name) => {
// eslint-disable-next-line no-param-reassign
delete target[name.toLowerCase()];
};
case 'forEach':
return (callback, thisArg) => {
Object.entries(target).forEach(([key, value]) => {
callback.call(thisArg, value, key, target);
});
};
case 'entries':
return () => Object.entries(target)[Symbol.iterator]();
case 'keys':
return () => Object.keys(target)[Symbol.iterator]();
case 'values':
return () => Object.values(target)[Symbol.iterator]();
case Symbol.iterator:
return (
target[Symbol.iterator] ||
function* iterator() {
yield* Object.entries(target);
}
);
default:
return typeof prop === 'string' ? getHeaderValue(target, prop) : target[prop];
}
},
set(target, prop, value) {
if (typeof prop === 'string') {
// eslint-disable-next-line no-param-reassign
target[prop.toLowerCase()] = value;
return true;
}
return false;
},
has(target, prop) {
if (typeof prop === 'string') {
return prop.toLowerCase() in target;
}
return prop in target;
},
deleteProperty(target, prop) {
if (typeof prop === 'string') {
// eslint-disable-next-line no-param-reassign
delete target[prop.toLowerCase()];
return true;
}
// eslint-disable-next-line no-param-reassign
return delete target[prop];
},
ownKeys(target) {
return Object.keys(target);
},
getOwnPropertyDescriptor(target, prop) {
return Object.getOwnPropertyDescriptor(target, prop);
}
});
}
module.exports = { createHeaders, getHeaderValue };

200
node_modules/node-mocks-http/lib/http-mock.d.ts generated vendored Normal file
View File

@@ -0,0 +1,200 @@
import { Request, Response, CookieOptions } from 'express';
import { IncomingMessage, OutgoingMessage } from 'http';
export type RequestType = IncomingMessage | globalThis.Request;
export type ResponseType = OutgoingMessage | globalThis.Response;
export type RequestMethod = 'CONNECT' | 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT' | 'TRACE';
export interface Params {
[key: string]: any;
}
export interface Session {
[key: string]: any;
}
export interface Cookies {
[key: string]: string;
}
export interface Headers {
// Standard HTTP headers
accept?: string;
'accept-language'?: string;
'accept-patch'?: string;
'accept-ranges'?: string;
'access-control-allow-credentials'?: string;
'access-control-allow-headers'?: string;
'access-control-allow-methods'?: string;
'access-control-allow-origin'?: string;
'access-control-expose-headers'?: string;
'access-control-max-age'?: string;
age?: string;
allow?: string;
'alt-svc'?: string;
authorization?: string;
'cache-control'?: string;
connection?: string;
'content-disposition'?: string;
'content-encoding'?: string;
'content-language'?: string;
'content-length'?: string;
'content-location'?: string;
'content-range'?: string;
'content-type'?: string;
cookie?: string;
date?: string;
expect?: string;
expires?: string;
forwarded?: string;
from?: string;
host?: string;
'if-match'?: string;
'if-modified-since'?: string;
'if-none-match'?: string;
'if-unmodified-since'?: string;
'last-modified'?: string;
location?: string;
pragma?: string;
'proxy-authenticate'?: string;
'proxy-authorization'?: string;
'public-key-pins'?: string;
range?: string;
referer?: string;
'retry-after'?: string;
'set-cookie'?: string[];
'strict-transport-security'?: string;
tk?: string;
trailer?: string;
'transfer-encoding'?: string;
upgrade?: string;
'user-agent'?: string;
vary?: string;
via?: string;
warning?: string;
'www-authenticate'?: string;
// Support for arbitrary headers
[header: string]: string | string[] | undefined;
}
/**
* HeaderWebAPI interface combines the existing Headers type with
* standard Web API Headers interface methods for better compatibility
* with browser environments.
*/
export interface HeaderWebAPI {
// Include all the header properties
[header: string]: any; // 'any' to accommodate both header values and methods
// Web API Headers methods
append(name: string, value: string): void;
delete(name: string): void;
get(name: string): string | null;
has(name: string): boolean;
set(name: string, value: string): void;
forEach(callbackfn: (value: string, key: string, parent: HeaderWebAPI) => void, thisArg?: any): void;
// Iterator methods
entries(): IterableIterator<[string, string]>;
keys(): IterableIterator<string>;
values(): IterableIterator<string>;
[Symbol.iterator](): IterableIterator<[string, string]>;
}
export interface Query {
[key: string]: any;
}
export interface Files {
[key: string]: string;
}
export interface Body {
[key: string]: any;
}
export interface RequestOptions {
method?: RequestMethod;
url?: string;
originalUrl?: string;
baseUrl?: string;
path?: string;
params?: Params;
session?: Session;
cookies?: Cookies;
signedCookies?: Cookies;
headers?: Headers;
body?: Body;
query?: Query;
files?: Files;
ip?: string;
// Support custom properties appended on Request objects.
[key: string]: any;
}
export type MockRequest<T extends RequestType> = T & {
_setParameter: (key: string, value?: string) => void;
_setSessionVariable: (variable: string, value?: string) => void;
_setCookiesVariable: (variable: string, value?: string) => void;
_setSignedCookiesVariable: (variable: string, value?: string) => void;
_setHeadersCookiesVariable: (variable: string, value: string) => void;
_setFilesCookiesVariable: (variable: string, value?: string) => void;
_setMethod: (method?: string) => void;
_setURL: (value?: string) => void;
_setOriginalUrl: (value?: string) => void;
_setBody: (body?: Body) => void;
_addBody: (key: string, value?: any) => void;
headers: HeaderWebAPI;
// Support custom properties appended on Request objects.
[key: string]: any;
};
export interface ResponseOptions {
eventEmitter?: any;
writableStream?: any;
req?: any;
locals?: any;
}
export type ResponseCookie = {
value: any;
options: CookieOptions;
};
export type MockResponse<T extends ResponseType> = T & {
_isEndCalled: () => boolean;
_getHeaders: () => HeaderWebAPI;
_getData: () => any;
_getJSONData: () => any;
_getBuffer: () => Buffer;
_getLocals: () => any;
_getStatusCode: () => number;
_getStatusMessage: () => string;
_isJSON: () => boolean;
_isUTF8: () => boolean;
_isDataLengthValid: () => boolean;
_getRedirectUrl: () => string;
_getRenderData: () => any;
_getRenderView: () => string;
cookies: { [name: string]: ResponseCookie };
};
export function createRequest<T extends RequestType = Request>(options?: RequestOptions): MockRequest<T>;
export function createResponse<T extends ResponseType = Response>(options?: ResponseOptions): MockResponse<T>;
export interface Mocks<T1 extends RequestType, T2 extends ResponseType> {
req: MockRequest<T1>;
res: MockResponse<T2>;
}
export function createMocks<T1 extends RequestType = Request, T2 extends ResponseType = Response>(
reqOptions?: RequestOptions,
resOptions?: ResponseOptions
): Mocks<T1, T2>;

32
node_modules/node-mocks-http/lib/http-mock.js generated vendored Normal file
View File

@@ -0,0 +1,32 @@
/**
* Module: http-mock
*
* The interface for this entire module that just exposes the exported
* functions from the other libraries.
*/
const request = require('./mockRequest');
const response = require('./mockResponse');
const express = require('./express/mock-express');
/**
* Creates linked req and res objects. Enables using methods that require both
* objects to interact, for example res.format.
*
* @param {Object} reqOpts Options for req creation, see
* @mockRequest.createRequest
* @param {Object} resOpts Options for res creation, see
* @mockResponse.createResponse
* @return {Object} Object with both mocks: { req, res }
*/
const createRequestResponse = function (reqOpts, resOpts) {
const req = request.createRequest(reqOpts);
const res = response.createResponse({ ...resOpts, req });
return { req, res };
};
exports.createRequest = request.createRequest;
exports.createResponse = response.createResponse;
exports.createMocks = createRequestResponse;
exports.express = express;

19
node_modules/node-mocks-http/lib/mockEventEmitter.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
/*
* http://nodejs.org/api/events.html
*/
function EventEmitter() {}
EventEmitter.prototype.addListener = () => {};
EventEmitter.prototype.on = () => {};
EventEmitter.prototype.once = () => {};
EventEmitter.prototype.removeListener = () => {};
EventEmitter.prototype.removeAllListeners = () => {};
// EventEmitter.prototype.removeAllListeners = function([event])
EventEmitter.prototype.setMaxListeners = () => {};
EventEmitter.prototype.listeners = () => {};
EventEmitter.prototype.emit = () => {};
EventEmitter.prototype.prependListener = () => {};
// EventEmitter.prototype.emit = function(event, [arg1], [arg2], [...]){}
module.exports = EventEmitter;

650
node_modules/node-mocks-http/lib/mockRequest.js generated vendored Normal file
View File

@@ -0,0 +1,650 @@
/**
* File: mockRequest
*
* This file implements node.js's implementation of a 'request' object.
* This is actually closer to what Express offers the user, in that the
* body is really a parsed object of values.
*
* @author Howard Abrams <howard.abrams@gmail.com>
*/
/**
* Function: createRequest
*
* Creates a new mock 'request' instance. All values are reset to the
* defaults.
*
* Parameters:
*
* options - An object of named parameters.
*
* Options:
*
* method - The method value, see <mockRequest._setMethod>
* url - The url value, see <mockRequest._setURL>
* originalUrl - The originalUrl value, see <mockRequest._setOriginalUrl>
* baseUrl - The baseUrl value, see <mockRequest._setBaseUrl>
* params - The parameters, see <mockRequest._setParam>
* body - The body values, , see <mockRequest._setBody>
*/
const url = require('url');
const typeis = require('type-is');
const accepts = require('accepts');
const parseRange = require('range-parser');
let { EventEmitter } = require('events');
const querystring = require('querystring');
const { createHeaders, getHeaderValue } = require('./headers');
const standardRequestOptions = [
'method',
'url',
'originalUrl',
'baseUrl',
'path',
'params',
'session',
'cookies',
'headers',
'body',
'query',
'files'
];
function createRequest(options = {}) {
if (options.eventEmitter) {
EventEmitter = options.eventEmitter;
}
// create mockRequest
const mockRequest = Object.create(EventEmitter.prototype);
EventEmitter.call(mockRequest);
mockRequest.method = options.method ? options.method : 'GET';
mockRequest.url = options.url || options.path || '';
mockRequest.originalUrl = options.originalUrl || mockRequest.url;
mockRequest.baseUrl = options.baseUrl || mockRequest.url;
mockRequest.path = options.path || (options.url ? url.parse(options.url).pathname : '');
mockRequest.params = options.params ? options.params : {};
if (options.session) {
mockRequest.session = options.session;
}
mockRequest.cookies = options.cookies ? options.cookies : {};
if (options.signedCookies) {
mockRequest.signedCookies = options.signedCookies;
}
// Create headers using the Headers.js module
mockRequest.headers = createHeaders(options.headers);
mockRequest.body = options.body ? options.body : {};
mockRequest.query = options.query ? options.query : {};
mockRequest.files = options.files ? options.files : {};
mockRequest.socket = options.socket ? options.socket : {};
mockRequest.ip = options.ip || '127.0.0.1';
mockRequest.ips = [mockRequest.ip];
mockRequest.destroy = () => {};
// parse query string from url to object
if (Object.keys(mockRequest.query).length === 0) {
mockRequest.query = querystring.parse(mockRequest.url.split('?')[1]);
if (!mockRequest.query.hasOwnProperty) {
Object.defineProperty(mockRequest.query, 'hasOwnProperty', {
enumerable: false,
value: Object.hasOwnProperty.bind(mockRequest.query)
});
}
}
// attach any other provided objects into the request for more advanced testing
for (const n in options) {
if (standardRequestOptions.indexOf(n) === -1) {
mockRequest[n] = options[n];
}
}
/**
* Return request header.
*
* The `Referrer` header field is special-cased,
* both `Referrer` and `Referer` are interchangeable.
*
* Examples:
*
* mockRequest.get('Content-Type');
* // => "text/plain"
*
* mockRequest.get('content-type');
* // => "text/plain"
*
* mockRequest.get('Something');
* // => undefined
*
* Aliased as `mockRequest.header()`.
*
* @param {String} name
* @return {String}
* @api public
*/
mockRequest.getHeader = function getHeader(name) {
return getHeaderValue(mockRequest.headers, name);
};
mockRequest.header = mockRequest.getHeader;
mockRequest.get = mockRequest.getHeader;
/**
* Function: is
*
* Checks for matching content types in the content-type header.
* Requires a request body, identified by transfer-encoding or content-length headers
*
* Examples:
*
* mockRequest.headers['content-type'] = 'text/html';
* mockRequest.headers['transfer-encoding'] = 'chunked';
* mockRequest.headers['content-length'] = '100';
*
* mockRequest.is('html');
* // => "html"
*
* mockRequest.is('json');
* // => false
*
* mockRequest.is(['json', 'html', 'text']);
* // => "html"
*
* @param {String|String[]} types content type or array of types to match
* @return {String|false|null} Matching content type as string, false if no match, null if request has no body.
* @api public
*/
mockRequest.is = function isContentType(...args) {
let types = args;
if (Array.isArray(args[0])) {
types = args[0];
}
return typeis(mockRequest, types);
};
/**
* Function: accepts
*
* Checks for matching content types in the Accept header.
*
* Examples:
*
* mockRequest.headers['accept'] = 'application/json'
*
* mockRequest.accepts('json');
* // => 'json'
*
* mockRequest.accepts('html');
* // => false
*
* mockRequest.accepts(['html', 'json']);
* // => 'json'
*
* @param {String|String[]} types Mime type(s) to check against
* @return {String|false} Matching type or false if no match.
*/
mockRequest.accepts = function acceptsTypes(types) {
const Accepts = accepts(mockRequest);
return Accepts.type(types);
};
/**
* Check if the given `encoding`s are accepted.
*
* @param {String} ...encoding
* @return {String|Array}
* @public
*/
mockRequest.acceptsEncodings = function acceptsEncodings(...args) {
let encodings = args;
if (Array.isArray(args[0])) {
encodings = args[0];
}
const accept = accepts(mockRequest);
return accept.encodings(encodings);
};
/**
* Check if the given `charset`s are acceptable,
* otherwise you should respond with 406 "Not Acceptable".
*
* @param {String} ...charset
* @return {String|Array}
* @public
*/
mockRequest.acceptsCharsets = function acceptsCharsets(...args) {
let charsets = args;
if (Array.isArray(args[0])) {
charsets = args[0];
}
const accept = accepts(mockRequest);
return accept.charsets(charsets);
};
/**
* Check if the given `lang`s are acceptable,
* otherwise you should respond with 406 "Not Acceptable".
*
* @param {String} ...lang
* @return {String|Array}
* @public
*/
mockRequest.acceptsLanguages = function acceptsLanguages(...args) {
let languages = args;
if (Array.isArray(args[0])) {
languages = args[0];
}
const accept = accepts(mockRequest);
return accept.languages(languages);
};
/**
* Function: range
*
* Parse Range header field, capping to the given `size`.
*
* Unspecified ranges such as "0-" require knowledge of your resource length. In
* the case of a byte range this is of course the total number of bytes. If the
* Range header field is not given `undefined` is returned, `-1` when unsatisfiable,
* and `-2` when syntactically invalid.
*
* When ranges are returned, the array has a "type" property which is the type of
* range that is required (most commonly, "bytes"). Each array element is an object
* with a "start" and "end" property for the portion of the range.
*
* The "combine" option can be set to `true` and overlapping & adjacent ranges
* will be combined into a single range.
*
* NOTE: remember that ranges are inclusive, so for example "Range: users=0-3"
* should respond with 4 users when available, not 3.
*
* @param {number} size
* @param {object} [opts]
* @param {boolean} [opts.combine=false]
* @return {false|number|array}
* @public
*/
mockRequest.range = function isRange(size, opts) {
const range = mockRequest.get('Range');
if (!range) {
return undefined;
}
return parseRange(size, range, opts);
};
/**
* Function: param
*
* Return the value of param name when present.
* Lookup is performed in the following order:
* - req.params
* - req.body
* - req.query
*/
mockRequest.param = function param(parameterName, defaultValue) {
if ({}.hasOwnProperty.call(mockRequest.params, parameterName)) {
return mockRequest.params[parameterName];
}
if ({}.hasOwnProperty.call(mockRequest.body, parameterName)) {
return mockRequest.body[parameterName];
}
if ({}.hasOwnProperty.call(mockRequest.query, parameterName)) {
return mockRequest.query[parameterName];
}
return defaultValue;
};
/**
* Function: _setParameter
*
* Set parameters that the client can then get using the 'params'
* key.
*
* Parameters:
*
* key - The key. For instance, 'bob' would be accessed: request.params.bob
* value - The value to return when accessed.
*/
mockRequest._setParameter = function _setParameter(key, value) {
mockRequest.params[key] = value;
};
/**
* Sets a variable that is stored in the session.
*
* @param variable The variable to store in the session
* @param value The value associated with the variable
*/
mockRequest._setSessionVariable = function _setSessionVariable(variable, value) {
if (typeof mockRequest.session !== 'object') {
mockRequest.session = {};
}
mockRequest.session[variable] = value;
};
/**
* Sets a variable that is stored in the cookies.
*
* @param variable The variable to store in the cookies
* @param value The value associated with the variable
*/
mockRequest._setCookiesVariable = function _setCookiesVariable(variable, value) {
mockRequest.cookies[variable] = value;
};
/**
* Sets a variable that is stored in the signed cookies.
*
* @param variable The variable to store in the signed cookies
* @param value The value associated with the variable
*/
mockRequest._setSignedCookiesVariable = function _setSignedCookiesVariable(variable, value) {
if (typeof mockRequest.signedCookies !== 'object') {
mockRequest.signedCookies = {};
}
mockRequest.signedCookies[variable] = value;
};
/**
* Sets a variable that is stored in the headers.
*
* @param variable The variable to store in the headers
* @param value The value associated with the variable
*/
mockRequest._setHeadersVariable = function _setHeadersVariable(variable, value) {
mockRequest.headers[variable] = value;
};
/**
* Sets a variable that is stored in the files.
*
* @param variable The variable to store in the files
* @param value The value associated with the variable
*/
mockRequest._setFilesVariable = function _setFilesVariable(variable, value) {
mockRequest.files[variable] = value;
};
/**
* Function: _setMethod
*
* Sets the HTTP method that the client gets when the called the 'method'
* property. This defaults to 'GET' if it is not set.
*
* Parameters:
*
* method - The HTTP method, e.g. GET, POST, PUT, DELETE, etc.
*
* Note: We don't validate the string. We just return it.
*/
mockRequest._setMethod = function _setMethod(method) {
mockRequest.method = method;
};
/**
* Function: _setURL
*
* Sets the URL value that the client gets when the called the 'url'
* property.
*
* Parameters:
*
* value - The request path, e.g. /my-route/452
*
* Note: We don't validate the string. We just return it. Typically, these
* do not include hostname, port or that part of the URL.
*/
mockRequest._setURL = function _setURL(value) {
mockRequest.url = value;
};
/**
* Function: _setBaseUrl
*
* Sets the URL value that the client gets when the called the 'baseUrl'
* property.
*
* Parameters:
*
* value - The request base path, e.g. /my-route
*
* Note: We don't validate the string. We just return it. Typically, these
* do not include hostname, port or that part of the URL.
*/
mockRequest._setBaseUrl = function _setBaseUrl(value) {
mockRequest.baseUrl = value;
};
/**
* Function: _setOriginalUrl
*
* Sets the URL value that the client gets when the called the 'originalUrl'
* property.
*
* Parameters:
*
* value - The request path, e.g. /my-route/452
*
* Note: We don't validate the string. We just return it. Typically, these
* do not include hostname, port or that part of the URL.
*/
mockRequest._setOriginalUrl = function _setOriginalUrl(value) {
mockRequest.originalUrl = value;
};
/**
* Function: _setBody
*
* Sets the body that the client gets when the called the 'body'
* parameter. This defaults to 'GET' if it is not set.
*
* Parameters:
*
* body - An object representing the body.
*
* If you expect the 'body' to come from a form, this typically means that
* it would be a flat object of properties and values, as in:
*
* > { name: 'Howard Abrams',
* > age: 522
* > }
*
* If the client is expecting a JSON object through a REST interface, then
* this object could be anything.
*/
mockRequest._setBody = function _setBody(body) {
mockRequest.body = body;
};
/**
* Function: _addBody
*
* Adds another body parameter the client gets when calling the 'body'
* parameter with another property value, e.g. the name of a form element
* that was passed in.
*
* Parameters:
*
* key - The key. For instance, 'bob' would be accessed: request.params.bob
* value - The value to return when accessed.
*/
mockRequest._addBody = function _addBody(key, value) {
mockRequest.body[key] = value;
};
/**
* Function: send
*
* Write data to the request stream which will trigger request's 'data', and 'end' event
*
* Parameters:
*
* data - string, array, object, number, buffer
*/
mockRequest.send = function send(data) {
if (Buffer.isBuffer(data)) {
this.emit('data', data);
} else if (typeof data === 'object' || typeof data === 'number') {
this.emit('data', Buffer.from(JSON.stringify(data)));
} else if (typeof data === 'string') {
this.emit('data', Buffer.from(data));
}
this.emit('end');
};
/**
* Function: hostname
*
* If Hostname is not set explicitly, then derive it from the Host header without port information
*
*/
if (!mockRequest.hostname) {
mockRequest.hostname = (function getHostname() {
if (!mockRequest.headers.host) {
return '';
}
const hostname = mockRequest.headers.host.split(':')[0].split('.');
return hostname.join('.');
})();
}
/**
* Function: subdomains
*
* Subdomains are the dot-separated parts of the host before the main domain of the app.
*
*/
mockRequest.subdomains = (function getSubdomains() {
if (!mockRequest.headers.host) {
return [];
}
const offset = 2;
const subdomains = mockRequest.headers.host.split('.').reverse();
return subdomains.slice(offset);
})();
/**
* Function: asyncIterator
*
* Buffers data, error, end, and close events and yields them in order.
* Unlike stream.Readable, this async iterator implementation will not exit
* early on error or close.
*/
mockRequest[Symbol.asyncIterator] = async function* asyncIterator() {
let ended = false;
let closed = false;
let error = null;
const chunks = [];
let resolvePromise = null;
const promiseExecutor = (resolve) => {
resolvePromise = resolve;
};
const promiseResolver = () => {
if (resolvePromise) {
resolvePromise();
resolvePromise = null;
}
};
const dataEventHandler = (chunk) => {
if (ended || closed || error) {
return;
}
chunks.push(chunk);
promiseResolver();
};
const endEventHandler = () => {
if (ended || closed || error) {
return;
}
ended = true;
promiseResolver();
};
const closeEventHandler = () => {
if (closed || error) {
return;
}
closed = true;
promiseResolver();
};
const errorEventHandler = (err) => {
if (closed || error) {
return;
}
error = err;
promiseResolver();
};
mockRequest.on('data', dataEventHandler);
mockRequest.on('end', endEventHandler);
mockRequest.on('close', closeEventHandler);
mockRequest.on('error', errorEventHandler);
// Emit custom event after entering the loop.
setTimeout(() => {
this.emit('async_iterator');
});
try {
for (;;) {
// eslint-disable-next-line no-await-in-loop
await new Promise(promiseExecutor);
let i = 0;
for (;;) {
if (error) {
throw error;
}
if (closed) {
return;
}
const hasChunks = i < chunks.length;
if (!hasChunks) {
if (ended) {
// End signaled. Bail.
return;
}
// Wait for next push.
break;
}
const chunk = chunks[i];
chunks[i] = undefined;
i += 1;
yield chunk;
}
chunks.length = 0;
}
} finally {
chunks.length = 0;
error = null;
mockRequest.off('data', dataEventHandler);
mockRequest.off('end', endEventHandler);
mockRequest.off('close', closeEventHandler);
mockRequest.off('error', errorEventHandler);
}
};
return mockRequest;
}
module.exports.createRequest = createRequest;

959
node_modules/node-mocks-http/lib/mockResponse.js generated vendored Normal file
View File

@@ -0,0 +1,959 @@
/**
* File: mockResponse
*
* This file implements node.js's implementation of a 'response' object.
* Like all good mocks, the response file that can be called and used in
* place of a real HTTP response object.
*
* @author Howard Abrams <howard.abrams@gmail.com>
*/
/**
* Function: createResponse
*
* Creates a new mock 'response' instance. All values are reset to the
* defaults.
*
* Parameters:
*
* options - An object of named parameters.
*
* Options:
*
* encoding - The default encoding for the response
*/
const mime = require('mime');
const path = require('path');
const contentDisposition = require('content-disposition');
let WritableStream = require('./mockWritableStream');
let EventEmitter = require('./mockEventEmitter');
const http = require('./node/http');
const utils = require('./utils');
const TypedArray = Object.getPrototypeOf(Uint8Array);
function createResponse(options = {}) {
let _endCalled = false;
let _data = '';
let _buffer = Buffer.alloc(0);
const _chunks = [];
let _size = 0;
let _encoding = options.encoding;
let _redirectUrl = '';
let _renderView = '';
let _renderData = {};
if (options.writableStream) {
WritableStream = options.writableStream;
}
if (options.eventEmitter) {
EventEmitter = options.eventEmitter;
}
const writableStream = new WritableStream();
const mockRequest = options.req;
// create mockResponse
const mockResponse = Object.create(EventEmitter.prototype);
EventEmitter.call(mockResponse);
mockResponse._headers = {};
mockResponse.cookies = {};
mockResponse.finished = false;
mockResponse.writableEnded = false;
mockResponse.writableFinished = false;
mockResponse.headersSent = false;
mockResponse.statusCode = 200;
mockResponse.statusMessage = 'OK';
// http://expressjs.com/en/api.html#res.locals
mockResponse.locals = options.locals || {};
mockResponse.cookie = function cookie(name, value, opt) {
mockResponse.cookies[name] = {
value,
options: opt
};
return this;
};
mockResponse.clearCookie = function clearCookie(name, opt) {
const opts = opt || {};
opts.expires = new Date(1);
opts.path = '/';
return this.cookie(name, '', opts);
};
mockResponse.status = function status(code) {
mockResponse.statusCode = code;
return this;
};
/**
* Function: writeHead
*
* The 'writeHead' function from node's HTTP API.
*
* Parameters:
*
* statusCode - A number to send as a the HTTP status
* headers - An object of properties that will be used for
* the HTTP headers.
*/
mockResponse.writeHead = function writeHead(statusCode, statusMessage, headers) {
if (_endCalled) {
throw new Error('The end() method has already been called.');
}
if (mockResponse.headersSent) {
// Node docs: "This method must only be called once on a message"
// but it doesn't error if you do call it after first chunk of body is sent
// so we shouldn't throw here either (although it's a bug in the code).
// We return without updating since in real life it's just possible the double call didn't
// completely corrupt the response (for example not using chunked encoding due to HTTP/1.0 client)
// and in this case the client will see the _original_ headers.
return this;
}
mockResponse.statusCode = statusCode;
// resolve statusMessage and headers as optional
if (Object.prototype.toString.call(statusMessage) === '[object Object]') {
// eslint-disable-next-line no-param-reassign
headers = statusMessage;
// eslint-disable-next-line no-param-reassign
statusMessage = null;
}
if (statusMessage) {
mockResponse.statusMessage = statusMessage;
}
// The headers specified earlier (been set with `mockResponse.setHeader`)
// should not be overwritten but be merged with the headers
// passed into `mockResponse.writeHead`.
if (headers) {
Object.assign(mockResponse._headers, utils.convertKeysToLowerCase(headers));
}
this.headersSent = true;
return this;
};
/**
* The 'send' function from restify's Response API that returns data
* to the client. Can be called multiple times.
*
* @see http://mcavage.me/node-restify/#response-api
*
* @param data The data to return. Must be a string.
*/
mockResponse.send = function send(a, b, c) {
const _formatData = (data) => {
if (typeof data === 'object') {
if (data.statusCode) {
mockResponse.statusCode = data.statusCode;
} else if (data.httpCode) {
mockResponse.statusCode = data.httpCode;
}
if (data.body) {
_data = data.body;
} else {
_data = data;
}
} else {
_data += data ?? '';
}
};
switch (arguments.length) {
case 1:
if (typeof a === 'number') {
mockResponse.statusCode = a;
} else {
_formatData(a);
}
break;
case 2:
if (typeof a === 'number') {
_formatData(b);
mockResponse.statusCode = a;
} else if (typeof b === 'number') {
_formatData(a);
mockResponse.statusCode = b;
console.warn('WARNING: Called send() with deprecated parameter order');
} else {
_formatData(a);
_encoding = b;
}
break;
case 3:
_formatData(a);
mockResponse._headers = utils.convertKeysToLowerCase(b);
mockResponse.statusCode = c;
console.warn('WARNING: Called send() with deprecated three parameters');
break;
default:
break;
}
mockResponse.headersSent = true;
mockResponse.emit('send');
mockResponse.end();
return mockResponse;
};
/**
* Send given HTTP status code.
*
* Sets the response status to `statusCode` and the body of the
* response to the standard description from node's http.STATUS_CODES
* or the statusCode number if no description.
*
* Examples:
*
* mockResponse.sendStatus(200);
*
* @param {number} statusCode
* @api public
*/
mockResponse.sendStatus = function sendStatus(statusCode) {
const body = http.STATUS_CODES[statusCode] || String(statusCode);
mockResponse.statusCode = statusCode;
mockResponse.type('txt');
return mockResponse.send(body);
};
/**
* Function: json
*
* The 'json' function from node's HTTP API that returns JSON
* data to the client.
*
* Parameters:
*
* a - Either a statusCode or string containing JSON payload
* b - Either a statusCode or string containing JSON payload
*
* If not specified, the statusCode defaults to 200.
* Second parameter is optional.
*/
mockResponse.json = function json(a, b) {
mockResponse.setHeader('Content-Type', 'application/json');
if (typeof a !== 'undefined') {
if (typeof a === 'number' && typeof b !== 'undefined') {
mockResponse.statusCode = a;
mockResponse.write(JSON.stringify(b), 'utf8');
} else if (typeof b !== 'undefined' && typeof b === 'number') {
mockResponse.statusCode = b;
mockResponse.write(JSON.stringify(a), 'utf8');
} else {
mockResponse.write(JSON.stringify(a), 'utf8');
}
}
mockResponse.emit('send');
mockResponse.end();
return mockResponse;
};
/**
* Function: jsonp
*
* The 'jsonp' function from node's HTTP API that returns JSON
* data to the client.
*
* Parameters:
*
* a - Either a statusCode or string containing JSON payload
* b - Either a statusCode or string containing JSON payload
*
* If not specified, the statusCode defaults to 200.
* Second parameter is optional.
*/
mockResponse.jsonp = function jsonp(a, b) {
mockResponse.setHeader('Content-Type', 'text/javascript');
if (typeof a !== 'undefined') {
if (typeof a === 'number' && typeof b !== 'undefined') {
mockResponse.statusCode = a;
_data += JSON.stringify(b);
} else if (typeof b !== 'undefined' && typeof b === 'number') {
mockResponse.statusCode = b;
_data += JSON.stringify(a);
} else {
_data += JSON.stringify(a);
}
}
mockResponse.emit('send');
mockResponse.end();
return mockResponse;
};
/**
* Set "Content-Type" response header with `type` through `mime.lookup()`
* when it does not contain "/", or set the Content-Type to `type` otherwise.
*
* Examples:
*
* res.type('.html');
* res.type('html');
* res.type('json');
* res.type('application/json');
* res.type('png');
*
* @param {String} type
* @return {ServerResponse} for chaining
* @api public
*/
mockResponse.contentType = function contentType(type) {
return mockResponse.set('Content-Type', type.indexOf('/') >= 0 ? type : mime.lookup(type));
};
mockResponse.type = mockResponse.contentType;
/**
* Set 'Location' response header.
*
* @see http://expressjs.com/en/api.html#res.location
*
* @param {String} location The location to set in the header.
* @return {ServerResponse} For chaining
*/
mockResponse.location = function setLocation(location) {
return mockResponse.set('Location', location);
};
/**
* Function: write
*
* This function has the same behavior as the 'send' function.
*
* Parameters:
*
* data - The data to return. Must be a string. Appended to
* previous calls to data.
* encoding - Optional encoding value.
*/
mockResponse.write = function write(data, encoding) {
mockResponse.headersSent = true;
if (data instanceof Buffer) {
_chunks.push(data);
_size += data.length;
} else if (data instanceof TypedArray) {
_data += new TextDecoder(encoding).decode(data);
} else {
_data += data;
}
if (encoding) {
_encoding = encoding;
}
};
/**
* Function: getEndArguments
*
* Utility function that parses and names parameters for the various
* mockResponse.end() signatures. Reference:
* https://nodejs.org/api/http.html#http_response_end_data_encoding_callback
*
*/
function getEndArguments(args) {
let data;
let encoding;
let callback;
if (args[0]) {
if (typeof args[0] === 'function') {
callback = args[0];
} else {
data = args[0];
}
}
if (args[1]) {
const type = typeof args[1];
if (type === 'function') {
callback = args[1];
} else if (type === 'string' || args[1] instanceof String) {
encoding = args[1];
}
}
if (args[2] && typeof args[2] === 'function') {
callback = args[2];
}
return { data, encoding, callback };
}
/**
* Function: end
*
* The 'end' function from node's HTTP API that finishes
* the connection request. This must be called.
*
* Signature: response.end([data[, encoding]][, callback])
*
* Parameters:
*
* data - Optional data to return. Must be a string or Buffer instance.
* Appended to previous calls to <send>.
* encoding - Optional encoding value.
* callback - Optional callback function, called once the logic has run
*
*/
mockResponse.end = function end(...endArgs) {
if (_endCalled) {
// Do not emit this event twice.
return;
}
mockResponse.finished = true;
mockResponse.writableEnded = true;
mockResponse.headersSent = true;
_endCalled = true;
const args = getEndArguments(endArgs);
if (args.data) {
if (args.data instanceof Buffer) {
_chunks.push(args.data);
_size += args.data.length;
} else if (args.data instanceof TypedArray) {
_data += new TextDecoder(args.encoding).decode(args.data);
} else {
_data += args.data;
}
}
if (_chunks.length) {
switch (_chunks.length) {
case 1:
_buffer = _chunks[0];
break;
default:
_buffer = Buffer.alloc(_size);
for (let i = 0, pos = 0, l = _chunks.length; i < l; i++) {
const chunk = _chunks[i];
chunk.copy(_buffer, pos);
pos += chunk.length;
}
break;
}
}
if (args.encoding) {
_encoding = args.encoding;
}
mockResponse.emit('end');
mockResponse.writableFinished = true; // Reference: https://nodejs.org/docs/latest-v12.x/api/http.html#http_request_writablefinished
mockResponse.emit('finish');
if (args.callback) {
args.callback();
}
};
/**
* Function: vary
*
* Adds the field/s to the Vary response header
*
* Examples:
*
* res.vary('A-B-Test');
* res.vary(['A-B-Test', 'Known-User']);
*/
mockResponse.vary = function vary(fields) {
const header = mockResponse.getHeader('Vary') || '';
let values = header.length ? header.split(', ') : [];
const uniqueFields = (Array.isArray(fields) ? fields : [fields]).filter((field) => {
const regex = new RegExp(field, 'i');
const matches = values.filter((value) => value.match(regex));
return !matches.length;
});
values = values.concat(uniqueFields);
return mockResponse.setHeader('Vary', values.join(', '));
};
/**
* Set _Content-Disposition_ header to _attachment_ with optional `filename`.
*
* Example:
*
* res.attachment('download.csv')
*
* @param {String} filename
* @return {ServerResponse}
* @api public
*/
mockResponse.attachment = function attachment(filename) {
if (filename) {
mockResponse.type(path.extname(filename));
}
mockResponse.set('Content-Disposition', contentDisposition(filename));
return this;
};
/**
* Append additional header `field` with value `val`.
*
* Example:
*
* res.append('Link', ['<http://localhost/>', '<http://localhost:3000/>']);
* res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly');
* res.append('Warning', '199 Miscellaneous warning');
*
* @param {String} field
* @param {String|Array} val
* @return {ServerResponse} for chaining
* @api public
*/
mockResponse.append = function append(field, val) {
const prev = mockResponse.get(field);
let value = val;
if (prev) {
// concat the new and prev vals
value = Array.isArray(prev) ? prev.concat(val) : [prev].concat(val);
}
return mockResponse.set(field, value);
};
/**
* Set header `field` to `val`, or pass
* an object of header fields.
*
* Examples:
*
* res.set('Foo', ['bar', 'baz']);
* res.set('Accept', 'application/json');
* res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
*
* Aliased as `mockResponse.header()`.
*
* @param {String|Object|Array} field
* @param {String} val
* @return {ServerResponse} for chaining
* @api public
*/
mockResponse.header = function header(field, val) {
if (arguments.length === 2) {
let value;
if (Array.isArray(val)) {
value = val.map(String);
} else {
value = String(val);
}
mockResponse.setHeader(field, value);
} else if (typeof field === 'string') {
return mockResponse.getHeader(field);
} else {
for (const key in field) {
if ({}.hasOwnProperty.call(field, key)) {
mockResponse.setHeader(key, field[key]);
}
}
}
return mockResponse;
};
mockResponse.set = mockResponse.header;
/**
* Function: getHeaders
*
* Returns a shallow copy of the current outgoing headers.
*/
mockResponse.getHeaders = function getHeaders() {
return JSON.parse(JSON.stringify(mockResponse._headers));
};
/**
* Function: getHeader
* Function: get
*
* Returns a particular header by name.
*/
mockResponse.getHeader = function getHeader(name) {
return mockResponse._headers[name.toLowerCase()];
};
mockResponse.get = mockResponse.getHeader;
/**
* Function: getHeaderNames
*
* Returns an array containing the unique names of the current outgoing headers.
*/
mockResponse.getHeaderNames = function getHeaderNames() {
return Object.keys(mockResponse._headers); // names are already stored in lowercase
};
/**
* Function: hasHeader
*
* Returns `true` if the header identified by `name` is currently set.
*/
mockResponse.hasHeader = function hasHeader(name) {
return name.toLowerCase() in mockResponse._headers;
};
/**
* Function: setHeader
* Function: set
*
* Set a particular header by name.
*/
mockResponse.setHeader = function setHeader(name, value) {
mockResponse._headers[name.toLowerCase()] = value;
return this;
};
/**
* Function: appendHeader
*
* Append a header by name. If a header already exists, the new value is appended to the existing header.
*/
mockResponse.appendHeader = function appendHeader(name, value) {
mockResponse.append(name, value);
return this;
};
/**
* Function: removeHeader
*
* Removes an HTTP header by name.
*/
mockResponse.removeHeader = function removeHeader(name) {
delete mockResponse._headers[name.toLowerCase()];
};
/**
* Function: setEncoding
*
* Sets the encoding for the data. Generally 'utf8'.
*
* Parameters:
*
* encoding - The string representing the encoding value.
*/
mockResponse.setEncoding = function setEncoding(encoding) {
_encoding = encoding;
};
mockResponse.getEncoding = function getEncoding() {
return _encoding;
};
/**
* Function: redirect
*
* Redirect to a url with response code
*/
mockResponse.redirect = function redirect(a, b) {
switch (arguments.length) {
case 1:
mockResponse.statusCode = 302;
_redirectUrl = a;
break;
case 2:
if (typeof a === 'number') {
mockResponse.statusCode = a;
_redirectUrl = b;
}
break;
default:
break;
}
mockResponse.end();
};
/**
* Function: render
*
* Render a view with a callback responding with the
* rendered string.
*/
mockResponse.render = function render(a, b, c) {
_renderView = a;
let data = b;
let done = c;
// support callback function as second arg
if (typeof b === 'function') {
done = b;
data = {};
}
switch (arguments.length) {
case 2:
case 3:
_renderData = data;
break;
default:
break;
}
if (typeof done === 'function') {
done(null, '');
} else {
mockResponse.emit('render');
mockResponse.end();
}
};
/**
* Chooses the correct response function from the given supported types.
* This method requires that the mockResponse object be initialized with a
* mockRequest object reference, otherwise it will throw. @see createMocks.
*
* @param {Object} supported Object with formats to handler functions.
* @return {Object} Whatever handler function returns.
*/
mockResponse.format = function format(supported = {}) {
const types = Object.keys(supported);
if (types.length === 0) {
return mockResponse.sendStatus(406);
}
if (!mockRequest) {
throw new Error(
'Request object unavailable. Use createMocks or pass in a request object in createResponse to use format.'
);
}
const accepted = mockRequest.accepts(types);
if (accepted) {
return supported[accepted]();
}
if (supported.default) {
return supported.default();
}
return mockResponse.sendStatus(406);
};
// WritableStream.writable is not a function
// mockResponse.writable = function() {
// return writableStream.writable.apply(this, arguments);
// };
// mockResponse.end = function(){
// return writableStream.end.apply(this, arguments);
// };
mockResponse.destroy = function destroy(...args) {
return writableStream.destroy.apply(this, args);
};
mockResponse.destroySoon = function destroySoon(...args) {
return writableStream.destroySoon.apply(this, args);
};
// This mock object stores some state as well
// as some test-analysis functions:
/**
* Function: _isEndCalled
*
* Since the <end> function must be called, this function
* returns true if it has been called. False otherwise.
*/
mockResponse._isEndCalled = function _isEndCalled() {
return _endCalled;
};
/**
* Function: _getHeaders
*
* Returns all the headers that were set. This may be an
* empty object, but probably will have "Content-Type" set.
*/
mockResponse._getHeaders = function _getHeaders() {
return mockResponse._headers;
};
/**
* Function: _getLocals
*
* Returns all the locals that were set.
*/
mockResponse._getLocals = function _getLocals() {
return mockResponse.locals;
};
/**
* Function: _getData
*
* The data sent to the user.
*/
mockResponse._getData = function _getData() {
return _data;
};
/**
* Function: _getJSONData
*
* The data sent to the user as JSON.
*/
mockResponse._getJSONData = function _getJSONData() {
return JSON.parse(_data);
};
/**
* Function: _getBuffer
*
* The buffer containing data to be sent to the user.
* Non-empty if Buffers were given in calls to write() and end()
*/
mockResponse._getBuffer = function _getBuffer() {
return _buffer;
};
/**
* Function: _getChunks
*
* The buffer containing data to be sent to the user.
* Non-empty if Buffers were given in calls to write() and end()
*/
mockResponse._getChunks = function _getChunks() {
return _chunks;
};
/**
* Function: _getStatusCode
*
* The status code that was sent to the user.
*/
mockResponse._getStatusCode = function _getStatusCode() {
return mockResponse.statusCode;
};
/**
* Function: _getStatusMessage
*
* The status message that was sent to the user.
*/
mockResponse._getStatusMessage = function _getStatusMessage() {
return mockResponse.statusMessage;
};
/**
* Function: _isJSON
*
* Returns true if the data sent was defined as JSON.
* It doesn't validate the data that was sent.
*/
mockResponse._isJSON = function _isJSON() {
return mockResponse.getHeader('Content-Type') === 'application/json';
};
/**
* Function: _isUTF8
*
* If the encoding was set, and it was set to UTF-8, then
* this function return true. False otherwise.
*
* Returns:
*
* False if the encoding wasn't set and wasn't set to "utf8".
*/
mockResponse._isUTF8 = function _isUTF8() {
if (!_encoding) {
return false;
}
return _encoding === 'utf8';
};
/**
* Function: _isDataLengthValid
*
* If the Content-Length header was set, this will only
* return true if the length is actually the length of the
* data that was set.
*
* Returns:
*
* True if the "Content-Length" header was not
* set. Otherwise, it compares it.
*/
mockResponse._isDataLengthValid = function _isDataLengthValid() {
if (mockResponse.getHeader('Content-Length')) {
return mockResponse.getHeader('Content-Length').toString() === _data.length.toString();
}
return true;
};
/**
* Function: _getRedirectUrl
*
* Return redirect url of redirect method
*
* Returns:
*
* Redirect url
*/
mockResponse._getRedirectUrl = function _getRedirectUrl() {
return _redirectUrl;
};
/**
* Function: _getRenderView
*
* Return render view of render method
*
* Returns:
*
* render view
*/
mockResponse._getRenderView = function _getRenderView() {
return _renderView;
};
/**
* Function: _getRenderData
*
* Return render data of render method
*
* Returns:
*
* render data
*/
mockResponse._getRenderData = function _getRenderData() {
return _renderData;
};
return mockResponse;
}
module.exports.createResponse = createResponse;

23
node_modules/node-mocks-http/lib/mockWritableStream.js generated vendored Normal file
View File

@@ -0,0 +1,23 @@
/*
* http://nodejs.org/api/stream.html#stream_writable_stream
*/
function WritableStream() {}
Object.defineProperty(WritableStream, 'writable', {
configurable: true,
enumerable: true,
get() {
return true;
}
});
// WritableStream.prototype.write = function(string, [encoding], [fd]){}
// WritableStream.prototype.write = function(buffer){}
WritableStream.prototype.end = () => {};
// WritableStream.prototype.end = function(string, encoding){}
// WritableStream.prototype.end = function(buffer){}
WritableStream.prototype.destroy = () => {};
WritableStream.prototype.destroySoon = () => {};
module.exports = WritableStream;

121
node_modules/node-mocks-http/lib/node/_http_incoming.js generated vendored Normal file
View File

@@ -0,0 +1,121 @@
const util = require('util');
const Stream = require('stream');
function readStart() {}
exports.readStart = readStart;
function readStop() {}
exports.readStop = readStop;
function IncomingMessage() {
Stream.Readable.call(this);
this.httpVersionMajor = null;
this.httpVersionMinor = null;
this.httpVersion = null;
this.complete = false;
this.headers = {};
this.rawHeaders = [];
this.trailers = {};
this.rawTrailers = [];
this.readable = true;
this._pendings = [];
this._pendingIndex = 0;
this.upgrade = null;
this.url = '';
this.method = null;
this.statusCode = null;
this.statusMessage = null;
this._consuming = false;
this._dumped = false;
}
util.inherits(IncomingMessage, Stream.Readable);
exports.IncomingMessage = IncomingMessage;
IncomingMessage.prototype.read = () => {};
IncomingMessage.prototype._read = () => {};
IncomingMessage.prototype.destroy = () => {};
IncomingMessage.prototype.setTimeout = function setTimeout(msecs, callback) {
if (callback) {
setTimeout(callback, msecs);
}
};
IncomingMessage.prototype._addHeaderLines = function _addHeaderLines(headers, n) {
if (headers && headers.length) {
let raw;
let dest;
if (this.complete) {
raw = this.rawTrailers;
dest = this.trailers;
} else {
raw = this.rawHeaders;
dest = this.headers;
}
for (let i = 0; i < n; i += 2) {
const k = headers[i];
const v = headers[i + 1];
raw.push(k);
raw.push(v);
this._addHeaderLine(k, v, dest);
}
}
};
IncomingMessage.prototype._addHeaderLine = function _addHeaderLine(field, value, dest) {
const fieldName = field.toLowerCase();
switch (fieldName) {
// Array headers:
case 'set-cookie':
if (!util.isUndefined(dest[fieldName])) {
// eslint-disable-next-line no-param-reassign
dest[fieldName].push(value);
} else {
// eslint-disable-next-line no-param-reassign
dest[fieldName] = [value];
}
break;
case 'content-type':
case 'content-length':
case 'user-agent':
case 'referer':
case 'host':
case 'authorization':
case 'proxy-authorization':
case 'if-modified-since':
case 'if-unmodified-since':
case 'from':
case 'location':
case 'max-forwards':
if (util.isUndefined(dest[fieldName])) {
// eslint-disable-next-line no-param-reassign
dest[fieldName] = value;
}
break;
default:
if (!util.isUndefined(dest[fieldName])) {
// eslint-disable-next-line no-param-reassign
dest[fieldName] += `, ${value}`;
} else {
// eslint-disable-next-line no-param-reassign
dest[fieldName] = value;
}
}
};
IncomingMessage.prototype._dump = function _dump() {
if (!this._dumped) {
this._dumped = true;
}
};

59
node_modules/node-mocks-http/lib/node/_http_server.js generated vendored Normal file
View File

@@ -0,0 +1,59 @@
exports.STATUS_CODES = {
100: 'Continue',
101: 'Switching Protocols',
102: 'Processing',
200: 'OK',
201: 'Created',
202: 'Accepted',
203: 'Non-Authoritative Information',
204: 'No Content',
205: 'Reset Content',
206: 'Partial Content',
207: 'Multi-Status',
300: 'Multiple Choices',
301: 'Moved Permanently',
302: 'Moved Temporarily',
303: 'See Other',
304: 'Not Modified',
305: 'Use Proxy',
307: 'Temporary Redirect',
308: 'Permanent Redirect',
400: 'Bad Request',
401: 'Unauthorized',
402: 'Payment Required',
403: 'Forbidden',
404: 'Not Found',
405: 'Method Not Allowed',
406: 'Not Acceptable',
407: 'Proxy Authentication Required',
408: 'Request Time-out',
409: 'Conflict',
410: 'Gone',
411: 'Length Required',
412: 'Precondition Failed',
413: 'Request Entity Too Large',
414: 'Request-URI Too Large',
415: 'Unsupported Media Type',
416: 'Requested Range Not Satisfiable',
417: 'Expectation Failed',
418: "I'm a teapot",
422: 'Unprocessable Entity',
423: 'Locked',
424: 'Failed Dependency',
425: 'Unordered Collection',
426: 'Upgrade Required',
428: 'Precondition Required',
429: 'Too Many Requests',
431: 'Request Header Fields Too Large',
500: 'Internal Server Error',
501: 'Not Implemented',
502: 'Bad Gateway',
503: 'Service Unavailable',
504: 'Gateway Time-out',
505: 'HTTP Version Not Supported',
506: 'Variant Also Negotiates',
507: 'Insufficient Storage',
509: 'Bandwidth Limit Exceeded',
510: 'Not Extended',
511: 'Network Authentication Required'
};

5
node_modules/node-mocks-http/lib/node/http.js generated vendored Normal file
View File

@@ -0,0 +1,5 @@
const server = require('./_http_server');
exports.IncomingMessage = require('./_http_incoming').IncomingMessage;
exports.STATUS_CODES = server.STATUS_CODES;

9
node_modules/node-mocks-http/lib/utils.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
module.exports.convertKeysToLowerCase = (map) => {
const newMap = {};
for (const key in map) {
if ({}.hasOwnProperty.call(map, key)) {
newMap[key.toLowerCase()] = map[key];
}
}
return newMap;
};