@tsed/schema 8.19.2 → 8.19.4
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/components/open-spec/nullableMapper.js +6 -2
- 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,78 +1,112 @@
|
|
|
1
1
|
import { ValueOf } from "@tsed/core";
|
|
2
2
|
import { JsonFormatTypes } from "../../domain/JsonFormatTypes.js";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* - **date**: full-date according to [RFC3339](https://json-schema.org/latest/json-schema-validation.html#RFC3339).
|
|
7
|
-
* - **time**: time with optional time-zone.
|
|
8
|
-
* - **date-time**: date-time from the same source (time-zone is mandatory).
|
|
9
|
-
* - **uri**: full uri with optional protocol.
|
|
10
|
-
* - **email**: email address.
|
|
11
|
-
* - **hostname**: host name according to [RFC1034](https://tools.ietf.org/html/rfc1034#section-3.1).
|
|
12
|
-
* - **ipv4**: IP address v4.
|
|
13
|
-
* - **ipv6**: IP address v6.
|
|
14
|
-
* - **regex**: tests whether a string is a valid regular expression by passing it to RegExp constructor.
|
|
4
|
+
* Applies a format validation to string properties using JSON Schema's `format` keyword.
|
|
15
5
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
6
|
+
* The `@Format()` decorator validates string values against common formats like email,
|
|
7
|
+
* URI, date-time, and IP addresses. This provides semantic validation beyond just checking
|
|
8
|
+
* the string type.
|
|
19
9
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
10
|
+
* ### Supported Formats
|
|
11
|
+
*
|
|
12
|
+
* - **date**: Full-date according to RFC3339 (`2024-01-15`)
|
|
13
|
+
* - **time**: Time with optional time-zone (`14:30:00`, `14:30:00+02:00`)
|
|
14
|
+
* - **date-time**: Date-time from RFC3339 (time-zone mandatory: `2024-01-15T14:30:00Z`)
|
|
15
|
+
* - **uri**: Full URI with optional protocol (`https://example.com/path`)
|
|
16
|
+
* - **url**: Valid URL (stricter than uri)
|
|
17
|
+
* - **email**: Email address (`user@example.com`)
|
|
18
|
+
* - **hostname**: Host name according to RFC1034 (`example.com`)
|
|
19
|
+
* - **ipv4**: IPv4 address (`192.168.1.1`)
|
|
20
|
+
* - **ipv6**: IPv6 address (`2001:0db8:85a3::8a2e:0370:7334`)
|
|
21
|
+
* - **regex**: Valid regular expression pattern
|
|
22
|
+
*
|
|
23
|
+
* ### Basic Usage
|
|
22
24
|
*
|
|
23
25
|
* ```typescript
|
|
24
|
-
* class
|
|
25
|
-
*
|
|
26
|
-
*
|
|
26
|
+
* class ContactModel {
|
|
27
|
+
* @Format("email")
|
|
28
|
+
* email: string;
|
|
29
|
+
*
|
|
30
|
+
* @Format("uri")
|
|
31
|
+
* website: string;
|
|
32
|
+
*
|
|
33
|
+
* @Format("ipv4")
|
|
34
|
+
* serverIp: string;
|
|
27
35
|
* }
|
|
28
36
|
* ```
|
|
29
37
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* }
|
|
38
|
+
* ### With Arrays
|
|
39
|
+
*
|
|
40
|
+
* ```typescript
|
|
41
|
+
* class ServerConfig {
|
|
42
|
+
* @Format("email")
|
|
43
|
+
* @CollectionOf(String)
|
|
44
|
+
* adminEmails: string[];
|
|
45
|
+
* // Each email must be valid
|
|
39
46
|
* }
|
|
40
47
|
* ```
|
|
41
48
|
*
|
|
42
|
-
* ###
|
|
49
|
+
* ### Date/Time Formats
|
|
43
50
|
*
|
|
44
51
|
* ```typescript
|
|
45
|
-
* class
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
52
|
+
* class EventModel {
|
|
53
|
+
* @Format("date")
|
|
54
|
+
* eventDate: string; // "2024-12-25"
|
|
55
|
+
*
|
|
56
|
+
* @Format("time")
|
|
57
|
+
* startTime: string; // "14:30:00"
|
|
58
|
+
*
|
|
59
|
+
* @Format("date-time")
|
|
60
|
+
* createdAt: string; // "2024-01-15T14:30:00Z"
|
|
49
61
|
* }
|
|
50
62
|
* ```
|
|
51
63
|
*
|
|
52
|
-
*
|
|
64
|
+
* ### Convenience Decorators
|
|
53
65
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
66
|
+
* Ts.ED provides convenience decorators that use `@Format()` internally:
|
|
67
|
+
*
|
|
68
|
+
* - `@Email()` - Equivalent to `@Format("email")`
|
|
69
|
+
* - `@DateTime()` - Equivalent to `@Format("date-time")`
|
|
70
|
+
* - `@DateFormat()` - Equivalent to `@Format("date")`
|
|
71
|
+
* - `@TimeFormat()` - Equivalent to `@Format("time")`
|
|
72
|
+
* - `@Uri()` - Equivalent to `@Format("uri")`
|
|
73
|
+
* - `@Url()` - Equivalent to `@Format("url")`
|
|
74
|
+
*
|
|
75
|
+
* ### Use Cases
|
|
76
|
+
*
|
|
77
|
+
* - **Data Integrity**: Ensure strings conform to expected formats
|
|
78
|
+
* - **API Validation**: Validate input data at API boundaries
|
|
79
|
+
* - **Database Constraints**: Match database column format requirements
|
|
80
|
+
* - **Standards Compliance**: Ensure RFC compliance for dates, emails, URIs
|
|
81
|
+
*
|
|
82
|
+
* ### Validation Examples
|
|
83
|
+
*
|
|
84
|
+
* ```typescript
|
|
85
|
+
* @Format("email")
|
|
86
|
+
* email: string;
|
|
87
|
+
*
|
|
88
|
+
* // Valid:
|
|
89
|
+
* "user@example.com"
|
|
90
|
+
* "jane.doe+tag@company.co.uk"
|
|
91
|
+
*
|
|
92
|
+
* // Invalid:
|
|
93
|
+
* "not-an-email"
|
|
94
|
+
* "missing@domain"
|
|
95
|
+
* "@example.com"
|
|
67
96
|
* ```
|
|
68
97
|
*
|
|
69
|
-
*
|
|
98
|
+
* ### Important Notes
|
|
99
|
+
*
|
|
100
|
+
* - Format validation depends on the validator implementation (AJV, etc.)
|
|
101
|
+
* - Some formats may require additional validator plugins
|
|
102
|
+
* - Format is primarily for strings; use on other types may be ignored
|
|
103
|
+
* - Can be combined with other string validators (MinLength, Pattern, etc.)
|
|
104
|
+
*
|
|
105
|
+
* @param format - The format keyword to apply (from JsonFormatTypes enum)
|
|
106
|
+
*
|
|
70
107
|
* @decorator
|
|
71
108
|
* @validation
|
|
72
|
-
* @
|
|
73
|
-
* @schema
|
|
74
|
-
* @input
|
|
75
|
-
* @ajv-errors
|
|
109
|
+
* @public
|
|
76
110
|
*/
|
|
77
111
|
export declare const Format: import("../../utils/withErrorMsg.js").ErrorChainedDecorator<(format: JsonFormatTypes | ValueOf<JsonFormatTypes>) => (...args: any[]) => any>;
|
|
78
112
|
/**
|
|
@@ -1,25 +1,91 @@
|
|
|
1
1
|
import { Type } from "@tsed/core";
|
|
2
2
|
import type { JSONSchema6TypeName } from "json-schema";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Marks a property as nullable, allowing it to accept `null` in addition to its base type.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* The `@Nullable()` decorator creates a union type that includes `null` alongside the
|
|
7
|
+
* specified type(s). This is implemented using JSON Schema's `oneOf` keyword to allow
|
|
8
|
+
* either the specified type or null.
|
|
9
|
+
*
|
|
10
|
+
* ### Single Type with Null
|
|
7
11
|
*
|
|
8
12
|
* ```typescript
|
|
9
|
-
* class
|
|
10
|
-
*
|
|
11
|
-
*
|
|
13
|
+
* class UserModel {
|
|
14
|
+
* @Nullable(Date)
|
|
15
|
+
* lastLogin: Date | null;
|
|
16
|
+
* // Accepts: Date object OR null
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* ### Multiple Types with Null
|
|
12
21
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
22
|
+
* ```typescript
|
|
23
|
+
* class FlexibleModel {
|
|
24
|
+
* @Nullable(String, Number, Boolean)
|
|
25
|
+
* property: string | number | boolean | null;
|
|
26
|
+
* // Accepts: string OR number OR boolean OR null
|
|
15
27
|
* }
|
|
16
28
|
* ```
|
|
17
29
|
*
|
|
18
|
-
*
|
|
30
|
+
* ### With Custom Classes
|
|
31
|
+
*
|
|
32
|
+
* ```typescript
|
|
33
|
+
* class Address {
|
|
34
|
+
* @Property()
|
|
35
|
+
* street: string;
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* class Person {
|
|
39
|
+
* @Nullable(Address)
|
|
40
|
+
* address: Address | null;
|
|
41
|
+
* // Accepts: Address object OR null
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* ### TypeScript Integration
|
|
46
|
+
*
|
|
47
|
+
* ```typescript
|
|
48
|
+
* class Product {
|
|
49
|
+
* @Nullable(String)
|
|
50
|
+
* description: string | null;
|
|
51
|
+
*
|
|
52
|
+
* @Nullable(Number)
|
|
53
|
+
* discount: number | null;
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* ### Important: Arrays
|
|
58
|
+
*
|
|
59
|
+
* Do NOT use `@Nullable(Array)` as it produces incorrect schemas. Instead:
|
|
60
|
+
*
|
|
61
|
+
* ```typescript
|
|
62
|
+
* // Wrong
|
|
63
|
+
* @Nullable(Array)
|
|
64
|
+
* items: any[] | null;
|
|
65
|
+
*
|
|
66
|
+
* // Correct
|
|
67
|
+
* @Schema(array().items().nullable())
|
|
68
|
+
* items: any[] | null;
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* ### Use Cases
|
|
72
|
+
*
|
|
73
|
+
* - **Optional Database Fields**: Model nullable database columns
|
|
74
|
+
* - **Partial Updates**: Allow fields to be explicitly set to null in PATCH requests
|
|
75
|
+
* - **Default Values**: Distinguish between "not provided" and "explicitly null"
|
|
76
|
+
* - **External APIs**: Match nullable fields from third-party services
|
|
77
|
+
*
|
|
78
|
+
* ### vs Optional
|
|
79
|
+
*
|
|
80
|
+
* - `@Nullable()`: Field can be present with value `null`
|
|
81
|
+
* - `@Optional()`: Field can be omitted entirely
|
|
82
|
+
* - Can combine both: `@Optional() @Nullable(String)` allows omitted, null, or string
|
|
83
|
+
*
|
|
84
|
+
* @param type - The primary type that can be null
|
|
85
|
+
* @param types - Additional types that can be null (creates multi-type union with null)
|
|
86
|
+
*
|
|
19
87
|
* @decorator
|
|
20
88
|
* @validation
|
|
21
|
-
* @
|
|
22
|
-
* @schema
|
|
23
|
-
* @input
|
|
89
|
+
* @public
|
|
24
90
|
*/
|
|
25
91
|
export declare function Nullable(type: JSONSchema6TypeName | Type<any> | any, ...types: (JSONSchema6TypeName | Type<any> | any)[]): any;
|
|
@@ -1,17 +1,101 @@
|
|
|
1
1
|
import type { JsonSchema } from "../../domain/JsonSchema.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Validates that a value must match EXACTLY ONE of the provided schemas (exclusive union).
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* The `oneOf` keyword from JSON Schema requires the value to be valid against exactly
|
|
6
|
+
* one schema in the list - not zero and not more than one. This is useful for strict
|
|
7
|
+
* union types where overlapping schemas should be rejected.
|
|
8
|
+
*
|
|
9
|
+
* ### Basic Usage
|
|
10
|
+
*
|
|
11
|
+
* ```typescript
|
|
12
|
+
* @OneOf(
|
|
13
|
+
* { type: "string" },
|
|
14
|
+
* { type: "number" }
|
|
15
|
+
* )
|
|
16
|
+
* class StringOrNumber {
|
|
17
|
+
* // Valid: "hello" OR 42
|
|
18
|
+
* // Invalid: true (matches neither), or ambiguous values matching multiple schemas
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* ### Discriminated Unions
|
|
23
|
+
*
|
|
24
|
+
* ```typescript
|
|
25
|
+
* @OneOf(
|
|
26
|
+
* {
|
|
27
|
+
* type: "object",
|
|
28
|
+
* properties: { type: { const: "email" }, email: { type: "string" } },
|
|
29
|
+
* required: ["type", "email"]
|
|
30
|
+
* },
|
|
31
|
+
* {
|
|
32
|
+
* type: "object",
|
|
33
|
+
* properties: { type: { const: "phone" }, phone: { type: "string" } },
|
|
34
|
+
* required: ["type", "phone"]
|
|
35
|
+
* }
|
|
36
|
+
* )
|
|
37
|
+
* class Contact {
|
|
38
|
+
* // Must be EITHER email contact OR phone contact, not both or neither
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* ### With Model Classes
|
|
43
|
+
*
|
|
44
|
+
* ```typescript
|
|
45
|
+
* class CreditCard {
|
|
46
|
+
* @Const("credit")
|
|
47
|
+
* type: "credit";
|
|
48
|
+
*
|
|
49
|
+
* @Property()
|
|
50
|
+
* cardNumber: string;
|
|
51
|
+
* }
|
|
52
|
+
*
|
|
53
|
+
* class BankTransfer {
|
|
54
|
+
* @Const("bank")
|
|
55
|
+
* type: "bank";
|
|
56
|
+
*
|
|
57
|
+
* @Property()
|
|
58
|
+
* iban: string;
|
|
59
|
+
* }
|
|
60
|
+
*
|
|
61
|
+
* @OneOf(CreditCard, BankTransfer)
|
|
62
|
+
* class PaymentMethod {
|
|
63
|
+
* // Must be exactly one payment method type
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* ### Nullable with OneOf
|
|
68
|
+
*
|
|
69
|
+
* ```typescript
|
|
70
|
+
* @OneOf(null, { type: "string" })
|
|
71
|
+
* class NullableString {
|
|
72
|
+
* // Exactly null OR exactly a string
|
|
73
|
+
* }
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* ### Use Cases
|
|
77
|
+
*
|
|
78
|
+
* - **Strict Union Types**: Enforce exactly one type from a set
|
|
79
|
+
* - **Discriminated Unions**: Type-safe polymorphic data structures
|
|
80
|
+
* - **Mutually Exclusive Options**: Ensure only one option is selected
|
|
81
|
+
* - **Nullable Types**: Combine with null for nullable properties
|
|
82
|
+
*
|
|
83
|
+
* ### oneOf vs anyOf vs allOf
|
|
84
|
+
*
|
|
85
|
+
* - `@OneOf()`: Must match **exactly one** schema (exclusive)
|
|
86
|
+
* - `@AnyOf()`: Must match **at least one** schema (inclusive)
|
|
87
|
+
* - `@AllOf()`: Must match **all** schemas (intersection)
|
|
88
|
+
*
|
|
89
|
+
* ### Compatibility Note
|
|
90
|
+
*
|
|
91
|
+
* OneOf is not supported by OpenAPI 2.0 (Swagger). For OpenAPI 2.0 compatibility,
|
|
92
|
+
* consider using discriminator patterns or upgrade to OpenAPI 3.0.
|
|
93
|
+
*
|
|
94
|
+
* @param oneOf - Schemas where exactly one must be satisfied
|
|
8
95
|
*
|
|
9
96
|
* @decorator
|
|
10
97
|
* @validation
|
|
11
|
-
* @
|
|
12
|
-
* @schema
|
|
13
|
-
* @classDecorator
|
|
14
|
-
* @input
|
|
15
|
-
* @param oneOf
|
|
98
|
+
* @public
|
|
99
|
+
* @see https://json-schema.org/understanding-json-schema/reference/combining#oneOf
|
|
16
100
|
*/
|
|
17
101
|
export declare function OneOf(...oneOf: Parameters<JsonSchema["oneOf"]>[0]): (...args: any[]) => any;
|
|
@@ -1,10 +1,99 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Marks a property or parameter as optional, meaning it can be omitted from the input.
|
|
3
|
+
*
|
|
4
|
+
* The `@Optional()` decorator removes the property from the required fields list in the
|
|
5
|
+
* schema, allowing it to be absent from the object. For parameters, it marks them as
|
|
6
|
+
* not required in the method signature.
|
|
7
|
+
*
|
|
8
|
+
* ### On Properties
|
|
9
|
+
*
|
|
10
|
+
* ```typescript
|
|
11
|
+
* class UserModel {
|
|
12
|
+
* @Property()
|
|
13
|
+
* name: string; // Required by default
|
|
14
|
+
*
|
|
15
|
+
* @Optional()
|
|
16
|
+
* @Property()
|
|
17
|
+
* nickname?: string; // Optional - can be omitted
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* ### On Parameters
|
|
22
|
+
*
|
|
23
|
+
* ```typescript
|
|
24
|
+
* @Controller("/users")
|
|
25
|
+
* class UserController {
|
|
26
|
+
* @Get("/:id")
|
|
27
|
+
* async get(
|
|
28
|
+
* @PathParams("id") id: string,
|
|
29
|
+
* @Optional()
|
|
30
|
+
* @QueryParams("include") include?: string // Optional query param
|
|
31
|
+
* ) {
|
|
32
|
+
* // include can be undefined
|
|
33
|
+
* }
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* ### With Default Values
|
|
38
|
+
*
|
|
39
|
+
* ```typescript
|
|
40
|
+
* class ConfigModel {
|
|
41
|
+
* @Optional()
|
|
42
|
+
* @Default(10)
|
|
43
|
+
* timeout?: number;
|
|
44
|
+
* // Optional field with a default value
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* ### vs Nullable
|
|
49
|
+
*
|
|
50
|
+
* - `@Optional()`: Field can be **omitted** entirely from the object
|
|
51
|
+
* - `@Nullable()`: Field must be **present** but can have value `null`
|
|
52
|
+
* - Can combine: `@Optional() @Nullable(String)` allows omitted, null, or string
|
|
53
|
+
*
|
|
54
|
+
* ### Examples
|
|
55
|
+
*
|
|
56
|
+
* ```typescript
|
|
57
|
+
* // Optional only - field can be omitted
|
|
58
|
+
* @Optional()
|
|
59
|
+
* field1?: string;
|
|
60
|
+
* // Valid: {} or { field1: "value" }
|
|
61
|
+
* // Invalid: { field1: null }
|
|
62
|
+
*
|
|
63
|
+
* // Nullable only - field must be present
|
|
64
|
+
* @Nullable(String)
|
|
65
|
+
* field2: string | null;
|
|
66
|
+
* // Valid: { field2: null } or { field2: "value" }
|
|
67
|
+
* // Invalid: {}
|
|
68
|
+
*
|
|
69
|
+
* // Both - maximum flexibility
|
|
70
|
+
* @Optional()
|
|
71
|
+
* @Nullable(String)
|
|
72
|
+
* field3?: string | null;
|
|
73
|
+
* // Valid: {}, { field3: null }, { field3: "value" }
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* ### Use Cases
|
|
77
|
+
*
|
|
78
|
+
* - **Optional Configuration**: Non-required config properties
|
|
79
|
+
* - **Query Parameters**: Optional filters and options in APIs
|
|
80
|
+
* - **Partial Updates**: PATCH endpoints where only changed fields are sent
|
|
81
|
+
* - **Progressive Enhancement**: Features that aren't required for basic functionality
|
|
82
|
+
*
|
|
83
|
+
* ### TypeScript Integration
|
|
84
|
+
*
|
|
85
|
+
* Use TypeScript's optional property syntax (`?:`) alongside `@Optional()` for
|
|
86
|
+
* type safety:
|
|
87
|
+
*
|
|
88
|
+
* ```typescript
|
|
89
|
+
* class Model {
|
|
90
|
+
* @Optional()
|
|
91
|
+
* optionalField?: string; // TypeScript knows it can be undefined
|
|
92
|
+
* }
|
|
93
|
+
* ```
|
|
3
94
|
*
|
|
4
95
|
* @decorator
|
|
5
96
|
* @validation
|
|
6
|
-
* @
|
|
7
|
-
* @schema
|
|
8
|
-
* @input
|
|
97
|
+
* @public
|
|
9
98
|
*/
|
|
10
99
|
export declare function Optional(): (...args: any[]) => any;
|
|
@@ -1,11 +1,47 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Declare a
|
|
2
|
+
* Declare a property on a model class for schema generation.
|
|
3
|
+
*
|
|
4
|
+
* The `@Property()` decorator marks a class property for inclusion in generated
|
|
5
|
+
* JSON schemas and OpenAPI specifications. It can optionally specify the property's
|
|
6
|
+
* type, which is useful for arrays, generics, or when TypeScript's reflection
|
|
7
|
+
* doesn't provide sufficient type information.
|
|
8
|
+
*
|
|
9
|
+
* ### Usage
|
|
10
|
+
*
|
|
11
|
+
* ```typescript
|
|
12
|
+
* class User {
|
|
13
|
+
* // Basic property (type inferred from TypeScript)
|
|
14
|
+
* @Property()
|
|
15
|
+
* name: string;
|
|
16
|
+
*
|
|
17
|
+
* // Property with explicit type
|
|
18
|
+
* @Property(Number)
|
|
19
|
+
* age: number;
|
|
20
|
+
*
|
|
21
|
+
* // Array property
|
|
22
|
+
* @Property([String])
|
|
23
|
+
* tags: string[];
|
|
24
|
+
*
|
|
25
|
+
* // Nested model
|
|
26
|
+
* @Property(Address)
|
|
27
|
+
* address: Address;
|
|
28
|
+
*
|
|
29
|
+
* // Generic/complex type
|
|
30
|
+
* @Property(() => User)
|
|
31
|
+
* manager: User;
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* ### When to Use Explicit Types
|
|
36
|
+
*
|
|
37
|
+
* - **Arrays**: Always specify array item types: `@Property([String])`
|
|
38
|
+
* - **Generics**: Provide concrete types for generic classes
|
|
39
|
+
* - **Forward References**: Use arrow functions for circular dependencies
|
|
40
|
+
* - **Complex Types**: When TypeScript metadata is insufficient
|
|
41
|
+
*
|
|
42
|
+
* @param type - Optional type definition (class, primitive, array, or arrow function)
|
|
3
43
|
*
|
|
4
|
-
* @param type
|
|
5
44
|
* @decorator
|
|
6
|
-
* @
|
|
7
|
-
* @swagger
|
|
8
|
-
* @schema
|
|
9
|
-
* @input
|
|
45
|
+
* @public
|
|
10
46
|
*/
|
|
11
47
|
export declare function Property(type?: any): (...args: any[]) => any;
|
|
@@ -1,11 +1,112 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Marks a property as read-only, indicating it should not be modified by clients.
|
|
3
|
+
*
|
|
4
|
+
* The `@ReadOnly()` decorator sets the `readOnly` flag in the JSON Schema, which signals
|
|
5
|
+
* to validators and API consumers that this property is for reading only and should not
|
|
6
|
+
* be included in request payloads. In OpenAPI specs, read-only properties are excluded
|
|
7
|
+
* from request body schemas but included in response schemas.
|
|
8
|
+
*
|
|
9
|
+
* ### Basic Usage
|
|
10
|
+
*
|
|
11
|
+
* ```typescript
|
|
12
|
+
* class UserModel {
|
|
13
|
+
* @ReadOnly()
|
|
14
|
+
* id: string;
|
|
15
|
+
* // Server-generated, clients cannot set this
|
|
16
|
+
*
|
|
17
|
+
* @ReadOnly()
|
|
18
|
+
* createdAt: Date;
|
|
19
|
+
* // Timestamp set by server
|
|
20
|
+
*
|
|
21
|
+
* @Property()
|
|
22
|
+
* name: string;
|
|
23
|
+
* // Can be read and written
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* ### Server-Generated Fields
|
|
28
|
+
*
|
|
29
|
+
* ```typescript
|
|
30
|
+
* class PostModel {
|
|
31
|
+
* @ReadOnly()
|
|
32
|
+
* id: number;
|
|
33
|
+
*
|
|
34
|
+
* @ReadOnly()
|
|
35
|
+
* @Default(() => new Date())
|
|
36
|
+
* createdAt: Date;
|
|
37
|
+
*
|
|
38
|
+
* @ReadOnly()
|
|
39
|
+
* @Default(() => new Date())
|
|
40
|
+
* updatedAt: Date;
|
|
41
|
+
*
|
|
42
|
+
* @Property()
|
|
43
|
+
* title: string;
|
|
44
|
+
*
|
|
45
|
+
* @Property()
|
|
46
|
+
* content: string;
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* ### Computed Properties
|
|
51
|
+
*
|
|
52
|
+
* ```typescript
|
|
53
|
+
* class OrderModel {
|
|
54
|
+
* @Property()
|
|
55
|
+
* items: OrderItem[];
|
|
56
|
+
*
|
|
57
|
+
* @ReadOnly()
|
|
58
|
+
* get totalPrice(): number {
|
|
59
|
+
* return this.items.reduce((sum, item) => sum + item.price, 0);
|
|
60
|
+
* }
|
|
61
|
+
* // Computed value, clients cannot set it
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* ### Toggle Read-Only
|
|
66
|
+
*
|
|
67
|
+
* ```typescript
|
|
68
|
+
* class ConfigModel {
|
|
69
|
+
* @ReadOnly(true)
|
|
70
|
+
* lockedField: string;
|
|
71
|
+
* // Read-only
|
|
72
|
+
*
|
|
73
|
+
* @ReadOnly(false)
|
|
74
|
+
* editableField: string;
|
|
75
|
+
* // Explicitly not read-only (default behavior)
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* ### OpenAPI Behavior
|
|
80
|
+
*
|
|
81
|
+
* In OpenAPI/Swagger documentation:
|
|
82
|
+
* - Read-only properties appear in **response** schemas
|
|
83
|
+
* - Read-only properties are **excluded** from **request** schemas
|
|
84
|
+
* - Helps generate accurate API documentation
|
|
85
|
+
*
|
|
86
|
+
* ### vs WriteOnly
|
|
87
|
+
*
|
|
88
|
+
* - `@ReadOnly()`: Property can be read but not written (responses only)
|
|
89
|
+
* - `@WriteOnly()`: Property can be written but not read (requests only)
|
|
90
|
+
* - Neither: Property can be both read and written
|
|
91
|
+
*
|
|
92
|
+
* ### Use Cases
|
|
93
|
+
*
|
|
94
|
+
* - **Database IDs**: Auto-generated primary keys
|
|
95
|
+
* - **Timestamps**: Server-managed created/updated dates
|
|
96
|
+
* - **Computed Values**: Derived or calculated properties
|
|
97
|
+
* - **System Metadata**: Internal tracking fields
|
|
98
|
+
* - **Audit Fields**: Who created/modified records
|
|
99
|
+
*
|
|
100
|
+
* ### Security Note
|
|
101
|
+
*
|
|
102
|
+
* While `@ReadOnly()` provides documentation and client-side validation hints, it does
|
|
103
|
+
* not enforce security at the server level. Always validate incoming data server-side
|
|
104
|
+
* and ignore read-only fields in request payloads.
|
|
105
|
+
*
|
|
106
|
+
* @param readOnly - Whether the property is read-only (default: true)
|
|
3
107
|
*
|
|
4
|
-
* @returns {Function}
|
|
5
108
|
* @decorator
|
|
6
109
|
* @validation
|
|
7
|
-
* @
|
|
8
|
-
* @parameter
|
|
9
|
-
* @schema
|
|
110
|
+
* @public
|
|
10
111
|
*/
|
|
11
112
|
export declare function ReadOnly(readOnly?: boolean): (...args: any[]) => any;
|