Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
3a48b99
chore: remove singleton
bobbor Mar 27, 2026
8ba6537
chore: remove server-specific code (context portion)
bobbor Apr 22, 2026
0585ddc
chore: remove unneeded server side implementaion
bobbor Apr 2, 2026
07f5e3f
chore(storage): adjust endpoint provider
bobbor Apr 2, 2026
b6e88ce
fix(core): v6 compatibility
bobbor Apr 21, 2026
255a978
chore: phase 4-5 cleanup — configure storage, remove dead code, migra…
bobbor Apr 22, 2026
b83fde8
chore: remove WeakMap server context machinery
bobbor Apr 22, 2026
d9a7e62
chore: add deprecated server entry point shims redirecting to main ex…
bobbor Apr 22, 2026
96977d1
feat: add optional AmplifyContext overloads to all category APIs
bobbor Apr 22, 2026
e2c7948
chore: add deprecated stubs and disable adapter-nextjs type errors fo…
bobbor Apr 23, 2026
8c492ea
fix(analytics): fix lint/prettier errors in personalize and pinpoint …
bobbor Apr 29, 2026
c91cc7e
test(analytics): update tests for AmplifyContext parameter
bobbor Apr 29, 2026
0493839
test(auth): update tests for AmplifyContext parameter
bobbor Apr 29, 2026
d61ffc5
test(api): update tests for AmplifyContext and module-level mocks
bobbor Apr 29, 2026
7f853ea
test(storage): update tests for AmplifyContext parameter
bobbor Apr 29, 2026
dd82bd9
test(geo): update tests for AmplifyContext and add static method cove…
bobbor Apr 29, 2026
8faa168
test(predictions): update tests for AmplifyContext and add coverage
bobbor Apr 29, 2026
c875750
test(notifications): update tests for AmplifyContext parameter
bobbor Apr 29, 2026
fe6ba1a
test(interactions): update tests for AmplifyContext parameter
bobbor Apr 29, 2026
aa46314
test(pubsub): update tests for AmplifyContext parameter
bobbor Apr 29, 2026
8e46286
fix(datastore): use InternalAPI factory pattern instead of class refe…
bobbor Apr 29, 2026
a661d71
test(datastore): update tests for InternalAPI factory and AmplifyContext
bobbor Apr 29, 2026
2689def
test(core): add coverage tests for uncovered utilities
bobbor Apr 29, 2026
25c6e28
fix(adapter-nextjs): fix ContextSpec to AmplifyContext type casts
bobbor Apr 29, 2026
e73caca
chore: restore curated server exports matching main branch
bobbor Apr 29, 2026
229840c
test(aws-amplify): fix lint errors and add coverage tests
bobbor Apr 29, 2026
d1391e2
refactor(core): move context modules from singleton/ to context/ dire…
bobbor May 5, 2026
4fc8a09
refactor(aws-amplify): rename configure() to createAmplifyContext()
bobbor May 5, 2026
4e60da4
refactor(aws-amplify): remove deprecated server context stubs
bobbor May 5, 2026
7f0f9d9
refactor(adapter-nextjs): migrate to createAmplifyContext and remove …
bobbor May 5, 2026
3bb5163
chore: update yarn.lock
bobbor May 5, 2026
8ecfe98
chore: add .idea to license_config.json exclusions
bobbor May 5, 2026
cb4c327
fix(adapter-nextjs): use AmplifyError with recoverySuggestion and rem…
bobbor May 5, 2026
74b1fc8
test(analytics,predictions): replace as any with AmplifyContext type …
bobbor May 5, 2026
5da2843
test(api-rest): replace as unknown as AmplifyContext with proper type…
bobbor May 5, 2026
12fd4d1
test(api-graphql,analytics): remove unused import and fix mock contex…
bobbor May 5, 2026
82a3343
test(auth): migrate simple API tests from setUpGetConfig to createMoc…
bobbor May 7, 2026
8907b22
test(auth): migrate sign-in flow tests from setUpGetConfig to createM…
bobbor May 7, 2026
5db2301
test(auth): remove Amplify.configure from stateful tests and delete s…
bobbor May 7, 2026
21db6e5
fix(api-graphql): add GraphQLAPI Proxy shim for backwards compatibility
bobbor May 7, 2026
c9ff713
fix(core): restore ContextSpec type alias and AmplifyServerContextErr…
bobbor May 7, 2026
8e5a8c0
fix(aws-amplify): re-export fetchAuthSession from auth and restore co…
bobbor May 7, 2026
d7b1f97
fix(auth): add OAuth catch-up for late listener registration
bobbor May 7, 2026
31275fa
fix(aws-amplify): add deprecated runWithAmplifyServerContext wrapper
bobbor May 8, 2026
e79301d
fix(api-graphql): defer GraphQLAPI throw to invocation, not property …
bobbor May 8, 2026
e245ce5
chore(adapter-nextjs): remove stale noEmitOnError: false from rollup …
bobbor May 8, 2026
3f669f4
fix(core): re-export AmplifyServerContextError from internals/adapter…
bobbor May 8, 2026
591f989
chore: align cross-package version references after rebase
bobbor May 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ coverage-ts/
# Turborepo
.turbo

# TypeScript incremental build
*.tsbuildinfo

# ruby
vendor/
Gemfile.lock
1 change: 1 addition & 0 deletions license_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"rollup",
".husky",
".turbo",
".idea",
"eslint.config.mjs",
"packages/core/metadata",
"packages/react-native/example/.bundle/config"
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"packages/predictions",
"packages/storage",
"packages/adapter-nextjs",
"packages/adapter-express",
"packages/geo",
"packages/api-rest",
"packages/api-graphql",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ describe('generateServerClient', () => {
response: mockedRes,
},
operation: async contextSpec => {
await client.graphql(contextSpec, { query: '' });
await client.graphql(contextSpec, {
query: '',
});
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { getCurrentUser } from 'aws-amplify/auth/server';
import { NextRequest } from 'next/server';
import { AuthUser } from 'aws-amplify/auth';
import { NextApiRequest } from 'next';
import { AmplifyContext } from '@aws-amplify/core';

import {
hasActiveUserSessionWithAppRouter,
Expand All @@ -17,7 +18,13 @@ const mockRunWithAmplifyServerContext =
const mockGetCurrentUser = jest.mocked(getCurrentUser);

describe('hasUserSignedIn', () => {
const mockContextSpec = { token: { value: Symbol('mock') } };
const mockContextSpec: AmplifyContext = {
resourcesConfig: {},
libraryOptions: {},
fetchAuthSession: jest.fn(),
clearCredentials: jest.fn(),
getTokens: jest.fn(),
};
const mockCurrentUserResult: AuthUser = {
userId: 'mockUserId',
username: 'mockUsername',
Expand Down
13 changes: 8 additions & 5 deletions packages/adapter-nextjs/__tests__/createServerRunner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ describe('createServerRunner', () => {
const mockCreateAWSCredentialsAndIdentityIdProvider = jest.fn();
const mockCreateKeyValueStorageFromCookieStorageAdapter = jest.fn();
const mockCreateUserPoolsTokenProvider = jest.fn();
const mockRunWithAmplifyServerContextCore = jest.fn();
const mockCreateAmplifyContext = jest.fn(() => ({}));
const mockCreateAuthRouteHandlersFactory = jest.fn(() => jest.fn());
const mockIsSSLOriginUtil = jest.fn(() => true);
const mockIsValidOrigin = jest.fn(origin => !!origin);
Expand All @@ -87,7 +87,11 @@ describe('createServerRunner', () => {
createKeyValueStorageFromCookieStorageAdapter:
mockCreateKeyValueStorageFromCookieStorageAdapter,
createUserPoolsTokenProvider: mockCreateUserPoolsTokenProvider,
runWithAmplifyServerContext: mockRunWithAmplifyServerContextCore,
}));

jest.doMock('aws-amplify', () => ({
...jest.requireActual('aws-amplify'),
createAmplifyContext: mockCreateAmplifyContext,
}));

jest.doMock('aws-amplify/utils', () => ({
Expand Down Expand Up @@ -165,7 +169,7 @@ describe('createServerRunner', () => {

describe('runWithAmplifyServerContext', () => {
describe('when amplifyConfig.Auth is not defined', () => {
it('should call runWithAmplifyServerContextCore without Auth library options', () => {
it('should call createAmplifyContext without Auth library options', () => {
const mockAmplifyConfigWithoutAuth: ResourcesConfig = {
Analytics: {
Pinpoint: {
Expand All @@ -182,10 +186,9 @@ describe('createServerRunner', () => {
});
const operation = jest.fn();
runWithAmplifyServerContext({ operation, nextServerContext: null });
expect(mockRunWithAmplifyServerContextCore).toHaveBeenCalledWith(
expect(mockCreateAmplifyContext).toHaveBeenCalledWith(
mockAmplifyConfigWithoutAuth,
{},
operation,
);
expect(createRunWithAmplifyServerContextSpy).toHaveBeenCalledWith({
config: mockAmplifyConfigWithoutAuth,
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"version": "1.7.3",
"description": "The adapter for the supporting of using Amplify APIs in Next.js.",
"peerDependencies": {
"aws-amplify": "^6.16.4",
"aws-amplify": "^6.17.0",
"next": ">=13.5.0 <17.0.0"
},
"dependencies": {
Expand Down
21 changes: 8 additions & 13 deletions packages/adapter-nextjs/src/api/generateServerClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ import {
V6ClientSSRRequest,
generateClientWithAmplifyInstance,
} from 'aws-amplify/api/internals';
import { generateClient } from 'aws-amplify/api/server';
import {
AmplifyServerContextError,
getAmplifyServerContext,
} from 'aws-amplify/adapter-core/internals';
import { AmplifyError } from 'aws-amplify/adapter-core/internals';
import { parseAmplifyConfig } from 'aws-amplify/utils';

import { NextServer } from '../types';
Expand Down Expand Up @@ -43,12 +39,12 @@ export function generateServerClientUsingCookies<
CookiesClientParams = DefaultCommonClientOptions & CookiesClientParams,
>(options: Options): V6ClientSSRCookies<T, Options> {
if (typeof options.cookies !== 'function') {
throw new AmplifyServerContextError({
throw new AmplifyError({
name: 'InvalidCookiesError',
message:
'generateServerClientUsingCookies is only compatible with the `cookies` Dynamic Function available in Server Components.',
// TODO: link to docs
recoverySuggestion:
'use `generateServerClient` inside of `runWithAmplifyServerContext` with the `request` object.',
'Use `generateServerClient` inside of `runWithAmplifyServerContext` with the `request` object.',
});
}

Expand All @@ -61,8 +57,7 @@ export function generateServerClientUsingCookies<
const getAmplify = (fn: (amplify: any) => Promise<any>) =>
runWithAmplifyServerContext({
nextServerContext: { cookies: options.cookies },
operation: contextSpec =>
fn(getAmplifyServerContext(contextSpec).amplify),
operation: contextSpec => fn(contextSpec),
});

const { cookies: _cookies, config: _config, ...params } = options;
Expand All @@ -71,7 +66,7 @@ export function generateServerClientUsingCookies<
amplify: getAmplify,
config: resourcesConfig,
...params,
} as any); // TS can't narrow the type here.
});
}

/**
Expand Down Expand Up @@ -99,8 +94,8 @@ export function generateServerClientUsingReqRes<

const { config: _config, ...params } = options;

return generateClient<T>({
return generateClientWithAmplifyInstance<T, V6ClientSSRRequest<T, Options>>({
config: amplifyConfig,
...params,
}) as any;
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { NextRequest } from 'next/server';
import {
AmplifyServerContextError,
AmplifyError,
CookieStorage,
OAuthConfig,
assertOAuthConfig,
Expand Down Expand Up @@ -97,15 +97,17 @@ export const createAuthRouteHandlersFactory = ({
// origin validation should happen when createAuthRouteHandlers is being called to create
// Auth API routes.
if (!amplifyAppOrigin) {
throw new AmplifyServerContextError({
throw new AmplifyError({
name: 'MissingOriginError',
message: 'Could not find the AMPLIFY_APP_ORIGIN environment variable.',
recoverySuggestion:
'Add the AMPLIFY_APP_ORIGIN environment variable to the `.env` file of your Next.js project.',
});
}

if (!isValidOrigin(amplifyAppOrigin)) {
throw new AmplifyServerContextError({
throw new AmplifyError({
name: 'InvalidOriginError',
message:
'AMPLIFY_APP_ORIGIN environment variable contains an invalid origin string.',
recoverySuggestion:
Expand Down
10 changes: 4 additions & 6 deletions packages/adapter-nextjs/src/auth/utils/resolveRedirectUrl.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import {
AmplifyServerContextError,
OAuthConfig,
} from 'aws-amplify/adapter-core/internals';
import { AmplifyError, OAuthConfig } from 'aws-amplify/adapter-core/internals';

export const resolveRedirectSignInUrl = (
origin: string,
Expand Down Expand Up @@ -36,8 +33,9 @@ export const resolveRedirectSignOutUrl = (
return redirectUrl;
};

const createError = (urlType: string): AmplifyServerContextError =>
new AmplifyServerContextError({
const createError = (urlType: string): AmplifyError =>
new AmplifyError({
name: 'InvalidRedirectUrlError',
message: `No valid ${urlType} url found in the OAuth config.`,
recoverySuggestion: `Check the OAuth config and ensure the ${urlType} url is valid.`,
});
5 changes: 2 additions & 3 deletions packages/adapter-nextjs/src/types/NextServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import { NextRequest, NextResponse } from 'next/server.js';
import { cookies } from 'next/headers.js';
import {
AmplifyOutputsUnknown,
AmplifyServer,
CookieStorage,
LegacyConfig,
} from 'aws-amplify/adapter-core/internals';
import { ResourcesConfig } from 'aws-amplify';
import { AmplifyContext, ResourcesConfig } from 'aws-amplify';

import { CreateAuthRouteHandlers } from '../auth/types';

Expand Down Expand Up @@ -71,7 +70,7 @@ export declare namespace NextServer {
export interface RunWithContextInput<OperationResult> {
nextServerContext: Context | null;
operation(
contextSpec: AmplifyServer.ContextSpec,
contextSpec: AmplifyContext,
): OperationResult | Promise<OperationResult>;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { NextRequest, NextResponse } from 'next/server.js';
import {
AmplifyServerContextError,
AmplifyError,
CookieStorage,
} from 'aws-amplify/adapter-core/internals';

Expand Down Expand Up @@ -78,7 +78,8 @@ export const createCookieStorageAdapterFromNextServerContext = async (
}

// This should not happen normally.
throw new AmplifyServerContextError({
throw new AmplifyError({
name: 'UnsupportedServerContextError',
message:
'Attempted to create cookie storage adapter from an unsupported Next.js server context.',
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { ResourcesConfig } from 'aws-amplify';
import { ResourcesConfig, createAmplifyContext } from 'aws-amplify';
import { sharedInMemoryStorage } from 'aws-amplify/utils';
import { KeyValueStorageMethodValidator } from 'aws-amplify/adapter-core/internals';
import {
createAWSCredentialsAndIdentityIdProvider,
createKeyValueStorageFromCookieStorageAdapter,
createUserPoolsTokenProvider,
runWithAmplifyServerContext as runWithAmplifyServerContextCore,
} from 'aws-amplify/adapter-core';

import { NextServer } from '../types';
Expand Down Expand Up @@ -75,18 +74,18 @@ export const createRunWithAmplifyServerContext = ({
keyValueStorage,
);

return runWithAmplifyServerContextCore(
resourcesConfig,
{
Auth: { credentialsProvider, tokenProvider },
},
operation,
);
const amplifyContext = createAmplifyContext(resourcesConfig, {
Auth: { credentialsProvider, tokenProvider },
});

return operation(amplifyContext);
}

// Otherwise it may be the case that auth is not used, e.g. API key.
// Omitting the `Auth` in the second parameter.
return runWithAmplifyServerContextCore(resourcesConfig, {}, operation);
const amplifyContext = createAmplifyContext(resourcesConfig, {});

return operation(amplifyContext);
};

return runWithAmplifyServerContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,21 @@ import {
mockKinesisConfig,
} from '../../../testUtils/mockConstants';
import { flushEvents } from '../../../../src/providers/kinesis-firehose/apis';
import {
setupGlobalContext,
teardownGlobalContext,
} from '../../../testUtils/mockAmplifyContext';

jest.mock('../../../../src/utils');
jest.mock('../../../../src/providers/kinesis-firehose/utils');

describe('Analytics Kinesis Firehose API: flushEvents', () => {
beforeAll(() => {
setupGlobalContext();
});
afterAll(() => {
teardownGlobalContext();
});
const mockResolveConfig = resolveConfig as jest.Mock;
const mockResolveCredentials = resolveCredentials as jest.Mock;
const mockGetEventBuffer = getEventBuffer as jest.Mock;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,21 @@ import {
} from '../../../testUtils/mockConstants';
import { record } from '../../../../src/providers/kinesis-firehose';
import { RecordInput as KinesisFirehoseRecordInput } from '../../../../src/providers/kinesis-firehose/types';
import {
setupGlobalContext,
teardownGlobalContext,
} from '../../../testUtils/mockAmplifyContext';

jest.mock('../../../../src/utils');
jest.mock('../../../../src/providers/kinesis-firehose/utils');

describe('Analytics KinesisFirehose API: record', () => {
beforeAll(() => {
setupGlobalContext();
});
afterAll(() => {
teardownGlobalContext();
});
const mockRecordInput: KinesisFirehoseRecordInput = {
streamName: 'stream0',
data: new Uint8Array([0x01, 0x02, 0xff]),
Expand Down
Loading
Loading