UNPKG

@aws-amplify/core

Version:

Core category of aws-amplify

156 lines (153 loc) • 6.98 kB
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