UNPKG

@aws-amplify/core

Version:

Core category of aws-amplify

1 lines • 7.57 kB
{"version":3,"file":"createAmplifyContext.mjs","sources":["../../../src/context/createAmplifyContext.ts"],"sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nimport { AuthClass } from '../singleton/Auth';\nimport { deepFreeze } from '../utils/deepFreeze';\nimport { parseAmplifyConfig } from '../utils/parseAmplifyConfig';\nimport { AMPLIFY_CONTEXT_BRAND } from './contextBrand';\nimport { createAmplifyContextToken } from './contextToken';\n/**\n * Creates a local, branded {@link AmplifyContext} from the given resource\n * configuration.\n *\n * Unlike `Amplify.configure()`, the returned context is **not** set as the\n * global context and no Hub events are dispatched. Category APIs that receive\n * this context (as their first positional argument) will use it instead of the\n * global one, enabling per-request context injection in server-side /\n * multi-tenant scenarios.\n *\n * The factory follows the \"factory-provider\" style: it instantiates a **fresh,\n * per-context** {@link AuthClass} (never the process-wide singleton) whose\n * `fetchAuthSession` / `clearCredentials` / `getTokens` closures back the\n * returned context's methods. The context is branded via\n * {@link AMPLIFY_CONTEXT_BRAND} and frozen so it can be recognized at runtime\n * by `isAmplifyContext()` and cannot be mutated after creation.\n *\n * @remarks\n * `@aws-amplify/core` sits at the bottom of the dependency graph and therefore\n * cannot import the Cognito token/credentials provider factories (those live in\n * the `aws-amplify` umbrella package and depend on `@aws-amplify/auth`). As a\n * result this core-level factory does **not** inject default providers: callers\n * that need auth must supply `libraryOptions.Auth.{tokenProvider,credentialsProvider}`.\n * The `aws-amplify` package wraps this factory (Phase C2) to resolve and inject\n * the default Cognito providers (SSR cookie storage vs. localStorage) before\n * delegating here.\n *\n * @param resourceConfig - Back-end resource configuration (typed config,\n * legacy `aws-exports`, or `amplify_outputs`).\n * @param libraryOptions - Optional library options (e.g. Auth token/credentials\n * providers, `ssr`).\n * @param internalOptions - Internal-only options. `skipConfigParse` lets a\n * trusted caller (the `aws-amplify` wrapper) that has *already* normalized the\n * config via `parseAmplifyConfig` opt out of a redundant re-parse. Since\n * `parseAmplifyConfig` is a no-op on an already-parsed `ResourcesConfig`, this\n * only removes duplicate work (which otherwise runs on every context creation,\n * and twice per SSR request through adapter-nextjs) — behavior is identical.\n * @returns A branded, frozen {@link AmplifyContext}.\n *\n * @example\n * ```ts\n * import { createAmplifyContext } from '@aws-amplify/core';\n *\n * const ctx = createAmplifyContext(resourcesConfig, {\n * Auth: { tokenProvider, credentialsProvider },\n * });\n * // Pass ctx explicitly to category APIs:\n * await signIn(ctx, { username, password });\n * ```\n */\nexport function createAmplifyContext(resourceConfig, libraryOptions, internalOptions) {\n // `parseAmplifyConfig` returns an already-parsed `ResourcesConfig` unchanged,\n // so skipping it when the caller has pre-parsed keeps behavior identical while\n // avoiding a redundant parse.\n //\n // The resolved config is DEEP-frozen (matching `Amplify.configure()` in\n // Amplify.ts) on BOTH paths: a shallow `Object.freeze` would leave nested\n // config (e.g. `Auth.Cognito`) mutable, and on the `skipConfigParse` path the\n // caller's object passes through by reference — potentially SHARED between\n // several per-request contexts (adapter-nextjs reuses one parsed config for\n // every request), so any nested mutation would leak across contexts.\n // `deepFreeze` is idempotent, so re-freezing that shared object is safe.\n const resolvedResourceConfig = deepFreeze(internalOptions?.skipConfigParse\n ? resourceConfig\n : parseAmplifyConfig(resourceConfig));\n const resolvedLibraryOptions = libraryOptions ?? {};\n // Fresh, per-context Auth instance (not the global singleton) so that\n // multiple contexts remain isolated from one another.\n //\n // `configure()` is called UNCONDITIONALLY, exactly as the pre-context\n // `AmplifyClass.configure()` does (see singleton/Amplify.ts). It is the only\n // place `AuthClass` stores `libraryOptions.Auth`, so gating it on the\n // presence of `resourcesConfig.Auth` would silently drop caller-supplied\n // token/credentials providers whenever the resource config carries no `Auth`\n // block — the shape `getAmplifyDataClientConfig()` produces for IAM-authed\n // Data access from a Lambda (`API.GraphQL` only, plus a custom\n // `credentialsProvider`). `AuthClass.configure()` tolerates an undefined\n // auth resource config.\n //\n // The `Auth!` assertion is deliberately false: in the very case this fixes,\n // `Auth` IS undefined at runtime. It mirrors the identical assertion in the\n // singleton rather than widening `AuthClass.configure()`'s parameter type.\n const auth = new AuthClass();\n auth.configure(resolvedResourceConfig.Auth, resolvedLibraryOptions.Auth);\n const ctx = {\n // Already deep-frozen above (both parse paths).\n resourcesConfig: resolvedResourceConfig,\n libraryOptions: resolvedLibraryOptions,\n // Unique, frozen per-context identity handle (see AmplifyContextToken).\n // Attached before the brand/freeze below so the frozen context carries it.\n token: createAmplifyContextToken(),\n fetchAuthSession: fetchOptions => auth.fetchAuthSession(fetchOptions ?? {}),\n clearCredentials: () => auth.clearCredentials(),\n getTokens: tokenOptions => auth.getTokens(tokenOptions),\n };\n // Brand the context for runtime identification by isAmplifyContext().\n Object.defineProperty(ctx, AMPLIFY_CONTEXT_BRAND, {\n value: true,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n Object.freeze(ctx);\n return ctx;\n}\n"],"names":[],"mappings":";;;;;;AAAA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,oBAAoB,CAAC,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,sBAAsB,GAAG,UAAU,CAAC,eAAe,EAAE;AAC/D,UAAU;AACV,UAAU,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAC7C,IAAI,MAAM,sBAAsB,GAAG,cAAc,IAAI,EAAE;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,IAAI,GAAG,IAAI,SAAS,EAAE;AAChC,IAAI,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,IAAI,EAAE,sBAAsB,CAAC,IAAI,CAAC;AAC5E,IAAI,MAAM,GAAG,GAAG;AAChB;AACA,QAAQ,eAAe,EAAE,sBAAsB;AAC/C,QAAQ,cAAc,EAAE,sBAAsB;AAC9C;AACA;AACA,QAAQ,KAAK,EAAE,yBAAyB,EAAE;AAC1C,QAAQ,gBAAgB,EAAE,YAAY,IAAI,IAAI,CAAC,gBAAgB,CAAC,YAAY,IAAI,EAAE,CAAC;AACnF,QAAQ,gBAAgB,EAAE,MAAM,IAAI,CAAC,gBAAgB,EAAE;AACvD,QAAQ,SAAS,EAAE,YAAY,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC;AAC/D,KAAK;AACL;AACA,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,qBAAqB,EAAE;AACtD,QAAQ,KAAK,EAAE,IAAI;AACnB,QAAQ,UAAU,EAAE,KAAK;AACzB,QAAQ,YAAY,EAAE,KAAK;AAC3B,QAAQ,QAAQ,EAAE,KAAK;AACvB,KAAK,CAAC;AACN,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;AACtB,IAAI,OAAO,GAAG;AACd;;;;"}