@aws-amplify/core
Version:
Core category of aws-amplify
156 lines (153 loc) • 6.98 kB
JavaScript
import { AMPLIFY_CONTEXT_BRAND } from '../../context/contextBrand.mjs';
import { createAmplifyContext } from '../../context/createAmplifyContext.mjs';
import { AmplifyServerContextError } from '../../errors/AmplifyServerContextError.mjs';
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
/**
* Registry of live legacy server contexts, keyed by the per-context token
* symbol carried on every branded {@link AmplifyContext}
* (`contextSpec.token.value`). Entries are added by
* {@link createAmplifyServerContext} and removed by
* {@link destroyAmplifyServerContext}, exactly mirroring the lifecycle of the
* removed server-context registry.
*/
const legacyServerContextRegistry = new Map();
/**
* Builds the {@link LegacyBridgedAmplify} reverse bridge for a context.
* The bridge is branded (it IS a valid {@link AmplifyContext} by delegation)
* and frozen, mirroring the invariants of `createAmplifyContext`.
*/
const createLegacyBridgedAmplify = (ctx) => {
const auth = Object.freeze({
fetchAuthSession: (options) => ctx.fetchAuthSession(options),
clearCredentials: () => ctx.clearCredentials(),
getTokens: (options) => ctx.getTokens(options),
});
const amplify = {
// Full AmplifyContext surface, delegating to the real context. The token
// is shared so the bridge itself also resolves in the registry.
resourcesConfig: ctx.resourcesConfig,
libraryOptions: ctx.libraryOptions,
token: ctx.token,
fetchAuthSession: options => ctx.fetchAuthSession(options),
clearCredentials: () => ctx.clearCredentials(),
getTokens: options => ctx.getTokens(options),
// Legacy AmplifyClass surface.
getConfig: () => ctx.resourcesConfig,
Auth: auth,
configure: () => {
throw new AmplifyServerContextError({
message: '`configure()` is not supported on a server context. The legacy ' +
'per-request `AmplifyClass` has been replaced by an immutable, ' +
'branded `AmplifyContext`.',
recoverySuggestion: 'Pass the resource config and library options when creating the ' +
'context (e.g. via `createAmplifyContext()` or ' +
'`createAmplifyServerContext()`) instead of reconfiguring it.',
});
},
};
// Brand the bridge for runtime identification by `isAmplifyContext()`, so
// context-first internals accept it without re-bridging (mirrors
// `createAmplifyContext`).
Object.defineProperty(amplify, AMPLIFY_CONTEXT_BRAND, {
value: true,
enumerable: false,
configurable: false,
writable: false,
});
return Object.freeze(amplify);
};
/**
* Creates an Amplify server context.
*
* @deprecated This registry-backed API exists solely so OLD published
* `@aws-amplify/adapter-nextjs` versions (≤ 1.7.3, peer `aws-amplify: ^6.16.4`)
* — which call it (via `runWithAmplifyServerContext`) at runtime — keep working
* against this version of `aws-amplify`. It will be removed in the next major
* version. New code should use `createAmplifyContext()` and pass the context
* to category APIs directly.
*
* Unlike the removed original (which registered a per-request `AmplifyClass`),
* this shim builds a REAL branded `AmplifyContext` via `createAmplifyContext`
* and returns it as the context spec: the branded context structurally
* satisfies the legacy `ContextSpec` shape (`{ token: { value: symbol } }`),
* so old adapter code can hand it BOTH to new context-first APIs (e.g.
* `fetchAuthSession(contextSpec)` from `aws-amplify/auth/server`) and to the
* legacy {@link getAmplifyServerContext} lookup.
*
* @param amplifyConfig The Amplify resource config.
* @param libraryOptions The Amplify library options (the old adapter supplies
* cookie-backed `Auth.tokenProvider` / `Auth.credentialsProvider` here).
* @returns The branded {@link AmplifyContext}, usable as the legacy context
* spec.
*/
const createAmplifyServerContext = (amplifyConfig, libraryOptions) => {
const ctx = createAmplifyContext(amplifyConfig, libraryOptions);
legacyServerContextRegistry.set(ctx.token.value, {
amplify: createLegacyBridgedAmplify(ctx),
});
return ctx;
};
/**
* Returns an Amplify server context.
*
* @deprecated See {@link createAmplifyServerContext}; retained solely for OLD
* published `@aws-amplify/adapter-nextjs` versions (≤ 1.7.3) and removed in
* the next major version. The returned envelope's `amplify` member is a
* {@link LegacyBridgedAmplify} reverse bridge, not an `AmplifyClass`.
*
* @param contextSpec The context spec used to get the Amplify server context.
* @returns The Amplify server context.
*/
const getAmplifyServerContext = (contextSpec) => {
assertContextSpec(contextSpec);
const context = legacyServerContextRegistry.get(contextSpec.token.value);
if (context) {
return context;
}
// Preserves the message of the removed original: reaching here means the
// spec was well-formed but already destroyed (or never registered).
throw new AmplifyServerContextError({
message: 'Attempted to get the Amplify Server Context that may have been destroyed.',
recoverySuggestion: 'Ensure always call Amplify APIs within `runWithAmplifyServerContext` function, and do not attempt to reuse `contextSpec` object.',
});
};
/**
* Destroys an Amplify server context.
*
* @deprecated See {@link createAmplifyServerContext}; retained solely for OLD
* published `@aws-amplify/adapter-nextjs` versions (≤ 1.7.3) and removed in
* the next major version.
*
* @param contextSpec The context spec used to destroy the Amplify server
* context.
*/
const destroyAmplifyServerContext = (contextSpec) => {
legacyServerContextRegistry.delete(contextSpec.token.value);
};
/**
* Validates the structural `ContextSpec` shape exactly like the removed
* original, so malformed input from untyped JS callers fails with the same
* descriptive error as before.
*/
const assertContextSpec = (contextSpec) => {
let invalid = false;
if (!Object.prototype.hasOwnProperty.call(contextSpec, 'token')) {
invalid = true;
}
else if (!Object.prototype.hasOwnProperty.call(contextSpec.token, 'value')) {
invalid = true;
}
else if (Object.prototype.toString.call(contextSpec.token?.value) !==
'[object Symbol]') {
invalid = true;
}
if (invalid) {
throw new AmplifyServerContextError({
message: 'Invalid `contextSpec`.',
recoverySuggestion: 'Ensure to use the `contextSpec` object injected by `runWithAmplifyServerContext` function.',
});
}
};
export { createAmplifyServerContext, destroyAmplifyServerContext, getAmplifyServerContext };
//# sourceMappingURL=legacyServerContext.mjs.map