{"version":3,"sources":["../../../../src/lib/A-Server/A-HttpServer.container.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AAwBO,MAAM,aAAA,GAAN,MAAM,aAAA,SAAqB,SAAA,CAAU;AAAA,EAKxC,WAAW,eAAA,GAAkB;AACzB,IAAA,OAAO,CAAC,MAAA,EAAa,WAAA,EAAqB,UAAA,KAAmC;AACzE,MAAA,OAAO,UAAU,MAAA,CAAO;AAAA,QACpB,MAAM,oBAAA,CAAqB,eAAA;AAAA,QAC3B,KAAA,EAAO,CAAC,aAAY;AAAA,OACvB,CAAA,CAAE,MAAA,EAAQ,WAAA,EAAa,UAAU,CAAA;AAAA,IACtC,CAAA;AAAA,EACJ;AAAA,EAEA,WAAW,SAAA,GAAY;AACnB,IAAA,OAAO,CAAC,MAAA,EAAa,WAAA,EAAqB,UAAA,KAAmC;AACzE,MAAA,OAAO,UAAU,MAAA,CAAO;AAAA,QACpB,MAAM,oBAAA,CAAqB,SAAA;AAAA,QAC3B,KAAA,EAAO,CAAC,aAAY;AAAA,OACvB,CAAA,CAAE,MAAA,EAAQ,WAAA,EAAa,UAAU,CAAA;AAAA,IACtC,CAAA;AAAA,EACJ;AAAA,EAEA,WAAW,cAAA,GAAiB;AACxB,IAAA,OAAO,CAAC,MAAA,EAAa,WAAA,EAAqB,UAAA,KAAmC;AACzE,MAAA,OAAO,UAAU,MAAA,CAAO;AAAA,QACpB,MAAM,oBAAA,CAAqB,cAAA;AAAA,QAC3B,KAAA,EAAO,CAAC,aAAY;AAAA,OACvB,CAAA,CAAE,MAAA,EAAQ,WAAA,EAAa,UAAU,CAAA;AAAA,IACtC,CAAA;AAAA,EACJ;AAAA,EAKA,OAAiB,EAAA,GAAA,iBAAA,CAAkB,OAAO,CAAA,CAGhB,UAGF,MAAA,EAEP;AACb,IAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AAGjC,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,YAAA,CAAa,KAAK,aAAA,CAAc,IAAA,CAAK,IAAI,CAAC,CAAA;AAG7D,IAAA,MAAM,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,eAAe,CAAC,CAAA;AAAA,EACjD;AAAA,EAGA,OAAiB,EAAA,GAAA,iBAAA,CAAkB,YAAY,CAAA,CACvB,QACM,MAAA,EACb;AACb,IAAA,MAAA,CAAO,WAAA,CAAY;AAAA,MACf,IAAA,EAAM,MAAA,CAAO,GAAA,CAAI,eAAe,CAAA;AAAA,MAChC,GAAA,EAAK;AAAA,QACD,IAAA,EAAM,KAAK,KAAA,CAAM;AAAA;AACrB,KACH,CAAA;AAAA,EACL;AAAA,EAEA,OAAiB,iBAAA,CAAkB,MAAM,CAAA,CAAA,GAAK,IAAA,EAA4B;AACtE,IAAA,MAAM,KAAK,KAAA,EAAM;AAAA,EACrB;AAAA,EAEA,KAAA,GAAQ;AACJ,IAAA,OAAO,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AAC1C,MAAA,IAAA,CAAK,MAAA,CAAO,MAAM,MAAM;AACpB,QAAA,OAAA,EAAQ;AAAA,MACZ,CAAC,CAAA;AAAA,IACL,CAAC,CAAA;AAAA,EACL;AAAA,EAEA,OAAO,IAAA,EAAc;AACjB,IAAA,OAAO,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AAC1C,MAAA,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,IAAA,EAAM,MAAM;AAC3B,QAAA,OAAA,EAAQ;AAAA,MACZ,CAAC,CAAA;AAAA,IACL,CAAC,CAAA;AAAA,EACL;AAAA,EAQA,OAAiB,EAAA,GAAA,oBAAA,CAAqB,eAAe,CAAA,CAAA,GAAK,IAAA,EAAa;AAAA,EAAE;AAAA,EAGzE,OAAiB,EAAA,GAAA,oBAAA,CAAqB,SAAS,CAAA,CAAA,GAAK,IAAA,EAAa;AAAA,EAAE;AAAA,EAGnE,OAAiB,EAAA,GAAA,oBAAA,CAAqB,cAAc,CAAA,CAAA,GAAK,IAAA,EAAa;AAAA,EAAE;AAAA;AAAA;AAAA;AAAA,EAOxE,MAAM,aAAA,CACF,OAAA,EACA,QAAA,EACF;AACE,IAAA,MAAM,QAAQ,IAAI,aAAA;AAAA,MACd,QAAQ,GAAA,IAAO,EAAA;AAAA,MACf,OAAA,CAAQ;AAAA,KACZ;AAEA,IAAA,MAAM,EAAA,GAAK,iBAAiB,cAAA,EAAe;AAC3C,IAAA,MAAM,KAAA,GAAQ,CAAA,EAAG,OAAA,CAAQ,MAAM,CAAA,CAAA,EAAI,MAAM,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK,GAAG,CAAC,CAAA,CAAA;AAE/D,IAAA,MAAM,GAAA,GAAM,IAAI,SAAA,CAAU,EAAE,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,CAAA;AACxE,IAAA,MAAM,GAAA,GAAM,IAAI,UAAA,CAAW,EAAE,EAAA,EAAI,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,IAAA,EAAM,CAAA;AAC1E,IAAA,MAAM,OAAA,GAAU,IAAI,0BAAA,CAA2B,OAAA,EAAS,QAAQ,CAAA;AAEhE,IAAA,MAAM,KAAA,GAAQ,IAAI,OAAA,CAAQ;AAAA,MACtB,IAAA,EAAM,EAAA;AAAA,MACN,QAAA,EAAU,CAAC,GAAA,EAAK,GAAG,CAAA;AAAA,MACnB,SAAA,EAAW,CAAC,KAAA,EAAO,OAAO;AAAA,KAC7B,CAAA,CAAE,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA;AAErB,IAAA,IAAI;AACA,MAAA,MAAM,sBAAA,GAAyB,IAAI,SAAA,CAAU;AAAA,QACzC,MAAM,oBAAA,CAAqB,eAAA;AAAA,QAC3B,SAAA,EAAW;AAAA,OACd,CAAA;AAED,MAAA,MAAM,gBAAA,GAAmB,IAAI,SAAA,CAAU;AAAA,QACnC,MAAM,oBAAA,CAAqB,SAAA;AAAA,QAC3B,SAAA,EAAW;AAAA,OACd,CAAA;AAED,MAAA,MAAM,qBAAA,GAAwB,IAAI,SAAA,CAAU;AAAA,QACxC,MAAM,oBAAA,CAAqB,cAAA;AAAA,QAC3B,SAAA,EAAW;AAAA,OACd,CAAA;AAED,MAAA,MAAM,IAAI,OAAA,CAAc,OAAO,OAAA,EAAS,MAAA,KAAW;AAE/C,QAAA,MAAM,UAAU,MAAM;AAClB,UAAA,sBAAA,CAAuB,SAAA,EAAU;AACjC,UAAA,gBAAA,CAAiB,SAAA,EAAU;AAC3B,UAAA,qBAAA,CAAsB,SAAA,EAAU;AAEhC,UAAA,GAAA,CAAI,GAAA,CAAI,iBAAA,CAAkB,OAAA,EAAS,OAAO,CAAA;AAC1C,UAAA,GAAA,CAAI,GAAA,CAAI,iBAAA,CAAkB,OAAA,EAAS,OAAO,CAAA;AAC1C,UAAA,GAAA,CAAI,GAAA,CAAI,iBAAA,CAAkB,SAAA,EAAW,OAAO,CAAA;AAG5C,UAAA,MAAA,CAAO,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAE,CAAA;AAAA,QAClC,CAAA;AAGA,QAAA,GAAA,CAAI,GAAG,iBAAA,CAAkB,OAAA,EAAS,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAC,CAAA;AACpD,QAAA,GAAA,CAAI,GAAG,iBAAA,CAAkB,OAAA,EAAS,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAC,CAAA;AAEpD,QAAA,IAAI;AACA,UAAA,MAAM,IAAI,IAAA,EAAK;AACf,UAAA,MAAM,IAAI,IAAA,EAAK;AAGf,UAAA,MAAM,sBAAA,CAAuB,QAAQ,KAAK,CAAA;AAE1C,UAAA,MAAM,gBAAA,CAAiB,QAAQ,KAAK,CAAA;AAEpC,UAAA,MAAM,qBAAA,CAAsB,QAAQ,KAAK,CAAA;AAGzC,UAAA,GAAA,CAAI,YAAA,EAAa;AAIjB,UAAA,IAAI,CAAC,IAAI,WAAA,EAAa;AAClB,YAAA,MAAM,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,EAAK;AAAA,UAC/B;AAEA,UAAA,OAAA,EAAQ;AAAA,QACZ,SAAS,KAAA,EAAO;AAEZ,UAAA,GAAA,CAAI,YAAA,EAAa;AACjB,UAAA,MAAA,CAAO,KAAK,CAAA;AAAA,QAChB;AAAA,MACJ,CAAC,CAAA;AAAA,IAEL,SAAS,KAAA,EAAO;AAEZ,MAAA,IAAI,YAAA;AAEJ,MAAA,QAAQ,IAAA;AAAM,QACV,KAAK,KAAA,YAAiB,iBAAA;AAClB,UAAA,YAAA,GAAe,KAAA;AACf,UAAA;AAAA,QAEJ,MAAK,KAAA,YAAiB,OAAA,IAAW,KAAA,CAAM,aAAA,YAAyB,iBAAA;AAC5D,UAAA,YAAA,GAAe,KAAA,CAAM,aAAA;AACrB,UAAA;AAAA;AAAA;AAAA;AAAA,QAKJ,MAAK,iBAAiB,OAAA,IAClB,KAAA,CAAM,yBAAyB,KAAA,IAC/B,OAAQ,KAAA,CAAM,aAAA,CAAsB,UAAA,KAAe,QAAA;AACnD,UAAA,YAAA,GAAe,IAAI,iBAAA,CAAkB;AAAA,YACjC,MAAA,EAAS,MAAM,aAAA,CAAsB,UAAA;AAAA,YACrC,WAAA,EAAc,MAAM,aAAA,CAAwB,OAAA;AAAA,YAC5C,eAAe,KAAA,CAAM;AAAA,WACxB,CAAA;AACD,UAAA;AAAA;AAAA;AAAA;AAAA,QAKJ,MAAK,KAAA,YAAiB,KAAA,IAAS,OAAQ,MAAc,UAAA,KAAe,QAAA;AAChE,UAAA,YAAA,GAAe,IAAI,iBAAA,CAAkB;AAAA,YACjC,QAAS,KAAA,CAAc,UAAA;AAAA,YACvB,aAAa,KAAA,CAAM,OAAA;AAAA,YACnB,aAAA,EAAe;AAAA,WAClB,CAAA;AACD,UAAA;AAAA,QAEJ;AACI,UAAA,YAAA,GAAe,IAAI,iBAAA,CAAkB;AAAA,YACjC,MAAA,EAAQ,GAAA;AAAA,YACR,WAAA,EAAa,iDAAA;AAAA,YACb,aAAA,EAAe;AAAA,WAClB,CAAA;AACD,UAAA;AAAA;AAIR,MAAA,KAAA,CAAM,SAAS,YAAY,CAAA;AAE3B,MAAA,MAAM,GAAA,CAAI,KAAK,YAAY,CAAA;AAE3B,MAAA,MAAM,IAAA,CAAK,IAAA,CAAK,iBAAA,CAAkB,OAAA,EAAS,KAAK,CAAA;AAAA,IACpD;AAEA,IAAA,KAAA,CAAM,OAAA,EAAQ;AAAA,EAClB;AAEJ,CAAA;AApNqB,eAAA,CAAA;AAAA,EADhB,UAAU,MAAA,EAAO;AAAA,EAGb,gCAAa,QAAA,EAAS,CAAA;AAAA,EACtB,4BAAS,UAAU,CAAA,CAAA;AAAA,EAEnB,gCAAa,QAAA,EAAS,CAAA;AAAA,EACtB,4BAAS,QAAQ,CAAA;AAAA,CAAA,EAzCb,aAAA,CAmCQ,SAAA,EAAA,EAAA,EAAA,CAAA,CAAA;AAmBA,eAAA,CAAA;AAAA,EADhB,UAAU,MAAA,EAAO;AAAA,EAEb,4BAAS,QAAQ,CAAA,CAAA;AAAA,EACjB,4BAAS,cAAc,CAAA;AAAA,CAAA,EAxDnB,aAAA,CAsDQ,SAAA,EAAA,EAAA,EAAA,CAAA,CAAA;AAsCA,eAAA,CAAA;AAAA,EADhB,UAAU,MAAA;AAAO,CAAA,EA3FT,aAAA,CA4FQ,SAAA,EAAA,EAAA,EAAA,CAAA,CAAA;AAGA,eAAA,CAAA;AAAA,EADhB,UAAU,MAAA;AAAO,CAAA,EA9FT,aAAA,CA+FQ,SAAA,EAAA,EAAA,EAAA,CAAA,CAAA;AAGA,eAAA,CAAA;AAAA,EADhB,UAAU,MAAA;AAAO,CAAA,EAjGT,aAAA,CAkGQ,SAAA,EAAA,EAAA,EAAA,CAAA,CAAA;AAlGd,IAAM,YAAA,GAAN","file":"A-HttpServer.container.mjs","sourcesContent":["import type { IncomingMessage, Server, ServerResponse } from \"http\";\nimport { A_HttpServerFeatures } from \"./A-HttpServer.constants\";\nimport { A_Request } from \"@adaas/a-server/request/A-Request.entity\";\nimport { A_Response } from \"@adaas/a-server/response/A-Response.entity\";\nimport { A_TYPES__ServerENVVariables } from \"@adaas/a-server/constants/env.constants\";\nimport { A_Dependency, A_Error, A_Feature, A_IdentityHelper, A_Inject, A_Scope } from \"@adaas/a-concept\";\nimport { A_ServerRoute } from \"@adaas/a-server/route/A-ServerRoute.entity\";\nimport { A_HttpServerRequestMethod } from \"./A-HttpServer.types\";\nimport { A_HttpServerError } from \"./A-HttpServer.error\";\nimport { A_RequestFeatures } from \"@adaas/a-server/request/A-Request.constants\";\nimport { A_HttpServerRequestContext } from \"@adaas/a-server/request/A-HttpServerRequest.context\";\nimport { A_ServerLogger } from \"@adaas/a-server/logger/A-ServerLogger.component\";\nimport { A_Service, A_ServiceFeatures } from \"@adaas/a-utils/a-service\";\nimport { A_Polyfill } from \"@adaas/a-utils/a-polyfill\";\nimport { A_Config } from \"@adaas/a-utils/a-config\";\n\n\n\n\n/**\n * A-Service is a container that can run different types of services, such as HTTP servers, workers, etc.\n * Depending on the provided config and configuration, it will load the necessary components and start the service.\n * \n */\nexport class A_HttpServer extends A_Service {\n\n    protected server!: Server;\n\n\n    static get onBeforeRequest() {\n        return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {\n            return A_Feature.Extend({\n                name: A_HttpServerFeatures.onBeforeRequest,\n                scope: [A_HttpServer],\n            })(target, propertyKey, descriptor);\n        }\n    }\n\n    static get onRequest() {\n        return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {\n            return A_Feature.Extend({\n                name: A_HttpServerFeatures.onRequest,\n                scope: [A_HttpServer],\n            })(target, propertyKey, descriptor);\n        }\n    }\n\n    static get onAfterRequest() {\n        return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {\n            return A_Feature.Extend({\n                name: A_HttpServerFeatures.onAfterRequest,\n                scope: [A_HttpServer],\n            })(target, propertyKey, descriptor);\n        }\n    }\n\n\n\n    @A_Feature.Extend()\n    protected async [A_ServiceFeatures.onStart](\n\n        @A_Dependency.Required()\n        @A_Inject(A_Polyfill) polyfill: A_Polyfill,\n\n        @A_Dependency.Required()\n        @A_Inject(A_Config) config: A_Config<A_TYPES__ServerENVVariables>,\n\n    ): Promise<void> {\n        const http = await polyfill.http();\n\n        // Create the HTTP server\n        this.server = http.createServer(this.handleRequest.bind(this));\n\n        // Start listening on the specified port\n        await this.listen(config.get('A_SERVER_PORT'));\n    }\n\n    @A_Feature.Extend()\n    protected async [A_ServiceFeatures.onAfterStart](\n        @A_Inject(A_Config) config: A_Config<A_TYPES__ServerENVVariables>,\n        @A_Inject(A_ServerLogger) logger: A_ServerLogger,\n    ): Promise<void> {\n        logger.serverReady({\n            port: config.get('A_SERVER_PORT'),\n            app: {\n                name: this.scope.name,\n            }\n        });\n    }\n\n    protected async [A_ServiceFeatures.onStop](...args: any[]): Promise<void> {\n        await this.close();\n    }\n\n    close() {\n        return new Promise<void>((resolve, reject) => {\n            this.server.close(() => {\n                resolve();\n            });\n        });\n    }\n\n    listen(port: number) {\n        return new Promise<void>((resolve, reject) => {\n            this.server.listen(port, () => {\n                resolve();\n            });\n        });\n    }\n\n\n    // ======================================================================================\n    // ============================= A_HttpServer Lifecycle =================================\n    // ======================================================================================\n\n    @A_Feature.Extend()\n    protected async [A_HttpServerFeatures.onBeforeRequest](...args: any[]) { }\n\n    @A_Feature.Extend()\n    protected async [A_HttpServerFeatures.onRequest](...args: any[]) { }\n\n    @A_Feature.Extend()\n    protected async [A_HttpServerFeatures.onAfterRequest](...args: any[]) { }\n\n\n    // ======================================================================================\n    // ============================= A_HttpServer Methods =================================\n    // ======================================================================================\n\n    async handleRequest(\n        request: IncomingMessage,\n        response: ServerResponse\n    ) {\n        const route = new A_ServerRoute(\n            request.url || '',\n            request.method as A_HttpServerRequestMethod\n        );\n\n        const id = A_IdentityHelper.generateTimeId();\n        const shard = `${request.method}-${route.path.replace('/', '-')}`;\n\n        const req = new A_Request({ id, shard, request, scope: this.scope.name });\n        const res = new A_Response({ id, shard, response, scope: this.scope.name });\n        const context = new A_HttpServerRequestContext(request, response);\n\n        const scope = new A_Scope({\n            name: id,\n            entities: [req, res],\n            fragments: [route, context]\n        }).inherit(this.scope);\n\n        try {\n            const onBeforeRequestFeature = new A_Feature({\n                name: A_HttpServerFeatures.onBeforeRequest,\n                component: this\n            });\n\n            const onRequestFeature = new A_Feature({\n                name: A_HttpServerFeatures.onRequest,\n                component: this\n            });\n\n            const onAfterRequestFeature = new A_Feature({\n                name: A_HttpServerFeatures.onAfterRequest,\n                component: this\n            });\n\n            await new Promise<void>(async (resolve, reject) => {\n\n                const cleanup = () => {\n                    onBeforeRequestFeature.interrupt();\n                    onRequestFeature.interrupt();\n                    onAfterRequestFeature.interrupt();\n\n                    req.off(A_RequestFeatures.onError, cleanup);\n                    req.off(A_RequestFeatures.onClose, cleanup);\n                    req.off(A_RequestFeatures.onTimeout, cleanup);\n\n\n                    reject(scope.resolve(A_Error)!);\n                }\n\n\n                req.on(A_RequestFeatures.onError, cleanup.bind(this));\n                req.on(A_RequestFeatures.onClose, cleanup.bind(this));\n\n                try {\n                    await req.load();\n                    await res.load();\n\n\n                    await onBeforeRequestFeature.process(scope);\n\n                    await onRequestFeature.process(scope);\n\n                    await onAfterRequestFeature.process(scope);\n\n\n                    req.clearTimeout();\n\n                    // For SSE streams the controller calls response.sseOpen() which keeps\n                    // the socket alive; skip the auto-send so we don't close it here.\n                    if (!res.isStreaming) {\n                        await res.status(200).send();\n                    }\n\n                    resolve();\n                } catch (error) {\n\n                    req.clearTimeout();\n                    reject(error);\n                }\n            });\n\n        } catch (error) {\n\n            let wrappedError;\n\n            switch (true) {\n                case error instanceof A_HttpServerError:\n                    wrappedError = error;\n                    break;\n\n                case error instanceof A_Error && error.originalError instanceof A_HttpServerError:\n                    wrappedError = error.originalError;\n                    break;\n\n                // Duck-type: A_Error (e.g. A_FeatureError) wrapping an HttpError-like original.\n                // A_Error.fromConstructor() unwraps nested A_Error chains, so originalError is\n                // always the root non-A_Error cause — check it for a numeric statusCode.\n                case error instanceof A_Error &&\n                    error.originalError instanceof Error &&\n                    typeof (error.originalError as any).statusCode === 'number':\n                    wrappedError = new A_HttpServerError({\n                        status: (error.originalError as any).statusCode as number,\n                        description: (error.originalError as Error).message,\n                        originalError: error.originalError,\n                    });\n                    break;\n\n                // Duck-type: any Error with a numeric statusCode property (e.g. http-errors,\n                // Express-style errors, or plain project HttpError classes).  Honour the\n                // status code so the caller gets the right 4xx / 5xx rather than a blanket 500.\n                case error instanceof Error && typeof (error as any).statusCode === 'number':\n                    wrappedError = new A_HttpServerError({\n                        status: (error as any).statusCode as number,\n                        description: error.message,\n                        originalError: error,\n                    });\n                    break;\n\n                default:\n                    wrappedError = new A_HttpServerError({\n                        status: 500,\n                        description: 'An error occurred while processing the request.',\n                        originalError: error\n                    })\n                    break;\n            }\n\n\n            scope.register(wrappedError);\n\n            await res.fail(wrappedError);\n\n            await this.call(A_ServiceFeatures.onError, scope);\n        }\n\n        scope.destroy();\n    }\n\n}\n\n\n\n\n\n\n\n\n"]}