import { merge } from "../../lib/merge" ; import type { InternalProvider } from "../../lib/types" ; import type { Provider } from "../../providers" ; import type { InternalUrl } from "../../lib/parse-url" ; /**
 * Adds `signinUrl` and `callbackUrl` to each provider
 * and deep merge user-defined options.
 */ export default function parseProviders ( params ) { const { url , providerId } = params ; const providers = params . providers . map ( ( { options , ... rest } ) => { const defaultOptions = normalizeProvider ( rest as Provider ) ; const userOptions = normalizeProvider ( options as Provider ) ; return merge ( defaultOptions , { ... userOptions , signinUrl : `${ url }/signin/${ userOptions ?. id ?? rest . id }` , callbackUrl : `${ url }/callback/${ userOptions ?. id ?? rest . id }` , } ) ; } ) ; const provider = providers . find ( ( { id } ) => id === providerId ) ; return { providers , provider } ; } function normalizeProvider ( provider ? ) { if ( ! provider ) return ; const normalized = Object . entries ( provider ) . reduce < InternalProvider > ( ( acc , [ key , value ] ) => { if ( [ "authorization" , "token" , "userinfo" ] . includes ( key ) && typeof value === "string" ) { const url = new URL ( value ) ; acc [ key ] = { url : `${ url . origin }${ url . pathname }` , params : Object . fromEntries ( url . searchParams ?? [ ] ) , } ; } else { acc [ key ] = value ; } return acc ; } , { } as any ) ; if ( normalized . type === "oauth" && ! normalized . version ?. startsWith ( "1." ) ) { normalized . idToken = Boolean ( normalized . idToken ?? normalized . wellKnown ?. includes ( "openid-configuration" ) ?? normalized . authorization ?. params ?. scope ?. includes ( "openid" ) ) ; if ( ! normalized . checks ) normalized . checks = [ "state" ] ; } return normalized ; }