@aws-amplify/data-schema 1.19.0 → 1.20.1

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 (198) hide show
  1. package/dist/cjs/Authorization.js.map +1 -1
  2. package/dist/cjs/ClientSchema/utilities/index.js.map +1 -1
  3. package/dist/cjs/CombineSchema.js +2 -2
  4. package/dist/cjs/CombineSchema.js.map +1 -1
  5. package/dist/cjs/CustomOperation.js +5 -5
  6. package/dist/cjs/CustomOperation.js.map +1 -1
  7. package/dist/cjs/CustomType.js +1 -2
  8. package/dist/cjs/CustomType.js.map +1 -1
  9. package/dist/cjs/EnumType.js +1 -2
  10. package/dist/cjs/EnumType.js.map +1 -1
  11. package/dist/cjs/Handler.js +2 -2
  12. package/dist/cjs/Handler.js.map +1 -1
  13. package/dist/cjs/ModelField.js +24 -17
  14. package/dist/cjs/ModelField.js.map +1 -1
  15. package/dist/cjs/ModelIndex.js +1 -2
  16. package/dist/cjs/ModelIndex.js.map +1 -1
  17. package/dist/cjs/ModelRelationshipField.js +4 -4
  18. package/dist/cjs/ModelRelationshipField.js.map +1 -1
  19. package/dist/cjs/ModelSchema.js +3 -3
  20. package/dist/cjs/ModelSchema.js.map +1 -1
  21. package/dist/cjs/ModelType.js +2 -2
  22. package/dist/cjs/ModelType.js.map +1 -1
  23. package/dist/cjs/RefType.js +1 -2
  24. package/dist/cjs/RefType.js.map +1 -1
  25. package/dist/cjs/SchemaProcessor.js +36 -5
  26. package/dist/cjs/SchemaProcessor.js.map +1 -1
  27. package/dist/cjs/Validate.js +145 -0
  28. package/dist/cjs/Validate.js.map +1 -0
  29. package/dist/cjs/a.js.map +1 -1
  30. package/dist/cjs/ai/ConversationSchemaGraphQLTypes.js.map +1 -1
  31. package/dist/cjs/ai/ConversationSchemaProcessor.js.map +1 -1
  32. package/dist/cjs/ai/ConversationType.js +3 -3
  33. package/dist/cjs/ai/ConversationType.js.map +1 -1
  34. package/dist/cjs/ai/ModelType.js +1 -2
  35. package/dist/cjs/ai/ModelType.js.map +1 -1
  36. package/dist/cjs/index.js.map +1 -1
  37. package/dist/cjs/internals/index.js.map +1 -1
  38. package/dist/cjs/runtime/addSchemaToClient.js +1 -2
  39. package/dist/cjs/runtime/addSchemaToClient.js.map +1 -1
  40. package/dist/cjs/runtime/addSchemaToClientWithInstance.js +1 -2
  41. package/dist/cjs/runtime/addSchemaToClientWithInstance.js.map +1 -1
  42. package/dist/cjs/runtime/bridge-types.js.map +1 -1
  43. package/dist/cjs/runtime/client/index.js.map +1 -1
  44. package/dist/cjs/runtime/client/index.v3.js.map +1 -1
  45. package/dist/cjs/runtime/index.js.map +1 -1
  46. package/dist/cjs/runtime/index.v3.js.map +1 -1
  47. package/dist/cjs/runtime/internals/APIClient.js +10 -10
  48. package/dist/cjs/runtime/internals/APIClient.js.map +1 -1
  49. package/dist/cjs/runtime/internals/ai/conversationMessageDeserializers.js.map +1 -1
  50. package/dist/cjs/runtime/internals/ai/conversationMessageSerializers.js.map +1 -1
  51. package/dist/cjs/runtime/internals/ai/conversationStreamEventDeserializers.js.map +1 -1
  52. package/dist/cjs/runtime/internals/ai/convertItemToConversation.js.map +1 -1
  53. package/dist/cjs/runtime/internals/ai/convertItemToConversationMessage.js.map +1 -1
  54. package/dist/cjs/runtime/internals/ai/createCreateConversationFunction.js.map +1 -1
  55. package/dist/cjs/runtime/internals/ai/createDeleteConversationFunction.js.map +1 -1
  56. package/dist/cjs/runtime/internals/ai/createGetConversationFunction.js.map +1 -1
  57. package/dist/cjs/runtime/internals/ai/createListConversationsFunction.js.map +1 -1
  58. package/dist/cjs/runtime/internals/ai/createListMessagesFunction.js.map +1 -1
  59. package/dist/cjs/runtime/internals/ai/createOnStreamEventFunction.js.map +1 -1
  60. package/dist/cjs/runtime/internals/ai/createSendMessageFunction.js.map +1 -1
  61. package/dist/cjs/runtime/internals/ai/createUpdateConversationFunction.js.map +1 -1
  62. package/dist/cjs/runtime/internals/ai/getCustomUserAgentDetails.js +2 -2
  63. package/dist/cjs/runtime/internals/ai/getCustomUserAgentDetails.js.map +1 -1
  64. package/dist/cjs/runtime/internals/cancellation.js +2 -3
  65. package/dist/cjs/runtime/internals/cancellation.js.map +1 -1
  66. package/dist/cjs/runtime/internals/clientUtils.js.map +1 -1
  67. package/dist/cjs/runtime/internals/generateCustomOperationsProperty.js +4 -5
  68. package/dist/cjs/runtime/internals/generateCustomOperationsProperty.js.map +1 -1
  69. package/dist/cjs/runtime/internals/index.js.map +1 -1
  70. package/dist/cjs/runtime/internals/operations/custom.js +1 -2
  71. package/dist/cjs/runtime/internals/operations/custom.js.map +1 -1
  72. package/dist/cjs/runtime/internals/operations/get.js +1 -2
  73. package/dist/cjs/runtime/internals/operations/get.js.map +1 -1
  74. package/dist/cjs/runtime/internals/operations/indexQuery.js +1 -2
  75. package/dist/cjs/runtime/internals/operations/indexQuery.js.map +1 -1
  76. package/dist/cjs/runtime/internals/operations/list.js +1 -2
  77. package/dist/cjs/runtime/internals/operations/list.js.map +1 -1
  78. package/dist/cjs/runtime/internals/operations/observeQuery.js +1 -2
  79. package/dist/cjs/runtime/internals/operations/observeQuery.js.map +1 -1
  80. package/dist/cjs/runtime/internals/operations/subscription.js +1 -2
  81. package/dist/cjs/runtime/internals/operations/subscription.js.map +1 -1
  82. package/dist/cjs/runtime/internals/operations/utils.js +2 -3
  83. package/dist/cjs/runtime/internals/operations/utils.js.map +1 -1
  84. package/dist/cjs/runtime/internals/server/generateModelsProperty.js +1 -2
  85. package/dist/cjs/runtime/internals/server/generateModelsProperty.js.map +1 -1
  86. package/dist/cjs/runtime/internals/server/index.js.map +1 -1
  87. package/dist/cjs/runtime/internals/utils/clientProperties/generateConversationsProperty.js +1 -2
  88. package/dist/cjs/runtime/internals/utils/clientProperties/generateConversationsProperty.js.map +1 -1
  89. package/dist/cjs/runtime/internals/utils/clientProperties/generateEnumsProperty.js.map +1 -1
  90. package/dist/cjs/runtime/internals/utils/clientProperties/generateGenerationsProperty.js +1 -2
  91. package/dist/cjs/runtime/internals/utils/clientProperties/generateGenerationsProperty.js.map +1 -1
  92. package/dist/cjs/runtime/internals/utils/clientProperties/generateModelsProperty.js +1 -2
  93. package/dist/cjs/runtime/internals/utils/clientProperties/generateModelsProperty.js.map +1 -1
  94. package/dist/cjs/runtime/internals/utils/runtimeTypeGuards/isApiGraphQLProviderConfig.js +1 -2
  95. package/dist/cjs/runtime/internals/utils/runtimeTypeGuards/isApiGraphQLProviderConfig.js.map +1 -1
  96. package/dist/cjs/runtime/internals/utils/runtimeTypeGuards/isConfigureEventWithResourceConfig.js +1 -2
  97. package/dist/cjs/runtime/internals/utils/runtimeTypeGuards/isConfigureEventWithResourceConfig.js.map +1 -1
  98. package/dist/cjs/runtime/internals/utils/runtimeTypeGuards/isGraphQLResponseWithErrors.js +1 -2
  99. package/dist/cjs/runtime/internals/utils/runtimeTypeGuards/isGraphQLResponseWithErrors.js.map +1 -1
  100. package/dist/cjs/runtime/utils/findIndexByFields.js +1 -2
  101. package/dist/cjs/runtime/utils/findIndexByFields.js.map +1 -1
  102. package/dist/cjs/runtime/utils/index.js.map +1 -1
  103. package/dist/cjs/runtime/utils/resolveOwnerFields.js +1 -2
  104. package/dist/cjs/runtime/utils/resolveOwnerFields.js.map +1 -1
  105. package/dist/cjs/runtime/utils/resolvePKFields.js +1 -2
  106. package/dist/cjs/runtime/utils/resolvePKFields.js.map +1 -1
  107. package/dist/cjs/runtime/utils/selfAwareAsync.js +1 -2
  108. package/dist/cjs/runtime/utils/selfAwareAsync.js.map +1 -1
  109. package/dist/cjs/runtime/utils/stringTransformation.js +1 -2
  110. package/dist/cjs/runtime/utils/stringTransformation.js.map +1 -1
  111. package/dist/cjs/util/Brand.js +3 -3
  112. package/dist/cjs/util/Brand.js.map +1 -1
  113. package/dist/cjs/util/index.js.map +1 -1
  114. package/dist/esm/Authorization.d.ts +8 -8
  115. package/dist/esm/Authorization.mjs.map +1 -1
  116. package/dist/esm/CombineSchema.mjs.map +1 -1
  117. package/dist/esm/CustomOperation.mjs.map +1 -1
  118. package/dist/esm/CustomType.mjs.map +1 -1
  119. package/dist/esm/EnumType.mjs.map +1 -1
  120. package/dist/esm/Handler.mjs.map +1 -1
  121. package/dist/esm/ModelField.d.ts +39 -24
  122. package/dist/esm/ModelField.mjs +9 -2
  123. package/dist/esm/ModelField.mjs.map +1 -1
  124. package/dist/esm/ModelIndex.mjs.map +1 -1
  125. package/dist/esm/ModelRelationshipField.mjs.map +1 -1
  126. package/dist/esm/ModelSchema.mjs.map +1 -1
  127. package/dist/esm/ModelType.d.ts +1 -1
  128. package/dist/esm/ModelType.mjs.map +1 -1
  129. package/dist/esm/RefType.mjs.map +1 -1
  130. package/dist/esm/SchemaProcessor.mjs +36 -4
  131. package/dist/esm/SchemaProcessor.mjs.map +1 -1
  132. package/dist/esm/Validate.d.ts +218 -0
  133. package/dist/esm/Validate.mjs +142 -0
  134. package/dist/esm/Validate.mjs.map +1 -0
  135. package/dist/esm/ai/ConversationSchemaGraphQLTypes.mjs.map +1 -1
  136. package/dist/esm/ai/ConversationSchemaProcessor.mjs.map +1 -1
  137. package/dist/esm/ai/ConversationType.mjs.map +1 -1
  138. package/dist/esm/ai/ModelType.mjs.map +1 -1
  139. package/dist/esm/index.d.ts +1 -1
  140. package/dist/esm/runtime/addSchemaToClient.mjs.map +1 -1
  141. package/dist/esm/runtime/addSchemaToClientWithInstance.mjs.map +1 -1
  142. package/dist/esm/runtime/bridge-types.mjs.map +1 -1
  143. package/dist/esm/runtime/internals/APIClient.mjs.map +1 -1
  144. package/dist/esm/runtime/internals/ai/conversationMessageDeserializers.mjs.map +1 -1
  145. package/dist/esm/runtime/internals/ai/conversationMessageSerializers.mjs.map +1 -1
  146. package/dist/esm/runtime/internals/ai/conversationStreamEventDeserializers.mjs.map +1 -1
  147. package/dist/esm/runtime/internals/ai/convertItemToConversation.mjs.map +1 -1
  148. package/dist/esm/runtime/internals/ai/createCreateConversationFunction.d.ts +1 -1
  149. package/dist/esm/runtime/internals/ai/createCreateConversationFunction.mjs.map +1 -1
  150. package/dist/esm/runtime/internals/ai/createDeleteConversationFunction.d.ts +1 -1
  151. package/dist/esm/runtime/internals/ai/createDeleteConversationFunction.mjs.map +1 -1
  152. package/dist/esm/runtime/internals/ai/createGetConversationFunction.d.ts +1 -1
  153. package/dist/esm/runtime/internals/ai/createGetConversationFunction.mjs.map +1 -1
  154. package/dist/esm/runtime/internals/ai/createListConversationsFunction.d.ts +1 -1
  155. package/dist/esm/runtime/internals/ai/createListConversationsFunction.mjs.map +1 -1
  156. package/dist/esm/runtime/internals/ai/createListMessagesFunction.d.ts +1 -1
  157. package/dist/esm/runtime/internals/ai/createListMessagesFunction.mjs.map +1 -1
  158. package/dist/esm/runtime/internals/ai/createOnStreamEventFunction.d.ts +1 -1
  159. package/dist/esm/runtime/internals/ai/createOnStreamEventFunction.mjs.map +1 -1
  160. package/dist/esm/runtime/internals/ai/createSendMessageFunction.d.ts +1 -1
  161. package/dist/esm/runtime/internals/ai/createSendMessageFunction.mjs +1 -1
  162. package/dist/esm/runtime/internals/ai/createSendMessageFunction.mjs.map +1 -1
  163. package/dist/esm/runtime/internals/ai/createUpdateConversationFunction.d.ts +1 -1
  164. package/dist/esm/runtime/internals/ai/createUpdateConversationFunction.mjs.map +1 -1
  165. package/dist/esm/runtime/internals/ai/getCustomUserAgentDetails.mjs.map +1 -1
  166. package/dist/esm/runtime/internals/cancellation.mjs.map +1 -1
  167. package/dist/esm/runtime/internals/clientUtils.mjs.map +1 -1
  168. package/dist/esm/runtime/internals/generateCustomOperationsProperty.d.ts +3 -3
  169. package/dist/esm/runtime/internals/generateCustomOperationsProperty.mjs.map +1 -1
  170. package/dist/esm/runtime/internals/operations/custom.mjs.map +1 -1
  171. package/dist/esm/runtime/internals/operations/get.mjs.map +1 -1
  172. package/dist/esm/runtime/internals/operations/indexQuery.mjs +1 -1
  173. package/dist/esm/runtime/internals/operations/indexQuery.mjs.map +1 -1
  174. package/dist/esm/runtime/internals/operations/list.mjs.map +1 -1
  175. package/dist/esm/runtime/internals/operations/observeQuery.mjs.map +1 -1
  176. package/dist/esm/runtime/internals/operations/subscription.mjs.map +1 -1
  177. package/dist/esm/runtime/internals/operations/utils.mjs.map +1 -1
  178. package/dist/esm/runtime/internals/server/generateModelsProperty.mjs.map +1 -1
  179. package/dist/esm/runtime/internals/utils/clientProperties/generateConversationsProperty.mjs.map +1 -1
  180. package/dist/esm/runtime/internals/utils/clientProperties/generateEnumsProperty.d.ts +1 -1
  181. package/dist/esm/runtime/internals/utils/clientProperties/generateEnumsProperty.mjs.map +1 -1
  182. package/dist/esm/runtime/internals/utils/clientProperties/generateGenerationsProperty.mjs.map +1 -1
  183. package/dist/esm/runtime/internals/utils/clientProperties/generateModelsProperty.mjs.map +1 -1
  184. package/dist/esm/runtime/internals/utils/runtimeTypeGuards/isApiGraphQLProviderConfig.mjs.map +1 -1
  185. package/dist/esm/runtime/internals/utils/runtimeTypeGuards/isConfigureEventWithResourceConfig.mjs.map +1 -1
  186. package/dist/esm/runtime/internals/utils/runtimeTypeGuards/isGraphQLResponseWithErrors.mjs.map +1 -1
  187. package/dist/esm/runtime/utils/findIndexByFields.mjs.map +1 -1
  188. package/dist/esm/runtime/utils/resolveOwnerFields.mjs.map +1 -1
  189. package/dist/esm/runtime/utils/resolvePKFields.mjs.map +1 -1
  190. package/dist/esm/runtime/utils/selfAwareAsync.mjs.map +1 -1
  191. package/dist/esm/runtime/utils/stringTransformation.mjs.map +1 -1
  192. package/dist/esm/util/Brand.mjs.map +1 -1
  193. package/dist/meta/cjs.tsbuildinfo +1 -1
  194. package/package.json +1 -1
  195. package/src/ModelField.ts +70 -29
  196. package/src/SchemaProcessor.ts +46 -2
  197. package/src/Validate.ts +418 -0
  198. package/src/index.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws-amplify/data-schema",
3
- "version": "1.19.0",
3
+ "version": "1.20.1",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
package/src/ModelField.ts CHANGED
@@ -2,6 +2,11 @@ import { brand } from './util';
2
2
  import { AllowModifier, Authorization, allow } from './Authorization';
3
3
  import type { methodKeyOf, satisfy } from './util/usedMethods.js';
4
4
  import type { brandSymbol } from './util/Brand.js';
5
+ import {
6
+ ValidationRule,
7
+ FieldTypeToValidationBuilder,
8
+ createValidationBuilder,
9
+ } from './Validate';
5
10
 
6
11
  /**
7
12
  * Used to "attach" auth types to ModelField without exposing them on the builder.
@@ -52,6 +57,7 @@ type FieldData = {
52
57
  arrayRequired: boolean;
53
58
  default: undefined | symbol | ModelFieldTypeParamOuter;
54
59
  authorization: Authorization<any, any, any>[];
60
+ validation: ValidationRule[];
55
61
  };
56
62
 
57
63
  type ModelFieldTypeParamInner = string | number | boolean | Date | Json | null;
@@ -79,11 +85,12 @@ export type ArrayField<T> = [T] extends [ModelFieldTypeParamInner]
79
85
 
80
86
  export type BaseModelField<
81
87
  T extends ModelFieldTypeParamOuter = ModelFieldTypeParamOuter,
82
- > = ModelField<T, UsableModelFieldKey, any>;
88
+ FT extends ModelFieldType = ModelFieldType
89
+ > = ModelField<T, UsableModelFieldKey, any, FT>
83
90
 
84
91
  export type UsableModelFieldKey = satisfy<
85
92
  methodKeyOf<ModelField>,
86
- 'required' | 'default' | 'authorization' | 'array'
93
+ 'required' | 'default' | 'authorization' | 'array' | 'validate'
87
94
  >;
88
95
 
89
96
  /**
@@ -92,11 +99,14 @@ export type UsableModelFieldKey = satisfy<
92
99
  *
93
100
  * @typeParam T - holds the JS data type of the field
94
101
  * @typeParam UsedMethod - union of strings representing already-invoked method names. Used to improve Intellisense
102
+ * @typeParam Auth - type of the authorization rules attached to the field
103
+ * @typeParam FT - specific ModelFieldType of the field
95
104
  */
96
105
  export type ModelField<
97
106
  T extends ModelFieldTypeParamOuter = ModelFieldTypeParamOuter,
98
107
  UsedMethod extends UsableModelFieldKey = never,
99
108
  Auth = undefined,
109
+ FT extends ModelFieldType = ModelFieldType
100
110
  > = Omit<
101
111
  {
102
112
  // This is a lie. This property is never set at runtime. It's just used to smuggle auth types through.
@@ -109,19 +119,21 @@ export type ModelField<
109
119
  * some property on the type is guaranteed to reference `T`
110
120
  * Context: https://github.com/aws-amplify/amplify-data/pull/406/files#r1869481467
111
121
  */
112
- [internal](): ModelField<T>;
122
+ [internal](): ModelField<T, UsedMethod, Auth, FT>;
113
123
 
114
124
  /**
115
125
  * Marks a field as required.
116
126
  */
117
- required(): ModelField<Required<T>, UsedMethod | 'required'>;
127
+ required(): ModelField<Required<T>, UsedMethod | 'required', Auth, FT>;
118
128
  // Exclude `optional` after calling array, because both the value and the array itself can be optional
119
129
  /**
120
130
  * Converts a field type definition to an array of the field type.
121
131
  */
122
132
  array(): ModelField<
123
133
  ArrayField<T>,
124
- Exclude<UsedMethod, 'required'> | 'array'
134
+ Exclude<UsedMethod, 'required'> | 'array' | 'validate',
135
+ Auth,
136
+ FT
125
137
  >;
126
138
  // TODO: should be T, but .array breaks this constraint. Fix later
127
139
  /**
@@ -130,7 +142,7 @@ export type ModelField<
130
142
  */
131
143
  default(
132
144
  value?: ModelFieldTypeParamOuter,
133
- ): ModelField<T, UsedMethod | 'default'>;
145
+ ): ModelField<T, UsedMethod | 'default', Auth, FT>;
134
146
  /**
135
147
  * Configures field-level authorization rules. Pass in an array of authorizations `(allow => allow.____)` to mix and match
136
148
  * multiple authorization rules for this field.
@@ -139,7 +151,20 @@ export type ModelField<
139
151
  callback: (
140
152
  allow: Omit<AllowModifier, 'resource'>,
141
153
  ) => AuthRuleType | AuthRuleType[],
142
- ): ModelField<T, UsedMethod | 'authorization', AuthRuleType>;
154
+ ): ModelField<T, UsedMethod | 'authorization', AuthRuleType, FT>;
155
+ /**
156
+ * Configures field-level validation rules.
157
+ *
158
+ * @example
159
+ * a.integer().validate(v => v.gt(0, 'Integer must be greater than 0'))
160
+ * a.float().validate(v => v.gt(0.99, 'Float must be greater than 0.99'))
161
+ * a.string().validate(v => v.minLength(5, 'String must be at least 5 characters'))
162
+ *
163
+ * @param callback - A function that receives a validation builder object for the field type
164
+ */
165
+ validate(
166
+ callback: (v: FieldTypeToValidationBuilder<T, FT>) => void
167
+ ): ModelField<T, UsedMethod | 'validate' | 'default' | 'array', Auth, FT>;
143
168
  },
144
169
  UsedMethod
145
170
  >;
@@ -148,7 +173,12 @@ export type ModelField<
148
173
  * Internal representation of Model Field that exposes the `data` property.
149
174
  * Used at buildtime.
150
175
  */
151
- export interface InternalField extends ModelField {
176
+ export type InternalField<
177
+ T extends ModelFieldTypeParamOuter = ModelFieldTypeParamOuter,
178
+ UsedMethod extends UsableModelFieldKey = never,
179
+ Auth = undefined,
180
+ FT extends ModelFieldType = ModelFieldType
181
+ > = ModelField<T, UsedMethod, Auth, FT> & {
152
182
  data: FieldData;
153
183
  }
154
184
 
@@ -164,7 +194,9 @@ export interface InternalField extends ModelField {
164
194
  *
165
195
  * @param fieldType - stores the GraphQL data type of the field
166
196
  */
167
- function _field<T extends ModelFieldTypeParamOuter>(fieldType: ModelFieldType) {
197
+ function _field<T extends ModelFieldTypeParamOuter, FT extends ModelFieldType>(
198
+ fieldType: FT
199
+ ): ModelField<T, never, undefined, FT> {
168
200
  const _meta: FieldMeta = {
169
201
  lastInvokedMethod: null,
170
202
  };
@@ -176,6 +208,7 @@ function _field<T extends ModelFieldTypeParamOuter>(fieldType: ModelFieldType) {
176
208
  arrayRequired: false,
177
209
  default: undefined,
178
210
  authorization: [],
211
+ validation: [],
179
212
  };
180
213
 
181
214
  const builder = {
@@ -190,7 +223,7 @@ function _field<T extends ModelFieldTypeParamOuter>(fieldType: ModelFieldType) {
190
223
 
191
224
  return this;
192
225
  },
193
- array(): ModelField<ArrayField<T>> {
226
+ array(): ModelField<ArrayField<T>, 'array', undefined, FT> {
194
227
  data.array = true;
195
228
  _meta.lastInvokedMethod = 'array';
196
229
 
@@ -210,15 +243,23 @@ function _field<T extends ModelFieldTypeParamOuter>(fieldType: ModelFieldType) {
210
243
 
211
244
  return this;
212
245
  },
246
+ validate(
247
+ callback: (v: FieldTypeToValidationBuilder<T, FT>) => void
248
+ ) {
249
+ const { builder, getRules } = createValidationBuilder<T, FT>();
250
+ callback(builder);
251
+ data.validation = getRules();
252
+
253
+ _meta.lastInvokedMethod = 'validate';
254
+
255
+ return this;
256
+ },
213
257
  ...brand(brandName),
214
258
  [internal]() {
215
259
  return this;
216
260
  },
217
- } as ModelField<T>;
218
-
219
- // this double cast gives us a Subtyping Constraint i.e., hides `data` from the public API,
220
- // but makes it available internally when needed
221
- return { ...builder, data } as InternalField as ModelField<T>;
261
+ } as ModelField<T, never, undefined, FT>;
262
+ return { ...builder, data } as InternalField as ModelField<T, never, undefined, FT>;
222
263
  }
223
264
 
224
265
  /**
@@ -226,7 +267,7 @@ function _field<T extends ModelFieldTypeParamOuter>(fieldType: ModelFieldType) {
226
267
  * If not specified on create operations, a ULID will be auto-generated service-side.
227
268
  * @returns ID field definition
228
269
  */
229
- export function id(): ModelField<Nullable<string>> {
270
+ export function id(): ModelField<Nullable<string>, never, undefined, ModelFieldType.Id> {
230
271
  return _field(ModelFieldType.Id);
231
272
  }
232
273
 
@@ -234,7 +275,7 @@ export function id(): ModelField<Nullable<string>> {
234
275
  * A string scalar type that is represented server-side as a UTF-8 character sequence.
235
276
  * @returns string field definition
236
277
  */
237
- export function string(): ModelField<Nullable<string>> {
278
+ export function string(): ModelField<Nullable<string>, never, undefined, ModelFieldType.String> {
238
279
  return _field(ModelFieldType.String);
239
280
  }
240
281
 
@@ -242,7 +283,7 @@ export function string(): ModelField<Nullable<string>> {
242
283
  * An integer scalar type with a supported value range between -(2^31) and 2^31-1.
243
284
  * @returns integer field definition
244
285
  */
245
- export function integer(): ModelField<Nullable<number>> {
286
+ export function integer(): ModelField<Nullable<number>, never, undefined, ModelFieldType.Integer> {
246
287
  return _field(ModelFieldType.Integer);
247
288
  }
248
289
 
@@ -250,7 +291,7 @@ export function integer(): ModelField<Nullable<number>> {
250
291
  * A float scalar type following represented server-side as an IEEE 754 floating point value.
251
292
  * @returns float field definition
252
293
  */
253
- export function float(): ModelField<Nullable<number>> {
294
+ export function float(): ModelField<Nullable<number>, never, undefined, ModelFieldType.Float> {
254
295
  return _field(ModelFieldType.Float);
255
296
  }
256
297
 
@@ -258,7 +299,7 @@ export function float(): ModelField<Nullable<number>> {
258
299
  * A boolean scalar type that can be either true or false.
259
300
  * @returns boolean field definition
260
301
  */
261
- export function boolean(): ModelField<Nullable<boolean>> {
302
+ export function boolean(): ModelField<Nullable<boolean>, never, undefined, ModelFieldType.Boolean> {
262
303
  return _field(ModelFieldType.Boolean);
263
304
  }
264
305
 
@@ -266,7 +307,7 @@ export function boolean(): ModelField<Nullable<boolean>> {
266
307
  * A date scalar type that is represented server-side as an extended ISO 8601 date string in the format `YYYY-MM-DD`.
267
308
  * @returns date field definition
268
309
  */
269
- export function date(): ModelField<Nullable<string>> {
310
+ export function date(): ModelField<Nullable<string>, never, undefined, ModelFieldType.Date> {
270
311
  return _field(ModelFieldType.Date);
271
312
  }
272
313
 
@@ -274,7 +315,7 @@ export function date(): ModelField<Nullable<string>> {
274
315
  * A time scalar type that is represented server-side as an extended ISO 8601 time string in the format `hh:mm:ss.sss`.
275
316
  * @returns time field definition
276
317
  */
277
- export function time(): ModelField<Nullable<string>> {
318
+ export function time(): ModelField<Nullable<string>, never, undefined, ModelFieldType.Time> {
278
319
  return _field(ModelFieldType.Time);
279
320
  }
280
321
 
@@ -282,7 +323,7 @@ export function time(): ModelField<Nullable<string>> {
282
323
  * A date time scalar type that is represented server-side as an extended ISO 8601 date and time string in the format `YYYY-MM-DDThh:mm:ss.sssZ`.
283
324
  * @returns datetime field definition
284
325
  */
285
- export function datetime(): ModelField<Nullable<string>> {
326
+ export function datetime(): ModelField<Nullable<string>, never, undefined, ModelFieldType.DateTime> {
286
327
  return _field(ModelFieldType.DateTime);
287
328
  }
288
329
 
@@ -290,7 +331,7 @@ export function datetime(): ModelField<Nullable<string>> {
290
331
  * A timestamp scalar type that is represented by an integer value of the number of seconds before or after `1970-01-01-T00:00Z`.
291
332
  * @returns timestamp field definition
292
333
  */
293
- export function timestamp(): ModelField<Nullable<number>> {
334
+ export function timestamp(): ModelField<Nullable<number>, never, undefined, ModelFieldType.Timestamp> {
294
335
  return _field(ModelFieldType.Timestamp);
295
336
  }
296
337
 
@@ -298,7 +339,7 @@ export function timestamp(): ModelField<Nullable<number>> {
298
339
  * An email scalar type that is represented server-side in the format `local-part@domain-part` as defined by RFC 822.
299
340
  * @returns email field definition
300
341
  */
301
- export function email(): ModelField<Nullable<string>> {
342
+ export function email(): ModelField<Nullable<string>, never, undefined, ModelFieldType.Email> {
302
343
  return _field(ModelFieldType.Email);
303
344
  }
304
345
 
@@ -307,7 +348,7 @@ export function email(): ModelField<Nullable<string>> {
307
348
  * rather than as the literal input strings.
308
349
  * @returns JSON field definition
309
350
  */
310
- export function json(): ModelField<Nullable<Json>> {
351
+ export function json(): ModelField<Nullable<Json>, never, undefined, ModelFieldType.JSON> {
311
352
  return _field(ModelFieldType.JSON);
312
353
  }
313
354
 
@@ -317,7 +358,7 @@ export function json(): ModelField<Nullable<Json>> {
317
358
  * to the North American Numbering Plan.
318
359
  * @returns phone number field definition
319
360
  */
320
- export function phone(): ModelField<Nullable<string>> {
361
+ export function phone(): ModelField<Nullable<string>, never, undefined, ModelFieldType.Phone> {
321
362
  return _field(ModelFieldType.Phone);
322
363
  }
323
364
 
@@ -326,7 +367,7 @@ export function phone(): ModelField<Nullable<string>> {
326
367
  * URLs must contain a schema (http, mailto) and can't contain two forward slashes (//) in the path part.
327
368
  * @returns URL field definition
328
369
  */
329
- export function url(): ModelField<Nullable<string>> {
370
+ export function url(): ModelField<Nullable<string>, never, undefined, ModelFieldType.Url> {
330
371
  return _field(ModelFieldType.Url);
331
372
  }
332
373
 
@@ -336,6 +377,6 @@ export function url(): ModelField<Nullable<string>> {
336
377
  * to indicate subnet mask.
337
378
  * @returns IP address field definition
338
379
  */
339
- export function ipAddress(): ModelField<Nullable<string>> {
380
+ export function ipAddress(): ModelField<Nullable<string>, never, undefined, ModelFieldType.IPAddress> {
340
381
  return _field(ModelFieldType.IPAddress);
341
382
  }
@@ -170,6 +170,7 @@ function scalarFieldToGql(
170
170
  array,
171
171
  arrayRequired,
172
172
  default: _default,
173
+ validation = [],
173
174
  } = fieldDef;
174
175
  let field: string = fieldType;
175
176
 
@@ -216,6 +217,17 @@ function scalarFieldToGql(
216
217
  for (const index of secondaryIndexes) {
217
218
  field += ` ${index}`;
218
219
  }
220
+
221
+ // Add validation directives for each validation rule
222
+ for (const validationRule of validation) {
223
+ const valueStr = typeof validationRule.value === 'number' ? validationRule.value.toString() : validationRule.value;
224
+ if (validationRule.errorMessage) {
225
+ field += ` @validate(type: ${validationRule.type}, value: "${valueStr}", errorMessage: ${escapeGraphQlString(validationRule.errorMessage)})`;
226
+ } else {
227
+ field += ` @validate(type: ${validationRule.type}, value: "${valueStr}")`;
228
+ }
229
+ }
230
+
219
231
  return field;
220
232
  }
221
233
 
@@ -1432,8 +1444,24 @@ function generateInputTypes(
1432
1444
  if (isRefField(argDef)) {
1433
1445
  const refType = getRefType(argDef.data.link, operationName);
1434
1446
  if (refType.type === 'CustomType') {
1447
+ const { valueRequired, array, arrayRequired } = argDef.data;
1448
+
1435
1449
  const inputTypeName = `${argDef.data.link}Input`;
1436
- argDefinitions.push(`${argName}: ${inputTypeName}`);
1450
+ let field = inputTypeName;
1451
+
1452
+ if (valueRequired === true) {
1453
+ field += '!';
1454
+ }
1455
+
1456
+ if (array) {
1457
+ field = `[${field}]`;
1458
+
1459
+ if (arrayRequired === true) {
1460
+ field += '!';
1461
+ }
1462
+ }
1463
+
1464
+ argDefinitions.push(`${argName}: ${field}`);
1437
1465
 
1438
1466
  // Process the input type if it hasn't been processed yet
1439
1467
  if (!processedTypes.has(inputTypeName)) {
@@ -1450,7 +1478,23 @@ function generateInputTypes(
1450
1478
  });
1451
1479
  }
1452
1480
  } else if (refType.type === 'Enum') {
1453
- argDefinitions.push(`${argName}: ${argDef.data.link}`);
1481
+ const { valueRequired, array, arrayRequired } = argDef.data;
1482
+
1483
+ let field = argDef.data.link;
1484
+
1485
+ if (valueRequired === true) {
1486
+ field += '!';
1487
+ }
1488
+
1489
+ if (array) {
1490
+ field = `[${field}]`;
1491
+
1492
+ if (arrayRequired === true) {
1493
+ field += '!';
1494
+ }
1495
+ }
1496
+
1497
+ argDefinitions.push(`${argName}: ${field}`);
1454
1498
  } else {
1455
1499
  throw new Error(
1456
1500
  `Unsupported reference type '${refType.type}' for argument '${argName}' in '${operationName}'. ` +