@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,224 @@
1
+ import { entries } from '#object';
2
+ import { isArray, isDate, isError, isFunction, isMap, isNil, isNotNil, isObject, isPrimitive, isSet, isString, isSymbol, isWeakMapLike, isWeakSetLike, } from './check.js';
3
+ import { getPredicateDescriptor } from './describe.js';
4
+ /**
5
+ * Creates an expected message string for a given predicate, value, and value name.
6
+ *
7
+ * This function validates that the predicate is a valid function and constructs
8
+ * an informative error message describing what was expected of the `value` in
9
+ * terms of the `predicate`'s description or descriptor. This message integrates
10
+ * details about the provided `value` to aid debugging.
11
+ *
12
+ * @internal
13
+ * @param predicate - The predicate function used to test the value. Must be a valid function.
14
+ * @param value - The value being evaluated against the predicate.
15
+ * @param valueName - The name of the value being tested. Defaults to `'value'`.
16
+ * @returns A formatted string message describing the expected value and its type.
17
+ * @throws {TypeError} if the `predicate` is not a function.
18
+ */
19
+ export const formatPredicateExpectedMessage = (predicate, value, valueName = 'value') => {
20
+ const { condition, isType, isValue } = getPredicateConditions(predicate);
21
+ return `Expected ${valueName} ${condition}, got${isType ? ` ${debugValueType(value)}` : ''}${isValue ?
22
+ isType ? [' (', debugValueString(value), ')'].join('')
23
+ : ` ${debugValueString(value)}`
24
+ : ''} instead`;
25
+ };
26
+ /**
27
+ * Generates a description of the conditions associated with a given predicate.
28
+ * The description includes whether the predicate is a type guard, a value check, or both.
29
+ *
30
+ * @internal
31
+ * @param predicate - The predicate whose conditions are to be analyzed and described.
32
+ * @param nested - A flag indicating if the predicate is part of a nested structure. Defaults to `false`.
33
+ * @returns An object comprising:
34
+ * - `condition`: A string describing the predicate's conditions.
35
+ * - `isType`: A boolean indicating whether the predicate is a type guard.
36
+ * - `isValue`: A boolean indicating whether the predicate checks a value.
37
+ * @typeParam Predicate - The expected type of the predicate parameter.
38
+ */
39
+ export const getPredicateConditions = (predicate, nested = false) => {
40
+ const descriptor = getPredicateDescriptor(predicate);
41
+ if (isNil(descriptor))
42
+ return {
43
+ condition: defaultDescription(predicate),
44
+ isType: false,
45
+ isValue: true,
46
+ };
47
+ const descriptorEntry = entries(descriptor)[0];
48
+ if (descriptorEntry[0] === 'condition') {
49
+ return { condition: descriptorEntry[1], isType: false, isValue: true };
50
+ }
51
+ else if (descriptorEntry[0] === 'type') {
52
+ return {
53
+ condition: nested ? descriptorEntry[1] : `to be ${descriptorEntry[1]}`,
54
+ isType: true,
55
+ isValue: false,
56
+ };
57
+ }
58
+ else {
59
+ const [conjunction, predicates] = descriptorEntry;
60
+ const separator = `, ${conjunction} `;
61
+ let isType = false, isValue = false;
62
+ const typeGuards = [];
63
+ const plains = [];
64
+ for (const p of predicates) {
65
+ const pc = getPredicateConditions(p, true);
66
+ isType || (isType = pc.isType);
67
+ isValue || (isValue = pc.isValue);
68
+ if (pc.isValue) {
69
+ plains.push(pc.isType ? `(${pc.condition})` : pc.condition);
70
+ }
71
+ else if (pc.isType) {
72
+ typeGuards.push(pc.condition);
73
+ }
74
+ }
75
+ const typeGuardString = typeGuards.length === 1 ?
76
+ typeGuards[0]
77
+ : [typeGuards.slice(0, -1).join(',')]
78
+ .concat(typeGuards.slice(-1))
79
+ .join(separator);
80
+ const plainString = plains.join(separator);
81
+ const isPrintableTypes = typeGuards.length > 0;
82
+ const condition = `${isPrintableTypes ? `to be ${typeGuardString}` : ''}${isValue ? `${isPrintableTypes ? separator : ''}${plainString}` : ''}`;
83
+ return { condition, isType, isValue };
84
+ }
85
+ };
86
+ /**
87
+ * Determines the type description of a given value in a human-readable format.
88
+ *
89
+ * - If the value is `null`, `undefined`, or a `Symbol`, it will return the string representation.
90
+ * - If the value is a primitive type (e.g., `number`, `string`, `boolean`), it will return the result of `typeof value`.
91
+ * - If the value is a function, it will return `'function'`.
92
+ * - If the value is an array, it will return `'array'`.
93
+ * - For objects, it will return the `Symbol.toStringTag` or the internal `[[Class]]` property of the object.
94
+ *
95
+ * @param value - The value whose type needs to be determined.
96
+ * @returns A string representation of the value's type.
97
+ */
98
+ export const debugValueType = (value) => {
99
+ if (isNil(value) || isSymbol(value))
100
+ return String(value);
101
+ if (Number.isNaN(value))
102
+ return 'NaN';
103
+ if (isPrimitive(value))
104
+ return typeof value;
105
+ if (isFunction(value))
106
+ return 'function';
107
+ if (isArray(value))
108
+ return 'array';
109
+ const proto = Object.getPrototypeOf(value);
110
+ if (proto === Object.prototype || proto === null)
111
+ return 'object';
112
+ return `${objectTag(value)} object`;
113
+ };
114
+ /**
115
+ * Generates a string representation of a given value for debugging purposes.
116
+ *
117
+ * The function handles various data types and outputs an appropriate string representation:
118
+ * - Strings are truncated to 15 characters and represented in JSON format.
119
+ * - Primitives are converted to their string form.
120
+ * - Functions are represented by their name or identified as anonymous.
121
+ * - Arrays are truncated to a preview of up to 5 elements, followed by `...` if there are more.
122
+ * - Objects attempt to serialize to JSON, truncating lengthy results, or falling back to custom fallback logic.
123
+ *
124
+ * @param value - A value of any type to be represented as a debug string.
125
+ * @param options
126
+ * @returns A debug-friendly string representation of the provided value.
127
+ */
128
+ export const debugValueString = (value, { maxLength = 15, maxDepth = 2, maxItems = 3, seen = new WeakSet(), } = {}) => {
129
+ if (isString(value)) {
130
+ return JSON.stringify(clamp(value, maxLength));
131
+ }
132
+ if (isPrimitive(value))
133
+ return String(value);
134
+ if (seen.has(value))
135
+ return '[Circular]';
136
+ if (isFunction(value))
137
+ return value.name.length > 0 ?
138
+ `function ${value.name}`
139
+ : 'anonymous function';
140
+ if (isArray(value)) {
141
+ if (maxDepth === 0)
142
+ return '[...]';
143
+ const debugSlice = value.slice(0, maxItems).map((item) => debugValueString(item, {
144
+ maxLength,
145
+ maxDepth: maxDepth - 1,
146
+ maxItems,
147
+ seen,
148
+ }));
149
+ return `[${debugSlice.join(',')}${value.length > maxItems ? ', ...' : ''}]`;
150
+ }
151
+ if (isDate(value))
152
+ return `Date(${Number.isNaN(value.getTime()) ? 'Invalid' : value.toISOString()})`;
153
+ if (isError(value))
154
+ return `${value.name}(${debugValueString(value.message)})`;
155
+ const tag = shortObjectTag(value);
156
+ if (isMap(value) || isSet(value))
157
+ return `${tag}(${String(value.size)})`;
158
+ if (isWeakMapLike(value) || isWeakSetLike(value))
159
+ return `${tag}(?)`;
160
+ if ('toString' in value &&
161
+ // eslint-disable-next-line @typescript-eslint/unbound-method
162
+ isFunction(value.toString) &&
163
+ value.toString !== Object.prototype.toString) {
164
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
165
+ return `${tag}(${value.toString()})`;
166
+ }
167
+ try {
168
+ return `${tag}(${clamp(JSON.stringify(value), maxLength)})`;
169
+ }
170
+ catch {
171
+ return `${shortObjectTag(value)} object`;
172
+ }
173
+ };
174
+ /**
175
+ *
176
+ * @param value
177
+ */
178
+ export const formatError = (value) => {
179
+ const { name, message } = value;
180
+ let codePart, causePart;
181
+ };
182
+ /**
183
+ * Constructs a dot-notation or bracket-notation string representation
184
+ * for accessing nested properties of an object based on the provided keys.
185
+ *
186
+ * @internal
187
+ * @param sourceName - The base name of the object or source from which properties are being accessed.
188
+ * @param keys - A variadic list of property keys representing the nested path.
189
+ * Each key will be used to generate the accessor string.
190
+ * @returns A string representing the accessor path in dot-notation for valid identifiers
191
+ * or bracket-notation for non-identifier keys.
192
+ * @remarks The function is intended to be used for generating error messages.
193
+ */
194
+ export const formatAccessString = (sourceName, ...keys) => keys.reduce((acc, key) => `${acc}${isString(key) && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? `.${key}` : `[${debugValueString(key)}]`}`, sourceName);
195
+ /**
196
+ * Extracts and returns the `Symbol.toStringTag` or internal `[[Class]]` property of a given object as a string.
197
+ *
198
+ * The method utilizes `Object.prototype.toString` to determine the object type
199
+ * and removes the surrounding `[object ...]` syntax to provide the type name.
200
+ *
201
+ * @param value - The input value from which the object tag will be extracted.
202
+ * @returns The name of the internal `[[Class]]` corresponding to the input value.
203
+ */
204
+ export const shortObjectTag = (value) => Object.prototype.toString.call(value).slice(8, -1);
205
+ /**
206
+ *
207
+ * @param value
208
+ */
209
+ export const objectTag = (value) => {
210
+ if (isObject(value)) {
211
+ const ctor = [
212
+ value.constructor,
213
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
214
+ Object.getPrototypeOf(value)?.constructor,
215
+ ].find(isFunction);
216
+ const ctorName = isNotNil(ctor) && ctor.name ? ctor.name : 'Object';
217
+ const tag = Symbol.toStringTag in value ? value[Symbol.toStringTag] : ctorName;
218
+ return `${ctorName}${isString(tag) && tag !== ctorName ? `[${tag}]` : ''}`;
219
+ }
220
+ return shortObjectTag(value);
221
+ };
222
+ const defaultDescription = (predicate) => `to satisfy ${predicate.name || '(anonymous)'} predicate`;
223
+ const clamp = (str, maxLength) => str.length > maxLength ? `${str.slice(0, maxLength)}...` : str;
224
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1,232 @@
1
+ import type { IsNever, IsUnknown, IterableElement, KeysOfUnion } from 'type-fest';
2
+ import type { AnyRecord, CustomRecord, DistributedPropValue, Infer, IsEmptyObject, NarrowedType, Nil, Predicate, TypePredicate, Undef, ValuePredicate, WithFallback } from '@budsbox/lib-types';
3
+ /** @ignore */
4
+ export declare function hasProp(source: Nil, prop: PropertyKey, ...rest: HasPropRest): source is never;
5
+ /** @ignore */
6
+ export declare function hasProp(source: unknown, prop: ProtectedKey, ...rest: HasPropRest): source is never;
7
+ /**
8
+ * Checks if a property exists on the provided source object.
9
+ *
10
+ * Narrows the source type to include the specified property key with an unknown value.
11
+ *
12
+ * @param source - The object to check.
13
+ * @param key - The property key to verify.
14
+ * @param checkProto - Whether to check the prototype chain.
15
+ * @returns Boolean indicating whether the property exists.
16
+ * @throws {@link !TypeError} If the provided key is not a valid property key.
17
+ * @throws {@link !TypeError} If the provided checkProto flag is not a boolean.
18
+ * @typeParam TSource - The source object type.
19
+ * @typeParam TKey - The property key type.
20
+ * @remarks The `__proto__` and `constructor` keys are always considered non-existent.
21
+ * {@label NO_PREDICATE}
22
+ * @category Checks
23
+ */
24
+ export declare function hasProp<TSource, TKey extends PropertyKey>(source: TSource, key: TKey, checkProto?: boolean): source is SourceNarrowed<TSource, TKey>;
25
+ /**
26
+ * Checks if a property exists on a non-null source and passes a type guard test.
27
+ *
28
+ * Narrows both the source type and the property value type based on the provided type guard.
29
+ *
30
+ * @param source - The object to check.
31
+ * @param key - The property key to verify.
32
+ * @param typeGuard - A type guard to narrow the property value type.
33
+ * Accepts the property value as the only parameter.
34
+ * @param checkProto - Whether to check the prototype chain.
35
+ * @returns Boolean indicating whether the property exists and satisfies the type guard.
36
+ * @throws {@link !TypeError} In the following cases:
37
+ * - If the provided `key` is not a valid property key.
38
+ * - If the provided `checkProto` flag is not a boolean.
39
+ * - If the provided type guard is not a function.
40
+ * - If the provided type guard does not return a boolean.
41
+ * @typeParam TSource - The source object type.
42
+ * @typeParam TKey - The property key type.
43
+ * @typeParam TGuard - The type guard type.
44
+ * @remarks The `__proto__` and `constructor` keys are always considered non-existent.
45
+ * {@label TYPE_GUARD}
46
+ */
47
+ export declare function hasProp<TSource, TKey extends PropertyKey, TGuard extends TypePredicate<PropValue<TSource, TKey>>>(source: TSource, key: TKey, typeGuard: TGuard, checkProto?: boolean): source is SourceNarrowedWithTypeGuard<TSource, TKey, TGuard>;
48
+ /**
49
+ * Checks if a property exists on the provided source and optionally passes a test.
50
+ *
51
+ * This overload doesn't narrow a type,
52
+ * because the predicate may reject valid property values without invalidating their existence,
53
+ * which would cause incorrect type elimination in the `else` branch.
54
+ * If you need type narrowing for the property value, use the type guard overload instead.
55
+ * Alternatively, you can split the checks: `hasProp(source, key) && test(source[key])`.
56
+ *
57
+ * @param source - The object to check.
58
+ * @param key - The property key to verify.
59
+ * @param predicate - An optional predicate to test the property value.
60
+ * Accepts the property value as the only parameter.
61
+ * @param checkProto - Whether to check the prototype chain.
62
+ * @returns Boolean indicating whether the property exists and satisfies the test.
63
+ * @throws {@link !TypeError} In the following cases:
64
+ * - If the provided key is not a valid property key.
65
+ * - If the provided checkProto flag is not a boolean.
66
+ * - If the provided predicate is not a function.
67
+ * - If the provided predicate does not return a boolean.
68
+ * @remarks The `__proto__` and `constructor` keys are always considered non-existent.
69
+ * @typeParam TSource - The source object type.
70
+ * @typeParam TKey - The property key type.
71
+ * {@label PREDICATE}
72
+ */
73
+ export declare function hasProp<TSource, TKey extends PropertyKey>(source: TSource, key: TKey, predicate: ValuePredicate<PropValue<TSource, TKey>>, checkProto?: boolean): boolean;
74
+ /** @ignore */
75
+ export declare function assertProp(source: Nil, key: PropertyKey, ...rest: AssertPropRest): never;
76
+ /** @ignore */
77
+ export declare function assertProp(source: unknown, key: ProtectedKey, ...rest: AssertPropRest): never;
78
+ /**
79
+ * Asserts that a property exists on the provided source object.
80
+ *
81
+ * Narrows the source type to include the specified property key with an unknown value.
82
+ *
83
+ * @param source - The object to check.
84
+ * @param key - The property key to verify.
85
+ * @param rest - Optional parameters: checkProto flag and sourceName for error messages.
86
+ * @returns void if the assertion succeeds, otherwise throws an error.
87
+ * {@label NO_PREDICATE}
88
+ * @throws {@link !TypeError} In the following cases:
89
+ * - If the source is nil.
90
+ * - If the provided key is not a valid property key.
91
+ * - If the property does not exist.
92
+ * @typeParam TSource - The source object type.
93
+ * @typeParam TKey - The property key type.
94
+ * @remarks The `__proto__` and `constructor` keys are always considered non-existent.
95
+ * @category Assertions
96
+ */
97
+ export declare function assertProp<TSource, TKey extends StrictKey<TSource>>(source: TSource, key: TKey, ...rest: WithoutPredicate<AssertPropRest>): asserts source is SourceNarrowed<TSource, TKey>;
98
+ /**
99
+ * Asserts that a property exists on a non-null source and passes a type guard test.
100
+ *
101
+ * Narrows both the source type and the property value type based on the provided type guard.
102
+ *
103
+ * @param source - The object to check.
104
+ * @param key - The property key to verify.
105
+ * @param typeGuard - A type guard to narrow the property value type.
106
+ * Accepts the property value as the only parameter.
107
+ * @param rest - Optional parameters: `checkProto` flag and `sourceName` for error messages.
108
+ * @returns void if the assertion succeeds, otherwise throws an error.
109
+ * {@label TYPE_GUARD}
110
+ * @throws {@link !TypeError} In the following cases:
111
+ * - If the source is nil.
112
+ * - If the provided key is not a valid property key.
113
+ * - If the property does not exist.
114
+ * - If the provided type guard is not a function.
115
+ * - If the provided type guard does not return a boolean.
116
+ * - If the property value fails the type guard test.
117
+ * @typeParam TSource - The source object type.
118
+ * @typeParam TKey - The property key type.
119
+ * @typeParam TGuard - The type guard type.
120
+ * @remarks The `__proto__` and `constructor` keys are always considered non-existent.
121
+ * @category Assertions
122
+ */
123
+ export declare function assertProp<TSource, TKey extends StrictKey<TSource>, TGuard extends TypePredicate<PropValue<TSource, TKey>>>(source: TSource, key: TKey, typeGuard: TGuard, ...rest: WithoutPredicate<AssertPropRest>): asserts source is SourceNarrowedWithTypeGuard<TSource, TKey, TGuard>;
124
+ /**
125
+ * Asserts that a property exists on the provided source and optionally passes a test.
126
+ *
127
+ * @param source - The object to check.
128
+ * @param key - The property key to verify.
129
+ * @param predicate - An optional predicate to test the property value.
130
+ * Accepts the property value as the only parameter.
131
+ * @param rest - Optional parameters: checkProto flag and sourceName for error messages.
132
+ * @returns void if the assertion succeeds, otherwise throws an error.
133
+ * {@label PREDICATE}
134
+ * @throws {@link !TypeError} In the following cases:
135
+ * - If the source is nil.
136
+ * - If the provided key is not a valid property key.
137
+ * - If the property does not exist.
138
+ * - If the provided predicate is not a function.
139
+ * - If the provided predicate does not return a boolean.
140
+ * - If the property value fails the predicate test.
141
+ * @typeParam TSource - The source object type.
142
+ * @typeParam TKey - The property key type.
143
+ * @remarks The `__proto__` and `constructor` keys are always considered non-existent.
144
+ * @category Assertions
145
+ */
146
+ export declare function assertProp<TSource, TKey extends StrictKey<TSource>>(source: TSource, key: TKey, predicate?: ValuePredicate<PropValue<TSource, TKey>>, ...rest: WithoutPredicate<AssertPropRest>): asserts source is SourceNarrowed<TSource, TKey>;
147
+ /**
148
+ * Asserts that a property either does not exist or passes a type guard test.
149
+ *
150
+ * Narrows both the source type and the property value type based on the provided type guard.
151
+ *
152
+ * @param source - The object to check.
153
+ * @param key - The property key to verify.
154
+ * @param typeGuard - A type guard to narrow the property value type.
155
+ * Accepts the property value as the only parameter.
156
+ * @param rest - Optional parameters: `checkProto` flag and `sourceName` for error messages.
157
+ * @returns void.
158
+ * {@label TYPE_GUARD}
159
+ * @throws {@link !TypeError} In the following cases:
160
+ * - If the provided key is not a valid property key.
161
+ * - If the provided type guard is not a function.
162
+ * - If the provided type guard does not return a boolean.
163
+ * - If the property exists but fails the type guard test.
164
+ * @typeParam TSource - The source object type.
165
+ * @typeParam TKey - The property key type.
166
+ * @typeParam TGuard - The type guard type.
167
+ * @remarks The `__proto__` and `constructor` keys are always considered non-existent.
168
+ * @category Assertions
169
+ */
170
+ export declare function assertOptionalProp<TSource, TKey extends PropertyKey, TGuard extends TypePredicate<PropValue<TSource, TKey>>>(source: TSource, key: TKey, typeGuard: TGuard, ...rest: WithoutPredicate<AssertPropRest>): asserts source is SourceEliminated<TSource, TKey> | SourceNarrowedWithTypeGuard<TSource, TKey, TGuard, true>;
171
+ /**
172
+ * Asserts that a property either does not exist or passes a predicate test.
173
+ *
174
+ * @param source - The object to check.
175
+ * @param key - The property key to verify.
176
+ * @param predicate - A predicate to test the property value if it exists.
177
+ * Accepts the property value as the only parameter.
178
+ * @param rest - Optional parameters: `checkProto` flag and `sourceName` for error messages.
179
+ * @returns void.
180
+ * {@label PREDICATE}
181
+ * @throws {@link !TypeError} In the following cases:
182
+ * - If the provided key is not a valid property key.
183
+ * - If the provided predicate is not a function.
184
+ * - If the provided predicate does not return a boolean.
185
+ * - If the property exists but fails the predicate test.
186
+ * @typeParam TSource - The source object type.
187
+ * @typeParam TKey - The property key type.
188
+ * @remarks The `__proto__` and `constructor` keys are always considered non-existent.
189
+ * @category Assertions
190
+ */
191
+ export declare function assertOptionalProp<TSource, TKey extends PropertyKey>(source: TSource, key: TKey, predicate: ValuePredicate<PropValue<TSource, TKey>>, ...rest: WithoutPredicate<AssertPropRest>): asserts source is SourceEliminated<TSource, TKey> | SourceNarrowed<TSource, TKey, true>;
192
+ declare const protectedKeys: Set<"constructor" | "__proto__">;
193
+ type PropValue<TSource, TKey extends PropertyKey> = WithFallback<DistributedPropValue<TSource, TKey, true>>;
194
+ type StrictKey<TSource> = WithFallback<KeysOfUnion<TSource>, PropertyKey>;
195
+ /**
196
+ * Represents a utility type that narrows the source object `TSource`
197
+ * to include a subset of properties defined by `TKey` with their respective value types.
198
+ *
199
+ * If `TSource` is compatible with the specified property key and value criteria,
200
+ * it extends `CustomRecord` to provide the narrowed structure. Otherwise, it falls
201
+ * back to the specified fallback type.
202
+ *
203
+ * @internal
204
+ * @typeParam TSource - The source object type to be narrowed.
205
+ * @typeParam TKey - The property key or keys to narrow down on.
206
+ * @typeParam TPartial - A boolean flag indicating whether the properties in `TKey` should be optional.
207
+ * @inline
208
+ */
209
+ type SourceNarrowed<TSource, TKey extends PropertyKey, TPartial extends boolean = false> = WithFallback<TSource extends AnyRecord<TKey, unknown> ? TSource & CustomRecord<TKey, PropValue<TSource, TKey>, TPartial> : never, TSource & CustomRecord<TKey, PropValue<TSource, TKey>, TPartial>>;
210
+ /**
211
+ * @preventInline
212
+ * @ignore
213
+ */
214
+ type SourceNarrowedWithTypeGuard<TSource, TKey extends PropertyKey, TGuard extends TypePredicate, TPartial extends boolean = false> = WithFallback<TSource extends AnyRecord<TKey, unknown> ? IsNever<TSource[TKey & keyof TSource] & NarrowedType<TGuard>> extends true ? never : TSource & CustomRecord<TKey, NarrowedType<TGuard>, TPartial> : never, TSource & CustomRecord<TKey, NarrowedType<TGuard>, TPartial>>;
215
+ /**
216
+ * @preventInline
217
+ * @ignore
218
+ */
219
+ type SourceEliminated<TSource, TKey extends PropertyKey> = TSource extends Readonly<Record<TKey, unknown>> ? never : TSource extends AnyRecord<TKey, unknown> ? Infer<IsEmptyObject<Omit<TSource, TKey>> extends true ? never : TSource & CustomRecord<TKey, never, true>> : IsUnknown<TSource> extends true ? (null | undefined) & TSource : TSource;
220
+ type HasPropRest = readonly [checkProto?: Undef<boolean>] | readonly [predicate?: Undef<Predicate>, checkProto?: Undef<boolean>] | readonly [predicate?: Undef<Predicate>];
221
+ type AssertPropRest = readonly [
222
+ ...(HasPropRest | []),
223
+ sourceName?: Undef<string>
224
+ ];
225
+ /**
226
+ * @preventInline
227
+ * @ignore
228
+ */
229
+ type WithoutPredicate<TRest extends readonly unknown[]> = Exclude<TRest, readonly [predicate?: Undef<Predicate>, ...rest: unknown[]]>;
230
+ type ProtectedKey = IterableElement<typeof protectedKeys>;
231
+ export {};
232
+ //# sourceMappingURL=prop.d.ts.map
@@ -0,0 +1,45 @@
1
+ import { assertFunction, assertNotNil, assertPropKey, callPredicate, invariant, normalizeOptionalRest, } from './assert.js';
2
+ import { isBoolean, isFunction, isNil, isString } from './check.js';
3
+ import { formatAccessString, formatDebugValue, formatPredicateExpectedMessage, } from './format.js';
4
+ export function hasProp(source, key, ...rest) {
5
+ assertPropKey(key, 'key');
6
+ invariant(rest.length <= 2, () => `Expected 2, 3, or 4 arguments, got ${String(rest.length + 2)} instead.`);
7
+ let predicate = () => true, checkProto = false, index = 0;
8
+ if (isFunction(rest[index]))
9
+ predicate = rest[index++];
10
+ if (isBoolean(rest[index]))
11
+ checkProto = rest[index++];
12
+ invariant(index >= rest.length, () => `Invalid arguments. Unexpected arguments at position ${String(index + 2)}: ${rest
13
+ .slice(index)
14
+ .map((arg) => formatDebugValue(arg, { maxDepth: 1 }))
15
+ .join(', ')}`);
16
+ return (!isNil(source) &&
17
+ propExists(source, key, checkProto) &&
18
+ callPredicate(predicate, source[key]));
19
+ }
20
+ export function assertProp(source, key, ...rest) {
21
+ assertPropKey(key, 'key');
22
+ const [predicate = () => true, checkProto = false, sourceName = 'source'] = normalizeOptionalRest([isFunction, isBoolean, isString], rest, 2);
23
+ assertNotNil(source, sourceName);
24
+ invariant(propExists(source, key, checkProto), () => checkProto ?
25
+ `Expected ${formatAccessString(sourceName, key)} to exist`
26
+ : `Expected ${sourceName} to have own property ${formatDebugValue(key)}`);
27
+ const propValue = source[key];
28
+ invariant(callPredicate(predicate, propValue), () => formatPredicateExpectedMessage(predicate, propValue, formatAccessString(sourceName, key)));
29
+ }
30
+ export function assertOptionalProp(source, key, predicate, ...rest) {
31
+ assertPropKey(key, 'key');
32
+ assertFunction(predicate, 'predicate');
33
+ const [checkProto = false, sourceName = 'source'] = normalizeOptionalRest([isBoolean, isString], rest, 2);
34
+ if (isNil(source) || !propExists(source, key, checkProto))
35
+ return;
36
+ const propValue = source[key];
37
+ invariant(callPredicate(predicate, propValue), () => formatPredicateExpectedMessage(predicate, propValue, formatAccessString(sourceName, key)));
38
+ }
39
+ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Internals ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
40
+ const protectedKeys = new Set(['constructor', '__proto__']);
41
+ const propExists = (source, key, checkProto) =>
42
+ // a little (not exhaustive) guard against prototype pollution
43
+ !protectedKeys.has(key) &&
44
+ (checkProto ? key in Object(source) : Object.hasOwn(source, key));
45
+ //# sourceMappingURL=prop.js.map