summaryrefslogtreecommitdiff
path: root/node_modules/hoek/lib/index.js
diff options
context:
space:
mode:
authorArman Shah <[email protected]>2018-02-19 23:50:04 -0800
committerArman Shah <[email protected]>2018-02-19 23:50:04 -0800
commitae34dcfd3823a609ba7182f2d6eda593be876f7d (patch)
treeb9d7f2884c4999349418cbdc4f9ab46d113e0afd /node_modules/hoek/lib/index.js
parentInitial commit (diff)
downloadlauncher-ae34dcfd3823a609ba7182f2d6eda593be876f7d.tar.xz
launcher-ae34dcfd3823a609ba7182f2d6eda593be876f7d.zip
add base files
Diffstat (limited to 'node_modules/hoek/lib/index.js')
-rwxr-xr-xnode_modules/hoek/lib/index.js978
1 files changed, 978 insertions, 0 deletions
diff --git a/node_modules/hoek/lib/index.js b/node_modules/hoek/lib/index.js
new file mode 100755
index 0000000..75bbeb7
--- /dev/null
+++ b/node_modules/hoek/lib/index.js
@@ -0,0 +1,978 @@
+'use strict';
+
+// Load modules
+
+const Crypto = require('crypto');
+const Path = require('path');
+const Util = require('util');
+const Escape = require('./escape');
+
+
+// Declare internals
+
+const internals = {};
+
+
+// Clone object or array
+
+exports.clone = function (obj, seen) {
+
+ if (typeof obj !== 'object' ||
+ obj === null) {
+
+ return obj;
+ }
+
+ seen = seen || new Map();
+
+ const lookup = seen.get(obj);
+ if (lookup) {
+ return lookup;
+ }
+
+ let newObj;
+ let cloneDeep = false;
+
+ if (!Array.isArray(obj)) {
+ if (Buffer.isBuffer(obj)) {
+ newObj = new Buffer(obj);
+ }
+ else if (obj instanceof Date) {
+ newObj = new Date(obj.getTime());
+ }
+ else if (obj instanceof RegExp) {
+ newObj = new RegExp(obj);
+ }
+ else {
+ const proto = Object.getPrototypeOf(obj);
+ if (proto &&
+ proto.isImmutable) {
+
+ newObj = obj;
+ }
+ else {
+ newObj = Object.create(proto);
+ cloneDeep = true;
+ }
+ }
+ }
+ else {
+ newObj = [];
+ cloneDeep = true;
+ }
+
+ seen.set(obj, newObj);
+
+ if (cloneDeep) {
+ const keys = Object.getOwnPropertyNames(obj);
+ for (let i = 0; i < keys.length; ++i) {
+ const key = keys[i];
+ const descriptor = Object.getOwnPropertyDescriptor(obj, key);
+ if (descriptor &&
+ (descriptor.get ||
+ descriptor.set)) {
+
+ Object.defineProperty(newObj, key, descriptor);
+ }
+ else {
+ newObj[key] = exports.clone(obj[key], seen);
+ }
+ }
+ }
+
+ return newObj;
+};
+
+
+// Merge all the properties of source into target, source wins in conflict, and by default null and undefined from source are applied
+
+/*eslint-disable */
+exports.merge = function (target, source, isNullOverride /* = true */, isMergeArrays /* = true */) {
+/*eslint-enable */
+
+ exports.assert(target && typeof target === 'object', 'Invalid target value: must be an object');
+ exports.assert(source === null || source === undefined || typeof source === 'object', 'Invalid source value: must be null, undefined, or an object');
+
+ if (!source) {
+ return target;
+ }
+
+ if (Array.isArray(source)) {
+ exports.assert(Array.isArray(target), 'Cannot merge array onto an object');
+ if (isMergeArrays === false) { // isMergeArrays defaults to true
+ target.length = 0; // Must not change target assignment
+ }
+
+ for (let i = 0; i < source.length; ++i) {
+ target.push(exports.clone(source[i]));
+ }
+
+ return target;
+ }
+
+ const keys = Object.keys(source);
+ for (let i = 0; i < keys.length; ++i) {
+ const key = keys[i];
+ if (key === '__proto__') {
+ continue;
+ }
+
+ const value = source[key];
+ if (value &&
+ typeof value === 'object') {
+
+ if (!target[key] ||
+ typeof target[key] !== 'object' ||
+ (Array.isArray(target[key]) !== Array.isArray(value)) ||
+ value instanceof Date ||
+ Buffer.isBuffer(value) ||
+ value instanceof RegExp) {
+
+ target[key] = exports.clone(value);
+ }
+ else {
+ exports.merge(target[key], value, isNullOverride, isMergeArrays);
+ }
+ }
+ else {
+ if (value !== null &&
+ value !== undefined) { // Explicit to preserve empty strings
+
+ target[key] = value;
+ }
+ else if (isNullOverride !== false) { // Defaults to true
+ target[key] = value;
+ }
+ }
+ }
+
+ return target;
+};
+
+
+// Apply options to a copy of the defaults
+
+exports.applyToDefaults = function (defaults, options, isNullOverride) {
+
+ exports.assert(defaults && typeof defaults === 'object', 'Invalid defaults value: must be an object');
+ exports.assert(!options || options === true || typeof options === 'object', 'Invalid options value: must be true, falsy or an object');
+
+ if (!options) { // If no options, return null
+ return null;
+ }
+
+ const copy = exports.clone(defaults);
+
+ if (options === true) { // If options is set to true, use defaults
+ return copy;
+ }
+
+ return exports.merge(copy, options, isNullOverride === true, false);
+};
+
+
+// Clone an object except for the listed keys which are shallow copied
+
+exports.cloneWithShallow = function (source, keys) {
+
+ if (!source ||
+ typeof source !== 'object') {
+
+ return source;
+ }
+
+ const storage = internals.store(source, keys); // Move shallow copy items to storage
+ const copy = exports.clone(source); // Deep copy the rest
+ internals.restore(copy, source, storage); // Shallow copy the stored items and restore
+ return copy;
+};
+
+
+internals.store = function (source, keys) {
+
+ const storage = {};
+ for (let i = 0; i < keys.length; ++i) {
+ const key = keys[i];
+ const value = exports.reach(source, key);
+ if (value !== undefined) {
+ storage[key] = value;
+ internals.reachSet(source, key, undefined);
+ }
+ }
+
+ return storage;
+};
+
+
+internals.restore = function (copy, source, storage) {
+
+ const keys = Object.keys(storage);
+ for (let i = 0; i < keys.length; ++i) {
+ const key = keys[i];
+ internals.reachSet(copy, key, storage[key]);
+ internals.reachSet(source, key, storage[key]);
+ }
+};
+
+
+internals.reachSet = function (obj, key, value) {
+
+ const path = key.split('.');
+ let ref = obj;
+ for (let i = 0; i < path.length; ++i) {
+ const segment = path[i];
+ if (i + 1 === path.length) {
+ ref[segment] = value;
+ }
+
+ ref = ref[segment];
+ }
+};
+
+
+// Apply options to defaults except for the listed keys which are shallow copied from option without merging
+
+exports.applyToDefaultsWithShallow = function (defaults, options, keys) {
+
+ exports.assert(defaults && typeof defaults === 'object', 'Invalid defaults value: must be an object');
+ exports.assert(!options || options === true || typeof options === 'object', 'Invalid options value: must be true, falsy or an object');
+ exports.assert(keys && Array.isArray(keys), 'Invalid keys');
+
+ if (!options) { // If no options, return null
+ return null;
+ }
+
+ const copy = exports.cloneWithShallow(defaults, keys);
+
+ if (options === true) { // If options is set to true, use defaults
+ return copy;
+ }
+
+ const storage = internals.store(options, keys); // Move shallow copy items to storage
+ exports.merge(copy, options, false, false); // Deep copy the rest
+ internals.restore(copy, options, storage); // Shallow copy the stored items and restore
+ return copy;
+};
+
+
+// Deep object or array comparison
+
+exports.deepEqual = function (obj, ref, options, seen) {
+
+ options = options || { prototype: true };
+
+ const type = typeof obj;
+
+ if (type !== typeof ref) {
+ return false;
+ }
+
+ if (type !== 'object' ||
+ obj === null ||
+ ref === null) {
+
+ if (obj === ref) { // Copied from Deep-eql, copyright(c) 2013 Jake Luer, [email protected], MIT Licensed, https://github.com/chaijs/deep-eql
+ return obj !== 0 || 1 / obj === 1 / ref; // -0 / +0
+ }
+
+ return obj !== obj && ref !== ref; // NaN
+ }
+
+ seen = seen || [];
+ if (seen.indexOf(obj) !== -1) {
+ return true; // If previous comparison failed, it would have stopped execution
+ }
+
+ seen.push(obj);
+
+ if (Array.isArray(obj)) {
+ if (!Array.isArray(ref)) {
+ return false;
+ }
+
+ if (!options.part && obj.length !== ref.length) {
+ return false;
+ }
+
+ for (let i = 0; i < obj.length; ++i) {
+ if (options.part) {
+ let found = false;
+ for (let j = 0; j < ref.length; ++j) {
+ if (exports.deepEqual(obj[i], ref[j], options)) {
+ found = true;
+ break;
+ }
+ }
+
+ return found;
+ }
+
+ if (!exports.deepEqual(obj[i], ref[i], options)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ if (Buffer.isBuffer(obj)) {
+ if (!Buffer.isBuffer(ref)) {
+ return false;
+ }
+
+ if (obj.length !== ref.length) {
+ return false;
+ }
+
+ for (let i = 0; i < obj.length; ++i) {
+ if (obj[i] !== ref[i]) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ if (obj instanceof Date) {
+ return (ref instanceof Date && obj.getTime() === ref.getTime());
+ }
+
+ if (obj instanceof RegExp) {
+ return (ref instanceof RegExp && obj.toString() === ref.toString());
+ }
+
+ if (options.prototype) {
+ if (Object.getPrototypeOf(obj) !== Object.getPrototypeOf(ref)) {
+ return false;
+ }
+ }
+
+ const keys = Object.getOwnPropertyNames(obj);
+
+ if (!options.part && keys.length !== Object.getOwnPropertyNames(ref).length) {
+ return false;
+ }
+
+ for (let i = 0; i < keys.length; ++i) {
+ const key = keys[i];
+ const descriptor = Object.getOwnPropertyDescriptor(obj, key);
+ if (descriptor.get) {
+ if (!exports.deepEqual(descriptor, Object.getOwnPropertyDescriptor(ref, key), options, seen)) {
+ return false;
+ }
+ }
+ else if (!exports.deepEqual(obj[key], ref[key], options, seen)) {
+ return false;
+ }
+ }
+
+ return true;
+};
+
+
+// Remove duplicate items from array
+
+exports.unique = (array, key) => {
+
+ let result;
+ if (key) {
+ result = [];
+ const index = new Set();
+ array.forEach((item) => {
+
+ const identifier = item[key];
+ if (!index.has(identifier)) {
+ index.add(identifier);
+ result.push(item);
+ }
+ });
+ }
+ else {
+ result = Array.from(new Set(array));
+ }
+
+ return result;
+};
+
+
+// Convert array into object
+
+exports.mapToObject = function (array, key) {
+
+ if (!array) {
+ return null;
+ }
+
+ const obj = {};
+ for (let i = 0; i < array.length; ++i) {
+ if (key) {
+ if (array[i][key]) {
+ obj[array[i][key]] = true;
+ }
+ }
+ else {
+ obj[array[i]] = true;
+ }
+ }
+
+ return obj;
+};
+
+
+// Find the common unique items in two arrays
+
+exports.intersect = function (array1, array2, justFirst) {
+
+ if (!array1 || !array2) {
+ return [];
+ }
+
+ const common = [];
+ const hash = (Array.isArray(array1) ? exports.mapToObject(array1) : array1);
+ const found = {};
+ for (let i = 0; i < array2.length; ++i) {
+ if (hash[array2[i]] && !found[array2[i]]) {
+ if (justFirst) {
+ return array2[i];
+ }
+
+ common.push(array2[i]);
+ found[array2[i]] = true;
+ }
+ }
+
+ return (justFirst ? null : common);
+};
+
+
+// Test if the reference contains the values
+
+exports.contain = function (ref, values, options) {
+
+ /*
+ string -> string(s)
+ array -> item(s)
+ object -> key(s)
+ object -> object (key:value)
+ */
+
+ let valuePairs = null;
+ if (typeof ref === 'object' &&
+ typeof values === 'object' &&
+ !Array.isArray(ref) &&
+ !Array.isArray(values)) {
+
+ valuePairs = values;
+ values = Object.keys(values);
+ }
+ else {
+ values = [].concat(values);
+ }
+
+ options = options || {}; // deep, once, only, part
+
+ exports.assert(arguments.length >= 2, 'Insufficient arguments');
+ exports.assert(typeof ref === 'string' || typeof ref === 'object', 'Reference must be string or an object');
+ exports.assert(values.length, 'Values array cannot be empty');
+
+ let compare;
+ let compareFlags;
+ if (options.deep) {
+ compare = exports.deepEqual;
+
+ const hasOnly = options.hasOwnProperty('only');
+ const hasPart = options.hasOwnProperty('part');
+
+ compareFlags = {
+ prototype: hasOnly ? options.only : hasPart ? !options.part : false,
+ part: hasOnly ? !options.only : hasPart ? options.part : true
+ };
+ }
+ else {
+ compare = (a, b) => a === b;
+ }
+
+ let misses = false;
+ const matches = new Array(values.length);
+ for (let i = 0; i < matches.length; ++i) {
+ matches[i] = 0;
+ }
+
+ if (typeof ref === 'string') {
+ let pattern = '(';
+ for (let i = 0; i < values.length; ++i) {
+ const value = values[i];
+ exports.assert(typeof value === 'string', 'Cannot compare string reference to non-string value');
+ pattern += (i ? '|' : '') + exports.escapeRegex(value);
+ }
+
+ const regex = new RegExp(pattern + ')', 'g');
+ const leftovers = ref.replace(regex, ($0, $1) => {
+
+ const index = values.indexOf($1);
+ ++matches[index];
+ return ''; // Remove from string
+ });
+
+ misses = !!leftovers;
+ }
+ else if (Array.isArray(ref)) {
+ for (let i = 0; i < ref.length; ++i) {
+ let matched = false;
+ for (let j = 0; j < values.length && matched === false; ++j) {
+ matched = compare(values[j], ref[i], compareFlags) && j;
+ }
+
+ if (matched !== false) {
+ ++matches[matched];
+ }
+ else {
+ misses = true;
+ }
+ }
+ }
+ else {
+ const keys = Object.getOwnPropertyNames(ref);
+ for (let i = 0; i < keys.length; ++i) {
+ const key = keys[i];
+ const pos = values.indexOf(key);
+ if (pos !== -1) {
+ if (valuePairs &&
+ !compare(valuePairs[key], ref[key], compareFlags)) {
+
+ return false;
+ }
+
+ ++matches[pos];
+ }
+ else {
+ misses = true;
+ }
+ }
+ }
+
+ let result = false;
+ for (let i = 0; i < matches.length; ++i) {
+ result = result || !!matches[i];
+ if ((options.once && matches[i] > 1) ||
+ (!options.part && !matches[i])) {
+
+ return false;
+ }
+ }
+
+ if (options.only &&
+ misses) {
+
+ return false;
+ }
+
+ return result;
+};
+
+
+// Flatten array
+
+exports.flatten = function (array, target) {
+
+ const result = target || [];
+
+ for (let i = 0; i < array.length; ++i) {
+ if (Array.isArray(array[i])) {
+ exports.flatten(array[i], result);
+ }
+ else {
+ result.push(array[i]);
+ }
+ }
+
+ return result;
+};
+
+
+// Convert an object key chain string ('a.b.c') to reference (object[a][b][c])
+
+exports.reach = function (obj, chain, options) {
+
+ if (chain === false ||
+ chain === null ||
+ typeof chain === 'undefined') {
+
+ return obj;
+ }
+
+ options = options || {};
+ if (typeof options === 'string') {
+ options = { separator: options };
+ }
+
+ const path = chain.split(options.separator || '.');
+ let ref = obj;
+ for (let i = 0; i < path.length; ++i) {
+ let key = path[i];
+ if (key[0] === '-' && Array.isArray(ref)) {
+ key = key.slice(1, key.length);
+ key = ref.length - key;
+ }
+
+ if (!ref ||
+ !((typeof ref === 'object' || typeof ref === 'function') && key in ref) ||
+ (typeof ref !== 'object' && options.functions === false)) { // Only object and function can have properties
+
+ exports.assert(!options.strict || i + 1 === path.length, 'Missing segment', key, 'in reach path ', chain);
+ exports.assert(typeof ref === 'object' || options.functions === true || typeof ref !== 'function', 'Invalid segment', key, 'in reach path ', chain);
+ ref = options.default;
+ break;
+ }
+
+ ref = ref[key];
+ }
+
+ return ref;
+};
+
+
+exports.reachTemplate = function (obj, template, options) {
+
+ return template.replace(/{([^}]+)}/g, ($0, chain) => {
+
+ const value = exports.reach(obj, chain, options);
+ return (value === undefined || value === null ? '' : value);
+ });
+};
+
+
+exports.formatStack = function (stack) {
+
+ const trace = [];
+ for (let i = 0; i < stack.length; ++i) {
+ const item = stack[i];
+ trace.push([item.getFileName(), item.getLineNumber(), item.getColumnNumber(), item.getFunctionName(), item.isConstructor()]);
+ }
+
+ return trace;
+};
+
+
+exports.formatTrace = function (trace) {
+
+ const display = [];
+
+ for (let i = 0; i < trace.length; ++i) {
+ const row = trace[i];
+ display.push((row[4] ? 'new ' : '') + row[3] + ' (' + row[0] + ':' + row[1] + ':' + row[2] + ')');
+ }
+
+ return display;
+};
+
+
+exports.callStack = function (slice) {
+
+ // http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
+
+ const v8 = Error.prepareStackTrace;
+ Error.prepareStackTrace = function (_, stack) {
+
+ return stack;
+ };
+
+ const capture = {};
+ Error.captureStackTrace(capture, this); // arguments.callee is not supported in strict mode so we use this and slice the trace of this off the result
+ const stack = capture.stack;
+
+ Error.prepareStackTrace = v8;
+
+ const trace = exports.formatStack(stack);
+
+ return trace.slice(1 + slice);
+};
+
+
+exports.displayStack = function (slice) {
+
+ const trace = exports.callStack(slice === undefined ? 1 : slice + 1);
+
+ return exports.formatTrace(trace);
+};
+
+
+exports.abortThrow = false;
+
+
+exports.abort = function (message, hideStack) {
+
+ if (process.env.NODE_ENV === 'test' || exports.abortThrow === true) {
+ throw new Error(message || 'Unknown error');
+ }
+
+ let stack = '';
+ if (!hideStack) {
+ stack = exports.displayStack(1).join('\n\t');
+ }
+ console.log('ABORT: ' + message + '\n\t' + stack);
+ process.exit(1);
+};
+
+
+exports.assert = function (condition /*, msg1, msg2, msg3 */) {
+
+ if (condition) {
+ return;
+ }
+
+ if (arguments.length === 2 && arguments[1] instanceof Error) {
+ throw arguments[1];
+ }
+
+ let msgs = [];
+ for (let i = 1; i < arguments.length; ++i) {
+ if (arguments[i] !== '') {
+ msgs.push(arguments[i]); // Avoids Array.slice arguments leak, allowing for V8 optimizations
+ }
+ }
+
+ msgs = msgs.map((msg) => {
+
+ return typeof msg === 'string' ? msg : msg instanceof Error ? msg.message : exports.stringify(msg);
+ });
+
+ throw new Error(msgs.join(' ') || 'Unknown error');
+};
+
+
+exports.Timer = function () {
+
+ this.ts = 0;
+ this.reset();
+};
+
+
+exports.Timer.prototype.reset = function () {
+
+ this.ts = Date.now();
+};
+
+
+exports.Timer.prototype.elapsed = function () {
+
+ return Date.now() - this.ts;
+};
+
+
+exports.Bench = function () {
+
+ this.ts = 0;
+ this.reset();
+};
+
+
+exports.Bench.prototype.reset = function () {
+
+ this.ts = exports.Bench.now();
+};
+
+
+exports.Bench.prototype.elapsed = function () {
+
+ return exports.Bench.now() - this.ts;
+};
+
+
+exports.Bench.now = function () {
+
+ const ts = process.hrtime();
+ return (ts[0] * 1e3) + (ts[1] / 1e6);
+};
+
+
+// Escape string for Regex construction
+
+exports.escapeRegex = function (string) {
+
+ // Escape ^$.*+-?=!:|\/()[]{},
+ return string.replace(/[\^\$\.\*\+\-\?\=\!\:\|\\\/\(\)\[\]\{\}\,]/g, '\\$&');
+};
+
+
+// Base64url (RFC 4648) encode
+
+exports.base64urlEncode = function (value, encoding) {
+
+ exports.assert(typeof value === 'string' || Buffer.isBuffer(value), 'value must be string or buffer');
+ const buf = (Buffer.isBuffer(value) ? value : new Buffer(value, encoding || 'binary'));
+ return buf.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
+};
+
+
+// Base64url (RFC 4648) decode
+
+exports.base64urlDecode = function (value, encoding) {
+
+ if (typeof value !== 'string') {
+
+ return new Error('Value not a string');
+ }
+
+ if (!/^[\w\-]*$/.test(value)) {
+
+ return new Error('Invalid character');
+ }
+
+ const buf = new Buffer(value, 'base64');
+ return (encoding === 'buffer' ? buf : buf.toString(encoding || 'binary'));
+};
+
+
+// Escape attribute value for use in HTTP header
+
+exports.escapeHeaderAttribute = function (attribute) {
+
+ // Allowed value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9, \, "
+
+ exports.assert(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~\"\\]*$/.test(attribute), 'Bad attribute value (' + attribute + ')');
+
+ return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"'); // Escape quotes and slash
+};
+
+
+exports.escapeHtml = function (string) {
+
+ return Escape.escapeHtml(string);
+};
+
+
+exports.escapeJavaScript = function (string) {
+
+ return Escape.escapeJavaScript(string);
+};
+
+exports.escapeJson = function (string) {
+
+ return Escape.escapeJson(string);
+};
+
+exports.nextTick = function (callback) {
+
+ return function () {
+
+ const args = arguments;
+ process.nextTick(() => {
+
+ callback.apply(null, args);
+ });
+ };
+};
+
+
+exports.once = function (method) {
+
+ if (method._hoekOnce) {
+ return method;
+ }
+
+ let once = false;
+ const wrapped = function () {
+
+ if (!once) {
+ once = true;
+ method.apply(null, arguments);
+ }
+ };
+
+ wrapped._hoekOnce = true;
+
+ return wrapped;
+};
+
+
+exports.isInteger = Number.isSafeInteger;
+
+
+exports.ignore = function () { };
+
+
+exports.inherits = Util.inherits;
+
+
+exports.format = Util.format;
+
+
+exports.transform = function (source, transform, options) {
+
+ exports.assert(source === null || source === undefined || typeof source === 'object' || Array.isArray(source), 'Invalid source object: must be null, undefined, an object, or an array');
+ const separator = (typeof options === 'object' && options !== null) ? (options.separator || '.') : '.';
+
+ if (Array.isArray(source)) {
+ const results = [];
+ for (let i = 0; i < source.length; ++i) {
+ results.push(exports.transform(source[i], transform, options));
+ }
+ return results;
+ }
+
+ const result = {};
+ const keys = Object.keys(transform);
+
+ for (let i = 0; i < keys.length; ++i) {
+ const key = keys[i];
+ const path = key.split(separator);
+ const sourcePath = transform[key];
+
+ exports.assert(typeof sourcePath === 'string', 'All mappings must be "." delineated strings');
+
+ let segment;
+ let res = result;
+
+ while (path.length > 1) {
+ segment = path.shift();
+ if (!res[segment]) {
+ res[segment] = {};
+ }
+ res = res[segment];
+ }
+ segment = path.shift();
+ res[segment] = exports.reach(source, sourcePath, options);
+ }
+
+ return result;
+};
+
+
+exports.uniqueFilename = function (path, extension) {
+
+ if (extension) {
+ extension = extension[0] !== '.' ? '.' + extension : extension;
+ }
+ else {
+ extension = '';
+ }
+
+ path = Path.resolve(path);
+ const name = [Date.now(), process.pid, Crypto.randomBytes(8).toString('hex')].join('-') + extension;
+ return Path.join(path, name);
+};
+
+
+exports.stringify = function () {
+
+ try {
+ return JSON.stringify.apply(null, arguments);
+ }
+ catch (err) {
+ return '[Cannot display object: ' + err.message + ']';
+ }
+};
+
+
+exports.shallow = function (source) {
+
+ const target = {};
+ const keys = Object.keys(source);
+ for (let i = 0; i < keys.length; ++i) {
+ const key = keys[i];
+ target[key] = source[key];
+ }
+
+ return target;
+};