{"version":3,"file":"index.cjs","names":["#hooks","#hookRegistry","#states","#server","#stack","#pluginRegistry","#hookRegistry","#insideBeforePluginRegister","#providerRegistry","#extractorService","#omssServer","#entries","#handlers","#hookRegistry","#core","#middleware","#inFlight","#cleaningFunction","#internalGetSources","#getInFlightKey","#providers","#providerRegistry","#hookRegistry","#middleware","#insideBeforeProviderRegister","#extractorRegistry","#hookRegistry","#insideBeforeRegisterExtractor","#extractors","#config"],"sources":["../src/features/hooks/HookRegistry.ts","../src/features/hooks/HookService.ts","../src/features/plugins/plugin-state.ts","../src/utils/error.ts","../src/utils/regexp.ts","../src/utils/utils.ts","../src/features/plugins/PluginRegistry.ts","../src/features/plugins/PluginService.ts","../src/features/resolvers/utils.ts","../src/features/providers/ProviderResultEmitter.ts","../src/features/source/SourceCore.ts","../src/utils/AsyncDeduper.ts","../src/utils/middleware.ts","../src/features/source/SourceService.ts","../src/features/providers/ProviderRegistry.ts","../src/features/providers/ProviderService.ts","../src/features/extractors/ExtractorService.ts","../src/features/extractors/ExtractorRegistry.ts","../src/core/server.ts","../src/features/providers/BaseProvider.ts","../src/features/resolvers/BaseResolver.ts"],"sourcesContent":["/**\n * Hook Registry\n *\n * Manages lifecycle hooks for OMSS events.\n */\nexport class HookRegistry<T> {\n    /**\n     * Map storing arrays of hook handlers for each hook name.\n     */\n    readonly #hooks = new Map<keyof T, unknown[]>()\n\n    /**\n     * Get all registered hooks immutable.\n     * @dangerous - Be careful with this. what you are doing might cause side effects.\n     */\n    get hooks(): ReadonlyMap<keyof T, unknown[]> {\n        return this.#hooks\n    }\n\n    /**\n     * Clear all registered hooks.\n     * @dangerous - Be careful with this. Might cause side effects.\n     */\n    reset(): void {\n        return this.#hooks.clear()\n    }\n\n    /**\n     * Run all hooks for a lifecycle event with the provided payload.\n     *\n     * @typeParam K - The name of the hook to run.\n     * @param name - The hook name (key of THooks).\n     * @param payload - The payload to pass to each hook handler.\n     */\n    async run<K extends keyof T>(name: K, payload: T[K] extends (payload: infer P) => unknown ? P : never): Promise<void> {\n        const fns = this.#hooks.get(name) ?? []\n\n        for (const fn of fns) {\n            await (fn as (payload: unknown) => void | Promise<void>)(payload)\n        }\n    }\n\n    /**\n     * Add a hook handler for a lifecycle event.\n     * @param name - The hook name (key of THooks).\n     * @param cb - The hook handler function.\n     */\n    add<K extends keyof T>(name: K, cb: T[K]): void {\n        const existing = this.#hooks.get(name) ?? []\n\n        this.#hooks.set(name, [...existing, cb])\n    }\n}\n","import { HookRegistry } from '@/features/hooks/HookRegistry.js'\n\nexport class HookService<T> {\n    readonly #hookRegistry: HookRegistry<T>\n\n    constructor(hookRegistry: HookRegistry<T> = new HookRegistry<T>()) {\n        this.#hookRegistry = hookRegistry\n    }\n\n    /**\n     * Get all registered hooks immutable. TO ADD HOOKS, USE THE ADD METHOD\n     * @dangerous - Be careful with this. what you are doing might cause side effects.\n     */\n    get hooks(): ReadonlyMap<keyof T, unknown[]> {\n        return this.#hookRegistry.hooks\n    }\n\n    /**\n     * Register a hook for a lifecycle event.\n     *\n     * @typeParam K - The name of the hook to register.\n     * @param name - The hook name (key of THooks).\n     * @param cb - The handler function for this hook.\n     */\n    add<K extends keyof T>(name: K, cb: T[K]): ReturnType<HookRegistry<T>['add']> {\n        this.#hookRegistry.add(name, cb)\n    }\n\n    /**\n     * Clear all registered hooks.\n     * @dangerous - Be careful with this. Might cause side effects.\n     */\n    reset(): ReturnType<HookRegistry<T>['reset']> {\n        return this.#hookRegistry.reset()\n    }\n\n    /**\n     * Get the hook registry.\n     *\n     * This is only exposed for internal purposes and should not be accessed in consumer projects.\n     * @dangerous\n     * @internal\n     */\n    __getRegistry(): HookRegistry<T> {\n        return this.#hookRegistry\n    }\n}\n","/**\n * The states of which a plugin can be.\n */\nexport enum PluginState {\n    Registering,\n    Registered,\n    Unavailable,\n}\n","/**\n * Base class for all OMSS framework errors.\n * Use `instanceof OMSSError` to catch any framework error.\n * Always throw a specific subclass, never this directly.\n * Cause is not standardized and may change frequently.\n */\nexport class OMSSError extends Error {\n    /**\n     * Create a new OMSSError.\n     * @param message - Error message\n     * @param options - Additional options for the error\n     */\n    constructor(message: string, options?: { cause?: unknown }) {\n        super(message, options)\n        this.name = this.constructor.name\n    }\n}\n\n/**\n * Returned when an error gets Returned in the OMSSServer class.\n *\n * @example\n * return ERR(OMSSServerError('config.name must be a non-empty string', {cause: config}))\n */\nexport class OMSSServerError extends OMSSError {}\n\n/**\n * Returned during plugin registration or execution.\n *\n * @example\n * return ERR(OMSSPluginError(`Plugin \"${name}\" is already registered`, { cause: plugin }))\n */\nexport class OMSSPluginError extends OMSSError {}\n\n/**\n * Returned during resolver registration or ID resolution.\n *\n * @example\n * return ERR(OMSSResolverError(`No resolver found for namespace \"xyz\"`, { cause: rawId }))\n */\nexport class OMSSResolverError extends OMSSError {}\n\n/**\n * Returned during provider registration or source fetching.\n *\n * @example\n * return ERR(OMSSProviderError('Provider must have at least one resolver', { cause: provider }))\n */\nexport class OMSSProviderError extends OMSSError {}\n\n/**\n * Returned when an extractor fails to extract the media from a host.\n *\n * @example\n * return ERR(OMSSExtractor('Failed to extract media from host due to host changes', { cause: html }))\n */\nexport class OMSSExtractorError extends OMSSError {}\n\n/**\n * Returned when something/several things fail during source gathering.\n *\n * @example\n * return ERR(OMSSSourceGatheringError('Failed to gather sources', { cause: providerResults }))\n */\nexport class OMSSSourceGatheringError extends OMSSError {}\n","/**\n * Regex for validating namespace names.\n */\nconst SAFE_UNIQUE_STRING_PATTERN = '[a-z0-9-]+'\nexport const SAFE_UNIQUE_STRING = new RegExp(`^${SAFE_UNIQUE_STRING_PATTERN}$`)\n\n/**\n * Regex for matching media formats by keyword or file extension.\n *\n * Matches:\n * - format keywords (`hls`, `dash`, `mp4`, etc.)\n * - common media file extensions\n * - extensions followed by URL query strings, fragments, paths, or the end of the URL\n */\nexport const HLS_REGEX = /\\bhls\\b|\\.(?:m3u8|ts)(?:$|[\\/?#])/i\nexport const MP4_REGEX = /\\bmp4\\b|\\.mp4(?:$|[\\/?#])/i\nexport const DASH_REGEX = /\\bdash\\b|\\.(?:mpd|m4a)(?:$|[\\/?#])/i\nexport const MKV_REGEX = /\\bmkv\\b|\\.mkv(?:$|[\\/?#])/i\nexport const VTT_REGEX = /\\bvtt\\b|\\.vtt(?:$|[\\/?#])/i\nexport const SRT_REGEX = /\\bsrt\\b|\\.srt(?:$|[\\/?#])/i\n\n/**\n * Regex for validating a single catalog entry value.\n *\n * A catalog entry must be either exactly `\"*\"` (wildcard — provider supports\n * all IDs in the namespace) or a safe unique string.\n *\n * Mixing `\"*\"` with other entries in the same catalog array is not allowed\n * and is validated separately at registration time.\n */\nexport const CATALOG_ENTRY = new RegExp(`^(?:\\\\*|${SAFE_UNIQUE_STRING_PATTERN})$`)\n","import { Result } from '@/types/utils.js'\nimport { OMSSError } from '@/utils/error.js'\nimport { SAFE_UNIQUE_STRING } from '@/utils/regexp.js'\n\n/**\n * Convenience factory for a successful result.\n */\nexport function OK(): Result<void, never>\nexport function OK<T>(value: T): Result<T, never>\n\nexport function OK(value?: unknown) {\n    if (arguments.length === 0) {\n        return { ok: true }\n    }\n\n    return { ok: true, value }\n}\n/**\n * Convenience factory for a failed result.\n */\nexport const ERR = <E extends Error>(error: E): Result<never, E> => ({ ok: false, error })\n\ntype ErrorConstructor<T extends OMSSError> = new (message: string, options?: { cause?: Error }) => T\n\n/**\n * Validate a string is safe for use as a unique identifier (only lowercase letters, numbers, and hyphens).\n * @param value - The string to validate\n * @param name - The name of the identifier, for error messages\n * @param ErrorType - The error type to return if validation fails\n */\nexport function validateSafeUniqueString<T extends OMSSError>(value: string, name: string, ErrorType: ErrorConstructor<T>): Result<void, T> {\n    if (!SAFE_UNIQUE_STRING.test(value)) {\n        return ERR(new ErrorType(`Invalid ${name} \"${value}\". Expected only letters (lowercase), numbers, and hyphens.`))\n    }\n\n    return OK()\n}\n","import type { OMSSConfiguredPluginType, OMSSPluginOptions, OMSSPluginType, UnknownPluginType } from '@/types/plugin.js'\nimport OMSSServer from '@/core/server.js'\nimport { PluginState } from '@/features/plugins/plugin-state.js'\nimport { OMSSPluginError } from '@/utils/error.js'\nimport { Result } from '@/types/utils.js'\nimport { ERR, OK } from '@/utils/utils.js'\n\n/**\n * Registry responsible for executing and managing OMSS Plugins.\n *\n * Plugins are executed when added.\n */\nexport class PluginRegistry {\n    /**\n     * States of plugin x\n     */\n    readonly #states = new Map<UnknownPluginType, PluginState>()\n    readonly #server: OMSSServer\n\n    /**\n     * Registration stack used for circular dependency detection.\n     */\n    readonly #stack: UnknownPluginType[] = []\n\n    constructor(server: OMSSServer) {\n        this.#server = server\n    }\n\n    async add(plugin: OMSSPluginType): Promise<Result<PluginState.Registered, OMSSPluginError>>\n\n    async add<T>(plugin: OMSSConfiguredPluginType<T>, options: OMSSPluginOptions<T>): Promise<Result<PluginState.Registered, OMSSPluginError>>\n\n    /**\n     * Adds and runs a plugin with its options.\n     *\n     * @typeParam T - Plugin options type.\n     * @param plugin - The plugin function to register.\n     * @param options - Plugin options or a factory function that resolves options.\n     */\n    async add(plugin: UnknownPluginType, options?: unknown): Promise<Result<PluginState.Registered, OMSSPluginError>> {\n        // Check whether this plugin is already known\n        const state = this.#states.get(plugin)\n\n        if (state === PluginState.Registering) {\n            const chain = [...this.#stack, plugin].map((p) => p.name).join(' -> ')\n\n            return ERR(new OMSSPluginError(`Circular plugin dependency detected: ${chain}`))\n        }\n\n        if (state === PluginState.Registered) {\n            return ERR(new OMSSPluginError(`Plugin \"${plugin.name}\" is already registered`))\n        }\n\n        // Start registering\n        this.#states.set(plugin, PluginState.Registering)\n        this.#stack.push(plugin)\n\n        // Build options if a factory function is provided\n        const resolved = typeof options === 'function' ? (options as (server: OMSSServer) => unknown)(this.#server) : options\n\n        try {\n            // Check if the plugin has a single argument\n            if (plugin.length === 1) {\n                // execute the plugin with the server instance\n                await (plugin as OMSSPluginType)(this.#server)\n            } else {\n                // execute the plugin with the server instance and resolved options\n                await plugin(this.#server, resolved)\n            }\n\n            this.#states.set(plugin, PluginState.Registered)\n            return OK(PluginState.Registered)\n        } catch (err) {\n            this.#states.delete(plugin)\n            return ERR(err instanceof OMSSPluginError ? err : new OMSSPluginError(String(err), { cause: err }))\n        } finally {\n            this.#stack.pop()\n        }\n    }\n\n    /**\n     * Get the current plugin state.\n     */\n    getState<T>(plugin: UnknownPluginType | OMSSPluginType | OMSSConfiguredPluginType<T>): PluginState {\n        return this.#states.get(plugin as UnknownPluginType) ?? PluginState.Unavailable\n    }\n}\n","import { PluginRegistry } from '@/features/plugins/PluginRegistry.js'\nimport { HookRegistry } from '@/features/hooks/HookRegistry.js'\nimport type { OMSSConfiguredPluginType, OMSSPluginOptions, OMSSPluginType, UnknownPluginType } from '@/types/plugin.js'\nimport OMSSServer from '@/core/server.js'\nimport { ERR } from '@/utils/utils.js'\nimport { OMSSPluginError } from '@/utils/error.js'\nimport type { OMSSHooks } from '@/types/hooks.js'\n\n/**\n * The public API for managing OMSS plugins.\n */\nexport class PluginService {\n    readonly #pluginRegistry: PluginRegistry\n    readonly #hookRegistry: HookRegistry<OMSSHooks>\n    #insideBeforePluginRegister = false\n\n    constructor(omssServer: OMSSServer, pluginRegistry: PluginRegistry, hookRegistry: HookRegistry<OMSSHooks>) {\n        this.#pluginRegistry = pluginRegistry\n        this.#hookRegistry = hookRegistry\n    }\n\n    /**\n     * Register an OMSS plugin with no config into the system.\n     * @param plugin - Plugin function\n     */\n    async register(plugin: OMSSPluginType): ReturnType<PluginRegistry['add']>\n\n    /**\n     * Register an OMSS plugin with a config into the system.\n     * @param plugin - Plugin function\n     * @param options - Plugin configuration\n     */\n    async register<T>(plugin: OMSSConfiguredPluginType<T>, options: OMSSPluginOptions<T>): ReturnType<PluginRegistry['add']>\n\n    /**\n     * Registers an OMSS plugin that can take a config into the system, but does not need to.\n     * @param plugin - Plugin implementation\n     * @param options - Plugin configuration\n     */\n    async register(plugin: UnknownPluginType, options?: unknown): ReturnType<PluginRegistry['add']> {\n        if (this.#insideBeforePluginRegister) {\n            return ERR(new OMSSPluginError('Plugins cannot be registered during beforePluginRegister'))\n        }\n\n        this.#insideBeforePluginRegister = true\n        try {\n            await this.#hookRegistry.run('beforePluginRegister', { plugin: plugin as UnknownPluginType, options })\n        } finally {\n            this.#insideBeforePluginRegister = false\n        }\n\n        const result = await this.#pluginRegistry.add(plugin, options)\n\n        if (!result.ok) {\n            await this.#hookRegistry.run('pluginRegisterFailed', { plugin, options, error: result.error })\n            return result\n        }\n\n        await this.#hookRegistry.run('afterPluginRegister', { plugin, options })\n        return result\n    }\n\n    /**\n     * Get the current State of a plugin\n     * @param plugin - the plugin to get the state from\n     * @returns - a value of the PluginState enum\n     */\n    getPluginState(plugin: UnknownPluginType): ReturnType<PluginRegistry['getState']> {\n        return this.#pluginRegistry.getState(plugin)\n    }\n}\n","import type { OMSSId, ParsedOMSSId } from '@/types/resolver.js'\nimport { OMSSResolverError } from '@/utils/error.js'\nimport { Result } from '@/types/utils.js'\nimport { ERR, OK, validateSafeUniqueString } from '@/utils/utils.js'\n\n/**\n * Parses an OMSS ID in the form `namespace:value_1[:value_2[:...]]`.\n */\nexport function parseOMSSId(id: OMSSId): Result<ParsedOMSSId, OMSSResolverError> {\n    if (/\\s/.test(id)) {\n        return ERR(new OMSSResolverError(`Invalid OMSS ID \"${id}\": cannot contain whitespace`))\n    }\n\n    const parts = id.split(':')\n\n    if (parts.length < 2) {\n        return ERR(new OMSSResolverError(`Invalid OMSS ID \"${id}\": missing namespace separator \":\"`))\n    }\n\n    const [namespace, ...values] = parts\n\n    if (!namespace) {\n        return ERR(new OMSSResolverError(`Invalid OMSS ID \"${id}\": namespace cannot be empty`))\n    }\n\n    const req = validateSafeUniqueString(namespace, 'OMSS namespace', OMSSResolverError)\n\n    if (!req.ok) {\n        return ERR(req.error)\n    }\n\n    for (const [i, value] of values.entries()) {\n        if (value.length === 0) {\n            return ERR(new OMSSResolverError(`Invalid OMSS ID \"${id}\": value ${i + 1} cannot be empty`))\n        }\n    }\n\n    const decodedValues = values.map((value) => decodeURIComponent(value))\n\n    return OK({\n        namespace,\n        values: decodedValues,\n        raw: id,\n    })\n}\n","import {\r\n    EmittedSource,\r\n    EmittedSubtitle,\r\n    OMSSProviderResult,\r\n    ProviderResult,\r\n    ProviderResultEmitter,\r\n    Source,\r\n    SourceQuality,\r\n    SourceTypes,\r\n    Subtitle,\r\n    SubtitleFormat,\r\n    UnknownProvider,\r\n} from '@/types/provider.js'\r\nimport { OMSSProviderError } from '@/utils/error.js'\r\nimport { Result } from '@/types/utils.js'\r\nimport { ERR, OK } from '@/utils/utils.js'\r\nimport { HookRegistry } from '@/features/hooks/HookRegistry.js'\r\nimport { ProviderHooks } from '@/types/hooks.js'\r\nimport { DASH_REGEX, HLS_REGEX, MKV_REGEX, MP4_REGEX, SRT_REGEX, VTT_REGEX } from '@/utils/regexp.js'\r\nimport { CleaningFunction } from '@/types/source.js'\r\nimport { ParsedOMSSId } from '@/types/resolver.js'\r\n\r\n/**\r\n * Creates a fresh `ProviderResultEmitter` instance scoped to a single\r\n * `getSources()` execution.\r\n *\r\n * A new emitter MUST be created per provider call. Emitters hold internal,\r\n * mutable state (accumulated sources/subtitles/errors) via closures, so\r\n * reusing a single emitter across concurrent provider executions would\r\n * cause data from one provider to leak into another's response.\r\n *\r\n * @param provider - The provider instance for which this emitter is being created.\r\n * @param hookReg - The hook registry instance for managing hooks.\r\n * @param cleaningFunc - A function to clean up source/subtitle URLs and headers.\r\n * @param id - The parsed OMSS ID of the current request.\r\n * @returns A new `ProviderResultEmitter` bound to this execution.\r\n *\r\n */\r\nexport function createProviderResultEmitter(provider: Readonly<UnknownProvider>, hookReg: HookRegistry<ProviderHooks>, cleaningFunc: CleaningFunction, id: ParsedOMSSId): ProviderResultEmitter {\r\n    /**\r\n     * Accumulated sources emitted via `source()` during this execution.\r\n     * Flushed into the final result when `done()` is called.\r\n     */\r\n    const sources: Source[] = []\r\n\r\n    /**\r\n     * Accumulated subtitles emitted via `subtitle()` during this execution.\r\n     * Subtitles are intentionally NOT linked to any source or audio track,\r\n     * so they live in their own flat array regardless of how many sources\r\n     * were emitted.\r\n     */\r\n    const subtitles: Subtitle[] = []\r\n\r\n    /**\r\n     * Accumulated NON-fatal errors emitted via `error()` during this execution.\r\n     * These are returned alongside successful results (via `done()`) so\r\n     * that partial failures (e.g. \"server 2 of 3 failed\") don't discard\r\n     * otherwise-valid sources.\r\n     */\r\n    const errors: OMSSProviderError[] = []\r\n\r\n    return {\r\n        /**\r\n         * Utilities to make your life easier\r\n         */\r\n        utils: {\r\n            /**\r\n             * Utilities for parsing metadata of sources\r\n             */\r\n            source: {\r\n                /**\r\n                 * Parse a string into a possible source type.\r\n                 * @param possibleType - The string to parse\r\n                 */\r\n                parseType(possibleType: string): SourceTypes {\r\n                    if (HLS_REGEX.test(possibleType)) {\r\n                        return 'hls'\r\n                    } else if (MP4_REGEX.test(possibleType)) {\r\n                        return 'mp4'\r\n                    } else if (DASH_REGEX.test(possibleType)) {\r\n                        return 'dash'\r\n                    } else if (MKV_REGEX.test(possibleType)) {\r\n                        return 'mkv'\r\n                    } else {\r\n                        // most commonly used is hls\r\n                        return 'hls'\r\n                    }\r\n                },\r\n                /**\r\n                 * Parse a string into a possible source quality.\r\n                 * @param possibleQuality - The string to parse\r\n                 */\r\n                parseQuality(possibleQuality: string): SourceQuality {\r\n                    if (!possibleQuality) {\r\n                        return 'Auto'\r\n                    }\r\n\r\n                    const value = possibleQuality.toLowerCase().trim().replace(/_/g, ' ').replace(/-/g, ' ')\r\n\r\n                    // Direct quality labels / aliases\r\n                    if (/\\b(8k|uhd\\s*8k|4320p)\\b/.test(value)) {\r\n                        return '8K'\r\n                    }\r\n\r\n                    if (/\\b(4k|uhd|ultra\\s*hd|2160p)\\b/.test(value)) {\r\n                        return '4K'\r\n                    }\r\n\r\n                    if (/\\b(qhd|2k|1440p|2560x1440)\\b/.test(value)) {\r\n                        return 'QHD'\r\n                    }\r\n\r\n                    if (/\\b(fhd|full\\s*hd|1080p|1920x1080)\\b/.test(value)) {\r\n                        return 'FHD'\r\n                    }\r\n\r\n                    if (/\\b(hd|720p|1280x720)\\b/.test(value)) {\r\n                        return 'HD'\r\n                    }\r\n\r\n                    if (/\\b(sd|480p|576p|360p|240p)\\b/.test(value)) {\r\n                        return 'SD'\r\n                    }\r\n\r\n                    const resolutionMatch = value.match(/(\\d{3,4})(?:p|x\\d{3,4})?/)\r\n\r\n                    if (resolutionMatch) {\r\n                        const resolution = Number(resolutionMatch[1])\r\n\r\n                        if (resolution >= 4320) {\r\n                            return '8K'\r\n                        }\r\n\r\n                        if (resolution >= 2160) {\r\n                            return '4K'\r\n                        }\r\n\r\n                        if (resolution >= 1440) {\r\n                            return 'QHD'\r\n                        }\r\n\r\n                        if (resolution >= 1080) {\r\n                            return 'FHD'\r\n                        }\r\n\r\n                        if (resolution >= 720) {\r\n                            return 'HD'\r\n                        }\r\n\r\n                        if (resolution > 0) {\r\n                            return 'SD'\r\n                        }\r\n                    }\r\n\r\n                    const bitrateMatch = value.match(/(\\d+(?:\\.\\d+)?)\\s*(mbps|kbps)/)\r\n\r\n                    if (bitrateMatch) {\r\n                        const bitrate = Number(bitrateMatch[1])\r\n                        const unit = bitrateMatch[2]\r\n\r\n                        const mbps = unit === 'kbps' ? bitrate / 1000 : bitrate\r\n\r\n                        if (mbps >= 25) {\r\n                            return '4K'\r\n                        }\r\n\r\n                        if (mbps >= 8) {\r\n                            return 'FHD'\r\n                        }\r\n\r\n                        if (mbps >= 3) {\r\n                            return 'HD'\r\n                        }\r\n\r\n                        return 'SD'\r\n                    }\r\n\r\n                    return 'Auto'\r\n                },\r\n            },\r\n            /**\r\n             * Utilities for parsing metadata of subtitles\r\n             */\r\n            subtitle: {\r\n                /**\r\n                 * Parse a string into a possible subtitle format.\r\n                 * @param possibleFormat - The string to parse\r\n                 */\r\n                parseFormat(possibleFormat: string): SubtitleFormat {\r\n                    if (VTT_REGEX.test(possibleFormat)) {\r\n                        return 'vtt'\r\n                    } else if (SRT_REGEX.test(possibleFormat)) {\r\n                        return 'srt'\r\n                    } else {\r\n                        return 'vtt'\r\n                    }\r\n                },\r\n            },\r\n        },\r\n\r\n        /**\r\n         * Emits a custom, provider-defined action/event.\r\n         *\r\n         * @param action - A custom event name (e.g. \"cache.hit\").\r\n         * @param data - Arbitrary payload associated with the event.\r\n         */\r\n        emit(action: string, data: unknown): void {\r\n            // action cannot be whitespace or another hook name\r\n            if (/\\s/.test(action) || Object.keys(this).includes(action)) {\r\n                return\r\n            }\r\n            hookReg.run(action, { data, provider, id, timestamp: new Date().toISOString() })\r\n        },\r\n\r\n        /**\r\n         * Logs verbose debug information. Intended for development/troubleshooting\r\n         * only and should be stripped or gated behind a debug flag in production.\r\n         *\r\n         * @param args - Values to log, forwarded as-is (same semantics as `console.debug`).\r\n         */\r\n        debug(...args: unknown[]): void {\r\n            hookReg.run('debug', { provider, args, id, timestamp: new Date().toISOString() })\r\n        },\r\n\r\n        /**\r\n         * Logs general informational messages about provider execution\r\n         * (e.g. \"Fetched media\", \"Cache miss, fetching from upstream\").\r\n         *\r\n         * @param args - Values to log.\r\n         */\r\n        info(...args: unknown[]): void {\r\n            hookReg.run('info', { provider, args, id, timestamp: new Date().toISOString() })\r\n        },\r\n\r\n        /**\r\n         * Logs a non-fatal warning. Use this for degraded-but-recoverable\r\n         * situations (e.g. \"missing quality metadata, defaulting to Auto\").\r\n         *\r\n         * @param args - Values to log.\r\n         */\r\n        warn(...args: unknown[]): void {\r\n            hookReg.run('warn', { provider, args, id, timestamp: new Date().toISOString() })\r\n        },\r\n\r\n        /**\r\n         * Records a NON-fatal error. The provider continues executing after\r\n         * calling this — use `fatal()` instead if the provider cannot continue.\r\n         *\r\n         * The error is accumulated and returned to the requestor as part of\r\n         * the `diagnostics`/`errors` field once `done()` is called, allowing\r\n         * partial success (e.g. some sources found despite one upstream\r\n         * server failing).\r\n         *\r\n         * @param error - The error to record. Will be surfaced to the client.\r\n         */\r\n        error(error: OMSSProviderError): void {\r\n            errors.push(error)\r\n            hookReg.run('error', { provider, error, id, timestamp: new Date().toISOString() })\r\n        },\r\n\r\n        /**\r\n         * Emits a single resolved source.\r\n         *\r\n         * @param source - The fully-formed source object to emit.\r\n         */\r\n        source(source: EmittedSource): void {\r\n            const cleanedSource = {\r\n                ...source,\r\n            }\r\n\r\n            const cleaned = cleaningFunc({\r\n                url: cleanedSource.url,\r\n                header: cleanedSource.header,\r\n            })\r\n\r\n            cleanedSource.url = cleaned.url\r\n            cleanedSource.header = cleaned.header\r\n\r\n            if ('audioTracks' in cleanedSource && cleanedSource.audioTracks) {\r\n                // had to split first and rest, since audioTracks requires least one track.\r\n                const [first, ...rest] = cleanedSource.audioTracks\r\n\r\n                cleanedSource.audioTracks = [\r\n                    {\r\n                        ...first,\r\n                        ...cleaningFunc({\r\n                            url: first.url,\r\n                            header: first.header,\r\n                        }),\r\n                    },\r\n                    ...rest.map((track) => ({\r\n                        ...track,\r\n                        ...cleaningFunc({\r\n                            url: track.url,\r\n                            header: track.header,\r\n                        }),\r\n                    })),\r\n                ]\r\n            }\r\n            const fullSource: Source = {\r\n                ...cleanedSource,\r\n                provider: {\r\n                    id: provider.id,\r\n                    name: provider.name,\r\n                },\r\n            }\r\n\r\n            sources.push(fullSource)\r\n\r\n            hookReg.run('source', {\r\n                provider,\r\n                source: fullSource,\r\n                id,\r\n                timestamp: new Date().toISOString(),\r\n            })\r\n        },\r\n\r\n        /**\r\n         * Emits a single subtitle track.\r\n         *\r\n         * @param subtitle - The subtitle object to emit.\r\n         */\r\n        subtitle(subtitle: EmittedSubtitle): void {\r\n            const obj = {\r\n                url: subtitle.url,\r\n                header: subtitle.header,\r\n            }\r\n            const { url, header } = cleaningFunc(obj)\r\n            subtitle.url = url\r\n            subtitle.header = header\r\n            const fullSub = { ...subtitle, provider: { id: provider.id, name: provider.name } }\r\n            subtitles.push(fullSub)\r\n            hookReg.run('subtitle', { provider, subtitle: fullSub, id, timestamp: new Date().toISOString() })\r\n        },\r\n\r\n        /**\r\n         * Immediately aborts provider execution with a fatal error.\r\n         *\r\n         * @param error - The fatal error describing why the provider could not proceed.\r\n         * @returns An `ERR` result wrapping the given error.\r\n         */\r\n        fatal(error: OMSSProviderError): Result<never, OMSSProviderError> {\r\n            const accumulatedError = new AggregateError([error, ...errors], error.message, { cause: error.cause })\r\n\r\n            const finalErr = new OMSSProviderError(accumulatedError.message, { cause: accumulatedError })\r\n\r\n            hookReg.run('error', { provider, error: finalErr, id, timestamp: new Date().toISOString() })\r\n\r\n            return ERR(finalErr)\r\n        },\r\n\r\n        /**\r\n         * Signals that the provider has finished emitting sources/subtitles\r\n         * and finalizes the result.\r\n         *\r\n         * @returns An `OK` result containing all accumulated sources,\r\n         *          subtitles, and non-fatal errors for this execution.\r\n         */\r\n        done(): ProviderResult {\r\n            const result: OMSSProviderResult = {\r\n                sources,\r\n                subtitles,\r\n                errors,\r\n            }\r\n\r\n            hookReg.run('done', { provider, result, id, timestamp: new Date().toISOString() })\r\n\r\n            return OK(result)\r\n        },\r\n    }\r\n}\r\n","import OMSSServer from '@/core/server.js'\r\nimport { ProviderRegistry } from '@/features/providers/ProviderRegistry.js'\r\nimport { parseOMSSId } from '@/features/resolvers/utils.js'\r\nimport type { ProviderResult, Source, Subtitle, UnknownProvider } from '@/types/provider.js'\r\nimport type { OMSSId, ResolverExecutionContext } from '@/types/resolver.js'\r\nimport { CleaningFunction, GatheredSources, GetSourcesOptions } from '@/types/source.js'\r\nimport type { Result } from '@/types/utils.js'\r\nimport { OMSSProviderError, OMSSSourceGatheringError } from '@/utils/error.js'\r\nimport { ERR, OK } from '@/utils/utils.js'\r\nimport { createProviderResultEmitter } from '@/features/providers/ProviderResultEmitter.js'\r\nimport { ProviderHooks } from '@/types/hooks.js'\r\nimport { ExtractorService } from '@/features/extractors/ExtractorService.js'\r\nimport { HookService } from '@/features/hooks/HookService.js'\r\n\r\n/**\r\n * Internal source gathering core.\r\n *\r\n * Handles OMSS ID parsing, provider lookup, resolver-level deduplication,\r\n * provider execution, and final result aggregation.\r\n *\r\n * This class intentionally does not know about OMSS Hooks, middleware, or in-flight\r\n * request sharing. Those concerns belong to SourceService.\r\n */\r\nexport class SourceCore {\r\n    readonly #providerRegistry: ProviderRegistry\r\n    readonly #extractorService: ExtractorService\r\n    readonly #omssServer: OMSSServer\r\n\r\n    constructor(omssServer: OMSSServer, providerRegistry: ProviderRegistry, extractorService: ExtractorService) {\r\n        this.#omssServer = omssServer\r\n        this.#providerRegistry = providerRegistry\r\n        this.#extractorService = extractorService\r\n    }\r\n\r\n    /**\r\n     * Gather sources for a single OMSS ID.\r\n     *\r\n     * @param omssId - Raw OMSS identifier.\r\n     * @param opts - Optional source gathering parameters.\r\n     * @param providerHookRegistry - Hook registry for provider hooks.\r\n     * @param cleaningFunction - Optional custom function to clean url's and headers\r\n     * @returns Aggregated provider results or a source gathering error.\r\n     */\r\n    async getSources(\r\n        omssId: OMSSId,\r\n        opts: GetSourcesOptions,\r\n        providerHookRegistry: HookService<ProviderHooks>,\r\n        cleaningFunction: CleaningFunction\r\n    ): Promise<Result<GatheredSources, OMSSSourceGatheringError>> {\r\n        // try to parse the OMSS ID\r\n        const parsed = parseOMSSId(omssId)\r\n\r\n        if (!parsed.ok) {\r\n            return ERR(new OMSSSourceGatheringError(`Failed to parse OMSS id \"${omssId}\": ${parsed.error.message}`, { cause: parsed.error }))\r\n        }\r\n\r\n        // we know that the id is valid now. Now we got to find the providers that can handle that namespace. If a specific provider is requested, we only look for that one.\r\n        const providers: UnknownProvider[] = opts.providerId\r\n            ? this.#providerRegistry.getAll((p) => p.id === opts.providerId && p.resolver.namespace === parsed.value.namespace)\r\n            : this.#providerRegistry.getAll((p) => p.resolver.namespace === parsed.value.namespace)\r\n\r\n        // if no provider can handle that namespace, return an error\r\n        if (providers.length === 0) {\r\n            return ERR(new OMSSSourceGatheringError(`No providers found for namespace \"${parsed.value.namespace}\"` + (opts.providerId ? ` and provider \"${opts.providerId}\"` : '')))\r\n        }\r\n\r\n        // if no abortsignal comes, just create a new one (does not abort)\r\n        const signal = opts.abortSignal ?? new AbortController().signal\r\n\r\n        // create the resolver context\r\n        const ctx: ResolverExecutionContext = {\r\n            server: this.#omssServer,\r\n            signal,\r\n        }\r\n\r\n        /**\r\n         * Resolver-level deduplication: multiple providers that share the same\r\n         * resolver run that resolver only once, then share the result.\r\n         */\r\n        const resolverCache = new Map<string, Promise<Result<unknown, OMSSSourceGatheringError>>>()\r\n\r\n        /**\r\n         * Get resolver metadata for a provider, reusing the same resolver\r\n         * promise when multiple providers share the same resolver.\r\n         *\r\n         * @param provider - Provider whose resolver metadata should be loaded.\r\n         * @returns Resolver metadata or a source gathering error.\r\n         */\r\n        const getResolvedMeta = (provider: UnknownProvider): Promise<Result<unknown, OMSSSourceGatheringError>> => {\r\n            const resolverKey = `${provider.resolver.namespace}:${provider.resolver.name}`\r\n\r\n            let promise = resolverCache.get(resolverKey)\r\n\r\n            if (!promise) {\r\n                promise = (async (): Promise<Result<unknown, OMSSSourceGatheringError>> => {\r\n                    if (signal.aborted) {\r\n                        return ERR(new OMSSSourceGatheringError('Operation aborted'))\r\n                    }\r\n\r\n                    const result = await provider.resolver.resolve(parsed.value, ctx)\r\n\r\n                    if (!result.ok) {\r\n                        return ERR(new OMSSSourceGatheringError(`Resolver failed for ${resolverKey}: ${result.error.message}`, { cause: result.error }))\r\n                    }\r\n\r\n                    return OK(result.value)\r\n                })()\r\n\r\n                resolverCache.set(resolverKey, promise)\r\n            }\r\n\r\n            return promise\r\n        }\r\n\r\n        /**\r\n         * Resolve sources for a single provider.\r\n         *\r\n         * @param provider - Provider to execute.\r\n         * @returns Provider result or a source gathering error.\r\n         */\r\n        const resolveForProvider = async (provider: UnknownProvider): Promise<ProviderResult | Result<never, OMSSSourceGatheringError>> => {\r\n            if (signal.aborted) {\r\n                return ERR(new OMSSSourceGatheringError('Operation aborted'))\r\n            }\r\n\r\n            const supportsId = await provider.supportsId(parsed.value)\r\n            if (!supportsId) {\r\n                return OK({ sources: [], subtitles: [], errors: [new OMSSProviderError(`Provider \"${provider.id}\" did not support this id: \"${parsed.value.raw}\"`)] })\r\n            }\r\n\r\n            if (signal.aborted) {\r\n                return ERR(new OMSSSourceGatheringError('Operation aborted'))\r\n            }\r\n\r\n            const metaResult = await getResolvedMeta(provider)\r\n\r\n            if (!metaResult.ok) {\r\n                return metaResult\r\n            }\r\n\r\n            if (signal.aborted) {\r\n                return ERR(new OMSSSourceGatheringError('Operation aborted'))\r\n            }\r\n\r\n            const resultEmitter = createProviderResultEmitter(provider, providerHookRegistry.__getRegistry(), cleaningFunction, parsed.value)\r\n\r\n            return provider.getSources(\r\n                {\r\n                    utils: {\r\n                        omssId: parsed.value,\r\n                        abortSignal: signal,\r\n                        findExtractor: this.#extractorService.find,\r\n                    },\r\n                    meta: metaResult.value,\r\n                },\r\n                resultEmitter\r\n            )\r\n        }\r\n\r\n        const settled = await Promise.allSettled(providers.map((provider) => resolveForProvider(provider)))\r\n\r\n        if (signal.aborted) {\r\n            return ERR(new OMSSSourceGatheringError('Operation aborted'))\r\n        }\r\n\r\n        const allSources: Source[] = []\r\n        const allSubtitles: Subtitle[] = []\r\n        const unexpectedErrors: unknown[] = []\r\n        const omssErrors: Array<Extract<ProviderResult, { ok: false }>['error'] | OMSSSourceGatheringError> = []\r\n        let hasSuccess = false\r\n\r\n        for (const item of settled) {\r\n            if (item.status === 'rejected') {\r\n                omssErrors.push(\r\n                    new OMSSSourceGatheringError(`Provider execution failed: ${item.reason instanceof Error ? item.reason.message : String(item.reason)}`, {\r\n                        cause: item.reason instanceof Error ? item.reason : undefined,\r\n                    })\r\n                )\r\n                unexpectedErrors.push(item.reason)\r\n                continue\r\n            }\r\n\r\n            const res = item.value\r\n\r\n            if (res.ok) {\r\n                hasSuccess = true\r\n                allSources.push(...res.value.sources)\r\n                allSubtitles.push(...res.value.subtitles)\r\n                omssErrors.push(...res.value.errors)\r\n                continue\r\n            }\r\n\r\n            omssErrors.push(res.error)\r\n        }\r\n\r\n        if (!hasSuccess) {\r\n            return ERR(\r\n                new OMSSSourceGatheringError(`All providers failed for namespace \"${parsed.value.namespace}\" and id: \"${parsed.value.raw}\"`, {\r\n                    cause: new AggregateError([...omssErrors, ...unexpectedErrors], 'Multiple failures detected'),\r\n                })\r\n            )\r\n        }\r\n\r\n        return OK({\r\n            sources: allSources,\r\n            subtitles: allSubtitles,\r\n            errors: omssErrors,\r\n        })\r\n    }\r\n}\r\n","/**\n * Generic helper for deduplicating concurrent asynchronous work by key.\n *\n * When the same key is requested multiple times while a request is still in\n * flight, all callers receive the same Promise. Once the Promise settles, the\n * key is removed automatically so the next request starts fresh.\n *\n * @typeParam TKey - Cache key type.\n * @typeParam TValue - Promise resolution type.\n */\nexport class AsyncDeduper<TKey, TValue> {\n    readonly #entries = new Map<TKey, Promise<TValue>>()\n\n    /**\n     * Returns the current in-flight Promise for a key, if one exists.\n     *\n     * @param key - In-flight request key.\n     * @returns Existing Promise or undefined.\n     */\n    get(key: TKey): Promise<TValue> | undefined {\n        return this.#entries.get(key)\n    }\n\n    /**\n     * Check whether a key currently has an in-flight Promise.\n     *\n     * @param key - In-flight request key.\n     * @returns True if the key is currently in flight.\n     */\n    has(key: TKey): boolean {\n        return this.#entries.has(key)\n    }\n\n    /**\n     * Delete a key manually.\n     *\n     * @param key - In-flight request key.\n     * @returns True if an entry existed and was removed.\n     */\n    delete(key: TKey): boolean {\n        return this.#entries.delete(key)\n    }\n\n    /**\n     * Clear all tracked in-flight requests.\n     */\n    clear(): void {\n        this.#entries.clear()\n    }\n\n    /**\n     * Run a Promise factory for a key, reusing an existing in-flight Promise\n     * when available.\n     *\n     * @param key - In-flight request key.\n     * @param factory - Factory that creates the Promise when no request exists yet.\n     * @returns Shared or newly created Promise.\n     */\n    run(key: TKey, factory: () => Promise<TValue>): Promise<TValue> {\n        const existing = this.#entries.get(key)\n\n        if (existing) {\n            return existing\n        }\n\n        const promise = factory().finally(() => {\n            this.#entries.delete(key)\n        })\n\n        this.#entries.set(key, promise)\n\n        return promise\n    }\n}\n","import { MiddlewareHandler, MiddlewareOperationMap } from '@/types/middleware.js'\n\n/**\n * Reusable typed middleware runner.\n */\nexport class MiddlewareRunner<TOperations extends MiddlewareOperationMap> {\n    readonly #handlers: Partial<{\n        [K in keyof TOperations]: MiddlewareHandler<TOperations, K>[]\n    }> = {}\n\n    /**\n     * Register middleware for a specific operation.\n     *\n     * @param method - Operation name.\n     * @param handler - Middleware handler.\n     */\n    use<TMethod extends keyof TOperations>(method: TMethod, handler: MiddlewareHandler<TOperations, TMethod>): void {\n        const list = (this.#handlers[method] ??= []) as MiddlewareHandler<TOperations, TMethod>[]\n\n        list.push(handler)\n    }\n\n    /**\n     * Run middleware chain for a specific operation.\n     *\n     * @param method - Operation name.\n     * @param context - Operation context payload.\n     * @param finalHandler - Final function to execute after middleware.\n     * @returns The operation result.\n     */\n    run<TMethod extends keyof TOperations>(\n        method: TMethod,\n        context: TOperations[TMethod]['context'],\n        finalHandler: () => Promise<TOperations[TMethod]['result']>\n    ): Promise<TOperations[TMethod]['result']> {\n        const handlers = (this.#handlers[method] ?? []) as readonly MiddlewareHandler<TOperations, TMethod>[]\n\n        let index = -1\n\n        const dispatch = (position: number): Promise<TOperations[TMethod]['result']> => {\n            if (position <= index) {\n                return Promise.reject(new Error('next() called multiple times'))\n            }\n\n            index = position\n\n            const handler = handlers[position]\n\n            if (!handler) {\n                return finalHandler()\n            }\n\n            return handler(context, () => dispatch(position + 1))\n        }\n\n        return dispatch(0)\n    }\n}\n","import OMSSServer from '@/core/server.js'\nimport { HookRegistry } from '@/features/hooks/HookRegistry.js'\nimport { ProviderRegistry } from '@/features/providers/ProviderRegistry.js'\nimport { SourceCore } from '@/features/source/SourceCore.js'\nimport type { CleaningFunction, GatheredSources, GetSourcesOptions, SourceServiceMiddleware, SourceServiceOperations } from '@/types/source.js'\nimport type { OMSSId } from '@/types/resolver.js'\nimport type { Result } from '@/types/utils.js'\nimport { OMSSSourceGatheringError } from '@/utils/error.js'\nimport { AsyncDeduper } from '@/utils/AsyncDeduper.js'\nimport { MiddlewareRunner } from '@/utils/middleware.js'\nimport type { OMSSHooks, ProviderHooks } from '@/types/hooks.js'\nimport { ExtractorService } from '@/features/extractors/ExtractorService.js'\nimport { HookService } from '@/features/hooks/HookService.js'\n\n/**\n * Public API for resolving sources for media.\n *\n * This service owns the public method surface, middleware execution,\n * lifecycle hook dispatching, and request coalescing. The actual source\n * gathering implementation lives in {@link SourceCore}.\n */\nexport class SourceService {\n    readonly #hookRegistry: HookRegistry<OMSSHooks>\n    readonly #core: SourceCore\n\n    /**\n     * Middleware runner for SourceService operations.\n     */\n    readonly #middleware = new MiddlewareRunner<SourceServiceOperations>()\n\n    /**\n     * Deduplicates concurrent getSources requests by request key.\n     */\n    readonly #inFlight = new AsyncDeduper<string, Result<GatheredSources, OMSSSourceGatheringError>>()\n\n    constructor(omssServer: OMSSServer, providerRegistry: ProviderRegistry, hookRegistry: HookRegistry<OMSSHooks>, extractorService: ExtractorService) {\n        this.#hookRegistry = hookRegistry\n        this.#core = new SourceCore(omssServer, providerRegistry, extractorService)\n    }\n\n    public get cleaningFunction(): CleaningFunction {\n        return this.#cleaningFunction\n    }\n\n    public set cleaningFunction(fn: CleaningFunction) {\n        this.#cleaningFunction = fn\n    }\n\n    /**\n     * Register middleware for a SourceService method.\n     *\n     * Middleware can be used for cross-cutting concerns such as caching,\n     * logging, tracing, or metrics.\n     *\n     * @param method - Middleware-enabled method name.\n     * @param handler - Middleware handler.\n     */\n    use<TMethod extends keyof SourceServiceOperations>(method: TMethod, handler: SourceServiceMiddleware<TMethod>): void {\n        this.#middleware.use(method, handler)\n    }\n\n    /**\n     * Fetch sources from all matching providers for an OMSS ID.\n     *\n     * This method is middleware-enabled. Concurrent requests for the same\n     * `omssId` and `providerId` share the same in-flight Promise until the\n     * request settles.\n     *\n     * @param omssId - OMSS identifier such as `\"tmdb:12345\"`.\n     * @param options - Optional source gathering parameters.\n     * @returns Aggregated provider results or a source gathering error.\n     */\n    async getSources(omssId: OMSSId, options: GetSourcesOptions = {}): Promise<Result<GatheredSources, OMSSSourceGatheringError>> {\n        return this.#middleware.run('getSources', { omssId, options }, () => this.#internalGetSources(omssId, options))\n    }\n\n    /**\n     * Get and set the cleaning function for the source core.\n     */\n    #cleaningFunction: CleaningFunction = (obj) => obj\n\n    /**\n     * Internal wrapper around source gathering.\n     *\n     * Runs lifecycle hooks and deduplicates concurrent requests before\n     * delegating to {@link SourceCore}.\n     *\n     * @param omssId - OMSS identifier.\n     * @param options - Optional source gathering parameters.\n     * @returns Aggregated provider results or a source gathering error.\n     */\n    async #internalGetSources(omssId: OMSSId, options: GetSourcesOptions): Promise<Result<GatheredSources, OMSSSourceGatheringError>> {\n        await this.#hookRegistry.run('beforeGetSources', {\n            omssId,\n            providerId: options.providerId,\n        })\n\n        const inFlightKey = this.#getInFlightKey(omssId, options.providerId)\n\n        const result = await this.#inFlight.run(inFlightKey, () =>\n            this.#core.getSources(omssId, options, options.providerHookService ?? new HookService<ProviderHooks>(), options.cleaningFunction ?? this.cleaningFunction)\n        )\n\n        if (result.ok) {\n            await this.#hookRegistry.run('afterGetSources', {\n                omssId,\n                providerId: options.providerId,\n                result: result.value,\n            })\n\n            return this.#middleware.run('afterGetSources', { omssId, options, result }, () => Promise.resolve(result))\n        }\n\n        await this.#hookRegistry.run('getSourcesFailed', {\n            omssId,\n            providerId: options.providerId,\n            error: result.error,\n        })\n\n        return result\n    }\n\n    /**\n     * Build the stable in-flight key for a getSources request.\n     *\n     * @param omssId - OMSS identifier.\n     * @param providerId - Optional provider filter.\n     * @returns Unique in-flight request key.\n     */\n    #getInFlightKey(omssId: OMSSId, providerId?: string): string {\n        return `${omssId}|${providerId ?? ''}`\n    }\n}\n","import type { UnknownProvider } from '@/types/provider.js'\nimport { OMSSProviderError } from '@/utils/error.js'\nimport { ERR, OK, validateSafeUniqueString } from '@/utils/utils.js'\nimport { Result } from '@/types/utils.js'\nimport { CATALOG_ENTRY } from '@/utils/regexp.js'\n\n/**\n * Registry responsible for storing and managing OMSS Providers.\n *\n * Providers are stored by their unique {@link UnknownProvider.id}.\n * This registry does not know about hooks.\n */\nexport class ProviderRegistry {\n    /**\n     * Internal map of registered providers, keyed by provider ID.\n     */\n    readonly #providers = new Map<string, UnknownProvider>()\n\n    /**\n     * Adds a provider to the registry.\n     *\n     * @param provider - The provider instance to register.\n     * @returns `OK` if registration succeeded, `ERR` if the provider ID is already taken.\n     */\n    async add(provider: UnknownProvider): Promise<Result<UnknownProvider, OMSSProviderError>> {\n        if (this.#providers.has(provider.id)) {\n            return ERR(new OMSSProviderError(`Provider \"${provider.id}\" is already registered`))\n        }\n\n        const valProvIdReq = validateSafeUniqueString(provider.id, 'provider ID', OMSSProviderError)\n        if (!valProvIdReq.ok) {\n            return ERR(valProvIdReq.error)\n        }\n\n        const valResolverNamespaceReq = validateSafeUniqueString(provider.resolver.namespace, 'resolver namespace for resolver with name: \"' + provider.resolver.name + '\" and id:', OMSSProviderError)\n        if (!valResolverNamespaceReq.ok) {\n            return ERR(valResolverNamespaceReq.error)\n        }\n\n        if (this.getAll().some((p) => p.resolver.namespace === provider.resolver.namespace && p.resolver !== provider.resolver)) {\n            return ERR(new OMSSProviderError(`Resolver namespace \"${provider.resolver.namespace}\" is already registered by another provider and another resolver. Use one resolver per namespace.`))\n        }\n\n        if (provider.catalog) {\n            const entries = await provider.catalog()\n            const hasWildcard = entries.includes('*')\n            const hasOther = entries.some((id) => id !== '*')\n\n            if (hasWildcard && hasOther) {\n                return ERR(new OMSSProviderError(`Provider \"${provider.id}\" catalog contains \"*\" mixed with other IDs. Use either a single \"*\" or a list of valid IDs.`))\n            }\n\n            for (const id of entries) {\n                if (!CATALOG_ENTRY.test(id)) {\n                    return ERR(new OMSSProviderError(`Provider \"${provider.id}\" catalog contains an invalid entry \"${id}\". Entries must be non-empty strings with no whitespace, or \"*\".`))\n                }\n            }\n        }\n\n        this.#providers.set(provider.id, provider)\n        return OK(provider)\n    }\n\n    /**\n     * Retrieves a registered provider by its ID.\n     *\n     * @param id - The unique provider ID.\n     * @returns The provider instance, or `undefined` if not found.\n     */\n    get(id: string): UnknownProvider | undefined {\n        return this.#providers.get(id)\n    }\n\n    /**\n     * Returns all registered providers.\n     */\n    getAll(filter?: (p: UnknownProvider) => boolean): UnknownProvider[] {\n        if (filter) {\n            return [...this.#providers.values()].filter(filter)\n        }\n        return [...this.#providers.values()]\n    }\n\n    /**\n     * Returns whether a provider with the given ID is registered.\n     *\n     * @param id - The unique provider ID.\n     */\n    has(id: string): boolean {\n        return this.#providers.has(id)\n    }\n}\n","import type { ProviderServiceMiddleware, ProviderServiceOperations, UnknownProvider } from '@/types/provider.js'\r\nimport { OMSSProviderError } from '@/utils/error.js'\r\nimport { ERR, OK } from '@/utils/utils.js'\r\nimport { ProviderRegistry } from '@/features/providers/ProviderRegistry.js'\r\nimport { HookRegistry } from '@/features/hooks/HookRegistry.js'\r\nimport type { Result } from '@/types/utils.js'\r\nimport type { OMSSHooks } from '@/types/hooks.js'\r\nimport { MiddlewareRunner } from '@/utils/middleware.js'\r\n\r\n/**\r\n * The public API for managing OMSS Providers.\r\n */\r\nexport class ProviderService {\r\n    readonly #providerRegistry: ProviderRegistry\r\n    readonly #hookRegistry: HookRegistry<OMSSHooks>\r\n    readonly #middleware = new MiddlewareRunner<ProviderServiceOperations>()\r\n    #insideBeforeProviderRegister = false\r\n\r\n    constructor(providerRegistry: ProviderRegistry, hookRegistry: HookRegistry<OMSSHooks>) {\r\n        this.#providerRegistry = providerRegistry\r\n        this.#hookRegistry = hookRegistry\r\n    }\r\n\r\n    /**\r\n     * Adds middleware to the `register` pipeline.\r\n     * Middlewares run in insertion order, after hooks and before the\r\n     * actual registry `add()` call.\r\n     */\r\n    use<TMethod extends keyof ProviderServiceOperations>(method: TMethod, handler: ProviderServiceMiddleware<TMethod>): this {\r\n        this.#middleware.use(method, handler)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Registers a provider into the system.\r\n     */\r\n    async register(provider: UnknownProvider): Promise<Result<UnknownProvider, OMSSProviderError>> {\r\n        if (this.#insideBeforeProviderRegister) {\r\n            return ERR(new OMSSProviderError('Providers cannot be registered during beforeProviderRegister'))\r\n        }\r\n\r\n        this.#insideBeforeProviderRegister = true\r\n        try {\r\n            await this.#hookRegistry.run('beforeProviderRegister', { provider })\r\n        } finally {\r\n            this.#insideBeforeProviderRegister = false\r\n        }\r\n\r\n        const result = await this.#middleware.run('register', { provider }, () => this.#providerRegistry.add(provider))\r\n\r\n        if (!result.ok) {\r\n            await this.#hookRegistry.run('providerRegisterFailed', {\r\n                provider,\r\n                error: result.error,\r\n            })\r\n            return ERR(result.error)\r\n        }\r\n\r\n        await this.#hookRegistry.run('afterProviderRegister', { provider })\r\n        return result\r\n    }\r\n\r\n    /**\r\n     * Retrieves a registered provider by its ID.\r\n     *\r\n     * @param id - The provider ID to look up.\r\n     * @returns The provider instance, or `undefined` if not found.\r\n     */\r\n    get(id: string): ReturnType<ProviderRegistry['get']> {\r\n        return this.#providerRegistry.get(id)\r\n    }\r\n\r\n    /**\r\n     * Returns all registered providers.\r\n     * @param filter - Optional filter function to apply to providers.\r\n     */\r\n    getAll(filter?: (p: UnknownProvider) => boolean): ReturnType<ProviderRegistry['getAll']> {\r\n        return this.#providerRegistry.getAll(filter)\r\n    }\r\n\r\n    /**\r\n     * Returns whether a provider with the given ID has been registered.\r\n     *\r\n     * @param id - The provider ID to check.\r\n     */\r\n    has(id: string): ReturnType<ProviderRegistry['has']> {\r\n        return this.#providerRegistry.has(id)\r\n    }\r\n\r\n    /**\r\n     * Returns a map of all namespaces and an array of all known identifiers for each namespace.\r\n     * This list is BEST EFFORT ONLY. Do not rely on this. If any provider returns a `*` automatically, the namespace will support all identifiers (e.g. `\"tmdb\": [\"*\"], \"imdb\": [\"tt37636\", \"...\"]`.\r\n     */\r\n    async catalog(): Promise<Result<Map<string, string[]>, OMSSProviderError>> {\r\n        const allProviders = this.getAll()\r\n        const result = new Map<string, string[]>()\r\n\r\n        await Promise.all(\r\n            allProviders.map(async (provider) => {\r\n                if (!provider.catalog) return\r\n\r\n                const namespace = provider.resolver.namespace\r\n                const entries = await provider.catalog()\r\n\r\n                // If namespace already collapsed to wildcard, skip.\r\n                if (result.get(namespace)?.[0] === '*') return\r\n\r\n                if (entries.includes('*')) {\r\n                    // Any single wildcard provider collapses the whole namespace.\r\n                    result.set(namespace, ['*'])\r\n                    return\r\n                }\r\n\r\n                // Merge deduplicated IDs into the namespace bucket.\r\n                const existing = result.get(namespace) ?? []\r\n                const merged = Array.from(new Set([...existing, ...entries]))\r\n                result.set(namespace, merged)\r\n            })\r\n        )\r\n\r\n        return OK(result)\r\n    }\r\n\r\n    /**\r\n     * Returns the catalog for a single namespace.\r\n     * Returns `undefined` if no provider in that namespace exposes a catalog.\r\n     *\r\n     * @param namespace - The resolver namespace to look up (e.g. `\"tmdb\"`).\r\n     * @returns Merged list of IDs for the namespace, `[\"*\"]` if any provider\r\n     *          signals wildcard support, or `undefined` if no catalog data exists.\r\n     */\r\n    async catalogForNamespace(namespace: string): Promise<Result<string[], OMSSProviderError>> {\r\n        const providers = this.getAll((p) => p.resolver.namespace === namespace)\r\n        if (providers.length === 0) return ERR(new OMSSProviderError(`No providers registered for namespace \"${namespace}\"`))\r\n\r\n        const result: string[] = []\r\n\r\n        for (const provider of providers) {\r\n            if (!provider.catalog) continue\r\n\r\n            const entries = await provider.catalog()\r\n\r\n            if (entries.includes('*')) {\r\n                return OK(['*'])\r\n            }\r\n\r\n            for (const id of entries) {\r\n                if (!result.includes(id)) {\r\n                    result.push(id)\r\n                }\r\n            }\r\n        }\r\n\r\n        return result.length > 0 ? OK(result) : ERR(new OMSSProviderError(`No catalog data available for namespace \"${namespace}\"`))\r\n    }\r\n}\r\n","import { ExtractorRegistry } from '@/features/extractors/ExtractorRegistry.js'\nimport { HookRegistry } from '@/features/hooks/HookRegistry.js'\nimport type { OMSSHooks } from '@/types/hooks.js'\nimport { Extractor } from '@/types/extractor.js'\nimport { Result } from '@/types/utils.js'\nimport { ERR, OK } from '@/utils/utils.js'\nimport { OMSSExtractorError } from '@/utils/error.js'\n\nexport class ExtractorService {\n    readonly #extractorRegistry: ExtractorRegistry\n    readonly #hookRegistry: HookRegistry<OMSSHooks>\n    #insideBeforeRegisterExtractor = false\n\n    constructor(extractorRegistry: ExtractorRegistry, hookRegistry: HookRegistry<OMSSHooks>) {\n        this.#extractorRegistry = extractorRegistry\n        this.#hookRegistry = hookRegistry\n    }\n\n    /**\n     * Get all registered extractors (read-only).\n     */\n    get extractors(): Result<ReadonlyArray<Extractor>, Error> {\n        return OK(this.#extractorRegistry.extractors)\n    }\n\n    /**\n     * Find an extractor capable of handling the given URL.\n     *\n     * @param url - URL to search for.\n     * @returns The first matching {@link Extractor} or an {@link OMSSExtractorError}.\n     */\n    async find(url: string): Promise<Result<Extractor, OMSSExtractorError>> {\n        await this.#hookRegistry.run('beforeFindExtractor', { url })\n\n        const extractors = this.#extractorRegistry.extractors\n\n        const results = await Promise.all(extractors.map((extractor) => extractor.matcher(url)))\n\n        for (let i = 0; i < extractors.length; i++) {\n            if (results[i]!.ok) {\n                const extractor = extractors[i]!\n\n                await this.#hookRegistry.run('afterFindExtractor', {\n                    url,\n                    extractor,\n                })\n\n                return OK(extractor)\n            }\n        }\n\n        const error = new OMSSExtractorError(`No extractor found for URL \"${url}\"`)\n\n        await this.#hookRegistry.run('findExtractorFailed', {\n            url,\n            error,\n        })\n\n        return ERR(error)\n    }\n\n    /**\n     * Register an extractor.\n     *\n     * @param extractor - Extractor to register.\n     */\n    async register(extractor: Extractor): Promise<Result<void, Error>> {\n        if (this.#insideBeforeRegisterExtractor) {\n            return ERR(new OMSSExtractorError('Extractors cannot be registered during beforeRegisterExtractor'))\n        }\n\n        this.#insideBeforeRegisterExtractor = true\n\n        try {\n            await this.#hookRegistry.run('beforeRegisterExtractor', {\n                extractor,\n            })\n        } finally {\n            this.#insideBeforeRegisterExtractor = false\n        }\n\n        try {\n            this.#extractorRegistry.add(extractor)\n        } catch (error) {\n            const extractorError = error instanceof OMSSExtractorError ? error : new OMSSExtractorError(error instanceof Error ? error.message : String(error))\n\n            await this.#hookRegistry.run('extractorRegisterFailed', {\n                extractor,\n                error: extractorError,\n            })\n\n            return ERR(extractorError)\n        }\n\n        await this.#hookRegistry.run('afterRegisterExtractor', {\n            extractor,\n        })\n\n        return OK()\n    }\n\n    /**\n     * Remove every registered extractor.\n     */\n    reset(): Result<void, Error> {\n        this.#extractorRegistry.reset()\n        return OK()\n    }\n\n    /**\n     * Determine whether an extractor has already been registered.\n     *\n     * @param extractor - Extractor to check.\n     */\n    has(extractor: Extractor): Result<boolean, Error> {\n        return OK(this.#extractorRegistry.has(extractor))\n    }\n\n    /**\n     * Remove an extractor.\n     *\n     * @param extractor - Extractor to remove.\n     * @returns Whether the extractor was removed.\n     */\n    remove(extractor: Extractor): Result<boolean, Error> {\n        return OK(this.#extractorRegistry.remove(extractor))\n    }\n}\n","import { Extractor } from '@/types/extractor.js'\n\n/**\n * Extractor Registry\n *\n * Manages all extractors.\n */\nexport class ExtractorRegistry {\n    /**\n     * Array of extractors.\n     */\n    readonly #extractors = Array<Extractor>()\n\n    /**\n     * Get all extractors.\n     */\n    get extractors(): Readonly<Extractor[]> {\n        return this.#extractors\n    }\n\n    /**\n     * Clear all extractors.\n     */\n    reset(): void {\n        this.#extractors.length = 0\n    }\n\n    /**\n     * Add an extractor.\n     * @param extractor - Extractor to add.\n     */\n    add(extractor: Extractor): void {\n        if (this.#extractors.some((e) => e === extractor)) return\n\n        this.#extractors.push(extractor)\n    }\n\n    /**\n     * Check if an extractor is already registered.\n     * @param extractor - Extractor to check.\n     */\n    has(extractor: Extractor): boolean {\n        return this.#extractors.includes(extractor)\n    }\n\n    /**\n     * Remove an extractor.\n     * @param extractor - Extractor to remove.\n     * @returns True if the extractor was removed, false otherwise.\n     */\n    remove(extractor: Extractor): boolean {\n        if (!this.has(extractor)) return false\n        this.#extractors.splice(this.#extractors.indexOf(extractor), 1)\n        return true\n    }\n}\n","import { HookRegistry } from '@/features/hooks/HookRegistry.js'\r\nimport { HookService } from '@/features/hooks/HookService.js'\r\nimport { PluginRegistry } from '@/features/plugins/PluginRegistry.js'\r\nimport { PluginService } from '@/features/plugins/PluginService.js'\r\nimport { OMSSServerError } from '@/utils/error.js'\r\nimport type { OMSSConfig } from '@/types/config.js'\r\nimport { SourceService } from '@/features/source/SourceService.js'\r\nimport { ProviderRegistry } from '@/features/providers/ProviderRegistry.js'\r\nimport { ERR, OK } from '@/utils/utils.js'\r\nimport { Result } from '@/types/utils.js'\r\nimport { ProviderService } from '@/features/providers/ProviderService.js'\r\nimport { OMSSHooks } from '@/types/hooks.js'\r\nimport { ExtractorService } from '@/features/extractors/ExtractorService.js'\r\nimport { ExtractorRegistry } from '@/features/extractors/ExtractorRegistry.js'\r\n\r\n/**\r\n * Core server class for OMSS.\r\n */\r\nexport class OMSSServer {\r\n    readonly hooks: HookService<OMSSHooks>\r\n    readonly plugins: PluginService\r\n    readonly providers: ProviderService\r\n    readonly sources: SourceService\r\n    readonly extractors: ExtractorService\r\n    readonly #config: OMSSConfig\r\n\r\n    /**\r\n     * Creates a new OMSSServer instance.\r\n     *\r\n     * @param config - Immutable server configuration\r\n     */\r\n    constructor(config: OMSSConfig) {\r\n        this.#config = config\r\n\r\n        const hooksRegistry = new HookRegistry<OMSSHooks>()\r\n        const extractorRegistry = new ExtractorRegistry()\r\n        const pluginRegistry = new PluginRegistry(this)\r\n        const providerRegistry = new ProviderRegistry()\r\n\r\n        this.hooks = new HookService<OMSSHooks>(hooksRegistry)\r\n        this.extractors = new ExtractorService(extractorRegistry, hooksRegistry)\r\n        this.plugins = new PluginService(this, pluginRegistry, hooksRegistry)\r\n        this.providers = new ProviderService(providerRegistry, hooksRegistry)\r\n        this.sources = new SourceService(this, providerRegistry, hooksRegistry, this.extractors)\r\n    }\r\n\r\n    /**\r\n     * Get the OMSS Config from the constructor\r\n     * @returns the initialised OMSS Config\r\n     */\r\n    get config(): Readonly<OMSSConfig> {\r\n        return this.#config\r\n    }\r\n\r\n    /**\r\n     * Decorate the OMSSServer instance with a new property.\r\n     * @param name - The name of the property to be decorated.\r\n     * @param value - The value to be assigned to the property.\r\n     * @param deps - An array of dependency names.\r\n     * @returns The name of the decorated property in the {@link Result} object.\r\n     */\r\n    decorate<T>(name: string, value: T, deps: string[] = []): Result<string, OMSSServerError> {\r\n        if (Object.hasOwn(this, name)) {\r\n            return ERR(\r\n                new OMSSServerError(`Decorator \"${name}\" already exists`, {\r\n                    cause: {\r\n                        existing: this[name as keyof this],\r\n                    },\r\n                })\r\n            )\r\n        }\r\n\r\n        for (const dep of deps) {\r\n            if (!this.hasDecorator(dep)) {\r\n                return ERR(new OMSSServerError(`\"${name}\" depends on \"${dep}\", which does not exist`))\r\n            }\r\n        }\r\n\r\n        // modify the instance to make the decorator available as a property\r\n        Object.defineProperty(this, name, {\r\n            value,\r\n            writable: false,\r\n            configurable: false,\r\n            enumerable: true,\r\n        })\r\n\r\n        return OK(name)\r\n    }\r\n\r\n    /**\r\n     * Check if a decorator with the given name exists.\r\n     * @param name - The name of the decorator to check.\r\n     * @returns True if the decorator exists, false otherwise.\r\n     */\r\n    hasDecorator(name: string): boolean {\r\n        return Object.hasOwn(this, name)\r\n    }\r\n\r\n    /**\r\n     * Get a decorated property by its name.\r\n     * @param name - The name of the property to retrieve.\r\n     * @returns The decorated property value in the {@link Result} object.\r\n     */\r\n    getDecorator<T>(name: string): Result<T, OMSSServerError> {\r\n        if (!Object.hasOwn(this, name)) {\r\n            return ERR(new OMSSServerError(`Decorator \"${name}\" not found`))\r\n        }\r\n\r\n        return OK(this[name as keyof this] as T)\r\n    }\r\n}\r\n\r\nexport default OMSSServer\r\n","import { BaseResolver } from '@/features/resolvers/BaseResolver.js'\r\nimport { OMSSProvider, ProviderResult, ProviderResultEmitter, ProviderSourcesMeta, ResolverMetadata } from '@/types/provider.js'\r\nimport type { ParsedOMSSId } from '@/types/resolver.js'\r\nimport { NonEmptyArray } from '@/types/utils.js'\r\n\r\n/**\r\n * Base class for all providers.\r\n */\r\nexport abstract class BaseProvider<P extends BaseResolver<unknown>> implements OMSSProvider<P> {\r\n    /**\r\n     * Provider ID. Must be unique.\r\n     */\r\n    abstract readonly id: string\r\n\r\n    /**\r\n     * Friendly name of the provider.\r\n     */\r\n    abstract readonly name: string\r\n\r\n    /**\r\n     * Whether the provider will be used.\r\n     */\r\n    abstract readonly enabled: boolean\r\n\r\n    /**\r\n     * Catalog of media this provider supports. It does not have to exist. If it does, it should be a list of media IDs.\r\n     * This does not get queried for source resolving, but more metadata about the provider.\r\n     */\r\n    abstract readonly catalog?: () => Promise<NonEmptyArray<string>> | NonEmptyArray<string>\r\n\r\n    /**\r\n     * Provide a method that checks whether this provider supports a certain ID.\r\n     * @param id - Parsed OMSS ID\r\n     */\r\n    abstract readonly supportsId: (id: ParsedOMSSId) => boolean | Promise<boolean>\r\n\r\n    /**\r\n     * Resolvers that this provider supports.\r\n     */\r\n    abstract readonly resolver: P\r\n\r\n    /**\r\n     * Fetch sources for a certain media.\r\n     * @param media - Return object of the resolver's resolve() method.\r\n     * @param result - The result emitter.\r\n     */\r\n    abstract getSources(media: ProviderSourcesMeta<ResolverMetadata<P>>, result: ProviderResultEmitter): Promise<ProviderResult>\r\n}\r\n","import { OMSSResolverError, Result } from '@/public-api.js'\nimport { OMSSId, OMSSResolver, ParsedOMSSId, ResolverExecutionContext, ResolverResult } from '@/types/resolver.js'\n\n/**\n * Base class for all OMSS resolvers.\n *\n * Resolvers convert an OMSS ID into usable metadata for providers.\n */\nexport abstract class BaseResolver<T> implements OMSSResolver<T> {\n    /**\n     * Namespace this resolver owns, e.g. \"tmdb\".\n     * Must be unique for a single server instance.\n     */\n    abstract namespace: string\n\n    /**\n     * Human-readable resolver name.\n     */\n    abstract name: string\n\n    /**\n     * A map of ID converters.\n     *\n     * @key - The unhandled namespace\n     * @value - A function that converts that id (from an unknown namespace/id provider) to this resolver's namespace.\n     */\n    abstract converter: Map<string, (noHandlerId: OMSSId, ctx: ResolverExecutionContext) => Promise<Result<OMSSId, OMSSResolverError>>>\n\n    /**\n     * Resolve a single ID into metadata.\n     *\n     * @param id - Parsed OMSS ID\n     * @param ctx - Execution context.\n     */\n    abstract resolve(id: ParsedOMSSId, ctx: ResolverExecutionContext): Promise<ResolverResult<T>>\n}\n"],"mappings":"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"}