From 4de6c72b5e461a591b202cc73cc08b128dfc852e Mon Sep 17 00:00:00 2001 From: Ian Saultz <52051793+atierian@users.noreply.github.com> Date: Fri, 30 Aug 2024 16:13:29 -0400 Subject: [PATCH] magic-stringectomy --- ...raphql-generation-transformer.test.ts.snap | 2 +- .../src/grapqhl-generation-transformer.ts | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/amplify-graphql-generation-transformer/src/__tests__/__snapshots__/amplify-graphql-generation-transformer.test.ts.snap b/packages/amplify-graphql-generation-transformer/src/__tests__/__snapshots__/amplify-graphql-generation-transformer.test.ts.snap index 0bc73895bb..277e4297d9 100644 --- a/packages/amplify-graphql-generation-transformer/src/__tests__/__snapshots__/amplify-graphql-generation-transformer.test.ts.snap +++ b/packages/amplify-graphql-generation-transformer/src/__tests__/__snapshots__/amplify-graphql-generation-transformer.test.ts.snap @@ -57,7 +57,7 @@ export const response = (ctx) => { exports[`generation route all scalar types 2`] = ` "export function request(ctx) { - const toolConfig = {\\"tools\\":[{\\"toolSpec\\":{\\"name\\":\\"responseType\\",\\"description\\":\\"Generate a response type for the given field\\",\\"inputSchema\\":{\\"json\\":{\\"type\\":\\"object\\",\\"properties\\":{\\"value\\":{\\"type\\":\\"object\\",\\"properties\\":{\\"int\\":{\\"type\\":\\"number\\",\\"description\\":\\"A signed 32-bit integer value.\\"},\\"float\\":{\\"type\\":\\"number\\",\\"description\\":\\"An IEEE 754 floating point value.\\"},\\"string\\":{\\"type\\":\\"string\\",\\"description\\":\\"A UTF-8 character sequence.\\"},\\"id\\":{\\"type\\":\\"string\\",\\"description\\":\\"A unique identifier for an object. This scalar is serialized like a String but isn't meant to be human-readable.\\"},\\"boolean\\":{\\"type\\":\\"boolean\\",\\"description\\":\\"A boolean value.\\"},\\"awsjson\\":{\\"type\\":\\"string\\",\\"description\\":\\"A JSON string. Any valid JSON construct is automatically parsed and loaded in the resolver code as maps, lists, or scalar values rather than as the literal input strings. Unquoted strings or otherwise invalid JSON result in a GraphQL validation error.\\"},\\"awsemail\\":{\\"type\\":\\"string\\",\\"description\\":\\"An email address in the format local-part@domain-part as defined by RFC 822.\\",\\"pattern\\":\\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\\\\\.[a-zA-Z]{2,}$\\"},\\"awsdate\\":{\\"type\\":\\"string\\",\\"description\\":\\"An extended ISO 8601 date string in the format YYYY-MM-DD.\\",\\"pattern\\":\\"^\\\\\\\\d{4}-d{2}-d{2}$\\"},\\"awstime\\":{\\"type\\":\\"string\\",\\"description\\":\\"An extended ISO 8601 time string in the format hh:mm:ss.sss.\\",\\"pattern\\":\\"^\\\\\\\\d{2}:\\\\\\\\d{2}:\\\\\\\\d{2}\\\\\\\\.\\\\\\\\d{3}$\\"},\\"awsdatetime\\":{\\"type\\":\\"string\\",\\"description\\":\\"An extended ISO 8601 date and time string in the format YYYY-MM-DDThh:mm:ss.sssZ.\\",\\"pattern\\":\\"^\\\\\\\\d{4}-\\\\\\\\d{2}-\\\\\\\\d{2}T\\\\\\\\d{2}:\\\\\\\\d{2}:\\\\\\\\d{2}\\\\\\\\.\\\\\\\\d{3}Z$\\"},\\"awstimestamp\\":{\\"type\\":\\"string\\",\\"description\\":\\"An integer value representing the number of seconds before or after 1970-01-01-T00:00Z.\\",\\"pattern\\":\\"^\\\\\\\\d+$\\"},\\"awsphone\\":{\\"type\\":\\"string\\",\\"description\\":\\"A phone number. This value is stored as a string. Phone numbers can contain either spaces or hyphens to separate digit groups. Phone numbers without a country code are assumed to be US/North American numbers adhering to the North American Numbering Plan (NANP).\\",\\"pattern\\":\\"^\\\\\\\\d{3}-d{3}-d{4}$\\"},\\"awsurl\\":{\\"type\\":\\"string\\",\\"description\\":\\"A URL as defined by RFC 1738. For example, https://www.amazon.com/dp/B000NZW3KC/ or mailto:example@example.com. URLs must contain a schema (http, mailto) and can't contain two forward slashes (//) in the path part.\\",\\"pattern\\":\\"^(https?|mailto)://[^s/$.?#].[^s]*$\\"},\\"awsipaddress\\":{\\"type\\":\\"string\\",\\"description\\":\\"A valid IPv4 or IPv6 address. IPv4 addresses are expected in quad-dotted notation (123.12.34.56). IPv6 addresses are expected in non-bracketed, colon-separated format (1a2b:3c4b::1234:4567). You can include an optional CIDR suffix (123.45.67.89/16) to indicate subnet mask.\\",\\"pattern\\":\\"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\\\\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:/d{1,2})?$|^(?:(?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\\\\\\\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\\\\\\\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(?:/d{1,3})?$\\"}},\\"required\\":[]}},\\"required\\":[\\"value\\"]}}}}],\\"toolChoice\\":{\\"tool\\":{\\"name\\":\\"responseType\\"}}}; + const toolConfig = {\\"tools\\":[{\\"toolSpec\\":{\\"name\\":\\"responseType\\",\\"description\\":\\"Generate a response type for the given field\\",\\"inputSchema\\":{\\"json\\":{\\"type\\":\\"object\\",\\"properties\\":{\\"value\\":{\\"type\\":\\"object\\",\\"properties\\":{\\"int\\":{\\"type\\":\\"number\\",\\"description\\":\\"A signed 32-bit integer value.\\"},\\"float\\":{\\"type\\":\\"number\\",\\"description\\":\\"An IEEE 754 floating point value.\\"},\\"string\\":{\\"type\\":\\"string\\",\\"description\\":\\"A UTF-8 character sequence.\\"},\\"id\\":{\\"type\\":\\"string\\",\\"description\\":\\"A unique identifier for an object. This scalar is serialized like a String but isn't meant to be human-readable.\\"},\\"boolean\\":{\\"type\\":\\"boolean\\",\\"description\\":\\"A boolean value.\\"},\\"awsjson\\":{\\"type\\":\\"string\\",\\"description\\":\\"A JSON string. Any valid JSON construct is automatically parsed and loaded in the resolver code as maps, lists, or scalar values rather than as the literal input strings. Unquoted strings or otherwise invalid JSON result in a GraphQL validation error.\\"},\\"awsemail\\":{\\"type\\":\\"string\\",\\"description\\":\\"An email address in the format local-part@domain-part as defined by RFC 822.\\",\\"pattern\\":\\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\\\\\.[a-zA-Z]{2,}$\\"},\\"awsdate\\":{\\"type\\":\\"string\\",\\"description\\":\\"An extended ISO 8601 date string in the format YYYY-MM-DD.\\",\\"pattern\\":\\"^\\\\\\\\d{4}-d{2}-d{2}$\\"},\\"awstime\\":{\\"type\\":\\"string\\",\\"description\\":\\"An extended ISO 8601 time string in the format hh:mm:ss.sss.\\",\\"pattern\\":\\"^\\\\\\\\d{2}:\\\\\\\\d{2}:\\\\\\\\d{2}\\\\\\\\.\\\\\\\\d{3}$\\"},\\"awsdatetime\\":{\\"type\\":\\"string\\",\\"description\\":\\"An extended ISO 8601 date and time string in the format YYYY-MM-DDThh:mm:ss.sssZ.\\",\\"pattern\\":\\"^\\\\\\\\d{4}-\\\\\\\\d{2}-\\\\\\\\d{2}T\\\\\\\\d{2}:\\\\\\\\d{2}:\\\\\\\\d{2}\\\\\\\\.\\\\\\\\d{3}Z$\\"},\\"awstimestamp\\":{\\"type\\":\\"string\\",\\"description\\":\\"An integer value representing the number of seconds before or after 1970-01-01-T00:00Z.\\",\\"pattern\\":\\"^\\\\\\\\d+$\\"},\\"awsphone\\":{\\"type\\":\\"string\\",\\"description\\":\\"A phone number. This value is stored as a string. Phone numbers can contain either spaces or hyphens to separate digit groups. Phone numbers without a country code are assumed to be US/North American numbers adhering to the North American Numbering Plan (NANP).\\",\\"pattern\\":\\"^\\\\\\\\d{3}-d{3}-d{4}$\\"},\\"awsurl\\":{\\"type\\":\\"string\\",\\"description\\":\\"A URL as defined by RFC 1738. For example, https://www.amazon.com/dp/B000NZW3KC/ or mailto:example@example.com. URLs must contain a schema (http, mailto) and can't contain two forward slashes (//) in the path part.\\",\\"pattern\\":\\"^(https?|mailto)://[^s/$.?#].[^s]*$\\"},\\"awsipaddress\\":{\\"type\\":\\"string\\",\\"description\\":\\"A valid IPv4 or IPv6 address. IPv4 addresses are expected in quad-dotted notation (123.12.34.56). IPv6 addresses are expected in non-bracketed, colon-separated format (1a2b:3c4b::1234:4567). You can include an optional CIDR suffix (123.45.67.89/16) to indicate subnet mask.\\"}},\\"required\\":[]}},\\"required\\":[\\"value\\"]}}}}],\\"toolChoice\\":{\\"tool\\":{\\"name\\":\\"responseType\\"}}}; const prompt = \\"\\"; const args = JSON.stringify(ctx.args); diff --git a/packages/amplify-graphql-generation-transformer/src/grapqhl-generation-transformer.ts b/packages/amplify-graphql-generation-transformer/src/grapqhl-generation-transformer.ts index ffa2cd2d9c..63a025349a 100644 --- a/packages/amplify-graphql-generation-transformer/src/grapqhl-generation-transformer.ts +++ b/packages/amplify-graphql-generation-transformer/src/grapqhl-generation-transformer.ts @@ -1,7 +1,6 @@ import { GenerationDirective } from '@aws-amplify/graphql-directives'; import { DirectiveWrapper, - InvalidDirectiveError, TransformerPluginBase, generateGetArgumentsInput, TransformerResolver, @@ -81,11 +80,11 @@ export class GenerationTransformer extends TransformerPluginBase { toolConfig: createResponseTypeTool(field, ctx), }; - const stackName = `Generation${toUpper(fieldName)}BedrockDataSourceStack`; + const stackName = this.bedrockDataSourceName(fieldName) + 'Stack'; const stack = this.createStack(ctx, stackName); const resolverResourceId = ResolverResourceIDs.ResolverResourceID(parentName, fieldName); - const httpDataSourceId = HttpResourceIDs.HttpDataSourceID(`GenerationBedrockDataSource-${fieldName}`); + const httpDataSourceId = HttpResourceIDs.HttpDataSourceID(this.bedrockDataSourceName(fieldName)); const dataSource = this.createBedrockDataSource(ctx, directive, stack.region, stackName, httpDataSourceId); const invokeBedrockFunction = createInvokeBedrockResolverFunction(directiveWithToolConfig); @@ -175,8 +174,10 @@ export class GenerationTransformer extends TransformerPluginBase { dataSourceScope, ); - const roleName = ctx.resourceHelper.generateIAMRoleName(`GenerationBedrockDataSourceRole${fieldName}`); - const role = this.createBedrockDataSourceRole(dataSourceScope, fieldName, roleName, region, aiModel); + // This follows the existing pattern of generating logical IDs and names for IAM roles. + const roleLogicalId = this.bedrockDataSourceName(fieldName) + 'IAMRole'; + const roleName = ctx.resourceHelper.generateIAMRoleName(roleLogicalId); + const role = this.createBedrockDataSourceRole(dataSourceScope, roleLogicalId, roleName, region, aiModel); dataSource.ds.serviceRoleArn = role.roleArn; return dataSource; } @@ -192,12 +193,12 @@ export class GenerationTransformer extends TransformerPluginBase { */ private createBedrockDataSourceRole( dataSourceScope: Construct, - fieldName: string, + roleLogicalId: string, roleName: string, region: string, bedrockModelId: string, ): cdk.aws_iam.Role { - return new iam.Role(dataSourceScope, `GenerationBedrockDataSourceRole${fieldName}`, { + return new iam.Role(dataSourceScope, roleLogicalId, { roleName, assumedBy: new iam.ServicePrincipal('appsync.amazonaws.com'), inlinePolicies: { @@ -213,4 +214,8 @@ export class GenerationTransformer extends TransformerPluginBase { }, }); } + + private bedrockDataSourceName(fieldName: string): string { + return `GenerationBedrockDataSource${toUpper(fieldName)}`; + } }