@aws-amplify/data-schema 1.10.2 → 1.12.0

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 (28) hide show
  1. package/dist/cjs/SchemaProcessor.js +40 -5
  2. package/dist/cjs/SchemaProcessor.js.map +1 -1
  3. package/dist/cjs/runtime/internals/ai/createUpdateConversationFunction.js +21 -0
  4. package/dist/cjs/runtime/internals/ai/createUpdateConversationFunction.js.map +1 -0
  5. package/dist/cjs/runtime/internals/ai/getCustomUserAgentDetails.js +1 -0
  6. package/dist/cjs/runtime/internals/ai/getCustomUserAgentDetails.js.map +1 -1
  7. package/dist/cjs/runtime/internals/utils/clientProperties/generateConversationsProperty.js +2 -0
  8. package/dist/cjs/runtime/internals/utils/clientProperties/generateConversationsProperty.js.map +1 -1
  9. package/dist/esm/ModelType.d.ts +3 -3
  10. package/dist/esm/SchemaProcessor.mjs +40 -5
  11. package/dist/esm/SchemaProcessor.mjs.map +1 -1
  12. package/dist/esm/ai/ConversationType.d.ts +16 -1
  13. package/dist/esm/runtime/internals/ai/createUpdateConversationFunction.d.ts +3 -0
  14. package/dist/esm/runtime/internals/ai/createUpdateConversationFunction.mjs +19 -0
  15. package/dist/esm/runtime/internals/ai/createUpdateConversationFunction.mjs.map +1 -0
  16. package/dist/esm/runtime/internals/ai/getCustomUserAgentDetails.d.ts +2 -1
  17. package/dist/esm/runtime/internals/ai/getCustomUserAgentDetails.mjs +1 -0
  18. package/dist/esm/runtime/internals/ai/getCustomUserAgentDetails.mjs.map +1 -1
  19. package/dist/esm/runtime/internals/utils/clientProperties/generateConversationsProperty.mjs +2 -0
  20. package/dist/esm/runtime/internals/utils/clientProperties/generateConversationsProperty.mjs.map +1 -1
  21. package/dist/meta/cjs.tsbuildinfo +1 -1
  22. package/package.json +1 -1
  23. package/src/ModelType.ts +2 -7
  24. package/src/SchemaProcessor.ts +55 -1
  25. package/src/ai/ConversationType.ts +25 -2
  26. package/src/runtime/internals/ai/createUpdateConversationFunction.ts +58 -0
  27. package/src/runtime/internals/ai/getCustomUserAgentDetails.ts +1 -0
  28. package/src/runtime/internals/utils/clientProperties/generateConversationsProperty.ts +9 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws-amplify/data-schema",
3
- "version": "1.10.2",
3
+ "version": "1.12.0",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
package/src/ModelType.ts CHANGED
@@ -97,17 +97,12 @@ export type ModelTypeParamShape = {
97
97
  */
98
98
  export type ExtractSecondaryIndexIRFields<
99
99
  T extends ModelTypeParamShape,
100
- RequiredOnly extends boolean = false,
101
100
  > = {
102
101
  [FieldProp in keyof T['fields'] as T['fields'][FieldProp] extends BaseModelField<
103
102
  infer R
104
103
  >
105
104
  ? NonNullable<R> extends string | number
106
- ? RequiredOnly extends false
107
- ? FieldProp
108
- : null extends R
109
- ? never
110
- : FieldProp
105
+ ? FieldProp
111
106
  : never
112
107
  : T['fields'][FieldProp] extends
113
108
  | EnumType
@@ -230,7 +225,7 @@ export type ModelType<
230
225
  {
231
226
  [brandSymbol]: typeof brandName;
232
227
  identifier<
233
- PrimaryIndexFields = ExtractSecondaryIndexIRFields<T, true>,
228
+ PrimaryIndexFields = ExtractSecondaryIndexIRFields<T>,
234
229
  PrimaryIndexPool extends string = keyof PrimaryIndexFields & string,
235
230
  const ID extends ReadonlyArray<PrimaryIndexPool> = readonly [],
236
231
  const PrimaryIndexIR extends PrimaryIndexIrShape = PrimaryIndexFieldsToIR<
@@ -27,6 +27,7 @@ import {
27
27
  FunctionSchemaAccess,
28
28
  LambdaFunctionDefinition,
29
29
  CustomSqlDataSourceStrategy,
30
+ DatasourceEngine,
30
31
  } from '@aws-amplify/data-schema-types';
31
32
  import type { InternalRef, RefType } from './RefType';
32
33
  import type { EnumType } from './EnumType';
@@ -155,6 +156,12 @@ function isRefField(
155
156
  return isRefFieldDef((field as any)?.data);
156
157
  }
157
158
 
159
+ function canGenerateFieldType(
160
+ fieldType: ModelFieldType
161
+ ): boolean {
162
+ return fieldType === 'Int';
163
+ }
164
+
158
165
  function scalarFieldToGql(
159
166
  fieldDef: ScalarFieldDef,
160
167
  identifier?: readonly string[],
@@ -169,6 +176,7 @@ function scalarFieldToGql(
169
176
  } = fieldDef;
170
177
  let field: string = fieldType;
171
178
 
179
+
172
180
  if (identifier !== undefined) {
173
181
  field += '!';
174
182
  if (identifier.length > 1) {
@@ -184,6 +192,10 @@ function scalarFieldToGql(
184
192
  field += ` ${index}`;
185
193
  }
186
194
 
195
+ if (_default === __generated) {
196
+ field += ` @default`;
197
+ }
198
+
187
199
  return field;
188
200
  }
189
201
 
@@ -918,6 +930,37 @@ function processFieldLevelAuthRules(
918
930
  return fieldLevelAuthRules;
919
931
  }
920
932
 
933
+ function validateDBGeneration(fields: Record<string, any>, databaseEngine: DatasourceEngine) {
934
+ for (const [fieldName, fieldDef] of Object.entries(fields)) {
935
+ const _default = fieldDef.data?.default;
936
+ const fieldType = fieldDef.data?.fieldType;
937
+ const isGenerated = _default === __generated;
938
+
939
+ if (isGenerated && databaseEngine !== 'postgresql') {
940
+ throw new Error(`Invalid field definition for ${fieldName}. DB-generated fields are only supported with PostgreSQL data sources.`);
941
+ }
942
+
943
+ if (isGenerated && !canGenerateFieldType(fieldType)) {
944
+ throw new Error(`Incompatible field type. Field type ${fieldType} in field ${fieldName} cannot be configured as a DB-generated field.`);
945
+ }
946
+ }
947
+ }
948
+
949
+ function validateNullableIdentifiers(fields: Record<string, any>, identifier?: readonly string[]){
950
+ for (const [fieldName, fieldDef] of Object.entries(fields)) {
951
+ const fieldType = fieldDef.data?.fieldType;
952
+ const required = fieldDef.data?.required;
953
+ const _default = fieldDef.data?.default;
954
+ const isGenerated = _default === __generated;
955
+
956
+ if (identifier !== undefined && identifier.includes(fieldName)) {
957
+ if (!required && fieldType !== 'ID' && !isGenerated) {
958
+ throw new Error(`Invalid identifier definition. Field ${fieldName} cannot be used in the identifier. Identifiers must reference required or DB-generated fields)`);
959
+ }
960
+ }
961
+ }
962
+ }
963
+
921
964
  function processFields(
922
965
  typeName: string,
923
966
  fields: Record<string, any>,
@@ -926,6 +969,7 @@ function processFields(
926
969
  identifier?: readonly string[],
927
970
  partitionKey?: string,
928
971
  secondaryIndexes: TransformedSecondaryIndexes = {},
972
+ databaseEngine: DatasourceEngine = 'dynamodb',
929
973
  ) {
930
974
  const gqlFields: string[] = [];
931
975
  // stores nested, field-level type definitions (custom types and enums)
@@ -933,6 +977,8 @@ function processFields(
933
977
  const implicitTypes: [string, any][] = [];
934
978
 
935
979
  validateImpliedFields(fields, impliedFields);
980
+ validateDBGeneration(fields, databaseEngine);
981
+ validateNullableIdentifiers(fields, identifier)
936
982
 
937
983
  for (const [fieldName, fieldDef] of Object.entries(fields)) {
938
984
  const fieldAuth = fieldLevelAuthRules[fieldName]
@@ -1289,8 +1335,9 @@ const schemaPreprocessor = (
1289
1335
  const lambdaFunctions: LambdaFunctionDefinition = {};
1290
1336
  const customSqlDataSourceStrategies: CustomSqlDataSourceStrategy[] = [];
1291
1337
 
1338
+ const databaseEngine = schema.data.configuration.database.engine
1292
1339
  const databaseType =
1293
- schema.data.configuration.database.engine === 'dynamodb'
1340
+ databaseEngine === 'dynamodb'
1294
1341
  ? 'dynamodb'
1295
1342
  : 'sql';
1296
1343
 
@@ -1373,6 +1420,10 @@ const schemaPreprocessor = (
1373
1420
  fields,
1374
1421
  authFields,
1375
1422
  fieldLevelAuthRules,
1423
+ undefined,
1424
+ undefined,
1425
+ undefined,
1426
+ databaseEngine
1376
1427
  );
1377
1428
 
1378
1429
  topLevelTypes.push(...implicitTypes);
@@ -1484,6 +1535,8 @@ const schemaPreprocessor = (
1484
1535
  fieldLevelAuthRules,
1485
1536
  identifier,
1486
1537
  partitionKey,
1538
+ undefined,
1539
+ databaseEngine,
1487
1540
  );
1488
1541
 
1489
1542
  topLevelTypes.push(...implicitTypes);
@@ -1548,6 +1601,7 @@ const schemaPreprocessor = (
1548
1601
  identifier,
1549
1602
  partitionKey,
1550
1603
  transformedSecondaryIndexes,
1604
+ databaseEngine,
1551
1605
  );
1552
1606
  topLevelTypes.push(...implicitTypes);
1553
1607
 
@@ -33,6 +33,17 @@ interface ConversationRouteDeleteInput {
33
33
  id: string;
34
34
  }
35
35
 
36
+ interface ConversationRouteCreateInput {
37
+ metadata?: Record<string, any>;
38
+ name?: string;
39
+ }
40
+
41
+ interface ConversationRouteUpdateInput {
42
+ id: string;
43
+ metadata?: Record<string, any>;
44
+ name?: string;
45
+ }
46
+
36
47
  interface ConversationRouteListInput {
37
48
  limit?: number;
38
49
  nextToken?: string | null;
@@ -44,7 +55,17 @@ export interface ConversationRoute {
44
55
  *
45
56
  * Creates a {@link Conversation} from the current conversation route.
46
57
  */
47
- create: () => SingularReturnValue<Conversation>;
58
+ create: (
59
+ input?: ConversationRouteCreateInput,
60
+ ) => SingularReturnValue<Conversation>;
61
+ /**
62
+ * @experimental
63
+ *
64
+ * Creates a {@link Conversation} from the current conversation route.
65
+ */
66
+ update: (
67
+ input: ConversationRouteUpdateInput,
68
+ ) => SingularReturnValue<Conversation>;
48
69
  /**
49
70
  * @experimental
50
71
  *
@@ -74,7 +95,9 @@ interface ConversationSendMessageInputObject {
74
95
  toolConfiguration?: ToolConfiguration;
75
96
  }
76
97
 
77
- export type ConversationSendMessageInput = ConversationSendMessageInputObject | string;
98
+ export type ConversationSendMessageInput =
99
+ | ConversationSendMessageInputObject
100
+ | string;
78
101
 
79
102
  interface ConversationListMessagesInput {
80
103
  limit?: number;
@@ -0,0 +1,58 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { ConversationRoute } from '../../../ai/ConversationType';
5
+ import type { SingularReturnValue } from '../../../runtime/client';
6
+ import {
7
+ BaseClient,
8
+ ClientInternalsGetter,
9
+ ModelIntrospectionSchema,
10
+ SchemaModel,
11
+ } from '../../bridge-types';
12
+ import { getFactory } from '../operations/get';
13
+ import { convertItemToConversation } from './convertItemToConversation';
14
+ import {
15
+ AiAction,
16
+ getCustomUserAgentDetails,
17
+ } from './getCustomUserAgentDetails';
18
+
19
+ export const createUpdateConversationFunction =
20
+ (
21
+ client: BaseClient,
22
+ modelIntrospection: ModelIntrospectionSchema,
23
+ conversationRouteName: string,
24
+ conversationModel: SchemaModel,
25
+ conversationMessageModel: SchemaModel,
26
+ getInternals: ClientInternalsGetter,
27
+ ): ConversationRoute['update'] =>
28
+ async ({ id, metadata, name }) => {
29
+ const updateOperation = getFactory(
30
+ client,
31
+ modelIntrospection,
32
+ conversationModel,
33
+ 'UPDATE',
34
+ getInternals,
35
+ false,
36
+ getCustomUserAgentDetails(AiAction.UpdateConversation),
37
+ ) as (
38
+ args?: Record<string, any>,
39
+ ) => SingularReturnValue<Record<string, any>>;
40
+ const { data, errors } = await updateOperation({ id, metadata, name });
41
+ return {
42
+ data: data
43
+ ? convertItemToConversation(
44
+ client,
45
+ modelIntrospection,
46
+ data?.id,
47
+ data?.createdAt,
48
+ data?.updatedAt,
49
+ conversationRouteName,
50
+ conversationMessageModel,
51
+ getInternals,
52
+ data?.metadata,
53
+ data?.name,
54
+ )
55
+ : data,
56
+ errors,
57
+ };
58
+ };
@@ -26,6 +26,7 @@ export enum AiAction {
26
26
  ListMessages = '6',
27
27
  OnMessage = '7',
28
28
  Generation = '8',
29
+ UpdateConversation = '9',
29
30
  }
30
31
 
31
32
  export const getCustomUserAgentDetails = (
@@ -12,6 +12,7 @@ import { createCreateConversationFunction } from '../../ai/createCreateConversat
12
12
  import { createGetConversationFunction } from '../../ai/createGetConversationFunction';
13
13
  import { createListConversationsFunction } from '../../ai/createListConversationsFunction';
14
14
  import { createDeleteConversationFunction } from '../../ai/createDeleteConversationFunction';
15
+ import { createUpdateConversationFunction } from '../../ai/createUpdateConversationFunction';
15
16
 
16
17
  export function generateConversationsProperty(
17
18
  client: BaseClient,
@@ -61,6 +62,14 @@ export function generateConversationsProperty(
61
62
  };
62
63
 
63
64
  conversations[name] = {
65
+ update: createUpdateConversationFunction(
66
+ client,
67
+ conversationModelIntrospection,
68
+ name,
69
+ conversationModel,
70
+ conversationMessageModel,
71
+ getInternals,
72
+ ),
64
73
  create: createCreateConversationFunction(
65
74
  client,
66
75
  conversationModelIntrospection,