@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
@@ -0,0 +1,98 @@
1
+ // Copyright IBM Corp. 2018,2019. 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 {ParameterObject, SchemaObject} from '@loopback/openapi-v3';
7
+ import {RestHttpErrors} from '../';
8
+
9
+ /**
10
+ * A set of options to pass into the validator functions
11
+ */
12
+ export type ValidationOptions = {
13
+ required?: boolean;
14
+ };
15
+
16
+ /**
17
+ * The context information that a validator needs
18
+ */
19
+ export type ValidationContext = {
20
+ parameterSpec: ParameterObject;
21
+ };
22
+
23
+ /**
24
+ * Validator class provides a bunch of functions that perform
25
+ * validations on the request parameters and request body.
26
+ */
27
+ export class Validator {
28
+ constructor(public ctx: ValidationContext) {}
29
+
30
+ /**
31
+ * The validation executed before type coercion. Like
32
+ * checking absence.
33
+ *
34
+ * @param type - A parameter's type.
35
+ * @param value - A parameter's raw value from http request.
36
+ * @param opts - options
37
+ */
38
+ validateParamBeforeCoercion(
39
+ value: string | object | undefined,
40
+ opts?: ValidationOptions,
41
+ ) {
42
+ if (this.isAbsent(value) && this.isRequired(opts)) {
43
+ const name = this.ctx.parameterSpec.name;
44
+ throw RestHttpErrors.missingRequired(name);
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Check is a parameter required or not.
50
+ *
51
+ * @param opts
52
+ */
53
+ isRequired(opts?: ValidationOptions) {
54
+ if (this.ctx.parameterSpec.required) return true;
55
+ if (opts?.required) return true;
56
+ return false;
57
+ }
58
+
59
+ /**
60
+ * Return `true` if the value is empty, return `false` otherwise.
61
+ *
62
+ * @param value
63
+ */
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ isAbsent(value: any) {
66
+ if (value === '' || value === undefined) return true;
67
+
68
+ const spec: ParameterObject = this.ctx.parameterSpec;
69
+ const schema: SchemaObject = this.ctx.parameterSpec.schema ?? {};
70
+ const valueIsNull = value === 'null' || value === null;
71
+
72
+ if (this.isUrlEncodedJsonParam()) {
73
+ // is this an url encoded Json object query parameter?
74
+ // check for NULL values
75
+ if (valueIsNull) return true;
76
+ } else if (spec.schema) {
77
+ // if parameter spec contains schema object, check if supplied value is NULL
78
+ if (schema.type === 'object' && valueIsNull) return true;
79
+ }
80
+
81
+ return false;
82
+ }
83
+
84
+ /**
85
+ * Return `true` if defined specification is for a url encoded Json object query parameter
86
+ *
87
+ * for url encoded Json object query parameters,
88
+ * schema is defined under content['application/json']
89
+ */
90
+ isUrlEncodedJsonParam() {
91
+ const spec: ParameterObject = this.ctx.parameterSpec;
92
+
93
+ if (spec.in === 'query' && spec.content?.['application/json']?.schema) {
94
+ return true;
95
+ }
96
+ return false;
97
+ }
98
+ }
@@ -1,74 +1,117 @@
1
- // Copyright IBM Corp. 2017. All Rights Reserved.
1
+ // Copyright IBM Corp. 2017,2019. All Rights Reserved.
2
2
  // Node module: @loopback/rest
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
6
  import {Context} from '@loopback/context';
7
- import {PathsObject} from '@loopback/openapi-spec';
8
- import {ServerRequest, ServerResponse} from 'http';
9
- import {ControllerSpec} from './router/metadata';
10
-
11
- import {SequenceHandler} from './sequence';
12
7
  import {
13
- RoutingTable,
14
- parseRequestUrl,
8
+ ComponentsObject,
9
+ ControllerSpec,
10
+ PathObject,
11
+ ReferenceObject,
12
+ SchemaObject,
13
+ SchemasObject,
14
+ } from '@loopback/openapi-v3';
15
+ import {RestBindings} from './keys';
16
+ import {RequestContext} from './request-context';
17
+ import {RestServerResolvedConfig} from './rest.server';
18
+ import {
19
+ ControllerClass,
20
+ ControllerFactory,
15
21
  ResolvedRoute,
16
22
  RouteEntry,
17
- ControllerClass,
18
- } from './router/routing-table';
19
- import {ParsedRequest} from './internal-types';
20
-
21
- import {RestBindings} from './keys';
23
+ RoutingTable,
24
+ } from './router';
25
+ import {SequenceHandler} from './sequence';
26
+ import {Request, Response} from './types';
22
27
 
23
28
  export class HttpHandler {
24
- protected _routes: RoutingTable = new RoutingTable();
29
+ /**
30
+ * Shared OpenAPI spec objects as `components`
31
+ */
32
+ protected _openApiComponents: ComponentsObject;
25
33
 
26
- public handleRequest: (
27
- request: ServerRequest,
28
- response: ServerResponse,
29
- ) => Promise<void>;
34
+ public handleRequest: (request: Request, response: Response) => Promise<void>;
30
35
 
31
- constructor(protected _rootContext: Context) {
36
+ constructor(
37
+ protected readonly _rootContext: Context,
38
+ protected readonly _serverConfig: RestServerResolvedConfig,
39
+ protected readonly _routes = new RoutingTable(),
40
+ ) {
32
41
  this.handleRequest = (req, res) => this._handleRequest(req, res);
33
42
  }
34
43
 
35
- registerController(name: ControllerClass, spec: ControllerSpec) {
36
- this._routes.registerController(name, spec);
44
+ registerController<T>(
45
+ spec: ControllerSpec,
46
+ controllerCtor: ControllerClass<T>,
47
+ controllerFactory?: ControllerFactory<T>,
48
+ ) {
49
+ this._routes.registerController(spec, controllerCtor, controllerFactory);
37
50
  }
38
51
 
39
52
  registerRoute(route: RouteEntry) {
40
53
  this._routes.registerRoute(route);
41
54
  }
42
55
 
43
- describeApiPaths(): PathsObject {
56
+ /**
57
+ * @deprecated Use `registerApiComponents`
58
+ * @param defs Schemas
59
+ */
60
+ registerApiDefinitions(defs: SchemasObject) {
61
+ this.registerApiComponents({schemas: defs});
62
+ }
63
+
64
+ /**
65
+ * Merge components into the OpenApi spec
66
+ * @param defs - Components
67
+ */
68
+ registerApiComponents(defs: ComponentsObject) {
69
+ this._openApiComponents = this._openApiComponents ?? {};
70
+ for (const p in defs) {
71
+ // Merge each child, such as `schemas`, `parameters`, and `headers`
72
+ this._openApiComponents[p] = {...this._openApiComponents[p], ...defs[p]};
73
+ }
74
+ }
75
+
76
+ getApiComponents() {
77
+ return this._openApiComponents;
78
+ }
79
+
80
+ /**
81
+ * @deprecated Use `getApiComponents`
82
+ */
83
+ getApiDefinitions():
84
+ | {
85
+ [schema: string]: SchemaObject | ReferenceObject;
86
+ }
87
+ | undefined {
88
+ return this._openApiComponents?.schemas;
89
+ }
90
+
91
+ describeApiPaths(): PathObject {
44
92
  return this._routes.describeApiPaths();
45
93
  }
46
94
 
47
- findRoute(request: ParsedRequest): ResolvedRoute {
48
- return this._routes.find(request);
95
+ findRoute(request: Request): ResolvedRoute {
96
+ const route = this._routes.find(request);
97
+ Object.assign(route.schemas, this.getApiDefinitions());
98
+ return route;
49
99
  }
50
100
 
51
101
  protected async _handleRequest(
52
- request: ServerRequest,
53
- response: ServerResponse,
102
+ request: Request,
103
+ response: Response,
54
104
  ): Promise<void> {
55
- const parsedRequest: ParsedRequest = parseRequestUrl(request);
56
- const requestContext = this._createRequestContext(request, response);
105
+ const requestContext = new RequestContext(
106
+ request,
107
+ response,
108
+ this._rootContext,
109
+ this._serverConfig,
110
+ );
57
111
 
58
- const sequence: SequenceHandler = await requestContext.get(
112
+ const sequence = await requestContext.get<SequenceHandler>(
59
113
  RestBindings.SEQUENCE,
60
114
  );
61
- await sequence.handle(parsedRequest, response);
62
- }
63
-
64
- protected _createRequestContext(
65
- req: ServerRequest,
66
- res: ServerResponse,
67
- ): Context {
68
- const requestContext = new Context(this._rootContext);
69
- requestContext.bind(RestBindings.Http.REQUEST).to(req);
70
- requestContext.bind(RestBindings.Http.RESPONSE).to(res);
71
- requestContext.bind(RestBindings.Http.CONTEXT).to(requestContext);
72
- return requestContext;
115
+ await sequence.handle(requestContext);
73
116
  }
74
117
  }
package/src/index.ts CHANGED
@@ -1,37 +1,44 @@
1
- // Copyright IBM Corp. 2017. All Rights Reserved.
1
+ // Copyright IBM Corp. 2017,2020. All Rights Reserved.
2
2
  // Node module: @loopback/rest
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
- // external dependencies
7
- export {ServerRequest, ServerResponse} from 'http';
8
-
9
- export {
10
- RouteEntry,
11
- RoutingTable,
12
- Route,
13
- ControllerRoute,
14
- ResolvedRoute,
15
- createResolvedRoute,
16
- parseRequestUrl,
17
- } from './router/routing-table';
18
-
19
- export * from './router/metadata';
20
- export * from './providers';
21
-
22
- // import all errors from external http-errors package
23
- import * as HttpErrors from 'http-errors';
24
-
25
- export * from './parser';
26
-
27
- export {writeResultToResponse} from './writer';
28
-
29
- // http errors
30
- export {HttpErrors};
31
-
6
+ /**
7
+ * The REST API package for loopback-next.
8
+ *
9
+ * @remarks
10
+ * A REST server for LoopBack 4 application instances, complete with:
11
+ *
12
+ * - new custom routing engine (special thanks to @bajtos)!
13
+ * - tools for defining your application routes
14
+ * - OpenAPI 3.0 spec (openapi.json/openapi.yaml) generation using
15
+ * @loopback/openapi-v3
16
+ * - a default sequence implementation to manage the request and response
17
+ * lifecycle
18
+ *
19
+ *
20
+ * @packageDocumentation
21
+ */
22
+
23
+ export * from '@loopback/openapi-v3';
24
+ export * from './body-parsers';
32
25
  export * from './http-handler';
33
- export * from './internal-types';
34
26
  export * from './keys';
35
- export * from './rest-component';
36
- export * from './rest-server';
27
+ export * from './parse-json';
28
+ export * from './parser';
29
+ export * from './providers';
30
+ export * from './request-context';
31
+ export * from './rest-http-error';
32
+ export * from './rest.application';
33
+ export * from './rest.component';
34
+ export * from './rest.server';
35
+ export * from './router';
37
36
  export * from './sequence';
37
+ export * from './spec-enhancers/info.spec-enhancer';
38
+ export * from './types';
39
+ export * from './validation/request-body.validator';
40
+ export * from './writer';
41
+ export {HttpErrors};
42
+
43
+ // export all errors from external http-errors package
44
+ import HttpErrors from 'http-errors';
package/src/keys.ts CHANGED
@@ -1,36 +1,289 @@
1
- // Copyright IBM Corp. 2017. All Rights Reserved.
1
+ // Copyright IBM Corp. 2017,2020. All Rights Reserved.
2
2
  // Node module: @loopback/rest
3
3
  // This file is licensed under the MIT License.
4
4
  // License text available at https://opensource.org/licenses/MIT
5
5
 
6
+ import {BindingKey, Context} from '@loopback/context';
6
7
  import {CoreBindings} from '@loopback/core';
8
+ import {InvokeMiddleware} from '@loopback/express';
9
+ import {HttpProtocol} from '@loopback/http-server';
10
+ import {OpenApiSpec, OperationObject} from '@loopback/openapi-v3';
11
+ import https from 'https';
12
+ import {ErrorWriterOptions} from 'strong-error-handler';
13
+ import {BodyParser, RequestBodyParser} from './body-parsers';
14
+ import {HttpHandler} from './http-handler';
15
+ import {RestServer, RestServerConfig} from './rest.server';
16
+ import {RestRouter, RestRouterOptions} from './router';
17
+ import {SequenceHandler} from './sequence';
18
+ import {
19
+ AjvFactory,
20
+ FindRoute,
21
+ InvokeMethod,
22
+ LogError,
23
+ ParseParams,
24
+ Reject,
25
+ Request,
26
+ RequestBodyParserOptions,
27
+ Response,
28
+ Send,
29
+ } from './types';
7
30
 
31
+ /**
32
+ * RestServer-specific bindings
33
+ */
8
34
  export namespace RestBindings {
9
- // RestServer-specific bindings
10
- export const CONFIG = `${CoreBindings.APPLICATION_CONFIG}#rest`;
11
- export const PORT = 'rest.port';
12
- export const HANDLER = 'rest.handler';
35
+ /**
36
+ * Binding key for setting and injecting RestComponentConfig
37
+ */
38
+ export const CONFIG: BindingKey<RestServerConfig> = CoreBindings.APPLICATION_CONFIG.deepProperty(
39
+ 'rest',
40
+ );
41
+ /**
42
+ * Binding key for setting and injecting the host name of RestServer
43
+ */
44
+ export const HOST = BindingKey.create<string | undefined>('rest.host');
45
+ /**
46
+ * Binding key for setting and injecting the port number of RestServer
47
+ */
48
+ export const PORT = BindingKey.create<number>('rest.port');
49
+ /**
50
+ * Binding key for setting and injecting the socket path of the RestServer
51
+ */
52
+ export const PATH = BindingKey.create<string | undefined>('rest.path');
53
+ /**
54
+ * Binding key for setting and injecting the URL of RestServer
55
+ */
56
+ export const URL = BindingKey.create<string>('rest.url');
57
+ /**
58
+ * Binding key for setting and injecting the protocol of RestServer
59
+ */
60
+ export const PROTOCOL = BindingKey.create<HttpProtocol>('rest.protocol');
61
+ /**
62
+ * Binding key for HTTPS options
63
+ */
64
+ export const HTTPS_OPTIONS = BindingKey.create<https.ServerOptions>(
65
+ 'rest.httpsOptions',
66
+ );
13
67
 
14
- export const API_SPEC = 'rest.apiSpec';
15
- export const SEQUENCE = 'rest.sequence';
68
+ /**
69
+ * Binding key for the server itself
70
+ */
71
+ export const SERVER = BindingKey.create<RestServer>('servers.RestServer');
16
72
 
17
- export namespace SequenceActions {
18
- export const FIND_ROUTE = 'rest.sequence.actions.findRoute';
19
- export const PARSE_PARAMS = 'rest.sequence.actions.parseParams';
20
- export const INVOKE_METHOD = 'rest.sequence.actions.invokeMethod';
21
- export const LOG_ERROR = 'rest.sequence.actions.logError';
22
- export const SEND = 'rest.sequence.actions.send';
23
- export const REJECT = 'rest.sequence.actions.reject';
73
+ /**
74
+ * Internal binding key for basePath
75
+ */
76
+ export const BASE_PATH = BindingKey.create<string>('rest.basePath');
77
+
78
+ /**
79
+ * Internal binding key for http-handler
80
+ */
81
+ export const HANDLER = BindingKey.create<HttpHandler>('rest.handler');
82
+
83
+ /**
84
+ * Internal binding key for rest router
85
+ */
86
+ export const ROUTER = BindingKey.create<RestRouter>('rest.router');
87
+
88
+ export const ROUTER_OPTIONS = BindingKey.create<RestRouterOptions>(
89
+ 'rest.router.options',
90
+ );
91
+
92
+ /**
93
+ * Binding key for setting and injecting Reject action's error handling
94
+ * options.
95
+ *
96
+ * See https://github.com/strongloop/strong-error-handler#options for
97
+ * the list of available options. Please note that the flag `log` is not used
98
+ * by `@loopback/rest`.
99
+ */
100
+ export const ERROR_WRITER_OPTIONS = BindingKey.create<ErrorWriterOptions>(
101
+ 'rest.errorWriterOptions',
102
+ );
103
+
104
+ /**
105
+ * Binding key for request body parser options
106
+ */
107
+ export const REQUEST_BODY_PARSER_OPTIONS = BindingKey.create<
108
+ RequestBodyParserOptions
109
+ >('rest.requestBodyParserOptions');
110
+
111
+ /**
112
+ * Binding key for request body parser
113
+ */
114
+ export const REQUEST_BODY_PARSER = BindingKey.create<RequestBodyParser>(
115
+ 'rest.requestBodyParser',
116
+ );
117
+
118
+ function bodyParserBindingKey(parser: string) {
119
+ return `${REQUEST_BODY_PARSER}.${parser}`;
24
120
  }
25
121
 
26
- export const GET_FROM_CONTEXT = 'getFromContext';
27
- export const BIND_ELEMENT = 'bindElement';
122
+ /**
123
+ * Binding key for request json body parser
124
+ */
125
+ export const REQUEST_BODY_PARSER_JSON = BindingKey.create<BodyParser>(
126
+ bodyParserBindingKey('JsonBodyParser'),
127
+ );
128
+
129
+ /**
130
+ * Binding key for request urlencoded body parser
131
+ */
132
+ export const REQUEST_BODY_PARSER_URLENCODED = BindingKey.create<BodyParser>(
133
+ bodyParserBindingKey('UrlEncodedBodyParser'),
134
+ );
135
+
136
+ /**
137
+ * Binding key for request text body parser
138
+ */
139
+ export const REQUEST_BODY_PARSER_TEXT = BindingKey.create<BodyParser>(
140
+ bodyParserBindingKey('TextBodyParser'),
141
+ );
142
+
143
+ /**
144
+ * Binding key for request raw body parser
145
+ */
146
+ export const REQUEST_BODY_PARSER_RAW = BindingKey.create<BodyParser>(
147
+ bodyParserBindingKey('RawBodyParser'),
148
+ );
149
+
150
+ /**
151
+ * Binding key for request raw body parser
152
+ */
153
+ export const REQUEST_BODY_PARSER_STREAM = BindingKey.create<BodyParser>(
154
+ bodyParserBindingKey('StreamBodyParser'),
155
+ );
156
+
157
+ /**
158
+ * Binding key for AJV
159
+ */
160
+ export const AJV_FACTORY = BindingKey.create<AjvFactory>(
161
+ bodyParserBindingKey('rest.ajvFactory'),
162
+ );
28
163
 
29
- // request-specific bindings
164
+ /**
165
+ * Binding key for setting and injecting an OpenAPI spec
166
+ */
167
+ export const API_SPEC: BindingKey<OpenApiSpec> = BindingKey.create<
168
+ OpenApiSpec
169
+ >('rest.apiSpec');
30
170
 
171
+ /**
172
+ * Binding key for setting and injecting an OpenAPI operation spec
173
+ */
174
+ export const OPERATION_SPEC_CURRENT = BindingKey.create<OperationObject>(
175
+ 'rest.operationSpec.current',
176
+ );
177
+
178
+ /**
179
+ * Binding key for setting and injecting a Sequence
180
+ */
181
+ export const SEQUENCE = BindingKey.create<SequenceHandler>('rest.sequence');
182
+
183
+ /**
184
+ * Bindings for potential actions that could be used in a sequence
185
+ */
186
+ export namespace SequenceActions {
187
+ /**
188
+ * Binding key for setting and injecting a route finding function
189
+ */
190
+ export const INVOKE_MIDDLEWARE = BindingKey.create<InvokeMiddleware>(
191
+ 'rest.sequence.actions.invokeMiddleware',
192
+ );
193
+ /**
194
+ * Binding key for setting and injecting a route finding function
195
+ */
196
+ export const FIND_ROUTE = BindingKey.create<FindRoute>(
197
+ 'rest.sequence.actions.findRoute',
198
+ );
199
+ /**
200
+ * Binding key for setting and injecting a parameter parsing function
201
+ */
202
+ export const PARSE_PARAMS = BindingKey.create<ParseParams>(
203
+ 'rest.sequence.actions.parseParams',
204
+ );
205
+ /**
206
+ * Binding key for setting and injecting a controller route invoking function
207
+ */
208
+ export const INVOKE_METHOD = BindingKey.create<InvokeMethod>(
209
+ 'rest.sequence.actions.invokeMethod',
210
+ );
211
+ /**
212
+ * Binding key for setting and injecting an error logging function
213
+ */
214
+ export const LOG_ERROR = BindingKey.create<LogError>(
215
+ 'rest.sequence.actions.logError',
216
+ );
217
+ /**
218
+ * Binding key for setting and injecting a response writing function
219
+ */
220
+ export const SEND = BindingKey.create<Send>('rest.sequence.actions.send');
221
+ /**
222
+ * Binding key for setting and injecting a bad response writing function
223
+ */
224
+ export const REJECT = BindingKey.create<Reject>(
225
+ 'rest.sequence.actions.reject',
226
+ );
227
+ }
228
+
229
+ /**
230
+ * Request-specific bindings
231
+ */
31
232
  export namespace Http {
32
- export const REQUEST = 'rest.http.request';
33
- export const RESPONSE = 'rest.http.response';
34
- export const CONTEXT = 'rest.http.request.context';
233
+ /**
234
+ * Binding key for setting and injecting the http request
235
+ */
236
+ export const REQUEST: BindingKey<Request> = BindingKey.create<Request>(
237
+ 'rest.http.request',
238
+ );
239
+ /**
240
+ * Binding key for setting and injecting the http response
241
+ */
242
+ export const RESPONSE = BindingKey.create<Response>('rest.http.response');
243
+ /**
244
+ * Binding key for setting and injecting the http request context
245
+ */
246
+ export const CONTEXT = BindingKey.create<Context>(
247
+ 'rest.http.request.context',
248
+ );
35
249
  }
250
+
251
+ /**
252
+ * Namespace for REST routes
253
+ */
254
+ export const ROUTES = 'routes';
255
+ }
256
+
257
+ /**
258
+ * Binding tags for RestServer
259
+ */
260
+ export namespace RestTags {
261
+ /**
262
+ * Binding tag to identify REST routes
263
+ */
264
+ export const REST_ROUTE = 'restRoute';
265
+
266
+ /**
267
+ * Binding tag for the REST route verb
268
+ */
269
+ export const ROUTE_VERB = 'restRouteVerb';
270
+
271
+ /**
272
+ * Binding tag for the REST route path
273
+ */
274
+ export const ROUTE_PATH = 'restRoutePath';
275
+
276
+ /**
277
+ * Binding tag to identify controller based REST routes
278
+ */
279
+ export const CONTROLLER_ROUTE = 'controllerRoute';
280
+
281
+ /**
282
+ * Binding tag for controller route bindings to represent the controller
283
+ * binding key
284
+ */
285
+ export const CONTROLLER_BINDING = 'controllerBinding';
286
+
287
+ export const AJV_KEYWORD = 'ajvKeyword';
288
+ export const AJV_FORMAT = 'ajvFormat';
36
289
  }
@@ -0,0 +1,42 @@
1
+ // Copyright IBM Corp. 2019. 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
+ /* eslint-disable @typescript-eslint/no-explicit-any */
7
+
8
+ // These utilities are introduced to mitigate the prototype pollution issue
9
+ // with `JSON.parse`.
10
+ // See https://hueniverse.com/a-tale-of-prototype-poisoning-2610fa170061
11
+ //
12
+ // The [bourne](https://github.com/hapijs/bourne) module provides a drop-in
13
+ // replacement for `JSON.parse` but we need to instruct `body-parser` to honor
14
+ // a `reviver` function.
15
+
16
+ /**
17
+ * Factory to create a reviver function for `JSON.parse` to sanitize keys
18
+ * @param reviver - Reviver function
19
+ */
20
+ export function sanitizeJsonParse(reviver?: (key: any, value: any) => any) {
21
+ return (key: string, value: any) => {
22
+ if (key === '__proto__')
23
+ throw new Error('JSON string cannot contain "__proto__" key.');
24
+ if (reviver) {
25
+ return reviver(key, value);
26
+ } else {
27
+ return value;
28
+ }
29
+ };
30
+ }
31
+
32
+ /**
33
+ *
34
+ * @param text - JSON string
35
+ * @param reviver - Optional reviver function for `JSON.parse`
36
+ */
37
+ export function parseJson(
38
+ text: string,
39
+ reviver?: (key: any, value: any) => any,
40
+ ) {
41
+ return JSON.parse(text, sanitizeJsonParse(reviver));
42
+ }