@tsed/schema 8.19.2 → 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
@@ -1,51 +1,121 @@
1
1
  import { withErrorMsg } from "../../utils/withErrorMsg.js";
2
2
  import { JsonEntityFn } from "../common/jsonEntityFn.js";
3
3
  /**
4
- * The value `maxItems` MUST be a non-negative integer.
4
+ * Sets the maximum number of items allowed in an array.
5
5
  *
6
- * An array instance is valid against `maxItems` if its size is less than, or equal to, the value of this keyword.
6
+ * The `@MaxItems()` decorator validates that an array has at most the specified number
7
+ * of elements. This is useful for enforcing size limits on collections to prevent
8
+ * excessive data, manage performance, or enforce business rules.
7
9
  *
8
- * :: warning
9
- * The value `maxItems` MUST be a non-negative integer.
10
- * :::
11
- *
12
- * :: warning
13
- * This decorator will be removed in v7.
14
- * For v6 user, use @@MaxItems@@ from @tsed/schema instead of @tsed/platform-http.
15
- * :::
16
- *
17
- * ## Example
10
+ * ### Basic Usage
18
11
  *
19
12
  * ```typescript
20
- * class Model {
21
- * @CollectionOf(String)
22
- * @MaxItems(10)
23
- * property: string[];
13
+ * class UserModel {
14
+ * @CollectionOf(String)
15
+ * @MaxItems(5)
16
+ * tags: string[];
17
+ * // Maximum 5 tags allowed
24
18
  * }
25
19
  * ```
26
20
  *
27
- * Will produce:
28
- *
21
+ * Generated schema:
29
22
  * ```json
30
23
  * {
31
24
  * "type": "object",
32
25
  * "properties": {
33
- * "property": {
34
- * "type": "number",
35
- * "maxItems": 10
26
+ * "tags": {
27
+ * "type": "array",
28
+ * "maxItems": 5,
29
+ * "items": {
30
+ * "type": "string"
31
+ * }
36
32
  * }
37
33
  * }
38
34
  * }
39
35
  * ```
40
36
  *
41
- * @param {number} maxItems
37
+ * ### With MinItems - Range Validation
38
+ *
39
+ * ```typescript
40
+ * class TeamModel {
41
+ * @CollectionOf(String)
42
+ * @MinItems(1)
43
+ * @MaxItems(10)
44
+ * members: string[];
45
+ * // Must have between 1 and 10 members
46
+ * }
47
+ * ```
48
+ *
49
+ * ### API Rate Limiting
50
+ *
51
+ * ```typescript
52
+ * class BulkRequest {
53
+ * @CollectionOf(Number)
54
+ * @MaxItems(100)
55
+ * ids: number[];
56
+ * // Limit bulk operations to 100 items
57
+ * }
58
+ * ```
59
+ *
60
+ * ### File Uploads
61
+ *
62
+ * ```typescript
63
+ * class FileUpload {
64
+ * @CollectionOf(Object)
65
+ * @MaxItems(5)
66
+ * attachments: File[];
67
+ * // Maximum 5 file attachments
68
+ * }
69
+ * ```
70
+ *
71
+ * ### Validation Examples
72
+ *
73
+ * ```typescript
74
+ * @MaxItems(3)
75
+ * items: string[];
76
+ *
77
+ * // Valid:
78
+ * [] // 0 items (≤ 3)
79
+ * ["a"] // 1 item (≤ 3)
80
+ * ["a", "b", "c"] // 3 items (≤ 3)
81
+ *
82
+ * // Invalid:
83
+ * ["a", "b", "c", "d"] // 4 items (> 3)
84
+ * ```
85
+ *
86
+ * ### Use Cases
87
+ *
88
+ * - **Performance**: Limit collection sizes to prevent memory issues
89
+ * - **Business Rules**: Enforce maximum quantities (cart items, selections)
90
+ * - **API Protection**: Prevent abuse with excessive bulk requests
91
+ * - **UI Constraints**: Match front-end limitations (max selections)
92
+ * - **Data Quality**: Encourage focused, manageable data sets
93
+ *
94
+ * ### Combining with Other Validators
95
+ *
96
+ * ```typescript
97
+ * class SearchQuery {
98
+ * @CollectionOf(String)
99
+ * @MinItems(1)
100
+ * @MaxItems(10)
101
+ * @UniqueItems()
102
+ * keywords: string[];
103
+ * // 1-10 unique search keywords
104
+ * }
105
+ * ```
106
+ *
107
+ * ### Important Notes
108
+ *
109
+ * - The value must be a **non-negative integer** (0 or greater)
110
+ * - Throws an error if a negative value is provided
111
+ * - Empty arrays (length 0) always pass maxItems validation
112
+ * - Can be combined with custom error messages using ajv-errors
113
+ *
114
+ * @param maxItems - Maximum number of items allowed (must be non-negative)
115
+ *
42
116
  * @decorator
43
117
  * @validation
44
- * @swagger
45
- * @schema
46
- * @input
47
- * @collections
48
- * @ajv-errors
118
+ * @public
49
119
  */
50
120
  export const MaxItems = withErrorMsg("maxItems", (maxItems) => {
51
121
  if (maxItems < 0) {
@@ -1,50 +1,45 @@
1
1
  import { withErrorMsg } from "../../utils/withErrorMsg.js";
2
2
  import { JsonEntityFn } from "../common/jsonEntityFn.js";
3
3
  /**
4
- * An object instance is valid against `maxProperties` if its number of properties is less than, or equal to, the value of this keyword.
4
+ * Sets the maximum number of properties allowed on an object.
5
5
  *
6
- * ::: warning
7
- * The value of this keyword MUST be a non-negative integer.
8
- * :::
6
+ * The `@MaxProperties()` decorator validates that an object has at most the specified
7
+ * number of properties. This is useful for limiting dynamic object sizes, preventing
8
+ * excessive data structures, or enforcing schema constraints on flexible objects.
9
9
  *
10
- * ::: warning
11
- * This decorator will be removed in v7.
12
- * For v6 user, use @@MaxProperties@@ from @tsed/schema instead of @tsed/platform-http.
13
- * :::
10
+ * ### On Property
14
11
  *
15
- * ## Example
16
- * ### On prop
17
12
  * ```typescript
18
- * class Model {
19
- * @MaxProperties(10)
20
- * property: any;
13
+ * class ConfigModel {
14
+ * @MaxProperties(5)
15
+ * metadata: Record<string, any>;
16
+ * // Object can have at most 5 properties
21
17
  * }
22
18
  * ```
23
19
  *
24
- * Will produce:
25
- *
20
+ * Generated schema:
26
21
  * ```json
27
22
  * {
28
23
  * "type": "object",
29
24
  * "properties": {
30
- * "property": {
31
- * "type": "any",
32
- * "maxProperties": 10
25
+ * "metadata": {
26
+ * "type": "object",
27
+ * "maxProperties": 5
33
28
  * }
34
29
  * }
35
30
  * }
36
31
  * ```
37
32
  *
38
- * ### On class
33
+ * ### On Class
39
34
  *
40
35
  * ```typescript
41
36
  * @MaxProperties(10)
42
- * class Model {
37
+ * class DynamicModel {
38
+ * // Class instances can have at most 10 properties total
43
39
  * }
44
40
  * ```
45
41
  *
46
- * Will produce:
47
- *
42
+ * Generated schema:
48
43
  * ```json
49
44
  * {
50
45
  * "type": "object",
@@ -55,20 +50,91 @@ import { JsonEntityFn } from "../common/jsonEntityFn.js";
55
50
  * ### On Parameter
56
51
  *
57
52
  * ```typescript
53
+ * @Controller("/api")
54
+ * class ApiController {
55
+ * @Post("/config")
56
+ * updateConfig(
57
+ * @BodyParams() @MaxProperties(10) config: any
58
+ * ) {
59
+ * // Config object limited to 10 properties
60
+ * }
61
+ * }
62
+ * ```
63
+ *
64
+ * ### With MinProperties - Range Validation
65
+ *
66
+ * ```typescript
67
+ * class FilterModel {
68
+ * @MinProperties(1)
69
+ * @MaxProperties(5)
70
+ * filters: Record<string, string>;
71
+ * // Must have 1-5 filter properties
72
+ * }
73
+ * ```
74
+ *
75
+ * ### Dynamic Objects
76
+ *
77
+ * ```typescript
78
+ * class UserPreferences {
79
+ * @MaxProperties(20)
80
+ * @AdditionalProperties({ type: "string" })
81
+ * settings: Record<string, string>;
82
+ * // Up to 20 custom settings, all string values
83
+ * }
84
+ * ```
85
+ *
86
+ * ### Validation Examples
87
+ *
88
+ * ```typescript
89
+ * @MaxProperties(2)
90
+ * data: object;
91
+ *
92
+ * // Valid:
93
+ * {} // 0 properties (≤ 2)
94
+ * { a: 1 } // 1 property (≤ 2)
95
+ * { a: 1, b: 2 } // 2 properties (≤ 2)
96
+ *
97
+ * // Invalid:
98
+ * { a: 1, b: 2, c: 3 } // 3 properties (> 2)
99
+ * ```
100
+ *
101
+ * ### Use Cases
102
+ *
103
+ * - **API Rate Limiting**: Restrict filter/query parameter counts
104
+ * - **Performance**: Prevent overly complex objects
105
+ * - **Schema Constraints**: Limit dynamic data structures
106
+ * - **Configuration**: Cap number of custom settings
107
+ * - **Security**: Prevent payload bloat attacks
58
108
  *
59
- * class Model {
60
- * method(@Any() @MaxProperties(10) obj: any){}
109
+ * ### Flexible Schemas
110
+ *
111
+ * ```typescript
112
+ * class ExtensibleModel {
113
+ * @Property()
114
+ * id: string;
115
+ *
116
+ * @Property()
117
+ * name: string;
118
+ *
119
+ * @MaxProperties(5)
120
+ * @AdditionalProperties(true)
121
+ * // 2 defined properties + up to 3 additional properties
61
122
  * }
62
123
  * ```
63
124
  *
64
- * @param {number} maxProperties The maximum properties allowed on the given object
125
+ * ### Important Notes
126
+ *
127
+ * - The value must be a **non-negative integer** (0 or greater)
128
+ * - Throws an error if a negative value is provided
129
+ * - Empty objects (`{}`) always pass maxProperties validation
130
+ * - Counts all properties, including inherited and additional ones
131
+ * - Can be combined with custom error messages using ajv-errors
132
+ *
133
+ * @param maxProperties - Maximum number of properties allowed (must be non-negative)
134
+ *
65
135
  * @decorator
66
136
  * @validation
67
- * @swagger
68
- * @schema
69
- * @input
70
- * @collections
71
- * @ajv-errors
137
+ * @public
72
138
  */
73
139
  export const MaxProperties = withErrorMsg("maxProperties", (maxProperties) => {
74
140
  if (maxProperties < 0) {
@@ -1,39 +1,31 @@
1
1
  import { withErrorMsg } from "../../utils/withErrorMsg.js";
2
2
  import { JsonEntityFn } from "../common/jsonEntityFn.js";
3
3
  /**
4
- * An array instance is valid against `minItems` if its size is greater than, or equal to, the value of this keyword.
4
+ * Sets the minimum number of items required in an array.
5
5
  *
6
- * ::: warning
7
- * The value `minItems` MUST be a non-negative integer.
8
- * :::
6
+ * The `@MinItems()` decorator validates that an array has at least the specified number
7
+ * of elements. This is useful for ensuring required data is provided, enforcing business
8
+ * rules, or guaranteeing minimum quantities.
9
9
  *
10
- * ::: tip
11
- * Omitting this keyword has the same behavior as a value of 0.
12
- * :::
13
- *
14
- * ::: warning
15
- * For v6 user, use @@MinItems@@ from @tsed/schema instead of @tsed/platform-http.
16
- * :::
17
- *
18
- * ## Example
10
+ * ### Basic Usage
19
11
  *
20
12
  * ```typescript
21
- * class Model {
22
- * @CollectionOf(String)
23
- * @MinItems(10)
24
- * property: string[];
13
+ * class OrderModel {
14
+ * @CollectionOf(String)
15
+ * @MinItems(1)
16
+ * items: string[];
17
+ * // Order must have at least 1 item
25
18
  * }
26
19
  * ```
27
20
  *
28
- * Will produce:
29
- *
21
+ * Generated schema:
30
22
  * ```json
31
23
  * {
32
24
  * "type": "object",
33
25
  * "properties": {
34
- * "property": {
26
+ * "items": {
35
27
  * "type": "array",
36
- * "minItems": 10,
28
+ * "minItems": 1,
37
29
  * "items": {
38
30
  * "type": "string"
39
31
  * }
@@ -42,14 +34,117 @@ import { JsonEntityFn } from "../common/jsonEntityFn.js";
42
34
  * }
43
35
  * ```
44
36
  *
45
- * @param {number} minItems
37
+ * ### With MaxItems - Range Validation
38
+ *
39
+ * ```typescript
40
+ * class VotingModel {
41
+ * @CollectionOf(String)
42
+ * @MinItems(3)
43
+ * @MaxItems(10)
44
+ * candidates: string[];
45
+ * // Must have between 3 and 10 candidates
46
+ * }
47
+ * ```
48
+ *
49
+ * ### Required Selections
50
+ *
51
+ * ```typescript
52
+ * class SurveyResponse {
53
+ * @CollectionOf(String)
54
+ * @MinItems(1)
55
+ * selectedOptions: string[];
56
+ * // User must select at least one option
57
+ * }
58
+ * ```
59
+ *
60
+ * ### Business Rules
61
+ *
62
+ * ```typescript
63
+ * class TeamCreation {
64
+ * @CollectionOf(String)
65
+ * @MinItems(2)
66
+ * memberIds: string[];
67
+ * // Team requires minimum 2 members
68
+ * }
69
+ * ```
70
+ *
71
+ * ### Validation Examples
72
+ *
73
+ * ```typescript
74
+ * @MinItems(2)
75
+ * items: string[];
76
+ *
77
+ * // Valid:
78
+ * ["a", "b"] // 2 items (≥ 2)
79
+ * ["a", "b", "c"] // 3 items (≥ 2)
80
+ *
81
+ * // Invalid:
82
+ * [] // 0 items (< 2)
83
+ * ["a"] // 1 item (< 2)
84
+ * ```
85
+ *
86
+ * ### Use Cases
87
+ *
88
+ * - **Required Data**: Ensure minimum data is provided
89
+ * - **Business Logic**: Enforce minimum quantities (team size, votes)
90
+ * - **Data Quality**: Prevent submission with insufficient information
91
+ * - **User Input**: Require multiple selections or answers
92
+ * - **Validation**: Ensure arrays are not empty when data is expected
93
+ *
94
+ * ### Non-Empty Arrays
95
+ *
96
+ * ```typescript
97
+ * class CommentModel {
98
+ * @CollectionOf(String)
99
+ * @MinItems(1)
100
+ * tags: string[];
101
+ * // Prevent empty tag arrays
102
+ * }
103
+ * ```
104
+ *
105
+ * ### Combining with Uniqueness
106
+ *
107
+ * ```typescript
108
+ * class CategoryModel {
109
+ * @CollectionOf(String)
110
+ * @MinItems(2)
111
+ * @UniqueItems()
112
+ * subcategories: string[];
113
+ * // Must have at least 2 unique subcategories
114
+ * }
115
+ * ```
116
+ *
117
+ * ### Important Notes
118
+ *
119
+ * - The value must be a **non-negative integer** (0 or greater)
120
+ * - Throws an error if a negative value is provided
121
+ * - Omitting `@MinItems()` is equivalent to `@MinItems(0)` (no minimum)
122
+ * - Can be combined with custom error messages using ajv-errors
123
+ * - Arrays with exactly minItems elements are valid (inclusive)
124
+ *
125
+ * ### Default Behavior
126
+ *
127
+ * Without `@MinItems()`, arrays can be empty:
128
+ * ```typescript
129
+ * @CollectionOf(String)
130
+ * tags: string[];
131
+ * // Valid: [], ["tag1"], ["tag1", "tag2"], etc.
132
+ * ```
133
+ *
134
+ * With `@MinItems(1)`, empty arrays are rejected:
135
+ * ```typescript
136
+ * @CollectionOf(String)
137
+ * @MinItems(1)
138
+ * tags: string[];
139
+ * // Invalid: []
140
+ * // Valid: ["tag1"], ["tag1", "tag2"], etc.
141
+ * ```
142
+ *
143
+ * @param minItems - Minimum number of items required (must be non-negative)
144
+ *
46
145
  * @decorator
47
146
  * @validation
48
- * @swagger
49
- * @schema
50
- * @input
51
- * @collections
52
- * @ajv-errors
147
+ * @public
53
148
  */
54
149
  export const MinItems = withErrorMsg("minItems", (minItems) => {
55
150
  if (minItems < 0) {
@@ -1,73 +1,174 @@
1
1
  import { withErrorMsg } from "../../utils/withErrorMsg.js";
2
2
  import { JsonEntityFn } from "../common/jsonEntityFn.js";
3
3
  /**
4
- * An object instance is valid against `minProperties` if its number of properties is less than, or equal to, the value of this keyword.
4
+ * Sets the minimum number of properties required on an object.
5
5
  *
6
- * ::: warning
7
- * The value of this keyword MUST be a non-negative integer.
8
- * :::
6
+ * The `@MinProperties()` decorator validates that an object has at least the specified
7
+ * number of properties. This is useful for ensuring objects aren't empty, enforcing
8
+ * minimum data requirements, or validating that dynamic objects have sufficient content.
9
9
  *
10
- * ::: warning
11
- * For v6 user, use @@MinProperties@@ from @tsed/schema instead of @tsed/platform-http.
12
- * :::
10
+ * ### On Property
13
11
  *
14
- * ## Example
15
- * ### On prop
16
12
  * ```typescript
17
- * class Model {
18
- * @MinProperties(10)
19
- * property: any;
13
+ * class DataModel {
14
+ * @MinProperties(1)
15
+ * attributes: Record<string, any>;
16
+ * // Object must have at least 1 property
20
17
  * }
21
18
  * ```
22
19
  *
23
- * Will produce:
24
- *
20
+ * Generated schema:
25
21
  * ```json
26
22
  * {
27
23
  * "type": "object",
28
24
  * "properties": {
29
- * "property": {
30
- * "type": "any",
31
- * "minProperties": 10
25
+ * "attributes": {
26
+ * "type": "object",
27
+ * "minProperties": 1
32
28
  * }
33
29
  * }
34
30
  * }
35
31
  * ```
36
32
  *
37
- * ### On class
33
+ * ### On Class
38
34
  *
39
35
  * ```typescript
40
- * @MinProperties(10)
41
- * class Model {
36
+ * @MinProperties(2)
37
+ * class RequiredDataModel {
38
+ * // Class instances must have at least 2 properties
42
39
  * }
43
40
  * ```
44
41
  *
45
- * Will produce:
46
- *
42
+ * Generated schema:
47
43
  * ```json
48
44
  * {
49
45
  * "type": "object",
50
- * "minProperties": 10
46
+ * "minProperties": 2
51
47
  * }
52
48
  * ```
53
49
  *
54
50
  * ### On Parameter
55
51
  *
56
52
  * ```typescript
53
+ * @Controller("/api")
54
+ * class ApiController {
55
+ * @Post("/filters")
56
+ * search(
57
+ * @BodyParams() @MinProperties(1) filters: any
58
+ * ) {
59
+ * // Filters object must have at least 1 property
60
+ * }
61
+ * }
62
+ * ```
63
+ *
64
+ * ### With MaxProperties - Range Validation
65
+ *
66
+ * ```typescript
67
+ * class MetadataModel {
68
+ * @MinProperties(2)
69
+ * @MaxProperties(10)
70
+ * metadata: Record<string, string>;
71
+ * // Must have between 2 and 10 properties
72
+ * }
73
+ * ```
74
+ *
75
+ * ### Non-Empty Objects
76
+ *
77
+ * ```typescript
78
+ * class SearchCriteria {
79
+ * @MinProperties(1)
80
+ * criteria: Record<string, any>;
81
+ * // Prevent empty search criteria objects
82
+ * }
83
+ * ```
84
+ *
85
+ * ### Dynamic Configuration
86
+ *
87
+ * ```typescript
88
+ * class PluginConfig {
89
+ * @MinProperties(1)
90
+ * @AdditionalProperties({ type: "string" })
91
+ * options: Record<string, string>;
92
+ * // At least 1 configuration option required
93
+ * }
94
+ * ```
95
+ *
96
+ * ### Validation Examples
97
+ *
98
+ * ```typescript
99
+ * @MinProperties(2)
100
+ * data: object;
57
101
  *
58
- * class Model {
59
- * method(@Any() @MinProperties(10) obj: any){}
102
+ * // Valid:
103
+ * { a: 1, b: 2 } // 2 properties (≥ 2)
104
+ * { a: 1, b: 2, c: 3 } // 3 properties (≥ 2)
105
+ *
106
+ * // Invalid:
107
+ * {} // 0 properties (< 2)
108
+ * { a: 1 } // 1 property (< 2)
109
+ * ```
110
+ *
111
+ * ### Use Cases
112
+ *
113
+ * - **Required Data**: Ensure objects have minimum content
114
+ * - **Non-Empty Objects**: Prevent empty dynamic objects
115
+ * - **Business Rules**: Enforce minimum configuration requirements
116
+ * - **API Validation**: Require sufficient filter/search criteria
117
+ * - **Data Quality**: Ensure objects contain meaningful data
118
+ *
119
+ * ### Filter Validation
120
+ *
121
+ * ```typescript
122
+ * class QueryModel {
123
+ * @MinProperties(1)
124
+ * filters: Record<string, string>;
125
+ * // Must specify at least one filter
60
126
  * }
61
127
  * ```
62
128
  *
63
- * @param {number} minProperties The minimum properties allowed on the object.
129
+ * ### Combining with AdditionalProperties
130
+ *
131
+ * ```typescript
132
+ * class FlexibleModel {
133
+ * @Property()
134
+ * id: string;
135
+ *
136
+ * @MinProperties(3)
137
+ * @AdditionalProperties({ type: "string" })
138
+ * // 1 defined property + at least 2 additional properties = 3 minimum
139
+ * }
140
+ * ```
141
+ *
142
+ * ### Important Notes
143
+ *
144
+ * - The value must be a **non-negative integer** (0 or greater)
145
+ * - Throws an error if a negative value is provided
146
+ * - Omitting `@MinProperties()` is equivalent to `@MinProperties(0)` (no minimum)
147
+ * - Counts all properties, including defined and additional ones
148
+ * - Objects with exactly minProperties count are valid (inclusive)
149
+ * - Can be combined with custom error messages using ajv-errors
150
+ *
151
+ * ### Default Behavior
152
+ *
153
+ * Without `@MinProperties()`, empty objects are valid:
154
+ * ```typescript
155
+ * data: Record<string, any>;
156
+ * // Valid: {}, { a: 1 }, { a: 1, b: 2 }, etc.
157
+ * ```
158
+ *
159
+ * With `@MinProperties(1)`, empty objects are rejected:
160
+ * ```typescript
161
+ * @MinProperties(1)
162
+ * data: Record<string, any>;
163
+ * // Invalid: {}
164
+ * // Valid: { a: 1 }, { a: 1, b: 2 }, etc.
165
+ * ```
166
+ *
167
+ * @param minProperties - Minimum number of properties required (must be non-negative)
168
+ *
64
169
  * @decorator
65
170
  * @validation
66
- * @swagger
67
- * @schema
68
- * @input
69
- * @collections
70
- * @ajv-errors
171
+ * @public
71
172
  */
72
173
  export const MinProperties = withErrorMsg("minProperties", (minProperties) => {
73
174
  if (minProperties < 0) {