@stone-js/validation 0.8.10 → 0.8.12

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.
@@ -1,18 +1,28 @@
1
+ import { ClassType } from '@stone-js/core';
1
2
  /**
2
- * Class decorator: register a schema class under a name.
3
+ * Declare a class as a rule set.
3
4
  *
4
- * ```ts
5
- * @ValidationSchema('createUser')
6
- * export class CreateUserSchema implements IValidationSchema { rules () { … } }
7
- * ```
5
+ * Three statements in one, which is why nothing has to be wired by hand:
8
6
  *
9
- * Routes and handlers then refer to it by name (`@Validate('createUser')`), so schemas live in their
10
- * own files, organised however the application likes, and nothing has to be imported at the route.
11
- * The class is resolved by the container, so its constructor receives services and `rules()` can use
12
- * them.
7
+ * 1. **It is a service.** The container builds it, as a singleton, so its constructor is auto-wired
8
+ * like any other class: a repository, a client, a translator, whatever it destructures is resolved
9
+ * for it. That is what lets a rule set depend on the application instead of on constants.
10
+ * 2. **It is reachable by name.** The alias is bound as `schema:<name>`, prefixed on purpose: an
11
+ * application is free to bind its own service under a plain word, and a declaration named after a
12
+ * domain concept must not compete for that name.
13
+ * 3. **It activates the module.** The blueprint comes with the decorator, so declaring this is the
14
+ * whole setup, and a route naming it resolves to this class.
13
15
  *
14
- * @param alias - The name the schema is registered under. Defaults to the class name, which the
15
- * discovery middleware fills in, since it is the one holding the class.
16
+ * @param alias - The name a route refers to it by. Defaults to the class name.
16
17
  * @returns A class decorator.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * @ValidationSchema('createUser')
22
+ * export class CreateUser {
23
+ * constructor (private readonly users: UserRepository) {}
24
+ * rules (): RouteValidationRules { return { body: { email: { rules: 'email' } } } }
25
+ * }
26
+ * ```
17
27
  */
18
- export declare const ValidationSchema: (alias?: string) => ClassDecorator;
28
+ export declare const ValidationSchema: <T extends ClassType = ClassType>(alias?: string) => ClassDecorator;
package/dist/index.d.ts CHANGED
@@ -1,18 +1,17 @@
1
- export * from './ValidationServiceProvider.js';
2
- export * from './Validator.js';
3
1
  export * from './adapters/standardSchema.js';
4
2
  export * from './adapters/zod.js';
5
3
  export * from './declarations.js';
4
+ export * from './decorators/constants.js';
6
5
  export * from './decorators/Validate.js';
7
6
  export * from './decorators/Validation.js';
8
7
  export * from './decorators/ValidationSchema.js';
9
- export * from './decorators/constants.js';
10
8
  export * from './errors/ValidationError.js';
11
- export * from './middleware/BlueprintMiddleware.js';
12
- export * from './middleware/ValidateRouteMiddleware.js';
13
9
  export * from './middleware/validate.js';
10
+ export * from './middleware/ValidateRouteMiddleware.js';
14
11
  export * from './options/ValidationBlueprint.js';
15
12
  export * from './schema.js';
16
13
  export * from './schemaClass.js';
17
14
  export * from './sources.js';
18
15
  export * from './validateEvent.js';
16
+ export * from './ValidationServiceProvider.js';
17
+ export * from './Validator.js';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { IntegrationError, methodDecoratorLegacyWrapper, addMetadata, hasMetadata, getMetadata, classDecoratorLegacyWrapper, addBlueprint, setClassMetadata } from '@stone-js/core';
1
+ import { IntegrationError, methodDecoratorLegacyWrapper, addMetadata, hasMetadata, getMetadata, classDecoratorLegacyWrapper, addBlueprint, setMetadata, SERVICE_KEY } from '@stone-js/core';
2
2
  import { cloneValue } from '@stone-js/config';
3
3
 
4
4
  /**
@@ -595,42 +595,6 @@ const MetaValidateRouteMiddleware = {
595
595
  priority: 5
596
596
  };
597
597
 
598
- /**
599
- * Build-phase middleware: collect every class registered with `@ValidationSchema` into the registry.
600
- *
601
- * The same scan the router does for its route definitions, applied to this module's own key. After
602
- * it runs, `stone.validation.schemas` maps each alias to its class, so a route or a handler can name
603
- * a schema instead of importing it, and `@stone-js/openapi` can walk the registry to publish request
604
- * schemas without loading anything itself.
605
- *
606
- * @param context - The blueprint context.
607
- * @param next - The next blueprint middleware.
608
- * @returns The blueprint.
609
- */
610
- async function ValidationSchemaMiddleware(context, next) {
611
- const registered = context
612
- .modules
613
- .filter((module) => hasMetadata(module, VALIDATION_SCHEMA_KEY))
614
- .reduce((registry, module) => {
615
- const { alias } = getMetadata(module, VALIDATION_SCHEMA_KEY, {});
616
- return { ...registry, [alias ?? module.name]: module };
617
- }, {});
618
- if (Object.keys(registered).length > 0) {
619
- context.blueprint.set('stone.validation.schemas', {
620
- ...context.blueprint.get('stone.validation.schemas', {}),
621
- ...registered
622
- });
623
- }
624
- return await next(context);
625
- }
626
- /**
627
- * Meta blueprint middleware for schema discovery.
628
- */
629
- const MetaValidationSchemaMiddleware = {
630
- module: ValidationSchemaMiddleware,
631
- priority: 5
632
- };
633
-
634
598
  /**
635
599
  * Opt-in blueprint: import and register it to enable validation.
636
600
  *
@@ -644,11 +608,6 @@ const MetaValidationSchemaMiddleware = {
644
608
  const validationBlueprint = {
645
609
  stone: {
646
610
  validation: {},
647
- blueprint: {
648
- middleware: [
649
- MetaValidationSchemaMiddleware
650
- ]
651
- },
652
611
  providers: [
653
612
  ValidationServiceProvider
654
613
  ],
@@ -693,24 +652,44 @@ const Validation = (options = {}) => {
693
652
  };
694
653
 
695
654
  /**
696
- * Class decorator: register a schema class under a name.
655
+ * Declare a class as a rule set.
697
656
  *
698
- * ```ts
699
- * @ValidationSchema('createUser')
700
- * export class CreateUserSchema implements IValidationSchema { rules () { … } }
701
- * ```
657
+ * Three statements in one, which is why nothing has to be wired by hand:
702
658
  *
703
- * Routes and handlers then refer to it by name (`@Validate('createUser')`), so schemas live in their
704
- * own files, organised however the application likes, and nothing has to be imported at the route.
705
- * The class is resolved by the container, so its constructor receives services and `rules()` can use
706
- * them.
659
+ * 1. **It is a service.** The container builds it, as a singleton, so its constructor is auto-wired
660
+ * like any other class: a repository, a client, a translator, whatever it destructures is resolved
661
+ * for it. That is what lets a rule set depend on the application instead of on constants.
662
+ * 2. **It is reachable by name.** The alias is bound as `schema:<name>`, prefixed on purpose: an
663
+ * application is free to bind its own service under a plain word, and a declaration named after a
664
+ * domain concept must not compete for that name.
665
+ * 3. **It activates the module.** The blueprint comes with the decorator, so declaring this is the
666
+ * whole setup, and a route naming it resolves to this class.
707
667
  *
708
- * @param alias - The name the schema is registered under. Defaults to the class name, which the
709
- * discovery middleware fills in, since it is the one holding the class.
668
+ * @param alias - The name a route refers to it by. Defaults to the class name.
710
669
  * @returns A class decorator.
670
+ *
671
+ * @example
672
+ * ```ts
673
+ * @ValidationSchema('createUser')
674
+ * export class CreateUser {
675
+ * constructor (private readonly users: UserRepository) {}
676
+ * rules (): RouteValidationRules { return { body: { email: { rules: 'email' } } } }
677
+ * }
678
+ * ```
711
679
  */
712
680
  const ValidationSchema = (alias) => {
713
- return setClassMetadata(VALIDATION_SCHEMA_KEY, { alias });
681
+ return classDecoratorLegacyWrapper((target, context) => {
682
+ const name = alias ?? target.name;
683
+ setMetadata(context, VALIDATION_SCHEMA_KEY, { alias: name });
684
+ setMetadata(context, SERVICE_KEY, { singleton: true, isClass: true, alias: `schema:${name}` });
685
+ addBlueprint(target, context, validationBlueprint, {
686
+ stone: {
687
+ validation: {
688
+ schemas: { [name]: target }
689
+ }
690
+ }
691
+ });
692
+ });
714
693
  };
715
694
 
716
695
  /**
@@ -734,4 +713,4 @@ function validate(rules) {
734
713
  };
735
714
  }
736
715
 
737
- export { MetaValidateRouteMiddleware, MetaValidationSchemaMiddleware, VALIDATE_KEY, VALIDATION_SCHEMA_KEY, Validate, ValidateRouteMiddleware, Validation, ValidationError, ValidationSchema, ValidationSchemaMiddleware, ValidationServiceProvider, Validator, defineValidationSchema, fromStandard, fromZod, isNativeSchema, isSchemaLike, isStandardSchema, isValidationSchema, isValidationSchemaClass, isZodLike, metadataKeyFor, readSource, resolveSchema, rulesOf, toValidationRules, validate, validateEvent, validationBlueprint };
716
+ export { MetaValidateRouteMiddleware, VALIDATE_KEY, VALIDATION_SCHEMA_KEY, Validate, ValidateRouteMiddleware, Validation, ValidationError, ValidationSchema, ValidationServiceProvider, Validator, defineValidationSchema, fromStandard, fromZod, isNativeSchema, isSchemaLike, isStandardSchema, isValidationSchema, isValidationSchemaClass, isZodLike, metadataKeyFor, readSource, resolveSchema, rulesOf, toValidationRules, validate, validateEvent, validationBlueprint };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stone-js/validation",
3
- "version": "0.8.10",
3
+ "version": "0.8.12",
4
4
  "description": "Framework-agnostic input validation for Stone.js. Define a schema once (Zod, Valibot, ArkType — anything Standard Schema) and validate it identically on the backend and the frontend.",
5
5
  "author": "Mr. Stone <evensstone@gmail.com>",
6
6
  "license": "MIT",
@@ -40,7 +40,7 @@
40
40
  "node": ">=18.17.0"
41
41
  },
42
42
  "peerDependencies": {
43
- "@stone-js/core": "0.8.10"
43
+ "@stone-js/core": "0.8.12"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@commitlint/cli": "^19.8.1",
@@ -62,7 +62,7 @@
62
62
  "typescript": "^5.6.3",
63
63
  "vitest": "^3.2.4",
64
64
  "zod": "^3.24.1",
65
- "@stone-js/core": "0.8.10"
65
+ "@stone-js/core": "0.8.12"
66
66
  },
67
67
  "ts-standard": {
68
68
  "globals": [
@@ -75,7 +75,7 @@
75
75
  ]
76
76
  },
77
77
  "dependencies": {
78
- "@stone-js/config": "0.8.10"
78
+ "@stone-js/config": "0.8.12"
79
79
  },
80
80
  "scripts": {
81
81
  "lint": "ts-standard src",
@@ -1,18 +0,0 @@
1
- import { BlueprintContext, ClassType, IBlueprint, NextMiddleware, type MetaMiddleware } from '@stone-js/core';
2
- /**
3
- * Build-phase middleware: collect every class registered with `@ValidationSchema` into the registry.
4
- *
5
- * The same scan the router does for its route definitions, applied to this module's own key. After
6
- * it runs, `stone.validation.schemas` maps each alias to its class, so a route or a handler can name
7
- * a schema instead of importing it, and `@stone-js/openapi` can walk the registry to publish request
8
- * schemas without loading anything itself.
9
- *
10
- * @param context - The blueprint context.
11
- * @param next - The next blueprint middleware.
12
- * @returns The blueprint.
13
- */
14
- export declare function ValidationSchemaMiddleware(context: BlueprintContext<IBlueprint, ClassType>, next: NextMiddleware<BlueprintContext<IBlueprint, ClassType>, IBlueprint>): Promise<IBlueprint>;
15
- /**
16
- * Meta blueprint middleware for schema discovery.
17
- */
18
- export declare const MetaValidationSchemaMiddleware: MetaMiddleware<any, any>;