{"version":3,"file":"base.mjs","names":[],"sources":["../../src/auth/base.ts"],"sourcesContent":["import type { AuthContext, BetterAuthOptions } from \"@better-auth/core\";\nimport { runWithAdapter } from \"@better-auth/core/context\";\nimport { BASE_ERROR_CODES, BetterAuthError } from \"@better-auth/core/error\";\nimport { getEndpoints, router } from \"../api\";\nimport { getTrustedOrigins, getTrustedProviders } from \"../context/helpers\";\nimport { createCookieGetter, getCookies } from \"../cookies\";\nimport type { Auth } from \"../types\";\nimport {\n\tgetBaseURL,\n\tgetOrigin,\n\tisDynamicBaseURLConfig,\n\tresolveBaseURL,\n} from \"../utils/url\";\n\nexport const createBetterAuth = <Options extends BetterAuthOptions>(\n\toptions: Options,\n\tinitFn: (options: Options) => Promise<AuthContext>,\n): Auth<Options> => {\n\tconst authContext = initFn(options);\n\tconst { api } = getEndpoints(authContext, options);\n\tconst errorCodes = options.plugins?.reduce((acc, plugin) => {\n\t\tif (plugin.$ERROR_CODES) {\n\t\t\treturn {\n\t\t\t\t...acc,\n\t\t\t\t...plugin.$ERROR_CODES,\n\t\t\t};\n\t\t}\n\t\treturn acc;\n\t}, {});\n\treturn {\n\t\thandler: async (request: Request) => {\n\t\t\tconst ctx = await authContext;\n\t\t\tconst basePath = ctx.options.basePath || \"/api/auth\";\n\n\t\t\tlet handlerCtx: AuthContext;\n\n\t\t\tif (isDynamicBaseURLConfig(options.baseURL)) {\n\t\t\t\t// Create per-request context to avoid concurrent request race conditions.\n\t\t\t\t// Each request may resolve to a different host, so we must not mutate the shared ctx.\n\t\t\t\thandlerCtx = Object.create(\n\t\t\t\t\tObject.getPrototypeOf(ctx),\n\t\t\t\t\tObject.getOwnPropertyDescriptors(ctx),\n\t\t\t\t) as AuthContext;\n\t\t\t\tconst baseURL = resolveBaseURL(options.baseURL, basePath, request);\n\t\t\t\tif (baseURL) {\n\t\t\t\t\thandlerCtx.baseURL = baseURL;\n\t\t\t\t\thandlerCtx.options = {\n\t\t\t\t\t\t...ctx.options,\n\t\t\t\t\t\tbaseURL: getOrigin(baseURL) || undefined,\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tthrow new BetterAuthError(\n\t\t\t\t\t\t\"Could not resolve base URL from request. Check your allowedHosts config.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// Use a typed variable so the baseURL override doesn't need\n\t\t\t\t// an unsafe cast — the spread is structurally BetterAuthOptions.\n\t\t\t\tconst trustedOriginOptions: BetterAuthOptions = {\n\t\t\t\t\t...handlerCtx.options,\n\t\t\t\t\tbaseURL: options.baseURL,\n\t\t\t\t};\n\t\t\t\thandlerCtx.trustedOrigins = await getTrustedOrigins(\n\t\t\t\t\ttrustedOriginOptions,\n\t\t\t\t\trequest,\n\t\t\t\t);\n\t\t\t\t// When crossSubDomainCookies is enabled, recompute cookies\n\t\t\t\t// per-request so the domain matches the resolved host.\n\t\t\t\tif (options.advanced?.crossSubDomainCookies?.enabled) {\n\t\t\t\t\thandlerCtx.authCookies = getCookies(handlerCtx.options);\n\t\t\t\t\thandlerCtx.createAuthCookie = createCookieGetter(handlerCtx.options);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\thandlerCtx = ctx;\n\t\t\t\t// Static config: resolve once from the first request when no\n\t\t\t\t// baseURL was provided. Mutates the shared ctx intentionally so\n\t\t\t\t// subsequent requests reuse the cached value.\n\t\t\t\t// NOTE: narrow race if the very first requests arrive concurrently —\n\t\t\t\t// both will enter this block and write to ctx. This is harmless\n\t\t\t\t// because they resolve the same value, and matches pre-existing\n\t\t\t\t// behavior. Using Object.create(ctx) here would break downstream\n\t\t\t\t// references that depend on ctx.options being mutated in-place.\n\t\t\t\tif (!ctx.options.baseURL) {\n\t\t\t\t\tconst baseURL = getBaseURL(\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tbasePath,\n\t\t\t\t\t\trequest,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tctx.options.advanced?.trustedProxyHeaders,\n\t\t\t\t\t);\n\t\t\t\t\tif (baseURL) {\n\t\t\t\t\t\tctx.baseURL = baseURL;\n\t\t\t\t\t\tctx.options.baseURL = getOrigin(ctx.baseURL) || undefined;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new BetterAuthError(\n\t\t\t\t\t\t\t\"Could not get base URL from request. Please provide a valid base URL.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\thandlerCtx.trustedOrigins = await getTrustedOrigins(\n\t\t\t\t\tctx.options,\n\t\t\t\t\trequest,\n\t\t\t\t);\n\t\t\t}\n\t\t\thandlerCtx.trustedProviders = await getTrustedProviders(\n\t\t\t\thandlerCtx.options,\n\t\t\t\trequest,\n\t\t\t);\n\n\t\t\tconst { handler } = router(handlerCtx, options);\n\t\t\treturn runWithAdapter(handlerCtx.adapter, () => handler(request));\n\t\t},\n\t\tapi,\n\t\toptions: options,\n\t\t$context: authContext,\n\t\t$ERROR_CODES: {\n\t\t\t...errorCodes,\n\t\t\t...BASE_ERROR_CODES,\n\t\t},\n\t} as any;\n};\n"],"mappings":";;;;;;;;AAcA,MAAa,oBACZ,SACA,WACmB;CACnB,MAAM,cAAc,OAAO,QAAQ;CACnC,MAAM,EAAE,QAAQ,aAAa,aAAa,QAAQ;AAUlD,QAAO;EACN,SAAS,OAAO,YAAqB;GACpC,MAAM,MAAM,MAAM;GAClB,MAAM,WAAW,IAAI,QAAQ,YAAY;GAEzC,IAAI;AAEJ,OAAI,uBAAuB,QAAQ,QAAQ,EAAE;AAG5C,iBAAa,OAAO,OACnB,OAAO,eAAe,IAAI,EAC1B,OAAO,0BAA0B,IAAI,CACrC;IACD,MAAM,UAAU,eAAe,QAAQ,SAAS,UAAU,QAAQ;AAClE,QAAI,SAAS;AACZ,gBAAW,UAAU;AACrB,gBAAW,UAAU;MACpB,GAAG,IAAI;MACP,SAAS,UAAU,QAAQ,IAAI;MAC/B;UAED,OAAM,IAAI,gBACT,2EACA;IAIF,MAAM,uBAA0C;KAC/C,GAAG,WAAW;KACd,SAAS,QAAQ;KACjB;AACD,eAAW,iBAAiB,MAAM,kBACjC,sBACA,QACA;AAGD,QAAI,QAAQ,UAAU,uBAAuB,SAAS;AACrD,gBAAW,cAAc,WAAW,WAAW,QAAQ;AACvD,gBAAW,mBAAmB,mBAAmB,WAAW,QAAQ;;UAE/D;AACN,iBAAa;AASb,QAAI,CAAC,IAAI,QAAQ,SAAS;KACzB,MAAM,UAAU,WACf,QACA,UACA,SACA,QACA,IAAI,QAAQ,UAAU,oBACtB;AACD,SAAI,SAAS;AACZ,UAAI,UAAU;AACd,UAAI,QAAQ,UAAU,UAAU,IAAI,QAAQ,IAAI;WAEhD,OAAM,IAAI,gBACT,wEACA;;AAGH,eAAW,iBAAiB,MAAM,kBACjC,IAAI,SACJ,QACA;;AAEF,cAAW,mBAAmB,MAAM,oBACnC,WAAW,SACX,QACA;GAED,MAAM,EAAE,YAAY,OAAO,YAAY,QAAQ;AAC/C,UAAO,eAAe,WAAW,eAAe,QAAQ,QAAQ,CAAC;;EAElE;EACS;EACT,UAAU;EACV,cAAc;GACb,GA/FiB,QAAQ,SAAS,QAAQ,KAAK,WAAW;AAC3D,QAAI,OAAO,aACV,QAAO;KACN,GAAG;KACH,GAAG,OAAO;KACV;AAEF,WAAO;MACL,EAAE,CAAC;GAwFJ,GAAG;GACH;EACD"}