@orkestrel/validator 0.0.1

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,297 @@
1
+ import type { AnyConstructor, Guard, GuardType, GuardsShape, IntersectionFromGuards, ShapeGuardResult, TupleFromGuards } from './types.js';
2
+ /**
3
+ * Build an array guard from an element guard or predicate.
4
+ *
5
+ * @param elementGuard - Guard or predicate for each array element.
6
+ * @returns A guard for arrays whose values all satisfy the provided guard.
7
+ * @example
8
+ * ```ts
9
+ * const isStrings = arrayOf(isString)
10
+ * ```
11
+ */
12
+ export declare function arrayOf<T>(elementGuard: Guard<T>): Guard<readonly T[]>;
13
+ export declare function arrayOf(elementGuard: (value: unknown) => boolean): Guard<readonly unknown[]>;
14
+ /**
15
+ * Build a fixed-length tuple guard from per-index guards.
16
+ *
17
+ * @param guards - Guards applied by tuple index.
18
+ * @returns A guard for a tuple that matches the provided index guards.
19
+ * @example
20
+ * ```ts
21
+ * const isPair = tupleOf(isString, isNumber)
22
+ * ```
23
+ */
24
+ export declare function tupleOf<const Gs extends Array<Guard<unknown>>>(...guards: Gs): Guard<TupleFromGuards<Gs>>;
25
+ export declare function tupleOf(...guards: Array<(value: unknown) => boolean>): Guard<readonly unknown[]>;
26
+ /**
27
+ * Build an exact object guard from a guard shape.
28
+ *
29
+ * @param shape - Guards per property.
30
+ * @param optional - Optional keys, or `true` to make every key optional.
31
+ * @returns A guard for an exact object matching the provided shape.
32
+ * @example
33
+ * ```ts
34
+ * const isUser = objectOf({ id: isString, age: isNumber })
35
+ * ```
36
+ */
37
+ export declare function objectOf<S extends GuardsShape>(shape: S): Guard<ShapeGuardResult<S, undefined>>;
38
+ export declare function objectOf<S extends GuardsShape, const K extends Array<keyof S & string>>(shape: S, optional: K): Guard<ShapeGuardResult<S, K>>;
39
+ export declare function objectOf<S extends GuardsShape>(shape: S, optional: true): Guard<ShapeGuardResult<S, true>>;
40
+ /**
41
+ * Create a guard that accepts one of the provided literal values.
42
+ *
43
+ * @param literals - Literal values to accept.
44
+ * @returns A guard for the provided literal union.
45
+ * @example
46
+ * ```ts
47
+ * const isRole = literalOf('user', 'admin')
48
+ * ```
49
+ */
50
+ export declare function literalOf<const Literals extends Array<string | number | boolean>>(...literals: Literals): Guard<Literals[number]>;
51
+ /**
52
+ * Create a guard using `instanceof`.
53
+ *
54
+ * @param constructor - Constructor used for the `instanceof` check.
55
+ * @returns A guard that narrows to instances of the provided constructor.
56
+ * @example
57
+ * ```ts
58
+ * const isDateInstance = instanceOf(Date)
59
+ * ```
60
+ */
61
+ export declare function instanceOf<C extends AnyConstructor>(constructor: C): Guard<InstanceType<C>>;
62
+ /**
63
+ * Create a guard from an enum-like object.
64
+ *
65
+ * @param enumeration - Enum object or enum-like map.
66
+ * @returns A guard that accepts enum values.
67
+ * @example
68
+ * ```ts
69
+ * const isStatus = enumOf({ ok: 'OK', fail: 'FAIL' })
70
+ * ```
71
+ */
72
+ export declare function enumOf<E extends Record<string, string | number>>(enumeration: E): Guard<E[keyof E]>;
73
+ /**
74
+ * Build a Set guard from an element guard or predicate.
75
+ *
76
+ * @param elementGuard - Guard or predicate for each set element.
77
+ * @returns A guard for sets whose elements all satisfy the provided guard.
78
+ * @example
79
+ * ```ts
80
+ * const isNumberSet = setOf(isNumber)
81
+ * ```
82
+ */
83
+ export declare function setOf<T>(elementGuard: Guard<T>): Guard<ReadonlySet<T>>;
84
+ export declare function setOf(elementGuard: (value: unknown) => boolean): Guard<ReadonlySet<unknown>>;
85
+ /**
86
+ * Build a Map guard from key and value guards.
87
+ *
88
+ * @param keyGuard - Guard or predicate for each key.
89
+ * @param valueGuard - Guard or predicate for each value.
90
+ * @returns A guard for maps whose keys and values satisfy the provided guards.
91
+ * @example
92
+ * ```ts
93
+ * const isScores = mapOf(isString, isNumber)
94
+ * ```
95
+ */
96
+ export declare function mapOf<K, V>(keyGuard: Guard<K>, valueGuard: Guard<V>): Guard<ReadonlyMap<K, V>>;
97
+ export declare function mapOf(keyGuard: (value: unknown) => boolean, valueGuard: (value: unknown) => boolean): Guard<ReadonlyMap<unknown, unknown>>;
98
+ /**
99
+ * Build an exact record guard from a guard shape.
100
+ *
101
+ * @param shape - Guards per property.
102
+ * @param optional - Optional keys, or `true` to make every key optional.
103
+ * @returns A guard for an exact record matching the provided shape.
104
+ * @example
105
+ * ```ts
106
+ * const isUser = recordOf({ id: isString, age: isNumber })
107
+ * ```
108
+ */
109
+ export declare function recordOf<S extends GuardsShape>(shape: S): Guard<ShapeGuardResult<S, undefined>>;
110
+ export declare function recordOf<S extends GuardsShape, const K extends Array<keyof S & string>>(shape: S, optional: K): Guard<ShapeGuardResult<S, K>>;
111
+ export declare function recordOf<S extends GuardsShape>(shape: S, optional: true): Guard<ShapeGuardResult<S, true>>;
112
+ /**
113
+ * Build an iterable guard from an element guard or predicate.
114
+ *
115
+ * @param elementGuard - Guard or predicate applied to each iterated value.
116
+ * @returns A guard for iterables whose yielded values satisfy the provided guard.
117
+ * @example
118
+ * ```ts
119
+ * const isNumbers = iterableOf(isNumber)
120
+ * ```
121
+ */
122
+ export declare function iterableOf<T>(elementGuard: Guard<T>): Guard<Iterable<T>>;
123
+ export declare function iterableOf(elementGuard: (value: unknown) => boolean): Guard<Iterable<unknown>>;
124
+ /**
125
+ * Create a guard for keys of the provided object.
126
+ *
127
+ * @param value - Object whose keys form the allowed key set.
128
+ * @returns A guard that accepts keys present on the provided object.
129
+ * @example
130
+ * ```ts
131
+ * const isKey = keyOf({ id: 1, name: 2 })
132
+ * ```
133
+ */
134
+ export declare function keyOf<const O extends Readonly<Record<PropertyKey, unknown>>>(value: O): Guard<keyof O>;
135
+ /**
136
+ * Build a new guard shape by picking specific keys.
137
+ *
138
+ * @param shape - Source shape.
139
+ * @param keys - Keys to keep.
140
+ * @returns A new shape containing only the selected keys.
141
+ * @example
142
+ * ```ts
143
+ * const picked = pickOf({ id: isString, age: isNumber }, ['id'])
144
+ * ```
145
+ */
146
+ export declare function pickOf<S extends GuardsShape, const K extends Array<keyof S & string>>(shape: S, keys: K): Pick<S, K[number]>;
147
+ /**
148
+ * Build a new guard shape by omitting specific keys.
149
+ *
150
+ * @param shape - Source shape.
151
+ * @param keys - Keys to remove.
152
+ * @returns A new shape without the omitted keys.
153
+ * @example
154
+ * ```ts
155
+ * const omitted = omitOf({ id: isString, age: isNumber }, ['age'])
156
+ * ```
157
+ */
158
+ export declare function omitOf<S extends GuardsShape, const K extends Array<keyof S & string>>(shape: S, keys: K): Omit<S, K[number]>;
159
+ /**
160
+ * Combine two guards or predicates with logical AND.
161
+ *
162
+ * @param left - First guard or predicate.
163
+ * @param right - Second guard or predicate.
164
+ * @returns A guard that requires both inputs to pass.
165
+ * @example
166
+ * ```ts
167
+ * const isNonEmptyString = andOf(isString, (value: string) => value.length > 0)
168
+ * ```
169
+ */
170
+ export declare function andOf<A, B>(left: Guard<A>, right: Guard<B>): Guard<A & B>;
171
+ export declare function andOf<T, U extends T>(left: Guard<T>, right: (value: T) => value is U): Guard<U>;
172
+ export declare function andOf<T>(left: Guard<T>, right: (value: T) => boolean): Guard<T>;
173
+ export declare function andOf(left: (value: unknown) => boolean, right: (value: unknown) => boolean): Guard<unknown>;
174
+ /**
175
+ * Combine two guards or predicates with logical OR.
176
+ *
177
+ * @param left - First guard or predicate.
178
+ * @param right - Second guard or predicate.
179
+ * @returns A guard that accepts values from either side.
180
+ * @example
181
+ * ```ts
182
+ * const isLetter = orOf(literalOf('a'), literalOf('b'))
183
+ * ```
184
+ */
185
+ export declare function orOf<A, B>(left: Guard<A>, right: Guard<B>): Guard<A | B>;
186
+ export declare function orOf(left: (value: unknown) => boolean, right: (value: unknown) => boolean): Guard<unknown>;
187
+ /**
188
+ * Negate a guard or predicate.
189
+ *
190
+ * @param guard - Guard or predicate to negate.
191
+ * @returns A guard that passes when the provided guard fails.
192
+ * @example
193
+ * ```ts
194
+ * const isNotString = notOf(isString)
195
+ * ```
196
+ */
197
+ export declare function notOf(guard: (value: unknown) => boolean): Guard<unknown>;
198
+ /**
199
+ * Exclude a narrower guard from a broader one.
200
+ *
201
+ * @param base - Base guard describing the larger set.
202
+ * @param excluded - Guard describing the subset to exclude.
203
+ * @returns A guard that accepts the base type minus the excluded subset.
204
+ * @example
205
+ * ```ts
206
+ * const isNonEmpty = complementOf(isString, (value: string): value is '' => value === '')
207
+ * ```
208
+ */
209
+ export declare function complementOf<TBase, TExcluded extends TBase>(base: Guard<TBase>, excluded: Guard<TExcluded> | ((value: TBase) => value is TExcluded)): Guard<Exclude<TBase, TExcluded>>;
210
+ /**
211
+ * Create a union guard from multiple guards or predicates.
212
+ *
213
+ * @param guards - Guards or predicates to union.
214
+ * @returns A guard that accepts any value matching one of the inputs.
215
+ * @example
216
+ * ```ts
217
+ * const isRole = unionOf(literalOf('user'), literalOf('admin'))
218
+ * ```
219
+ */
220
+ export declare function unionOf<const Gs extends Array<Guard<unknown>>>(...guards: Gs): Guard<GuardType<Gs[number]>>;
221
+ export declare function unionOf(...guards: Array<(value: unknown) => boolean>): Guard<unknown>;
222
+ /**
223
+ * Create an intersection guard from multiple guards or predicates.
224
+ *
225
+ * @param guards - Guards or predicates to intersect.
226
+ * @returns A guard that requires every input guard to pass.
227
+ * @example
228
+ * ```ts
229
+ * const isShortString = intersectionOf(isString, (value): value is string => isString(value) && value.length < 5)
230
+ * ```
231
+ */
232
+ export declare function intersectionOf<const Gs extends Array<Guard<unknown>>>(...guards: Gs): Guard<IntersectionFromGuards<Gs>>;
233
+ export declare function intersectionOf(...guards: Array<(value: unknown) => boolean>): Guard<unknown>;
234
+ /**
235
+ * Compose multiple guards through logical AND.
236
+ *
237
+ * @param guards - Guards or predicates to compose.
238
+ * @returns A guard that passes only when every input guard passes.
239
+ * @example
240
+ * ```ts
241
+ * const isAlphaTwo = composedOf(
242
+ * (value): value is string => isString(value) && /^[A-Za-z]+$/.test(value),
243
+ * (value): value is string => isString(value) && value.length === 2,
244
+ * )
245
+ * ```
246
+ */
247
+ export declare function composedOf<const Gs extends Array<Guard<unknown>>>(...guards: Gs): Guard<IntersectionFromGuards<Gs>>;
248
+ export declare function composedOf(...guards: Array<(value: unknown) => boolean>): Guard<unknown>;
249
+ /**
250
+ * Refine a base guard with an additional predicate.
251
+ *
252
+ * @param base - Base guard checked first.
253
+ * @param predicate - Predicate evaluated after the base guard succeeds.
254
+ * @returns A guard preserving the base type while enforcing the predicate.
255
+ * @example
256
+ * ```ts
257
+ * const isNonEmptyString = whereOf(isString, (value) => value.length > 0)
258
+ * ```
259
+ */
260
+ export declare function whereOf<T>(base: Guard<T>, predicate: (value: T) => boolean): Guard<T>;
261
+ export declare function whereOf<T, U extends T>(base: Guard<T>, predicate: (value: T) => value is U): Guard<U>;
262
+ /**
263
+ * Defer guard creation until runtime.
264
+ *
265
+ * @param thunk - Function that returns the real guard.
266
+ * @returns A lazily resolved guard.
267
+ * @example
268
+ * ```ts
269
+ * const isTree = lazyOf(() => objectOf({ value: isNumber }))
270
+ * ```
271
+ */
272
+ export declare function lazyOf<T>(thunk: () => Guard<T>): Guard<T>;
273
+ /**
274
+ * Validate a projected value after a base guard passes.
275
+ *
276
+ * @param base - Base guard checked first.
277
+ * @param project - Projection applied after the base guard succeeds.
278
+ * @param target - Guard or predicate evaluated against the projected value.
279
+ * @returns A guard that validates the original input through the projected value.
280
+ * @example
281
+ * ```ts
282
+ * const hasLength = transformOf(isString, (value) => value.length, (value): value is number => typeof value === 'number' && value > 0)
283
+ * ```
284
+ */
285
+ export declare function transformOf<T, U>(base: Guard<T>, project: (value: T) => U, target: Guard<U>): Guard<T>;
286
+ export declare function transformOf<T>(base: Guard<T>, project: (value: T) => unknown, target: (value: unknown) => boolean): Guard<T>;
287
+ /**
288
+ * Extend a guard to also allow `null`.
289
+ *
290
+ * @param guard - Base guard.
291
+ * @returns A guard that accepts `null` or values passing the base guard.
292
+ * @example
293
+ * ```ts
294
+ * const isNullableString = nullableOf(isString)
295
+ * ```
296
+ */
297
+ export declare function nullableOf<T>(guard: Guard<T>): Guard<T | null>;
@@ -0,0 +1,223 @@
1
+ import type { GuardsShape, ValidationError, ValidationResult, ValidationRuleName, ValidationRuleValue, ValidationRules, ValidatorFunction } from './types.js';
2
+ /**
3
+ * Read a property value from a record-like object.
4
+ *
5
+ * @param record - Object to read from.
6
+ * @param key - Property key to resolve.
7
+ * @returns The resolved property value.
8
+ * @example
9
+ * ```ts
10
+ * recordValue({ id: 'u1' }, 'id')
11
+ * ```
12
+ */
13
+ export declare function recordValue(record: object, key: PropertyKey): unknown;
14
+ /**
15
+ * Resolve a named validation rule from a rule object.
16
+ *
17
+ * @param rules - Rule object to read from.
18
+ * @param ruleName - Rule name to resolve.
19
+ * @returns The configured rule value, or `undefined` when not configured.
20
+ * @example
21
+ * ```ts
22
+ * ruleValue({ required: true }, 'required')
23
+ * ```
24
+ */
25
+ export declare function ruleValue(rules: ValidationRules, ruleName: ValidationRuleName): ValidationRuleValue | undefined;
26
+ /**
27
+ * Check whether a validation rule value is a boolean rule configuration.
28
+ *
29
+ * @param value - Value to test.
30
+ * @returns `true` when the value is `undefined`, a boolean, or a validator function.
31
+ * @example
32
+ * ```ts
33
+ * isBooleanRuleValue(true)
34
+ * ```
35
+ */
36
+ export declare function isBooleanRuleValue(value: unknown): boolean;
37
+ /**
38
+ * Check whether a validation rule value is a number rule configuration.
39
+ *
40
+ * @param value - Value to test.
41
+ * @returns `true` when the value is `undefined`, a non-negative integer, or a validator function.
42
+ * @example
43
+ * ```ts
44
+ * isNumberRuleValue(3)
45
+ * ```
46
+ */
47
+ export declare function isNumberRuleValue(value: unknown): boolean;
48
+ /**
49
+ * Check whether a validation rule value is a pattern rule configuration.
50
+ *
51
+ * @param value - Value to test.
52
+ * @returns `true` when the value is `undefined`, a string pattern, or a validator function.
53
+ * @example
54
+ * ```ts
55
+ * isPatternRuleValue('^a+$')
56
+ * ```
57
+ */
58
+ export declare function isPatternRuleValue(value: unknown): boolean;
59
+ /**
60
+ * Check whether a value is valid for a specific validation rule.
61
+ *
62
+ * @param ruleName - Rule name controlling the accepted value kind.
63
+ * @param value - Value to test.
64
+ * @returns `true` when the value is valid for the given rule name.
65
+ * @example
66
+ * ```ts
67
+ * isRuleValue('minimum', 3)
68
+ * ```
69
+ */
70
+ export declare function isRuleValue(ruleName: ValidationRuleName, value: unknown): boolean;
71
+ /**
72
+ * Count enumerable symbol keys on an object.
73
+ *
74
+ * @param value - Object to inspect.
75
+ * @returns The number of enumerable symbol properties.
76
+ * @example
77
+ * ```ts
78
+ * enumerableSymbolCount({ [Symbol('x')]: true })
79
+ * ```
80
+ */
81
+ export declare function enumerableSymbolCount(value: object): number;
82
+ /**
83
+ * Assert that a partial shape result matches a picked guard shape.
84
+ *
85
+ * @param value - Value to refine.
86
+ * @param shape - Source shape.
87
+ * @param keys - Picked keys.
88
+ * @returns Nothing. Refines `value` for the caller.
89
+ * @example
90
+ * ```ts
91
+ * const value: unknown = {}
92
+ * ensurePickedShape(value, { id: isString }, ['id'])
93
+ * ```
94
+ */
95
+ export declare function ensurePickedShape<S extends GuardsShape, K extends Array<keyof S & string>>(value: unknown, shape: S, keys: K): asserts value is Pick<S, K[number]>;
96
+ /**
97
+ * Assert that a partial shape result matches an omitted guard shape.
98
+ *
99
+ * @param value - Value to refine.
100
+ * @param shape - Source shape.
101
+ * @param keys - Omitted keys.
102
+ * @returns Nothing. Refines `value` for the caller.
103
+ * @example
104
+ * ```ts
105
+ * const value: unknown = {}
106
+ * ensureOmittedShape(value, { id: isString }, [])
107
+ * ```
108
+ */
109
+ export declare function ensureOmittedShape<S extends GuardsShape, K extends Array<keyof S & string>>(value: unknown, shape: S, keys: K): asserts value is Omit<S, K[number]>;
110
+ /**
111
+ * Narrow an unknown value to a validator callback.
112
+ *
113
+ * @param value - Value to test.
114
+ * @returns `true` when the value is a validator callback.
115
+ * @example
116
+ * ```ts
117
+ * isValidatorFunction((input) => input.length > 0)
118
+ * ```
119
+ */
120
+ export declare function isValidatorFunction(value: unknown): value is ValidatorFunction;
121
+ /**
122
+ * Narrow an unknown value to `ValidationRuleName`.
123
+ *
124
+ * @param value - Value to test.
125
+ * @returns `true` when the value is a supported rule name.
126
+ * @example
127
+ * ```ts
128
+ * isValidationRuleName('required')
129
+ * ```
130
+ */
131
+ export declare function isValidationRuleName(value: unknown): value is ValidationRuleName;
132
+ /**
133
+ * Narrow an unknown value to `ValidationRules`.
134
+ *
135
+ * @param value - Value to test.
136
+ * @returns `true` when the value is a valid validation rule object.
137
+ * @example
138
+ * ```ts
139
+ * isValidationRules({ required: true, minimum: 3 })
140
+ * ```
141
+ */
142
+ export declare function isValidationRules(value: unknown): value is ValidationRules;
143
+ /**
144
+ * Narrow an unknown value to `ValidationError`.
145
+ *
146
+ * @param value - Value to test.
147
+ * @returns `true` when the value is a validation error object.
148
+ * @example
149
+ * ```ts
150
+ * isValidationError({ rule: 'required', message: 'Missing' })
151
+ * ```
152
+ */
153
+ export declare function isValidationError(value: unknown): value is ValidationError;
154
+ /**
155
+ * Narrow an unknown value to `ValidationResult`.
156
+ *
157
+ * @param value - Value to test.
158
+ * @returns `true` when the value is a validation result object.
159
+ * @example
160
+ * ```ts
161
+ * isValidationResult({ valid: true, errors: [] })
162
+ * ```
163
+ */
164
+ export declare function isValidationResult(value: unknown): value is ValidationResult;
165
+ /**
166
+ * Assert that a validation rule object is well-formed.
167
+ *
168
+ * @param rules - Rules to validate.
169
+ * @returns Nothing. Throws when the rules are invalid.
170
+ * @example
171
+ * ```ts
172
+ * assertValidationRules({ required: true })
173
+ * ```
174
+ */
175
+ export declare function assertValidationRules(rules: unknown): asserts rules is ValidationRules;
176
+ /**
177
+ * Clone a validation rule object.
178
+ *
179
+ * @param rules - Rules to clone.
180
+ * @returns A shallow cloned rule object.
181
+ * @example
182
+ * ```ts
183
+ * const rules = cloneValidationRules({ required: true })
184
+ * ```
185
+ */
186
+ export declare function cloneValidationRules(rules: ValidationRules): ValidationRules;
187
+ /**
188
+ * Evaluate a single validation rule against input.
189
+ *
190
+ * @param ruleName - Rule being evaluated.
191
+ * @param check - Rule value to evaluate.
192
+ * @param input - Input value to validate.
193
+ * @returns An error message when the rule fails, otherwise `undefined`.
194
+ * @example
195
+ * ```ts
196
+ * evaluateRule('required', true, '')
197
+ * ```
198
+ */
199
+ export declare function evaluateRule(ruleName: ValidationRuleName, check: ValidationRuleValue, input: string): string | undefined;
200
+ /**
201
+ * Validate input against all configured validation rules.
202
+ *
203
+ * @param input - Input string to validate.
204
+ * @param rules - Rules to evaluate.
205
+ * @returns A structured validation result.
206
+ * @example
207
+ * ```ts
208
+ * validateInput('', { required: true })
209
+ * ```
210
+ */
211
+ export declare function validateInput(input: string, rules: ValidationRules): ValidationResult;
212
+ /**
213
+ * Test whether input passes all configured validation rules.
214
+ *
215
+ * @param input - Input string to validate.
216
+ * @param rules - Rules to evaluate.
217
+ * @returns `true` when the input is valid.
218
+ * @example
219
+ * ```ts
220
+ * testInput('value', { required: true })
221
+ * ```
222
+ */
223
+ export declare function testInput(input: string, rules: ValidationRules): boolean;