jimpex 7.0.1 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +87 -0
- package/LICENSE +1 -1
- package/README.md +446 -434
- package/dist/app/index.d.ts +13 -0
- package/dist/app/index.js +19 -0
- package/dist/app/index.js.map +1 -0
- package/dist/app/jimpex.d.ts +13 -0
- package/dist/app/jimpex.js +440 -0
- package/dist/app/jimpex.js.map +1 -0
- package/dist/controllers/common/config.d.ts +78 -0
- package/dist/controllers/common/config.js +89 -0
- package/dist/controllers/common/config.js.map +1 -0
- package/dist/controllers/common/health.d.ts +82 -0
- package/dist/controllers/common/health.js +97 -0
- package/dist/controllers/common/health.js.map +1 -0
- package/dist/controllers/common/index.d.ts +21 -0
- package/dist/controllers/common/index.js +21 -0
- package/dist/controllers/common/index.js.map +1 -0
- package/dist/controllers/common/statics.d.ts +215 -0
- package/dist/controllers/common/statics.js +202 -0
- package/dist/controllers/common/statics.js.map +1 -0
- package/dist/controllers/index.d.ts +24 -0
- package/dist/controllers/index.js +20 -0
- package/dist/controllers/index.js.map +1 -0
- package/dist/controllers/utils/gateway.d.ts +724 -0
- package/dist/controllers/utils/gateway.js +425 -0
- package/dist/controllers/utils/gateway.js.map +1 -0
- package/dist/controllers/utils/index.d.ts +16 -0
- package/dist/controllers/utils/index.js +19 -0
- package/dist/controllers/utils/index.js.map +1 -0
- package/dist/esm/app/index.js +2 -0
- package/dist/esm/app/index.js.map +1 -0
- package/dist/esm/app/jimpex.js +415 -0
- package/dist/esm/app/jimpex.js.map +1 -0
- package/dist/esm/chunk-T2T6Q22Z.js +11 -0
- package/dist/esm/chunk-T2T6Q22Z.js.map +1 -0
- package/dist/esm/controllers/common/config.js +62 -0
- package/dist/esm/controllers/common/config.js.map +1 -0
- package/dist/esm/controllers/common/health.js +70 -0
- package/dist/esm/controllers/common/health.js.map +1 -0
- package/dist/esm/controllers/common/index.js +4 -0
- package/dist/esm/controllers/common/index.js.map +1 -0
- package/dist/esm/controllers/common/statics.js +173 -0
- package/dist/esm/controllers/common/statics.js.map +1 -0
- package/dist/esm/controllers/index.js +3 -0
- package/dist/esm/controllers/index.js.map +1 -0
- package/dist/esm/controllers/utils/gateway.js +404 -0
- package/dist/esm/controllers/utils/gateway.js.map +1 -0
- package/dist/esm/controllers/utils/index.js +2 -0
- package/dist/esm/controllers/utils/index.js.map +1 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/middlewares/common/errorHandler.js +92 -0
- package/dist/esm/middlewares/common/errorHandler.js.map +1 -0
- package/dist/esm/middlewares/common/forceHTTPS.js +41 -0
- package/dist/esm/middlewares/common/forceHTTPS.js.map +1 -0
- package/dist/esm/middlewares/common/hsts.js +53 -0
- package/dist/esm/middlewares/common/hsts.js.map +1 -0
- package/dist/esm/middlewares/common/index.js +4 -0
- package/dist/esm/middlewares/common/index.js.map +1 -0
- package/dist/esm/middlewares/html/fastHTML.js +104 -0
- package/dist/esm/middlewares/html/fastHTML.js.map +1 -0
- package/dist/esm/middlewares/html/index.js +3 -0
- package/dist/esm/middlewares/html/index.js.map +1 -0
- package/dist/esm/middlewares/html/showHTML.js +68 -0
- package/dist/esm/middlewares/html/showHTML.js.map +1 -0
- package/dist/esm/middlewares/index.js +4 -0
- package/dist/esm/middlewares/index.js.map +1 -0
- package/dist/esm/middlewares/utils/index.js +2 -0
- package/dist/esm/middlewares/utils/index.js.map +1 -0
- package/dist/esm/middlewares/utils/versionValidator.js +101 -0
- package/dist/esm/middlewares/utils/versionValidator.js.map +1 -0
- package/dist/esm/services/common/appError.js +52 -0
- package/dist/esm/services/common/appError.js.map +1 -0
- package/dist/esm/services/common/httpError.js +19 -0
- package/dist/esm/services/common/httpError.js.map +1 -0
- package/dist/esm/services/common/index.js +17 -0
- package/dist/esm/services/common/index.js.map +1 -0
- package/dist/esm/services/common/sendFile.js +27 -0
- package/dist/esm/services/common/sendFile.js.map +1 -0
- package/dist/esm/services/frontend/frontendFs.js +38 -0
- package/dist/esm/services/frontend/frontendFs.js.map +1 -0
- package/dist/esm/services/frontend/index.js +11 -0
- package/dist/esm/services/frontend/index.js.map +1 -0
- package/dist/esm/services/html/htmlGenerator.js +144 -0
- package/dist/esm/services/html/htmlGenerator.js.map +1 -0
- package/dist/esm/services/html/index.js +11 -0
- package/dist/esm/services/html/index.js.map +1 -0
- package/dist/esm/services/http/apiClient.js +71 -0
- package/dist/esm/services/http/apiClient.js.map +1 -0
- package/dist/esm/services/http/http.js +125 -0
- package/dist/esm/services/http/http.js.map +1 -0
- package/dist/esm/services/http/index.js +17 -0
- package/dist/esm/services/http/index.js.map +1 -0
- package/dist/esm/services/http/responsesBuilder.js +105 -0
- package/dist/esm/services/http/responsesBuilder.js.map +1 -0
- package/dist/esm/services/index.js +6 -0
- package/dist/esm/services/index.js.map +1 -0
- package/dist/esm/services/utils/ensureBearerToken.js +78 -0
- package/dist/esm/services/utils/ensureBearerToken.js.map +1 -0
- package/dist/esm/services/utils/index.js +11 -0
- package/dist/esm/services/utils/index.js.map +1 -0
- package/dist/esm/types/events.js +1 -0
- package/dist/esm/types/events.js.map +1 -0
- package/dist/esm/types/express.js +1 -0
- package/dist/esm/types/express.js.map +1 -0
- package/dist/esm/types/http.js +1 -0
- package/dist/esm/types/http.js.map +1 -0
- package/dist/esm/types/index.js +7 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/options.js +1 -0
- package/dist/esm/types/options.js.map +1 -0
- package/dist/esm/types/utils.js +1 -0
- package/dist/esm/types/utils.js.map +1 -0
- package/dist/esm/types/wootils.js +1 -0
- package/dist/esm/types/wootils.js.map +1 -0
- package/dist/esm/utils/fns/index.js +5 -0
- package/dist/esm/utils/fns/index.js.map +1 -0
- package/dist/esm/utils/fns/others.js +6 -0
- package/dist/esm/utils/fns/others.js.map +1 -0
- package/dist/esm/utils/fns/routes.js +25 -0
- package/dist/esm/utils/fns/routes.js.map +1 -0
- package/dist/esm/utils/fns/statuses.js +6 -0
- package/dist/esm/utils/fns/statuses.js.map +1 -0
- package/dist/esm/utils/fns/text.js +6 -0
- package/dist/esm/utils/fns/text.js.map +1 -0
- package/dist/esm/utils/index.js +3 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/wrappers.js +41 -0
- package/dist/esm/utils/wrappers.js.map +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/jimpex-7eaee271.d.ts +1278 -0
- package/dist/middlewares/common/errorHandler.d.ts +131 -0
- package/dist/middlewares/common/errorHandler.js +119 -0
- package/dist/middlewares/common/errorHandler.js.map +1 -0
- package/dist/middlewares/common/forceHTTPS.d.ts +68 -0
- package/dist/middlewares/common/forceHTTPS.js +68 -0
- package/dist/middlewares/common/forceHTTPS.js.map +1 -0
- package/dist/middlewares/common/hsts.d.ts +109 -0
- package/dist/middlewares/common/hsts.js +80 -0
- package/dist/middlewares/common/hsts.js.map +1 -0
- package/dist/middlewares/common/index.d.ts +21 -0
- package/dist/middlewares/common/index.js +21 -0
- package/dist/middlewares/common/index.js.map +1 -0
- package/dist/middlewares/html/fastHTML.d.ts +180 -0
- package/dist/middlewares/html/fastHTML.js +131 -0
- package/dist/middlewares/html/fastHTML.js.map +1 -0
- package/dist/middlewares/html/index.d.ts +21 -0
- package/dist/middlewares/html/index.js +20 -0
- package/dist/middlewares/html/index.js.map +1 -0
- package/dist/middlewares/html/showHTML.d.ts +127 -0
- package/dist/middlewares/html/showHTML.js +95 -0
- package/dist/middlewares/html/showHTML.js.map +1 -0
- package/dist/middlewares/index.d.ts +30 -0
- package/dist/middlewares/index.js +21 -0
- package/dist/middlewares/index.js.map +1 -0
- package/dist/middlewares/utils/index.d.ts +19 -0
- package/dist/middlewares/utils/index.js +19 -0
- package/dist/middlewares/utils/index.js.map +1 -0
- package/dist/middlewares/utils/versionValidator.d.ts +214 -0
- package/dist/middlewares/utils/versionValidator.js +128 -0
- package/dist/middlewares/utils/versionValidator.js.map +1 -0
- package/dist/services/common/appError.d.ts +138 -0
- package/dist/services/common/appError.js +80 -0
- package/dist/services/common/appError.js.map +1 -0
- package/dist/services/common/httpError.d.ts +79 -0
- package/dist/services/common/httpError.js +44 -0
- package/dist/services/common/httpError.js.map +1 -0
- package/dist/services/common/index.d.ts +47 -0
- package/dist/services/common/index.js +41 -0
- package/dist/services/common/index.js.map +1 -0
- package/dist/services/common/sendFile.d.ts +102 -0
- package/dist/services/common/sendFile.js +51 -0
- package/dist/services/common/sendFile.js.map +1 -0
- package/dist/services/frontend/frontendFs.d.ts +96 -0
- package/dist/services/frontend/frontendFs.js +71 -0
- package/dist/services/frontend/frontendFs.js.map +1 -0
- package/dist/services/frontend/index.d.ts +40 -0
- package/dist/services/frontend/index.js +35 -0
- package/dist/services/frontend/index.js.map +1 -0
- package/dist/services/html/htmlGenerator.d.ts +237 -0
- package/dist/services/html/htmlGenerator.js +171 -0
- package/dist/services/html/htmlGenerator.js.map +1 -0
- package/dist/services/html/index.d.ts +43 -0
- package/dist/services/html/index.js +35 -0
- package/dist/services/html/index.js.map +1 -0
- package/dist/services/http/apiClient.d.ts +169 -0
- package/dist/services/http/apiClient.js +96 -0
- package/dist/services/http/apiClient.js.map +1 -0
- package/dist/services/http/http.d.ts +175 -0
- package/dist/services/http/http.js +158 -0
- package/dist/services/http/http.js.map +1 -0
- package/dist/services/http/index.d.ts +50 -0
- package/dist/services/http/index.js +41 -0
- package/dist/services/http/index.js.map +1 -0
- package/dist/services/http/responsesBuilder.d.ts +178 -0
- package/dist/services/http/responsesBuilder.js +132 -0
- package/dist/services/http/responsesBuilder.js.map +1 -0
- package/dist/services/index.d.ts +33 -0
- package/dist/services/index.js +23 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/utils/ensureBearerToken.d.ts +157 -0
- package/dist/services/utils/ensureBearerToken.js +105 -0
- package/dist/services/utils/ensureBearerToken.js.map +1 -0
- package/dist/services/utils/index.d.ts +43 -0
- package/dist/services/utils/index.js +35 -0
- package/dist/services/utils/index.js.map +1 -0
- package/dist/types/events.d.ts +13 -0
- package/dist/types/events.js +17 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/express.d.ts +10 -0
- package/dist/types/express.js +17 -0
- package/dist/types/express.js.map +1 -0
- package/dist/types/http.d.ts +79 -0
- package/dist/types/http.js +17 -0
- package/dist/types/http.js.map +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.js +24 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/options.d.ts +13 -0
- package/dist/types/options.js +17 -0
- package/dist/types/options.js.map +1 -0
- package/dist/types/utils.d.ts +48 -0
- package/dist/types/utils.js +17 -0
- package/dist/types/utils.js.map +1 -0
- package/dist/types/wootils.d.ts +4 -0
- package/dist/types/wootils.js +17 -0
- package/dist/types/wootils.js.map +1 -0
- package/dist/utils/fns/index.d.ts +5 -0
- package/dist/utils/fns/index.js +22 -0
- package/dist/utils/fns/index.js.map +1 -0
- package/dist/utils/fns/others.d.ts +17 -0
- package/dist/utils/fns/others.js +29 -0
- package/dist/utils/fns/others.js.map +1 -0
- package/dist/utils/fns/routes.d.ts +39 -0
- package/dist/utils/fns/routes.js +51 -0
- package/dist/utils/fns/routes.js.map +1 -0
- package/dist/utils/fns/statuses.d.ts +45 -0
- package/dist/utils/fns/statuses.js +35 -0
- package/dist/utils/fns/statuses.js.map +1 -0
- package/dist/utils/fns/text.d.ts +9 -0
- package/dist/utils/fns/text.js +29 -0
- package/dist/utils/fns/text.js.map +1 -0
- package/dist/utils/index.d.ts +18 -0
- package/dist/utils/index.js +20 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/wrappers.d.ts +13 -0
- package/dist/utils/wrappers.js +68 -0
- package/dist/utils/wrappers.js.map +1 -0
- package/examples/basic/404.html +12 -0
- package/examples/basic/README.md +30 -0
- package/examples/basic/app.ts +18 -0
- package/examples/basic/controller.ts +45 -0
- package/examples/basic/index.ts +19 -0
- package/examples/basic/middleware.ts +13 -0
- package/examples/basic/service.ts +11 -0
- package/package.json +59 -38
- package/src/app/index.ts +1 -0
- package/src/app/jimpex.ts +743 -0
- package/src/controllers/common/config.ts +115 -0
- package/src/controllers/common/health.ts +128 -0
- package/src/controllers/common/index.ts +3 -0
- package/src/controllers/common/statics.ts +380 -0
- package/src/controllers/index.ts +2 -0
- package/src/controllers/utils/gateway.ts +1186 -0
- package/src/controllers/utils/index.ts +1 -0
- package/src/index.ts +6 -0
- package/src/middlewares/common/errorHandler.ts +203 -0
- package/src/middlewares/common/forceHTTPS.ts +83 -0
- package/src/middlewares/common/hsts.ts +135 -0
- package/src/middlewares/common/index.ts +3 -0
- package/src/middlewares/html/fastHTML.ts +255 -0
- package/src/middlewares/html/index.ts +2 -0
- package/src/middlewares/html/showHTML.ts +165 -0
- package/src/middlewares/index.ts +3 -0
- package/src/middlewares/utils/index.ts +1 -0
- package/src/middlewares/utils/versionValidator.ts +289 -0
- package/src/services/common/appError.ts +158 -0
- package/src/services/common/httpError.ts +74 -0
- package/src/services/common/index.ts +29 -0
- package/src/services/common/sendFile.ts +106 -0
- package/src/services/frontend/frontendFs.ts +101 -0
- package/src/services/frontend/index.ts +21 -0
- package/src/services/html/htmlGenerator.ts +356 -0
- package/src/services/html/index.ts +21 -0
- package/src/services/http/apiClient.ts +221 -0
- package/src/services/http/http.ts +286 -0
- package/src/services/http/index.ts +29 -0
- package/src/services/http/responsesBuilder.ts +265 -0
- package/src/services/index.ts +5 -0
- package/src/services/utils/ensureBearerToken.ts +202 -0
- package/src/services/utils/index.ts +21 -0
- package/src/types/events.ts +303 -0
- package/src/types/express.ts +21 -0
- package/src/types/http.ts +77 -0
- package/src/types/index.ts +6 -0
- package/src/types/options.ts +248 -0
- package/src/types/utils.ts +52 -0
- package/src/types/wootils.ts +4 -0
- package/src/utils/fns/index.ts +4 -0
- package/src/utils/fns/others.ts +15 -0
- package/src/utils/fns/routes.ts +64 -0
- package/src/utils/fns/statuses.ts +44 -0
- package/src/utils/fns/text.ts +8 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/wrappers.ts +537 -0
- package/tsconfig.json +5 -8
- package/tsup.config.ts +10 -0
- package/src/app/index.js +0 -692
- package/src/constants/eventNames.js +0 -48
- package/src/constants/index.js +0 -7
- package/src/controllers/common/configuration.js +0 -116
- package/src/controllers/common/health.js +0 -79
- package/src/controllers/common/index.js +0 -7
- package/src/controllers/common/statics.js +0 -336
- package/src/controllers/index.js +0 -9
- package/src/controllers/utils/gateway.js +0 -1039
- package/src/controllers/utils/index.js +0 -3
- package/src/index.js +0 -30
- package/src/middlewares/common/errorHandler.js +0 -185
- package/src/middlewares/common/forceHTTPS.js +0 -80
- package/src/middlewares/common/hsts.js +0 -122
- package/src/middlewares/common/index.js +0 -7
- package/src/middlewares/html/fastHTML.js +0 -298
- package/src/middlewares/html/index.js +0 -5
- package/src/middlewares/html/showHTML.js +0 -167
- package/src/middlewares/index.js +0 -11
- package/src/middlewares/utils/index.js +0 -3
- package/src/middlewares/utils/versionValidator.js +0 -261
- package/src/services/common/appError.js +0 -136
- package/src/services/common/httpError.js +0 -60
- package/src/services/common/index.js +0 -25
- package/src/services/common/sendFile.js +0 -68
- package/src/services/frontend/frontendFs.js +0 -85
- package/src/services/frontend/index.js +0 -17
- package/src/services/html/htmlGenerator.js +0 -391
- package/src/services/html/index.js +0 -17
- package/src/services/http/apiClient.js +0 -148
- package/src/services/http/http.js +0 -256
- package/src/services/http/index.js +0 -25
- package/src/services/http/responsesBuilder.js +0 -193
- package/src/services/index.js +0 -15
- package/src/services/utils/ensureBearerToken.js +0 -147
- package/src/services/utils/index.js +0 -19
- package/src/types.js +0 -377
- package/src/utils/functions.js +0 -78
- package/src/utils/wrappers.js +0 -131
- package/types/app/index.d.ts +0 -417
- package/types/constants/eventNames.d.ts +0 -93
- package/types/constants/index.d.ts +0 -2
- package/types/controllers/common/configuration.d.ts +0 -71
- package/types/controllers/common/health.d.ts +0 -55
- package/types/controllers/common/index.d.ts +0 -4
- package/types/controllers/common/statics.d.ts +0 -271
- package/types/controllers/index.d.ts +0 -3
- package/types/controllers/utils/gateway.d.ts +0 -947
- package/types/controllers/utils/index.d.ts +0 -2
- package/types/index.d.ts +0 -15
- package/types/middlewares/common/errorHandler.d.ts +0 -143
- package/types/middlewares/common/forceHTTPS.d.ts +0 -64
- package/types/middlewares/common/hsts.d.ts +0 -111
- package/types/middlewares/common/index.d.ts +0 -4
- package/types/middlewares/html/fastHTML.d.ts +0 -238
- package/types/middlewares/html/index.d.ts +0 -3
- package/types/middlewares/html/showHTML.d.ts +0 -128
- package/types/middlewares/index.d.ts +0 -4
- package/types/middlewares/utils/index.d.ts +0 -2
- package/types/middlewares/utils/versionValidator.d.ts +0 -247
- package/types/services/common/appError.d.ts +0 -89
- package/types/services/common/httpError.d.ts +0 -37
- package/types/services/common/index.d.ts +0 -18
- package/types/services/common/sendFile.d.ts +0 -56
- package/types/services/frontend/frontendFs.d.ts +0 -72
- package/types/services/frontend/index.d.ts +0 -3
- package/types/services/html/htmlGenerator.d.ts +0 -298
- package/types/services/html/index.d.ts +0 -3
- package/types/services/http/apiClient.d.ts +0 -141
- package/types/services/http/http.d.ts +0 -159
- package/types/services/http/index.d.ts +0 -18
- package/types/services/http/responsesBuilder.d.ts +0 -140
- package/types/services/index.d.ts +0 -6
- package/types/services/utils/ensureBearerToken.d.ts +0 -137
- package/types/services/utils/index.d.ts +0 -16
- package/types/types.d.ts +0 -280
- package/types/utils/functions.d.ts +0 -55
- package/types/utils/wrappers.d.ts +0 -127
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__publicField
|
|
3
|
+
} from "../../chunk-T2T6Q22Z.js";
|
|
4
|
+
import * as path from "path";
|
|
5
|
+
import * as mime from "mime";
|
|
6
|
+
import { deepAssignWithOverwrite } from "@homer0/deep-assign";
|
|
7
|
+
import {
|
|
8
|
+
controllerCreator,
|
|
9
|
+
removeSlashes,
|
|
10
|
+
notUndefined
|
|
11
|
+
} from "../../utils";
|
|
12
|
+
class StaticsController {
|
|
13
|
+
constructor({ inject, ...options }) {
|
|
14
|
+
__publicField(this, "_sendFile");
|
|
15
|
+
__publicField(this, "_options");
|
|
16
|
+
__publicField(this, "files");
|
|
17
|
+
this._sendFile = inject.sendFile;
|
|
18
|
+
this._options = this._validateOptions(
|
|
19
|
+
deepAssignWithOverwrite(
|
|
20
|
+
{
|
|
21
|
+
files: ["favicon.ico", "index.html"],
|
|
22
|
+
methods: options.methods || {
|
|
23
|
+
all: false,
|
|
24
|
+
get: true
|
|
25
|
+
},
|
|
26
|
+
paths: {
|
|
27
|
+
route: "",
|
|
28
|
+
source: "./"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
options
|
|
32
|
+
)
|
|
33
|
+
);
|
|
34
|
+
this.files = this._createFiles();
|
|
35
|
+
}
|
|
36
|
+
addRoutes(router, middlewares = []) {
|
|
37
|
+
const { methods } = this._options;
|
|
38
|
+
const use = methods.all ? ["all"] : Object.keys(methods).reduce((acc, name) => {
|
|
39
|
+
const methodName = name;
|
|
40
|
+
if (methods[methodName]) {
|
|
41
|
+
acc.push(methodName);
|
|
42
|
+
}
|
|
43
|
+
return acc;
|
|
44
|
+
}, []);
|
|
45
|
+
Object.keys(this.files).forEach((route) => {
|
|
46
|
+
const file = this.files[route];
|
|
47
|
+
const fileMiddleware = this._getMiddleware(file);
|
|
48
|
+
use.forEach(
|
|
49
|
+
(method) => this._addRoute({ router, method, file, fileMiddleware, middlewares })
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
return router;
|
|
53
|
+
}
|
|
54
|
+
get options() {
|
|
55
|
+
return { ...this._options };
|
|
56
|
+
}
|
|
57
|
+
_getMiddleware(file) {
|
|
58
|
+
return (_, res, next) => {
|
|
59
|
+
const extension = path.parse(file.path).ext.substring(1);
|
|
60
|
+
const headers = {
|
|
61
|
+
"Content-Type": mime.getType(extension) || "text/html",
|
|
62
|
+
...file.headers
|
|
63
|
+
};
|
|
64
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
65
|
+
res.setHeader(key, value);
|
|
66
|
+
});
|
|
67
|
+
this._sendFile({
|
|
68
|
+
res,
|
|
69
|
+
filepath: file.path,
|
|
70
|
+
next
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
_addRoute({
|
|
75
|
+
router,
|
|
76
|
+
method,
|
|
77
|
+
file,
|
|
78
|
+
fileMiddleware,
|
|
79
|
+
middlewares
|
|
80
|
+
}) {
|
|
81
|
+
const { route } = file;
|
|
82
|
+
router[method](route, [...middlewares, fileMiddleware]);
|
|
83
|
+
}
|
|
84
|
+
_validateOptions(options) {
|
|
85
|
+
if (!options.files || !options.files.length) {
|
|
86
|
+
throw new Error("You need to specify a list of files");
|
|
87
|
+
}
|
|
88
|
+
if (!options.methods) {
|
|
89
|
+
throw new Error("You need to specify which HTTP methods are allowed for the files");
|
|
90
|
+
}
|
|
91
|
+
const methods = Object.keys(options.methods);
|
|
92
|
+
const atLeastOne = methods.some((method) => options.methods[method]);
|
|
93
|
+
if (!atLeastOne) {
|
|
94
|
+
throw new Error("You need to enable at least one HTTP method to serve the files");
|
|
95
|
+
}
|
|
96
|
+
const allowedMethods = [
|
|
97
|
+
"all",
|
|
98
|
+
"get",
|
|
99
|
+
"head",
|
|
100
|
+
"post",
|
|
101
|
+
"patch",
|
|
102
|
+
"put",
|
|
103
|
+
"delete",
|
|
104
|
+
"connect",
|
|
105
|
+
"options",
|
|
106
|
+
"trace"
|
|
107
|
+
];
|
|
108
|
+
const invalid = methods.find(
|
|
109
|
+
(method) => !allowedMethods.includes(method.toLowerCase())
|
|
110
|
+
);
|
|
111
|
+
if (invalid) {
|
|
112
|
+
throw new Error(`${invalid} is not a valid HTTP method`);
|
|
113
|
+
}
|
|
114
|
+
const newMethods = methods.reduce((acc, method) => {
|
|
115
|
+
acc[method.toLowerCase()] = !!options.methods[method];
|
|
116
|
+
return acc;
|
|
117
|
+
}, {});
|
|
118
|
+
return {
|
|
119
|
+
...options,
|
|
120
|
+
methods: newMethods
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
_createFiles() {
|
|
124
|
+
const { files, paths } = this._options;
|
|
125
|
+
const routePath = removeSlashes(paths.route, false, true);
|
|
126
|
+
return files.reduce((acc, file) => {
|
|
127
|
+
let src;
|
|
128
|
+
let route;
|
|
129
|
+
let headers;
|
|
130
|
+
if (typeof file === "object") {
|
|
131
|
+
({ route, path: src, headers } = file);
|
|
132
|
+
} else {
|
|
133
|
+
src = file;
|
|
134
|
+
route = file;
|
|
135
|
+
}
|
|
136
|
+
src = path.join(paths.source, src);
|
|
137
|
+
route = removeSlashes(route, true, false);
|
|
138
|
+
route = `${routePath}/${route}`;
|
|
139
|
+
acc[route] = {
|
|
140
|
+
path: src,
|
|
141
|
+
route,
|
|
142
|
+
headers: headers || {}
|
|
143
|
+
};
|
|
144
|
+
return acc;
|
|
145
|
+
}, {});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const staticsController = controllerCreator(
|
|
149
|
+
({ getMiddlewares, ...options } = {}) => (app) => {
|
|
150
|
+
const router = app.getRouter();
|
|
151
|
+
const ctrl = new StaticsController({
|
|
152
|
+
inject: {
|
|
153
|
+
sendFile: app.get("sendFile")
|
|
154
|
+
},
|
|
155
|
+
...options
|
|
156
|
+
});
|
|
157
|
+
let useMiddlewares;
|
|
158
|
+
if (getMiddlewares) {
|
|
159
|
+
useMiddlewares = getMiddlewares(app).map((middleware) => {
|
|
160
|
+
if ("middleware" in middleware) {
|
|
161
|
+
return middleware.connect(app);
|
|
162
|
+
}
|
|
163
|
+
return middleware;
|
|
164
|
+
}).filter(notUndefined);
|
|
165
|
+
}
|
|
166
|
+
return ctrl.addRoutes(router, useMiddlewares);
|
|
167
|
+
}
|
|
168
|
+
);
|
|
169
|
+
export {
|
|
170
|
+
StaticsController,
|
|
171
|
+
staticsController
|
|
172
|
+
};
|
|
173
|
+
//# sourceMappingURL=statics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/controllers/common/statics.ts"],"sourcesContent":["import * as path from 'path';\nimport * as mime from 'mime';\nimport { deepAssignWithOverwrite } from '@homer0/deep-assign';\nimport {\n controllerCreator,\n removeSlashes,\n notUndefined,\n type MiddlewareLike,\n} from '../../utils';\nimport type { SendFile } from '../../services';\nimport type { Jimpex } from '../../app';\nimport type { DeepPartial, ExpressMiddleware, Router, RouterMethod } from '../../types';\n/**\n * The definition for each file the controller handles.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerFile = {\n /**\n * The route, relative to the controller root, to the file.\n */\n route: string;\n /**\n * The path to the file in the filesystem. Since the file is served using the\n * {@link SendFile} service, whether the file is relative to the project root or the\n * application executable depends on how the service is configured (relative to the\n * executable by default).\n */\n path: string;\n /**\n * A dictionary of headers for the response.\n */\n headers?: Record<string, string>;\n};\n/**\n * These are like \"master paths\" that get prepended to all the file paths and routes the\n * controller use.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerPathsOptions = {\n /**\n * A custom route to prefix all the file routes with.\n */\n route: string;\n /**\n * A custom path to prefix all the file paths with.\n */\n source: string;\n};\n/**\n * The options to customize the controller.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerOptions = {\n /**\n * A list of filenames, or definitions for the files to handle.\n */\n files: Array<string | StaticsControllerFile>;\n /**\n * A dictionary with the allowed router (HTTP) methods the controller can use to serve\n * the files. If `all` is set to `true`, the rest of the values will be ignored.\n *\n * @default {get: true, all: false}\n */\n methods: Partial<Record<RouterMethod, boolean>>;\n /**\n * The \"master paths\" the controller can use to prefix the file paths and routes.\n *\n * @default {route: '', source: './',}\n */\n paths: StaticsControllerPathsOptions;\n};\n/**\n * The options to construct a {@link StaticsController}.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerConstructorOptions =\n DeepPartial<StaticsControllerOptions> & {\n /**\n * A dictionary with the dependencies to inject.\n */\n inject: {\n sendFile: SendFile;\n };\n };\n/**\n * A function to generate a list of middlewares that can be executed before the tontroller\n * main middleware.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerGetMiddlewaresFn = (app: Jimpex) => MiddlewareLike[];\n/**\n * The options for the controller creator that mounts {@link StaticsController}.\n *\n * @group Controllers/Statics\n */\nexport type StaticsControllerCreatorOptions = DeepPartial<StaticsControllerOptions> & {\n /**\n * A function to generate a list of middlewares that can be executed before the\n * tontroller main middleware.\n */\n getMiddlewares?: StaticsControllerGetMiddlewaresFn;\n};\n/**\n * The options for {@link StaticsController._addRoute}.\n *\n * @access protected\n * @group Controllers/Statics\n */\nexport type AddStaticRouteOptions = {\n /**\n * The reference for the router in which the middlewares will be added.\n */\n router: Router;\n /**\n * The router method in which the middlewares will be added.\n */\n method: RouterMethod;\n /**\n * The definition of the file to serve.\n */\n file: StaticsControllerFile;\n /**\n * The middleware created by {@link StaticsController}, that will serve the file.\n */\n fileMiddleware: ExpressMiddleware;\n /**\n * A list of extra middlewares to execute before the file middleware.\n */\n middlewares: ExpressMiddleware[];\n};\n\n/**\n * The controller class that allows the application to serve specific files from any\n * folder to any route without the need of mounting directories as \"static\".\n *\n * @group Controller Classes\n * @group Controllers/Statics\n * @prettierignore\n */\nexport class StaticsController {\n /**\n * The service that serves static files.\n */\n protected readonly _sendFile: SendFile;\n /**\n * The controller customization options.\n */\n protected _options: StaticsControllerOptions;\n /**\n * A dictionary with the formatted definitions of the files that will be served.\n * It uses the files' routes as keys, for easy access in the middleware.\n */\n protected files: Record<string, StaticsControllerFile>;\n /**\n * @param options The options to construct the controller.\n */\n constructor({ inject, ...options }: StaticsControllerConstructorOptions) {\n this._sendFile = inject.sendFile;\n this._options = this._validateOptions(\n deepAssignWithOverwrite(\n {\n files: ['favicon.ico', 'index.html'],\n methods: options.methods || {\n all: false,\n get: true,\n },\n paths: {\n route: '',\n source: './',\n },\n },\n options,\n ),\n );\n this.files = this._createFiles();\n }\n /**\n * Mounts the middlewares in the router in order to serve the files.\n *\n * @param router A reference to the application router.\n * @param middlewares A list of extra middlewares to execute before the file\n * middleware.\n */\n addRoutes(router: Router, middlewares: ExpressMiddleware[] = []): Router {\n const { methods } = this._options;\n const use: RouterMethod[] = methods.all\n ? ['all']\n : Object.keys(methods).reduce<RouterMethod[]>((acc, name) => {\n const methodName = name as RouterMethod;\n if (methods[methodName]) {\n acc.push(methodName);\n }\n\n return acc;\n }, []);\n\n Object.keys(this.files).forEach((route) => {\n const file = this.files[route as keyof typeof this.files]!;\n const fileMiddleware = this._getMiddleware(file);\n use.forEach((method) =>\n this._addRoute({ router, method, file, fileMiddleware, middlewares }),\n );\n });\n\n return router;\n }\n /**\n * The controller options.\n */\n get options(): Readonly<StaticsControllerOptions> {\n return { ...this._options };\n }\n /**\n * Generates the middleware that will serve the file.\n *\n * @param file The definition of the file to serve.\n */\n protected _getMiddleware(file: StaticsControllerFile): ExpressMiddleware {\n return (_, res, next) => {\n const extension = path.parse(file.path).ext.substring(1);\n const headers = {\n 'Content-Type': mime.getType(extension) || 'text/html',\n ...file.headers,\n };\n\n Object.entries(headers).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n\n this._sendFile({\n res,\n filepath: file.path,\n next,\n });\n };\n }\n /**\n * Mounts the middleware(s) for a file in the router.\n *\n * @param options The information of the file and how it needs to be added.\n */\n protected _addRoute({\n router,\n method,\n file,\n fileMiddleware,\n middlewares,\n }: AddStaticRouteOptions): void {\n const { route } = file;\n router[method](route, [...middlewares, fileMiddleware]);\n }\n /**\n * Validates and formats the options sent to the constructor in order to get the final\n * set that will be stored in the controller.\n *\n * @param options The options to validate.\n * @throws If no files are specified.\n * @throws If methods is not defined.\n * @throws If no methods are enabled.\n * @throws If there's an invalid HTTP method.\n */\n protected _validateOptions(\n options: StaticsControllerOptions,\n ): StaticsControllerOptions {\n if (!options.files || !options.files.length) {\n throw new Error('You need to specify a list of files');\n }\n\n if (!options.methods) {\n throw new Error('You need to specify which HTTP methods are allowed for the files');\n }\n\n const methods = Object.keys(options.methods) as RouterMethod[];\n\n const atLeastOne = methods.some((method) => options.methods[method]);\n if (!atLeastOne) {\n throw new Error('You need to enable at least one HTTP method to serve the files');\n }\n\n const allowedMethods: RouterMethod[] = [\n 'all',\n 'get',\n 'head',\n 'post',\n 'patch',\n 'put',\n 'delete',\n 'connect',\n 'options',\n 'trace',\n ];\n\n const invalid = methods.find(\n (method) => !allowedMethods.includes(method.toLowerCase() as RouterMethod),\n );\n\n if (invalid) {\n throw new Error(`${invalid} is not a valid HTTP method`);\n }\n\n const newMethods = methods.reduce<Record<string, boolean>>((acc, method) => {\n acc[method.toLowerCase()] = !!options.methods[method];\n return acc;\n }, {});\n\n return {\n ...options,\n methods: newMethods,\n };\n }\n /**\n * Parses the files received from the constructor's options, and formats them into\n * proper definitions the controller can use.\n */\n protected _createFiles(): Record<string, StaticsControllerFile> {\n const { files, paths } = this._options;\n const routePath = removeSlashes(paths.route, false, true);\n return files.reduce<Record<string, StaticsControllerFile>>((acc, file) => {\n let src;\n let route;\n let headers;\n if (typeof file === 'object') {\n ({ route, path: src, headers } = file);\n } else {\n src = file;\n route = file;\n }\n\n src = path.join(paths.source, src);\n route = removeSlashes(route, true, false);\n route = `${routePath}/${route}`;\n acc[route] = {\n path: src,\n route,\n headers: headers || {},\n };\n\n return acc;\n }, {});\n }\n}\n/**\n * A controller that allows the application to server specific files from any folder to\n * any route without the need of mounting directories as \"static\" folders.\n *\n * @group Controllers\n * @group Controllers/Statics\n */\nexport const staticsController = controllerCreator(\n ({ getMiddlewares, ...options }: StaticsControllerCreatorOptions = {}) =>\n (app) => {\n const router = app.getRouter();\n const ctrl = new StaticsController({\n inject: {\n sendFile: app.get('sendFile'),\n },\n ...options,\n });\n\n let useMiddlewares: ExpressMiddleware[] | undefined;\n if (getMiddlewares) {\n useMiddlewares = getMiddlewares(app)\n .map((middleware) => {\n if ('middleware' in middleware) {\n return middleware.connect(app) as ExpressMiddleware | undefined;\n }\n\n return middleware as ExpressMiddleware;\n })\n .filter(notUndefined);\n }\n\n return ctrl.addRoutes(router, useMiddlewares);\n },\n);\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/controllers/index.ts"],"sourcesContent":["export * from './common';\nexport * from './utils';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;","names":[]}
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__publicField
|
|
3
|
+
} from "../../chunk-T2T6Q22Z.js";
|
|
4
|
+
import { deepAssignWithOverwrite } from "@homer0/deep-assign";
|
|
5
|
+
import { flat, unflat } from "@homer0/object-utils";
|
|
6
|
+
import {
|
|
7
|
+
controllerProviderCreator,
|
|
8
|
+
controller,
|
|
9
|
+
createRouteExpression,
|
|
10
|
+
removeSlashes,
|
|
11
|
+
notUndefined
|
|
12
|
+
} from "../../utils";
|
|
13
|
+
class GatewayController {
|
|
14
|
+
constructor({
|
|
15
|
+
inject,
|
|
16
|
+
route,
|
|
17
|
+
gatewayConfig,
|
|
18
|
+
...options
|
|
19
|
+
}) {
|
|
20
|
+
__publicField(this, "http");
|
|
21
|
+
__publicField(this, "_getHelperService");
|
|
22
|
+
__publicField(this, "_gatewayConfig");
|
|
23
|
+
__publicField(this, "_route");
|
|
24
|
+
__publicField(this, "_routeExpression");
|
|
25
|
+
__publicField(this, "_options");
|
|
26
|
+
__publicField(this, "_endpoints");
|
|
27
|
+
__publicField(this, "_apiConfigUrl");
|
|
28
|
+
__publicField(this, "_apiConfigEndpoints");
|
|
29
|
+
__publicField(this, "_routes");
|
|
30
|
+
this.http = inject.http;
|
|
31
|
+
this._getHelperService = inject.getHelperService || (() => void 0);
|
|
32
|
+
this._route = removeSlashes(route);
|
|
33
|
+
this._options = this._formatOptions(
|
|
34
|
+
deepAssignWithOverwrite(
|
|
35
|
+
{
|
|
36
|
+
root: "",
|
|
37
|
+
apiConfigSetting: "api",
|
|
38
|
+
headers: {
|
|
39
|
+
useXForwardedFor: true,
|
|
40
|
+
copyCustomHeaders: true,
|
|
41
|
+
copy: ["authorization", "content-type", "referer", "user-agent"],
|
|
42
|
+
remove: ["server", "x-powered-by", "content-encoding"]
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
options
|
|
46
|
+
)
|
|
47
|
+
);
|
|
48
|
+
this._gatewayConfig = {
|
|
49
|
+
...gatewayConfig,
|
|
50
|
+
url: removeSlashes(gatewayConfig.url, false, true)
|
|
51
|
+
};
|
|
52
|
+
this._routeExpression = createRouteExpression(
|
|
53
|
+
this._options.root ? `${this._route}/${this._options.root}` : this._route,
|
|
54
|
+
true,
|
|
55
|
+
true
|
|
56
|
+
);
|
|
57
|
+
this._endpoints = this._formatEndpoints();
|
|
58
|
+
this._routes = this._createRoutes();
|
|
59
|
+
const { url, endpoints } = this._createAPIConfig();
|
|
60
|
+
this._apiConfigUrl = url;
|
|
61
|
+
this._apiConfigEndpoints = endpoints;
|
|
62
|
+
}
|
|
63
|
+
getAPIConfig({
|
|
64
|
+
setting,
|
|
65
|
+
placeholders = {}
|
|
66
|
+
} = {}) {
|
|
67
|
+
const useSetting = setting || this._options.apiConfigSetting;
|
|
68
|
+
let url;
|
|
69
|
+
const placeholdersEntries = Object.entries(placeholders);
|
|
70
|
+
if (placeholdersEntries.length) {
|
|
71
|
+
url = placeholdersEntries.reduce(
|
|
72
|
+
(acc, [key, value]) => acc.replace(`:${key}`, value),
|
|
73
|
+
this._apiConfigUrl
|
|
74
|
+
);
|
|
75
|
+
} else {
|
|
76
|
+
url = this._apiConfigUrl;
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
url,
|
|
80
|
+
endpoints: {
|
|
81
|
+
[useSetting]: this._apiConfigEndpoints
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
addRoutes(router, middlewares = []) {
|
|
86
|
+
this._routes.forEach((route) => {
|
|
87
|
+
route.methods.forEach((info) => {
|
|
88
|
+
this._addRoute({
|
|
89
|
+
router,
|
|
90
|
+
method: info.method,
|
|
91
|
+
route: route.route,
|
|
92
|
+
gatewayMiddleware: this._createGatewayMiddleware(info.endpoint),
|
|
93
|
+
middlewares
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
return router;
|
|
98
|
+
}
|
|
99
|
+
get options() {
|
|
100
|
+
return { ...this._options };
|
|
101
|
+
}
|
|
102
|
+
get gatewayConfig() {
|
|
103
|
+
return { ...this._gatewayConfig };
|
|
104
|
+
}
|
|
105
|
+
_createGatewayMiddleware(endpoint) {
|
|
106
|
+
return async (req, res, next) => {
|
|
107
|
+
const {
|
|
108
|
+
_options: { headers: headersOptions },
|
|
109
|
+
_gatewayConfig: { url: gatewayUrl },
|
|
110
|
+
_routeExpression: routeExpression
|
|
111
|
+
} = this;
|
|
112
|
+
const reqPath = req.originalUrl.replace(routeExpression, "");
|
|
113
|
+
let headers = {};
|
|
114
|
+
headersOptions.copy.forEach((name) => {
|
|
115
|
+
if (req.headers[name]) {
|
|
116
|
+
headers[name] = req.headers[name];
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
if (headersOptions.copyCustomHeaders) {
|
|
120
|
+
headers = deepAssignWithOverwrite(
|
|
121
|
+
headers,
|
|
122
|
+
this.http.getCustomHeadersFromRequest(req)
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
if (headersOptions.useXForwardedFor) {
|
|
126
|
+
const ip = this.http.getIPFromRequest(req);
|
|
127
|
+
if (ip) {
|
|
128
|
+
headers["x-forwarded-for"] = ip;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const method = req.method.toUpperCase();
|
|
132
|
+
let body;
|
|
133
|
+
if (method !== "GET" && typeof req.body === "object") {
|
|
134
|
+
body = JSON.stringify(req.body);
|
|
135
|
+
if (!headers["content-type"]) {
|
|
136
|
+
headers["content-type"] = "application/json";
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const helper = this._getHelperService() || {};
|
|
140
|
+
const helperBasePayload = {
|
|
141
|
+
endpoint,
|
|
142
|
+
req,
|
|
143
|
+
res,
|
|
144
|
+
next,
|
|
145
|
+
helper
|
|
146
|
+
};
|
|
147
|
+
try {
|
|
148
|
+
const request = await this._reduceEndpointRequest({
|
|
149
|
+
endpointReq: {
|
|
150
|
+
url: `${gatewayUrl}/${reqPath}`,
|
|
151
|
+
options: {
|
|
152
|
+
method,
|
|
153
|
+
headers,
|
|
154
|
+
body
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
...helperBasePayload
|
|
158
|
+
});
|
|
159
|
+
const responseRaw = await this.http.fetch(request.url, request.options);
|
|
160
|
+
const response = await this._reduceEndpointResponse({
|
|
161
|
+
endpointRes: responseRaw,
|
|
162
|
+
...helperBasePayload
|
|
163
|
+
});
|
|
164
|
+
const shouldStream = await this._shouldStreamEndpointResponse({
|
|
165
|
+
endpointRes: responseRaw,
|
|
166
|
+
...helperBasePayload
|
|
167
|
+
});
|
|
168
|
+
if (shouldStream) {
|
|
169
|
+
res.status(response.status);
|
|
170
|
+
response.headers.forEach((value, name) => {
|
|
171
|
+
if (!headersOptions.remove.includes(name)) {
|
|
172
|
+
res.setHeader(name, value);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
response.body.pipe(res).on("error", (error) => {
|
|
176
|
+
next(error);
|
|
177
|
+
});
|
|
178
|
+
} else {
|
|
179
|
+
await this._handleEndpointResponse({
|
|
180
|
+
endpointRes: response,
|
|
181
|
+
...helperBasePayload
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
} catch (error) {
|
|
185
|
+
this._handleEndpointError({
|
|
186
|
+
error,
|
|
187
|
+
...helperBasePayload
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
_addRoute({
|
|
193
|
+
router,
|
|
194
|
+
method,
|
|
195
|
+
route,
|
|
196
|
+
gatewayMiddleware,
|
|
197
|
+
middlewares
|
|
198
|
+
}) {
|
|
199
|
+
router[method](route, [...middlewares, gatewayMiddleware]);
|
|
200
|
+
}
|
|
201
|
+
_formatEndpoints() {
|
|
202
|
+
return flat({
|
|
203
|
+
target: this._gatewayConfig.gateway,
|
|
204
|
+
shouldFlatten: (_, value) => {
|
|
205
|
+
const useValue = value;
|
|
206
|
+
return typeof useValue.path === "undefined";
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
_createRoutes() {
|
|
211
|
+
const routes = {};
|
|
212
|
+
Object.keys(this._endpoints).forEach((name) => {
|
|
213
|
+
const endpoint = this._endpoints[name];
|
|
214
|
+
let endpointPath;
|
|
215
|
+
let endpointMethod;
|
|
216
|
+
if (typeof endpoint === "string") {
|
|
217
|
+
endpointPath = endpoint;
|
|
218
|
+
endpointMethod = "all";
|
|
219
|
+
} else {
|
|
220
|
+
endpointPath = endpoint.path;
|
|
221
|
+
endpointMethod = endpoint.method ? this._validateHTTPMethod(endpoint.method) : "all";
|
|
222
|
+
}
|
|
223
|
+
endpointPath = removeSlashes(endpointPath);
|
|
224
|
+
if (!routes[endpointPath]) {
|
|
225
|
+
routes[endpointPath] = {
|
|
226
|
+
path: endpointPath,
|
|
227
|
+
methods: {}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
if (routes[endpointPath].methods[endpointMethod]) {
|
|
231
|
+
const repeatedEndpoint = routes[endpointPath].methods[endpointMethod];
|
|
232
|
+
throw new Error(
|
|
233
|
+
`You can't have two gateway endpoints to the same path and with the same HTTP method: '${repeatedEndpoint}' and '${name}'`
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
routes[endpointPath].methods[endpointMethod] = name;
|
|
237
|
+
});
|
|
238
|
+
const routePrefixes = this._options.root ? `/${this._options.root}/` : "/";
|
|
239
|
+
return Object.keys(routes).map((endpointPath) => {
|
|
240
|
+
const info = routes[endpointPath];
|
|
241
|
+
return {
|
|
242
|
+
path: info.path,
|
|
243
|
+
route: `${routePrefixes}${info.path}`,
|
|
244
|
+
methods: Object.keys(info.methods).map((methodNameRaw) => {
|
|
245
|
+
const methodName = methodNameRaw;
|
|
246
|
+
const endpointName = info.methods[methodName];
|
|
247
|
+
const endpointDefinition = this._endpoints[endpointName];
|
|
248
|
+
return {
|
|
249
|
+
method: methodName,
|
|
250
|
+
endpoint: {
|
|
251
|
+
name: endpointName,
|
|
252
|
+
definition: endpointDefinition
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
})
|
|
256
|
+
};
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
_reduceEndpointRequest({
|
|
260
|
+
helper,
|
|
261
|
+
...options
|
|
262
|
+
}) {
|
|
263
|
+
if (helper.reduceEndpointRequest) {
|
|
264
|
+
return helper.reduceEndpointRequest(options);
|
|
265
|
+
}
|
|
266
|
+
return Promise.resolve(options.endpointReq);
|
|
267
|
+
}
|
|
268
|
+
_reduceEndpointResponse({
|
|
269
|
+
helper,
|
|
270
|
+
...options
|
|
271
|
+
}) {
|
|
272
|
+
if (helper.reduceEndpointResponse) {
|
|
273
|
+
return helper.reduceEndpointResponse(options);
|
|
274
|
+
}
|
|
275
|
+
return Promise.resolve(options.endpointRes);
|
|
276
|
+
}
|
|
277
|
+
_shouldStreamEndpointResponse({
|
|
278
|
+
helper,
|
|
279
|
+
...options
|
|
280
|
+
}) {
|
|
281
|
+
if (helper.shouldStreamEndpointResponse) {
|
|
282
|
+
return helper.shouldStreamEndpointResponse(options);
|
|
283
|
+
}
|
|
284
|
+
return Promise.resolve(true);
|
|
285
|
+
}
|
|
286
|
+
_handleEndpointResponse({
|
|
287
|
+
helper,
|
|
288
|
+
...options
|
|
289
|
+
}) {
|
|
290
|
+
if (!helper.handleEndpointResponse) {
|
|
291
|
+
throw new Error("You must implement handleEndpointResponse");
|
|
292
|
+
}
|
|
293
|
+
return helper.handleEndpointResponse(options);
|
|
294
|
+
}
|
|
295
|
+
_handleEndpointError({
|
|
296
|
+
helper,
|
|
297
|
+
...options
|
|
298
|
+
}) {
|
|
299
|
+
if (helper.handleEndpointError) {
|
|
300
|
+
return helper.handleEndpointError(options);
|
|
301
|
+
}
|
|
302
|
+
return options.next(options.error);
|
|
303
|
+
}
|
|
304
|
+
_formatOptions(options) {
|
|
305
|
+
if (options.root) {
|
|
306
|
+
const root = removeSlashes(options.root).trim();
|
|
307
|
+
return { ...options, root };
|
|
308
|
+
}
|
|
309
|
+
return options;
|
|
310
|
+
}
|
|
311
|
+
_validateHTTPMethod(method) {
|
|
312
|
+
const newMethod = method.toLowerCase();
|
|
313
|
+
return [
|
|
314
|
+
"get",
|
|
315
|
+
"head",
|
|
316
|
+
"post",
|
|
317
|
+
"patch",
|
|
318
|
+
"put",
|
|
319
|
+
"delete",
|
|
320
|
+
"connect",
|
|
321
|
+
"options",
|
|
322
|
+
"trace"
|
|
323
|
+
].includes(newMethod) ? newMethod : "all";
|
|
324
|
+
}
|
|
325
|
+
_createAPIConfig() {
|
|
326
|
+
let endpoints;
|
|
327
|
+
const { root } = this._options;
|
|
328
|
+
if (root) {
|
|
329
|
+
endpoints = Object.keys(this._endpoints).reduce((acc, name) => {
|
|
330
|
+
const endpoint = this._endpoints[name];
|
|
331
|
+
let newEndpoint;
|
|
332
|
+
if (typeof endpoint === "string") {
|
|
333
|
+
newEndpoint = removeSlashes(endpoint);
|
|
334
|
+
newEndpoint = `${root}/${newEndpoint}`;
|
|
335
|
+
} else {
|
|
336
|
+
const endpointPath = removeSlashes(endpoint.path);
|
|
337
|
+
newEndpoint = {
|
|
338
|
+
...endpoint,
|
|
339
|
+
path: `${root}/${endpointPath}`
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
acc[name] = newEndpoint;
|
|
343
|
+
return acc;
|
|
344
|
+
}, {});
|
|
345
|
+
} else {
|
|
346
|
+
endpoints = this._endpoints;
|
|
347
|
+
}
|
|
348
|
+
return {
|
|
349
|
+
url: `/${this._route}`,
|
|
350
|
+
endpoints: unflat({ target: endpoints })
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
const gatewayController = controllerProviderCreator(
|
|
355
|
+
(options = {}) => (app, route) => {
|
|
356
|
+
const defaultServiceName = "apiGateway";
|
|
357
|
+
let defaultHelperServiceName = "apiGatewayHelper";
|
|
358
|
+
let defaultConfigSetting = "api";
|
|
359
|
+
let { serviceName = defaultServiceName } = options;
|
|
360
|
+
if (serviceName !== defaultServiceName) {
|
|
361
|
+
defaultConfigSetting = serviceName;
|
|
362
|
+
if (!serviceName.match(/gateway$/i)) {
|
|
363
|
+
serviceName = `${serviceName}Gateway`;
|
|
364
|
+
}
|
|
365
|
+
defaultHelperServiceName = `${serviceName}Helper`;
|
|
366
|
+
}
|
|
367
|
+
app.set(serviceName, () => {
|
|
368
|
+
const {
|
|
369
|
+
helperServiceName = defaultHelperServiceName,
|
|
370
|
+
gatewaySettingName = defaultConfigSetting,
|
|
371
|
+
gatewayClass: GatewayClass = GatewayController
|
|
372
|
+
} = options;
|
|
373
|
+
const gtConfig = app.getConfig(gatewaySettingName);
|
|
374
|
+
return new GatewayClass({
|
|
375
|
+
...options,
|
|
376
|
+
apiConfigSetting: gatewaySettingName,
|
|
377
|
+
gatewayConfig: gtConfig,
|
|
378
|
+
route,
|
|
379
|
+
inject: {
|
|
380
|
+
http: app.get("http"),
|
|
381
|
+
getHelperService: () => app.try(helperServiceName)
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
return controller(() => {
|
|
386
|
+
const ctrl = app.get(serviceName);
|
|
387
|
+
let useMiddlewares;
|
|
388
|
+
if (options.getMiddlewares) {
|
|
389
|
+
useMiddlewares = options.getMiddlewares(app).map((middleware) => {
|
|
390
|
+
if ("middleware" in middleware) {
|
|
391
|
+
return middleware.connect(app);
|
|
392
|
+
}
|
|
393
|
+
return middleware;
|
|
394
|
+
}).filter(notUndefined);
|
|
395
|
+
}
|
|
396
|
+
return ctrl.addRoutes(app.get("router"), useMiddlewares);
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
);
|
|
400
|
+
export {
|
|
401
|
+
GatewayController,
|
|
402
|
+
gatewayController
|
|
403
|
+
};
|
|
404
|
+
//# sourceMappingURL=gateway.js.map
|