🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Sign inDemoInstall
Socket

@commercial/hoek

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@commercial/hoek - npm Package Compare versions

Comparing version

to
8.5.0

lib/applyToDefaults.js

500

lib/index.d.ts

@@ -1,12 +0,15 @@

/**
Performs a deep comparison of the two values including support for circular dependencies, prototype, and enumerable properties.
/// <reference types="node" />
@param obj - The value being compared.
@param ref - The reference value used for comparison.
@return true when the two values are equal, otherwise false.
/**
* Performs a deep comparison of the two values including support for circular dependencies, prototype, and enumerable properties.
*
* @param obj - The value being compared.
* @param ref - The reference value used for comparison.
*
* @return true when the two values are equal, otherwise false.
*/
export function deepEqual(obj: any, ref: any, options?: deepEqual.Options): boolean;
declare namespace deepEqual {
export namespace deepEqual {

@@ -16,20 +19,34 @@ interface Options {

/**
Allow partial match.
* Compare functions with difference references by comparing their internal code and properties.
*
* @default false
*/
readonly deepFunction?: boolean;
@default false
*/
/**
* Allow partial match.
*
* @default false
*/
readonly part?: boolean;
/**
Compare the objects' prototypes.
@default true
*/
* Compare the objects' prototypes.
*
* @default true
*/
readonly prototype?: boolean;
/**
Compare symbol properties.
* List of object keys to ignore different values of.
*
* @default null
*/
readonly skip?: (string | symbol)[];
@default false
*/
/**
* Compare symbol properties.
*
* @default true
*/
readonly symbols?: boolean;

@@ -41,12 +58,12 @@ }

/**
Clone any value, object, or array.
@param obj - The value being cloned.
@param options - The second number to add.
@returns A deep clone of `obj`.
*/
* Clone any value, object, or array.
*
* @param obj - The value being cloned.
* @param options - Optional settings.
*
* @returns A deep clone of `obj`.
*/
export function clone<T>(obj: T, options?: clone.Options): T;
declare namespace clone {
export namespace clone {

@@ -56,14 +73,21 @@ interface Options {

/**
Clone the object's prototype.
@default true
*/
* Clone the object's prototype.
*
* @default true
*/
readonly prototype?: boolean;
/**
Include symbol properties.
* Include symbol properties.
*
* @default true
*/
readonly symbols?: boolean;
@default false
*/
readonly symbols?: boolean;
/**
* Shallow clone the specified keys.
*
* @default undefined
*/
readonly shallow?: string[] | string[][] | boolean;
}

@@ -74,64 +98,97 @@ }

/**
Merge all the properties of source into target.
* Merge all the properties of source into target.
*
* @param target - The object being modified.
* @param source - The object used to copy properties from.
* @param options - Optional settings.
*
* @returns The `target` object.
*/
export function merge<T1 extends object, T2 extends object>(target: T1, source: T2, options?: merge.Options): T1 & T2;
@param target - The object being modified.
@param source - The object used to copy properties from.
@param isNullOverride - When true, null value from `source` overrides existing value in `target`. Defaults to true.
@param isMergeArrays - When true, array value from `source` is merged with the existing value in `target`. Defaults to true.
export namespace merge {
@returns The `target` object.
*/
export function merge<T1 extends object, T2 extends object>(target: T1, source: T2, isNullOverride?: boolean, isMergeArrays?: boolean): T1 & T2;
interface Options {
/**
* When true, null value from `source` overrides existing value in `target`.
*
* @default true
*/
readonly nullOverride?: boolean;
/**
Apply options to a copy of the defaults.
/**
* When true, array value from `source` is merged with the existing value in `target`.
*
* @default false
*/
readonly mergeArrays?: boolean;
@param defaults - An object with the default values to use of `options` does not contain the same keys.
@param options - The options used to override the `defaults`.
@param isNullOverride - When true, null value from `options` overrides existing value in `defaults`. Defaults to false.
/**
* Compare symbol properties.
*
* @default true
*/
readonly symbols?: boolean;
}
}
@returns A copy of `defaults` with `options` keys overriding any conflicts.
*/
export function applyToDefaults<T extends object>(defaults: Partial<T>, options: Partial<T> | boolean | null, isNullOverride?: boolean): Partial<T>;
/**
Clone an object or array with specific keys shallowly cloned.
* Apply source to a copy of the defaults.
*
* @param defaults - An object with the default values to use of `options` does not contain the same keys.
* @param source - The source used to override the `defaults`.
* @param options - Optional settings.
*
* @returns A copy of `defaults` with `source` keys overriding any conflicts.
*/
export function applyToDefaults<T extends object>(defaults: Partial<T>, source: Partial<T> | boolean | null, options?: applyToDefaults.Options): Partial<T>;
@param obj - The object being cloned.
@param keys - An array of string keys indicating which `obj` properties to shallow copy instead of deep clone. Use dot-notation to indicate nested keys (e.g. "a.b").
export namespace applyToDefaults {
@returns A deep clone of `obj` with the requested `keys` shallowly cloned.
*/
export function cloneWithShallow<T>(obj: T, keys: string[], options?: clone.Options): T;
interface Options {
/**
* When true, null value from `source` overrides existing value in `target`.
*
* @default true
*/
readonly nullOverride?: boolean;
/**
Apply options to a copy of the defaults with specific keys shallowly cloned.
/**
* Shallow clone the specified keys.
*
* @default undefined
*/
readonly shallow?: string[] | string[][];
}
}
@param defaults - An object with the default values to use of `options` does not contain the same keys.
@param options - The options used to override the `defaults`.
@param keys - An array of string keys indicating which `options` properties to shallow copy instead of deep clone. Use dot-notation to indicate nested keys (e.g. "a.b").
@returns A copy of `defaults` with `options` keys overriding any conflicts.
*/
export function applyToDefaultsWithShallow<T extends object>(defaults: Partial<T>, options: Partial<T> | boolean | null, keys: string[]): Partial<T>;
/**
Find the common unique items in two arrays.
* Find the common unique items in two arrays.
*
* @param array1 - The first array to compare.
* @param array2 - The second array to compare.
* @param options - Optional settings.
*
* @return - An array of the common items. If `justFirst` is true, returns the first common item.
*/
export function intersect<T1, T2>(array1: intersect.Array<T1>, array2: intersect.Array<T2>, options?: intersect.Options): Array<T1 | T2>;
export function intersect<T1, T2>(array1: intersect.Array<T1>, array2: intersect.Array<T2>, options?: intersect.Options): T1 | T2;
@param array1 - The first array to compare.
@param array2 - The second array to compare.
@param justFirst - If true, return the first overlapping value. Defaults to false.
export namespace intersect {
@return - An array of the common items. If `justFirst` is true, returns the first common item.
*/
export function intersect<T1, T2>(array1: intersect.Array<T1>, array2: intersect.Array<T2>, justFirst?: false): Array<T1 | T2>;
export function intersect<T1, T2>(array1: intersect.Array<T1>, array2: intersect.Array<T2>, justFirst: true): T1 | T2;
type Array<T> = ArrayLike<T> | Set<T> | null;
declare namespace intersect {
interface Options {
type Array<T> = ArrayLike<T> | Set<T> | null;
/**
* When true, return the first overlapping value.
*
* @default false
*/
readonly first?: boolean;
}
}

@@ -141,14 +198,14 @@

/**
Checks if the reference value contains the provided values.
@param ref - The reference string, array, or object.
@param values - A single or array of values to find within `ref`. If `ref` is an object, `values` can be a key name, an array of key names, or an object with key-value pairs to compare.
@return true if the value contains the provided values, otherwise false.
*/
* Checks if the reference value contains the provided values.
*
* @param ref - The reference string, array, or object.
* @param values - A single or array of values to find within `ref`. If `ref` is an object, `values` can be a key name, an array of key names, or an object with key-value pairs to compare.
*
* @return true if the value contains the provided values, otherwise false.
*/
export function contain(ref: string, values: string | string[], options?: contain.Options): boolean;
export function contain(ref: any[], values: any, options?: contain.Options): boolean;
export function contain(ref: object, values: string | string[] | object, options?: contain.Options): boolean;
export function contain(ref: object, values: string | string[] | object, options?: Omit<contain.Options, 'once'>): boolean;
declare namespace contain {
export namespace contain {

@@ -158,34 +215,34 @@ interface Options {

/**
Perform a deep comparison.
@default false
*/
* Perform a deep comparison.
*
* @default false
*/
readonly deep?: boolean;
/**
Allow only one occurrence of each value.
@default false
*/
* Allow only one occurrence of each value.
*
* @default false
*/
readonly once?: boolean;
/**
Allow only values explicitly listed.
@default false
*/
* Allow only values explicitly listed.
*
* @default false
*/
readonly only?: boolean;
/**
Allow partial match.
@default false
*/
* Allow partial match.
*
* @default false
*/
readonly part?: boolean;
/**
Include symbol properties.
@default false
*/
* Include symbol properties.
*
* @default true
*/
readonly symbols?: boolean;

@@ -197,9 +254,9 @@ }

/**
Flatten an array with sub arrays
@param array - an array of items or other arrays to flatten.
@param target - if provided, an array to shallow copy the flattened `array` items to
@return a flat array of the provided values (appended to `target` is provided).
*/
* Flatten an array with sub arrays
*
* @param array - an array of items or other arrays to flatten.
* @param target - if provided, an array to shallow copy the flattened `array` items to
*
* @return a flat array of the provided values (appended to `target` is provided).
*/
export function flatten<T>(array: ArrayLike<T | ReadonlyArray<T>>, target?: ArrayLike<T | ReadonlyArray<T>>): T[];

@@ -209,12 +266,12 @@

/**
Convert an object key chain string to reference.
@param obj - the object from which to look up the value.
@param chain - the string path of the requested value. The chain string is split into key names using `options.separator`, or an array containing each individual key name. A chain including negative numbers will work like negative indices on an array.
@return The value referenced by the chain if found, otherwise undefined. If chain is null, undefined, or false, the object itself will be returned.
*/
* Convert an object key chain string to reference.
*
* @param obj - the object from which to look up the value.
* @param chain - the string path of the requested value. The chain string is split into key names using `options.separator`, or an array containing each individual key name. A chain including negative numbers will work like a negative index on an array.
*
* @return The value referenced by the chain if found, otherwise undefined. If chain is null, undefined, or false, the object itself will be returned.
*/
export function reach(obj: object | null, chain: string | (string | number)[] | false | null | undefined, options?: reach.Options): any;
declare namespace reach {
export namespace reach {

@@ -224,28 +281,35 @@ interface Options {

/**
String to split chain path on. Defaults to '.'.
@default false
*/
* String to split chain path on. Defaults to '.'.
*
* @default false
*/
readonly separator?: string;
/**
Value to return if the path or value is not present. No default value.
@default false
*/
* Value to return if the path or value is not present. No default value.
*
* @default false
*/
readonly default?: any;
/**
If true, will throw an error on missing member in the chain. Default to false.
@default false
*/
* If true, will throw an error on missing member in the chain. Default to false.
*
* @default false
*/
readonly strict?: boolean;
/**
If true, allows traversing functions for properties. false will throw an error if a function is part of the chain.
* If true, allows traversing functions for properties. false will throw an error if a function is part of the chain.
*
* @default true
*/
readonly functions?: boolean;
@default false
*/
readonly functions?: boolean;
/**
* If true, allows traversing Set and Map objects for properties. false will return undefined regardless of the Set or Map passed.
*
* @default false
*/
readonly iterables?: boolean;
}

@@ -256,9 +320,9 @@ }

/**
Replace string parameters (using format "{path.to.key}") with their corresponding object key values using `Hoek.reach()`.
@param obj - the object from which to look up the value.
@param template - the string containing {} enclosed key paths to be replaced.
@return The template string with the {} enclosed keys replaced with looked-up values.
*/
* Replace string parameters (using format "{path.to.key}") with their corresponding object key values using `Hoek.reach()`.
*
* @param obj - the object from which to look up the value.
* @param template - the string containing {} enclosed key paths to be replaced.
*
* @return The template string with the {} enclosed keys replaced with looked-up values.
*/
export function reachTemplate(obj: object | null, template: string, options?: reach.Options): string;

@@ -268,9 +332,9 @@

/**
Throw an error if condition is falsey.
@param condition - If `condition` is not truthy, an exception is thrown.
@param error - The error thrown if the condition fails.
@return Does not return a value but throws if the `condition` is falsey.
*/
* Throw an error if condition is falsy.
*
* @param condition - If `condition` is not truthy, an exception is thrown.
* @param error - The error thrown if the condition fails.
*
* @return Does not return a value but throws if the `condition` is falsy.
*/
export function assert(condition: any, error: Error): void;

@@ -280,9 +344,9 @@

/**
Throw an error if condition is falsey.
@param condition - If `condition` is not truthy, an exception is thrown.
@param args - Any number of values, concatenated together (space separated) to create the error message.
@return Does not return a value but throws if the `condition` is falsey.
*/
* Throw an error if condition is falsy.
*
* @param condition - If `condition` is not truthy, an exception is thrown.
* @param args - Any number of values, concatenated together (space separated) to create the error message.
*
* @return Does not return a value but throws if the `condition` is falsy.
*/
export function assert(condition: any, ...args: any): void;

@@ -292,3 +356,3 @@

/**
A benchmarking timer, using the internal node clock for maximum accuracy.
* A benchmarking timer, using the internal node clock for maximum accuracy.
*/

@@ -314,8 +378,8 @@ export class Bench {

/**
Escape string for Regex construction by prefixing all reserved characters with a backslash.
@param string - The string to be escaped.
@return The escaped string.
*/
* Escape string for Regex construction by prefixing all reserved characters with a backslash.
*
* @param string - The string to be escaped.
*
* @return The escaped string.
*/
export function escapeRegex(string: string): string;

@@ -325,8 +389,8 @@

/**
Escape string for usage as an attribute value in HTTP headers.
@param attribute - The string to be escaped.
@return The escaped string. Will throw on invalid characters that are not supported to be escaped.
*/
* Escape string for usage as an attribute value in HTTP headers.
*
* @param attribute - The string to be escaped.
*
* @return The escaped string. Will throw on invalid characters that are not supported to be escaped.
*/
export function escapeHeaderAttribute(attribute: string): string;

@@ -336,8 +400,8 @@

/**
Escape string for usage in HTML.
@param string - The string to be escaped.
@return The escaped string.
*/
* Escape string for usage in HTML.
*
* @param string - The string to be escaped.
*
* @return The escaped string.
*/
export function escapeHtml(string: string): string;

@@ -347,8 +411,8 @@

/**
Escape string for usage in JSON.
@param string - The string to be escaped.
@return The escaped string.
*/
* Escape string for usage in JSON.
*
* @param string - The string to be escaped.
*
* @return The escaped string.
*/
export function escapeJson(string: string): string;

@@ -358,7 +422,7 @@

/**
Wraps a function to ensure it can only execute once.
@param method - The function to be wrapped.
@return The wrapped function.
* Wraps a function to ensure it can only execute once.
*
* @param method - The function to be wrapped.
*
* @return The wrapped function.
*/

@@ -369,4 +433,4 @@ export function once<T extends Function>(method: T): T;

/**
A reusable no-op function.
*/
* A reusable no-op function.
*/
export function ignore(...ignore: any): void;

@@ -376,37 +440,51 @@

/**
Generate a random file name within a given path and optional extension.
* Converts a JavaScript value to a JavaScript Object Notation (JSON) string with protection against thrown errors.
*
* @param value A JavaScript value, usually an object or array, to be converted.
* @param replacer The JSON.stringify() `replacer` argument.
* @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.
*
* @return The JSON string. If the operation fails, an error string value is returned (no exception thrown).
*/
export function stringify(value: any, replacer?: any, space?: string | number): string;
@param path - The file path within to generate a temporary file.
@param extension - File extension.
@return The generarted filename.
*/
export function uniqueFilename(path: string, extension?: string): string;
/**
* Returns a Promise that resolves after the requested timeout.
*
* @param timeout - The number of milliseconds to wait before resolving the Promise.
*
* @return A Promise.
*/
export function wait(timeout?: number): Promise<void>;
/**
Converts a JavaScript value to a JavaScript Object Notation (JSON) string with protection against thrown errors.
* Returns a Promise that never resolves.
*/
export function block(): Promise<void>;
@param value A JavaScript value, usually an object or array, to be converted.
@param replacer The JSON.stringify() `replacer` argument.
@param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.
@return The JSON string. If the operation fails, an error string value is returned (no exception thrown).
*/
export function stringify(value: any, replacer?: any, space?: string | number): string;
/**
* Determines if an object is a promise.
*
* @param promise - the object tested.
*
* @returns true if the object is a promise, otherwise false.
*/
export function isPromise(promise: any): boolean;
/**
Returns a Promise that resolves after the requested timeout.
export namespace ts {
@param timeout - The number of milliseconds to wait before resolving the Promise.
/**
* Defines a type that can must be one of T or U but not both.
*/
type XOR<T, U> = (T | U) extends object ? (internals.Without<T, U> & U) | (internals.Without<U, T> & T) : T | U;
}
@return A Promise.
*/
export function wait(timeout?: number): Promise<void>;
declare namespace internals {
/**
Returns a Promise that never resolves.
*/
export function block(): Promise<void>;
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
}
'use strict';
// Load modules
const internals = {};
const Assert = require('assert');
const Crypto = require('crypto');
const Path = require('path');
const DeepEqual = require('./deep-equal');
const Escape = require('./escape');
const Types = require('./types');
// Declare internals
const internals = {
needsProtoHack: new Set([Types.set, Types.map, Types.weakSet, Types.weakMap])
module.exports = {
applyToDefaults: require('./applyToDefaults'),
assert: require('./assert'),
Bench: require('./bench'),
block: require('./block'),
clone: require('./clone'),
contain: require('./contain'),
deepEqual: require('./deepEqual'),
Error: require('./error'),
escapeHeaderAttribute: require('./escapeHeaderAttribute'),
escapeHtml: require('./escapeHtml'),
escapeJson: require('./escapeJson'),
escapeRegex: require('./escapeRegex'),
flatten: require('./flatten'),
ignore: require('./ignore'),
intersect: require('./intersect'),
isPromise: require('./isPromise'),
merge: require('./merge'),
once: require('./once'),
reach: require('./reach'),
reachTemplate: require('./reachTemplate'),
stringify: require('./stringify'),
wait: require('./wait')
};
// Deep object or array comparison
exports.deepEqual = DeepEqual;
// Clone object or array
exports.clone = function (obj, options = {}, _seen = null) {
if (typeof obj !== 'object' ||
obj === null) {
return obj;
}
const seen = _seen || new Map();
const lookup = seen.get(obj);
if (lookup) {
return lookup;
}
const baseProto = Types.getInternalProto(obj);
let newObj;
switch (baseProto) {
case Types.buffer:
return Buffer.from(obj);
case Types.date:
return new Date(obj.getTime());
case Types.regex:
return new RegExp(obj);
case Types.array:
newObj = [];
break;
default:
if (options.prototype !== false) { // Defaults to true
const proto = Object.getPrototypeOf(obj);
if (proto &&
proto.isImmutable) {
return obj;
}
if (internals.needsProtoHack.has(baseProto)) {
newObj = new proto.constructor();
if (proto !== baseProto) {
Object.setPrototypeOf(newObj, proto);
}
}
else {
newObj = Object.create(proto);
}
}
else if (internals.needsProtoHack.has(baseProto)) {
newObj = new baseProto.constructor();
}
else {
newObj = {};
}
}
seen.set(obj, newObj); // Set seen, since obj could recurse
if (baseProto === Types.set) {
for (const value of obj) {
newObj.add(exports.clone(value, options, seen));
}
}
else if (baseProto === Types.map) {
for (const [key, value] of obj) {
newObj.set(key, exports.clone(value, options, seen));
}
}
const keys = internals.keys(obj, options);
for (let i = 0; i < keys.length; ++i) {
const key = keys[i];
if (baseProto === Types.array &&
key === 'length') {
continue;
}
const descriptor = Object.getOwnPropertyDescriptor(obj, key);
if (descriptor &&
(descriptor.get ||
descriptor.set)) {
Object.defineProperty(newObj, key, descriptor);
}
else {
Object.defineProperty(newObj, key, {
enumerable: descriptor ? descriptor.enumerable : true,
writable: true,
configurable: true,
value: exports.clone(obj[key], options, seen)
});
}
}
if (baseProto === Types.array) {
newObj.length = obj.length;
}
return newObj;
};
internals.keys = function (obj, options = {}) {
return options.symbols ? Reflect.ownKeys(obj) : Object.getOwnPropertyNames(obj);
};
// Merge all the properties of source into target, source wins in conflict, and by default null and undefined from source are applied
exports.merge = function (target, source, isNullOverride = true, isMergeArrays = true) {
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) {
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 = internals.keys(source);
for (let i = 0; i < keys.length; ++i) {
const key = keys[i];
if (key === '__proto__' ||
!Object.prototype.propertyIsEnumerable.call(source, key)) {
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) {
target[key] = value;
}
}
}
return target;
};
// Apply options to a copy of the defaults
exports.applyToDefaults = function (defaults, options, isNullOverride = false) {
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, false);
};
// Clone an object except for the listed keys which are shallow copied
exports.cloneWithShallow = function (source, keys, options) {
if (!source ||
typeof source !== 'object') {
return source;
}
const storage = internals.store(source, keys); // Move shallow copy items to storage
const copy = exports.clone(source, options); // 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 = new Map();
for (let i = 0; i < keys.length; ++i) {
const key = keys[i];
const value = exports.reach(source, key);
if (typeof value === 'object' ||
typeof value === 'function') {
storage.set(key, value);
internals.reachSet(source, key, undefined);
}
}
return storage;
};
internals.restore = function (copy, source, storage) {
for (const [key, value] of storage) {
internals.reachSet(copy, key, value);
internals.reachSet(source, key, value);
}
};
internals.reachSet = function (obj, key, value) {
const path = Array.isArray(key) ? key : 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;
};
// Find the common unique items in two arrays
exports.intersect = function (array1, array2, justFirst = false) {
if (!array1 ||
!array2) {
return (justFirst ? null : []);
}
const common = [];
const hash = (Array.isArray(array1) ? new Set(array1) : array1);
const found = new Set();
for (const value of array2) {
if (internals.has(hash, value) &&
!found.has(value)) {
if (justFirst) {
return value;
}
common.push(value);
found.add(value);
}
}
return (justFirst ? null : common);
};
internals.has = function (ref, key) {
if (typeof ref.has === 'function') {
return ref.has(key);
}
return ref[key] !== undefined;
};
// Test if the reference contains the values
exports.contain = function (ref, values, options = {}) { // options: { deep, once, only, part, symbols }
/*
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;
const symbols = Object.getOwnPropertySymbols(values).filter(Object.prototype.propertyIsEnumerable.bind(values));
values = [...Object.keys(values), ...symbols];
}
else {
values = [].concat(values);
}
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.only !== undefined;
const hasPart = options.part !== undefined;
compareFlags = {
prototype: hasOnly ? options.only : hasPart ? !options.part : false,
part: hasOnly ? !options.only : hasPart ? options.part : false
};
}
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)) {
const onlyOnce = !!(options.only && options.once);
if (onlyOnce && ref.length !== values.length) {
return false;
}
for (let i = 0; i < ref.length; ++i) {
let matched = false;
for (let j = 0; j < values.length && matched === false; ++j) {
if (!onlyOnce || matches[j] === 0) {
matched = compare(values[j], ref[i], compareFlags) && j;
}
}
if (matched !== false) {
++matches[matched];
}
else {
misses = true;
}
}
}
else {
const keys = internals.keys(ref, options);
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;
}
}
}
if (options.only) {
if (misses || !options.once) {
return !misses;
}
}
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;
}
}
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 ||
chain === undefined) {
return obj;
}
options = options || {};
if (typeof options === 'string') {
options = { separator: options };
}
const isChainArray = Array.isArray(chain);
exports.assert(!isChainArray || !options.separator, 'Separator option no valid for array-based chain');
const path = isChainArray ? chain : chain.split(options.separator || '.');
let ref = obj;
for (let i = 0; i < path.length; ++i) {
let key = path[i];
if (Array.isArray(ref)) {
const number = Number(key);
if (Number.isInteger(number) && number < 0) {
key = ref.length + number;
}
}
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.assert = function (condition, ...args) {
if (condition) {
return;
}
if (args.length === 1 && args[0] instanceof Error) {
throw args[0];
}
const msgs = args
.filter((arg) => arg !== '')
.map((arg) => {
return typeof arg === 'string' ? arg : arg instanceof Error ? arg.message : exports.stringify(arg);
});
throw new Assert.AssertionError({
message: msgs.join(' ') || 'Unknown error',
actual: false,
expected: true,
operator: '==',
stackStartFunction: exports.assert
});
};
exports.Bench = class {
constructor() {
this.ts = 0;
this.reset();
}
reset() {
this.ts = exports.Bench.now();
}
elapsed() {
return exports.Bench.now() - this.ts;
}
static now() {
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, '\\$&');
};
// 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.escapeJson = function (string) {
return Escape.escapeJson(string);
};
exports.once = function (method) {
if (method._hoekOnce) {
return method;
}
let once = false;
const wrapped = function (...args) {
if (!once) {
once = true;
method(...args);
}
};
wrapped._hoekOnce = true;
return wrapped;
};
exports.ignore = function () { };
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 (...args) {
try {
return JSON.stringify.apply(null, args);
}
catch (err) {
return '[Cannot display object: ' + err.message + ']';
}
};
exports.wait = function (timeout) {
return new Promise((resolve) => setTimeout(resolve, timeout));
};
exports.block = function () {
return new Promise(exports.ignore);
};

@@ -8,3 +8,3 @@ 'use strict';

array: Array.prototype,
buffer: Buffer.prototype,
buffer: Buffer && Buffer.prototype, // $lab:coverage:ignore$
date: Date.prototype,

@@ -38,3 +38,3 @@ error: Error.prototype,

if (obj instanceof Buffer) {
if (Buffer && obj instanceof Buffer) { // $lab:coverage:ignore$
return exports.buffer;

@@ -51,4 +51,8 @@ }

if (obj instanceof Error) {
return exports.error;
}
const objName = Object.prototype.toString.call(obj);
return internals.typeMap.get(objName) || exports.generic;
};
COMMERCIAL LICENSE
Copyright (c) 2019 Sideway Inc.
Copyright (c) 2019-2020 Sideway Inc.
This package requires a commercial license. You may not use, copy, or distribute it without first acquiring a commercial license from Sideway Inc. Using this software without a license is a violation of US and international law. To obtain a license, please contact [sales@sideway.com](mailto:sales@sideway.com).
This package requires a commercial license. You may not use, copy, or distribute it without first acquiring a commercial license from Sideway Inc. Using this software without a license is a violation of US and international law. To obtain a license, please contact sales@sideway.com.
This package contains code previously published under an open source license. You can find the previous materials and the terms under which they were originally published at: [https://github.com/hapijs/hoek/blob/master/LICENSE](https://github.com/hapijs/hoek/blob/master/LICENSE).
This package contains code previously published under an open source license. You can find the previous materials and the terms under which they were originally published at: https://github.com/hapijs/hoek/blob/master/LICENSE.
{
"name": "@commercial/hoek",
"description": "General purpose node utilities",
"version": "6.2.5",
"version": "8.5.0",
"repository": "git://github.com/hapijs/hoek",

@@ -6,0 +6,0 @@ "main": "lib/index.js",

@@ -1,18 +0,18 @@

<a href="http://hapijs.com"><img src="https://raw.githubusercontent.com/hapijs/assets/master/images/family.png" width="180px" align="right" /></a>
<a href="https://hapi.dev"><img src="https://raw.githubusercontent.com/hapijs/assets/master/images/family.png" width="180px" align="right" /></a>
# hoek
# @hapi/hoek
Utility methods for the hapi ecosystem. This module is not intended to solve every problem for
everyone, but rather as a central place to store hapi-specific methods. If you're looking for a
general purpose utility module, check out [lodash](https://github.com/lodash/lodash) or
[underscore](https://github.com/jashkenas/underscore).
#### Utility methods for the hapi ecosystem.
[![Build Status](https://secure.travis-ci.org/hapijs/hoek.svg)](http://travis-ci.org/hapijs/hoek)
**hoek** is part of the **hapi** ecosystem and was designed to work seamlessly with the [hapi web framework](https://hapi.dev) and its other components (but works great on its own or with other frameworks). If you are using a different web framework and find this module useful, check out [hapi](https://hapi.dev) – they work even better together.
## License
This module is not intended to solve every problem for everyone, but rather as a central place to store hapi-specific methods. If you're looking for a general purpose utility module, check out [lodash](https://github.com/lodash/lodash).
This version of the package requires a commercial license. You may not use, copy, or distribute it without first acquiring a commercial license from Sideway Inc. Using this software without a license is a violation of US and international law. To obtain a license, please contact [sales@sideway.com](mailto:sales@sideway.com). The open source version of this package can be found [here](https://github.com/hapijs/hoek).
### Visit the [hapi.dev](https://hapi.dev) Developer Portal for tutorials, documentation, and support
## Documentation
## Useful resources
[**API Reference**](API.md)
- [Documentation and API](https://hapi.dev/family/hoek/)
- [Version status](https://hapi.dev/resources/status/#hoek) (builds, dependencies, node versions, licenses, eol)
- [Project policies](https://hapi.dev/policies/)
- [Free and commercial support options](https://hapi.dev/support/)