@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.
Files changed (388) hide show
  1. package/CHANGELOG.md +1822 -0
  2. package/LICENSE +1 -1
  3. package/README.md +30 -58
  4. package/dist/body-parsers/body-parser.d.ts +25 -0
  5. package/dist/body-parsers/body-parser.helpers.d.ts +44 -0
  6. package/dist/body-parsers/body-parser.helpers.js +102 -0
  7. package/dist/body-parsers/body-parser.helpers.js.map +1 -0
  8. package/dist/body-parsers/body-parser.js +159 -0
  9. package/dist/body-parsers/body-parser.js.map +1 -0
  10. package/dist/body-parsers/body-parser.json.d.ts +9 -0
  11. package/dist/body-parsers/body-parser.json.js +43 -0
  12. package/dist/body-parsers/body-parser.json.js.map +1 -0
  13. package/dist/body-parsers/body-parser.raw.d.ts +12 -0
  14. package/dist/body-parsers/body-parser.raw.js +39 -0
  15. package/dist/body-parsers/body-parser.raw.js.map +1 -0
  16. package/dist/body-parsers/body-parser.stream.d.ts +12 -0
  17. package/dist/body-parsers/body-parser.stream.js +28 -0
  18. package/dist/body-parsers/body-parser.stream.js.map +1 -0
  19. package/dist/body-parsers/body-parser.text.d.ts +9 -0
  20. package/dist/body-parsers/body-parser.text.js +38 -0
  21. package/dist/body-parsers/body-parser.text.js.map +1 -0
  22. package/dist/body-parsers/body-parser.urlencoded.d.ts +9 -0
  23. package/dist/body-parsers/body-parser.urlencoded.js +36 -0
  24. package/dist/body-parsers/body-parser.urlencoded.js.map +1 -0
  25. package/dist/body-parsers/index.d.ts +8 -0
  26. package/dist/body-parsers/index.js +16 -0
  27. package/dist/body-parsers/index.js.map +1 -0
  28. package/dist/body-parsers/types.d.ts +51 -0
  29. package/dist/body-parsers/types.js +12 -0
  30. package/dist/body-parsers/types.js.map +1 -0
  31. package/dist/coercion/coerce-parameter.d.ts +9 -0
  32. package/dist/coercion/coerce-parameter.js +166 -0
  33. package/dist/coercion/coerce-parameter.js.map +1 -0
  34. package/dist/coercion/utils.d.ts +43 -0
  35. package/dist/coercion/utils.js +96 -0
  36. package/dist/coercion/utils.js.map +1 -0
  37. package/dist/coercion/validator.d.ts +49 -0
  38. package/dist/coercion/validator.js +85 -0
  39. package/dist/coercion/validator.js.map +1 -0
  40. package/dist/http-handler.d.ts +38 -0
  41. package/dist/http-handler.js +68 -0
  42. package/dist/http-handler.js.map +1 -0
  43. package/dist/index.d.ts +36 -1
  44. package/dist/index.js +40 -6
  45. package/dist/index.js.map +1 -0
  46. package/dist/keys.d.ts +198 -0
  47. package/dist/keys.js +202 -0
  48. package/dist/keys.js.map +1 -0
  49. package/dist/parse-json.d.ts +11 -0
  50. package/dist/parse-json.js +42 -0
  51. package/dist/parse-json.js.map +1 -0
  52. package/dist/parser.d.ts +11 -0
  53. package/dist/parser.js +76 -0
  54. package/dist/parser.js.map +1 -0
  55. package/{dist6/src/providers/find-route.d.ts → dist/providers/find-route.provider.d.ts} +3 -1
  56. package/dist/providers/find-route.provider.js +36 -0
  57. package/dist/providers/find-route.provider.js.map +1 -0
  58. package/dist/providers/index.d.ts +6 -0
  59. package/dist/providers/index.js +14 -0
  60. package/dist/providers/index.js.map +1 -0
  61. package/dist/{src/providers/invoke-method.d.ts → providers/invoke-method.provider.d.ts} +3 -1
  62. package/dist/providers/invoke-method.provider.js +30 -0
  63. package/dist/providers/invoke-method.provider.js.map +1 -0
  64. package/dist/providers/log-error.provider.d.ts +6 -0
  65. package/dist/providers/log-error.provider.js +21 -0
  66. package/dist/providers/log-error.provider.js.map +1 -0
  67. package/dist/providers/parse-params.provider.d.ts +15 -0
  68. package/dist/providers/parse-params.provider.js +41 -0
  69. package/dist/providers/parse-params.provider.js.map +1 -0
  70. package/dist/providers/reject.provider.d.ts +10 -0
  71. package/dist/providers/reject.provider.js +47 -0
  72. package/dist/providers/reject.provider.js.map +1 -0
  73. package/dist/{src/providers/send.d.ts → providers/send.provider.d.ts} +1 -4
  74. package/dist/{src/providers/send.js → providers/send.provider.js} +4 -6
  75. package/dist/providers/send.provider.js.map +1 -0
  76. package/dist/request-context.d.ts +36 -0
  77. package/dist/request-context.js +104 -0
  78. package/dist/request-context.js.map +1 -0
  79. package/dist/rest-http-error.d.ts +37 -0
  80. package/dist/rest-http-error.js +51 -0
  81. package/dist/rest-http-error.js.map +1 -0
  82. package/dist/rest.application.d.ts +232 -0
  83. package/dist/rest.application.js +174 -0
  84. package/dist/rest.application.js.map +1 -0
  85. package/dist/rest.component.d.ts +15 -0
  86. package/dist/rest.component.js +72 -0
  87. package/dist/rest.component.js.map +1 -0
  88. package/dist/rest.server.d.ts +443 -0
  89. package/dist/rest.server.js +748 -0
  90. package/dist/rest.server.js.map +1 -0
  91. package/dist/router/base-route.d.ts +29 -0
  92. package/dist/router/base-route.js +41 -0
  93. package/dist/router/base-route.js.map +1 -0
  94. package/dist/router/controller-route.d.ts +61 -0
  95. package/dist/router/controller-route.js +160 -0
  96. package/dist/router/controller-route.js.map +1 -0
  97. package/dist/router/external-express-routes.d.ts +24 -0
  98. package/dist/router/external-express-routes.js +90 -0
  99. package/dist/router/external-express-routes.js.map +1 -0
  100. package/dist/router/handler-route.d.ts +12 -0
  101. package/dist/router/handler-route.js +30 -0
  102. package/dist/router/handler-route.js.map +1 -0
  103. package/dist/router/index.d.ts +14 -0
  104. package/dist/router/index.js +25 -0
  105. package/dist/router/index.js.map +1 -0
  106. package/dist/router/openapi-path.d.ts +14 -0
  107. package/dist/router/openapi-path.js +64 -0
  108. package/dist/router/openapi-path.js.map +1 -0
  109. package/dist/router/redirect-route.d.ts +23 -0
  110. package/dist/router/redirect-route.js +50 -0
  111. package/dist/router/redirect-route.js.map +1 -0
  112. package/dist/router/regexp-router.d.ts +25 -0
  113. package/dist/router/regexp-router.js +84 -0
  114. package/dist/router/regexp-router.js.map +1 -0
  115. package/dist/router/rest-router.d.ts +35 -0
  116. package/dist/{src/internal-types.js → router/rest-router.js} +2 -2
  117. package/dist/router/rest-router.js.map +1 -0
  118. package/dist/router/route-entry.d.ts +46 -0
  119. package/dist/router/route-entry.js +20 -0
  120. package/dist/router/route-entry.js.map +1 -0
  121. package/dist/router/route-sort.d.ts +7 -0
  122. package/dist/router/route-sort.js +75 -0
  123. package/dist/router/route-sort.js.map +1 -0
  124. package/dist/router/router-base.d.ts +42 -0
  125. package/dist/router/router-base.js +101 -0
  126. package/dist/router/router-base.js.map +1 -0
  127. package/dist/router/router-spec.d.ts +3 -0
  128. package/dist/router/router-spec.js +40 -0
  129. package/dist/router/router-spec.js.map +1 -0
  130. package/dist/router/routing-table.d.ts +32 -0
  131. package/dist/router/routing-table.js +86 -0
  132. package/dist/router/routing-table.js.map +1 -0
  133. package/dist/router/trie-router.d.ts +13 -0
  134. package/dist/router/trie-router.js +55 -0
  135. package/dist/router/trie-router.js.map +1 -0
  136. package/dist/router/trie.d.ts +59 -0
  137. package/dist/router/trie.js +180 -0
  138. package/dist/router/trie.js.map +1 -0
  139. package/{dist6/src → dist}/sequence.d.ts +28 -23
  140. package/dist/sequence.js +112 -0
  141. package/dist/sequence.js.map +1 -0
  142. package/dist/spec-enhancers/consolidate.spec-enhancer.d.ts +68 -0
  143. package/dist/spec-enhancers/consolidate.spec-enhancer.js +145 -0
  144. package/dist/spec-enhancers/consolidate.spec-enhancer.js.map +1 -0
  145. package/dist/spec-enhancers/info.spec-enhancer.d.ts +19 -0
  146. package/dist/spec-enhancers/info.spec-enhancer.js +89 -0
  147. package/dist/spec-enhancers/info.spec-enhancer.js.map +1 -0
  148. package/dist/types.d.ts +178 -0
  149. package/dist/types.js +12 -0
  150. package/dist/types.js.map +1 -0
  151. package/dist/validation/ajv-factory.provider.d.ts +12 -0
  152. package/dist/validation/ajv-factory.provider.js +87 -0
  153. package/dist/validation/ajv-factory.provider.js.map +1 -0
  154. package/dist/validation/request-body.validator.d.ts +14 -0
  155. package/dist/validation/request-body.validator.js +161 -0
  156. package/dist/validation/request-body.validator.js.map +1 -0
  157. package/dist/writer.d.ts +9 -0
  158. package/dist/writer.js +62 -0
  159. package/dist/writer.js.map +1 -0
  160. package/package.json +66 -38
  161. package/src/body-parsers/body-parser.helpers.ts +148 -0
  162. package/src/body-parsers/body-parser.json.ts +46 -0
  163. package/src/body-parsers/body-parser.raw.ts +42 -0
  164. package/src/body-parsers/body-parser.stream.ts +27 -0
  165. package/src/body-parsers/body-parser.text.ts +44 -0
  166. package/src/body-parsers/body-parser.ts +208 -0
  167. package/src/body-parsers/body-parser.urlencoded.ts +42 -0
  168. package/src/body-parsers/index.ts +13 -0
  169. package/src/body-parsers/types.ts +60 -0
  170. package/src/coercion/coerce-parameter.ts +207 -0
  171. package/src/coercion/utils.ts +103 -0
  172. package/src/coercion/validator.ts +98 -0
  173. package/src/http-handler.ts +84 -41
  174. package/src/index.ts +37 -30
  175. package/src/keys.ts +273 -20
  176. package/src/parse-json.ts +42 -0
  177. package/src/parser.ts +89 -104
  178. package/src/providers/{find-route.ts → find-route.provider.ts} +10 -7
  179. package/src/providers/index.ts +7 -9
  180. package/src/providers/{invoke-method.ts → invoke-method.provider.ts} +8 -5
  181. package/src/providers/log-error.provider.ts +27 -0
  182. package/src/providers/parse-params.provider.ts +42 -0
  183. package/src/providers/reject.provider.ts +44 -0
  184. package/src/providers/{send.ts → send.provider.ts} +2 -5
  185. package/src/request-context.ts +123 -0
  186. package/src/rest-http-error.ts +87 -0
  187. package/src/rest.application.ts +390 -0
  188. package/src/rest.component.ts +111 -0
  189. package/src/rest.server.ts +1192 -0
  190. package/src/router/base-route.ts +53 -0
  191. package/src/router/controller-route.ts +241 -0
  192. package/src/router/external-express-routes.ts +139 -0
  193. package/src/router/handler-route.ts +44 -0
  194. package/src/router/index.ts +24 -0
  195. package/src/router/openapi-path.ts +67 -0
  196. package/src/router/redirect-route.ts +64 -0
  197. package/src/router/regexp-router.ts +104 -0
  198. package/src/router/rest-router.ts +48 -0
  199. package/src/router/route-entry.ts +74 -0
  200. package/src/router/route-sort.ts +74 -0
  201. package/src/router/router-base.ts +124 -0
  202. package/src/router/router-spec.ts +36 -0
  203. package/src/router/routing-table.ts +83 -279
  204. package/src/router/trie-router.ts +57 -0
  205. package/src/router/trie.ts +233 -0
  206. package/src/sequence.ts +44 -37
  207. package/src/spec-enhancers/consolidate.spec-enhancer.ts +182 -0
  208. package/src/spec-enhancers/info.spec-enhancer.ts +92 -0
  209. package/src/types.ts +216 -0
  210. package/src/validation/ajv-factory.provider.ts +94 -0
  211. package/src/validation/request-body.validator.ts +208 -0
  212. package/src/writer.ts +41 -68
  213. package/api-docs/.DS_Store +0 -0
  214. package/api-docs/apple-touch-icon-114x114-precomposed.png +0 -0
  215. package/api-docs/apple-touch-icon-144x144-precomposed.png +0 -0
  216. package/api-docs/apple-touch-icon-57x57-precomposed.png +0 -0
  217. package/api-docs/apple-touch-icon-72x72-precomposed.png +0 -0
  218. package/api-docs/apple-touch-icon-precomposed.png +0 -0
  219. package/api-docs/apple-touch-icon.png +0 -0
  220. package/api-docs/css/bootstrap.min.css +0 -9
  221. package/api-docs/css/code-themes/arta.css +0 -158
  222. package/api-docs/css/code-themes/ascetic.css +0 -50
  223. package/api-docs/css/code-themes/brown_paper.css +0 -104
  224. package/api-docs/css/code-themes/brown_papersq.png +0 -0
  225. package/api-docs/css/code-themes/dark.css +0 -103
  226. package/api-docs/css/code-themes/default.css +0 -135
  227. package/api-docs/css/code-themes/far.css +0 -111
  228. package/api-docs/css/code-themes/github.css +0 -127
  229. package/api-docs/css/code-themes/googlecode.css +0 -144
  230. package/api-docs/css/code-themes/idea.css +0 -121
  231. package/api-docs/css/code-themes/ir_black.css +0 -104
  232. package/api-docs/css/code-themes/magula.css +0 -121
  233. package/api-docs/css/code-themes/monokai.css +0 -114
  234. package/api-docs/css/code-themes/pojoaque.css +0 -104
  235. package/api-docs/css/code-themes/pojoaque.jpg +0 -0
  236. package/api-docs/css/code-themes/rainbow.css +0 -114
  237. package/api-docs/css/code-themes/school_book.css +0 -111
  238. package/api-docs/css/code-themes/school_book.png +0 -0
  239. package/api-docs/css/code-themes/sl-theme.css +0 -45
  240. package/api-docs/css/code-themes/solarized_dark.css +0 -88
  241. package/api-docs/css/code-themes/solarized_light.css +0 -88
  242. package/api-docs/css/code-themes/sunburst.css +0 -158
  243. package/api-docs/css/code-themes/tomorrow-night-blue.css +0 -52
  244. package/api-docs/css/code-themes/tomorrow-night-bright.css +0 -51
  245. package/api-docs/css/code-themes/tomorrow-night-eighties.css +0 -51
  246. package/api-docs/css/code-themes/tomorrow-night.css +0 -52
  247. package/api-docs/css/code-themes/tomorrow.css +0 -49
  248. package/api-docs/css/code-themes/vs.css +0 -86
  249. package/api-docs/css/code-themes/xcode.css +0 -154
  250. package/api-docs/css/code-themes/zenburn.css +0 -115
  251. package/api-docs/css/main.css +0 -139
  252. package/api-docs/favicon.ico +0 -0
  253. package/api-docs/fonts/0ihfXUL2emPh0ROJezvraLO3LdcAZYWl9Si6vvxL-qU.woff +0 -0
  254. package/api-docs/fonts/OsJ2DjdpjqFRVUSto6IffLO3LdcAZYWl9Si6vvxL-qU.woff +0 -0
  255. package/api-docs/fonts/_aijTyevf54tkVDLy-dlnLO3LdcAZYWl9Si6vvxL-qU.woff +0 -0
  256. package/api-docs/index.html +0 -7082
  257. package/api-docs/js/main.js +0 -19
  258. package/api-docs/js/vendor/bootstrap.min.js +0 -6
  259. package/api-docs/js/vendor/jquery-1.10.1.min.js +0 -6
  260. package/api-docs/js/vendor/jquery.scrollTo-1.4.3.1.js +0 -218
  261. package/api-docs/js/vendor/modernizr-2.6.2-respond-1.1.0.min.js +0 -11
  262. package/dist/src/http-handler.d.ts +0 -19
  263. package/dist/src/http-handler.js +0 -43
  264. package/dist/src/http-handler.js.map +0 -1
  265. package/dist/src/index.d.ts +0 -14
  266. package/dist/src/index.js +0 -33
  267. package/dist/src/index.js.map +0 -1
  268. package/dist/src/internal-types.d.ts +0 -67
  269. package/dist/src/internal-types.js.map +0 -1
  270. package/dist/src/keys.d.ts +0 -22
  271. package/dist/src/keys.js +0 -35
  272. package/dist/src/keys.js.map +0 -1
  273. package/dist/src/parser.d.ts +0 -11
  274. package/dist/src/parser.js +0 -98
  275. package/dist/src/parser.js.map +0 -1
  276. package/dist/src/providers/bind-element.d.ts +0 -7
  277. package/dist/src/providers/bind-element.js +0 -34
  278. package/dist/src/providers/bind-element.js.map +0 -1
  279. package/dist/src/providers/find-route.d.ts +0 -9
  280. package/dist/src/providers/find-route.js +0 -42
  281. package/dist/src/providers/find-route.js.map +0 -1
  282. package/dist/src/providers/get-from-context.d.ts +0 -7
  283. package/dist/src/providers/get-from-context.js +0 -34
  284. package/dist/src/providers/get-from-context.js.map +0 -1
  285. package/dist/src/providers/index.d.ts +0 -8
  286. package/dist/src/providers/index.js +0 -18
  287. package/dist/src/providers/index.js.map +0 -1
  288. package/dist/src/providers/invoke-method.js +0 -36
  289. package/dist/src/providers/invoke-method.js.map +0 -1
  290. package/dist/src/providers/log-error-provider.d.ts +0 -6
  291. package/dist/src/providers/log-error-provider.js +0 -17
  292. package/dist/src/providers/log-error-provider.js.map +0 -1
  293. package/dist/src/providers/parse-params.d.ts +0 -13
  294. package/dist/src/providers/parse-params.js +0 -22
  295. package/dist/src/providers/parse-params.js.map +0 -1
  296. package/dist/src/providers/reject.d.ts +0 -6
  297. package/dist/src/providers/reject.js +0 -40
  298. package/dist/src/providers/reject.js.map +0 -1
  299. package/dist/src/providers/send.js.map +0 -1
  300. package/dist/src/rest-component.d.ts +0 -12
  301. package/dist/src/rest-component.js +0 -50
  302. package/dist/src/rest-component.js.map +0 -1
  303. package/dist/src/rest-server.d.ts +0 -211
  304. package/dist/src/rest-server.js +0 -426
  305. package/dist/src/rest-server.js.map +0 -1
  306. package/dist/src/router/metadata.d.ts +0 -150
  307. package/dist/src/router/metadata.js +0 -410
  308. package/dist/src/router/metadata.js.map +0 -1
  309. package/dist/src/router/routing-table.d.ts +0 -68
  310. package/dist/src/router/routing-table.js +0 -204
  311. package/dist/src/router/routing-table.js.map +0 -1
  312. package/dist/src/sequence.d.ts +0 -81
  313. package/dist/src/sequence.js +0 -104
  314. package/dist/src/sequence.js.map +0 -1
  315. package/dist/src/writer.d.ts +0 -17
  316. package/dist/src/writer.js +0 -87
  317. package/dist/src/writer.js.map +0 -1
  318. package/dist6/index.d.ts +0 -1
  319. package/dist6/index.js +0 -12
  320. package/dist6/src/http-handler.d.ts +0 -19
  321. package/dist6/src/http-handler.js +0 -53
  322. package/dist6/src/http-handler.js.map +0 -1
  323. package/dist6/src/index.d.ts +0 -14
  324. package/dist6/src/index.js +0 -33
  325. package/dist6/src/index.js.map +0 -1
  326. package/dist6/src/internal-types.d.ts +0 -67
  327. package/dist6/src/internal-types.js +0 -7
  328. package/dist6/src/internal-types.js.map +0 -1
  329. package/dist6/src/keys.d.ts +0 -22
  330. package/dist6/src/keys.js +0 -35
  331. package/dist6/src/keys.js.map +0 -1
  332. package/dist6/src/parser.d.ts +0 -11
  333. package/dist6/src/parser.js +0 -108
  334. package/dist6/src/parser.js.map +0 -1
  335. package/dist6/src/providers/bind-element.d.ts +0 -7
  336. package/dist6/src/providers/bind-element.js +0 -34
  337. package/dist6/src/providers/bind-element.js.map +0 -1
  338. package/dist6/src/providers/find-route.js +0 -42
  339. package/dist6/src/providers/find-route.js.map +0 -1
  340. package/dist6/src/providers/get-from-context.d.ts +0 -7
  341. package/dist6/src/providers/get-from-context.js +0 -34
  342. package/dist6/src/providers/get-from-context.js.map +0 -1
  343. package/dist6/src/providers/index.d.ts +0 -8
  344. package/dist6/src/providers/index.js +0 -18
  345. package/dist6/src/providers/index.js.map +0 -1
  346. package/dist6/src/providers/invoke-method.d.ts +0 -7
  347. package/dist6/src/providers/invoke-method.js +0 -44
  348. package/dist6/src/providers/invoke-method.js.map +0 -1
  349. package/dist6/src/providers/log-error-provider.d.ts +0 -6
  350. package/dist6/src/providers/log-error-provider.js +0 -17
  351. package/dist6/src/providers/log-error-provider.js.map +0 -1
  352. package/dist6/src/providers/parse-params.d.ts +0 -13
  353. package/dist6/src/providers/parse-params.js +0 -22
  354. package/dist6/src/providers/parse-params.js.map +0 -1
  355. package/dist6/src/providers/reject.d.ts +0 -6
  356. package/dist6/src/providers/reject.js +0 -40
  357. package/dist6/src/providers/reject.js.map +0 -1
  358. package/dist6/src/providers/send.d.ts +0 -15
  359. package/dist6/src/providers/send.js +0 -24
  360. package/dist6/src/providers/send.js.map +0 -1
  361. package/dist6/src/rest-component.d.ts +0 -12
  362. package/dist6/src/rest-component.js +0 -50
  363. package/dist6/src/rest-component.js.map +0 -1
  364. package/dist6/src/rest-server.d.ts +0 -211
  365. package/dist6/src/rest-server.js +0 -444
  366. package/dist6/src/rest-server.js.map +0 -1
  367. package/dist6/src/router/metadata.d.ts +0 -150
  368. package/dist6/src/router/metadata.js +0 -410
  369. package/dist6/src/router/metadata.js.map +0 -1
  370. package/dist6/src/router/routing-table.d.ts +0 -68
  371. package/dist6/src/router/routing-table.js +0 -218
  372. package/dist6/src/router/routing-table.js.map +0 -1
  373. package/dist6/src/sequence.js +0 -114
  374. package/dist6/src/sequence.js.map +0 -1
  375. package/dist6/src/writer.d.ts +0 -17
  376. package/dist6/src/writer.js +0 -87
  377. package/dist6/src/writer.js.map +0 -1
  378. package/index.d.ts +0 -6
  379. package/index.js +0 -9
  380. package/src/internal-types.ts +0 -96
  381. package/src/providers/bind-element.ts +0 -15
  382. package/src/providers/get-from-context.ts +0 -16
  383. package/src/providers/log-error-provider.ts +0 -23
  384. package/src/providers/parse-params.ts +0 -20
  385. package/src/providers/reject.ts +0 -27
  386. package/src/rest-component.ts +0 -54
  387. package/src/rest-server.ts +0 -584
  388. package/src/router/metadata.ts +0 -517
@@ -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
- }