@boost/common
Advanced tools
Comparing version 2.8.1 to 2.8.2
import { Blueprint, Predicates } from 'optimal'; | ||
import { Optionable } from './types'; | ||
export declare abstract class Contract<T extends object = {}> implements Optionable<T> { | ||
/** Validated and configured options. */ | ||
readonly options: Readonly<Required<T>>; | ||
@@ -10,7 +11,22 @@ constructor(options?: T); | ||
* Freeze and return the options object. | ||
* | ||
* ```ts | ||
* object.configure({ name: 'Boost' }); | ||
* | ||
* object.configure((prevOptions) => ({ | ||
* nestedObject: { | ||
* ...prevOptions.nestedObject, | ||
* some: 'value', | ||
* }, | ||
* })); | ||
* ``` | ||
*/ | ||
configure(options?: Partial<T> | ((options: Required<T>) => Partial<T>)): Readonly<Required<T>>; | ||
/** | ||
* Define an optimal blueprint in which to validate and build the | ||
* Define an `optimal` blueprint in which to validate and build the | ||
* options object passed to the constructor, or when manual setting. | ||
* | ||
* A boolean is passed as the 2nd argument to determine whether this is | ||
* validating on class instantiation (first time), or by calling | ||
* `configure()` (all other times). | ||
*/ | ||
@@ -17,0 +33,0 @@ abstract blueprint(predicates: Predicates, onConstruction?: boolean): Blueprint<object>; |
import { Blueprint } from 'optimal'; | ||
import { BlueprintFactory } from '../types'; | ||
/** | ||
* Can be used to generate a blueprint object for use within | ||
* [optimal](https://github.com/milesj/optimal) checks. All supported optimal | ||
* predicates are passed as an object to the factory. | ||
* | ||
* ```ts | ||
* import { optimal, createBlueprint } from '@boost/common'; | ||
* | ||
* const blueprint = createBlueprint(({ string, number }) => ({ | ||
* name: string().required(), | ||
* age: number().gt(0), | ||
* })); | ||
* | ||
* const data = optimal({}, blueprint); | ||
* ``` | ||
*/ | ||
export declare function createBlueprint<T extends object>(factory: BlueprintFactory<T>): Blueprint<T>; | ||
//# sourceMappingURL=createBlueprint.d.ts.map |
@@ -0,2 +1,14 @@ | ||
/** | ||
* Can be used to recursively freeze plain objects with `Object.freeze`. | ||
* | ||
* ```ts | ||
* import { deepFreeze } from '@boost/common'; | ||
* | ||
* const obj = deepFreeze({ foo: 123 }); | ||
* | ||
* // Errors! | ||
* obj.foo = 456; | ||
* ``` | ||
*/ | ||
export declare function deepFreeze<T extends object = object>(obj: T): T; | ||
//# sourceMappingURL=deepFreeze.d.ts.map |
@@ -5,3 +5,17 @@ export declare type MergableArray = unknown[]; | ||
export declare type InferMergeable<T> = T extends unknown[] ? MergableArray : T extends object ? MergableObject : never; | ||
/** | ||
* Can be used to recursively merge objects and arrays, where values on the | ||
* right-hand side will overwrite values on the left-hand based on the key | ||
* or index respectively. Furthermore, if the 2nd argument is not provided, | ||
* it will simply clone the base value. | ||
* | ||
* ```ts | ||
* import { deepMerge } from '@boost/common'; | ||
* | ||
* const obj = deepMerge({ foo: 123, bar: 'abc' }, { foo: 456, baz: true }); | ||
* | ||
* // -> { foo: 456, bar: 'abc', baz: true } | ||
* ``` | ||
*/ | ||
export declare function deepMerge<T extends Mergeable, V extends InferMergeable<T>>(base: T, other?: V): T; | ||
//# sourceMappingURL=deepMerge.d.ts.map |
import { Options } from 'pretty-ms'; | ||
/** | ||
* Can be used to format a UNIX timestamp in milliseconds into a shorthand human readable format. | ||
* Wraps the [pretty-ms](https://www.npmjs.com/package/pretty-ms) package to handle infinite | ||
* numbers, zeros, and more. | ||
* | ||
* ```ts | ||
* import { formatMs } from '@boost/common'; | ||
* | ||
* formatMs(1337000000); // 15d 11h 23m 20s | ||
* ``` | ||
*/ | ||
export declare function formatMs(ms: number, options?: Options): string; | ||
//# sourceMappingURL=formatMs.d.ts.map |
@@ -7,3 +7,26 @@ import { Constructor } from '../types'; | ||
*/ | ||
/** | ||
* Performs a loose instance check by comparing class names up the prototype | ||
* chain if `instanceof` initially fails. To disable this loose check, | ||
* pass `false` as the 3rd argument. | ||
* | ||
* ```ts | ||
* import { instanceOf } from '@boost/common'; | ||
* | ||
* if (instanceOf(error, Error)) { | ||
* console.log(error.stack); | ||
* } | ||
* ``` | ||
* | ||
* Generics can be used to type the object being checked. This will default | ||
* to the declaration passed to the 2nd argument. | ||
* | ||
* ```ts | ||
* instanceOf<ParseError>(error, Error); | ||
* ``` | ||
* | ||
* > Loose checks can be useful if multiple copies of the same class declaration | ||
* > exists in the module tree. For example, multiple versions of the same package are imported. | ||
*/ | ||
export declare function instanceOf<T = unknown>(object: unknown, declaration: Constructor<T>, loose?: boolean): object is T; | ||
//# sourceMappingURL=instanceOf.d.ts.map |
@@ -0,2 +1,16 @@ | ||
/** | ||
* Returns `true` if an object has no properties, an array has no items, | ||
* or the value is falsy, otherwise, it returns `false`. | ||
* | ||
* ```ts | ||
* import { isEmpty } from '@boost/common'; | ||
* | ||
* isEmpty({}); // true | ||
* isEmpty({ name: 'Boost' }); // false | ||
* | ||
* isEmpty([]); // true | ||
* isEmpty(['Boost']); // false | ||
* ``` | ||
*/ | ||
export declare function isEmpty(value: unknown): boolean; | ||
//# sourceMappingURL=isEmpty.d.ts.map |
import { PortablePath } from '../types'; | ||
/** | ||
* Returns `true` if a string or `Path` instance looks like a file system path, | ||
* by checking for absolute or relative path markers, or the existence of | ||
* path separating slashes. Will return `false` for values that are only | ||
* the file or folder name. | ||
* | ||
* ```ts | ||
* import { isFilePath } from '@boost/common'; | ||
* | ||
* isFilePath('./path/to/file.ts'); // true | ||
* isFilePath(new Path('/path/to/folder')); // true | ||
* isFilePath('file.ts'); // false | ||
* ``` | ||
*/ | ||
export declare function isFilePath(path: PortablePath): boolean; | ||
//# sourceMappingURL=isFilePath.d.ts.map |
import { ModuleName } from '../types'; | ||
/** | ||
* Returns `true` if a string is a valid Node module package name, | ||
* according to the rules defined in | ||
* [validate-npm-package-name](https://github.com/npm/validate-npm-package-name). | ||
* Will `return` false for native builtin modules, like `fs`, and for the old name format. | ||
* | ||
* ```ts | ||
* import { isModuleName } from '@boost/common'; | ||
* | ||
* isModuleName('boost'); // true | ||
* isModuleName('@boost/common'); // true | ||
* isModuleName('fs'); // false | ||
* ``` | ||
*/ | ||
export declare function isModuleName(name: ModuleName): boolean; | ||
//# sourceMappingURL=isModuleName.d.ts.map |
@@ -0,2 +1,25 @@ | ||
/** | ||
* Returns `true` if the value is an object. | ||
* | ||
* ```ts | ||
* import { isObject } from '@boost/common'; | ||
* | ||
* isObject({}); // true | ||
* isObject(new Foo()); // true | ||
* isObject([]); // false | ||
* ``` | ||
* | ||
* Generics can be used to type the return value of the object (when necessary). | ||
* | ||
* ```ts | ||
* interface Person { | ||
* name: string; | ||
* } | ||
* | ||
* if (isObject<Person>(person)) { | ||
* console.log(person.name); | ||
* } | ||
* ``` | ||
*/ | ||
export declare function isObject<T = object>(value: unknown): value is T; | ||
//# sourceMappingURL=isObject.d.ts.map |
@@ -0,2 +1,16 @@ | ||
/** | ||
* Like `isObject` but only returns true if the value is a plain object | ||
* (no class instances, built-ins, etc). It achieves this by comparing | ||
* the value's prototype to the built-in `Object` types. If you need to | ||
* run these checks for cross-realm objects, pass true to the `loose` argument. | ||
* | ||
* ```ts | ||
* import { isPlainObject } from '@boost/common'; | ||
* | ||
* isPlainObject({}); // true | ||
* isPlainObject(new Foo()); // false | ||
* isPlainObject([]); // false | ||
* ``` | ||
*/ | ||
export declare function isPlainObject<T = object>(value: unknown, loose?: boolean): value is T; | ||
//# sourceMappingURL=isPlainObject.d.ts.map |
import { PortablePath } from '../types'; | ||
/** | ||
* Can be used to *sync*hronously parse and return an object for the following | ||
* file types & extensions: `js`, `ts`, `tsx`, `json`, `json5`, `yaml`, `yml`. | ||
* The function requires an absolute file path, and any unsupported file type will throw an error. | ||
* | ||
* ```ts | ||
* import { parseFile } from '@boost/common'; | ||
* | ||
* const data: ReturnShape = parseFile('/absolute/file/path'); | ||
* ``` | ||
* | ||
* > TypeScript files require the `typescript` package to be installed. | ||
*/ | ||
export declare function parseFile<T>(filePath: PortablePath): T; | ||
//# sourceMappingURL=parseFile.d.ts.map |
import { PortablePath } from '../types'; | ||
/** | ||
* Works in a similar fashion to the native NodeJS `require()`, but also handles | ||
* files built with Babel or TypeScript by properly returning the `default` export | ||
* if an "ES module", and also allowing the expected type to be defined. | ||
* | ||
* ```ts | ||
* import { requireModule } from '@boost/common'; | ||
* | ||
* const result: ReturnShape = requireModule('../../some/module'); | ||
* ``` | ||
* | ||
* There are some caveats to be aware of in regards to default and named exports | ||
* in the file being required, they are: | ||
* | ||
* - When only a default export, the exported value is returned directly instead | ||
* of on an object with a `default` property. | ||
* - When only named exports, the returned value is an object with all the named | ||
* exports as properties on the object. | ||
* - When a default export and named exports together, the returned value is an | ||
* object with a `default` property, and an additional property for every named | ||
* export. It's best to stay away from this pattern. | ||
*/ | ||
export declare function requireModule<T>(path: PortablePath): T; | ||
//# sourceMappingURL=requireModule.d.ts.map |
@@ -9,3 +9,17 @@ import { PortablePath } from '../types'; | ||
} | ||
/** | ||
* Like `requireModule` but for importing TypeScript files ending in `ts` or `tsx`. | ||
* When imported, will transform the file using the `typescript` package (must be installed), | ||
* evaluate the code in the current module context, and apply the same process to all child imports. | ||
* | ||
* ```ts | ||
* import { requireTypedModule } from '@boost/common'; | ||
* | ||
* const result: ReturnShape = requireTypedModule('../../some/module.ts'); | ||
* ``` | ||
* | ||
* > This helper rarely needs to be used directly as `parseFile` and `requireModule` will | ||
* > call it under the hood based on the file extension. | ||
*/ | ||
export declare function requireTypedModule<T>(path: PortablePath): T; | ||
//# sourceMappingURL=requireTypedModule.d.ts.map |
@@ -0,2 +1,15 @@ | ||
/** | ||
* Converts a non-array to an array. If the provided value is falsy, | ||
* an empty array is returned. If the provided value is truthy and a | ||
* non-array, an array of 1 item is returned. | ||
* | ||
* ```ts | ||
* import { toArray } from '@boost/common'; | ||
* | ||
* toArray(123); // [123] | ||
* toArray('abc'); // ['abc'] | ||
* toArray(['a', 'b', 'c']); // ['a', 'b', 'c'] | ||
* ``` | ||
*/ | ||
export declare function toArray<T = unknown>(value?: T | T[]): T[]; | ||
//# sourceMappingURL=toArray.d.ts.map |
@@ -26,2 +26,8 @@ import { PackageGraphTree, PackageStructure } from './types'; | ||
* `package.json` objects in the order they are depended on. | ||
* | ||
* ```ts | ||
* graph.resolveList().forEach((pkg) => { | ||
* console.log(pkg.name); | ||
* }); | ||
* ``` | ||
*/ | ||
@@ -32,7 +38,25 @@ resolveList(): T[]; | ||
* `package.json` objects and their dependency mappings. | ||
* | ||
* ```ts | ||
* graph.resolveTree().nodes.forEach((node) => { | ||
* console.log(node.package.name); | ||
* | ||
* if (node.nodes) { | ||
* // Dependents | ||
* } | ||
* }); | ||
* ``` | ||
*/ | ||
resolveTree(): PackageGraphTree<T>; | ||
/** | ||
* Resolve the dependency graph and return a list of batched | ||
* `package.json` objects in the order they are depended on. | ||
* Resolve the dependency graph and return a list of batched `package.json` objects | ||
* (array of arrays) in the order they are depended on. | ||
* | ||
* ```ts | ||
* graph.resolveBatchList().forEach((pkgs) => { | ||
* pkgs.forEach((pkg) => { | ||
* console.log(pkg.name); | ||
* }); | ||
* }); | ||
* ``` | ||
*/ | ||
@@ -39,0 +63,0 @@ resolveBatchList(): T[][]; |
@@ -23,3 +23,8 @@ import { Blueprint, Predicates } from 'optimal'; | ||
export interface Optionable<T extends object = {}> { | ||
/** Validated and configured options. */ | ||
readonly options: Required<T>; | ||
/** | ||
* Define an `optimal` blueprint in which to validate and build the | ||
* options object passed to the constructor, or when manual setting. | ||
*/ | ||
blueprint: BlueprintFactory<object>; | ||
@@ -57,2 +62,6 @@ } | ||
} | ||
/** | ||
* Shape of `package.json`, with support for third-party properties | ||
* like Yarn, Webpack, and TypeScript. | ||
*/ | ||
export interface PackageStructure { | ||
@@ -59,0 +68,0 @@ author?: PeopleSetting | string; |
@@ -724,2 +724,4 @@ 'use strict'; | ||
return call; | ||
} else if (call !== void 0) { | ||
throw new TypeError("Derived constructors may only return object or undefined"); | ||
} | ||
@@ -1707,3 +1709,3 @@ | ||
exports.defineProperty = _defineProperty; | ||
exports.extends = _extends; | ||
exports['extends'] = _extends; | ||
exports.get = _get; | ||
@@ -1715,3 +1717,3 @@ exports.getPrototypeOf = _getPrototypeOf; | ||
exports.initializerWarningHelper = _initializerWarningHelper; | ||
exports.instanceof = _instanceof; | ||
exports['instanceof'] = _instanceof; | ||
exports.interopRequireDefault = _interopRequireDefault; | ||
@@ -1751,3 +1753,3 @@ exports.interopRequireWildcard = _interopRequireWildcard; | ||
exports.toPropertyKey = _toPropertyKey; | ||
exports.typeof = _typeof; | ||
exports['typeof'] = _typeof; | ||
exports.unsupportedIterableToArray = _unsupportedIterableToArray; | ||
@@ -1754,0 +1756,0 @@ exports.wrapAsyncGenerator = _wrapAsyncGenerator; |
@@ -24,2 +24,3 @@ 'use strict'; | ||
class Contract { | ||
/** Validated and configured options. */ | ||
constructor(options) { | ||
@@ -33,2 +34,13 @@ this.options = void 0; | ||
* Freeze and return the options object. | ||
* | ||
* ```ts | ||
* object.configure({ name: 'Boost' }); | ||
* | ||
* object.configure((prevOptions) => ({ | ||
* nestedObject: { | ||
* ...prevOptions.nestedObject, | ||
* some: 'value', | ||
* }, | ||
* })); | ||
* ``` | ||
*/ | ||
@@ -48,4 +60,8 @@ | ||
/** | ||
* Define an optimal blueprint in which to validate and build the | ||
* Define an `optimal` blueprint in which to validate and build the | ||
* options object passed to the constructor, or when manual setting. | ||
* | ||
* A boolean is passed as the 2nd argument to determine whether this is | ||
* validating on class instantiation (first time), or by calling | ||
* `configure()` (all other times). | ||
*/ | ||
@@ -52,0 +68,0 @@ |
@@ -8,3 +8,20 @@ 'use strict'; | ||
var optimal = require('optimal'); | ||
/** | ||
* Can be used to generate a blueprint object for use within | ||
* [optimal](https://github.com/milesj/optimal) checks. All supported optimal | ||
* predicates are passed as an object to the factory. | ||
* | ||
* ```ts | ||
* import { optimal, createBlueprint } from '@boost/common'; | ||
* | ||
* const blueprint = createBlueprint(({ string, number }) => ({ | ||
* name: string().required(), | ||
* age: number().gt(0), | ||
* })); | ||
* | ||
* const data = optimal({}, blueprint); | ||
* ``` | ||
*/ | ||
function createBlueprint(factory) { | ||
@@ -11,0 +28,0 @@ return factory(optimal.predicates); |
@@ -8,3 +8,16 @@ 'use strict'; | ||
var isPlainObject = require('./isPlainObject.js'); | ||
/** | ||
* Can be used to recursively freeze plain objects with `Object.freeze`. | ||
* | ||
* ```ts | ||
* import { deepFreeze } from '@boost/common'; | ||
* | ||
* const obj = deepFreeze({ foo: 123 }); | ||
* | ||
* // Errors! | ||
* obj.foo = 456; | ||
* ``` | ||
*/ | ||
function deepFreeze(obj) { | ||
@@ -11,0 +24,0 @@ if (Object.isFrozen(obj)) { |
@@ -30,3 +30,18 @@ 'use strict'; | ||
} | ||
/** | ||
* Can be used to recursively merge objects and arrays, where values on the | ||
* right-hand side will overwrite values on the left-hand based on the key | ||
* or index respectively. Furthermore, if the 2nd argument is not provided, | ||
* it will simply clone the base value. | ||
* | ||
* ```ts | ||
* import { deepMerge } from '@boost/common'; | ||
* | ||
* const obj = deepMerge({ foo: 123, bar: 'abc' }, { foo: 456, baz: true }); | ||
* | ||
* // -> { foo: 456, bar: 'abc', baz: true } | ||
* ``` | ||
*/ | ||
function deepMerge(base, other) { | ||
@@ -33,0 +48,0 @@ const next = Array.isArray(base) ? merge([], base) : merge({}, base); |
@@ -22,3 +22,15 @@ 'use strict'; | ||
var prettyMs__default = /*#__PURE__*/_interopDefault(prettyMs); | ||
/** | ||
* Can be used to format a UNIX timestamp in milliseconds into a shorthand human readable format. | ||
* Wraps the [pretty-ms](https://www.npmjs.com/package/pretty-ms) package to handle infinite | ||
* numbers, zeros, and more. | ||
* | ||
* ```ts | ||
* import { formatMs } from '@boost/common'; | ||
* | ||
* formatMs(1337000000); // 15d 11h 23m 20s | ||
* ``` | ||
*/ | ||
function formatMs(ms, options) { | ||
@@ -25,0 +37,0 @@ if (!Number.isFinite(ms) || ms === 0) { |
@@ -12,2 +12,26 @@ 'use strict'; | ||
/** | ||
* Performs a loose instance check by comparing class names up the prototype | ||
* chain if `instanceof` initially fails. To disable this loose check, | ||
* pass `false` as the 3rd argument. | ||
* | ||
* ```ts | ||
* import { instanceOf } from '@boost/common'; | ||
* | ||
* if (instanceOf(error, Error)) { | ||
* console.log(error.stack); | ||
* } | ||
* ``` | ||
* | ||
* Generics can be used to type the object being checked. This will default | ||
* to the declaration passed to the 2nd argument. | ||
* | ||
* ```ts | ||
* instanceOf<ParseError>(error, Error); | ||
* ``` | ||
* | ||
* > Loose checks can be useful if multiple copies of the same class declaration | ||
* > exists in the module tree. For example, multiple versions of the same package are imported. | ||
*/ | ||
function instanceOf(object, declaration, loose = true) { | ||
@@ -33,4 +57,3 @@ if (!object || typeof object !== 'object') { | ||
if (current.constructor.name === declaration.name || // istanbul ignore next | ||
current instanceof Error && current.name === declaration.name) { | ||
if (current.constructor.name === declaration.name || current instanceof Error && current.name === declaration.name) { | ||
return true; | ||
@@ -37,0 +60,0 @@ } // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment |
@@ -8,3 +8,18 @@ 'use strict'; | ||
var isObject = require('./isObject.js'); | ||
/** | ||
* Returns `true` if an object has no properties, an array has no items, | ||
* or the value is falsy, otherwise, it returns `false`. | ||
* | ||
* ```ts | ||
* import { isEmpty } from '@boost/common'; | ||
* | ||
* isEmpty({}); // true | ||
* isEmpty({ name: 'Boost' }); // false | ||
* | ||
* isEmpty([]); // true | ||
* isEmpty(['Boost']); // false | ||
* ``` | ||
*/ | ||
function isEmpty(value) { | ||
@@ -11,0 +26,0 @@ return !value || Array.isArray(value) && value.length === 0 || isObject.isObject(value) && Object.keys(value).length === 0 || false; |
@@ -11,2 +11,16 @@ 'use strict'; | ||
const WIN_START = /^([A-Z]:|\.)/u; | ||
/** | ||
* Returns `true` if a string or `Path` instance looks like a file system path, | ||
* by checking for absolute or relative path markers, or the existence of | ||
* path separating slashes. Will return `false` for values that are only | ||
* the file or folder name. | ||
* | ||
* ```ts | ||
* import { isFilePath } from '@boost/common'; | ||
* | ||
* isFilePath('./path/to/file.ts'); // true | ||
* isFilePath(new Path('/path/to/folder')); // true | ||
* isFilePath('file.ts'); // false | ||
* ``` | ||
*/ | ||
@@ -13,0 +27,0 @@ function isFilePath(path) { |
@@ -12,2 +12,16 @@ 'use strict'; | ||
const RESERVED = new Set([...module$1.builtinModules, 'node_modules', 'favicon.ico']); | ||
/** | ||
* Returns `true` if a string is a valid Node module package name, | ||
* according to the rules defined in | ||
* [validate-npm-package-name](https://github.com/npm/validate-npm-package-name). | ||
* Will `return` false for native builtin modules, like `fs`, and for the old name format. | ||
* | ||
* ```ts | ||
* import { isModuleName } from '@boost/common'; | ||
* | ||
* isModuleName('boost'); // true | ||
* isModuleName('@boost/common'); // true | ||
* isModuleName('fs'); // false | ||
* ``` | ||
*/ | ||
@@ -14,0 +28,0 @@ function isModuleName(name) { |
@@ -6,2 +6,25 @@ 'use strict'; | ||
}); | ||
/** | ||
* Returns `true` if the value is an object. | ||
* | ||
* ```ts | ||
* import { isObject } from '@boost/common'; | ||
* | ||
* isObject({}); // true | ||
* isObject(new Foo()); // true | ||
* isObject([]); // false | ||
* ``` | ||
* | ||
* Generics can be used to type the return value of the object (when necessary). | ||
* | ||
* ```ts | ||
* interface Person { | ||
* name: string; | ||
* } | ||
* | ||
* if (isObject<Person>(person)) { | ||
* console.log(person.name); | ||
* } | ||
* ``` | ||
*/ | ||
@@ -8,0 +31,0 @@ function isObject(value) { |
@@ -8,3 +8,18 @@ 'use strict'; | ||
var isObject = require('./isObject.js'); | ||
/** | ||
* Like `isObject` but only returns true if the value is a plain object | ||
* (no class instances, built-ins, etc). It achieves this by comparing | ||
* the value's prototype to the built-in `Object` types. If you need to | ||
* run these checks for cross-realm objects, pass true to the `loose` argument. | ||
* | ||
* ```ts | ||
* import { isPlainObject } from '@boost/common'; | ||
* | ||
* isPlainObject({}); // true | ||
* isPlainObject(new Foo()); // false | ||
* isPlainObject([]); // false | ||
* ``` | ||
*/ | ||
function isPlainObject(value, loose = false) { | ||
@@ -17,4 +32,3 @@ if (!isObject.isObject(value)) { | ||
if (value.constructor === Object || proto === Object.prototype || proto === null || // This is to support cross-realm checks | ||
loose && value.constructor.name === 'Object') { | ||
if (value.constructor === Object || proto === Object.prototype || proto === null || loose && value.constructor.name === 'Object') { | ||
return true; | ||
@@ -21,0 +35,0 @@ } |
@@ -28,3 +28,17 @@ 'use strict'; | ||
var fs__default = /*#__PURE__*/_interopDefault(fs); | ||
/** | ||
* Can be used to *sync*hronously parse and return an object for the following | ||
* file types & extensions: `js`, `ts`, `tsx`, `json`, `json5`, `yaml`, `yml`. | ||
* The function requires an absolute file path, and any unsupported file type will throw an error. | ||
* | ||
* ```ts | ||
* import { parseFile } from '@boost/common'; | ||
* | ||
* const data: ReturnShape = parseFile('/absolute/file/path'); | ||
* ``` | ||
* | ||
* > TypeScript files require the `typescript` package to be installed. | ||
*/ | ||
function parseFile(filePath) { | ||
@@ -31,0 +45,0 @@ const path = Path.Path.create(filePath); |
@@ -10,3 +10,26 @@ 'use strict'; | ||
var requireTypedModule = require('./requireTypedModule.js'); | ||
/** | ||
* Works in a similar fashion to the native NodeJS `require()`, but also handles | ||
* files built with Babel or TypeScript by properly returning the `default` export | ||
* if an "ES module", and also allowing the expected type to be defined. | ||
* | ||
* ```ts | ||
* import { requireModule } from '@boost/common'; | ||
* | ||
* const result: ReturnShape = requireModule('../../some/module'); | ||
* ``` | ||
* | ||
* There are some caveats to be aware of in regards to default and named exports | ||
* in the file being required, they are: | ||
* | ||
* - When only a default export, the exported value is returned directly instead | ||
* of on an object with a `default` property. | ||
* - When only named exports, the returned value is an object with all the named | ||
* exports as properties on the object. | ||
* - When a default export and named exports together, the returned value is an | ||
* object with a `default` property, and an additional property for every named | ||
* export. It's best to stay away from this pattern. | ||
*/ | ||
function requireModule(path) { | ||
@@ -13,0 +36,0 @@ const filePath = String(path); |
@@ -72,3 +72,18 @@ 'use strict'; | ||
} | ||
/** | ||
* Like `requireModule` but for importing TypeScript files ending in `ts` or `tsx`. | ||
* When imported, will transform the file using the `typescript` package (must be installed), | ||
* evaluate the code in the current module context, and apply the same process to all child imports. | ||
* | ||
* ```ts | ||
* import { requireTypedModule } from '@boost/common'; | ||
* | ||
* const result: ReturnShape = requireTypedModule('../../some/module.ts'); | ||
* ``` | ||
* | ||
* > This helper rarely needs to be used directly as `parseFile` and `requireModule` will | ||
* > call it under the hood based on the file extension. | ||
*/ | ||
function requireTypedModule(path) { | ||
@@ -75,0 +90,0 @@ const filePath = String(path); |
@@ -6,2 +6,15 @@ 'use strict'; | ||
}); | ||
/** | ||
* Converts a non-array to an array. If the provided value is falsy, | ||
* an empty array is returned. If the provided value is truthy and a | ||
* non-array, an array of 1 item is returned. | ||
* | ||
* ```ts | ||
* import { toArray } from '@boost/common'; | ||
* | ||
* toArray(123); // [123] | ||
* toArray('abc'); // ['abc'] | ||
* toArray(['a', 'b', 'c']); // ['a', 'b', 'c'] | ||
* ``` | ||
*/ | ||
@@ -8,0 +21,0 @@ function toArray(value) { |
@@ -63,2 +63,8 @@ 'use strict'; | ||
* `package.json` objects in the order they are depended on. | ||
* | ||
* ```ts | ||
* graph.resolveList().forEach((pkg) => { | ||
* console.log(pkg.name); | ||
* }); | ||
* ``` | ||
*/ | ||
@@ -76,2 +82,12 @@ | ||
* `package.json` objects and their dependency mappings. | ||
* | ||
* ```ts | ||
* graph.resolveTree().nodes.forEach((node) => { | ||
* console.log(node.package.name); | ||
* | ||
* if (node.nodes) { | ||
* // Dependents | ||
* } | ||
* }); | ||
* ``` | ||
*/ | ||
@@ -128,4 +144,12 @@ | ||
/** | ||
* Resolve the dependency graph and return a list of batched | ||
* `package.json` objects in the order they are depended on. | ||
* Resolve the dependency graph and return a list of batched `package.json` objects | ||
* (array of arrays) in the order they are depended on. | ||
* | ||
* ```ts | ||
* graph.resolveBatchList().forEach((pkgs) => { | ||
* pkgs.forEach((pkg) => { | ||
* console.log(pkg.name); | ||
* }); | ||
* }); | ||
* ``` | ||
*/ | ||
@@ -174,3 +198,3 @@ | ||
if (cycle.has(node)) { | ||
const path = [...[...cycle], node].map(n => n.name).join(' -> '); | ||
const path = [...cycle, node].map(n => n.name).join(' -> '); | ||
throw new Error(`Circular dependency detected: ${path}`); | ||
@@ -177,0 +201,0 @@ } |
{ | ||
"name": "@boost/common", | ||
"version": "2.8.1", | ||
"version": "2.8.2", | ||
"release": "1594765247526", | ||
@@ -34,3 +34,3 @@ "description": "A collection of common utilities, classes, and helpers.", | ||
"dependencies": { | ||
"@boost/decorators": "^2.1.3", | ||
"@boost/decorators": "^2.1.4", | ||
"@boost/internal": "^2.2.3", | ||
@@ -63,3 +63,3 @@ "fast-glob": "^3.2.7", | ||
}, | ||
"gitHead": "ea3128b3fbb716e606b528c42478fcf1434f5c2b" | ||
"gitHead": "a44772937c04f8f818884444faee5c2a9f44b5ac" | ||
} |
# Common utilities - Boost | ||
[![Build Status](https://github.com/milesj/boost/workflows/Build/badge.svg)](https://github.com/milesj/boost/actions?query=branch%3Amaster) | ||
[![npm version](https://badge.fury.io/js/%40boost%common.svg)](https://www.npmjs.com/package/@boost/common) | ||
[![npm version](https://badge.fury.io/js/%40boost%2Fcommon.svg)](https://www.npmjs.com/package/@boost/common) | ||
[![npm deps](https://david-dm.org/milesj/boost.svg?path=packages/common)](https://www.npmjs.com/package/@boost/common) | ||
@@ -9,2 +9,6 @@ | ||
```ts | ||
import { isObject, toArray } from '@boost/common'; | ||
``` | ||
## Installation | ||
@@ -18,2 +22,3 @@ | ||
[https://boostlib.dev/docs/common](https://boostlib.dev/docs/common) | ||
- [https://boostlib.dev/docs/common](https://boostlib.dev/docs/common) | ||
- [https://boostlib.dev/api/common](https://boostlib.dev/api/common) |
@@ -5,2 +5,3 @@ import optimal, { Blueprint, Predicates, predicates } from 'optimal'; | ||
export abstract class Contract<T extends object = {}> implements Optionable<T> { | ||
/** Validated and configured options. */ | ||
readonly options: Readonly<Required<T>>; | ||
@@ -16,2 +17,13 @@ | ||
* Freeze and return the options object. | ||
* | ||
* ```ts | ||
* object.configure({ name: 'Boost' }); | ||
* | ||
* object.configure((prevOptions) => ({ | ||
* nestedObject: { | ||
* ...prevOptions.nestedObject, | ||
* some: 'value', | ||
* }, | ||
* })); | ||
* ``` | ||
*/ | ||
@@ -38,6 +50,10 @@ configure(options?: Partial<T> | ((options: Required<T>) => Partial<T>)): Readonly<Required<T>> { | ||
/** | ||
* Define an optimal blueprint in which to validate and build the | ||
* Define an `optimal` blueprint in which to validate and build the | ||
* options object passed to the constructor, or when manual setting. | ||
* | ||
* A boolean is passed as the 2nd argument to determine whether this is | ||
* validating on class instantiation (first time), or by calling | ||
* `configure()` (all other times). | ||
*/ | ||
abstract blueprint(predicates: Predicates, onConstruction?: boolean): Blueprint<object>; | ||
} |
import { Blueprint, predicates } from 'optimal'; | ||
import { BlueprintFactory } from '../types'; | ||
/** | ||
* Can be used to generate a blueprint object for use within | ||
* [optimal](https://github.com/milesj/optimal) checks. All supported optimal | ||
* predicates are passed as an object to the factory. | ||
* | ||
* ```ts | ||
* import { optimal, createBlueprint } from '@boost/common'; | ||
* | ||
* const blueprint = createBlueprint(({ string, number }) => ({ | ||
* name: string().required(), | ||
* age: number().gt(0), | ||
* })); | ||
* | ||
* const data = optimal({}, blueprint); | ||
* ``` | ||
*/ | ||
export function createBlueprint<T extends object>(factory: BlueprintFactory<T>): Blueprint<T> { | ||
return factory(predicates); | ||
} |
import { isPlainObject } from './isPlainObject'; | ||
/** | ||
* Can be used to recursively freeze plain objects with `Object.freeze`. | ||
* | ||
* ```ts | ||
* import { deepFreeze } from '@boost/common'; | ||
* | ||
* const obj = deepFreeze({ foo: 123 }); | ||
* | ||
* // Errors! | ||
* obj.foo = 456; | ||
* ``` | ||
*/ | ||
export function deepFreeze<T extends object = object>(obj: T): T { | ||
@@ -4,0 +16,0 @@ if (Object.isFrozen(obj)) { |
@@ -30,2 +30,16 @@ import { isObject } from './isObject'; | ||
/** | ||
* Can be used to recursively merge objects and arrays, where values on the | ||
* right-hand side will overwrite values on the left-hand based on the key | ||
* or index respectively. Furthermore, if the 2nd argument is not provided, | ||
* it will simply clone the base value. | ||
* | ||
* ```ts | ||
* import { deepMerge } from '@boost/common'; | ||
* | ||
* const obj = deepMerge({ foo: 123, bar: 'abc' }, { foo: 456, baz: true }); | ||
* | ||
* // -> { foo: 456, bar: 'abc', baz: true } | ||
* ``` | ||
*/ | ||
export function deepMerge<T extends Mergeable, V extends InferMergeable<T>>(base: T, other?: V): T { | ||
@@ -32,0 +46,0 @@ const next = Array.isArray(base) |
import prettyMs, { Options } from 'pretty-ms'; | ||
/** | ||
* Can be used to format a UNIX timestamp in milliseconds into a shorthand human readable format. | ||
* Wraps the [pretty-ms](https://www.npmjs.com/package/pretty-ms) package to handle infinite | ||
* numbers, zeros, and more. | ||
* | ||
* ```ts | ||
* import { formatMs } from '@boost/common'; | ||
* | ||
* formatMs(1337000000); // 15d 11h 23m 20s | ||
* ``` | ||
*/ | ||
export function formatMs(ms: number, options?: Options): string { | ||
@@ -4,0 +15,0 @@ if (!Number.isFinite(ms) || ms === 0) { |
@@ -8,2 +8,26 @@ import { Constructor } from '../types'; | ||
*/ | ||
/** | ||
* Performs a loose instance check by comparing class names up the prototype | ||
* chain if `instanceof` initially fails. To disable this loose check, | ||
* pass `false` as the 3rd argument. | ||
* | ||
* ```ts | ||
* import { instanceOf } from '@boost/common'; | ||
* | ||
* if (instanceOf(error, Error)) { | ||
* console.log(error.stack); | ||
* } | ||
* ``` | ||
* | ||
* Generics can be used to type the object being checked. This will default | ||
* to the declaration passed to the 2nd argument. | ||
* | ||
* ```ts | ||
* instanceOf<ParseError>(error, Error); | ||
* ``` | ||
* | ||
* > Loose checks can be useful if multiple copies of the same class declaration | ||
* > exists in the module tree. For example, multiple versions of the same package are imported. | ||
*/ | ||
export function instanceOf<T = unknown>( | ||
@@ -10,0 +34,0 @@ object: unknown, |
import { isObject } from './isObject'; | ||
/** | ||
* Returns `true` if an object has no properties, an array has no items, | ||
* or the value is falsy, otherwise, it returns `false`. | ||
* | ||
* ```ts | ||
* import { isEmpty } from '@boost/common'; | ||
* | ||
* isEmpty({}); // true | ||
* isEmpty({ name: 'Boost' }); // false | ||
* | ||
* isEmpty([]); // true | ||
* isEmpty(['Boost']); // false | ||
* ``` | ||
*/ | ||
export function isEmpty(value: unknown): boolean { | ||
@@ -4,0 +18,0 @@ return ( |
@@ -7,2 +7,16 @@ import { Path } from '../Path'; | ||
/** | ||
* Returns `true` if a string or `Path` instance looks like a file system path, | ||
* by checking for absolute or relative path markers, or the existence of | ||
* path separating slashes. Will return `false` for values that are only | ||
* the file or folder name. | ||
* | ||
* ```ts | ||
* import { isFilePath } from '@boost/common'; | ||
* | ||
* isFilePath('./path/to/file.ts'); // true | ||
* isFilePath(new Path('/path/to/folder')); // true | ||
* isFilePath('file.ts'); // false | ||
* ``` | ||
*/ | ||
export function isFilePath(path: PortablePath): boolean { | ||
@@ -9,0 +23,0 @@ const filePath = path instanceof Path ? path.path() : path; |
@@ -7,2 +7,16 @@ import { builtinModules } from 'module'; | ||
/** | ||
* Returns `true` if a string is a valid Node module package name, | ||
* according to the rules defined in | ||
* [validate-npm-package-name](https://github.com/npm/validate-npm-package-name). | ||
* Will `return` false for native builtin modules, like `fs`, and for the old name format. | ||
* | ||
* ```ts | ||
* import { isModuleName } from '@boost/common'; | ||
* | ||
* isModuleName('boost'); // true | ||
* isModuleName('@boost/common'); // true | ||
* isModuleName('fs'); // false | ||
* ``` | ||
*/ | ||
export function isModuleName(name: ModuleName): boolean { | ||
@@ -9,0 +23,0 @@ if (RESERVED.has(name)) { |
@@ -0,3 +1,26 @@ | ||
/** | ||
* Returns `true` if the value is an object. | ||
* | ||
* ```ts | ||
* import { isObject } from '@boost/common'; | ||
* | ||
* isObject({}); // true | ||
* isObject(new Foo()); // true | ||
* isObject([]); // false | ||
* ``` | ||
* | ||
* Generics can be used to type the return value of the object (when necessary). | ||
* | ||
* ```ts | ||
* interface Person { | ||
* name: string; | ||
* } | ||
* | ||
* if (isObject<Person>(person)) { | ||
* console.log(person.name); | ||
* } | ||
* ``` | ||
*/ | ||
export function isObject<T = object>(value: unknown): value is T { | ||
return typeof value === 'object' && value !== null && !Array.isArray(value); | ||
} |
import { isObject } from './isObject'; | ||
/** | ||
* Like `isObject` but only returns true if the value is a plain object | ||
* (no class instances, built-ins, etc). It achieves this by comparing | ||
* the value's prototype to the built-in `Object` types. If you need to | ||
* run these checks for cross-realm objects, pass true to the `loose` argument. | ||
* | ||
* ```ts | ||
* import { isPlainObject } from '@boost/common'; | ||
* | ||
* isPlainObject({}); // true | ||
* isPlainObject(new Foo()); // false | ||
* isPlainObject([]); // false | ||
* ``` | ||
*/ | ||
export function isPlainObject<T = object>(value: unknown, loose: boolean = false): value is T { | ||
@@ -4,0 +18,0 @@ if (!isObject(value)) { |
@@ -10,2 +10,15 @@ import fs from 'fs'; | ||
/** | ||
* Can be used to *sync*hronously parse and return an object for the following | ||
* file types & extensions: `js`, `ts`, `tsx`, `json`, `json5`, `yaml`, `yml`. | ||
* The function requires an absolute file path, and any unsupported file type will throw an error. | ||
* | ||
* ```ts | ||
* import { parseFile } from '@boost/common'; | ||
* | ||
* const data: ReturnShape = parseFile('/absolute/file/path'); | ||
* ``` | ||
* | ||
* > TypeScript files require the `typescript` package to be installed. | ||
*/ | ||
export function parseFile<T>(filePath: PortablePath): T { | ||
@@ -12,0 +25,0 @@ const path = Path.create(filePath); |
@@ -5,2 +5,24 @@ import { interopRequireModule } from '../internal/interopRequireModule'; | ||
/** | ||
* Works in a similar fashion to the native NodeJS `require()`, but also handles | ||
* files built with Babel or TypeScript by properly returning the `default` export | ||
* if an "ES module", and also allowing the expected type to be defined. | ||
* | ||
* ```ts | ||
* import { requireModule } from '@boost/common'; | ||
* | ||
* const result: ReturnShape = requireModule('../../some/module'); | ||
* ``` | ||
* | ||
* There are some caveats to be aware of in regards to default and named exports | ||
* in the file being required, they are: | ||
* | ||
* - When only a default export, the exported value is returned directly instead | ||
* of on an object with a `default` property. | ||
* - When only named exports, the returned value is an object with all the named | ||
* exports as properties on the object. | ||
* - When a default export and named exports together, the returned value is an | ||
* object with a `default` property, and an additional property for every named | ||
* export. It's best to stay away from this pattern. | ||
*/ | ||
export function requireModule<T>(path: PortablePath): T { | ||
@@ -7,0 +29,0 @@ const filePath = String(path); |
@@ -69,2 +69,16 @@ /* eslint-disable no-underscore-dangle, node/no-deprecated-api */ | ||
/** | ||
* Like `requireModule` but for importing TypeScript files ending in `ts` or `tsx`. | ||
* When imported, will transform the file using the `typescript` package (must be installed), | ||
* evaluate the code in the current module context, and apply the same process to all child imports. | ||
* | ||
* ```ts | ||
* import { requireTypedModule } from '@boost/common'; | ||
* | ||
* const result: ReturnShape = requireTypedModule('../../some/module.ts'); | ||
* ``` | ||
* | ||
* > This helper rarely needs to be used directly as `parseFile` and `requireModule` will | ||
* > call it under the hood based on the file extension. | ||
*/ | ||
export function requireTypedModule<T>(path: PortablePath): T { | ||
@@ -71,0 +85,0 @@ const filePath = String(path); |
@@ -0,1 +1,14 @@ | ||
/** | ||
* Converts a non-array to an array. If the provided value is falsy, | ||
* an empty array is returned. If the provided value is truthy and a | ||
* non-array, an array of 1 item is returned. | ||
* | ||
* ```ts | ||
* import { toArray } from '@boost/common'; | ||
* | ||
* toArray(123); // [123] | ||
* toArray('abc'); // ['abc'] | ||
* toArray(['a', 'b', 'c']); // ['a', 'b', 'c'] | ||
* ``` | ||
*/ | ||
export function toArray<T = unknown>(value?: T | T[]): T[] { | ||
@@ -2,0 +15,0 @@ if (typeof value === 'undefined') { |
@@ -61,2 +61,8 @@ /* eslint-disable max-classes-per-file */ | ||
* `package.json` objects in the order they are depended on. | ||
* | ||
* ```ts | ||
* graph.resolveList().forEach((pkg) => { | ||
* console.log(pkg.name); | ||
* }); | ||
* ``` | ||
*/ | ||
@@ -74,2 +80,12 @@ resolveList(): T[] { | ||
* `package.json` objects and their dependency mappings. | ||
* | ||
* ```ts | ||
* graph.resolveTree().nodes.forEach((node) => { | ||
* console.log(node.package.name); | ||
* | ||
* if (node.nodes) { | ||
* // Dependents | ||
* } | ||
* }); | ||
* ``` | ||
*/ | ||
@@ -128,4 +144,12 @@ resolveTree(): PackageGraphTree<T> { | ||
/** | ||
* Resolve the dependency graph and return a list of batched | ||
* `package.json` objects in the order they are depended on. | ||
* Resolve the dependency graph and return a list of batched `package.json` objects | ||
* (array of arrays) in the order they are depended on. | ||
* | ||
* ```ts | ||
* graph.resolveBatchList().forEach((pkgs) => { | ||
* pkgs.forEach((pkg) => { | ||
* console.log(pkg.name); | ||
* }); | ||
* }); | ||
* ``` | ||
*/ | ||
@@ -178,3 +202,3 @@ resolveBatchList(): T[][] { | ||
if (cycle.has(node)) { | ||
const path = [...[...cycle], node].map((n) => n.name).join(' -> '); | ||
const path = [...cycle, node].map((n) => n.name).join(' -> '); | ||
@@ -181,0 +205,0 @@ throw new Error(`Circular dependency detected: ${path}`); |
@@ -43,4 +43,9 @@ import { Blueprint, Predicates } from 'optimal'; | ||
export interface Optionable<T extends object = {}> { | ||
/** Validated and configured options. */ | ||
readonly options: Required<T>; | ||
/** | ||
* Define an `optimal` blueprint in which to validate and build the | ||
* options object passed to the constructor, or when manual setting. | ||
*/ | ||
blueprint: BlueprintFactory<object>; | ||
@@ -91,2 +96,6 @@ } | ||
/** | ||
* Shape of `package.json`, with support for third-party properties | ||
* like Yarn, Webpack, and TypeScript. | ||
*/ | ||
export interface PackageStructure { | ||
@@ -93,0 +102,0 @@ author?: PeopleSetting | string; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
201521
4945
23
Updated@boost/decorators@^2.1.4