Skip to content

Commit 9e3fd9a

Browse files
committed
feat: Add backend-function runtime behavior to get the data config
1 parent 38d6986 commit 9e3fd9a

File tree

7 files changed

+325
-23
lines changed

7 files changed

+325
-23
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@aws-amplify/backend-function': patch
3+
---
4+
5+
feat: Add backend-function runtime behavior to get the data config

package-lock.json

Lines changed: 24 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/backend-function/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"devDependencies": {
2828
"@aws-amplify/backend-platform-test-stubs": "^0.3.6",
2929
"@aws-amplify/platform-core": "^1.1.0",
30+
"@aws-sdk/client-s3": "^3.624.0",
3031
"@aws-sdk/client-ssm": "^3.624.0",
3132
"aws-sdk": "^2.1550.0",
3233
"uuid": "^9.0.1"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "@aws-amplify/backend-function/runtime",
3+
"main": "../dist/cjs/runtime/index.js",
4+
"react-native": "../src/runtime/index.ts",
5+
"browser": "../dist/esm/runtime/index.mjs",
6+
"module": "../dist/esm/runtime/index.mjs",
7+
"typings": "../dist/esm/runtime/index.d.ts"
8+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import { beforeEach, describe, it, mock } from 'node:test';
2+
import assert from 'assert';
3+
import { NoSuchKey, S3, S3ServiceException } from '@aws-sdk/client-s3';
4+
5+
import {
6+
getAmplifyClientsConfiguration,
7+
getAmplifyClientsConfigurationRetriever,
8+
} from './get_amplify_clients_configuration.js';
9+
10+
const validEnv = {
11+
AMPLIFY_DATA_MODEL_INTROSPECTION_SCHEMA_BUCKET_NAME:
12+
'TEST_VALUE for AMPLIFY_DATA_MODEL_INTROSPECTION_SCHEMA_BUCKET_NAME',
13+
AMPLIFY_DATA_MODEL_INTROSPECTION_SCHEMA_KEY:
14+
'TEST_VALUE for AMPLIFY_DATA_MODEL_INTROSPECTION_SCHEMA_KEY',
15+
AWS_ACCESS_KEY_ID: 'TEST_VALUE for AWS_ACCESS_KEY_ID',
16+
AWS_SECRET_ACCESS_KEY: 'TEST_VALUE for AWS_SECRET_ACCESS_KEY',
17+
AWS_SESSION_TOKEN: 'TEST_VALUE for AWS_SESSION_TOKEN',
18+
AWS_REGION: 'TEST_VALUE for AWS_REGION',
19+
AMPLIFY_DATA_GRAPHQL_ENDPOINT: 'TEST_VALUE for AMPLIFY_DATA_GRAPHQL_ENDPOINT',
20+
};
21+
22+
let mockS3Client: S3;
23+
24+
void describe('getAmplifyClientsConfiguration', () => {
25+
beforeEach(() => {
26+
mockS3Client = new S3();
27+
});
28+
29+
Object.keys(validEnv).forEach((envFieldToExclude) => {
30+
void it(`returns empty config objects when ${envFieldToExclude} is not included`, async () => {
31+
const env = { ...validEnv } as Record<string, string>;
32+
delete env[envFieldToExclude];
33+
assert.deepEqual(await getAmplifyClientsConfiguration(env), {
34+
resourceConfig: {},
35+
libraryOptions: {},
36+
});
37+
});
38+
39+
void it(`returns empty config objects when ${envFieldToExclude} is not a string`, async () => {
40+
const env = { ...validEnv } as Record<string, unknown>;
41+
env[envFieldToExclude] = 123;
42+
assert.deepEqual(await getAmplifyClientsConfiguration(env), {
43+
resourceConfig: {},
44+
libraryOptions: {},
45+
});
46+
});
47+
});
48+
49+
void it('raises a custom error message when the model introspection schema is missing from the s3 bucket', async () => {
50+
const s3ClientSendMock = mock.method(mockS3Client, 'send', async () => {
51+
throw new NoSuchKey({ message: 'TEST_ERROR', $metadata: {} });
52+
});
53+
mock.method(mockS3Client, 'send', s3ClientSendMock);
54+
55+
await assert.rejects(
56+
async () =>
57+
await getAmplifyClientsConfigurationRetriever(validEnv, mockS3Client),
58+
new Error(
59+
'Error retrieving the schema from S3. Please confirm that your project has a `defineData` included in the `defineBackend` definition.'
60+
)
61+
);
62+
});
63+
64+
void it('raises a custom error message when there is a S3ServiceException error retrieving the model introspection schema from the s3 bucket', async () => {
65+
const s3ClientSendMock = mock.method(mockS3Client, 'send', async () => {
66+
throw new S3ServiceException({
67+
name: 'TEST_ERROR',
68+
message: 'TEST_MESSAGE',
69+
$fault: 'server',
70+
$metadata: {},
71+
});
72+
});
73+
mock.method(mockS3Client, 'send', s3ClientSendMock);
74+
75+
await assert.rejects(
76+
async () =>
77+
await getAmplifyClientsConfigurationRetriever(validEnv, mockS3Client),
78+
new Error(
79+
'Error retrieving the schema from S3. You may need to grant this function authorization on the schema. TEST_ERROR: TEST_MESSAGE.'
80+
)
81+
);
82+
});
83+
84+
void it('re-raises a non-S3 error received when retrieving the model introspection schema from the s3 bucket', async () => {
85+
const s3ClientSendMock = mock.method(mockS3Client, 'send', async () => {
86+
throw new Error('Test Error');
87+
});
88+
mock.method(mockS3Client, 'send', s3ClientSendMock);
89+
90+
await assert.rejects(
91+
async () =>
92+
await getAmplifyClientsConfigurationRetriever(validEnv, mockS3Client),
93+
new Error('Test Error')
94+
);
95+
});
96+
97+
void it('returns the expected libraryOptions and resourceConfig values in the happy case', async () => {
98+
const s3ClientSendMock = mock.method(mockS3Client, 'send', () => {
99+
return Promise.resolve({
100+
Body: {
101+
transformToString: () => JSON.stringify({ testSchema: 'TESTING' }),
102+
},
103+
});
104+
});
105+
mock.method(mockS3Client, 'send', s3ClientSendMock);
106+
107+
const { resourceConfig, libraryOptions } =
108+
await getAmplifyClientsConfigurationRetriever(validEnv, mockS3Client);
109+
110+
assert.deepEqual(
111+
await libraryOptions.Auth.credentialsProvider.getCredentialsAndIdentityId?.(),
112+
{
113+
credentials: {
114+
accessKeyId: 'TEST_VALUE for AWS_ACCESS_KEY_ID',
115+
secretAccessKey: 'TEST_VALUE for AWS_SECRET_ACCESS_KEY',
116+
sessionToken: 'TEST_VALUE for AWS_SESSION_TOKEN',
117+
},
118+
}
119+
);
120+
assert.deepEqual(
121+
await libraryOptions.Auth.credentialsProvider.clearCredentialsAndIdentityId?.(),
122+
undefined
123+
);
124+
125+
assert.deepEqual(resourceConfig, {
126+
API: {
127+
GraphQL: {
128+
endpoint: 'TEST_VALUE for AMPLIFY_DATA_GRAPHQL_ENDPOINT',
129+
region: 'TEST_VALUE for AWS_REGION',
130+
defaultAuthMode: 'iam',
131+
modelIntrospection: { testSchema: 'TESTING' },
132+
},
133+
},
134+
});
135+
});
136+
});

0 commit comments

Comments
 (0)