node-consul-service
Version:
A robust Node.js service that integrates with HashiCorp Consul for service discovery and configuration management. This service provides a comprehensive solution for managing distributed systems and microservices architecture, making it easier to handle s
2,393 lines (2,207 loc) • 398 kB
JavaScript
'use strict';
var Consul = require('consul');
var require$$1 = require('util');
var stream = require('stream');
var require$$1$1 = require('path');
var require$$3 = require('http');
var require$$4 = require('https');
var require$$0$1 = require('url');
var require$$6 = require('fs');
var crypto = require('crypto');
var require$$4$1 = require('assert');
var zlib = require('zlib');
var events = require('events');
// src/lib/client.ts
let consulClient = null;
function toBoolean(value) {
if (typeof value === "boolean")
return value;
if (typeof value === "string")
return value.toLowerCase() === "true";
return false;
}
function initClient({ host = "127.0.0.1", port = 8500, secure = false, }) {
consulClient = new Consul({
host: host !== null && host !== void 0 ? host : "127.0.0.1",
port: port !== null && port !== void 0 ? port : 8500,
secure: toBoolean(secure),
});
consulClient.agent.self((err) => {
if (err) {
console.error("❌ Failed to connect to Consul:", err.message);
}
else {
console.log("✅ Connected to Consul successfully");
}
});
}
function getClient() {
if (!consulClient) {
throw new Error("Consul client not initialized. Call initClient() first.");
}
return consulClient;
}
const registeredServices = new Set();
async function registerService(options) {
var _a, _b, _c, _d;
const { name, id, port, address = 'localhost', check, tags, meta, } = options;
if (registeredServices.has(id)) {
console.log(`⚠️ Service "${id}" is already registered.`);
return;
}
const serviceDefinition = {
name,
id,
address,
port,
tags,
meta,
};
if (check !== false) {
const checkDefinition = {
name: (_a = check === null || check === void 0 ? void 0 : check.name) !== null && _a !== void 0 ? _a : `${name}-check`,
http: (_b = check === null || check === void 0 ? void 0 : check.http) !== null && _b !== void 0 ? _b : `http://${address}:${port}/health`,
interval: (_c = check === null || check === void 0 ? void 0 : check.interval) !== null && _c !== void 0 ? _c : '10s',
timeout: (_d = check === null || check === void 0 ? void 0 : check.timeout) !== null && _d !== void 0 ? _d : '5s',
};
if (check === null || check === void 0 ? void 0 : check.deregistercriticalserviceafter) {
checkDefinition.deregistercriticalserviceafter = check.deregistercriticalserviceafter;
}
serviceDefinition.check = checkDefinition;
}
await getClient().agent.service.register(serviceDefinition);
registeredServices.add(id);
console.log(`✅ Service "${id}" registered successfully.`);
}
async function deregisterService(id) {
if (!registeredServices.has(id)) {
console.log(`⚠️ Service "${id}" is not registered.`);
return;
}
await getClient().agent.service.deregister(id);
registeredServices.delete(id);
console.log(`🛑 Service "${id}" deregistered successfully.`);
}
async function listServices() {
const services = await getClient().agent.service.list();
return Object.values(services);
}
async function getServiceInstances(serviceName) {
const services = await getClient().catalog.service.nodes(serviceName);
return services;
}
async function getRandomServiceInstance(serviceName) {
const instances = await getServiceInstances(serviceName);
if (!instances.length)
throw new Error(`Service "${serviceName}" not found`);
const randomIndex = Math.floor(Math.random() * instances.length);
return instances[randomIndex];
}
async function getServiceUrl(serviceName) {
const instance = await getRandomServiceInstance(serviceName);
return `http://${instance.ServiceAddress}:${instance.ServicePort}`;
}
function bind(fn, thisArg) {
return function wrap() {
return fn.apply(thisArg, arguments);
};
}
// utils is a library of generic helper functions non-specific to axios
const {toString} = Object.prototype;
const {getPrototypeOf} = Object;
const {iterator, toStringTag} = Symbol;
const kindOf = (cache => thing => {
const str = toString.call(thing);
return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
})(Object.create(null));
const kindOfTest = (type) => {
type = type.toLowerCase();
return (thing) => kindOf(thing) === type
};
const typeOfTest = type => thing => typeof thing === type;
/**
* Determine if a value is an Array
*
* @param {Object} val The value to test
*
* @returns {boolean} True if value is an Array, otherwise false
*/
const {isArray} = Array;
/**
* Determine if a value is undefined
*
* @param {*} val The value to test
*
* @returns {boolean} True if the value is undefined, otherwise false
*/
const isUndefined = typeOfTest('undefined');
/**
* Determine if a value is a Buffer
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is a Buffer, otherwise false
*/
function isBuffer(val) {
return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)
&& isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);
}
/**
* Determine if a value is an ArrayBuffer
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is an ArrayBuffer, otherwise false
*/
const isArrayBuffer = kindOfTest('ArrayBuffer');
/**
* Determine if a value is a view on an ArrayBuffer
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false
*/
function isArrayBufferView(val) {
let result;
if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {
result = ArrayBuffer.isView(val);
} else {
result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));
}
return result;
}
/**
* Determine if a value is a String
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is a String, otherwise false
*/
const isString = typeOfTest('string');
/**
* Determine if a value is a Function
*
* @param {*} val The value to test
* @returns {boolean} True if value is a Function, otherwise false
*/
const isFunction = typeOfTest('function');
/**
* Determine if a value is a Number
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is a Number, otherwise false
*/
const isNumber = typeOfTest('number');
/**
* Determine if a value is an Object
*
* @param {*} thing The value to test
*
* @returns {boolean} True if value is an Object, otherwise false
*/
const isObject = (thing) => thing !== null && typeof thing === 'object';
/**
* Determine if a value is a Boolean
*
* @param {*} thing The value to test
* @returns {boolean} True if value is a Boolean, otherwise false
*/
const isBoolean = thing => thing === true || thing === false;
/**
* Determine if a value is a plain Object
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is a plain Object, otherwise false
*/
const isPlainObject = (val) => {
if (kindOf(val) !== 'object') {
return false;
}
const prototype = getPrototypeOf(val);
return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);
};
/**
* Determine if a value is a Date
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is a Date, otherwise false
*/
const isDate = kindOfTest('Date');
/**
* Determine if a value is a File
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is a File, otherwise false
*/
const isFile = kindOfTest('File');
/**
* Determine if a value is a Blob
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is a Blob, otherwise false
*/
const isBlob = kindOfTest('Blob');
/**
* Determine if a value is a FileList
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is a File, otherwise false
*/
const isFileList = kindOfTest('FileList');
/**
* Determine if a value is a Stream
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is a Stream, otherwise false
*/
const isStream = (val) => isObject(val) && isFunction(val.pipe);
/**
* Determine if a value is a FormData
*
* @param {*} thing The value to test
*
* @returns {boolean} True if value is an FormData, otherwise false
*/
const isFormData = (thing) => {
let kind;
return thing && (
(typeof FormData === 'function' && thing instanceof FormData) || (
isFunction(thing.append) && (
(kind = kindOf(thing)) === 'formdata' ||
// detect form-data instance
(kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')
)
)
)
};
/**
* Determine if a value is a URLSearchParams object
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is a URLSearchParams object, otherwise false
*/
const isURLSearchParams = kindOfTest('URLSearchParams');
const [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest);
/**
* Trim excess whitespace off the beginning and end of a string
*
* @param {String} str The String to trim
*
* @returns {String} The String freed of excess whitespace
*/
const trim = (str) => str.trim ?
str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
/**
* Iterate over an Array or an Object invoking a function for each item.
*
* If `obj` is an Array callback will be called passing
* the value, index, and complete array for each item.
*
* If 'obj' is an Object callback will be called passing
* the value, key, and complete object for each property.
*
* @param {Object|Array} obj The object to iterate
* @param {Function} fn The callback to invoke for each item
*
* @param {Boolean} [allOwnKeys = false]
* @returns {any}
*/
function forEach(obj, fn, {allOwnKeys = false} = {}) {
// Don't bother if no value provided
if (obj === null || typeof obj === 'undefined') {
return;
}
let i;
let l;
// Force an array if not already something iterable
if (typeof obj !== 'object') {
/*eslint no-param-reassign:0*/
obj = [obj];
}
if (isArray(obj)) {
// Iterate over array values
for (i = 0, l = obj.length; i < l; i++) {
fn.call(null, obj[i], i, obj);
}
} else {
// Iterate over object keys
const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
const len = keys.length;
let key;
for (i = 0; i < len; i++) {
key = keys[i];
fn.call(null, obj[key], key, obj);
}
}
}
function findKey(obj, key) {
key = key.toLowerCase();
const keys = Object.keys(obj);
let i = keys.length;
let _key;
while (i-- > 0) {
_key = keys[i];
if (key === _key.toLowerCase()) {
return _key;
}
}
return null;
}
const _global = (() => {
/*eslint no-undef:0*/
if (typeof globalThis !== "undefined") return globalThis;
return typeof self !== "undefined" ? self : (typeof window !== 'undefined' ? window : global)
})();
const isContextDefined = (context) => !isUndefined(context) && context !== _global;
/**
* Accepts varargs expecting each argument to be an object, then
* immutably merges the properties of each object and returns result.
*
* When multiple objects contain the same key the later object in
* the arguments list will take precedence.
*
* Example:
*
* ```js
* var result = merge({foo: 123}, {foo: 456});
* console.log(result.foo); // outputs 456
* ```
*
* @param {Object} obj1 Object to merge
*
* @returns {Object} Result of all merge properties
*/
function merge(/* obj1, obj2, obj3, ... */) {
const {caseless} = isContextDefined(this) && this || {};
const result = {};
const assignValue = (val, key) => {
const targetKey = caseless && findKey(result, key) || key;
if (isPlainObject(result[targetKey]) && isPlainObject(val)) {
result[targetKey] = merge(result[targetKey], val);
} else if (isPlainObject(val)) {
result[targetKey] = merge({}, val);
} else if (isArray(val)) {
result[targetKey] = val.slice();
} else {
result[targetKey] = val;
}
};
for (let i = 0, l = arguments.length; i < l; i++) {
arguments[i] && forEach(arguments[i], assignValue);
}
return result;
}
/**
* Extends object a by mutably adding to it the properties of object b.
*
* @param {Object} a The object to be extended
* @param {Object} b The object to copy properties from
* @param {Object} thisArg The object to bind function to
*
* @param {Boolean} [allOwnKeys]
* @returns {Object} The resulting value of object a
*/
const extend = (a, b, thisArg, {allOwnKeys}= {}) => {
forEach(b, (val, key) => {
if (thisArg && isFunction(val)) {
a[key] = bind(val, thisArg);
} else {
a[key] = val;
}
}, {allOwnKeys});
return a;
};
/**
* Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
*
* @param {string} content with BOM
*
* @returns {string} content value without BOM
*/
const stripBOM = (content) => {
if (content.charCodeAt(0) === 0xFEFF) {
content = content.slice(1);
}
return content;
};
/**
* Inherit the prototype methods from one constructor into another
* @param {function} constructor
* @param {function} superConstructor
* @param {object} [props]
* @param {object} [descriptors]
*
* @returns {void}
*/
const inherits = (constructor, superConstructor, props, descriptors) => {
constructor.prototype = Object.create(superConstructor.prototype, descriptors);
constructor.prototype.constructor = constructor;
Object.defineProperty(constructor, 'super', {
value: superConstructor.prototype
});
props && Object.assign(constructor.prototype, props);
};
/**
* Resolve object with deep prototype chain to a flat object
* @param {Object} sourceObj source object
* @param {Object} [destObj]
* @param {Function|Boolean} [filter]
* @param {Function} [propFilter]
*
* @returns {Object}
*/
const toFlatObject = (sourceObj, destObj, filter, propFilter) => {
let props;
let i;
let prop;
const merged = {};
destObj = destObj || {};
// eslint-disable-next-line no-eq-null,eqeqeq
if (sourceObj == null) return destObj;
do {
props = Object.getOwnPropertyNames(sourceObj);
i = props.length;
while (i-- > 0) {
prop = props[i];
if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {
destObj[prop] = sourceObj[prop];
merged[prop] = true;
}
}
sourceObj = filter !== false && getPrototypeOf(sourceObj);
} while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);
return destObj;
};
/**
* Determines whether a string ends with the characters of a specified string
*
* @param {String} str
* @param {String} searchString
* @param {Number} [position= 0]
*
* @returns {boolean}
*/
const endsWith = (str, searchString, position) => {
str = String(str);
if (position === undefined || position > str.length) {
position = str.length;
}
position -= searchString.length;
const lastIndex = str.indexOf(searchString, position);
return lastIndex !== -1 && lastIndex === position;
};
/**
* Returns new array from array like object or null if failed
*
* @param {*} [thing]
*
* @returns {?Array}
*/
const toArray = (thing) => {
if (!thing) return null;
if (isArray(thing)) return thing;
let i = thing.length;
if (!isNumber(i)) return null;
const arr = new Array(i);
while (i-- > 0) {
arr[i] = thing[i];
}
return arr;
};
/**
* Checking if the Uint8Array exists and if it does, it returns a function that checks if the
* thing passed in is an instance of Uint8Array
*
* @param {TypedArray}
*
* @returns {Array}
*/
// eslint-disable-next-line func-names
const isTypedArray = (TypedArray => {
// eslint-disable-next-line func-names
return thing => {
return TypedArray && thing instanceof TypedArray;
};
})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));
/**
* For each entry in the object, call the function with the key and value.
*
* @param {Object<any, any>} obj - The object to iterate over.
* @param {Function} fn - The function to call for each entry.
*
* @returns {void}
*/
const forEachEntry = (obj, fn) => {
const generator = obj && obj[iterator];
const _iterator = generator.call(obj);
let result;
while ((result = _iterator.next()) && !result.done) {
const pair = result.value;
fn.call(obj, pair[0], pair[1]);
}
};
/**
* It takes a regular expression and a string, and returns an array of all the matches
*
* @param {string} regExp - The regular expression to match against.
* @param {string} str - The string to search.
*
* @returns {Array<boolean>}
*/
const matchAll = (regExp, str) => {
let matches;
const arr = [];
while ((matches = regExp.exec(str)) !== null) {
arr.push(matches);
}
return arr;
};
/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */
const isHTMLForm = kindOfTest('HTMLFormElement');
const toCamelCase = str => {
return str.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,
function replacer(m, p1, p2) {
return p1.toUpperCase() + p2;
}
);
};
/* Creating a function that will check if an object has a property. */
const hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);
/**
* Determine if a value is a RegExp object
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is a RegExp object, otherwise false
*/
const isRegExp = kindOfTest('RegExp');
const reduceDescriptors = (obj, reducer) => {
const descriptors = Object.getOwnPropertyDescriptors(obj);
const reducedDescriptors = {};
forEach(descriptors, (descriptor, name) => {
let ret;
if ((ret = reducer(descriptor, name, obj)) !== false) {
reducedDescriptors[name] = ret || descriptor;
}
});
Object.defineProperties(obj, reducedDescriptors);
};
/**
* Makes all methods read-only
* @param {Object} obj
*/
const freezeMethods = (obj) => {
reduceDescriptors(obj, (descriptor, name) => {
// skip restricted props in strict mode
if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {
return false;
}
const value = obj[name];
if (!isFunction(value)) return;
descriptor.enumerable = false;
if ('writable' in descriptor) {
descriptor.writable = false;
return;
}
if (!descriptor.set) {
descriptor.set = () => {
throw Error('Can not rewrite read-only method \'' + name + '\'');
};
}
});
};
const toObjectSet = (arrayOrString, delimiter) => {
const obj = {};
const define = (arr) => {
arr.forEach(value => {
obj[value] = true;
});
};
isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));
return obj;
};
const noop = () => {};
const toFiniteNumber = (value, defaultValue) => {
return value != null && Number.isFinite(value = +value) ? value : defaultValue;
};
/**
* If the thing is a FormData object, return true, otherwise return false.
*
* @param {unknown} thing - The thing to check.
*
* @returns {boolean}
*/
function isSpecCompliantForm(thing) {
return !!(thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]);
}
const toJSONObject = (obj) => {
const stack = new Array(10);
const visit = (source, i) => {
if (isObject(source)) {
if (stack.indexOf(source) >= 0) {
return;
}
if(!('toJSON' in source)) {
stack[i] = source;
const target = isArray(source) ? [] : {};
forEach(source, (value, key) => {
const reducedValue = visit(value, i + 1);
!isUndefined(reducedValue) && (target[key] = reducedValue);
});
stack[i] = undefined;
return target;
}
}
return source;
};
return visit(obj, 0);
};
const isAsyncFn = kindOfTest('AsyncFunction');
const isThenable = (thing) =>
thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch);
// original code
// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34
const _setImmediate = ((setImmediateSupported, postMessageSupported) => {
if (setImmediateSupported) {
return setImmediate;
}
return postMessageSupported ? ((token, callbacks) => {
_global.addEventListener("message", ({source, data}) => {
if (source === _global && data === token) {
callbacks.length && callbacks.shift()();
}
}, false);
return (cb) => {
callbacks.push(cb);
_global.postMessage(token, "*");
}
})(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb);
})(
typeof setImmediate === 'function',
isFunction(_global.postMessage)
);
const asap = typeof queueMicrotask !== 'undefined' ?
queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate);
// *********************
const isIterable = (thing) => thing != null && isFunction(thing[iterator]);
var utils$1 = {
isArray,
isArrayBuffer,
isBuffer,
isFormData,
isArrayBufferView,
isString,
isNumber,
isBoolean,
isObject,
isPlainObject,
isReadableStream,
isRequest,
isResponse,
isHeaders,
isUndefined,
isDate,
isFile,
isBlob,
isRegExp,
isFunction,
isStream,
isURLSearchParams,
isTypedArray,
isFileList,
forEach,
merge,
extend,
trim,
stripBOM,
inherits,
toFlatObject,
kindOf,
kindOfTest,
endsWith,
toArray,
forEachEntry,
matchAll,
isHTMLForm,
hasOwnProperty,
hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection
reduceDescriptors,
freezeMethods,
toObjectSet,
toCamelCase,
noop,
toFiniteNumber,
findKey,
global: _global,
isContextDefined,
isSpecCompliantForm,
toJSONObject,
isAsyncFn,
isThenable,
setImmediate: _setImmediate,
asap,
isIterable
};
/**
* Create an Error with the specified message, config, error code, request and response.
*
* @param {string} message The error message.
* @param {string} [code] The error code (for example, 'ECONNABORTED').
* @param {Object} [config] The config.
* @param {Object} [request] The request.
* @param {Object} [response] The response.
*
* @returns {Error} The created error.
*/
function AxiosError$1(message, code, config, request, response) {
Error.call(this);
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
} else {
this.stack = (new Error()).stack;
}
this.message = message;
this.name = 'AxiosError';
code && (this.code = code);
config && (this.config = config);
request && (this.request = request);
if (response) {
this.response = response;
this.status = response.status ? response.status : null;
}
}
utils$1.inherits(AxiosError$1, Error, {
toJSON: function toJSON() {
return {
// Standard
message: this.message,
name: this.name,
// Microsoft
description: this.description,
number: this.number,
// Mozilla
fileName: this.fileName,
lineNumber: this.lineNumber,
columnNumber: this.columnNumber,
stack: this.stack,
// Axios
config: utils$1.toJSONObject(this.config),
code: this.code,
status: this.status
};
}
});
const prototype$1 = AxiosError$1.prototype;
const descriptors = {};
[
'ERR_BAD_OPTION_VALUE',
'ERR_BAD_OPTION',
'ECONNABORTED',
'ETIMEDOUT',
'ERR_NETWORK',
'ERR_FR_TOO_MANY_REDIRECTS',
'ERR_DEPRECATED',
'ERR_BAD_RESPONSE',
'ERR_BAD_REQUEST',
'ERR_CANCELED',
'ERR_NOT_SUPPORT',
'ERR_INVALID_URL'
// eslint-disable-next-line func-names
].forEach(code => {
descriptors[code] = {value: code};
});
Object.defineProperties(AxiosError$1, descriptors);
Object.defineProperty(prototype$1, 'isAxiosError', {value: true});
// eslint-disable-next-line func-names
AxiosError$1.from = (error, code, config, request, response, customProps) => {
const axiosError = Object.create(prototype$1);
utils$1.toFlatObject(error, axiosError, function filter(obj) {
return obj !== Error.prototype;
}, prop => {
return prop !== 'isAxiosError';
});
AxiosError$1.call(axiosError, error.message, code, config, request, response);
axiosError.cause = error;
axiosError.name = error.name;
customProps && Object.assign(axiosError, customProps);
return axiosError;
};
function getDefaultExportFromCjs (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
var delayed_stream;
var hasRequiredDelayed_stream;
function requireDelayed_stream () {
if (hasRequiredDelayed_stream) return delayed_stream;
hasRequiredDelayed_stream = 1;
var Stream = stream.Stream;
var util = require$$1;
delayed_stream = DelayedStream;
function DelayedStream() {
this.source = null;
this.dataSize = 0;
this.maxDataSize = 1024 * 1024;
this.pauseStream = true;
this._maxDataSizeExceeded = false;
this._released = false;
this._bufferedEvents = [];
}
util.inherits(DelayedStream, Stream);
DelayedStream.create = function(source, options) {
var delayedStream = new this();
options = options || {};
for (var option in options) {
delayedStream[option] = options[option];
}
delayedStream.source = source;
var realEmit = source.emit;
source.emit = function() {
delayedStream._handleEmit(arguments);
return realEmit.apply(source, arguments);
};
source.on('error', function() {});
if (delayedStream.pauseStream) {
source.pause();
}
return delayedStream;
};
Object.defineProperty(DelayedStream.prototype, 'readable', {
configurable: true,
enumerable: true,
get: function() {
return this.source.readable;
}
});
DelayedStream.prototype.setEncoding = function() {
return this.source.setEncoding.apply(this.source, arguments);
};
DelayedStream.prototype.resume = function() {
if (!this._released) {
this.release();
}
this.source.resume();
};
DelayedStream.prototype.pause = function() {
this.source.pause();
};
DelayedStream.prototype.release = function() {
this._released = true;
this._bufferedEvents.forEach(function(args) {
this.emit.apply(this, args);
}.bind(this));
this._bufferedEvents = [];
};
DelayedStream.prototype.pipe = function() {
var r = Stream.prototype.pipe.apply(this, arguments);
this.resume();
return r;
};
DelayedStream.prototype._handleEmit = function(args) {
if (this._released) {
this.emit.apply(this, args);
return;
}
if (args[0] === 'data') {
this.dataSize += args[1].length;
this._checkIfMaxDataSizeExceeded();
}
this._bufferedEvents.push(args);
};
DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() {
if (this._maxDataSizeExceeded) {
return;
}
if (this.dataSize <= this.maxDataSize) {
return;
}
this._maxDataSizeExceeded = true;
var message =
'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.';
this.emit('error', new Error(message));
};
return delayed_stream;
}
var combined_stream;
var hasRequiredCombined_stream;
function requireCombined_stream () {
if (hasRequiredCombined_stream) return combined_stream;
hasRequiredCombined_stream = 1;
var util = require$$1;
var Stream = stream.Stream;
var DelayedStream = requireDelayed_stream();
combined_stream = CombinedStream;
function CombinedStream() {
this.writable = false;
this.readable = true;
this.dataSize = 0;
this.maxDataSize = 2 * 1024 * 1024;
this.pauseStreams = true;
this._released = false;
this._streams = [];
this._currentStream = null;
this._insideLoop = false;
this._pendingNext = false;
}
util.inherits(CombinedStream, Stream);
CombinedStream.create = function(options) {
var combinedStream = new this();
options = options || {};
for (var option in options) {
combinedStream[option] = options[option];
}
return combinedStream;
};
CombinedStream.isStreamLike = function(stream) {
return (typeof stream !== 'function')
&& (typeof stream !== 'string')
&& (typeof stream !== 'boolean')
&& (typeof stream !== 'number')
&& (!Buffer.isBuffer(stream));
};
CombinedStream.prototype.append = function(stream) {
var isStreamLike = CombinedStream.isStreamLike(stream);
if (isStreamLike) {
if (!(stream instanceof DelayedStream)) {
var newStream = DelayedStream.create(stream, {
maxDataSize: Infinity,
pauseStream: this.pauseStreams,
});
stream.on('data', this._checkDataSize.bind(this));
stream = newStream;
}
this._handleErrors(stream);
if (this.pauseStreams) {
stream.pause();
}
}
this._streams.push(stream);
return this;
};
CombinedStream.prototype.pipe = function(dest, options) {
Stream.prototype.pipe.call(this, dest, options);
this.resume();
return dest;
};
CombinedStream.prototype._getNext = function() {
this._currentStream = null;
if (this._insideLoop) {
this._pendingNext = true;
return; // defer call
}
this._insideLoop = true;
try {
do {
this._pendingNext = false;
this._realGetNext();
} while (this._pendingNext);
} finally {
this._insideLoop = false;
}
};
CombinedStream.prototype._realGetNext = function() {
var stream = this._streams.shift();
if (typeof stream == 'undefined') {
this.end();
return;
}
if (typeof stream !== 'function') {
this._pipeNext(stream);
return;
}
var getStream = stream;
getStream(function(stream) {
var isStreamLike = CombinedStream.isStreamLike(stream);
if (isStreamLike) {
stream.on('data', this._checkDataSize.bind(this));
this._handleErrors(stream);
}
this._pipeNext(stream);
}.bind(this));
};
CombinedStream.prototype._pipeNext = function(stream) {
this._currentStream = stream;
var isStreamLike = CombinedStream.isStreamLike(stream);
if (isStreamLike) {
stream.on('end', this._getNext.bind(this));
stream.pipe(this, {end: false});
return;
}
var value = stream;
this.write(value);
this._getNext();
};
CombinedStream.prototype._handleErrors = function(stream) {
var self = this;
stream.on('error', function(err) {
self._emitError(err);
});
};
CombinedStream.prototype.write = function(data) {
this.emit('data', data);
};
CombinedStream.prototype.pause = function() {
if (!this.pauseStreams) {
return;
}
if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause();
this.emit('pause');
};
CombinedStream.prototype.resume = function() {
if (!this._released) {
this._released = true;
this.writable = true;
this._getNext();
}
if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume();
this.emit('resume');
};
CombinedStream.prototype.end = function() {
this._reset();
this.emit('end');
};
CombinedStream.prototype.destroy = function() {
this._reset();
this.emit('close');
};
CombinedStream.prototype._reset = function() {
this.writable = false;
this._streams = [];
this._currentStream = null;
};
CombinedStream.prototype._checkDataSize = function() {
this._updateDataSize();
if (this.dataSize <= this.maxDataSize) {
return;
}
var message =
'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.';
this._emitError(new Error(message));
};
CombinedStream.prototype._updateDataSize = function() {
this.dataSize = 0;
var self = this;
this._streams.forEach(function(stream) {
if (!stream.dataSize) {
return;
}
self.dataSize += stream.dataSize;
});
if (this._currentStream && this._currentStream.dataSize) {
this.dataSize += this._currentStream.dataSize;
}
};
CombinedStream.prototype._emitError = function(err) {
this._reset();
this.emit('error', err);
};
return combined_stream;
}
var mimeTypes = {};
var require$$0 = {
"application/1d-interleaved-parityfec": {
source: "iana"
},
"application/3gpdash-qoe-report+xml": {
source: "iana",
charset: "UTF-8",
compressible: true
},
"application/3gpp-ims+xml": {
source: "iana",
compressible: true
},
"application/3gpphal+json": {
source: "iana",
compressible: true
},
"application/3gpphalforms+json": {
source: "iana",
compressible: true
},
"application/a2l": {
source: "iana"
},
"application/ace+cbor": {
source: "iana"
},
"application/activemessage": {
source: "iana"
},
"application/activity+json": {
source: "iana",
compressible: true
},
"application/alto-costmap+json": {
source: "iana",
compressible: true
},
"application/alto-costmapfilter+json": {
source: "iana",
compressible: true
},
"application/alto-directory+json": {
source: "iana",
compressible: true
},
"application/alto-endpointcost+json": {
source: "iana",
compressible: true
},
"application/alto-endpointcostparams+json": {
source: "iana",
compressible: true
},
"application/alto-endpointprop+json": {
source: "iana",
compressible: true
},
"application/alto-endpointpropparams+json": {
source: "iana",
compressible: true
},
"application/alto-error+json": {
source: "iana",
compressible: true
},
"application/alto-networkmap+json": {
source: "iana",
compressible: true
},
"application/alto-networkmapfilter+json": {
source: "iana",
compressible: true
},
"application/alto-updatestreamcontrol+json": {
source: "iana",
compressible: true
},
"application/alto-updatestreamparams+json": {
source: "iana",
compressible: true
},
"application/aml": {
source: "iana"
},
"application/andrew-inset": {
source: "iana",
extensions: [
"ez"
]
},
"application/applefile": {
source: "iana"
},
"application/applixware": {
source: "apache",
extensions: [
"aw"
]
},
"application/at+jwt": {
source: "iana"
},
"application/atf": {
source: "iana"
},
"application/atfx": {
source: "iana"
},
"application/atom+xml": {
source: "iana",
compressible: true,
extensions: [
"atom"
]
},
"application/atomcat+xml": {
source: "iana",
compressible: true,
extensions: [
"atomcat"
]
},
"application/atomdeleted+xml": {
source: "iana",
compressible: true,
extensions: [
"atomdeleted"
]
},
"application/atomicmail": {
source: "iana"
},
"application/atomsvc+xml": {
source: "iana",
compressible: true,
extensions: [
"atomsvc"
]
},
"application/atsc-dwd+xml": {
source: "iana",
compressible: true,
extensions: [
"dwd"
]
},
"application/atsc-dynamic-event-message": {
source: "iana"
},
"application/atsc-held+xml": {
source: "iana",
compressible: true,
extensions: [
"held"
]
},
"application/atsc-rdt+json": {
source: "iana",
compressible: true
},
"application/atsc-rsat+xml": {
source: "iana",
compressible: true,
extensions: [
"rsat"
]
},
"application/atxml": {
source: "iana"
},
"application/auth-policy+xml": {
source: "iana",
compressible: true
},
"application/bacnet-xdd+zip": {
source: "iana",
compressible: false
},
"application/batch-smtp": {
source: "iana"
},
"application/bdoc": {
compressible: false,
extensions: [
"bdoc"
]
},
"application/beep+xml": {
source: "iana",
charset: "UTF-8",
compressible: true
},
"application/calendar+json": {
source: "iana",
compressible: true
},
"application/calendar+xml": {
source: "iana",
compressible: true,
extensions: [
"xcs"
]
},
"application/call-completion": {
source: "iana"
},
"application/cals-1840": {
source: "iana"
},
"application/captive+json": {
source: "iana",
compressible: true
},
"application/cbor": {
source: "iana"
},
"application/cbor-seq": {
source: "iana"
},
"application/cccex": {
source: "iana"
},
"application/ccmp+xml": {
source: "iana",
compressible: true
},
"application/ccxml+xml": {
source: "iana",
compressible: true,
extensions: [
"ccxml"
]
},
"application/cdfx+xml": {
source: "iana",
compressible: true,
extensions: [
"cdfx"
]
},
"application/cdmi-capability": {
source: "iana",
extensions: [
"cdmia"
]
},
"application/cdmi-container": {
source: "iana",
extensions: [
"cdmic"
]
},
"application/cdmi-domain": {
source: "iana",
extensions: [
"cdmid"
]
},
"application/cdmi-object": {
source: "iana",
extensions: [
"cdmio"
]
},
"application/cdmi-queue": {
source: "iana",
extensions: [
"cdmiq"
]
},
"application/cdni": {
source: "iana"
},
"application/cea": {
source: "iana"
},
"application/cea-2018+xml": {
source: "iana",
compressible: true
},
"application/cellml+xml": {
source: "iana",
compressible: true
},
"application/cfw": {
source: "iana"
},
"application/city+json": {
source: "iana",
compressible: true
},
"application/clr": {
source: "iana"
},
"application/clue+xml": {
source: "iana",
compressible: true
},
"application/clue_info+xml": {
source: "iana",
compressible: true
},
"application/cms": {
source: "iana"
},
"application/cnrp+xml": {
source: "iana",
compressible: true
},
"application/coap-group+json": {
source: "iana",
compressible: true
},
"application/coap-payload": {
source: "iana"
},
"application/commonground": {
source: "iana"
},
"application/conference-info+xml": {
source: "iana",
compressible: true
},
"application/cose": {
source: "iana"
},
"application/cose-key": {
source: "iana"
},
"application/cose-key-set": {
source: "iana"
},
"application/cpl+xml": {
source: "iana",
compressible: true,
extensions: [
"cpl"
]
},
"application/csrattrs": {
source: "iana"
},
"application/csta+xml": {
source: "iana",
compressible: true
},
"application/cstadata+xml": {
source: "iana",
compressible: true
},
"application/csvm+json": {
source: "iana",
compressible: true
},
"application/cu-seeme": {
source: "apache",
extensions: [
"cu"
]
},
"application/cwt": {
source: "iana"
},
"application/cybercash": {
source: "iana"
},
"application/dart": {
compressible: true
},
"application/dash+xml": {
source: "iana",
compressible: true,
extensions: [
"mpd"
]
},
"application/dash-patch+xml": {
source: "iana",
compressible: true,
extensions: [
"mpp"
]
},
"application/dashdelta": {
source: "iana"
},
"application/davmount+xml": {
source: "iana",
compressible: true,
extensions: [
"davmount"
]
},
"application/dca-rft": {
source: "iana"
},
"application/dcd": {
source: "iana"
},
"application/dec-dx": {
source: "iana"
},
"application/dialog-info+xml": {
source: "iana",
compressible: true
},
"application/dicom": {
source: "iana"
},
"application/dicom+json": {
source: "iana",
compressible: true
},
"application/dicom+xml": {
source: "iana",
compressible: true
},
"application/dii": {
source: "iana"
},
"application/dit": {
source: "iana"
},
"application/dns": {
source: "iana"
},
"application/dns+json": {
source: "iana",
compressible: true
},
"application/dns-message": {
source: "iana"
},
"application/docbook+xml": {
source: "apache",
compressible: true,
extensions: [
"dbk"
]
},
"application/dots+cbor": {
source: "iana"
},
"application/dskpp+xml": {
source: "iana",
compressible: true
},
"application/dssc+der": {
source: "iana",
extensions: [
"dssc"
]
},
"application/dssc+xml": {
source: "iana",
compressible: true,
extensions: [
"xdssc"
]
},
"application/dvcs": {
source: "iana"
},
"application/ecmascript": {
source: "iana",
compressible: true,
extensions: [
"es",
"ecma"
]
},
"application/edi-consent": {
source: "iana"
},
"application/edi-x12": {
source: "iana",
compressible: false
},
"application/edifact": {
source: "iana",
compressible: false
},
"application/efi": {
source: "iana"
},
"application/elm+json": {
source: "iana",
charset: "UTF-8",
compressible: true
},
"application/elm+xml": {
source: "iana",
compressible: true
},
"application/emergencycalldata.cap+xml": {
source: "iana",
charset: "UTF-8",
compressible: true
},
"application/emergencycalldata.comment+xml": {
source: "iana",
compressible: true
},
"application/emergencycalldata.control+xml": {
source: "iana",
compressible: true
},
"application/emergencycalldata.deviceinfo+xml": {
source: "iana",
compressible: true
},
"application/emergencycalldata.ecall.msd": {
source: "iana"
},
"application/emergencycalldata.providerinfo+xml": {
source: "iana",
compressible: true
},
"application/emergencycalldata.serviceinfo+xml": {
source: "iana",
compressible: true
},
"application/emergencycalldata.subscriberinfo+xml": {
source: "iana",
compressible: true
},
"application/emergencycalldata.veds+xml": {
source: "iana",
compressible: true
},
"application/emma+xml": {
source: "iana",
compressible: true,
extensions: [
"emma"
]
},
"application/emotionml+xml": {
source: "iana",
compressible: true,
extensions: [
"emotionml"
]
},
"application/encaprtp": {
source: "iana"
},
"application/epp+xml": {
source: "iana",
compressible: true
},
"application/epub+zip": {
source: "iana",
compressible: false,
extensions: [
"epub"
]
},
"application/eshop": {
source: "iana"
},
"application/exi": {
source: "iana",
extensions: [
"exi"
]
},
"application/expect-ct-report+json": {
source: "iana",
compressible: true
},
"application/express": {
source: "iana",
extensions: [
"exp"
]
},
"application/fastinfoset": {
source: "iana"
},
"application/fastsoap": {
source: "iana"
},
"application/fdt+xml": {
source: "iana",
compressible: true,
extensions: [
"fdt"
]
},
"application/fhir+json": {
source: "iana",
charset: "UTF-8",
compressible: true
},
"application/fhir+xml": {
source: "iana",
charset: "UTF-8",
compressible: true
},
"application/fido.trusted-apps+json": {
compressible: true
},
"application/fits": {
source: "iana"
},
"application/flexfec": {
source: "iana"
},
"application/font-sfnt": {
source: "iana"
},
"application/font-tdpfr": {
source: "iana",
extensions: [
"pfr"
]
},
"application/font-woff": {
source: "iana",
compressible: false
},
"application/framework-attributes+xml": {
source: "iana",
compressible: true
},
"application/geo+json": {
source: "iana",
compressible: true,
extensions: [
"geojson"
]
},
"application/geo+json-seq": {
source: "iana"
},
"application/geopackage+sqlite3": {
source: "iana"
},
"application/geoxacml+xml": {
source: "iana",
compressible: true
},
"application/gltf-buffer": {
source: "iana"
},
"application/gml+xml": {
source: "iana",
compressible: true,
extensions: [
"gml"
]
},
"application/gpx+xml": {
source: "apache",
compressible: true,
extensions: [
"gpx"
]
},
"application/gxf": {
source: "apache",
extensions: [
"gxf"
]
},
"application/gzip": {
source: "iana",
compressible: false,
extensions: [
"gz"
]
},
"application/h224": {
source: "iana"
},
"application/held+xml": {
source: "iana",
compressible: true
},
"application/hjson": {
extensions: [
"hjson"
]
},
"application/http": {
source: "iana"
},
"application/hyperstudio": {
source: "iana",
extensions: [
"stk"
]
},
"application/ibe-key-request+xml": {
source: "iana",
compressible: true
},
"application/ibe-pkg-reply+xml": {
source: "iana",
compressible: true
},
"application/ibe-pp-data": {
source: "iana"
},
"application/iges": {
source: "iana"
},
"application/im-iscomposing+xml": {
source: "iana",
charset: "UTF-8",
compressible: true
},
"application/index": {
source: "iana"
},
"application/index.cmd": {
source: "iana"
},
"application/index.obj": {
source: "iana"
},
"application/index.response": {
source: "iana"
},
"application/index.vnd": {
source: "iana"
},
"application/inkml+xml": {
source: "iana",
compressible: true,
extensions: [
"ink",
"inkml"
]
},
"application/iotp": {
source: "iana"
},
"application/ipfix": {
source: "iana",
extensions: [
"ipfix"
]
},
"application/ipp": {
source: "iana"
},
"application/isup": {
source: "iana"
},
"application/its+xml": {
source: "iana",
compressible: true,
extensions: [
"its"
]
},
"application/java-archive": {
source: "apache",
compressible: false,
extensions: [
"jar",
"war",
"ear"
]
},
"application/java-serialized-object": {
source: "apache",
compressible: false,
extensions: [
"ser"
]
},
"application/java-vm": {
source: "apache",
compressible: false,
extensions: [
"class"
]
},
"application/javascript": {
source: "iana",
charset: "UTF-8",
compressible: true,
extensions: [
"js",
"mjs"
]
},
"application/jf2feed+json": {
source: "iana",
compressible: true
},
"application/jose": {
source: "iana"
},
"application/jose+json": {
source: "iana",
compressible: true
},
"application/jrd+json": {
source: "iana",
compressible: true
},
"application/jscalendar+json": {
source: "iana",
compressible: true
},
"application/json": {
source: "iana",
charset: "UTF-8",
compressible: true,
extensions: [
"json",
"map"
]
},
"application/json-patch+json": {
source: "iana",
compressible: true
},
"application/json-seq": {
source: "iana"
},
"application/json5": {
extensions: [
"json5"
]
},
"application/jsonml+json": {
source: "apache",
compressible: true,
extensions: [
"jsonml"
]
},
"application/jwk+json": {
source: "iana",
compressible: true
},
"application/jwk-set+json": {
source: "iana",
compressible: true
},
"application/jwt": {
source: "iana"
},
"application/kpml-request+xml": {
source: "iana",
compressible: true
},
"application/kpml-response+xml": {
source: "iana",
compressible: true
},
"application/ld+json": {
source: "iana",
compressible: true,
extensions: [
"jsonld"
]
},
"application/lgr+xml": {
source: "iana",
compressible: true,
extensions: [
"lgr"
]
},
"application/link-format": {
source: "iana"
},
"application/load-control+xml": {
source: "iana",
compressible: true
},
"application/lost+xml": {
source: "iana",
compressible: true,
extensions: [
"lostxml"
]
},
"application/lostsync+xml": {
source: "iana",
compressible: true
},
"application/lpf+zip": {
source: "iana",
compressible: false
},
"application/lxf": {
source: "iana"
},
"application/mac-binhex40": {
source: "iana",
extensions: [
"hqx"
]
},
"application/mac-compactpro": {
source: "apache",
extensions: [
"cpt"
]
},
"application/macwriteii": {
source: "iana"
},
"application/mads+xml": {
source: "iana",
compressible: true,
extensions: [
"mads"
]
},
"application/manifest+json": {
source: "iana",
charset: "UTF-8",
compressible: true,
extensions: [
"webmanifest"
]
},
"application/marc": {
source: "iana",
extensions: [
"mrc"
]
},
"application/marcxml+xml": {
source: "iana",
compressible: true,
extensions: [
"mrcx"
]
},
"application/mathematica": {
source: "iana",
extensions: [
"ma",
"nb",
"mb"
]
},
"application/mathml+xml": {
source: "iana",
compressible: true,
extensions: [
"mathml"
]
},
"application/mathml-content+xml": {
source: "iana",
compressible: true
},
"application/mathml-presentation+xml": {
source: "iana",
compressible: true
},
"application/mbms-associated-procedure-description+xml": {
source: "iana",
compressible: true
},
"application/mbms-deregister+xml": {
source: "iana",
compressible: true
},
"application/mbms-envelope+xml": {
source: "iana",
compressible: true
},
"application/mbms-msk+xml": {
source: "iana",
compressible: true
},
"application/mbms-msk-response+xml": {
source: "iana",
compressible: true
},
"application/mbms-protection-description+xml": {
source: "iana",
compressible: true
},
"application/mbms-reception-report+xml": {
source: "iana",
compressible: true
},
"application/mbms-register+xml": {
source: "iana",
compressible: true
},
"application/mbms-register-response+xml": {
source: "iana",
compressible: true
},
"application/mbms-schedule+xml": {
source: "iana",
compressible: true
},
"application/mbms-user-service-description+xml": {
source: "iana",
compressible: true
},
"application/mbox": {
source: "iana",
extensions: [
"mbox"
]
},
"application/media-policy-dataset+xml": {
source: "iana",
compressible: true,
extensions: [
"mpf"
]
},
"application/media_control+xml": {
source: "iana",
compressible: true
},
"application/mediaservercontrol+xml": {
source: "iana",
compressible: true,
extensions: [
"mscml"
]
},
"application/merge-patch+json": {
source: "iana",
compressible: true
},
"application/metalink+xml": {
source: "apache",
compressible: true,
extensions: [
"metalink"
]
},
"application/metalink4+xml": {
source: "iana",
compressible: true,
extensions: [
"meta4"
]
},
"application/mets+xml": {
source: "iana",
compressible: true,
extensions: [
"mets"
]
},
"application/mf4": {
source: "iana"
},
"application/mikey": {
source: "iana"
},
"application/mipc": {
source: "iana"
},
"application/missing-blocks+cbor-seq": {
source: "iana"
},
"application/mmt-aei+xml": {
source: "iana",
compressible: true,
extensions: [
"maei"
]
},
"application/mmt-usd+xml": {
source: "iana",
compressible: true,
extensions: [
"musd"
]
},
"application/mods+xml": {
source: "iana",
compressible: true,
extensions: [
"mods"
]
},
"application/moss-keys": {
source: "iana"
},
"application/moss-signature": {
source: "iana"
},
"application/mosskey-data": {
source: "iana"
},
"application/mosskey-request": {
source: "iana"
},