-
Notifications
You must be signed in to change notification settings - Fork 92
[DevTools] PR2: Backend Services, Console Viewer, and Resources #2879
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e994339
02a7289
776fd8a
7bd6b1b
093c130
c9d0917
ce447ae
8ff3baf
3085faf
d9d10c9
9955896
1a0849a
ce3a461
134e83a
52d92e0
77b7f60
87fa132
740271c
68c9ab7
73f32e0
dc33887
4f2ed23
11c9684
fa14390
0d1c15f
e5c9925
61e3a47
1e47844
732c99d
3f95603
126366d
152f5c4
b3455b3
724ff1a
740e08c
050928b
7d12cb5
e289446
97c3b99
e53ec95
0fdfae9
66e7255
4708052
af2e6ac
33570fd
b96a7d1
72b1a55
ead3ee3
41ba348
219e3cd
1671e6d
88ed395
75e5b1d
ede0865
df5e7b5
a47c32d
6c2a488
9c49385
1089978
9153373
417b73e
24c704c
76b21a3
64c0c4d
109f154
b8fc07b
c9d2288
9416275
9b8693a
8db171f
b271bad
f569654
1004c78
5786485
4861a0d
1c6d9c0
e5d1da0
422058c
e3c1c9b
aaa7a5a
f55e43c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
'@aws-amplify/deployed-backend-client': patch | ||
'@aws-amplify/platform-core': patch | ||
--- | ||
|
||
made regionfetcher public, added metadata to deployedbackendresource |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@aws-amplify/cli-core': patch | ||
--- | ||
|
||
pulled out normalizeCDKconstructPath |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
'@aws-amplify/sandbox': minor | ||
'@aws-amplify/backend-cli': minor | ||
'@aws-amplify/backend-deployer': patch | ||
'@aws-amplify/ai-constructs': patch | ||
--- | ||
|
||
Devtools PR2 |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* Utilities for formatting CDK paths and constructs | ||
*/ | ||
|
||
/** | ||
* Normalizes a CDK construct path to create a more readable friendly name | ||
* @param constructPath The CDK construct path | ||
* @returns A normalized construct path | ||
*/ | ||
export const normalizeCDKConstructPath = (constructPath: string): string => { | ||
// Don't process very long paths to avoid performance issues | ||
if (constructPath.length > 1000) return constructPath; | ||
|
||
// Handle nested stack paths | ||
const nestedStackRegex = | ||
/(?<nestedStack>[a-zA-Z0-9_]+)\.NestedStack\/\1\.NestedStackResource$/; | ||
|
||
return constructPath | ||
.replace(nestedStackRegex, '$<nestedStack>') | ||
.replace('/amplifyAuth/', '/') | ||
.replace('/amplifyData/', '/'); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* eslint-disable spellcheck/spell-checker */ | ||
import { describe, it } from 'node:test'; | ||
import assert from 'node:assert'; | ||
import { createFriendlyName } from './cloudformation_format.js'; | ||
|
||
void describe('createFriendlyName function', () => { | ||
void it('handles empty string by returning the original ID', () => { | ||
const emptyId = ''; | ||
assert.strictEqual(createFriendlyName(emptyId), emptyId); | ||
}); | ||
|
||
void it('uses CDK metadata construct path when available', () => { | ||
const logicalId = 'amplifyFunction123ABC45'; | ||
const metadata = { constructPath: 'MyStack/MyFunction/Resource' }; | ||
assert.strictEqual(createFriendlyName(logicalId, metadata), 'My Function'); | ||
}); | ||
|
||
void it('removes amplify prefix and formats camel case', () => { | ||
const logicalId = 'amplifyDataTable123ABC45'; | ||
assert.strictEqual(createFriendlyName(logicalId), 'Data Table'); | ||
}); | ||
|
||
void it('removes Amplify prefix (capitalized) and formats camel case', () => { | ||
const logicalId = 'AmplifyDataTable123ABC45'; | ||
assert.strictEqual(createFriendlyName(logicalId), 'Data Table'); | ||
}); | ||
|
||
void it('handles IDs with only numeric characters', () => { | ||
const numericId = '12345'; | ||
assert.strictEqual(createFriendlyName(numericId), numericId); | ||
}); | ||
|
||
void it('normalizes CDK construct paths', () => { | ||
const logicalId = 'amplifyFunction'; | ||
const metadata = { | ||
constructPath: 'MyStack/auth.NestedStack/auth.NestedStackResource', | ||
}; | ||
assert.strictEqual(createFriendlyName(logicalId, metadata), 'auth'); | ||
}); | ||
|
||
void it('skips Resource and Default in construct paths', () => { | ||
const logicalId = 'amplifyFunction'; | ||
const metadata = { constructPath: 'MyStack/Auth/Resource' }; | ||
assert.strictEqual(createFriendlyName(logicalId, metadata), 'Auth'); | ||
}); | ||
|
||
void it('handles multiple levels of Resource and Default', () => { | ||
const logicalId = 'amplifyFunction'; | ||
const metadata = { constructPath: 'MyStack/Auth/Default/Resource' }; | ||
assert.strictEqual(createFriendlyName(logicalId, metadata), 'Auth'); | ||
}); | ||
|
||
void it('formats camel case with multiple uppercase letters', () => { | ||
const logicalId = 'amplifyGraphQLAPI123ABC45'; | ||
assert.strictEqual(createFriendlyName(logicalId), 'Graph QLAPI'); | ||
}); | ||
|
||
void it('handles complex CloudFormation resource IDs', () => { | ||
const logicalId = 'TodoIAMRole2DA8E66E'; | ||
assert.strictEqual(createFriendlyName(logicalId), 'Todo IAM Role'); | ||
}); | ||
|
||
void it('handles empty construct path', () => { | ||
const logicalId = 'amplifyFunction'; | ||
const metadata = { constructPath: '' }; | ||
assert.strictEqual(createFriendlyName(logicalId, metadata), 'Function'); | ||
}); | ||
|
||
// Examples from documentation | ||
void it('formats TodoTable correctly', () => { | ||
const logicalId = 'TodoTable'; | ||
assert.strictEqual(createFriendlyName(logicalId), 'Todo Table'); | ||
}); | ||
|
||
void it('formats TodoIAMRole with ID correctly', () => { | ||
const logicalId = 'TodoIAMRole2DA8E66E'; | ||
assert.strictEqual(createFriendlyName(logicalId), 'Todo IAM Role'); | ||
}); | ||
|
||
void it('formats amplifyDataGraphQLAPI with ID correctly', () => { | ||
const logicalId = 'amplifyDataGraphQLAPI42A6FA33'; | ||
assert.strictEqual(createFriendlyName(logicalId), 'Data Graph QLAPI'); | ||
}); | ||
|
||
void it('formats testNameBucketPolicy with ID correctly', () => { | ||
const logicalId = 'testNameBucketPolicyA5C458BB'; | ||
assert.strictEqual( | ||
createFriendlyName(logicalId), | ||
'test Name Bucket Policy', | ||
); | ||
}); | ||
|
||
void it('handles CDK construct path example', () => { | ||
const logicalId = 'somelogicalId'; | ||
const metadata = { | ||
constructPath: | ||
'amplify-amplifyvitereacttemplate-meghabit-sandbox-83e297d0db/data/modelIntrospectionSchemaBucket/Resource', | ||
}; | ||
assert.strictEqual( | ||
createFriendlyName(logicalId, metadata), | ||
'model Introspection Schema Bucket', | ||
); | ||
}); | ||
|
||
void it('handles CDK construct path example', () => { | ||
const logicalId = 'someLogicalId'; | ||
const metadata = { | ||
constructPath: | ||
'amplify-amplifyvitereacttemplate-meghabit-sandbox-83e297d0db/data/GraphQLAPI/DefaultApiKey', | ||
}; | ||
assert.strictEqual( | ||
createFriendlyName(logicalId, metadata), | ||
'Default Api Key', | ||
); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { normalizeCDKConstructPath } from '@aws-amplify/cli-core'; | ||
|
||
/** | ||
* Creates a friendly name for a resource, using CDK metadata when available. | ||
* @param logicalId The logical ID of the resource | ||
* @param metadata Optional CDK metadata that may contain construct path | ||
* @param metadata.constructPath Optional construct path from CDK metadata | ||
* @returns A user-friendly name for the resource | ||
* | ||
* Examples of friendly names: | ||
* - "TodoTable" → "Todo Table" | ||
* - "TodoIAMRole2DA8E66E" → "Todo IAM Role" | ||
* - "amplifyDataGraphQLAPI42A6FA33" → "Data GraphQLAPI" | ||
* - "testNameBucketPolicyA5C458BB" → "test Name Bucket Policy" | ||
* | ||
* For construct paths: | ||
* - amplify-amplify-identifier-sandbox-83e297d0db/data/GraphQLAPI/DefaultApiKey → "Default Api Key" | ||
* - amplify-amplify-identifier-sandbox-83e297d0db/auth/amplifyAuth/authenticatedUserRole/Resource → "authenticated User Role" | ||
*/ | ||
export const createFriendlyName = ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Borderline arcane incantations herein. Partially cp-ing a comment from below. Examples in docstrings will help future maintainers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank-you! Probably goes without saying, but explicit test coverage would also be ideal. Unless I'm overlooking it, just a small set of examples like you have here in a test loop would be good. |
||
logicalId: string, | ||
metadata?: { constructPath?: string }, | ||
): string => { | ||
let name = logicalId; | ||
if (metadata?.constructPath) { | ||
const normalizedPath = normalizeCDKConstructPath(metadata.constructPath); | ||
const parts = normalizedPath.split('/'); | ||
let resourceName = parts.pop(); | ||
while ( | ||
(resourceName === 'Resource' || resourceName === 'Default') && | ||
parts.length > 0 | ||
) { | ||
resourceName = parts.pop(); | ||
} | ||
|
||
name = resourceName || logicalId; | ||
} | ||
|
||
// Fall back to the basic transformation | ||
name = name.replace(/^amplify/, '').replace(/^Amplify/, ''); | ||
|
||
name = name.replace(/([a-z])([A-Z])/g, '$1 $2'); | ||
|
||
name = name.replace(/([A-Z])([A-Z][a-z])/g, '$1 $2'); | ||
|
||
// Remove CloudFormation resource IDs (alphanumeric suffixes) | ||
name = name.replace(/[0-9A-F]{6,}$/g, ''); | ||
|
||
name = name.replace(/\s+/g, ' ').trim(); | ||
|
||
const result = name || logicalId; | ||
return result; | ||
}; |
This file was deleted.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In one of future PR, we should remove all file level eslint suppression.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, will do.