/**
 * Auth configuration for @agentuity/auth.
 *
 * Provides sensible defaults and wraps BetterAuth with Agentuity-specific helpers.
 *
 * @module agentuity/config
 */
import { betterAuth } from 'better-auth';
import { drizzleAdapter } from 'better-auth/adapters/drizzle';
import { organization, jwt, bearer } from 'better-auth/plugins';
import { apiKey } from '@better-auth/api-key';
import { createPostgresDrizzle } from '@agentuity/drizzle';
import * as authSchema from "../schema.js";
export { DEFAULT_API_KEY_OPTIONS } from "./plugins/index.js";
import { DEFAULT_API_KEY_OPTIONS } from "./plugins/index.js";
/**
 * Safely parse a URL and return its origin, or undefined if invalid.
 */
function safeOrigin(url) {
    if (!url)
        return undefined;
    try {
        return new URL(url).origin;
    }
    catch {
        return undefined;
    }
}
/**
 * Parse a domain or URL into an origin.
 * Handles both full URLs (https://example.com) and bare domains (example.com).
 * Bare domains default to https:// scheme.
 */
function parseOriginLike(value) {
    const trimmed = value.trim();
    if (!trimmed)
        return undefined;
    // If it looks like a URL with scheme, parse as-is
    if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(trimmed)) {
        return safeOrigin(trimmed);
    }
    // Otherwise, treat as host[:port] and assume https
    return safeOrigin(`https://${trimmed}`);
}
/**
 * Resolve the base URL for the auth instance.
 *
 * Priority:
 * 1. Explicit `baseURL` option
 * 2. `AGENTUITY_CLOUD_BASE_URL` env var (Agentuity platform-injected for cloud deployments)
 * 3. `AGENTUITY_BASE_URL` env var (Agentuity platform-injected, legacy fallback)
 * 4. `BETTER_AUTH_URL` env var (BetterAuth standard, for 3rd party SDK compatibility)
 *
 * Empty or whitespace-only values are treated as missing and skipped.
 */
function resolveBaseURL(explicitBaseURL) {
    const candidates = [
        explicitBaseURL,
        process.env.AGENTUITY_CLOUD_BASE_URL,
        process.env.AGENTUITY_BASE_URL,
        process.env.BETTER_AUTH_URL,
    ];
    for (const candidate of candidates) {
        const trimmed = candidate?.trim();
        if (trimmed) {
            return trimmed;
        }
    }
    return undefined;
}
/**
 * Resolve the auth secret.
 *
 * Priority:
 * 1. Explicit `secret` option
 * 2. `AGENTUITY_AUTH_SECRET` env var (Agentuity convention)
 * 3. `BETTER_AUTH_SECRET` env var (BetterAuth standard, for backward compatibility)
 */
function resolveSecret(explicitSecret) {
    return explicitSecret ?? process.env.AGENTUITY_AUTH_SECRET ?? process.env.BETTER_AUTH_SECRET;
}
/**
 * Create the default trustedOrigins function for Agentuity deployments.
 *
 * This provides zero-config CORS/origin handling:
 * - Trusts the resolved baseURL origin
 * - Trusts the AGENTUITY_BASE_URL origin
 * - Trusts all domains from AGENTUITY_CLOUD_DOMAINS (platform-set, comma-separated)
 * - Trusts additional domains from AUTH_TRUSTED_DOMAINS (developer-set, comma-separated)
 * - Trusts the same-origin of incoming requests (request.url.origin)
 *
 * @param baseURL - The resolved base URL for the auth instance
 */
function createDefaultTrustedOrigins(baseURL) {
    const agentuityURL = process.env.AGENTUITY_BASE_URL;
    const cloudDomains = process.env.AGENTUITY_CLOUD_DOMAINS;
    const devTrustedDomains = process.env.AUTH_TRUSTED_DOMAINS;
    const staticOrigins = new Set();
    const baseOrigin = safeOrigin(baseURL);
    if (baseOrigin)
        staticOrigins.add(baseOrigin);
    const agentuityOrigin = safeOrigin(agentuityURL);
    if (agentuityOrigin)
        staticOrigins.add(agentuityOrigin);
    // Platform-set cloud domains (deployment, project, PR, custom domains, tunnels)
    if (cloudDomains) {
        for (const raw of cloudDomains.split(',')) {
            const origin = parseOriginLike(raw);
            if (origin)
                staticOrigins.add(origin);
        }
    }
    // Developer-set additional trusted domains
    if (devTrustedDomains) {
        for (const raw of devTrustedDomains.split(',')) {
            const origin = parseOriginLike(raw);
            if (origin)
                staticOrigins.add(origin);
        }
    }
    return async (request) => {
        const origins = new Set(staticOrigins);
        if (request) {
            const requestOrigin = safeOrigin(request.url);
            if (requestOrigin)
                origins.add(requestOrigin);
        }
        return [...origins];
    };
}
/**
 * Default plugins included with Agentuity auth.
 *
 * @param apiKeyOptions - API key plugin options, or false to disable
 */
export function getDefaultPlugins(apiKeyOptions) {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const plugins = [
        organization(),
        jwt({
            jwt: {
                definePayload: ({ user, session }) => ({
                    sub: user.id,
                    email: user.email,
                    name: user.name,
                    emailVerified: user.emailVerified,
                    createdAt: user.createdAt,
                    updatedAt: user.updatedAt,
                    sessionId: session.id,
                    activeOrganizationId: session.activeOrganizationId,
                    // Deliberately exclude user.image to keep JWT tokens small.
                    // Profile images (especially base64-encoded data URIs from OAuth)
                    // can significantly bloat the token. Consumers should fetch the
                    // image separately via the user API if needed.
                }),
            },
        }),
        bearer(),
    ];
    // Add API key plugin unless explicitly disabled
    if (apiKeyOptions !== false) {
        const opts = { ...DEFAULT_API_KEY_OPTIONS, ...apiKeyOptions };
        if (opts.enabled) {
            plugins.push(apiKey({
                apiKeyHeaders: opts.apiKeyHeaders,
                enableSessionForAPIKeys: opts.enableSessionForAPIKeys,
                defaultPrefix: opts.defaultPrefix,
                defaultKeyLength: opts.defaultKeyLength,
                enableMetadata: opts.enableMetadata,
            }));
        }
    }
    return plugins;
}
/**
 * Create an Auth instance.
 *
 * This wraps BetterAuth with sensible defaults for Agentuity projects:
 * - Default basePath: '/api/auth'
 * - Email/password authentication enabled by default
 * - Organization plugin for multi-tenancy
 * - JWT plugin for token-based auth
 * - Bearer plugin for API auth
 * - API Key plugin for programmatic access
 * - Experimental joins enabled by default for better performance
 *
 * @example Option A: Connection string (simplest)
 * ```typescript
 * import { createAuth } from '@agentuity/auth';
 *
 * export const auth = createAuth({
 *   connectionString: process.env.DATABASE_URL,
 * });
 * ```
 *
 * @example Option B: Bring your own Drizzle
 * ```typescript
 * import { drizzle } from 'drizzle-orm/bun-sql';
 * import { drizzleAdapter } from 'better-auth/adapters/drizzle';
 * import * as authSchema from '@agentuity/auth/schema';
 *
 * const schema = { ...authSchema, ...myAppSchema };
 * const db = drizzle(connectionString, { schema });
 *
 * export const auth = createAuth({
 *   database: drizzleAdapter(db, { provider: 'pg', schema: authSchema }),
 * });
 * ```
 *
 * @example Option C: Other adapters (Prisma, MongoDB, etc.)
 * ```typescript
 * import { prismaAdapter } from 'better-auth/adapters/prisma';
 *
 * export const auth = createAuth({
 *   database: prismaAdapter(new PrismaClient()),
 * });
 * ```
 */
export function createAuth(options) {
    const { skipDefaultPlugins, plugins = [], apiKey: apiKeyOptions, connectionString, ...restOptions } = options;
    const resolvedBaseURL = resolveBaseURL(typeof restOptions.baseURL === 'string' ? restOptions.baseURL : undefined);
    const resolvedSecret = resolveSecret(restOptions.secret);
    // Apply Agentuity defaults
    const basePath = restOptions.basePath ?? '/api/auth';
    const emailAndPassword = restOptions.emailAndPassword ?? { enabled: true };
    // Handle trustedOrigins - filter out undefined values from user input
    let trustedOrigins;
    if (restOptions.trustedOrigins) {
        const userOrigins = restOptions.trustedOrigins;
        if (typeof userOrigins === 'function') {
            // Wrap the function to filter undefined values from its result
            trustedOrigins = async (request) => {
                const result = await userOrigins(request);
                return result.filter((origin) => origin !== undefined);
            };
        }
        else {
            // Filter undefined values from static array
            trustedOrigins = userOrigins.filter((origin) => origin !== undefined);
        }
    }
    else {
        trustedOrigins = createDefaultTrustedOrigins(resolvedBaseURL);
    }
    const defaultPlugins = skipDefaultPlugins ? [] : getDefaultPlugins(apiKeyOptions);
    // Handle database configuration
    let database = restOptions.database;
    // ConnectionString provided — use createPostgresDrizzle (defaults to pg driver
    // with resilient PostgresPool for automatic reconnection).
    // See: https://github.com/agentuity/sdk/issues/1030
    if (connectionString && !database) {
        const { db } = createPostgresDrizzle({
            connectionString,
            schema: authSchema,
        });
        database = drizzleAdapter(db, {
            provider: 'pg',
            schema: authSchema,
        });
    }
    // Default experimental.joins to true for better performance
    const experimental = {
        joins: true,
        ...restOptions.experimental,
    };
    const authInstance = betterAuth({
        ...restOptions,
        database,
        basePath,
        emailAndPassword,
        experimental,
        ...(resolvedBaseURL ? { baseURL: resolvedBaseURL } : {}),
        ...(resolvedSecret ? { secret: resolvedSecret } : {}),
        trustedOrigins,
        plugins: [...defaultPlugins, ...plugins],
    });
    return authInstance;
}
//# sourceMappingURL=config.js.map