@stacksjs/validation 0.70.369 → 0.70.370

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.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,12 @@
1
1
  export type {
2
2
  ConditionalAPI,
3
3
  ConditionalRecord,
4
+ InferObjectShape,
5
+ InferValidatorValue,
6
+ InferredArrayValidator,
7
+ InferredEnumValidator,
4
8
  ObjectWithContextValidator,
9
+ ValidatorShape,
5
10
  ValidatorWithConditionals,
6
11
  } from './schema';
7
12
  // Type guard utilities
@@ -15,7 +15,16 @@ import type { ValidationResult, Validator } from '@stacksjs/ts-validation';
15
15
  * }).validate(input)
16
16
  * ```
17
17
  */
18
- export declare function objectWithContext<T extends Record<string, Validator<any>>>(initialShape?: T): ObjectWithContextValidator<T> & ConditionalAPI<ObjectWithContextValidator<T>>;
18
+ export declare function objectWithContext<const TShape extends ValidatorShape = Record<string, never>>(initialShape?: TShape): ObjectWithContextValidator<TShape> & ConditionalAPI<ObjectWithContextValidator<TShape>>;
19
+ export declare interface ObjectWithContextValidator<TShape extends ValidatorShape> extends Validator<InferObjectShape<TShape>> {
20
+ readonly name: 'object'
21
+ validate: (value: InferObjectShape<TShape>) => ValidationResult
22
+ getShape: () => TShape
23
+ required: () => this
24
+ optional: () => this
25
+ isPartOfShape: boolean
26
+ shape: <TNextShape extends ValidatorShape>(shape: TNextShape) => ObjectWithContextValidator<TNextShape>
27
+ }
19
28
  /**
20
29
  * Validator-shaped object returned by `schema.object()`. Mirrors the
21
30
  * subset of ts-validation's `ObjectValidatorType` that Stacks code
@@ -26,12 +35,10 @@ export declare function objectWithContext<T extends Record<string, Validator<any
26
35
  * and other introspection passes can walk the per-field validators
27
36
  * (and their `__conditionals` arrays).
28
37
  */
29
- export declare interface ObjectWithContextValidator<T extends Record<string, Validator<any>>> extends Validator<Record<string, unknown>> {
30
- readonly name: 'object'
31
- validate: (value: unknown) => ValidationResult
32
- getShape: () => T
33
- required: () => this
34
- optional: () => this
35
- isPartOfShape: boolean
36
- shape: (shape: T) => ObjectWithContextValidator<T>
38
+ export type ValidatorShape = Readonly<Record<string, Validator<any>>>;
39
+ /** Resolve the value accepted by one validator. */
40
+ export type InferValidatorValue<TValidator> = TValidator extends Validator<infer TValue> ? TValue : never;
41
+ /** Resolve an object value directly from its validator shape. */
42
+ export type InferObjectShape<TShape extends ValidatorShape> = {
43
+ -readonly [TKey in keyof TShape]: InferValidatorValue<TShape[TKey]>
37
44
  }
package/dist/schema.d.ts CHANGED
@@ -3,10 +3,10 @@ import { objectWithContext } from './object-with-context';
3
3
  import { withConditionals } from './conditional';
4
4
  import type { ConditionalAPI } from './conditional';
5
5
  import type { ObjectWithContextValidator } from './object-with-context';
6
- import type { ValidationInstance } from '@stacksjs/ts-validation';
6
+ import type { ValidationInstance, Validator } from '@stacksjs/ts-validation';
7
7
  export type { FileLike } from './file-validator';
8
8
  export type { ConditionalAPI, ConditionalRecord, ValidatorWithConditionals } from './conditional';
9
- export type { ObjectWithContextValidator } from './object-with-context';
9
+ export type { InferObjectShape, InferValidatorValue, ObjectWithContextValidator, ValidatorShape } from './object-with-context';
10
10
  /**
11
11
  * `Object.assign({}, v, { file })` would defeat the ts-validation
12
12
  * proxy's late-binding. Wrapping with `new Proxy` keeps every existing
@@ -15,6 +15,29 @@ export type { ObjectWithContextValidator } from './object-with-context';
15
15
  * mixin on primitive factories).
16
16
  */
17
17
  export declare const schema: SchemaWithFile;
18
+ export declare interface InferredEnumValidator<TValue extends string> extends Validator<TValue> {
19
+ readonly name: 'enum'
20
+ getAllowedValues: () => readonly TValue[]
21
+ custom: (fn: (value: TValue) => boolean, message: string) => InferredEnumValidator<TValue>
22
+ }
23
+ export declare interface InferredArrayValidator<TValue> extends Validator<TValue[]> {
24
+ readonly name: 'array'
25
+ min: (length: number) => InferredArrayValidator<TValue>
26
+ max: (length: number) => InferredArrayValidator<TValue>
27
+ length: (length: number) => InferredArrayValidator<TValue>
28
+ each: <TElement>(validator: Validator<TElement>) => InferredArrayValidator<TElement>
29
+ unique: () => InferredArrayValidator<TValue>
30
+ }
31
+ declare type WithConditionals<TValidator extends Validator<any>> = TValidator & ConditionalAPI<TValidator>;
32
+ declare type ConditionalValidationInstance = {
33
+ // eslint-disable-next-line pickier/no-unused-vars
34
+ [TKey in keyof ValidationInstance]: ValidationInstance[TKey] extends (...args: infer TArgs) => infer TValidator
35
+ ? TValidator extends Validator<any>
36
+ // eslint-disable-next-line pickier/no-unused-vars
37
+ ? (...args: TArgs) => WithConditionals<TValidator>
38
+ : ValidationInstance[TKey]
39
+ : ValidationInstance[TKey]
40
+ }
18
41
  /**
19
42
  * Extended `ValidationInstance` that adds `schema.file()` on top of the
20
43
  * ts-validation surface (stacksjs/stacks#1856). Upstream ts-validation
@@ -27,8 +50,10 @@ export declare const schema: SchemaWithFile;
27
50
  * and every primitive factory wrapped to attach `.when()` / `.sometimes()`
28
51
  * to the returned validator.
29
52
  */
30
- export type SchemaWithFile = Omit<ValidationInstance, 'object'> & {
53
+ export type SchemaWithFile = Omit<ConditionalValidationInstance, 'array' | 'enum' | 'file' | 'object'> & {
31
54
  file: () => FileValidator
55
+ array: <TValue = unknown>() => WithConditionals<InferredArrayValidator<TValue>>
56
+ enum: <const TValues extends readonly string[]>(values: TValues) => WithConditionals<InferredEnumValidator<TValues[number]>>
32
57
  object: typeof objectWithContext
33
58
  }
34
59
  export { file, FileValidator } from './file-validator';
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/validation",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.70.369",
5
+ "version": "0.70.370",
6
6
  "description": "The Stacks Validation ways.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -55,14 +55,15 @@
55
55
  "scripts": {
56
56
  "build": "bun build.ts",
57
57
  "typecheck": "bun tsc --noEmit",
58
+ "typecheck:inference": "bun tsc -p tsconfig.type-tests.json",
58
59
  "prepublishOnly": "bun run build"
59
60
  },
60
61
  "dependencies": {
61
- "@stacksjs/ts-validation": "^0.5.0"
62
+ "@stacksjs/ts-validation": "^0.5.3"
62
63
  },
63
64
  "devDependencies": {
64
65
  "better-dx": "^0.2.17",
65
- "@stacksjs/strings": "0.70.369",
66
- "@stacksjs/types": "0.70.369"
66
+ "@stacksjs/strings": "0.70.370",
67
+ "@stacksjs/types": "0.70.370"
67
68
  }
68
69
  }