@tsed/schema 8.19.1 → 8.19.3
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/lib/esm/constants/OperationVerbs.js +35 -0
- package/lib/esm/constants/VendorKeys.js +29 -0
- package/lib/esm/constants/httpStatusMessages.js +59 -0
- package/lib/esm/constants/jsonSchemaProperties.js +55 -0
- package/lib/esm/decorators/class/children.js +93 -5
- package/lib/esm/decorators/class/discriminatorValue.js +124 -20
- package/lib/esm/decorators/collections/collectionContains.js +91 -10
- package/lib/esm/decorators/collections/maxItems.js +97 -27
- package/lib/esm/decorators/collections/maxProperties.js +96 -30
- package/lib/esm/decorators/collections/minItems.js +122 -27
- package/lib/esm/decorators/collections/minProperties.js +132 -31
- package/lib/esm/decorators/common/additionalProperties.js +59 -4
- package/lib/esm/decorators/common/allOf.js +61 -6
- package/lib/esm/decorators/common/allow.js +56 -12
- package/lib/esm/decorators/common/any.js +58 -18
- package/lib/esm/decorators/common/anyOf.js +65 -9
- package/lib/esm/decorators/common/const.js +72 -30
- package/lib/esm/decorators/common/customKey.js +132 -12
- package/lib/esm/decorators/common/default.js +85 -19
- package/lib/esm/decorators/common/discriminatorKey.js +123 -0
- package/lib/esm/decorators/common/errorMsg.js +48 -2
- package/lib/esm/decorators/common/example.js +68 -6
- package/lib/esm/decorators/common/examples.js +99 -6
- package/lib/esm/decorators/common/format.js +86 -52
- package/lib/esm/decorators/common/nullable.js +77 -11
- package/lib/esm/decorators/common/oneOf.js +93 -9
- package/lib/esm/decorators/common/optional.js +93 -4
- package/lib/esm/decorators/common/property.js +42 -6
- package/lib/esm/decorators/common/readOnly.js +106 -5
- package/lib/esm/decorators/common/required.js +57 -20
- package/lib/esm/decorators/common/writeOnly.js +117 -5
- package/lib/esm/domain/JsonClassStore.js +75 -0
- package/lib/esm/domain/JsonDiscriminator.js +57 -0
- package/lib/esm/domain/JsonEntityStore.js +46 -0
- package/lib/esm/domain/JsonFormatTypes.js +39 -0
- package/lib/esm/domain/JsonLazyRef.js +33 -0
- package/lib/esm/domain/JsonMap.js +32 -0
- package/lib/esm/domain/JsonMedia.js +28 -0
- package/lib/esm/domain/JsonMethodStore.js +56 -0
- package/lib/esm/domain/JsonOperation.js +43 -0
- package/lib/esm/domain/JsonOperationPathsMap.js +38 -0
- package/lib/esm/domain/JsonOperationRoute.js +54 -0
- package/lib/esm/domain/JsonParameter.js +35 -0
- package/lib/esm/domain/JsonParameterStore.js +71 -0
- package/lib/esm/domain/JsonParameterTypes.js +26 -0
- package/lib/esm/domain/JsonPropertyStore.js +44 -0
- package/lib/esm/domain/JsonRequestBody.js +26 -0
- package/lib/esm/domain/JsonResponse.js +29 -0
- package/lib/esm/domain/JsonSchema.js +365 -16
- package/lib/esm/domain/SpecTypes.js +26 -0
- package/lib/esm/fn/boolean.js +39 -3
- package/lib/esm/fn/number.js +45 -3
- package/lib/esm/fn/string.js +43 -3
- package/lib/types/constants/OperationVerbs.d.ts +35 -0
- package/lib/types/constants/VendorKeys.d.ts +29 -0
- package/lib/types/constants/httpStatusMessages.d.ts +59 -0
- package/lib/types/constants/jsonSchemaProperties.d.ts +55 -0
- package/lib/types/decorators/class/children.d.ts +93 -5
- package/lib/types/decorators/class/discriminatorValue.d.ts +124 -20
- package/lib/types/decorators/collections/collectionContains.d.ts +91 -10
- package/lib/types/decorators/collections/maxItems.d.ts +97 -27
- package/lib/types/decorators/collections/maxProperties.d.ts +96 -30
- package/lib/types/decorators/collections/minItems.d.ts +122 -27
- package/lib/types/decorators/collections/minProperties.d.ts +132 -31
- package/lib/types/decorators/common/additionalProperties.d.ts +59 -4
- package/lib/types/decorators/common/allOf.d.ts +61 -6
- package/lib/types/decorators/common/allow.d.ts +56 -12
- package/lib/types/decorators/common/any.d.ts +58 -18
- package/lib/types/decorators/common/anyOf.d.ts +65 -9
- package/lib/types/decorators/common/const.d.ts +72 -30
- package/lib/types/decorators/common/customKey.d.ts +132 -12
- package/lib/types/decorators/common/default.d.ts +85 -19
- package/lib/types/decorators/common/discriminatorKey.d.ts +123 -0
- package/lib/types/decorators/common/errorMsg.d.ts +48 -2
- package/lib/types/decorators/common/example.d.ts +68 -6
- package/lib/types/decorators/common/examples.d.ts +99 -6
- package/lib/types/decorators/common/format.d.ts +86 -52
- package/lib/types/decorators/common/nullable.d.ts +77 -11
- package/lib/types/decorators/common/oneOf.d.ts +93 -9
- package/lib/types/decorators/common/optional.d.ts +93 -4
- package/lib/types/decorators/common/property.d.ts +42 -6
- package/lib/types/decorators/common/readOnly.d.ts +106 -5
- package/lib/types/decorators/common/required.d.ts +57 -20
- package/lib/types/decorators/common/writeOnly.d.ts +117 -5
- package/lib/types/domain/JsonClassStore.d.ts +75 -0
- package/lib/types/domain/JsonDiscriminator.d.ts +57 -0
- package/lib/types/domain/JsonEntityStore.d.ts +51 -0
- package/lib/types/domain/JsonFormatTypes.d.ts +39 -0
- package/lib/types/domain/JsonLazyRef.d.ts +33 -0
- package/lib/types/domain/JsonMap.d.ts +32 -0
- package/lib/types/domain/JsonMedia.d.ts +28 -0
- package/lib/types/domain/JsonMethodStore.d.ts +66 -0
- package/lib/types/domain/JsonOperation.d.ts +51 -0
- package/lib/types/domain/JsonOperationPathsMap.d.ts +38 -0
- package/lib/types/domain/JsonOperationRoute.d.ts +54 -0
- package/lib/types/domain/JsonParameter.d.ts +35 -0
- package/lib/types/domain/JsonParameterStore.d.ts +97 -0
- package/lib/types/domain/JsonParameterTypes.d.ts +26 -0
- package/lib/types/domain/JsonPropertyStore.d.ts +44 -0
- package/lib/types/domain/JsonRequestBody.d.ts +31 -0
- package/lib/types/domain/JsonResponse.d.ts +34 -0
- package/lib/types/domain/JsonSchema.d.ts +422 -19
- package/lib/types/domain/SpecTypes.d.ts +26 -0
- package/lib/types/domain/types.d.ts +90 -0
- package/lib/types/fn/boolean.d.ts +39 -3
- package/lib/types/fn/number.d.ts +45 -3
- package/lib/types/fn/string.d.ts +43 -3
- package/lib/types/interfaces/IgnoreCallback.d.ts +24 -0
- package/lib/types/interfaces/JsonHookContext.d.ts +31 -0
- package/lib/types/interfaces/JsonOpenSpec.d.ts +33 -0
- package/lib/types/interfaces/JsonSchemaOptions.d.ts +26 -0
- package/package.json +7 -7
|
@@ -1,12 +1,67 @@
|
|
|
1
1
|
import { JsonEntityFn } from "./jsonEntityFn.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Controls whether additional properties beyond those defined in the schema are allowed.
|
|
4
|
+
*
|
|
5
|
+
* By default, JSON Schema validation may allow properties not explicitly defined in the schema.
|
|
6
|
+
* This decorator lets you control that behavior either by disabling additional properties entirely
|
|
7
|
+
* or by specifying a schema that additional properties must conform to.
|
|
8
|
+
*
|
|
9
|
+
* ### Usage with boolean
|
|
10
|
+
*
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Disallow any additional properties
|
|
13
|
+
* @AdditionalProperties(false)
|
|
14
|
+
* class StrictModel {
|
|
15
|
+
* @Property()
|
|
16
|
+
* name: string;
|
|
17
|
+
* // Any other properties will cause validation errors
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* // Explicitly allow additional properties (default behavior)
|
|
21
|
+
* @AdditionalProperties(true)
|
|
22
|
+
* class FlexibleModel {
|
|
23
|
+
* @Property()
|
|
24
|
+
* name: string;
|
|
25
|
+
* // Additional properties are allowed
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* ### Usage with schema
|
|
30
|
+
*
|
|
31
|
+
* ```typescript
|
|
32
|
+
* // Additional properties must be strings
|
|
33
|
+
* @AdditionalProperties({ type: "string" })
|
|
34
|
+
* class DynamicModel {
|
|
35
|
+
* @Property()
|
|
36
|
+
* id: number;
|
|
37
|
+
* // Other properties must be strings
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* // Additional properties must match a complex schema
|
|
41
|
+
* @AdditionalProperties({
|
|
42
|
+
* type: "object",
|
|
43
|
+
* properties: {
|
|
44
|
+
* value: { type: "string" }
|
|
45
|
+
* }
|
|
46
|
+
* })
|
|
47
|
+
* class MetadataModel {
|
|
48
|
+
* @Property()
|
|
49
|
+
* name: string;
|
|
50
|
+
* // Additional properties must be objects with a 'value' string property
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* ### Common Use Cases
|
|
55
|
+
*
|
|
56
|
+
* - **Strict APIs**: Use `@AdditionalProperties(false)` to ensure clients only send expected fields
|
|
57
|
+
* - **Dynamic Data**: Use with a schema to validate dynamic property values
|
|
58
|
+
* - **Migration**: Allow additional properties during API versioning transitions
|
|
59
|
+
*
|
|
60
|
+
* @param schema - Boolean to allow/disallow additional properties, or a schema they must match
|
|
4
61
|
*
|
|
5
|
-
* @param schema
|
|
6
62
|
* @decorator
|
|
7
63
|
* @validation
|
|
8
|
-
* @
|
|
9
|
-
* @schema
|
|
64
|
+
* @public
|
|
10
65
|
*/
|
|
11
66
|
export function AdditionalProperties(schema) {
|
|
12
67
|
return JsonEntityFn((entity, parameters) => {
|
|
@@ -1,14 +1,69 @@
|
|
|
1
1
|
import { JsonEntityFn } from "./jsonEntityFn.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Validates that a value must match ALL of the provided schemas (intersection).
|
|
4
|
+
*
|
|
5
|
+
* The `allOf` keyword from JSON Schema allows combining multiple schemas where the
|
|
6
|
+
* value must satisfy every schema in the list. This is useful for:
|
|
7
|
+
* - Merging multiple schema constraints
|
|
8
|
+
* - Composing validation rules from different sources
|
|
9
|
+
* - Creating intersections of object types
|
|
10
|
+
*
|
|
11
|
+
* ### Basic Usage
|
|
12
|
+
*
|
|
13
|
+
* ```typescript
|
|
14
|
+
* @AllOf(
|
|
15
|
+
* { type: "object", properties: { id: { type: "number" } } },
|
|
16
|
+
* { type: "object", properties: { name: { type: "string" } } }
|
|
17
|
+
* )
|
|
18
|
+
* class Combined {
|
|
19
|
+
* // Must satisfy both schemas
|
|
20
|
+
* // Equivalent to: { id: number, name: string }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* ### With Model References
|
|
25
|
+
*
|
|
26
|
+
* ```typescript
|
|
27
|
+
* class BaseModel {
|
|
28
|
+
* @Property()
|
|
29
|
+
* id: number;
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* class NamedModel {
|
|
33
|
+
* @Property()
|
|
34
|
+
* name: string;
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* @AllOf(BaseModel, NamedModel)
|
|
38
|
+
* class CombinedModel {
|
|
39
|
+
* // Inherits validation from both BaseModel and NamedModel
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* ### Validation Composition
|
|
44
|
+
*
|
|
45
|
+
* ```typescript
|
|
46
|
+
* @AllOf(
|
|
47
|
+
* { minProperties: 1 },
|
|
48
|
+
* { maxProperties: 10 }
|
|
49
|
+
* )
|
|
50
|
+
* class BoundedObject {
|
|
51
|
+
* // Must have between 1 and 10 properties
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* ### Use Cases
|
|
56
|
+
*
|
|
57
|
+
* - **Mixin Patterns**: Combine validation from multiple models
|
|
58
|
+
* - **Constraint Merging**: Apply multiple validation rules together
|
|
59
|
+
* - **Type Intersection**: Create types that must satisfy multiple schemas
|
|
60
|
+
*
|
|
61
|
+
* @param allOf - One or more schemas that the value must satisfy
|
|
4
62
|
*
|
|
5
63
|
* @decorator
|
|
6
64
|
* @validation
|
|
7
|
-
* @
|
|
8
|
-
* @schema
|
|
9
|
-
* @classDecorator
|
|
10
|
-
* @input
|
|
11
|
-
* @param allOf
|
|
65
|
+
* @public
|
|
66
|
+
* @see https://json-schema.org/understanding-json-schema/reference/combining#allOf
|
|
12
67
|
*/
|
|
13
68
|
export function AllOf(...allOf) {
|
|
14
69
|
return JsonEntityFn((entity) => {
|
|
@@ -2,31 +2,75 @@ import { DecoratorTypes, isClass, useDecorators } from "@tsed/core";
|
|
|
2
2
|
import { JsonEntityFn } from "./jsonEntityFn.js";
|
|
3
3
|
import { Property } from "./property.js";
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Adds specific values to the list of allowed values for required properties or parameters.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* When a property or parameter is marked as required, it typically rejects `null`, `undefined`,
|
|
8
|
+
* and empty strings. The `@Allow()` decorator lets you explicitly permit certain values that
|
|
9
|
+
* would otherwise fail required validation.
|
|
10
|
+
*
|
|
11
|
+
* ### Common Use Case: Allow Empty Strings
|
|
12
|
+
*
|
|
13
|
+
* By default, required fields reject empty strings. Use `@Allow("")` to permit them:
|
|
8
14
|
*
|
|
9
15
|
* ```typescript
|
|
10
|
-
*
|
|
11
|
-
*
|
|
16
|
+
* class UserModel {
|
|
17
|
+
* @Required()
|
|
18
|
+
* @Allow("") // Empty string is now valid even though field is required
|
|
19
|
+
* nickname: string;
|
|
20
|
+
* }
|
|
12
21
|
* ```
|
|
13
|
-
* > Required will throw a BadRequest when the given value is `null` or `undefined` but not for an empty string.
|
|
14
22
|
*
|
|
15
|
-
*
|
|
23
|
+
* ### On Method Parameters
|
|
16
24
|
*
|
|
17
25
|
* ```typescript
|
|
18
|
-
*
|
|
26
|
+
* @Post("/")
|
|
27
|
+
* async createUser(
|
|
19
28
|
* @Allow("")
|
|
20
|
-
*
|
|
29
|
+
* @BodyParams("nickname")
|
|
30
|
+
* nickname: string // Empty string allowed, but null/undefined still rejected
|
|
31
|
+
* ) {
|
|
32
|
+
* // nickname can be "" but not null/undefined
|
|
21
33
|
* }
|
|
22
34
|
* ```
|
|
23
35
|
*
|
|
24
|
-
*
|
|
36
|
+
* ### Multiple Allowed Values
|
|
37
|
+
*
|
|
38
|
+
* ```typescript
|
|
39
|
+
* class ConfigModel {
|
|
40
|
+
* @Required()
|
|
41
|
+
* @Allow(null, "", 0) // Allow null, empty string, or zero
|
|
42
|
+
* threshold: number | null;
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* ### Combining with Type Specification
|
|
47
|
+
*
|
|
48
|
+
* You can specify a model type along with allowed values:
|
|
49
|
+
*
|
|
50
|
+
* ```typescript
|
|
51
|
+
* class FormData {
|
|
52
|
+
* @Allow("", SomeModel) // Allow empty string or a SomeModel instance
|
|
53
|
+
* data: SomeModel;
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* ### Behavior
|
|
58
|
+
*
|
|
59
|
+
* - For **parameters**: Automatically marks the parameter as required
|
|
60
|
+
* - For **properties**: Automatically adds the property to the required list
|
|
61
|
+
* - Adds specified values to the schema's allowedRequiredValues list
|
|
62
|
+
*
|
|
63
|
+
* ### Validation Logic
|
|
64
|
+
*
|
|
65
|
+
* Required validation will pass if the value is:
|
|
66
|
+
* - Not `null`, `undefined`, or `""` (default required behavior)
|
|
67
|
+
* - OR one of the values specified in `@Allow()`
|
|
68
|
+
*
|
|
69
|
+
* @param values - Values to allow even when the field is required (can include a model class)
|
|
70
|
+
*
|
|
25
71
|
* @decorator
|
|
26
72
|
* @validation
|
|
27
|
-
* @
|
|
28
|
-
* @schema
|
|
29
|
-
* @input
|
|
73
|
+
* @public
|
|
30
74
|
*/
|
|
31
75
|
export function Allow(...values) {
|
|
32
76
|
const model = values.find((item) => isClass(item));
|
|
@@ -1,38 +1,78 @@
|
|
|
1
1
|
import { JsonEntityFn } from "./jsonEntityFn.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Allows a property to accept any type or a union of specified types.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* The `@Any()` decorator creates a flexible schema that accepts multiple types. When called
|
|
6
|
+
* without arguments, it allows all JSON Schema types. When called with specific types, it
|
|
7
|
+
* restricts to those types only.
|
|
8
|
+
*
|
|
9
|
+
* ### Accept All Types
|
|
6
10
|
*
|
|
7
11
|
* ```typescript
|
|
8
|
-
* class
|
|
9
|
-
*
|
|
10
|
-
*
|
|
12
|
+
* class FlexibleModel {
|
|
13
|
+
* @Any()
|
|
14
|
+
* property: any;
|
|
15
|
+
* // Accepts: string, number, boolean, object, array, or null
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
11
18
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
19
|
+
* Generated schema:
|
|
20
|
+
* ```json
|
|
21
|
+
* {
|
|
22
|
+
* "type": ["integer", "number", "string", "boolean", "array", "object", "null"]
|
|
14
23
|
* }
|
|
15
24
|
* ```
|
|
16
25
|
*
|
|
17
|
-
*
|
|
26
|
+
* ### Restrict to Specific Types
|
|
18
27
|
*
|
|
28
|
+
* ```typescript
|
|
29
|
+
* class UnionModel {
|
|
30
|
+
* @Any(String, Number, Boolean)
|
|
31
|
+
* property: string | number | boolean;
|
|
32
|
+
* // Only accepts string, number, or boolean
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* Generated schema:
|
|
19
37
|
* ```json
|
|
20
38
|
* {
|
|
21
|
-
* "type": "
|
|
22
|
-
* "properties": {
|
|
23
|
-
* "property": {
|
|
24
|
-
* "type": ["integer", "number", "string", "boolean", "array", "object", "null"]
|
|
25
|
-
* }
|
|
26
|
-
* }
|
|
39
|
+
* "type": ["string", "integer", "number", "boolean"]
|
|
27
40
|
* }
|
|
28
41
|
* ```
|
|
29
42
|
*
|
|
30
|
-
*
|
|
43
|
+
* ### With Custom Classes
|
|
44
|
+
*
|
|
45
|
+
* ```typescript
|
|
46
|
+
* class UserModel {
|
|
47
|
+
* @Property()
|
|
48
|
+
* name: string;
|
|
49
|
+
* }
|
|
50
|
+
*
|
|
51
|
+
* class FlexibleData {
|
|
52
|
+
* @Any(String, UserModel)
|
|
53
|
+
* data: string | UserModel;
|
|
54
|
+
* // Accepts either a string or a UserModel object
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* ### Use Cases
|
|
59
|
+
*
|
|
60
|
+
* - **Dynamic Data**: When property type varies based on runtime conditions
|
|
61
|
+
* - **Migrations**: During API transitions when type requirements change
|
|
62
|
+
* - **Polymorphic Data**: When different types are valid in the same field
|
|
63
|
+
* - **Third-party Integration**: When dealing with untyped external data
|
|
64
|
+
*
|
|
65
|
+
* ### Considerations
|
|
66
|
+
*
|
|
67
|
+
* - More specific decorators like `@String()`, `@Number()` provide better validation
|
|
68
|
+
* - Consider using `@OneOf()` or `@AnyOf()` for complex type unions with constraints
|
|
69
|
+
* - Overuse of `@Any()` can reduce type safety benefits
|
|
70
|
+
*
|
|
71
|
+
* @param types - Optional list of types to restrict to (if omitted, allows all types)
|
|
72
|
+
*
|
|
31
73
|
* @decorator
|
|
32
74
|
* @validation
|
|
33
|
-
* @
|
|
34
|
-
* @schema
|
|
35
|
-
* @input
|
|
75
|
+
* @public
|
|
36
76
|
*/
|
|
37
77
|
export function Any(...types) {
|
|
38
78
|
return JsonEntityFn((store) => {
|
|
@@ -1,18 +1,74 @@
|
|
|
1
1
|
import { JsonEntityFn } from "./jsonEntityFn.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Validates that a value must match AT LEAST ONE of the provided schemas (union).
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* The `anyOf` keyword from JSON Schema allows combining multiple schemas where the
|
|
6
|
+
* value must satisfy at least one schema in the list. This is useful for creating
|
|
7
|
+
* union types with different validation rules for each variant.
|
|
8
|
+
*
|
|
9
|
+
* ### Basic Usage
|
|
10
|
+
*
|
|
11
|
+
* ```typescript
|
|
12
|
+
* @AnyOf(
|
|
13
|
+
* { type: "string", minLength: 5 },
|
|
14
|
+
* { type: "number", minimum: 100 }
|
|
15
|
+
* )
|
|
16
|
+
* class StringOrLargeNumber {
|
|
17
|
+
* // Valid: "hello" (string >= 5 chars) OR 150 (number >= 100)
|
|
18
|
+
* // Invalid: "hi" (too short) OR 50 (too small)
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* ### With Model References
|
|
23
|
+
*
|
|
24
|
+
* ```typescript
|
|
25
|
+
* class EmailContact {
|
|
26
|
+
* @Property()
|
|
27
|
+
* @Email()
|
|
28
|
+
* email: string;
|
|
29
|
+
* }
|
|
30
|
+
*
|
|
31
|
+
* class PhoneContact {
|
|
32
|
+
* @Property()
|
|
33
|
+
* @Pattern(/^\d{10}$/)
|
|
34
|
+
* phone: string;
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* @AnyOf(EmailContact, PhoneContact)
|
|
38
|
+
* class Contact {
|
|
39
|
+
* // Must be either a valid EmailContact OR a valid PhoneContact
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* ### Multiple Constraints
|
|
44
|
+
*
|
|
45
|
+
* ```typescript
|
|
46
|
+
* @AnyOf(
|
|
47
|
+
* { type: "object", required: ["id"] },
|
|
48
|
+
* { type: "object", required: ["name"] }
|
|
49
|
+
* )
|
|
50
|
+
* class FlexibleIdentifier {
|
|
51
|
+
* // Must have either 'id' property OR 'name' property (or both)
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* ### Use Cases
|
|
56
|
+
*
|
|
57
|
+
* - **Union Types**: Model TypeScript union types with validation
|
|
58
|
+
* - **Alternative Formats**: Accept data in multiple valid formats
|
|
59
|
+
* - **Flexible APIs**: Support different request shapes in the same endpoint
|
|
60
|
+
*
|
|
61
|
+
* ### Compatibility Note
|
|
62
|
+
*
|
|
63
|
+
* AnyOf is not supported by OpenAPI 2.0 (Swagger). For OpenAPI 2.0 compatibility,
|
|
64
|
+
* consider using simpler alternatives or upgrade to OpenAPI 3.0.
|
|
65
|
+
*
|
|
66
|
+
* @param anyOf - One or more schemas where at least one must be satisfied
|
|
8
67
|
*
|
|
9
68
|
* @decorator
|
|
10
69
|
* @validation
|
|
11
|
-
* @
|
|
12
|
-
* @schema
|
|
13
|
-
* @classDecorator
|
|
14
|
-
* @input
|
|
15
|
-
* @param anyOf
|
|
70
|
+
* @public
|
|
71
|
+
* @see https://json-schema.org/understanding-json-schema/reference/combining#anyOf
|
|
16
72
|
*/
|
|
17
73
|
export function AnyOf(...anyOf) {
|
|
18
74
|
return JsonEntityFn((entity) => {
|
|
@@ -1,62 +1,104 @@
|
|
|
1
1
|
import { JsonEntityFn } from "./jsonEntityFn.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Restricts a property to a single fixed value using JSON Schema's `const` keyword.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* The `@Const()` decorator ensures that a property must have exactly the specified value.
|
|
6
|
+
* This is useful for literal types, discriminator fields, API version indicators, and
|
|
7
|
+
* other cases where only one specific value is valid.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
* ### With a string
|
|
9
|
+
* ### String Constants
|
|
11
10
|
*
|
|
12
11
|
* ```typescript
|
|
13
|
-
* class
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* class ApiResponse {
|
|
13
|
+
* @Const("success")
|
|
14
|
+
* status: "success";
|
|
15
|
+
* // Only "success" is valid, any other value fails validation
|
|
16
16
|
* }
|
|
17
17
|
* ```
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
19
|
+
* Generated schema:
|
|
21
20
|
* ```json
|
|
22
21
|
* {
|
|
23
22
|
* "type": "object",
|
|
24
23
|
* "properties": {
|
|
25
|
-
* "
|
|
24
|
+
* "status": {
|
|
26
25
|
* "type": "string",
|
|
27
|
-
* "const": "
|
|
26
|
+
* "const": "success"
|
|
28
27
|
* }
|
|
29
28
|
* }
|
|
30
29
|
* }
|
|
31
30
|
* ```
|
|
32
|
-
*
|
|
31
|
+
*
|
|
32
|
+
* ### Number Constants
|
|
33
33
|
*
|
|
34
34
|
* ```typescript
|
|
35
|
-
* class
|
|
36
|
-
*
|
|
37
|
-
*
|
|
35
|
+
* class ConfigModel {
|
|
36
|
+
* @Const(1)
|
|
37
|
+
* version: 1;
|
|
38
|
+
* // Only version 1 is accepted
|
|
38
39
|
* }
|
|
39
40
|
* ```
|
|
40
41
|
*
|
|
41
|
-
*
|
|
42
|
+
* ### Boolean Constants
|
|
42
43
|
*
|
|
43
|
-
* ```
|
|
44
|
-
* {
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* "type": "boolean",
|
|
49
|
-
* "const": true
|
|
50
|
-
* }
|
|
51
|
-
* }
|
|
44
|
+
* ```typescript
|
|
45
|
+
* class FeatureFlag {
|
|
46
|
+
* @Const(true)
|
|
47
|
+
* enabled: true;
|
|
48
|
+
* // Must always be true
|
|
52
49
|
* }
|
|
53
50
|
* ```
|
|
54
51
|
*
|
|
55
|
-
*
|
|
52
|
+
* ### Discriminator Pattern
|
|
53
|
+
*
|
|
54
|
+
* ```typescript
|
|
55
|
+
* class DogAnimal {
|
|
56
|
+
* @Const("dog")
|
|
57
|
+
* type: "dog";
|
|
58
|
+
*
|
|
59
|
+
* @Property()
|
|
60
|
+
* breed: string;
|
|
61
|
+
* }
|
|
62
|
+
*
|
|
63
|
+
* class CatAnimal {
|
|
64
|
+
* @Const("cat")
|
|
65
|
+
* type: "cat";
|
|
66
|
+
*
|
|
67
|
+
* @Property()
|
|
68
|
+
* indoor: boolean;
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* ### API Versioning
|
|
73
|
+
*
|
|
74
|
+
* ```typescript
|
|
75
|
+
* class V2Request {
|
|
76
|
+
* @Const("v2")
|
|
77
|
+
* apiVersion: "v2";
|
|
78
|
+
*
|
|
79
|
+
* @Property()
|
|
80
|
+
* data: any;
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* ### Use Cases
|
|
85
|
+
*
|
|
86
|
+
* - **Type Discriminators**: Distinguish between union type variants
|
|
87
|
+
* - **Literal Types**: Enforce TypeScript literal types at runtime
|
|
88
|
+
* - **API Versioning**: Validate API version in requests
|
|
89
|
+
* - **Status Fields**: Ensure specific status values in responses
|
|
90
|
+
* - **Configuration**: Lock configuration values to specific constants
|
|
91
|
+
*
|
|
92
|
+
* ### vs Enum
|
|
93
|
+
*
|
|
94
|
+
* - `@Const()`: Single fixed value only
|
|
95
|
+
* - `@Enum()`: Multiple allowed values from a set
|
|
96
|
+
*
|
|
97
|
+
* @param constValue - The exact value that this property must have
|
|
98
|
+
*
|
|
56
99
|
* @decorator
|
|
57
100
|
* @validation
|
|
58
|
-
* @
|
|
59
|
-
* @schema
|
|
101
|
+
* @public
|
|
60
102
|
*/
|
|
61
103
|
export function Const(constValue) {
|
|
62
104
|
return JsonEntityFn((store) => {
|