@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.
- package/dist/cjs/SchemaProcessor.js +40 -5
- package/dist/cjs/SchemaProcessor.js.map +1 -1
- package/dist/cjs/runtime/internals/ai/createUpdateConversationFunction.js +21 -0
- package/dist/cjs/runtime/internals/ai/createUpdateConversationFunction.js.map +1 -0
- package/dist/cjs/runtime/internals/ai/getCustomUserAgentDetails.js +1 -0
- package/dist/cjs/runtime/internals/ai/getCustomUserAgentDetails.js.map +1 -1
- package/dist/cjs/runtime/internals/utils/clientProperties/generateConversationsProperty.js +2 -0
- package/dist/cjs/runtime/internals/utils/clientProperties/generateConversationsProperty.js.map +1 -1
- package/dist/esm/ModelType.d.ts +3 -3
- package/dist/esm/SchemaProcessor.mjs +40 -5
- package/dist/esm/SchemaProcessor.mjs.map +1 -1
- package/dist/esm/ai/ConversationType.d.ts +16 -1
- package/dist/esm/runtime/internals/ai/createUpdateConversationFunction.d.ts +3 -0
- package/dist/esm/runtime/internals/ai/createUpdateConversationFunction.mjs +19 -0
- package/dist/esm/runtime/internals/ai/createUpdateConversationFunction.mjs.map +1 -0
- package/dist/esm/runtime/internals/ai/getCustomUserAgentDetails.d.ts +2 -1
- package/dist/esm/runtime/internals/ai/getCustomUserAgentDetails.mjs +1 -0
- package/dist/esm/runtime/internals/ai/getCustomUserAgentDetails.mjs.map +1 -1
- package/dist/esm/runtime/internals/utils/clientProperties/generateConversationsProperty.mjs +2 -0
- package/dist/esm/runtime/internals/utils/clientProperties/generateConversationsProperty.mjs.map +1 -1
- package/dist/meta/cjs.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/ModelType.ts +2 -7
- package/src/SchemaProcessor.ts +55 -1
- package/src/ai/ConversationType.ts +25 -2
- package/src/runtime/internals/ai/createUpdateConversationFunction.ts +58 -0
- package/src/runtime/internals/ai/getCustomUserAgentDetails.ts +1 -0
- package/src/runtime/internals/utils/clientProperties/generateConversationsProperty.ts +9 -0
package/package.json
CHANGED
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
|
-
?
|
|
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
|
|
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<
|
package/src/SchemaProcessor.ts
CHANGED
|
@@ -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
|
-
|
|
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: (
|
|
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 =
|
|
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
|
+
};
|
|
@@ -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,
|