@budsbox/lib-es 2.3.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Due to their reliance on features from several other submodules,
3
+ * these functions are not located in more fitting areas, such as './assert.ts' or './check.ts'.
4
+ *
5
+ * @module high-level-functions
6
+ */
7
+ import { assertArray, assertFunction, assertString, callPredicate, invariantPredicate, } from './assert.js';
8
+ import { isArray, isFunction, isString, sameValueZero } from './check.js';
9
+ import { describeComplexPredicate, describePredicate, describeTypePredicate, getPredicateDescriptor, } from './describe.js';
10
+ import { formatDebugValue, getPredicateConditions, joinWithConjunction, } from './format.js';
11
+ import { assertProp, hasProp } from './prop.js';
12
+ /**
13
+ * Determines whether the provided key is a valid property key of the given source object.
14
+ *
15
+ * @param key - The property key to check for existence within the source object.
16
+ * @param source - The object in which to check for the property key.
17
+ * @param checkProto - Determines whether the prototype chain should also be checked. Defaults to `false`.
18
+ * @returns A boolean indicating whether the key is a valid property key of the source object.
19
+ * @typeParam TSource - The type of the source object to inspect.
20
+ */
21
+ export const isKeyOf = (key, source, checkProto = false) => {
22
+ return hasProp(source, key, checkProto);
23
+ };
24
+ /* ──────────────────────────────── Iterable ──────────────────────────────── */
25
+ /**
26
+ * Determines whether the provided value is iterable.
27
+ *
28
+ * @param value - The value to be checked.
29
+ * @returns `true` if the value is iterable, otherwise `false`.
30
+ * @category Checks
31
+ */
32
+ export function isIterable(value) {
33
+ return hasProp(value, Symbol.iterator, isFunction, true);
34
+ }
35
+ describePredicate(isIterable, 'to be iterable');
36
+ /**
37
+ * Asserts that the provided value is iterable.
38
+ *
39
+ * @param value - The value to be checked for iterable compatibility.
40
+ * @param valueName - The name of the value for the error message. Defaults to 'value'.
41
+ * @throws {@link !TypeError} If the provided value is not iterable.
42
+ * @category Assertions
43
+ */
44
+ export function assertIterable(value, valueName = 'value') {
45
+ // This assertion offers a more informative error message compared to the default one provided by assertProp.
46
+ assertString(valueName, 'valueName');
47
+ assertProp(value, Symbol.iterator, isFunction, true, valueName);
48
+ }
49
+ /* ──────────────────────────────── Of Type ───────────────────────────────── */
50
+ /**
51
+ * Creates a type predicate that checks whether a value is an instance of the provided constructor.
52
+ * The returned predicate acts as a type guard for narrowing the value to the constructor's type.
53
+ *
54
+ * @param ctor - A constructor function to check against.
55
+ * @returns A type predicate function that narrows the value type to an instance of the constructor.
56
+ * @throws {@link !TypeError} If `ctor` is not a function.
57
+ * @typeParam T - The type of instances produced by the constructor.
58
+ * @category Checks
59
+ */
60
+ export const ofType = (ctor) => {
61
+ assertFunction(ctor, 'ctor');
62
+ return describeTypePredicate((value) => value instanceof ctor, `instance of ${ctor.name ? ctor.name : 'anonymous class'}`);
63
+ };
64
+ /**
65
+ * Asserts that a value is an instance of the provided constructor.
66
+ * If the assertion succeeds, the value is narrowed to the constructor's type.
67
+ *
68
+ * @param ctor - A constructor function to check against.
69
+ * @param value - The value to be verified as an instance of the constructor.
70
+ * @param name - The name of the value for the error message. Defaults to 'value'.
71
+ * @throws {@link !TypeError} If `ctor` is not a function or if the value is not an instance of the constructor.
72
+ * @typeParam T - The type of instances produced by the constructor.
73
+ * @category Assertions
74
+ */
75
+ export function assertOfType(ctor, value, name = 'value') {
76
+ assertFunction(ctor, 'ctor');
77
+ assertString(name, 'valueName');
78
+ invariantPredicate(ofType(ctor), value, name);
79
+ }
80
+ export function somePredicate(...predicates) {
81
+ assertPredicates(predicates);
82
+ const compositePredicate = (value) => predicates.some((predicate) => callPredicate(predicate, value));
83
+ return describeComplexPredicate(compositePredicate, false, ...predicates);
84
+ }
85
+ export function assertSome(value, ...rest) {
86
+ let valueName, predicates;
87
+ if (isString(rest[0])) {
88
+ [valueName, ...predicates] = rest;
89
+ }
90
+ else {
91
+ predicates = rest;
92
+ }
93
+ invariantPredicate(somePredicate(...predicates), value, valueName);
94
+ }
95
+ export function everyPredicate(...predicates) {
96
+ assertPredicates(predicates);
97
+ const compositePredicate = (value) => predicates.every((predicate) => callPredicate(predicate, value));
98
+ return describeComplexPredicate(compositePredicate, true, ...predicates);
99
+ }
100
+ export function assertEvery(value, ...rest) {
101
+ let valueName, predicates;
102
+ if (isString(rest[0])) {
103
+ [valueName, ...predicates] = rest;
104
+ }
105
+ else {
106
+ predicates = rest;
107
+ }
108
+ invariantPredicate(everyPredicate(...predicates), value, valueName);
109
+ }
110
+ /* ───────────────────────────────── Any Of ───────────────────────────────── */
111
+ /**
112
+ * Creates a type predicate that checks if a given value matches any of the specified values.
113
+ *
114
+ * This function accepts a set of possible values and returns a predicate function
115
+ * that evaluates if an input value exists within the set of those specified values.
116
+ *
117
+ * @param values - The set of values to match the input against.
118
+ * @returns A type predicate that verifies whether a value is one of the specified values.
119
+ * @typeParam TValues - A tuple type of all possible values to check against.
120
+ * @remarks Value equality is based on the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Equality_comparisons_and_sameness#same-value-zero_equality SameValueZero algorithm}.
121
+ * @example
122
+ * ```typescript
123
+ * const isColor = anyOf('red', 'green', 'blue');
124
+ * const test = 'red';
125
+ * if (isColor(test)) {
126
+ * console.log("It\'s a color!");
127
+ * }
128
+ * ```
129
+ * @category Checks
130
+ */
131
+ export const anyOf = (...values) => {
132
+ const testSet = new Set(values);
133
+ return describePredicate((value) => testSet.has(value), `to be any of: ${joinWithConjunction(values.map((v) => formatDebugValue(v, { maxDepth: 1 })), 'or')}`);
134
+ };
135
+ export function assertAnyOf(values, value, valueName = 'value') {
136
+ assertIterable(values, 'values');
137
+ assertString(valueName, 'valueName');
138
+ const debugValues = [];
139
+ for (const example of values) {
140
+ if (sameValueZero(example, value))
141
+ return;
142
+ debugValues.push(example);
143
+ }
144
+ throw new TypeError(`Expected ${valueName} to be any of: ${joinWithConjunction(debugValues.map((v) => formatDebugValue(v, { maxDepth: 1 })), 'or')}, got ${formatDebugValue(value)} instead.`);
145
+ }
146
+ export function isTuple(...predicates) {
147
+ assertPredicates(predicates);
148
+ return describePredicate((value) => {
149
+ return (isArray(value) &&
150
+ value.length === predicates.length &&
151
+ predicates.every((predicate, index) => predicate(value[index])));
152
+ }, `to be a tuple [${predicates
153
+ .map((predicate) => {
154
+ const descriptor = getPredicateDescriptor(predicate);
155
+ return hasProp(descriptor, 'type') ?
156
+ descriptor.type
157
+ : getPredicateConditions(predicate).condition;
158
+ })
159
+ .join(',')}]`);
160
+ }
161
+ export function assertTuple(value, ...rest) {
162
+ let valueName = 'value', predicates;
163
+ if (isString(rest[0])) {
164
+ valueName = rest[0];
165
+ predicates = rest.slice(1);
166
+ }
167
+ else {
168
+ predicates = rest;
169
+ }
170
+ assertPredicates(predicates);
171
+ invariantPredicate(isTuple(...predicates), value, valueName);
172
+ }
173
+ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTERNALS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
174
+ function assertPredicates(predicates) {
175
+ assertArray(predicates, isFunction, 'predicates');
176
+ }
177
+ /* ───────────────────────────────── Types ────────────────────────────────── */
178
+ //# sourceMappingURL=hlf.js.map
@@ -0,0 +1,73 @@
1
+ /**
2
+ * This module provides type guards, assertions, and related utilities for JavaScript types.
3
+ *
4
+ * @module
5
+ * @showCategories
6
+ * @importTarget ./guards
7
+ */
8
+ import type { DescribePredicateFn, DescribeTypePredicateFn, FormatDebugValueFn, FormatErrorFn, FormatPredicateExpectedMessageFn, GetPredicateDescriptorFn, InvariantFn, InvariantPredicateFn } from './types.js';
9
+ import { objectTag, shortObjectTag } from './format.js';
10
+ export type * from './types.js';
11
+ export { assertArray, assertBoolean, assertDate, assertDef, assertError, assertFunction, assertMap, assertNotNil, assertNumber, assertObject, assertPrimitive, assertPropKey, assertRegExp, assertSet, assertString, assertSymbol, assertWeakMapLike, assertWeakSetLike, callPredicate, } from './assert.js';
12
+ export * from './check.js';
13
+ export { formatDebugType } from './format.js';
14
+ export * from './hlf.js';
15
+ export * from './prop.js';
16
+ export { objectTag, shortObjectTag };
17
+ /**
18
+ * {@link InvariantFn} implementation.
19
+ *
20
+ * @inheritDoc {@link InvariantFn}
21
+ * @category Assertions
22
+ */
23
+ export declare const invariant: InvariantFn;
24
+ /**
25
+ * {@link InvariantPredicateFn} implementation.
26
+ *
27
+ * @inheritDoc {@link InvariantPredicateFn}
28
+ * @category Assertions
29
+ */
30
+ export declare const invariantPredicate: InvariantPredicateFn;
31
+ /**
32
+ * {@link DescribeTypePredicateFn} implementation.
33
+ *
34
+ * @inheritDoc {@link DescribeTypePredicateFn}
35
+ * @category Describing
36
+ */
37
+ export declare const describeTypePredicate: DescribeTypePredicateFn;
38
+ /**
39
+ * {@link DescribePredicateFn} implementation.
40
+ *
41
+ * @inheritDoc {@link DescribePredicateFn}
42
+ * @category Describing
43
+ */
44
+ export declare const describePredicate: DescribePredicateFn;
45
+ /**
46
+ * {@link GetPredicateDescriptorFn} implementation.
47
+ *
48
+ * @inheritDoc {@link GetPredicateDescriptorFn}
49
+ * @category Describing
50
+ */
51
+ export declare const getPredicateDescriptor: GetPredicateDescriptorFn;
52
+ /**
53
+ * {@link FormatPredicateExpectedMessageFn} implementation.
54
+ *
55
+ * @inheritDoc {@link FormatPredicateExpectedMessageFn}
56
+ * @category Formatting
57
+ */
58
+ export declare const formatPredicateExpectedMessage: FormatPredicateExpectedMessageFn;
59
+ /**
60
+ * {@link FormatErrorFn} implementation.
61
+ *
62
+ * @inheritDoc {@link FormatErrorFn}
63
+ * @category Formatting
64
+ */
65
+ export declare const formatError: FormatErrorFn;
66
+ /**
67
+ * {@link FormatDebugValueFn} implementation.
68
+ *
69
+ * @inheritDoc {@link FormatDebugValueFn}
70
+ * @category Formatting
71
+ */
72
+ export declare const formatDebugValue: FormatDebugValueFn;
73
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,124 @@
1
+ /**
2
+ * This module provides type guards, assertions, and related utilities for JavaScript types.
3
+ *
4
+ * @module
5
+ * @showCategories
6
+ * @importTarget ./guards
7
+ */
8
+ import { invariant as _invariant, invariantPredicate as _invariantPredicate, assertBoolean, assertError, assertFunction, assertString, } from './assert.js';
9
+ import { isFunction, isInteger, isNonNegative, isNumber, isObject, isString, isTrue, isUndef, isWeakSetLike, } from './check.js';
10
+ import { describePredicate as _describePredicate, describeTypePredicate as _describeTypePredicate, getPredicateDescriptor as _getPredicateDescriptor, } from './describe.js';
11
+ import { formatDebugValue as _formatDebugValue, formatError as _formatError, formatPredicateExpectedMessage as _formatPredicateExpectedMessage, objectTag, shortObjectTag, } from './format.js';
12
+ import { assertSome, everyPredicate } from './hlf.js';
13
+ import { assertOptionalProp } from './prop.js';
14
+ // Value exports
15
+ export { assertArray, assertBoolean, assertDate, assertDef, assertError, assertFunction, assertMap, assertNotNil, assertNumber, assertObject, assertPrimitive, assertPropKey, assertRegExp, assertSet, assertString, assertSymbol, assertWeakMapLike, assertWeakSetLike, callPredicate, } from './assert.js';
16
+ export * from './check.js';
17
+ export { formatDebugType } from './format.js';
18
+ export * from './hlf.js';
19
+ export * from './prop.js';
20
+ export { objectTag, shortObjectTag };
21
+ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~ TYPE-SAFE WRAPPERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
22
+ /* ─────────────────────────────── assert.ts ──────────────────────────────── */
23
+ /**
24
+ * {@link InvariantFn} implementation.
25
+ *
26
+ * @inheritDoc {@link InvariantFn}
27
+ * @category Assertions
28
+ */
29
+ export const invariant = (condition, message = formatPredicateExpectedMessage(isTrue, false, 'condition')) => {
30
+ assertBoolean(condition, 'condition');
31
+ assertSome(message, 'message', isString, isFunction);
32
+ _invariant(condition, isString(message) ? message : (() => {
33
+ const result = message();
34
+ assertString(result, 'message function result');
35
+ return result;
36
+ }));
37
+ };
38
+ /**
39
+ * {@link InvariantPredicateFn} implementation.
40
+ *
41
+ * @inheritDoc {@link InvariantPredicateFn}
42
+ * @category Assertions
43
+ */
44
+ export const invariantPredicate = (predicate, value, valueName = 'value') => {
45
+ assertFunction(predicate);
46
+ assertString(valueName);
47
+ _invariantPredicate(predicate, value, valueName);
48
+ };
49
+ /* ────────────────────────────── describe.ts ─────────────────────────────── */
50
+ /**
51
+ * {@link DescribeTypePredicateFn} implementation.
52
+ *
53
+ * @inheritDoc {@link DescribeTypePredicateFn}
54
+ * @category Describing
55
+ */
56
+ export const describeTypePredicate = (typeGuard, typeDescription) => {
57
+ assertFunction(typeGuard, 'typeGuard');
58
+ assertString(typeDescription, 'typeDescription');
59
+ return _describeTypePredicate(typeGuard, typeDescription);
60
+ };
61
+ /**
62
+ * {@link DescribePredicateFn} implementation.
63
+ *
64
+ * @inheritDoc {@link DescribePredicateFn}
65
+ * @category Describing
66
+ */
67
+ export const describePredicate = (predicate, conditionDescription) => {
68
+ assertFunction(predicate, 'predicate');
69
+ assertString(conditionDescription, 'conditionDescription');
70
+ return _describePredicate(predicate, conditionDescription);
71
+ };
72
+ /**
73
+ * {@link GetPredicateDescriptorFn} implementation.
74
+ *
75
+ * @inheritDoc {@link GetPredicateDescriptorFn}
76
+ * @category Describing
77
+ */
78
+ export const getPredicateDescriptor = (predicate) => {
79
+ assertFunction(predicate, 'predicate');
80
+ return _getPredicateDescriptor(predicate);
81
+ };
82
+ /* ─────────────────────────────── format.ts ──────────────────────────────── */
83
+ /**
84
+ * {@link FormatPredicateExpectedMessageFn} implementation.
85
+ *
86
+ * @inheritDoc {@link FormatPredicateExpectedMessageFn}
87
+ * @category Formatting
88
+ */
89
+ export const formatPredicateExpectedMessage = (predicate, value, valueName = 'value') => {
90
+ assertFunction(predicate);
91
+ assertString(valueName, 'valueName');
92
+ return _formatPredicateExpectedMessage(predicate, value, valueName);
93
+ };
94
+ /**
95
+ * {@link FormatErrorFn} implementation.
96
+ *
97
+ * @inheritDoc {@link FormatErrorFn}
98
+ * @category Formatting
99
+ */
100
+ export const formatError = (error, options) => {
101
+ assertError(error);
102
+ assertFormatOptions(options);
103
+ return _formatError(error, options);
104
+ };
105
+ /**
106
+ * {@link FormatDebugValueFn} implementation.
107
+ *
108
+ * @inheritDoc {@link FormatDebugValueFn}
109
+ * @category Formatting
110
+ */
111
+ export const formatDebugValue = (value, options) => {
112
+ assertFormatOptions(options);
113
+ return _formatDebugValue(value, options);
114
+ };
115
+ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ INTERNALS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
116
+ /* ─────────────────────────────── Utilities ──────────────────────────────── */
117
+ function assertFormatOptions(options) {
118
+ assertSome(options, 'options', isObject, isUndef);
119
+ const numberKeys = ['maxDepth', 'maxLength', 'maxItems'];
120
+ for (const key of numberKeys)
121
+ assertOptionalProp(options, key, everyPredicate(isNumber, isNonNegative, isInteger));
122
+ assertOptionalProp(options, 'seen', isWeakSetLike, 'options');
123
+ }
124
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,102 @@
1
+ import type { Predicate } from '@budsbox/lib-types';
2
+ /**
3
+ * Creates an expected message string for a given predicate, value, and value name.
4
+ *
5
+ * This function validates that the predicate is a valid function and constructs
6
+ * an informative error message describing what was expected of the `value` in
7
+ * terms of the `predicate`'s description or descriptor. This message integrates
8
+ * details about the provided `value` to aid debugging.
9
+ *
10
+ * @internal
11
+ * @param predicate - The predicate function used to test the value. Must be a valid function.
12
+ * @param value - The value being evaluated against the predicate.
13
+ * @param valueName - The name of the value being tested. Defaults to `'value'`.
14
+ * @returns A formatted string message describing the expected value and its type.
15
+ * @throws {TypeError} if the `predicate` is not a function.
16
+ */
17
+ export declare const formatPredicateExpectedMessage: (predicate: Predicate, value: unknown, valueName?: string) => string;
18
+ /**
19
+ * Generates a description of the conditions associated with a given predicate.
20
+ * The description includes whether the predicate is a type guard, a value check, or both.
21
+ *
22
+ * @internal
23
+ * @param predicate - The predicate whose conditions are to be analyzed and described.
24
+ * @param nested - A flag indicating if the predicate is part of a nested structure. Defaults to `false`.
25
+ * @returns An object comprising:
26
+ * - `condition`: A string describing the predicate's conditions.
27
+ * - `isType`: A boolean indicating whether the predicate is a type guard.
28
+ * - `isValue`: A boolean indicating whether the predicate checks a value.
29
+ * @typeParam Predicate - The expected type of the predicate parameter.
30
+ */
31
+ export declare const getPredicateConditions: (predicate: Predicate, nested?: boolean) => {
32
+ condition: string;
33
+ isType: boolean;
34
+ isValue: boolean;
35
+ };
36
+ /**
37
+ * Determines the type description of a given value in a human-readable format.
38
+ *
39
+ * - If the value is `null`, `undefined`, or a `Symbol`, it will return the string representation.
40
+ * - If the value is a primitive type (e.g., `number`, `string`, `boolean`), it will return the result of `typeof value`.
41
+ * - If the value is a function, it will return `'function'`.
42
+ * - If the value is an array, it will return `'array'`.
43
+ * - For objects, it will return the `Symbol.toStringTag` or the internal `[[Class]]` property of the object.
44
+ *
45
+ * @param value - The value whose type needs to be determined.
46
+ * @returns A string representation of the value's type.
47
+ */
48
+ export declare const debugValueType: (value: unknown) => string;
49
+ /**
50
+ * Generates a string representation of a given value for debugging purposes.
51
+ *
52
+ * The function handles various data types and outputs an appropriate string representation:
53
+ * - Strings are truncated to 15 characters and represented in JSON format.
54
+ * - Primitives are converted to their string form.
55
+ * - Functions are represented by their name or identified as anonymous.
56
+ * - Arrays are truncated to a preview of up to 5 elements, followed by `...` if there are more.
57
+ * - Objects attempt to serialize to JSON, truncating lengthy results, or falling back to custom fallback logic.
58
+ *
59
+ * @param value - A value of any type to be represented as a debug string.
60
+ * @param options
61
+ * @returns A debug-friendly string representation of the provided value.
62
+ */
63
+ export declare const debugValueString: (value: unknown, { maxLength, maxDepth, maxItems, seen, }?: {
64
+ maxLength?: number | undefined;
65
+ maxDepth?: number | undefined;
66
+ maxItems?: number | undefined;
67
+ seen?: WeakSet<unknown> | undefined;
68
+ }) => string;
69
+ /**
70
+ *
71
+ * @param value
72
+ */
73
+ export declare const formatError: (value: Error) => string;
74
+ /**
75
+ * Constructs a dot-notation or bracket-notation string representation
76
+ * for accessing nested properties of an object based on the provided keys.
77
+ *
78
+ * @internal
79
+ * @param sourceName - The base name of the object or source from which properties are being accessed.
80
+ * @param keys - A variadic list of property keys representing the nested path.
81
+ * Each key will be used to generate the accessor string.
82
+ * @returns A string representing the accessor path in dot-notation for valid identifiers
83
+ * or bracket-notation for non-identifier keys.
84
+ * @remarks The function is intended to be used for generating error messages.
85
+ */
86
+ export declare const formatAccessString: (sourceName: string, ...keys: readonly PropertyKey[]) => string;
87
+ /**
88
+ * Extracts and returns the `Symbol.toStringTag` or internal `[[Class]]` property of a given object as a string.
89
+ *
90
+ * The method utilizes `Object.prototype.toString` to determine the object type
91
+ * and removes the surrounding `[object ...]` syntax to provide the type name.
92
+ *
93
+ * @param value - The input value from which the object tag will be extracted.
94
+ * @returns The name of the internal `[[Class]]` corresponding to the input value.
95
+ */
96
+ export declare const shortObjectTag: (value: unknown) => string;
97
+ /**
98
+ *
99
+ * @param value
100
+ */
101
+ export declare const objectTag: (value: unknown) => string;
102
+ //# sourceMappingURL=message.d.ts.map