@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,27 +0,0 @@
1
- // Copyright IBM Corp. 2017. All Rights Reserved.
2
- // Node module: loopback
3
- // This file is licensed under the MIT License.
4
- // License text available at https://opensource.org/licenses/MIT
5
-
6
- import {LogError, Reject} from '../internal-types';
7
- import {inject} from '@loopback/context';
8
- import {ServerResponse, ServerRequest} from 'http';
9
- import {HttpError} from 'http-errors';
10
- import {writeErrorToResponse} from '../writer';
11
- import {RestBindings} from '../keys';
12
-
13
- export class RejectProvider {
14
- constructor(
15
- @inject(RestBindings.SequenceActions.LOG_ERROR)
16
- protected logError: LogError,
17
- ) {}
18
-
19
- value(): Reject {
20
- return (response: ServerResponse, request: ServerRequest, error: Error) => {
21
- const err = <HttpError>error;
22
- const statusCode = err.statusCode || err.status || 500;
23
- writeErrorToResponse(response, err);
24
- this.logError(error, statusCode, request);
25
- };
26
- }
27
- }
@@ -1,54 +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 {
7
- Component,
8
- CoreBindings,
9
- ProviderMap,
10
- Server,
11
- Application,
12
- } from '@loopback/core';
13
- import {inject, Constructor} from '@loopback/context';
14
- import {RestBindings} from './keys';
15
- import {LogErrorProvider} from './providers';
16
- import {
17
- BindElementProvider,
18
- FindRouteProvider,
19
- GetFromContextProvider,
20
- InvokeMethodProvider,
21
- RejectProvider,
22
- ParseParamsProvider,
23
- SendProvider,
24
- } from './providers';
25
- import {RestServer, RestServerConfig} from './rest-server';
26
-
27
- export class RestComponent implements Component {
28
- providers: ProviderMap = {
29
- [RestBindings.SequenceActions.LOG_ERROR]: LogErrorProvider,
30
- [RestBindings.SequenceActions.FIND_ROUTE]: FindRouteProvider,
31
- [RestBindings.SequenceActions.INVOKE_METHOD]: InvokeMethodProvider,
32
- [RestBindings.SequenceActions.REJECT]: RejectProvider,
33
- [RestBindings.BIND_ELEMENT]: BindElementProvider,
34
- [RestBindings.GET_FROM_CONTEXT]: GetFromContextProvider,
35
- [RestBindings.SequenceActions.PARSE_PARAMS]: ParseParamsProvider,
36
- [RestBindings.SequenceActions.SEND]: SendProvider,
37
- };
38
- servers: {
39
- [name: string]: Constructor<Server>;
40
- } = {
41
- RestServer,
42
- };
43
-
44
- constructor(
45
- @inject(CoreBindings.APPLICATION_INSTANCE) app: Application,
46
- @inject(RestBindings.CONFIG) config?: RestComponentConfig,
47
- ) {
48
- if (!config) config = {};
49
- }
50
- }
51
-
52
- export interface RestComponentConfig extends RestServerConfig {
53
- // TODO(kevin): Extend this interface def to include multiple servers?
54
- }
@@ -1,584 +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 {AssertionError} from 'assert';
7
- const swagger2openapi = require('swagger2openapi');
8
- import {safeDump} from 'js-yaml';
9
- import {Binding, Context, Constructor, inject} from '@loopback/context';
10
- import {Route, ControllerRoute, RouteEntry, ParsedRequest} from '.';
11
- import {
12
- OpenApiSpec,
13
- createEmptyApiSpec,
14
- OperationObject,
15
- } from '@loopback/openapi-spec';
16
- import {ServerRequest, ServerResponse, createServer} from 'http';
17
- import * as Http from 'http';
18
- import {Application, CoreBindings, Server} from '@loopback/core';
19
- import {getControllerSpec} from './router/metadata';
20
- import {HttpHandler} from './http-handler';
21
- import {DefaultSequence, SequenceHandler, SequenceFunction} from './sequence';
22
- import {
23
- FindRoute,
24
- InvokeMethod,
25
- Send,
26
- Reject,
27
- ParseParams,
28
- } from './internal-types';
29
- import {ControllerClass} from './router/routing-table';
30
- import {RestBindings} from './keys';
31
-
32
- const SequenceActions = RestBindings.SequenceActions;
33
-
34
- // NOTE(bajtos) we cannot use `import * as cloneDeep from 'lodash/cloneDeep'
35
- // because it produces the following TypeScript error:
36
- // Module '"(...)/node_modules/@types/lodash/cloneDeep/index"' resolves to
37
- // a non-module entity and cannot be imported using this construct.
38
- const cloneDeep: <T>(value: T) => T = require('lodash/cloneDeep');
39
-
40
- /**
41
- * The object format used for building the template bases of our OpenAPI spec
42
- * files.
43
- *
44
- * @interface OpenApiSpecOptions
45
- */
46
- interface OpenApiSpecOptions {
47
- version?: string;
48
- format?: string;
49
- }
50
-
51
- const OPENAPI_SPEC_MAPPING: {[key: string]: OpenApiSpecOptions} = {
52
- '/openapi.json': {version: '3.0.0', format: 'json'},
53
- '/openapi.yaml': {version: '3.0.0', format: 'yaml'},
54
- '/swagger.json': {version: '2.0', format: 'json'},
55
- '/swagger.yaml': {version: '2.0', format: 'yaml'},
56
- };
57
-
58
- /**
59
- * A REST API server for use with Loopback.
60
- * Add this server to your application by importing the RestComponent.
61
- * ```ts
62
- * const app = new MyApplication({
63
- * components: [RestComponent]
64
- * });
65
- * // OR
66
- * app.component(RestComponent);
67
- * ```
68
- *
69
- * To add additional instances of RestServer to your application, use the
70
- * `.server` function:
71
- * ```ts
72
- * app.server(RestServer, 'nameOfYourServer');
73
- * ```
74
- *
75
- * By default, one instance of RestServer will be created when the RestComponent
76
- * is bootstrapped. This instance can be retrieved with
77
- * `app.getServer(RestServer)`, or by calling `app.get('servers.RestServer')`
78
- * Note that retrieving other instances of RestServer must be done using the
79
- * server's name:
80
- * ```ts
81
- * const server = await app.getServer('foo')
82
- * // OR
83
- * const server = await app.get('servers.foo');
84
- * ```
85
- *
86
- * @export
87
- * @class RestServer
88
- * @extends {Context}
89
- * @implements {Server}
90
- */
91
- export class RestServer extends Context implements Server {
92
- /**
93
- * Handle incoming HTTP(S) request by invoking the corresponding
94
- * Controller method via the configured Sequence.
95
- *
96
- * @example
97
- *
98
- * ```ts
99
- * const app = new Application();
100
- * // setup controllers, etc.
101
- *
102
- * const server = http.createServer(app.handleHttp);
103
- * server.listen(3000);
104
- * ```
105
- *
106
- * @param req The request.
107
- * @param res The response.
108
- */
109
- public handleHttp: (req: ServerRequest, res: ServerResponse) => void;
110
-
111
- protected _httpHandler: HttpHandler;
112
- protected get httpHandler(): HttpHandler {
113
- this._setupHandlerIfNeeded();
114
- return this._httpHandler;
115
- }
116
- protected _httpServer: Http.Server;
117
-
118
- /**
119
- * @memberof RestServer
120
- * Creates an instance of RestServer.
121
- *
122
- * @param {Application} app The application instance (injected via
123
- * CoreBindings.APPLICATION_INSTANCE).
124
- * @param {RestServerConfig=} options The configuration options (injected via
125
- * RestBindings.CONFIG).
126
- *
127
- */
128
- constructor(
129
- @inject(CoreBindings.APPLICATION_INSTANCE) app: Application,
130
- @inject(RestBindings.CONFIG) options?: RestServerConfig,
131
- ) {
132
- super(app);
133
-
134
- if (!options) options = {};
135
-
136
- // Can't check falsiness, 0 is a valid port.
137
- if (options.port === null || options.port === undefined) {
138
- options.port = 3000;
139
- }
140
- this.bind(RestBindings.PORT).to(options.port);
141
- this.api(createEmptyApiSpec());
142
-
143
- this.sequence(options.sequence ? options.sequence : DefaultSequence);
144
-
145
- this.handleHttp = (req: ServerRequest, res: ServerResponse) => {
146
- try {
147
- this._handleHttpRequest(req, res).catch(err =>
148
- this._onUnhandledError(req, res, err),
149
- );
150
- } catch (err) {
151
- this._onUnhandledError(req, res, err);
152
- }
153
- };
154
-
155
- this.bind(RestBindings.HANDLER).toDynamicValue(() => this.httpHandler);
156
- }
157
-
158
- protected _handleHttpRequest(
159
- request: ServerRequest,
160
- response: ServerResponse,
161
- ) {
162
- // allow CORS support for all endpoints so that users
163
- // can test with online SwaggerUI instance
164
- response.setHeader('Access-Control-Allow-Origin', '*');
165
- response.setHeader('Access-Control-Allow-Credentials', 'true');
166
- response.setHeader('Access-Control-Allow-Max-Age', '86400');
167
-
168
- if (
169
- request.method === 'GET' &&
170
- request.url &&
171
- request.url in OPENAPI_SPEC_MAPPING
172
- ) {
173
- // NOTE(bajtos) Regular routes are handled through Sequence.
174
- // IMO, this built-in endpoint should not run through a Sequence,
175
- // because it's not part of the application API itself.
176
- // E.g. if the app implements access/audit logs, I don't want
177
- // this endpoint to trigger a log entry. If the server implements
178
- // content-negotiation to support XML clients, I don't want the OpenAPI
179
- // spec to be converted into an XML response.
180
- const options = OPENAPI_SPEC_MAPPING[request.url];
181
- return this._serveOpenApiSpec(request, response, options);
182
- }
183
- if (
184
- request.method === 'GET' &&
185
- request.url &&
186
- request.url === '/swagger-ui'
187
- ) {
188
- return this._redirectToSwaggerUI(request, response);
189
- }
190
- return this.httpHandler.handleRequest(request, response);
191
- }
192
-
193
- protected _setupHandlerIfNeeded() {
194
- // TODO(bajtos) support hot-reloading of controllers
195
- // after the app started. The idea is to rebuild the HttpHandler
196
- // instance whenever a controller was added/deleted.
197
- // See https://github.com/strongloop/loopback-next/issues/433
198
- if (this._httpHandler) return;
199
-
200
- this._httpHandler = new HttpHandler(this);
201
- for (const b of this.find('controllers.*')) {
202
- const controllerName = b.key.replace(/^controllers\./, '');
203
- const ctor = b.valueConstructor;
204
- if (!ctor) {
205
- throw new Error(
206
- `The controller ${controllerName} was not bound via .toClass()`,
207
- );
208
- }
209
- const apiSpec = getControllerSpec(ctor);
210
- if (!apiSpec) {
211
- // controller methods are specified through app.api() spec
212
- continue;
213
- }
214
- this._httpHandler.registerController(ctor, apiSpec);
215
- }
216
-
217
- for (const b of this.find('routes.*')) {
218
- // TODO(bajtos) should we support routes defined asynchronously?
219
- const route = this.getSync(b.key);
220
- this._httpHandler.registerRoute(route);
221
- }
222
-
223
- // TODO(bajtos) should we support API spec defined asynchronously?
224
- const spec: OpenApiSpec = this.getSync(RestBindings.API_SPEC);
225
- for (const path in spec.paths) {
226
- for (const verb in spec.paths[path]) {
227
- const routeSpec: OperationObject = spec.paths[path][verb];
228
- this._setupOperation(verb, path, routeSpec);
229
- }
230
- }
231
- }
232
-
233
- private _setupOperation(verb: string, path: string, spec: OperationObject) {
234
- const handler = spec['x-operation'];
235
- if (typeof handler === 'function') {
236
- // Remove a field value that cannot be represented in JSON.
237
- // Start by creating a shallow-copy of the spec, so that we don't
238
- // modify the original spec object provided by user.
239
- spec = Object.assign({}, spec);
240
- delete spec['x-operation'];
241
-
242
- const route = new Route(verb, path, spec, handler);
243
- this._httpHandler.registerRoute(route);
244
- return;
245
- }
246
-
247
- const controllerName = spec['x-controller-name'];
248
- if (typeof controllerName === 'string') {
249
- const b = this.find(`controllers.${controllerName}`)[0];
250
- if (!b) {
251
- throw new Error(
252
- `Unknown controller ${controllerName} used by "${verb} ${path}"`,
253
- );
254
- }
255
-
256
- const ctor = b.valueConstructor;
257
- if (!ctor) {
258
- throw new Error(
259
- `The controller ${controllerName} was not bound via .toClass()`,
260
- );
261
- }
262
-
263
- const route = new ControllerRoute(verb, path, spec, ctor);
264
- this._httpHandler.registerRoute(route);
265
- return;
266
- }
267
-
268
- throw new Error(
269
- `There is no handler configured for operation "${verb} ${path}`,
270
- );
271
- }
272
-
273
- private async _serveOpenApiSpec(
274
- request: ServerRequest,
275
- response: ServerResponse,
276
- options?: OpenApiSpecOptions,
277
- ) {
278
- options = options || {version: '2.0', format: 'json'};
279
- let specObj = this.getApiSpec();
280
- if (options.version === '3.0.0') {
281
- specObj = await swagger2openapi.convertObj(specObj, {direct: true});
282
- }
283
- if (options.format === 'json') {
284
- const spec = JSON.stringify(specObj, null, 2);
285
- response.setHeader('content-type', 'application/json; charset=utf-8');
286
- response.end(spec, 'utf-8');
287
- } else {
288
- const yaml = safeDump(specObj, {});
289
- response.setHeader('content-type', 'text/yaml; charset=utf-8');
290
- response.end(yaml, 'utf-8');
291
- }
292
- }
293
-
294
- private async _redirectToSwaggerUI(
295
- request: ServerRequest,
296
- response: ServerResponse,
297
- ) {
298
- response.statusCode = 308;
299
- response.setHeader(
300
- 'Location',
301
- 'http://petstore.swagger.io/?url=' +
302
- 'http://' +
303
- request.headers.host +
304
- '/swagger.json',
305
- );
306
- response.end();
307
- }
308
-
309
- /**
310
- * Register a controller class with this server.
311
- *
312
- * @param {Constructor} controllerCtor The controller class
313
- * (constructor function).
314
- * @returns {Binding} The newly created binding, you can use the reference to
315
- * further modify the binding, e.g. lock the value to prevent further
316
- * modifications.
317
- *
318
- * ```ts
319
- * class MyController {
320
- * }
321
- * app.controller(MyController).lock();
322
- * ```
323
- *
324
- */
325
- controller(controllerCtor: ControllerClass): Binding {
326
- return this.bind('controllers.' + controllerCtor.name).toClass(
327
- controllerCtor,
328
- );
329
- }
330
-
331
- /**
332
- * Register a new Controller-based route.
333
- *
334
- * ```ts
335
- * class MyController {
336
- * greet(name: string) {
337
- * return `hello ${name}`;
338
- * }
339
- * }
340
- * app.route('get', '/greet', operationSpec, MyController, 'greet');
341
- * ```
342
- *
343
- * @param verb HTTP verb of the endpoint
344
- * @param path URL path of the endpoint
345
- * @param spec The OpenAPI spec describing the endpoint (operation)
346
- * @param controller Controller constructor
347
- * @param methodName The name of the controller method
348
- */
349
- route(
350
- verb: string,
351
- path: string,
352
- spec: OperationObject,
353
- controller: ControllerClass,
354
- methodName: string,
355
- ): Binding;
356
-
357
- /**
358
- * Register a new route.
359
- *
360
- * ```ts
361
- * function greet(name: string) {
362
- * return `hello ${name}`;
363
- * }
364
- * const route = new Route('get', '/', operationSpec, greet);
365
- * app.route(route);
366
- * ```
367
- *
368
- * @param route The route to add.
369
- */
370
- route(route: RouteEntry): Binding;
371
-
372
- route(
373
- routeOrVerb: RouteEntry | string,
374
- path?: string,
375
- spec?: OperationObject,
376
- controller?: ControllerClass,
377
- methodName?: string,
378
- ): Binding {
379
- if (typeof routeOrVerb === 'object') {
380
- const r = routeOrVerb;
381
- return this.bind(`routes.${r.verb} ${r.path}`).to(r);
382
- }
383
-
384
- if (!path) {
385
- throw new AssertionError({
386
- message: 'path is required for a controller-based route',
387
- });
388
- }
389
-
390
- if (!spec) {
391
- throw new AssertionError({
392
- message: 'spec is required for a controller-based route',
393
- });
394
- }
395
-
396
- if (!controller) {
397
- throw new AssertionError({
398
- message: 'controller is required for a controller-based route',
399
- });
400
- }
401
-
402
- if (!methodName) {
403
- throw new AssertionError({
404
- message: 'methodName is required for a controller-based route',
405
- });
406
- }
407
-
408
- return this.route(
409
- new ControllerRoute(routeOrVerb, path, spec, controller, methodName),
410
- );
411
- }
412
-
413
- /**
414
- * Set the OpenAPI specification that defines the REST API schema for this
415
- * server. All routes, parameter definitions and return types will be defined
416
- * in this way.
417
- *
418
- * Note that this will override any routes defined via decorators at the
419
- * controller level (this function takes precedent).
420
- *
421
- * @param {OpenApiSpec} spec The OpenAPI specification, as an object.
422
- * @returns {Binding}
423
- * @memberof RestServer
424
- */
425
- api(spec: OpenApiSpec): Binding {
426
- return this.bind(RestBindings.API_SPEC).to(spec);
427
- }
428
-
429
- /**
430
- * Get the OpenAPI specification describing the REST API provided by
431
- * this application.
432
- *
433
- * This method merges operations (HTTP endpoints) from the following sources:
434
- * - `app.api(spec)`
435
- * - `app.controller(MyController)`
436
- * - `app.route(route)`
437
- * - `app.route('get', '/greet', operationSpec, MyController, 'greet')`
438
- */
439
- getApiSpec(): OpenApiSpec {
440
- const spec = this.getSync(RestBindings.API_SPEC);
441
-
442
- // Apply deep clone to prevent getApiSpec() callers from
443
- // accidentally modifying our internal routing data
444
- spec.paths = cloneDeep(this.httpHandler.describeApiPaths());
445
-
446
- return spec;
447
- }
448
-
449
- /**
450
- * Configure a custom sequence class for handling incoming requests.
451
- *
452
- * ```ts
453
- * class MySequence implements SequenceHandler {
454
- * constructor(
455
- * @inject('send) public send: Send)) {
456
- * }
457
- *
458
- * public async handle(request: ParsedRequest, response: ServerResponse) {
459
- * send(response, 'hello world');
460
- * }
461
- * }
462
- * ```
463
- *
464
- * @param value The sequence to invoke for each incoming request.
465
- */
466
- public sequence(value: Constructor<SequenceHandler>) {
467
- this.bind(RestBindings.SEQUENCE).toClass(value);
468
- }
469
-
470
- /**
471
- * Configure a custom sequence function for handling incoming requests.
472
- *
473
- * ```ts
474
- * app.handler((sequence, request, response) => {
475
- * sequence.send(response, 'hello world');
476
- * });
477
- * ```
478
- *
479
- * @param handlerFn The handler to invoke for each incoming request.
480
- */
481
- public handler(handlerFn: SequenceFunction) {
482
- class SequenceFromFunction extends DefaultSequence {
483
- // NOTE(bajtos) Unfortunately, we have to duplicate the constructor
484
- // in order for our DI/IoC framework to inject constructor arguments
485
- constructor(
486
- @inject(RestBindings.Http.CONTEXT) public ctx: Context,
487
- @inject(SequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
488
- @inject(SequenceActions.PARSE_PARAMS)
489
- protected parseParams: ParseParams,
490
- @inject(SequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,
491
- @inject(SequenceActions.SEND) public send: Send,
492
- @inject(SequenceActions.REJECT) public reject: Reject,
493
- ) {
494
- super(ctx, findRoute, parseParams, invoke, send, reject);
495
- }
496
-
497
- async handle(
498
- request: ParsedRequest,
499
- response: ServerResponse,
500
- ): Promise<void> {
501
- await Promise.resolve(handlerFn(this, request, response));
502
- }
503
- }
504
-
505
- this.sequence(SequenceFromFunction);
506
- }
507
-
508
- /**
509
- * Start this REST API's HTTP/HTTPS server.
510
- *
511
- * @returns {Promise<void>}
512
- * @memberof RestServer
513
- */
514
- async start(): Promise<void> {
515
- // Setup the HTTP handler so that we can verify the configuration
516
- // of API spec, controllers and routes at startup time.
517
- this._setupHandlerIfNeeded();
518
-
519
- const httpPort = await this.get(RestBindings.PORT);
520
- this._httpServer = createServer(this.handleHttp);
521
- const httpServer = this._httpServer;
522
-
523
- // TODO(bajtos) support httpHostname too
524
- // See https://github.com/strongloop/loopback-next/issues/434
525
- httpServer.listen(httpPort);
526
-
527
- return new Promise<void>((resolve, reject) => {
528
- httpServer.once('listening', () => {
529
- this.bind(RestBindings.PORT).to(httpServer.address().port);
530
- resolve();
531
- });
532
- httpServer.once('error', reject);
533
- });
534
- }
535
-
536
- /**
537
- * Stop this REST API's HTTP/HTTPS server.
538
- *
539
- * @returns {Promise<void>}
540
- * @memberof RestServer
541
- */
542
- async stop() {
543
- // Kill the server instance.
544
- const server = this._httpServer;
545
- return new Promise<void>((resolve, reject) => {
546
- server.close((err: Error) => {
547
- if (err) {
548
- reject(err);
549
- } else {
550
- resolve();
551
- }
552
- });
553
- });
554
- }
555
-
556
- protected _onUnhandledError(
557
- req: ServerRequest,
558
- res: ServerResponse,
559
- err: Error,
560
- ) {
561
- if (!res.headersSent) {
562
- res.statusCode = 500;
563
- res.end();
564
- }
565
-
566
- // It's the responsibility of the Sequence to handle any errors.
567
- // If an unhandled error escaped, then something very wrong happened
568
- // and it's best to crash the process immediately.
569
- process.nextTick(() => {
570
- throw err;
571
- });
572
- }
573
- }
574
-
575
- /**
576
- * Valid configuration for the RestServer constructor.
577
- *
578
- * @export
579
- * @interface RestServerConfig
580
- */
581
- export interface RestServerConfig {
582
- port?: number;
583
- sequence?: Constructor<SequenceHandler>;
584
- }