Skip to content

Commit

Permalink
release(required): Amplify JS release (#13814)
Browse files Browse the repository at this point in the history
  • Loading branch information
Samaritan1011001 authored Sep 16, 2024
2 parents be1442d + 5918360 commit 4cf088c
Show file tree
Hide file tree
Showing 129 changed files with 2,913 additions and 1,030 deletions.
26 changes: 16 additions & 10 deletions .github/actions/load-verdaccio-with-amplify-js/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ runs:
steps:
- name: Start verdaccio
run: |
npx [email protected] &
# This version supports Node.js v22
npx [email protected] &
while ! nc -z localhost 4873; do
echo "Verdaccio not running yet"
sleep 1
Expand All @@ -18,25 +19,30 @@ runs:
- name: Install and run npm-cli-login
shell: bash
env:
NPM_REGISTRY: http://localhost:4873/
NPM_REGISTRY_HOST: localhost:4873
NPM_REGISTRY: http://localhost:4873
NPM_USER: verdaccio
NPM_PASS: verdaccio
NPM_EMAIL: [email protected]
run: |
npm i -g npm-cli-adduser
npm-cli-adduser
sleep 1
- name: Configure registry and git
# Make the HTTP request that npm addUser makes to avoid the "Exit handler never called" error
TOKEN=$(curl -s \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X PUT --data "{\"name\": \"$NPM_USER\", \"password\": \"$NPM_PASS\", \"email\": \"$NPM_EMAIL\"}" \
$NPM_REGISTRY/-/user/org.couchdb.user:$NPM_USER 2>&1 | jq -r '.token')
# Set the Verdaccio registry and set the token for logging in
yarn config set registry $NPM_REGISTRY
npm set registry $NPM_REGISTRY
npm set //"$NPM_REGISTRY_HOST"/:_authToken $TOKEN
- name: Configure git
shell: bash
working-directory: ./amplify-js
env:
NPM_REGISTRY: http://localhost:4873/
NPM_USER: verdaccio
NPM_PASS: verdaccio
NPM_EMAIL: [email protected]
run: |
yarn config set registry $NPM_REGISTRY
npm set registry $NPM_REGISTRY
git config --global user.email $NPM_EMAIL
git config --global user.name $NPM_USER
git status
Expand Down
6 changes: 4 additions & 2 deletions .github/actions/node-and-build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ inputs:
is-prebuild:
required: false
default: false
node_version:
required: false
runs:
using: 'composite'
steps:
- name: Setup Node.js 18
- name: Setup Node.js
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
with:
node-version: 18.20.2
node-version: ${{ inputs.node_version || '18.x' }}
env:
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 2
- uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
Expand Down
7 changes: 7 additions & 0 deletions .github/integ-config/integ-all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -870,3 +870,10 @@ tests:
spec: ssr-context-isolation
yarn_script: ci:ssr-context-isolation
browser: [chrome]
- test_name: integ_node_envs
desc: 'Node.js environment tests'
framework: node
category: integration
sample_name: auth-gql-storage
yarn_script: ci:node-env-test
node_versions: ['18.x', '20.x', '22.x']
7 changes: 7 additions & 0 deletions .github/workflows/callable-e2e-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ on:
yarn_script:
required: false
type: string
node_versions:
required: false
type: string

env:
AMPLIFY_DIR: /home/runner/work/amplify-js/amplify-js/amplify-js
Expand All @@ -54,6 +57,8 @@ jobs:
- ${{ fromJson(inputs.browser) }}
sample_name:
- ${{ fromJson(inputs.sample_name) }}
node_version:
- ${{ fromJson(inputs.node_versions) }}
fail-fast: false
timeout-minutes: ${{ inputs.timeout_minutes }}

Expand All @@ -64,6 +69,8 @@ jobs:
path: amplify-js
- name: Setup node and build the repository
uses: ./amplify-js/.github/actions/node-and-build
with:
node_version: ${{ matrix.node_version }}
- name: Setup samples staging repository
uses: ./amplify-js/.github/actions/setup-samples-staging
with:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/callable-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ jobs:
timeout_minutes: ${{ matrix.integ-config.timeout_minutes || 35 }}
retry_count: ${{ matrix.integ-config.retry_count || 3 }}
yarn_script: ${{ matrix.integ-config.yarn_script || '' }}
node_versions: ${{ toJSON(matrix.integ-config.node_versions) || '[""]' }}

# e2e-test-runner-headless:
# name: E2E test runnner_headless
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@
"webpack-bundle-analyzer": "^4.7.0",
"webpack-cli": "^5.0.0"
},
"engines": {
"node": ">=18"
},
"resolutions": {
"@types/babel__traverse": "7.20.0",
"path-scurry": "1.10.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/api-graphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"dependencies": {
"@aws-amplify/api-rest": "4.0.47",
"@aws-amplify/core": "6.4.0",
"@aws-amplify/data-schema": "^1.0.0",
"@aws-amplify/data-schema": "^1.5.0",
"@aws-sdk/types": "3.387.0",
"graphql": "15.8.0",
"rxjs": "^7.8.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { AmplifyUrl } from '@aws-amplify/core/internals/utils';

import { cognitoUserPoolEndpointResolver } from '../../src/foundation/cognitoUserPoolEndpointResolver';
import { COGNITO_IDP_SERVICE_NAME } from '../../src/foundation/constants';

describe('cognitoUserPoolEndpointResolver', () => {
it('should return the Cognito User Pool endpoint', () => {
const region = 'us-west-2';
const { url } = cognitoUserPoolEndpointResolver({ region });

expect(url instanceof AmplifyUrl).toBe(true);
expect(url.toString()).toEqual(
`https://${COGNITO_IDP_SERVICE_NAME}.us-west-2.amazonaws.com/`,
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { composeServiceApi } from '@aws-amplify/core/internals/aws-client-utils/composers';

import * as serviceClients from '../../../../../src/foundation/factories/serviceClients/cognitoIdentityProvider';
import { DEFAULT_SERVICE_CLIENT_API_CONFIG } from '../../../../../src/foundation/factories/serviceClients/cognitoIdentityProvider/constants';

import { mockServiceClientAPIConfig } from './testUtils/data';

jest.mock('@aws-amplify/core/internals/aws-client-utils/composers', () => ({
...jest.requireActual(
'@aws-amplify/core/internals/aws-client-utils/composers',
),
composeServiceApi: jest.fn(),
}));

export const mockComposeServiceApi = jest.mocked(composeServiceApi);

describe('service clients', () => {
const serviceClientFactories = Object.keys(serviceClients);

afterEach(() => {
mockComposeServiceApi.mockClear();
});

test.each(serviceClientFactories)(
'factory `%s` should invoke composeServiceApi with expected parameters',
serviceClientFactory => {
// eslint-disable-next-line import/namespace
serviceClients[serviceClientFactory](mockServiceClientAPIConfig);

expect(mockComposeServiceApi).toHaveBeenCalledWith(
expect.any(Function),
expect.any(Function),
expect.any(Function),
expect.objectContaining({
...DEFAULT_SERVICE_CLIENT_API_CONFIG,
...mockServiceClientAPIConfig,
}),
);
},
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { unauthenticatedHandler } from '@aws-amplify/core/internals/aws-client-utils';
import { composeTransferHandler } from '@aws-amplify/core/internals/aws-client-utils/composers';

import { cognitoUserPoolTransferHandler } from '../../../../../../../src/foundation/factories/serviceClients/cognitoIdentityProvider/shared/handler';

jest.mock('@aws-amplify/core/internals/aws-client-utils/composers');
jest.mock('@aws-amplify/core/internals/aws-client-utils');

const mockComposeTransferHandler = jest.mocked(composeTransferHandler);
const mockUnauthenticatedHandler = jest.mocked(unauthenticatedHandler);

describe('cognitoUserPoolTransferHandler', () => {
beforeAll(() => {
// need to make sure cognitoUserPoolTransferHandler is imported and used in
// the scope of the test
const _ = cognitoUserPoolTransferHandler;
});

it('adds the disableCacheMiddlewareFactory at module loading', () => {
expect(mockComposeTransferHandler).toHaveBeenCalledTimes(1);

const [core, middleware] = mockComposeTransferHandler.mock.calls[0];

expect(core).toStrictEqual(mockUnauthenticatedHandler);
expect(middleware).toHaveLength(1);

const disableCacheMiddlewareFactory = middleware[0] as any;
const disableCacheMiddlewarePendingNext = disableCacheMiddlewareFactory();

const mockNext = jest.fn();
const disableCacheMiddleware = disableCacheMiddlewarePendingNext(mockNext);
const mockRequest = {
headers: {},
};

disableCacheMiddleware(mockRequest);

expect(mockNext).toHaveBeenCalledWith(mockRequest);
expect(mockRequest.headers).toEqual({
'cache-control': 'no-store',
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {
HttpResponse,
parseJsonError,
} from '@aws-amplify/core/internals/aws-client-utils';

import { createEmptyResponseDeserializer } from '../../../../../../../src/foundation/factories/serviceClients/cognitoIdentityProvider/shared/serde/createEmptyResponseDeserializer';
import { AuthError } from '../../../../../../../src/errors/AuthError';

jest.mock('@aws-amplify/core/internals/aws-client-utils');

const mockParseJsonError = jest.mocked(parseJsonError);

describe('createEmptyResponseDeserializer created response deserializer', () => {
const deserializer = createEmptyResponseDeserializer();

it('returns undefined for 2xx status code', async () => {
const response: HttpResponse = {
statusCode: 200,
body: {
json: () => Promise.resolve({}),
blob: () => Promise.resolve(new Blob()),
text: () => Promise.resolve(''),
},
headers: {},
};
const output = await deserializer(response);

expect(output).toBeUndefined();
});

it('throws AuthError for 4xx status code', async () => {
const expectedErrorName = 'TestError';
const expectedErrorMessage = 'TestErrorMessage';
const expectedError = new Error(expectedErrorMessage);
expectedError.name = expectedErrorName;

mockParseJsonError.mockReturnValueOnce(expectedError as any);
const response: HttpResponse = {
statusCode: 400,
body: {
json: () => Promise.resolve({}),
blob: () => Promise.resolve(new Blob()),
text: () => Promise.resolve(''),
},
headers: {},
};

expect(deserializer(response as any)).rejects.toThrow(
new AuthError({
name: expectedErrorName,
message: expectedErrorMessage,
}),
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import {
HttpResponse,
parseJsonBody,
parseJsonError,
} from '@aws-amplify/core/internals/aws-client-utils';

import { createUserPoolDeserializer } from '../../../../../../../src/foundation/factories/serviceClients/cognitoIdentityProvider/shared/serde/createUserPoolDeserializer';
import { AuthError } from '../../../../../../../src/errors/AuthError';

jest.mock('@aws-amplify/core/internals/aws-client-utils');

const mockParseJsonBody = jest.mocked(parseJsonBody);
const mockParseJsonError = jest.mocked(parseJsonError);

describe('buildUserPoolDeserializer created response deserializer', () => {
const deserializer = createUserPoolDeserializer();

it('returns body for 2xx status code', async () => {
const expectedBody = { test: 'test' };
mockParseJsonBody.mockResolvedValueOnce(expectedBody);
const response: HttpResponse = {
statusCode: 200,
body: {
json: () => Promise.resolve({}),
blob: () => Promise.resolve(new Blob()),
text: () => Promise.resolve(''),
},
headers: {},
};
const output = await deserializer(response);

expect(output).toStrictEqual(expectedBody);
});

it('throws AuthError for 4xx status code', async () => {
const expectedErrorName = 'TestError';
const expectedErrorMessage = 'TestErrorMessage';
const expectedError = new Error(expectedErrorMessage);
expectedError.name = expectedErrorName;

mockParseJsonError.mockReturnValueOnce(expectedError as any);
const response: HttpResponse = {
statusCode: 400,
body: {
json: () => Promise.resolve({}),
blob: () => Promise.resolve(new Blob()),
text: () => Promise.resolve(''),
},
headers: {},
};

expect(deserializer(response as any)).rejects.toThrow(
new AuthError({
name: expectedErrorName,
message: expectedErrorMessage,
}),
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { AmplifyUrl } from '@aws-amplify/core/internals/utils';

import { createUserPoolSerializer } from '../../../../../../../src/foundation/factories/serviceClients/cognitoIdentityProvider/shared/serde/createUserPoolSerializer';

describe('createUserPoolSerializer created request serializer', () => {
test.each(['SignUp', 'InitiateAuth', 'RevokeToken'] as const)(
`it serializes requests from operation %s`,
operation => {
const testInput = { testBody: 'testBody' };
const testEndpoint = {
url: new AmplifyUrl('http://test.com'),
};
const serializer = createUserPoolSerializer(operation);
const result = serializer(testInput, testEndpoint);

expect(result).toEqual({
method: 'POST',
url: testEndpoint.url,
headers: {
'content-type': 'application/x-amz-json-1.1',
'x-amz-target': `AWSCognitoIdentityProviderService.${operation}`,
},
body: JSON.stringify(testInput),
});
},
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ServiceClientFactoryInput } from '../../../../../../src/foundation/factories/serviceClients/cognitoIdentityProvider/types';

export const mockServiceClientAPIConfig: ServiceClientFactoryInput = {
endpointResolver: jest.fn() as jest.MockedFunction<
ServiceClientFactoryInput['endpointResolver']
>,
};
Loading

0 comments on commit 4cf088c

Please sign in to comment.