@aws-amplify/data-schema 1.17.5 → 1.19.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 +154 -6
- package/dist/cjs/SchemaProcessor.js.map +1 -1
- package/dist/cjs/runtime/internals/ai/conversationMessageDeserializers.js +12 -0
- package/dist/cjs/runtime/internals/ai/conversationMessageDeserializers.js.map +1 -1
- package/dist/cjs/runtime/internals/ai/conversationMessageSerializers.js +12 -0
- package/dist/cjs/runtime/internals/ai/conversationMessageSerializers.js.map +1 -1
- package/dist/esm/ClientSchema/Core/ClientCustomOperations.d.ts +9 -6
- package/dist/esm/CustomOperation.d.ts +1 -1
- package/dist/esm/SchemaProcessor.mjs +154 -6
- package/dist/esm/SchemaProcessor.mjs.map +1 -1
- package/dist/esm/ai/types/ConversationMessageContent.d.ts +14 -3
- package/dist/esm/ai/types/contentBlocks.d.ts +8 -0
- package/dist/esm/runtime/bridge-types.d.ts +3 -1
- package/dist/esm/runtime/internals/ai/conversationMessageDeserializers.mjs +12 -0
- package/dist/esm/runtime/internals/ai/conversationMessageDeserializers.mjs.map +1 -1
- package/dist/esm/runtime/internals/ai/conversationMessageSerializers.d.ts +8 -0
- package/dist/esm/runtime/internals/ai/conversationMessageSerializers.mjs +12 -0
- package/dist/esm/runtime/internals/ai/conversationMessageSerializers.mjs.map +1 -1
- package/dist/meta/cjs.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/ClientSchema/Core/ClientCustomOperations.ts +14 -15
- package/src/CustomOperation.ts +1 -1
- package/src/SchemaProcessor.ts +212 -12
- package/src/ai/types/ConversationMessageContent.ts +20 -1
- package/src/ai/types/contentBlocks.ts +19 -0
- package/src/runtime/bridge-types.ts +8 -1
- package/src/runtime/internals/ai/conversationMessageDeserializers.ts +13 -0
- package/src/runtime/internals/ai/conversationMessageSerializers.ts +16 -0
|
@@ -257,10 +257,15 @@ function customOperationToGql(typeName, typeDef, authorization, isCustom = false
|
|
|
257
257
|
refererTypeName: typeName,
|
|
258
258
|
});
|
|
259
259
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
implicitTypes.
|
|
260
|
+
const { inputTypes, argDefinitions, collectedEnums } = generateInputTypes(typeName, fieldArgs, getRefType);
|
|
261
|
+
// Handle collected enums
|
|
262
|
+
for (const [enumName, enumDef] of collectedEnums) {
|
|
263
|
+
if (!implicitTypes.some(([name]) => name === enumName)) {
|
|
264
|
+
implicitTypes.push([enumName, enumDef]);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (argDefinitions.length > 0) {
|
|
268
|
+
callSignature += `(${argDefinitions.join(', ')})`;
|
|
264
269
|
}
|
|
265
270
|
const handler = handlers && handlers[0];
|
|
266
271
|
const brand = handler && (0, util_1.getBrand)(handler);
|
|
@@ -335,6 +340,7 @@ function customOperationToGql(typeName, typeDef, authorization, isCustom = false
|
|
|
335
340
|
customTypeAuthRules,
|
|
336
341
|
lambdaFunctionDefinition,
|
|
337
342
|
customSqlDataSourceStrategy,
|
|
343
|
+
inputTypes,
|
|
338
344
|
};
|
|
339
345
|
}
|
|
340
346
|
/**
|
|
@@ -858,6 +864,134 @@ const mergeCustomTypeAuthRules = (existing, added) => {
|
|
|
858
864
|
existing[typeName] = authRules;
|
|
859
865
|
}
|
|
860
866
|
};
|
|
867
|
+
/**
|
|
868
|
+
* Generates input types for custom operations in the schema.
|
|
869
|
+
*
|
|
870
|
+
* Processes operation arguments to create corresponding input types,
|
|
871
|
+
* handling referenced and inline custom types, enums, and nested structures.
|
|
872
|
+
* Manages circular references and prevents duplicate processing.
|
|
873
|
+
*
|
|
874
|
+
**/
|
|
875
|
+
function generateInputTypes(operationName, args, getRefType) {
|
|
876
|
+
const inputTypes = [];
|
|
877
|
+
const argDefinitions = [];
|
|
878
|
+
const collectedEnums = new Map();
|
|
879
|
+
const processedTypes = new Set(); // Track processed types to avoid duplicates
|
|
880
|
+
const processNonScalarFields = (fields, originalTypeName, isParentRef = false, parentChain = []) => {
|
|
881
|
+
const processedFields = {};
|
|
882
|
+
for (const [fieldName, fieldDef] of Object.entries(fields)) {
|
|
883
|
+
if (isRefField(fieldDef)) {
|
|
884
|
+
const refType = getRefType(fieldDef.data.link, originalTypeName);
|
|
885
|
+
if (refType.type === 'CustomType') {
|
|
886
|
+
const nestedInputTypeName = `${fieldDef.data.link}Input`;
|
|
887
|
+
processedFields[fieldName] = {
|
|
888
|
+
data: { type: 'ref', link: nestedInputTypeName },
|
|
889
|
+
};
|
|
890
|
+
// Process the nested type if it hasn't been processed and isn't a circular reference
|
|
891
|
+
if (!parentChain.includes(nestedInputTypeName) &&
|
|
892
|
+
!processedTypes.has(nestedInputTypeName)) {
|
|
893
|
+
processedTypes.add(nestedInputTypeName);
|
|
894
|
+
const nestedFields = processNonScalarFields(refType.def.data.fields, fieldDef.data.link, true, [...parentChain, nestedInputTypeName]);
|
|
895
|
+
inputTypes.push({
|
|
896
|
+
name: nestedInputTypeName,
|
|
897
|
+
fields: nestedFields,
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
else if (refType.type === 'Enum') {
|
|
902
|
+
processedFields[fieldName] = {
|
|
903
|
+
data: { type: 'ref', link: fieldDef.data.link },
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
else {
|
|
907
|
+
throw new Error(`Unsupported reference type '${refType.type}' for field '${fieldName}'. ` +
|
|
908
|
+
`Only references to CustomType and Enum are supported.`);
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
else if (isCustomType(fieldDef)) {
|
|
912
|
+
// Handle inline custom types
|
|
913
|
+
const nestedInputTypeName = `${capitalize(originalTypeName)}${capitalize(fieldName)}Input`;
|
|
914
|
+
processedFields[fieldName] = {
|
|
915
|
+
data: { type: 'ref', link: nestedInputTypeName },
|
|
916
|
+
};
|
|
917
|
+
if (!processedTypes.has(nestedInputTypeName)) {
|
|
918
|
+
processedTypes.add(nestedInputTypeName);
|
|
919
|
+
const nestedFields = processNonScalarFields(fieldDef.data.fields, `${capitalize(originalTypeName)}${capitalize(fieldName)}`, isParentRef, [...parentChain, nestedInputTypeName]);
|
|
920
|
+
inputTypes.push({
|
|
921
|
+
name: nestedInputTypeName,
|
|
922
|
+
fields: nestedFields,
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
else if (isEnumType(fieldDef)) {
|
|
927
|
+
// Handle enum types
|
|
928
|
+
const enumName = `${capitalize(originalTypeName)}${capitalize(fieldName)}`;
|
|
929
|
+
if (!collectedEnums.has(enumName) && !isParentRef) {
|
|
930
|
+
collectedEnums.set(enumName, fieldDef);
|
|
931
|
+
}
|
|
932
|
+
processedFields[fieldName] = { data: { type: 'ref', link: enumName } };
|
|
933
|
+
}
|
|
934
|
+
else {
|
|
935
|
+
processedFields[fieldName] = fieldDef;
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
return processedFields;
|
|
939
|
+
};
|
|
940
|
+
// Process top-level arguments
|
|
941
|
+
for (const [argName, argDef] of Object.entries(args)) {
|
|
942
|
+
if (isRefField(argDef)) {
|
|
943
|
+
const refType = getRefType(argDef.data.link, operationName);
|
|
944
|
+
if (refType.type === 'CustomType') {
|
|
945
|
+
const inputTypeName = `${argDef.data.link}Input`;
|
|
946
|
+
argDefinitions.push(`${argName}: ${inputTypeName}`);
|
|
947
|
+
// Process the input type if it hasn't been processed yet
|
|
948
|
+
if (!processedTypes.has(inputTypeName)) {
|
|
949
|
+
processedTypes.add(inputTypeName);
|
|
950
|
+
const fields = processNonScalarFields(refType.def.data.fields, argDef.data.link, true, [inputTypeName]);
|
|
951
|
+
inputTypes.push({
|
|
952
|
+
name: inputTypeName,
|
|
953
|
+
fields,
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
else if (refType.type === 'Enum') {
|
|
958
|
+
argDefinitions.push(`${argName}: ${argDef.data.link}`);
|
|
959
|
+
}
|
|
960
|
+
else {
|
|
961
|
+
throw new Error(`Unsupported reference type '${refType.type}' for argument '${argName}' in '${operationName}'. ` +
|
|
962
|
+
`Only references to CustomType and Enum are supported.`);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
else if (isEnumType(argDef)) {
|
|
966
|
+
// Handle top-level enum arguments
|
|
967
|
+
const enumName = `${capitalize(operationName)}${capitalize(argName)}`;
|
|
968
|
+
if (!collectedEnums.has(enumName)) {
|
|
969
|
+
collectedEnums.set(enumName, argDef);
|
|
970
|
+
}
|
|
971
|
+
argDefinitions.push(`${argName}: ${enumName}`);
|
|
972
|
+
}
|
|
973
|
+
else if (isCustomType(argDef)) {
|
|
974
|
+
// Handle top-level custom type arguments
|
|
975
|
+
const inputTypeName = `${capitalize(operationName)}${capitalize(argName)}Input`;
|
|
976
|
+
argDefinitions.push(`${argName}: ${inputTypeName}`);
|
|
977
|
+
if (!processedTypes.has(inputTypeName)) {
|
|
978
|
+
processedTypes.add(inputTypeName);
|
|
979
|
+
const fields = processNonScalarFields(argDef.data.fields, `${capitalize(operationName)}${capitalize(argName)}`, false, [inputTypeName]);
|
|
980
|
+
inputTypes.push({
|
|
981
|
+
name: inputTypeName,
|
|
982
|
+
fields,
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
else if (isScalarField(argDef)) {
|
|
987
|
+
argDefinitions.push(`${argName}: ${scalarFieldToGql(argDef.data)}`);
|
|
988
|
+
}
|
|
989
|
+
else {
|
|
990
|
+
throw new Error(`Unsupported argument type for ${argName}`);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
return { inputTypes, argDefinitions, collectedEnums };
|
|
994
|
+
}
|
|
861
995
|
const schemaPreprocessor = (schema) => {
|
|
862
996
|
const gqlModels = [];
|
|
863
997
|
const customQueries = [];
|
|
@@ -889,6 +1023,7 @@ const schemaPreprocessor = (schema) => {
|
|
|
889
1023
|
const topLevelTypes = sortTopLevelTypes(Object.entries(schema.data.types));
|
|
890
1024
|
const { schemaAuth, functionSchemaAccess } = extractFunctionSchemaAccess(schema.data.authorization);
|
|
891
1025
|
const getRefType = getRefTypeForSchema(schema);
|
|
1026
|
+
const uniqueInputTypes = new Map();
|
|
892
1027
|
for (const [typeName, typeDef] of topLevelTypes) {
|
|
893
1028
|
const mostRelevantAuthRules = typeDef.data?.authorization?.length > 0
|
|
894
1029
|
? typeDef.data.authorization
|
|
@@ -921,7 +1056,13 @@ const schemaPreprocessor = (schema) => {
|
|
|
921
1056
|
else if (isCustomOperation(typeDef)) {
|
|
922
1057
|
// TODO: add generation route logic.
|
|
923
1058
|
const { typeName: opType } = typeDef.data;
|
|
924
|
-
const { gqlField, implicitTypes, customTypeAuthRules, jsFunctionForField, lambdaFunctionDefinition, customSqlDataSourceStrategy, } = transformCustomOperations(typeDef, typeName, mostRelevantAuthRules, databaseType, getRefType);
|
|
1059
|
+
const { gqlField, implicitTypes, customTypeAuthRules, jsFunctionForField, lambdaFunctionDefinition, customSqlDataSourceStrategy, inputTypes, } = transformCustomOperations(typeDef, typeName, mostRelevantAuthRules, databaseType, getRefType);
|
|
1060
|
+
// Process input types without duplicates
|
|
1061
|
+
for (const { name, fields } of inputTypes) {
|
|
1062
|
+
if (!uniqueInputTypes.has(name)) {
|
|
1063
|
+
uniqueInputTypes.set(name, fields);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
925
1066
|
topLevelTypes.push(...implicitTypes);
|
|
926
1067
|
mergeCustomTypeAuthRules(customTypeInheritedAuthRules, customTypeAuthRules);
|
|
927
1068
|
if (customTypeAuthRules) {
|
|
@@ -1011,6 +1152,12 @@ const schemaPreprocessor = (schema) => {
|
|
|
1011
1152
|
gqlModels.push(model);
|
|
1012
1153
|
}
|
|
1013
1154
|
}
|
|
1155
|
+
// Generate input types after processing all custom operations
|
|
1156
|
+
for (const [name, fields] of uniqueInputTypes) {
|
|
1157
|
+
const { gqlFields } = processFields(name, fields, {}, {}, undefined, undefined, undefined, databaseEngine);
|
|
1158
|
+
const inputTypeDefinition = `input ${name} {\n ${gqlFields.join('\n ')}\n}`;
|
|
1159
|
+
gqlModels.push(inputTypeDefinition);
|
|
1160
|
+
}
|
|
1014
1161
|
const customOperations = {
|
|
1015
1162
|
queries: customQueries,
|
|
1016
1163
|
mutations: customMutations,
|
|
@@ -1205,7 +1352,7 @@ function transformCustomOperations(typeDef, typeName, authRules, databaseType, g
|
|
|
1205
1352
|
opType, typeName);
|
|
1206
1353
|
}
|
|
1207
1354
|
const isCustom = Boolean(jsFunctionForField);
|
|
1208
|
-
const { gqlField, implicitTypes, customTypeAuthRules, lambdaFunctionDefinition, customSqlDataSourceStrategy, } = customOperationToGql(typeName, typeDef, authRules, isCustom, databaseType, getRefType);
|
|
1355
|
+
const { gqlField, implicitTypes, customTypeAuthRules, lambdaFunctionDefinition, customSqlDataSourceStrategy, inputTypes, } = customOperationToGql(typeName, typeDef, authRules, isCustom, databaseType, getRefType);
|
|
1209
1356
|
return {
|
|
1210
1357
|
gqlField,
|
|
1211
1358
|
implicitTypes,
|
|
@@ -1213,6 +1360,7 @@ function transformCustomOperations(typeDef, typeName, authRules, databaseType, g
|
|
|
1213
1360
|
jsFunctionForField,
|
|
1214
1361
|
lambdaFunctionDefinition,
|
|
1215
1362
|
customSqlDataSourceStrategy,
|
|
1363
|
+
inputTypes,
|
|
1216
1364
|
};
|
|
1217
1365
|
}
|
|
1218
1366
|
function generateCustomOperationTypes({ queries, mutations, subscriptions, }) {
|