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