@loopback/rest 4.0.0-alpha.8 → 5.0.1
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 +1822 -0
- package/LICENSE +1 -1
- package/README.md +30 -58
- package/dist/body-parsers/body-parser.d.ts +25 -0
- package/dist/body-parsers/body-parser.helpers.d.ts +44 -0
- package/dist/body-parsers/body-parser.helpers.js +102 -0
- package/dist/body-parsers/body-parser.helpers.js.map +1 -0
- package/dist/body-parsers/body-parser.js +159 -0
- package/dist/body-parsers/body-parser.js.map +1 -0
- package/dist/body-parsers/body-parser.json.d.ts +9 -0
- package/dist/body-parsers/body-parser.json.js +43 -0
- package/dist/body-parsers/body-parser.json.js.map +1 -0
- package/dist/body-parsers/body-parser.raw.d.ts +12 -0
- package/dist/body-parsers/body-parser.raw.js +39 -0
- package/dist/body-parsers/body-parser.raw.js.map +1 -0
- package/dist/body-parsers/body-parser.stream.d.ts +12 -0
- package/dist/body-parsers/body-parser.stream.js +28 -0
- package/dist/body-parsers/body-parser.stream.js.map +1 -0
- package/dist/body-parsers/body-parser.text.d.ts +9 -0
- package/dist/body-parsers/body-parser.text.js +38 -0
- package/dist/body-parsers/body-parser.text.js.map +1 -0
- package/dist/body-parsers/body-parser.urlencoded.d.ts +9 -0
- package/dist/body-parsers/body-parser.urlencoded.js +36 -0
- package/dist/body-parsers/body-parser.urlencoded.js.map +1 -0
- package/dist/body-parsers/index.d.ts +8 -0
- package/dist/body-parsers/index.js +16 -0
- package/dist/body-parsers/index.js.map +1 -0
- package/dist/body-parsers/types.d.ts +51 -0
- package/dist/body-parsers/types.js +12 -0
- package/dist/body-parsers/types.js.map +1 -0
- package/dist/coercion/coerce-parameter.d.ts +9 -0
- package/dist/coercion/coerce-parameter.js +166 -0
- package/dist/coercion/coerce-parameter.js.map +1 -0
- package/dist/coercion/utils.d.ts +43 -0
- package/dist/coercion/utils.js +96 -0
- package/dist/coercion/utils.js.map +1 -0
- package/dist/coercion/validator.d.ts +49 -0
- package/dist/coercion/validator.js +85 -0
- package/dist/coercion/validator.js.map +1 -0
- package/dist/http-handler.d.ts +38 -0
- package/dist/http-handler.js +68 -0
- package/dist/http-handler.js.map +1 -0
- package/dist/index.d.ts +36 -1
- package/dist/index.js +40 -6
- package/dist/index.js.map +1 -0
- package/dist/keys.d.ts +198 -0
- package/dist/keys.js +202 -0
- package/dist/keys.js.map +1 -0
- package/dist/parse-json.d.ts +11 -0
- package/dist/parse-json.js +42 -0
- package/dist/parse-json.js.map +1 -0
- package/dist/parser.d.ts +11 -0
- package/dist/parser.js +76 -0
- package/dist/parser.js.map +1 -0
- package/{dist6/src/providers/find-route.d.ts → dist/providers/find-route.provider.d.ts} +3 -1
- package/dist/providers/find-route.provider.js +36 -0
- package/dist/providers/find-route.provider.js.map +1 -0
- package/dist/providers/index.d.ts +6 -0
- package/dist/providers/index.js +14 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/{src/providers/invoke-method.d.ts → providers/invoke-method.provider.d.ts} +3 -1
- package/dist/providers/invoke-method.provider.js +30 -0
- package/dist/providers/invoke-method.provider.js.map +1 -0
- package/dist/providers/log-error.provider.d.ts +6 -0
- package/dist/providers/log-error.provider.js +21 -0
- package/dist/providers/log-error.provider.js.map +1 -0
- package/dist/providers/parse-params.provider.d.ts +15 -0
- package/dist/providers/parse-params.provider.js +41 -0
- package/dist/providers/parse-params.provider.js.map +1 -0
- package/dist/providers/reject.provider.d.ts +10 -0
- package/dist/providers/reject.provider.js +47 -0
- package/dist/providers/reject.provider.js.map +1 -0
- package/dist/{src/providers/send.d.ts → providers/send.provider.d.ts} +1 -4
- package/dist/{src/providers/send.js → providers/send.provider.js} +4 -6
- package/dist/providers/send.provider.js.map +1 -0
- package/dist/request-context.d.ts +36 -0
- package/dist/request-context.js +104 -0
- package/dist/request-context.js.map +1 -0
- package/dist/rest-http-error.d.ts +37 -0
- package/dist/rest-http-error.js +51 -0
- package/dist/rest-http-error.js.map +1 -0
- package/dist/rest.application.d.ts +232 -0
- package/dist/rest.application.js +174 -0
- package/dist/rest.application.js.map +1 -0
- package/dist/rest.component.d.ts +15 -0
- package/dist/rest.component.js +72 -0
- package/dist/rest.component.js.map +1 -0
- package/dist/rest.server.d.ts +443 -0
- package/dist/rest.server.js +748 -0
- package/dist/rest.server.js.map +1 -0
- package/dist/router/base-route.d.ts +29 -0
- package/dist/router/base-route.js +41 -0
- package/dist/router/base-route.js.map +1 -0
- package/dist/router/controller-route.d.ts +61 -0
- package/dist/router/controller-route.js +160 -0
- package/dist/router/controller-route.js.map +1 -0
- package/dist/router/external-express-routes.d.ts +24 -0
- package/dist/router/external-express-routes.js +90 -0
- package/dist/router/external-express-routes.js.map +1 -0
- package/dist/router/handler-route.d.ts +12 -0
- package/dist/router/handler-route.js +30 -0
- package/dist/router/handler-route.js.map +1 -0
- package/dist/router/index.d.ts +14 -0
- package/dist/router/index.js +25 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/openapi-path.d.ts +14 -0
- package/dist/router/openapi-path.js +64 -0
- package/dist/router/openapi-path.js.map +1 -0
- package/dist/router/redirect-route.d.ts +23 -0
- package/dist/router/redirect-route.js +50 -0
- package/dist/router/redirect-route.js.map +1 -0
- package/dist/router/regexp-router.d.ts +25 -0
- package/dist/router/regexp-router.js +84 -0
- package/dist/router/regexp-router.js.map +1 -0
- package/dist/router/rest-router.d.ts +35 -0
- package/dist/{src/internal-types.js → router/rest-router.js} +2 -2
- package/dist/router/rest-router.js.map +1 -0
- package/dist/router/route-entry.d.ts +46 -0
- package/dist/router/route-entry.js +20 -0
- package/dist/router/route-entry.js.map +1 -0
- package/dist/router/route-sort.d.ts +7 -0
- package/dist/router/route-sort.js +75 -0
- package/dist/router/route-sort.js.map +1 -0
- package/dist/router/router-base.d.ts +42 -0
- package/dist/router/router-base.js +101 -0
- package/dist/router/router-base.js.map +1 -0
- package/dist/router/router-spec.d.ts +3 -0
- package/dist/router/router-spec.js +40 -0
- package/dist/router/router-spec.js.map +1 -0
- package/dist/router/routing-table.d.ts +32 -0
- package/dist/router/routing-table.js +86 -0
- package/dist/router/routing-table.js.map +1 -0
- package/dist/router/trie-router.d.ts +13 -0
- package/dist/router/trie-router.js +55 -0
- package/dist/router/trie-router.js.map +1 -0
- package/dist/router/trie.d.ts +59 -0
- package/dist/router/trie.js +180 -0
- package/dist/router/trie.js.map +1 -0
- package/{dist6/src → dist}/sequence.d.ts +28 -23
- package/dist/sequence.js +112 -0
- package/dist/sequence.js.map +1 -0
- package/dist/spec-enhancers/consolidate.spec-enhancer.d.ts +68 -0
- package/dist/spec-enhancers/consolidate.spec-enhancer.js +145 -0
- package/dist/spec-enhancers/consolidate.spec-enhancer.js.map +1 -0
- package/dist/spec-enhancers/info.spec-enhancer.d.ts +19 -0
- package/dist/spec-enhancers/info.spec-enhancer.js +89 -0
- package/dist/spec-enhancers/info.spec-enhancer.js.map +1 -0
- package/dist/types.d.ts +178 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/validation/ajv-factory.provider.d.ts +12 -0
- package/dist/validation/ajv-factory.provider.js +87 -0
- package/dist/validation/ajv-factory.provider.js.map +1 -0
- package/dist/validation/request-body.validator.d.ts +14 -0
- package/dist/validation/request-body.validator.js +161 -0
- package/dist/validation/request-body.validator.js.map +1 -0
- package/dist/writer.d.ts +9 -0
- package/dist/writer.js +62 -0
- package/dist/writer.js.map +1 -0
- package/package.json +66 -38
- package/src/body-parsers/body-parser.helpers.ts +148 -0
- package/src/body-parsers/body-parser.json.ts +46 -0
- package/src/body-parsers/body-parser.raw.ts +42 -0
- package/src/body-parsers/body-parser.stream.ts +27 -0
- package/src/body-parsers/body-parser.text.ts +44 -0
- package/src/body-parsers/body-parser.ts +208 -0
- package/src/body-parsers/body-parser.urlencoded.ts +42 -0
- package/src/body-parsers/index.ts +13 -0
- package/src/body-parsers/types.ts +60 -0
- package/src/coercion/coerce-parameter.ts +207 -0
- package/src/coercion/utils.ts +103 -0
- package/src/coercion/validator.ts +98 -0
- package/src/http-handler.ts +84 -41
- package/src/index.ts +37 -30
- package/src/keys.ts +273 -20
- package/src/parse-json.ts +42 -0
- package/src/parser.ts +89 -104
- package/src/providers/{find-route.ts → find-route.provider.ts} +10 -7
- package/src/providers/index.ts +7 -9
- package/src/providers/{invoke-method.ts → invoke-method.provider.ts} +8 -5
- package/src/providers/log-error.provider.ts +27 -0
- package/src/providers/parse-params.provider.ts +42 -0
- package/src/providers/reject.provider.ts +44 -0
- package/src/providers/{send.ts → send.provider.ts} +2 -5
- package/src/request-context.ts +123 -0
- package/src/rest-http-error.ts +87 -0
- package/src/rest.application.ts +390 -0
- package/src/rest.component.ts +111 -0
- package/src/rest.server.ts +1192 -0
- package/src/router/base-route.ts +53 -0
- package/src/router/controller-route.ts +241 -0
- package/src/router/external-express-routes.ts +139 -0
- package/src/router/handler-route.ts +44 -0
- package/src/router/index.ts +24 -0
- package/src/router/openapi-path.ts +67 -0
- package/src/router/redirect-route.ts +64 -0
- package/src/router/regexp-router.ts +104 -0
- package/src/router/rest-router.ts +48 -0
- package/src/router/route-entry.ts +74 -0
- package/src/router/route-sort.ts +74 -0
- package/src/router/router-base.ts +124 -0
- package/src/router/router-spec.ts +36 -0
- package/src/router/routing-table.ts +83 -279
- package/src/router/trie-router.ts +57 -0
- package/src/router/trie.ts +233 -0
- package/src/sequence.ts +44 -37
- package/src/spec-enhancers/consolidate.spec-enhancer.ts +182 -0
- package/src/spec-enhancers/info.spec-enhancer.ts +92 -0
- package/src/types.ts +216 -0
- package/src/validation/ajv-factory.provider.ts +94 -0
- package/src/validation/request-body.validator.ts +208 -0
- package/src/writer.ts +41 -68
- package/api-docs/.DS_Store +0 -0
- package/api-docs/apple-touch-icon-114x114-precomposed.png +0 -0
- package/api-docs/apple-touch-icon-144x144-precomposed.png +0 -0
- package/api-docs/apple-touch-icon-57x57-precomposed.png +0 -0
- package/api-docs/apple-touch-icon-72x72-precomposed.png +0 -0
- package/api-docs/apple-touch-icon-precomposed.png +0 -0
- package/api-docs/apple-touch-icon.png +0 -0
- package/api-docs/css/bootstrap.min.css +0 -9
- package/api-docs/css/code-themes/arta.css +0 -158
- package/api-docs/css/code-themes/ascetic.css +0 -50
- package/api-docs/css/code-themes/brown_paper.css +0 -104
- package/api-docs/css/code-themes/brown_papersq.png +0 -0
- package/api-docs/css/code-themes/dark.css +0 -103
- package/api-docs/css/code-themes/default.css +0 -135
- package/api-docs/css/code-themes/far.css +0 -111
- package/api-docs/css/code-themes/github.css +0 -127
- package/api-docs/css/code-themes/googlecode.css +0 -144
- package/api-docs/css/code-themes/idea.css +0 -121
- package/api-docs/css/code-themes/ir_black.css +0 -104
- package/api-docs/css/code-themes/magula.css +0 -121
- package/api-docs/css/code-themes/monokai.css +0 -114
- package/api-docs/css/code-themes/pojoaque.css +0 -104
- package/api-docs/css/code-themes/pojoaque.jpg +0 -0
- package/api-docs/css/code-themes/rainbow.css +0 -114
- package/api-docs/css/code-themes/school_book.css +0 -111
- package/api-docs/css/code-themes/school_book.png +0 -0
- package/api-docs/css/code-themes/sl-theme.css +0 -45
- package/api-docs/css/code-themes/solarized_dark.css +0 -88
- package/api-docs/css/code-themes/solarized_light.css +0 -88
- package/api-docs/css/code-themes/sunburst.css +0 -158
- package/api-docs/css/code-themes/tomorrow-night-blue.css +0 -52
- package/api-docs/css/code-themes/tomorrow-night-bright.css +0 -51
- package/api-docs/css/code-themes/tomorrow-night-eighties.css +0 -51
- package/api-docs/css/code-themes/tomorrow-night.css +0 -52
- package/api-docs/css/code-themes/tomorrow.css +0 -49
- package/api-docs/css/code-themes/vs.css +0 -86
- package/api-docs/css/code-themes/xcode.css +0 -154
- package/api-docs/css/code-themes/zenburn.css +0 -115
- package/api-docs/css/main.css +0 -139
- package/api-docs/favicon.ico +0 -0
- package/api-docs/fonts/0ihfXUL2emPh0ROJezvraLO3LdcAZYWl9Si6vvxL-qU.woff +0 -0
- package/api-docs/fonts/OsJ2DjdpjqFRVUSto6IffLO3LdcAZYWl9Si6vvxL-qU.woff +0 -0
- package/api-docs/fonts/_aijTyevf54tkVDLy-dlnLO3LdcAZYWl9Si6vvxL-qU.woff +0 -0
- package/api-docs/index.html +0 -7082
- package/api-docs/js/main.js +0 -19
- package/api-docs/js/vendor/bootstrap.min.js +0 -6
- package/api-docs/js/vendor/jquery-1.10.1.min.js +0 -6
- package/api-docs/js/vendor/jquery.scrollTo-1.4.3.1.js +0 -218
- package/api-docs/js/vendor/modernizr-2.6.2-respond-1.1.0.min.js +0 -11
- package/dist/src/http-handler.d.ts +0 -19
- package/dist/src/http-handler.js +0 -43
- package/dist/src/http-handler.js.map +0 -1
- package/dist/src/index.d.ts +0 -14
- package/dist/src/index.js +0 -33
- package/dist/src/index.js.map +0 -1
- package/dist/src/internal-types.d.ts +0 -67
- package/dist/src/internal-types.js.map +0 -1
- package/dist/src/keys.d.ts +0 -22
- package/dist/src/keys.js +0 -35
- package/dist/src/keys.js.map +0 -1
- package/dist/src/parser.d.ts +0 -11
- package/dist/src/parser.js +0 -98
- package/dist/src/parser.js.map +0 -1
- package/dist/src/providers/bind-element.d.ts +0 -7
- package/dist/src/providers/bind-element.js +0 -34
- package/dist/src/providers/bind-element.js.map +0 -1
- package/dist/src/providers/find-route.d.ts +0 -9
- package/dist/src/providers/find-route.js +0 -42
- package/dist/src/providers/find-route.js.map +0 -1
- package/dist/src/providers/get-from-context.d.ts +0 -7
- package/dist/src/providers/get-from-context.js +0 -34
- package/dist/src/providers/get-from-context.js.map +0 -1
- package/dist/src/providers/index.d.ts +0 -8
- package/dist/src/providers/index.js +0 -18
- package/dist/src/providers/index.js.map +0 -1
- package/dist/src/providers/invoke-method.js +0 -36
- package/dist/src/providers/invoke-method.js.map +0 -1
- package/dist/src/providers/log-error-provider.d.ts +0 -6
- package/dist/src/providers/log-error-provider.js +0 -17
- package/dist/src/providers/log-error-provider.js.map +0 -1
- package/dist/src/providers/parse-params.d.ts +0 -13
- package/dist/src/providers/parse-params.js +0 -22
- package/dist/src/providers/parse-params.js.map +0 -1
- package/dist/src/providers/reject.d.ts +0 -6
- package/dist/src/providers/reject.js +0 -40
- package/dist/src/providers/reject.js.map +0 -1
- package/dist/src/providers/send.js.map +0 -1
- package/dist/src/rest-component.d.ts +0 -12
- package/dist/src/rest-component.js +0 -50
- package/dist/src/rest-component.js.map +0 -1
- package/dist/src/rest-server.d.ts +0 -211
- package/dist/src/rest-server.js +0 -426
- package/dist/src/rest-server.js.map +0 -1
- package/dist/src/router/metadata.d.ts +0 -150
- package/dist/src/router/metadata.js +0 -410
- package/dist/src/router/metadata.js.map +0 -1
- package/dist/src/router/routing-table.d.ts +0 -68
- package/dist/src/router/routing-table.js +0 -204
- package/dist/src/router/routing-table.js.map +0 -1
- package/dist/src/sequence.d.ts +0 -81
- package/dist/src/sequence.js +0 -104
- package/dist/src/sequence.js.map +0 -1
- package/dist/src/writer.d.ts +0 -17
- package/dist/src/writer.js +0 -87
- package/dist/src/writer.js.map +0 -1
- package/dist6/index.d.ts +0 -1
- package/dist6/index.js +0 -12
- package/dist6/src/http-handler.d.ts +0 -19
- package/dist6/src/http-handler.js +0 -53
- package/dist6/src/http-handler.js.map +0 -1
- package/dist6/src/index.d.ts +0 -14
- package/dist6/src/index.js +0 -33
- package/dist6/src/index.js.map +0 -1
- package/dist6/src/internal-types.d.ts +0 -67
- package/dist6/src/internal-types.js +0 -7
- package/dist6/src/internal-types.js.map +0 -1
- package/dist6/src/keys.d.ts +0 -22
- package/dist6/src/keys.js +0 -35
- package/dist6/src/keys.js.map +0 -1
- package/dist6/src/parser.d.ts +0 -11
- package/dist6/src/parser.js +0 -108
- package/dist6/src/parser.js.map +0 -1
- package/dist6/src/providers/bind-element.d.ts +0 -7
- package/dist6/src/providers/bind-element.js +0 -34
- package/dist6/src/providers/bind-element.js.map +0 -1
- package/dist6/src/providers/find-route.js +0 -42
- package/dist6/src/providers/find-route.js.map +0 -1
- package/dist6/src/providers/get-from-context.d.ts +0 -7
- package/dist6/src/providers/get-from-context.js +0 -34
- package/dist6/src/providers/get-from-context.js.map +0 -1
- package/dist6/src/providers/index.d.ts +0 -8
- package/dist6/src/providers/index.js +0 -18
- package/dist6/src/providers/index.js.map +0 -1
- package/dist6/src/providers/invoke-method.d.ts +0 -7
- package/dist6/src/providers/invoke-method.js +0 -44
- package/dist6/src/providers/invoke-method.js.map +0 -1
- package/dist6/src/providers/log-error-provider.d.ts +0 -6
- package/dist6/src/providers/log-error-provider.js +0 -17
- package/dist6/src/providers/log-error-provider.js.map +0 -1
- package/dist6/src/providers/parse-params.d.ts +0 -13
- package/dist6/src/providers/parse-params.js +0 -22
- package/dist6/src/providers/parse-params.js.map +0 -1
- package/dist6/src/providers/reject.d.ts +0 -6
- package/dist6/src/providers/reject.js +0 -40
- package/dist6/src/providers/reject.js.map +0 -1
- package/dist6/src/providers/send.d.ts +0 -15
- package/dist6/src/providers/send.js +0 -24
- package/dist6/src/providers/send.js.map +0 -1
- package/dist6/src/rest-component.d.ts +0 -12
- package/dist6/src/rest-component.js +0 -50
- package/dist6/src/rest-component.js.map +0 -1
- package/dist6/src/rest-server.d.ts +0 -211
- package/dist6/src/rest-server.js +0 -444
- package/dist6/src/rest-server.js.map +0 -1
- package/dist6/src/router/metadata.d.ts +0 -150
- package/dist6/src/router/metadata.js +0 -410
- package/dist6/src/router/metadata.js.map +0 -1
- package/dist6/src/router/routing-table.d.ts +0 -68
- package/dist6/src/router/routing-table.js +0 -218
- package/dist6/src/router/routing-table.js.map +0 -1
- package/dist6/src/sequence.js +0 -114
- package/dist6/src/sequence.js.map +0 -1
- package/dist6/src/writer.d.ts +0 -17
- package/dist6/src/writer.js +0 -87
- package/dist6/src/writer.js.map +0 -1
- package/index.d.ts +0 -6
- package/index.js +0 -9
- package/src/internal-types.ts +0 -96
- package/src/providers/bind-element.ts +0 -15
- package/src/providers/get-from-context.ts +0 -16
- package/src/providers/log-error-provider.ts +0 -23
- package/src/providers/parse-params.ts +0 -20
- package/src/providers/reject.ts +0 -27
- package/src/rest-component.ts +0 -54
- package/src/rest-server.ts +0 -584
- package/src/router/metadata.ts +0 -517
package/src/router/metadata.ts
DELETED
|
@@ -1,517 +0,0 @@
|
|
|
1
|
-
// Copyright IBM Corp. 2017. All Rights Reserved.
|
|
2
|
-
// Node module: @loopback/rest
|
|
3
|
-
// This file is licensed under the MIT License.
|
|
4
|
-
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
-
|
|
6
|
-
import * as assert from 'assert';
|
|
7
|
-
import {Reflector} from '@loopback/context';
|
|
8
|
-
import {
|
|
9
|
-
OperationObject,
|
|
10
|
-
ParameterLocation,
|
|
11
|
-
ParameterObject,
|
|
12
|
-
SchemaObject,
|
|
13
|
-
ParameterType,
|
|
14
|
-
PathsObject,
|
|
15
|
-
} from '@loopback/openapi-spec';
|
|
16
|
-
|
|
17
|
-
const debug = require('debug')('loopback:core:router:metadata');
|
|
18
|
-
|
|
19
|
-
const ENDPOINTS_KEY = 'rest:endpoints';
|
|
20
|
-
const API_SPEC_KEY = 'rest:api-spec';
|
|
21
|
-
|
|
22
|
-
// tslint:disable:no-any
|
|
23
|
-
|
|
24
|
-
export interface ControllerSpec {
|
|
25
|
-
/**
|
|
26
|
-
* The base path on which the Controller API is served.
|
|
27
|
-
* If it is not included, the API is served directly under the host.
|
|
28
|
-
* The value MUST start with a leading slash (/).
|
|
29
|
-
*/
|
|
30
|
-
basePath?: string;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* The available paths and operations for the API.
|
|
34
|
-
*/
|
|
35
|
-
paths: PathsObject;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Decorate the given Controller constructor with metadata describing
|
|
40
|
-
* the HTTP/REST API the Controller implements/provides.
|
|
41
|
-
*
|
|
42
|
-
* `@api` can be applied to controller classes. For example,
|
|
43
|
-
* ```
|
|
44
|
-
* @api({basePath: '/my'})
|
|
45
|
-
* class MyController {
|
|
46
|
-
* // ...
|
|
47
|
-
* }
|
|
48
|
-
* ```
|
|
49
|
-
*
|
|
50
|
-
* @param spec OpenAPI specification describing the endpoints
|
|
51
|
-
* handled by this controller
|
|
52
|
-
*
|
|
53
|
-
* @decorator
|
|
54
|
-
*/
|
|
55
|
-
export function api(spec: ControllerSpec) {
|
|
56
|
-
return function(constructor: Function) {
|
|
57
|
-
assert(
|
|
58
|
-
typeof constructor === 'function',
|
|
59
|
-
'The @api decorator can be applied to constructors only.',
|
|
60
|
-
);
|
|
61
|
-
const apiSpec = resolveControllerSpec(constructor, spec);
|
|
62
|
-
Reflector.defineMetadata(API_SPEC_KEY, apiSpec, constructor);
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Data structure for REST related metadata
|
|
68
|
-
*/
|
|
69
|
-
interface RestEndpoint {
|
|
70
|
-
verb: string;
|
|
71
|
-
path: string;
|
|
72
|
-
spec?: OperationObject;
|
|
73
|
-
target: any;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Build the api spec from class and method level decorations
|
|
78
|
-
* @param constructor Controller class
|
|
79
|
-
* @param spec API spec
|
|
80
|
-
*/
|
|
81
|
-
function resolveControllerSpec(
|
|
82
|
-
constructor: Function,
|
|
83
|
-
spec?: ControllerSpec,
|
|
84
|
-
): ControllerSpec {
|
|
85
|
-
debug(`Retrieving OpenAPI specification for controller ${constructor.name}`);
|
|
86
|
-
|
|
87
|
-
if (spec) {
|
|
88
|
-
debug(' using class-level spec defined via @api()', spec);
|
|
89
|
-
spec = Object.assign({}, spec);
|
|
90
|
-
} else {
|
|
91
|
-
spec = {paths: {}};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const endpoints =
|
|
95
|
-
Reflector.getMetadata(ENDPOINTS_KEY, constructor.prototype) || {};
|
|
96
|
-
|
|
97
|
-
for (const op in endpoints) {
|
|
98
|
-
const endpoint = endpoints[op];
|
|
99
|
-
const className =
|
|
100
|
-
endpoint.target.constructor.name ||
|
|
101
|
-
constructor.name ||
|
|
102
|
-
'<AnonymousClass>';
|
|
103
|
-
const fullMethodName = `${className}.${op}`;
|
|
104
|
-
|
|
105
|
-
const {verb, path} = endpoint;
|
|
106
|
-
const endpointName = `${fullMethodName} (${verb} ${path})`;
|
|
107
|
-
|
|
108
|
-
let operationSpec = endpoint.spec;
|
|
109
|
-
if (!operationSpec) {
|
|
110
|
-
// The operation was defined via @operation(verb, path) with no spec
|
|
111
|
-
operationSpec = {
|
|
112
|
-
responses: {},
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (!spec.paths[path]) {
|
|
117
|
-
spec.paths[path] = {};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (spec.paths[path][verb]) {
|
|
121
|
-
// Operations from subclasses override those from the base
|
|
122
|
-
debug(` Overriding ${endpointName} - endpoint was already defined`);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
debug(` adding ${endpointName}`, operationSpec);
|
|
126
|
-
spec.paths[path][verb] = Object.assign({}, operationSpec, {
|
|
127
|
-
'x-operation-name': op,
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
return spec;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Get the controller spec for the given class
|
|
135
|
-
* @param constructor Controller class
|
|
136
|
-
*/
|
|
137
|
-
export function getControllerSpec(constructor: Function): ControllerSpec {
|
|
138
|
-
let spec = Reflector.getMetadata(API_SPEC_KEY, constructor);
|
|
139
|
-
if (!spec) {
|
|
140
|
-
spec = resolveControllerSpec(constructor, spec);
|
|
141
|
-
Reflector.defineMetadata(API_SPEC_KEY, spec, constructor);
|
|
142
|
-
}
|
|
143
|
-
return spec;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Expose a Controller method as a REST API operation
|
|
148
|
-
* mapped to `GET` request method.
|
|
149
|
-
*
|
|
150
|
-
* @param path The URL path of this operation, e.g. `/product/{id}`
|
|
151
|
-
* @param spec The OpenAPI specification describing parameters and responses
|
|
152
|
-
* of this operation.
|
|
153
|
-
*/
|
|
154
|
-
export function get(path: string, spec?: OperationObject) {
|
|
155
|
-
return operation('get', path, spec);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Expose a Controller method as a REST API operation
|
|
160
|
-
* mapped to `POST` request method.
|
|
161
|
-
*
|
|
162
|
-
* @param path The URL path of this operation, e.g. `/product/{id}`
|
|
163
|
-
* @param spec The OpenAPI specification describing parameters and responses
|
|
164
|
-
* of this operation.
|
|
165
|
-
*/
|
|
166
|
-
export function post(path: string, spec?: OperationObject) {
|
|
167
|
-
return operation('post', path, spec);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Expose a Controller method as a REST API operation
|
|
172
|
-
* mapped to `PUT` request method.
|
|
173
|
-
*
|
|
174
|
-
* @param path The URL path of this operation, e.g. `/product/{id}`
|
|
175
|
-
* @param spec The OpenAPI specification describing parameters and responses
|
|
176
|
-
* of this operation.
|
|
177
|
-
*/
|
|
178
|
-
export function put(path: string, spec?: OperationObject) {
|
|
179
|
-
return operation('put', path, spec);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Expose a Controller method as a REST API operation
|
|
184
|
-
* mapped to `PATCH` request method.
|
|
185
|
-
*
|
|
186
|
-
* @param path The URL path of this operation, e.g. `/product/{id}`
|
|
187
|
-
* @param spec The OpenAPI specification describing parameters and responses
|
|
188
|
-
* of this operation.
|
|
189
|
-
*/
|
|
190
|
-
export function patch(path: string, spec?: OperationObject) {
|
|
191
|
-
return operation('patch', path, spec);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Expose a Controller method as a REST API operation
|
|
196
|
-
* mapped to `DELETE` request method.
|
|
197
|
-
*
|
|
198
|
-
* @param path The URL path of this operation, e.g. `/product/{id}`
|
|
199
|
-
* @param spec The OpenAPI specification describing parameters and responses
|
|
200
|
-
* of this operation.
|
|
201
|
-
*/
|
|
202
|
-
export function del(path: string, spec?: OperationObject) {
|
|
203
|
-
return operation('delete', path, spec);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Expose a Controller method as a REST API operation.
|
|
208
|
-
*
|
|
209
|
-
* @param verb HTTP verb, e.g. `GET` or `POST`.
|
|
210
|
-
* @param path The URL path of this operation, e.g. `/product/{id}`
|
|
211
|
-
* @param spec The OpenAPI specification describing parameters and responses
|
|
212
|
-
* of this operation.
|
|
213
|
-
*/
|
|
214
|
-
export function operation(verb: string, path: string, spec?: OperationObject) {
|
|
215
|
-
return function(
|
|
216
|
-
target: any,
|
|
217
|
-
propertyKey: string,
|
|
218
|
-
descriptor: PropertyDescriptor,
|
|
219
|
-
) {
|
|
220
|
-
assert(
|
|
221
|
-
typeof target[propertyKey] === 'function',
|
|
222
|
-
'@operation decorator can be applied to methods only',
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
let endpoints = Object.assign(
|
|
226
|
-
{},
|
|
227
|
-
Reflector.getMetadata(ENDPOINTS_KEY, target),
|
|
228
|
-
);
|
|
229
|
-
Reflector.defineMetadata(ENDPOINTS_KEY, endpoints, target);
|
|
230
|
-
|
|
231
|
-
let endpoint: Partial<RestEndpoint> = endpoints[propertyKey];
|
|
232
|
-
if (!endpoint) {
|
|
233
|
-
// Add the new endpoint metadata for the method
|
|
234
|
-
endpoint = {verb, path, spec, target};
|
|
235
|
-
endpoints[propertyKey] = endpoint;
|
|
236
|
-
} else {
|
|
237
|
-
// Update the endpoint metadata
|
|
238
|
-
// It can be created by @param
|
|
239
|
-
endpoint.verb = verb;
|
|
240
|
-
endpoint.path = path;
|
|
241
|
-
endpoint.target = target;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
if (!spec) {
|
|
245
|
-
// Users can define parameters and responses using decorators
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Decorator are invoked in reverse order of their definition.
|
|
250
|
-
// For example, a method decorated with @operation() @param()
|
|
251
|
-
// will invoke param() decorator first and operation() second.
|
|
252
|
-
// As a result, we need to preserve any partial definitions
|
|
253
|
-
// already provided by other decorators.
|
|
254
|
-
editOperationSpec(endpoint, overrides => {
|
|
255
|
-
const mergedSpec = Object.assign({}, spec, overrides);
|
|
256
|
-
|
|
257
|
-
// Merge "responses" definitions
|
|
258
|
-
mergedSpec.responses = Object.assign(
|
|
259
|
-
{},
|
|
260
|
-
spec.responses,
|
|
261
|
-
overrides.responses,
|
|
262
|
-
);
|
|
263
|
-
|
|
264
|
-
return mergedSpec;
|
|
265
|
-
});
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const paramDecoratorStyle = Symbol('ParamDecoratorStyle');
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Describe an input parameter of a Controller method.
|
|
273
|
-
*
|
|
274
|
-
* `@param` can be applied to method itself or specific parameters. For example,
|
|
275
|
-
* ```
|
|
276
|
-
* class MyController {
|
|
277
|
-
* @get('/')
|
|
278
|
-
* @param(offsetSpec)
|
|
279
|
-
* @param(pageSizeSpec)
|
|
280
|
-
* list(offset?: number, pageSize?: number) {}
|
|
281
|
-
* }
|
|
282
|
-
* ```
|
|
283
|
-
* or
|
|
284
|
-
* ```
|
|
285
|
-
* class MyController {
|
|
286
|
-
* @get('/')
|
|
287
|
-
* list(
|
|
288
|
-
* @param(offsetSpec) offset?: number,
|
|
289
|
-
* @param(pageSizeSpec) pageSize?: number,
|
|
290
|
-
* ) {}
|
|
291
|
-
* }
|
|
292
|
-
* ```
|
|
293
|
-
* Please note mixed usage of `@param` at method/parameter level is not allowed.
|
|
294
|
-
*
|
|
295
|
-
* @param paramSpec Parameter specification.
|
|
296
|
-
*/
|
|
297
|
-
export function param(paramSpec: ParameterObject) {
|
|
298
|
-
return function(
|
|
299
|
-
target: any,
|
|
300
|
-
propertyKey: string,
|
|
301
|
-
descriptorOrParameterIndex: PropertyDescriptor | number,
|
|
302
|
-
) {
|
|
303
|
-
assert(
|
|
304
|
-
typeof target[propertyKey] === 'function',
|
|
305
|
-
'@param decorator can be applied to methods only',
|
|
306
|
-
);
|
|
307
|
-
|
|
308
|
-
let endpoints = Object.assign(
|
|
309
|
-
{},
|
|
310
|
-
Reflector.getMetadata(ENDPOINTS_KEY, target),
|
|
311
|
-
);
|
|
312
|
-
Reflector.defineMetadata(ENDPOINTS_KEY, endpoints, target);
|
|
313
|
-
|
|
314
|
-
let endpoint: Partial<RestEndpoint> = endpoints[propertyKey];
|
|
315
|
-
if (!endpoint) {
|
|
316
|
-
// Add the new endpoint metadata for the method
|
|
317
|
-
endpoint = {target};
|
|
318
|
-
endpoints[propertyKey] = endpoint;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
editOperationSpec(endpoint, operationSpec => {
|
|
322
|
-
let decoratorStyle;
|
|
323
|
-
if (typeof descriptorOrParameterIndex === 'number') {
|
|
324
|
-
decoratorStyle = 'parameter';
|
|
325
|
-
} else {
|
|
326
|
-
decoratorStyle = 'method';
|
|
327
|
-
}
|
|
328
|
-
if (!operationSpec.parameters) {
|
|
329
|
-
operationSpec.parameters = [];
|
|
330
|
-
// Record the @param decorator style to ensure consistency
|
|
331
|
-
operationSpec[paramDecoratorStyle] = decoratorStyle;
|
|
332
|
-
} else {
|
|
333
|
-
// Mixed usage of @param at method/parameter level is not allowed
|
|
334
|
-
if (operationSpec[paramDecoratorStyle] !== decoratorStyle) {
|
|
335
|
-
throw new Error(
|
|
336
|
-
'Mixed usage of @param at method/parameter level' +
|
|
337
|
-
' is not allowed.',
|
|
338
|
-
);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
if (typeof descriptorOrParameterIndex === 'number') {
|
|
343
|
-
operationSpec.parameters[descriptorOrParameterIndex] = paramSpec;
|
|
344
|
-
} else {
|
|
345
|
-
operationSpec.parameters.unshift(paramSpec);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
return operationSpec;
|
|
349
|
-
});
|
|
350
|
-
};
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
function editOperationSpec(
|
|
354
|
-
endpoint: Partial<RestEndpoint>,
|
|
355
|
-
updateFn: (spec: OperationObject) => OperationObject,
|
|
356
|
-
) {
|
|
357
|
-
let spec = endpoint.spec;
|
|
358
|
-
if (!spec) {
|
|
359
|
-
spec = {
|
|
360
|
-
responses: {},
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
spec = updateFn(spec);
|
|
365
|
-
endpoint.spec = spec;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
export namespace param {
|
|
369
|
-
export const query = {
|
|
370
|
-
/**
|
|
371
|
-
* Define a parameter of "string" type that's read from the query string.
|
|
372
|
-
*
|
|
373
|
-
* @param name Parameter name.
|
|
374
|
-
*/
|
|
375
|
-
string: createParamShortcut('query', 'string'),
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Define a parameter of "number" type that's read from the query string.
|
|
379
|
-
*
|
|
380
|
-
* @param name Parameter name.
|
|
381
|
-
*/
|
|
382
|
-
number: createParamShortcut('query', 'number'),
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
* Define a parameter of "integer" type that's read from the query string.
|
|
386
|
-
*
|
|
387
|
-
* @param name Parameter name.
|
|
388
|
-
*/
|
|
389
|
-
integer: createParamShortcut('query', 'integer'),
|
|
390
|
-
|
|
391
|
-
/**
|
|
392
|
-
* Define a parameter of "boolean" type that's read from the query string.
|
|
393
|
-
*
|
|
394
|
-
* @param name Parameter name.
|
|
395
|
-
*/
|
|
396
|
-
boolean: createParamShortcut('query', 'boolean'),
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
export const header = {
|
|
400
|
-
/**
|
|
401
|
-
* Define a parameter of "string" type that's read from a request header.
|
|
402
|
-
*
|
|
403
|
-
* @param name Parameter name, it must match the header name
|
|
404
|
-
* (e.g. `Content-Type`).
|
|
405
|
-
*/
|
|
406
|
-
string: createParamShortcut('header', 'string'),
|
|
407
|
-
|
|
408
|
-
/**
|
|
409
|
-
* Define a parameter of "number" type that's read from a request header.
|
|
410
|
-
*
|
|
411
|
-
* @param name Parameter name, it must match the header name
|
|
412
|
-
* (e.g. `Content-Length`).
|
|
413
|
-
*/
|
|
414
|
-
number: createParamShortcut('header', 'number'),
|
|
415
|
-
|
|
416
|
-
/**
|
|
417
|
-
* Define a parameter of "integer" type that's read from a request header.
|
|
418
|
-
*
|
|
419
|
-
* @param name Parameter name, it must match the header name
|
|
420
|
-
* (e.g. `Content-Length`).
|
|
421
|
-
*/
|
|
422
|
-
integer: createParamShortcut('header', 'integer'),
|
|
423
|
-
|
|
424
|
-
/**
|
|
425
|
-
* Define a parameter of "boolean" type that's read from a request header.
|
|
426
|
-
*
|
|
427
|
-
* @param name Parameter name, it must match the header name,
|
|
428
|
-
* (e.g. `DNT` or `X-Do-Not-Track`).
|
|
429
|
-
*/
|
|
430
|
-
boolean: createParamShortcut('header', 'boolean'),
|
|
431
|
-
};
|
|
432
|
-
|
|
433
|
-
export const path = {
|
|
434
|
-
/**
|
|
435
|
-
* Define a parameter of "string" type that's read from request path.
|
|
436
|
-
*
|
|
437
|
-
* @param name Parameter name matching one of the placeholders in the path
|
|
438
|
-
* string.
|
|
439
|
-
*/
|
|
440
|
-
string: createParamShortcut('path', 'string'),
|
|
441
|
-
|
|
442
|
-
/**
|
|
443
|
-
* Define a parameter of "number" type that's read from request path.
|
|
444
|
-
*
|
|
445
|
-
* @param name Parameter name matching one of the placeholders in the path
|
|
446
|
-
* string.
|
|
447
|
-
*/
|
|
448
|
-
number: createParamShortcut('path', 'number'),
|
|
449
|
-
|
|
450
|
-
/**
|
|
451
|
-
* Define a parameter of "integer" type that's read from request path.
|
|
452
|
-
*
|
|
453
|
-
* @param name Parameter name matching one of the placeholders in the path
|
|
454
|
-
* string.
|
|
455
|
-
*/
|
|
456
|
-
integer: createParamShortcut('path', 'integer'),
|
|
457
|
-
|
|
458
|
-
/**
|
|
459
|
-
* Define a parameter of "boolean" type that's read from request path.
|
|
460
|
-
*
|
|
461
|
-
* @param name Parameter name matching one of the placeholders in the path
|
|
462
|
-
* string.
|
|
463
|
-
*/
|
|
464
|
-
boolean: createParamShortcut('path', 'boolean'),
|
|
465
|
-
};
|
|
466
|
-
|
|
467
|
-
export const formData = {
|
|
468
|
-
/**
|
|
469
|
-
* Define a parameter of "string" type that's read
|
|
470
|
-
* from a field in the request body.
|
|
471
|
-
*
|
|
472
|
-
* @param name Parameter name.
|
|
473
|
-
*/
|
|
474
|
-
string: createParamShortcut('formData', 'string'),
|
|
475
|
-
|
|
476
|
-
/**
|
|
477
|
-
* Define a parameter of "number" type that's read
|
|
478
|
-
* from a field in the request body.
|
|
479
|
-
*
|
|
480
|
-
* @param name Parameter name.
|
|
481
|
-
*/
|
|
482
|
-
number: createParamShortcut('formData', 'number'),
|
|
483
|
-
|
|
484
|
-
/**
|
|
485
|
-
* Define a parameter of "integer" type that's read
|
|
486
|
-
* from a field in the request body.
|
|
487
|
-
*
|
|
488
|
-
* @param name Parameter name.
|
|
489
|
-
*/
|
|
490
|
-
integer: createParamShortcut('formData', 'integer'),
|
|
491
|
-
|
|
492
|
-
/**
|
|
493
|
-
* Define a parameter of "boolean" type that's read
|
|
494
|
-
* from a field in the request body.
|
|
495
|
-
*
|
|
496
|
-
* @param name Parameter name.
|
|
497
|
-
*/
|
|
498
|
-
boolean: createParamShortcut('formData', 'boolean'),
|
|
499
|
-
};
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Define a parameter that's set to the full request body.
|
|
503
|
-
*
|
|
504
|
-
* @param name Parameter name
|
|
505
|
-
* @param schema The schema defining the type used for the body parameter.
|
|
506
|
-
*/
|
|
507
|
-
export const body = function(name: string, schema: SchemaObject) {
|
|
508
|
-
return param({name, in: 'body', schema});
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
function createParamShortcut(source: ParameterLocation, type: ParameterType) {
|
|
513
|
-
// TODO(bajtos) @param.IN.TYPE('foo', {required: true})
|
|
514
|
-
return (name: string) => {
|
|
515
|
-
return param({name, in: source, type});
|
|
516
|
-
};
|
|
517
|
-
}
|