{"version":3,"sources":["../../src/models/file-based-routing.ts"],"sourcesContent":["import {\n    RouteGroupEntryConfig,\n    FileBasedRoutingOptions,\n    RouteEntryConfig,\n    RouteMappingOptions,\n    RouteEndpoint,\n    RouteEndpoints,\n    RouteHandlersMap,\n    Plugin,\n    RouteMiddleware,\n    ExpressMethod,\n    RoutePlugins\n} from \"../types\";\n\nimport { Express, RequestHandler } from \"express\";\nimport fs from \"fs\";\nimport path from \"path\";\n\nimport {\n    extractDirContext,\n    extractEndpointName,\n    extractFileContext\n} from \"../helpers/extractors\";\n\nimport {\n    buildRoutePattern,\n    buildRouteWithOneLeadingSlash\n} from \"../helpers/builders\";\n\nimport {\n    filenameIsJSorTS,\n    isDefined,\n    isErrorHandler,\n    isFunction,\n    isNotDefined,\n    isRequestHandler,\n    methodIsExpressMethod\n} from \"../helpers/validators\";\n\nimport { pathToFileURL } from \"url\";\nimport { errorGuardMiddleware } from \"../guards/exception\";\nimport { InvalidPluginError, InvalidRouteHandler, RoutesRootNotFound, UnknownPluginError } from \"../types/exceptions\";\nimport { tracingMiddleware } from \"../guards/tracing\";\nimport { logger } from \"../helpers/logging\";\n\nclass FileBasedRouting {\n    public readonly base: string;\n    public readonly endpoints: RouteEndpoints;\n\n    private readonly endpointsQueue: RouteEndpoints;\n\n    private _app: Express;\n    private readonly errorGuard: typeof errorGuardMiddleware | undefined;\n    private readonly plugins: Map<string, Plugin> = new Map();\n    private readonly collectEndpoints: boolean = false;\n\n    constructor({ app, target, errorGuard, plugins, collectEndpoints }: FileBasedRoutingOptions) {\n        this.base = target || path.resolve(process.cwd(), \"src\", \"routes\");\n        this.endpoints = [];\n        this.endpointsQueue = [];\n        this.plugins = this.buildPluginMap(plugins ?? []);\n        this.collectEndpoints = collectEndpoints ?? false;\n\n        this._app = app;\n\n        if (isFunction(errorGuard)) {\n            this.errorGuard = errorGuard;\n        } else if (errorGuard === true) {\n            this.errorGuard = errorGuardMiddleware;\n        }\n    }\n\n    public async createRoutes() {\n        await this.mapRoutes({\n            target: this.base,\n            route: \"/\",\n            parentGroup: undefined\n        });\n    }\n\n    private async mapRoutes({ target, route, parentGroup }: RouteMappingOptions) {\n        if (!fs.existsSync(target)) throw new RoutesRootNotFound(target);\n\n        let parent = parentGroup?.route?.trim() || \"/\";\n\n        const targetStat = fs.statSync(target);\n        const basename = path.basename(target.replace(this.base, \"\"));\n        const { name, isParam } = extractEndpointName(path.parse(basename).name);\n\n        route = buildRouteWithOneLeadingSlash(route);\n\n        if (targetStat.isDirectory()) {\n            return this.handleDir({\n                route,\n                parent,\n                name,\n                basename,\n                target,\n                isParam,\n            });\n        }\n\n        if (targetStat.isFile()) {\n            return this.handleFile({\n                route,\n                name,\n                basename,\n                target,\n                isParam,\n            });\n        }\n    }\n\n    private async handleDir({ route, parent, name, basename, target, isParam }: RouteGroupEntryConfig) {\n        parent = path.join(parent, basename);\n\n        const routes = fs.readdirSync(target);\n        const { config, middlewares, errorHandler } = extractDirContext(target);\n\n        const endpoint = buildRoutePattern(\n            route,\n            name,\n            isParam,\n            typeof config?.pattern === \"string\" || config.pattern instanceof RegExp\n                ? config.pattern\n                : undefined\n        );\n\n        middlewares.forEach(middleware => this._app.use(endpoint, middleware));\n\n        if(this.collectEndpoints) {\n            const routeEndpoint: RouteEndpoint = {\n                depth: this.endpointsQueue.length,\n                name,\n                endpoint,\n                method: \"-\",\n                middlewares: middlewares.map(item => item.name),\n                errorHandler: errorHandler?.name || \"-\",\n                plugins: [],\n                children: []\n            };\n\n            const parent = this.endpointsQueue.at(this.endpointsQueue.length - 1)?.children ?? this.endpoints;\n            parent.push(routeEndpoint);\n            this.endpointsQueue.push(routeEndpoint);\n        }\n\n        for(const item of routes) {\n            if (item.startsWith(\"_\")) return;\n\n            const newTarget = path.join(target, item);\n            if (!fs.existsSync(newTarget)) return;\n\n            await this.mapRoutes({\n                target: newTarget,\n                route: endpoint,\n                parentGroup: {\n                    route: parent,\n                }\n            });\n        }\n\n        if(this.collectEndpoints) {\n            this.endpointsQueue.pop();\n        }\n\n        if (errorHandler) this._app.use(endpoint, errorHandler);\n    }\n\n    private async handleFile({ route, name, basename, target, isParam }: RouteEntryConfig) {\n        if (!filenameIsJSorTS(basename)) return;\n\n        const targetAbsolutePath = pathToFileURL(path.resolve(target)).href;\n        const module = await import(targetAbsolutePath);\n\n        if (!module) return;\n\n        const handlers: RouteHandlersMap = {\n            get: module._get ?? module.default?._get,\n            post: module._post ?? module.default?._post,\n            delete: module._delete ?? module.default?._delete,\n            put: module._put ?? module.default?._put,\n            patch: module._patch ?? module.default?._patch,\n            all: module._all ?? module.default?._all\n        };\n\n        let { config, middlewares, errorHandler } = extractFileContext(target);\n\n        for (const [method, handler] of Object.entries(handlers)) {\n            if (!methodIsExpressMethod(method) || isNotDefined(handler)) continue;\n\n            this.isRequestHandlerOrThrow(handler, method)\n            const endpoint = buildRoutePattern(\n                route,\n                name,\n                isParam,\n                config.pattern instanceof RegExp || typeof config.pattern === \"string\"\n                    ? config.pattern\n                    : config.pattern?.[method] || config.pattern?.all,\n                true\n            );\n\n            const routeMiddlewares = this.pushMiddlewares(middlewares, method);\n            const methodPlugins = config.plugins?.[method] ?? config.plugins?.all ?? {};\n\n            const wrappedHandler = this.bindPlugins(handler, route, methodPlugins);\n            this._app[method](\n                endpoint, \n                tracingMiddleware, \n                ...routeMiddlewares, \n                this.errorGuard?.(wrappedHandler) ?? wrappedHandler\n            );\n  \n            let routerEndpoint: RouteEndpoint | undefined;\n            if(this.collectEndpoints) {\n                routerEndpoint = {\n                    depth: this.endpointsQueue.length,\n                    name,\n                    endpoint,\n                    method,\n                    middlewares: [],\n                    errorHandler: \"-\",\n                    plugins: Object.keys(methodPlugins),\n                    children: []\n                };\n    \n                routerEndpoint.middlewares.push(...routeMiddlewares.map(middleware => middleware.name));\n            }\n\n            if (errorHandler) {\n                let resolvedError = errorHandler as typeof errorHandler | undefined;\n\n                if (typeof resolvedError !== \"function\") {\n                    resolvedError = resolvedError?.[method] || resolvedError?.all;\n                }\n\n                if (isErrorHandler(resolvedError)) {\n                    this._app.use(endpoint, resolvedError);\n                    if(isDefined(routerEndpoint)) routerEndpoint.errorHandler = resolvedError.name;\n                }\n            }\n\n            if(isDefined(routerEndpoint)){\n                const parent = this.endpointsQueue.at(this.endpointsQueue.length - 1)?.children ?? this.endpoints;\n                parent.push(routerEndpoint);\n            };\n        }\n    }\n\n    private pushMiddlewares(middlewares: RouteMiddleware, method: ExpressMethod): RequestHandler[] {\n        const routeMiddlewares: RequestHandler[] = [];\n\n        if (Array.isArray(middlewares)) {\n            middlewares.forEach(middleware => {\n                this.isRequestHandlerOrThrow(middleware, method);\n                routeMiddlewares.push(this.errorGuard?.(middleware) ?? middleware);\n            });\n        } else if (middlewares && typeof middlewares === \"object\") {\n            const methodMiddlewares = middlewares[method] || middlewares.all;\n\n            if (Array.isArray(methodMiddlewares)) {\n                methodMiddlewares.forEach(middleware => {\n                    this.isRequestHandlerOrThrow(middleware, method);\n                    routeMiddlewares.push(this.errorGuard?.(middleware) ?? middleware);\n                });\n            } else if (methodMiddlewares) {\n                this.isRequestHandlerOrThrow(methodMiddlewares, method);\n                routeMiddlewares.push(this.errorGuard?.(methodMiddlewares) ?? methodMiddlewares);\n            }\n        } else if (middlewares) {\n            this.isRequestHandlerOrThrow(middlewares, method);\n            routeMiddlewares.push(this.errorGuard?.(middlewares) ?? middlewares);\n        }\n\n        return routeMiddlewares;\n    }\n\n    private bindPlugins(\n        handler: RequestHandler,\n        route: string,\n        routePlugins: RoutePlugins | undefined\n    ): RequestHandler {\n        if (isNotDefined(routePlugins)) return handler;\n        \n        const active: {\n            plugin: Plugin<any>;\n            config: any;\n        }[] = [];\n        \n        for (const [name, value] of Object.entries(routePlugins)) {\n            const plugin = this.plugins.get(name);\n\n            if (isNotDefined(plugin)) {\n                if (this.collectEndpoints) {\n                    logger.warn(`Unknown plugin \"${name}\" in route \"${route}\"`);\n                    continue;\n                }\n\n                throw new UnknownPluginError(\n                    name,\n                    route,\n                    [...this.plugins.keys()]\n                );\n            }\n    \n            let enabled = true;\n            let config: any = undefined;\n    \n            if (typeof value === \"boolean\") {\n                enabled = value;\n            } else {\n                enabled = value.enabled ?? true;\n                config = value.config;\n            }\n    \n            if (!enabled) continue;\n    \n            plugin.validateConfig?.(config);\n            active.push({ plugin, config });\n        }\n\n        let wrapped = handler;\n        for (const { plugin, config } of active) {\n            wrapped = plugin.wrap?.(wrapped, config) ?? wrapped;\n        }\n\n        return async (req, res, next)=> {\n            const ctx = {\n                req,\n                res,\n                state: {},\n                config: undefined as any\n            };\n\n            const executed: typeof active = [];\n            const delegate = async (i: number)=> {\n                if(i >= active.length) {\n                    await wrapped(req, res, next);\n                    return;\n                };\n\n                let called = false;\n                const nextFn = async ()=> {\n                    if(called) return;\n                    called = true;\n                    await delegate(i + 1)\n                }\n    \n                const entry = active[i];\n                const { plugin, config } = entry;\n    \n                executed.push(entry);\n\n                ctx.config = config;\n                if(isDefined(plugin.onRequest)) {\n                    await plugin.onRequest(ctx, nextFn);\n                } else {\n                    await delegate(i + 1);\n                }\n\n            }\n\n            try {\n                await delegate(0);\n        \n                while(executed.length > 0) {\n                    const { config, plugin } = executed[executed.length - 1];\n\n                    ctx.config = config;\n            \n                    if (isDefined(plugin.onResponse)) {\n                        await plugin.onResponse(ctx);\n                    }\n                    executed.pop();\n                }\n            } catch (err) {\n                while(executed.length > 0) {\n                    const { config, plugin } = executed.pop()!;\n\n                    ctx.config = config;\n            \n                    if (isDefined(plugin.onError)) {\n                        await plugin.onError(err, ctx);\n                    }\n                }\n            \n                throw err;\n            }\n        }\n    }\n\n    private isRequestHandlerOrThrow(handler: RequestHandler, method: ExpressMethod): void {\n        if(!isRequestHandler(handler)) throw new InvalidRouteHandler(method, handler);\n    }\n\n    private buildPluginMap(plugins: Plugin[]): Map<string, Plugin> {\n        const map = new Map<string, Plugin>();\n\n        for (const plugin of plugins) {\n            if (!plugin || typeof plugin !== \"object\") {\n                throw new InvalidPluginError(`Invalid plugin: expected object`);\n            }\n    \n            if (typeof plugin.name !== \"string\" || plugin.name.trim() === \"\") {\n                throw new InvalidPluginError(`Plugin must have a valid name`);\n            }\n    \n            if (map.has(plugin.name)) {\n                throw new InvalidPluginError(`Duplicate plugin name \"${plugin.name}\"`);\n            }\n    \n            if (isDefined(plugin.wrap) && !isFunction(plugin.wrap)) {\n                throw new InvalidPluginError(`Plugin \"${plugin.name}\": wrap must be a function`);\n            }\n            \n            if (isDefined(plugin.onRequest) && !isFunction(plugin.onRequest)) {\n                throw new InvalidPluginError(`Plugin \"${plugin.name}\": onRequest must be a function`);\n            }\n            \n            if (isDefined(plugin.onResponse) && !isFunction(plugin.onResponse)) {\n                throw new InvalidPluginError(`Plugin \"${plugin.name}\": onResponse must be a function`);\n            }\n            \n            if (isDefined(plugin.onError) && !isFunction(plugin.onError)) {\n                throw new InvalidPluginError(`Plugin \"${plugin.name}\": onError must be a function`);\n            }\n            \n            if (isDefined(plugin.validateConfig) && !isFunction(plugin.validateConfig)) {\n                throw new InvalidPluginError(`Plugin \"${plugin.name}\": validateConfig must be a function`);\n            }\n            \n            Object.freeze(plugin);\n            map.set(plugin.name, plugin);\n        }\n    \n        return map;\n    }\n\n    public static async collectRoutes(target: string) {\n        const fakeApp = {\n            use: () => {},\n            get: () => {},\n            post: () => {},\n            put: () => {},\n            patch: () => {},\n            delete: () => {},\n            all: () => {}\n        } as unknown as Express;\n\n        const instance = new FileBasedRouting({\n            app: fakeApp,\n            target,\n            collectEndpoints: true\n        });\n\n        await instance.createRoutes();\n\n        return instance.endpoints;\n    }\n}\n\nexport default FileBasedRouting;"],"mappings":"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","names":["parent","_a","_b"]}