@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,161 @@
1
+ "use strict";
2
+ // Copyright IBM Corp. 2018,2020. All Rights Reserved.
3
+ // Node module: @loopback/rest
4
+ // This file is licensed under the MIT License.
5
+ // License text available at https://opensource.org/licenses/MIT
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.validateRequestBody = void 0;
8
+ const tslib_1 = require("tslib");
9
+ const openapi_v3_1 = require("@loopback/openapi-v3");
10
+ const debug_1 = tslib_1.__importDefault(require("debug"));
11
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
12
+ const util_1 = tslib_1.__importDefault(require("util"));
13
+ const __1 = require("..");
14
+ const ajv_factory_provider_1 = require("./ajv-factory.provider");
15
+ const toJsonSchema = require('@openapi-contrib/openapi-schema-to-json-schema');
16
+ const debug = debug_1.default('loopback:rest:validation');
17
+ /**
18
+ * Check whether the request body is valid according to the provided OpenAPI schema.
19
+ * The JSON schema is generated from the OpenAPI schema which is typically defined
20
+ * by `@requestBody()`.
21
+ * The validation leverages AJV schema validator.
22
+ * @param body - The request body parsed from an HTTP request.
23
+ * @param requestBodySpec - The OpenAPI requestBody specification defined in `@requestBody()`.
24
+ * @param globalSchemas - The referenced schemas generated from `OpenAPISpec.components.schemas`.
25
+ * @param options - Request body validation options for AJV
26
+ */
27
+ async function validateRequestBody(body, requestBodySpec, globalSchemas = {}, options = {}) {
28
+ const required = requestBodySpec === null || requestBodySpec === void 0 ? void 0 : requestBodySpec.required;
29
+ if (required && body.value == null) {
30
+ const err = Object.assign(new __1.HttpErrors.BadRequest('Request body is required'), {
31
+ code: 'MISSING_REQUIRED_PARAMETER',
32
+ parameterName: 'request body',
33
+ });
34
+ throw err;
35
+ }
36
+ const schema = body.schema;
37
+ /* istanbul ignore if */
38
+ if (debug.enabled) {
39
+ debug('Request body schema:', util_1.default.inspect(schema, { depth: null }));
40
+ if (schema &&
41
+ openapi_v3_1.isReferenceObject(schema) &&
42
+ schema.$ref.startsWith('#/components/schemas/')) {
43
+ const ref = schema.$ref.slice('#/components/schemas/'.length);
44
+ debug(' referencing:', util_1.default.inspect(globalSchemas[ref], { depth: null }));
45
+ }
46
+ }
47
+ if (!schema)
48
+ return;
49
+ options = { coerceTypes: !!body.coercionRequired, ...options };
50
+ await validateValueAgainstSchema(body.value, schema, globalSchemas, options);
51
+ }
52
+ exports.validateRequestBody = validateRequestBody;
53
+ /**
54
+ * Convert an OpenAPI schema to the corresponding JSON schema.
55
+ * @param openapiSchema - The OpenAPI schema to convert.
56
+ */
57
+ function convertToJsonSchema(openapiSchema) {
58
+ const jsonSchema = toJsonSchema(openapiSchema);
59
+ delete jsonSchema['$schema'];
60
+ /* istanbul ignore if */
61
+ if (debug.enabled) {
62
+ debug('Converted OpenAPI schema to JSON schema: %s', util_1.default.inspect(jsonSchema, { depth: null }));
63
+ }
64
+ return jsonSchema;
65
+ }
66
+ /**
67
+ * Built-in cache for complied schemas by AJV
68
+ */
69
+ const DEFAULT_COMPILED_SCHEMA_CACHE = new WeakMap();
70
+ /**
71
+ * Build a cache key for AJV options
72
+ * @param options - Request body validation options
73
+ */
74
+ function getKeyForOptions(options) {
75
+ const ajvOptions = {};
76
+ // Sort keys for options
77
+ const keys = Object.keys(options).sort();
78
+ for (const k of keys) {
79
+ if (k === 'compiledSchemaCache')
80
+ continue;
81
+ ajvOptions[k] = options[k];
82
+ }
83
+ return JSON.stringify(ajvOptions);
84
+ }
85
+ /**
86
+ * Validate the request body data against JSON schema.
87
+ * @param body - The request body data.
88
+ * @param schema - The JSON schema used to perform the validation.
89
+ * @param globalSchemas - Schema references.
90
+ * @param options - Request body validation options.
91
+ */
92
+ async function validateValueAgainstSchema(
93
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
+ body, schema, globalSchemas = {}, options = {}) {
95
+ var _a, _b;
96
+ let validate;
97
+ const cache = (_a = options.compiledSchemaCache) !== null && _a !== void 0 ? _a : DEFAULT_COMPILED_SCHEMA_CACHE;
98
+ const key = getKeyForOptions(options);
99
+ let validatorMap;
100
+ if (cache.has(schema)) {
101
+ validatorMap = cache.get(schema);
102
+ validate = validatorMap.get(key);
103
+ }
104
+ if (!validate) {
105
+ const ajvFactory = (_b = options.ajvFactory) !== null && _b !== void 0 ? _b : new ajv_factory_provider_1.AjvFactoryProvider(options).value();
106
+ const ajvInst = ajvFactory(options);
107
+ validate = createValidator(schema, globalSchemas, ajvInst);
108
+ validatorMap = validatorMap !== null && validatorMap !== void 0 ? validatorMap : new Map();
109
+ validatorMap.set(key, validate);
110
+ cache.set(schema, validatorMap);
111
+ }
112
+ let validationErrors = [];
113
+ try {
114
+ const validationResult = await validate(body);
115
+ // When body is optional & values is empty / null, ajv returns null
116
+ if (validationResult || validationResult === null) {
117
+ debug('Request body passed AJV validation.');
118
+ return;
119
+ }
120
+ }
121
+ catch (error) {
122
+ validationErrors = error.errors;
123
+ }
124
+ /* istanbul ignore if */
125
+ if (debug.enabled) {
126
+ debug('Invalid request body: %s. Errors: %s', util_1.default.inspect(body, { depth: null }), util_1.default.inspect(validationErrors));
127
+ }
128
+ if (typeof options.ajvErrorTransformer === 'function') {
129
+ validationErrors = options.ajvErrorTransformer(validationErrors);
130
+ }
131
+ const error = __1.RestHttpErrors.invalidRequestBody();
132
+ error.details = lodash_1.default.map(validationErrors, e => {
133
+ return {
134
+ path: e.dataPath,
135
+ code: e.keyword,
136
+ message: e.message,
137
+ info: e.params,
138
+ };
139
+ });
140
+ throw error;
141
+ }
142
+ /**
143
+ * Create a validate function for the given schema
144
+ * @param schema - JSON schema for the target
145
+ * @param globalSchemas - Global schemas
146
+ * @param ajvInst - An instance of Ajv
147
+ */
148
+ function createValidator(schema, globalSchemas = {}, ajvInst) {
149
+ const jsonSchema = convertToJsonSchema(schema);
150
+ // Clone global schemas to set `$async: true` flag
151
+ const schemas = {};
152
+ for (const name in globalSchemas) {
153
+ // See https://github.com/strongloop/loopback-next/issues/4939
154
+ schemas[name] = { ...globalSchemas[name], $async: true };
155
+ }
156
+ const schemaWithRef = { components: { schemas }, ...jsonSchema };
157
+ // See https://ajv.js.org/#asynchronous-validation for async validation
158
+ schemaWithRef.$async = true;
159
+ return ajvInst.compile(schemaWithRef);
160
+ }
161
+ //# sourceMappingURL=request-body.validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-body.validator.js","sourceRoot":"","sources":["../../src/validation/request-body.validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { OperationRetval, Response } from './types';
2
+ /**
3
+ * Writes the result from Application controller method
4
+ * into the HTTP response
5
+ *
6
+ * @param response - HTTP Response
7
+ * @param result - Result from the API to write into HTTP Response
8
+ */
9
+ export declare function writeResultToResponse(response: Response, result: OperationRetval): void;
package/dist/writer.js ADDED
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ // Copyright IBM Corp. 2017,2020. All Rights Reserved.
3
+ // Node module: @loopback/rest
4
+ // This file is licensed under the MIT License.
5
+ // License text available at https://opensource.org/licenses/MIT
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.writeResultToResponse = void 0;
8
+ const stream_1 = require("stream");
9
+ /**
10
+ * Writes the result from Application controller method
11
+ * into the HTTP response
12
+ *
13
+ * @param response - HTTP Response
14
+ * @param result - Result from the API to write into HTTP Response
15
+ */
16
+ function writeResultToResponse(
17
+ // not needed and responsibility should be in the sequence.send
18
+ response,
19
+ // result returned back from invoking controller method
20
+ result) {
21
+ // Bypass response writing if the controller method returns `response` itself
22
+ // or the response headers have been sent
23
+ if (result === response || response.headersSent) {
24
+ return;
25
+ }
26
+ if (result === undefined) {
27
+ response.statusCode = 204;
28
+ response.end();
29
+ return;
30
+ }
31
+ const isStream = result instanceof stream_1.Readable || typeof (result === null || result === void 0 ? void 0 : result.pipe) === 'function';
32
+ if (isStream) {
33
+ response.setHeader('Content-Type', 'application/octet-stream');
34
+ // Stream
35
+ result.pipe(response);
36
+ return;
37
+ }
38
+ switch (typeof result) {
39
+ case 'object':
40
+ case 'boolean':
41
+ case 'number':
42
+ if (Buffer.isBuffer(result)) {
43
+ // Buffer for binary data
44
+ response.setHeader('Content-Type', 'application/octet-stream');
45
+ }
46
+ else {
47
+ // TODO(ritch) remove this, should be configurable
48
+ // See https://github.com/strongloop/loopback-next/issues/436
49
+ response.setHeader('Content-Type', 'application/json');
50
+ // TODO(bajtos) handle errors - JSON.stringify can throw
51
+ result = JSON.stringify(result);
52
+ }
53
+ break;
54
+ default:
55
+ response.setHeader('Content-Type', 'text/plain');
56
+ result = result.toString();
57
+ break;
58
+ }
59
+ response.end(result);
60
+ }
61
+ exports.writeResultToResponse = writeResultToResponse;
62
+ //# sourceMappingURL=writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writer.js","sourceRoot":"","sources":["../src/writer.ts"],"names":[],"mappings":";AAAA,sDAAsD;AACtD,8BAA8B;AAC9B,+CAA+C;AAC/C,gEAAgE;;;AAGhE,mCAAgC;AAEhC;;;;;;GAMG;AACH,SAAgB,qBAAqB;AACnC,+DAA+D;AAC/D,QAAkB;AAClB,uDAAuD;AACvD,MAAuB;IAEvB,6EAA6E;IAC7E,yCAAyC;IACzC,IAAI,MAAM,KAAK,QAAQ,IAAI,QAAQ,CAAC,WAAW,EAAE;QAC/C,OAAO;KACR;IACD,IAAI,MAAM,KAAK,SAAS,EAAE;QACxB,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC;QAC1B,QAAQ,CAAC,GAAG,EAAE,CAAC;QACf,OAAO;KACR;IAED,MAAM,QAAQ,GACZ,MAAM,YAAY,iBAAQ,IAAI,QAAO,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAA,KAAK,UAAU,CAAC;IAEnE,IAAI,QAAQ,EAAE;QACZ,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;QAC/D,SAAS;QACT,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtB,OAAO;KACR;IACD,QAAQ,OAAO,MAAM,EAAE;QACrB,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS,CAAC;QACf,KAAK,QAAQ;YACX,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;gBAC3B,yBAAyB;gBACzB,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;aAChE;iBAAM;gBACL,kDAAkD;gBAClD,6DAA6D;gBAC7D,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;gBACvD,wDAAwD;gBACxD,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;aACjC;YACD,MAAM;QACR;YACE,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;YACjD,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC3B,MAAM;KACT;IACD,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACvB,CAAC;AA/CD,sDA+CC"}
package/package.json CHANGED
@@ -1,57 +1,85 @@
1
1
  {
2
2
  "name": "@loopback/rest",
3
- "version": "4.0.0-alpha.8",
3
+ "version": "5.0.1",
4
4
  "description": "",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
5
7
  "engines": {
6
- "node": ">=6"
8
+ "node": ">=10"
7
9
  },
8
10
  "scripts": {
9
- "acceptance": "lb-dist mocha --opts ../../test/mocha.opts 'DIST/test/acceptance/**/*.js'",
10
- "build": "npm run build:dist && npm run build:dist6",
11
- "build:current": "lb-tsc",
12
- "build:dist": "lb-tsc es2017",
13
- "build:dist6": "lb-tsc es2015",
14
- "build:apidocs": "lb-apidocs",
15
- "clean": "rm -rf loopback-rest*.tgz dist* package",
16
- "prepare": "npm run build && npm run build:apidocs",
17
- "pretest": "npm run build:current",
18
- "integration": "lb-dist mocha --opts ../../test/mocha.opts 'DIST/test/integration/**/*.js'",
19
- "test": "lb-dist mocha --opts ../../test/mocha.opts 'DIST/test/unit/**/*.js' 'DIST/test/integration/**/*.js' 'DIST/test/acceptance/**/*.js'",
20
- "unit": "lb-dist mocha --opts ../../test/mocha.opts 'DIST/test/unit/**/*.js'",
11
+ "acceptance": "lb-mocha \"dist/__tests__/acceptance/**/*.js\"",
12
+ "build": "lb-tsc",
13
+ "clean": "lb-clean loopback-rest*.tgz dist *.tsbuildinfo package",
14
+ "pretest": "npm run build",
15
+ "integration": "lb-mocha \"dist/__tests__/integration/**/*.js\"",
16
+ "test": "lb-mocha \"dist/__tests__/**/*.js\"",
17
+ "unit": "lb-mocha \"dist/__tests__/unit/**/*.js\"",
21
18
  "verify": "npm pack && tar xf loopback-rest*.tgz && tree package && npm run clean"
22
19
  },
23
- "author": "IBM",
20
+ "author": "IBM Corp.",
21
+ "copyright.owner": "IBM Corp.",
24
22
  "license": "MIT",
25
23
  "dependencies": {
26
- "@loopback/context": "^4.0.0-alpha.19",
27
- "@loopback/core": "^4.0.0-alpha.21",
28
- "@loopback/openapi-spec": "^4.0.0-alpha.15",
29
- "@types/http-errors": "^1.5.34",
30
- "@types/js-yaml": "^3.9.1",
31
- "body": "^5.1.0",
32
- "debug": "^3.1.0",
33
- "http-errors": "^1.6.1",
34
- "js-yaml": "^3.9.1",
35
- "lodash": "^4.17.4",
36
- "path-to-regexp": "^2.0.0",
37
- "swagger2openapi": "^2.10.7"
24
+ "@loopback/context": "^3.8.1",
25
+ "@loopback/core": "^2.7.0",
26
+ "@loopback/express": "^1.2.1",
27
+ "@loopback/http-server": "^2.1.5",
28
+ "@loopback/openapi-v3": "^3.4.1",
29
+ "@openapi-contrib/openapi-schema-to-json-schema": "^3.0.0",
30
+ "@types/body-parser": "^1.19.0",
31
+ "@types/cors": "^2.8.6",
32
+ "@types/express": "^4.17.6",
33
+ "@types/express-serve-static-core": "^4.17.6",
34
+ "@types/http-errors": "^1.6.3",
35
+ "@types/on-finished": "^2.3.1",
36
+ "@types/serve-static": "1.13.4",
37
+ "@types/type-is": "^1.6.3",
38
+ "ajv": "^6.12.2",
39
+ "ajv-errors": "^1.0.1",
40
+ "ajv-keywords": "^3.4.1",
41
+ "body-parser": "^1.19.0",
42
+ "cors": "^2.8.5",
43
+ "debug": "^4.1.1",
44
+ "express": "^4.17.1",
45
+ "http-errors": "^1.7.3",
46
+ "js-yaml": "^3.13.1",
47
+ "json-schema-compare": "^0.2.2",
48
+ "lodash": "^4.17.15",
49
+ "on-finished": "^2.3.0",
50
+ "path-to-regexp": "^6.1.0",
51
+ "qs": "^6.9.4",
52
+ "strong-error-handler": "^3.4.0",
53
+ "tslib": "^2.0.0",
54
+ "type-is": "^1.6.18",
55
+ "validator": "^13.0.0"
38
56
  },
39
57
  "devDependencies": {
40
- "@loopback/build": "^4.0.0-alpha.5",
41
- "@loopback/openapi-spec-builder": "^4.0.0-alpha.12",
42
- "@loopback/testlab": "^4.0.0-alpha.14"
58
+ "@loopback/build": "^5.4.1",
59
+ "@loopback/eslint-config": "^7.0.1",
60
+ "@loopback/openapi-spec-builder": "^2.1.5",
61
+ "@loopback/repository": "^2.5.1",
62
+ "@loopback/testlab": "^3.1.5",
63
+ "@types/debug": "^4.1.5",
64
+ "@types/js-yaml": "^3.12.4",
65
+ "@types/json-schema-compare": "^0.2.0",
66
+ "@types/lodash": "^4.14.152",
67
+ "@types/multer": "^1.4.3",
68
+ "@types/node": "^10.17.24",
69
+ "@types/on-finished": "^2.3.1",
70
+ "@types/qs": "^6.9.3",
71
+ "multer": "^1.4.2"
43
72
  },
44
73
  "files": [
45
74
  "README.md",
46
- "index.js",
47
- "index.d.ts",
48
- "dist/src",
49
- "dist6/src",
50
- "api-docs",
51
- "src"
75
+ "dist",
76
+ "src",
77
+ "!*/__tests__"
52
78
  ],
53
79
  "repository": {
54
80
  "type": "git",
55
- "url": "https://github.com/strongloop/loopback-next.git"
56
- }
81
+ "url": "https://github.com/strongloop/loopback-next.git",
82
+ "directory": "packages/rest"
83
+ },
84
+ "gitHead": "62aea854bf85c5a5995b59e6908fe5409f7eea96"
57
85
  }
@@ -0,0 +1,148 @@
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 {
7
+ Options,
8
+ OptionsJson,
9
+ OptionsText,
10
+ OptionsUrlencoded,
11
+ } from 'body-parser';
12
+ import debugModule from 'debug';
13
+ import {HttpError} from 'http-errors';
14
+ import {Request, RequestBodyParserOptions, Response} from '../types';
15
+
16
+ const debug = debugModule('loopback:rest:body-parser');
17
+
18
+ /**
19
+ * Get the content-type header value from the request
20
+ * @param req - Http request
21
+ */
22
+ export function getContentType(req: Request): string | undefined {
23
+ return req.get('content-type');
24
+ }
25
+
26
+ /**
27
+ * Express body parser function type
28
+ */
29
+ export type BodyParserMiddleware = (
30
+ request: Request,
31
+ response: Response,
32
+ next: (err: HttpError) => void,
33
+ ) => void;
34
+
35
+ /**
36
+ * Normalize parsing errors as `4xx`
37
+ * @param err
38
+ */
39
+ export function normalizeParsingError(err: HttpError) {
40
+ debug('Cannot parse request body %j', err);
41
+ if (!err.statusCode || err.statusCode >= 500) {
42
+ err.statusCode = 400;
43
+ }
44
+ return err;
45
+ }
46
+
47
+ /* eslint-disable @typescript-eslint/no-explicit-any */
48
+
49
+ /**
50
+ * Parse the request body asynchronously
51
+ * @param handle - The express middleware handler
52
+ * @param request - Http request
53
+ */
54
+ export function invokeBodyParserMiddleware(
55
+ handle: BodyParserMiddleware,
56
+ request: Request,
57
+ ): Promise<any> {
58
+ // A hack to fool TypeScript as we don't need `response`
59
+ const response = ({} as any) as Response;
60
+ return new Promise<void>((resolve, reject) => {
61
+ handle(request, response, err => {
62
+ if (err) {
63
+ reject(err);
64
+ return;
65
+ }
66
+ resolve(request.body);
67
+ });
68
+ });
69
+ }
70
+
71
+ // Default limit of the body length
72
+ export const DEFAULT_LIMIT = '1mb';
73
+
74
+ /**
75
+ * Extract parser options based on the parser type
76
+ * @param type - json|urlencoded|text
77
+ * @param options
78
+ */
79
+ export function getParserOptions(
80
+ type: 'json',
81
+ options: RequestBodyParserOptions,
82
+ ): OptionsJson;
83
+ export function getParserOptions(
84
+ type: 'urlencoded',
85
+ options: RequestBodyParserOptions,
86
+ ): OptionsUrlencoded;
87
+ export function getParserOptions(
88
+ type: 'text',
89
+ options: RequestBodyParserOptions,
90
+ ): OptionsText;
91
+ export function getParserOptions(
92
+ type: 'raw',
93
+ options: RequestBodyParserOptions,
94
+ ): Options;
95
+
96
+ export function getParserOptions(
97
+ type: 'json' | 'urlencoded' | 'text' | 'raw',
98
+ options: RequestBodyParserOptions,
99
+ ) {
100
+ const opts: {[name: string]: any} = {limit: DEFAULT_LIMIT};
101
+ switch (type) {
102
+ case 'json':
103
+ // Allow */json and */*+json
104
+ opts.type = ['*/json', '*/*+json'];
105
+ opts.strict = false;
106
+ break;
107
+ case 'urlencoded':
108
+ opts.type = type;
109
+ opts.extended = true;
110
+ break;
111
+ case 'text':
112
+ // Set media type to `text/*` to match `text/plain` or `text/html`
113
+ opts.type = 'text/*';
114
+ break;
115
+ case 'raw':
116
+ opts.type = ['application/octet-stream', '*/*'];
117
+ break;
118
+ }
119
+ Object.assign(opts, options[type], options);
120
+ for (const k of ['json', 'urlencoded', 'text', 'raw']) {
121
+ delete opts[k];
122
+ }
123
+ return opts;
124
+ }
125
+
126
+ export namespace builtinParsers {
127
+ export const json = Symbol('json');
128
+ export const urlencoded = Symbol('urlencoded');
129
+ export const text = Symbol('text');
130
+ export const raw = Symbol('raw');
131
+ export const stream = Symbol('stream');
132
+
133
+ export const names: (string | symbol)[] = [
134
+ json,
135
+ urlencoded,
136
+ text,
137
+ raw,
138
+ stream,
139
+ ];
140
+
141
+ export const mapping: {[name: string]: symbol} = {
142
+ json,
143
+ urlencoded,
144
+ text,
145
+ raw,
146
+ stream,
147
+ };
148
+ }
@@ -0,0 +1,46 @@
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 {inject} from '@loopback/context';
7
+ import {json} from 'body-parser';
8
+ import {is} from 'type-is';
9
+ import {RestBindings} from '../keys';
10
+ import {Request, RequestBodyParserOptions} from '../types';
11
+ import {
12
+ BodyParserMiddleware,
13
+ getParserOptions,
14
+ invokeBodyParserMiddleware,
15
+ builtinParsers,
16
+ } from './body-parser.helpers';
17
+ import {BodyParser, RequestBody} from './types';
18
+ import {sanitizeJsonParse} from '../parse-json';
19
+
20
+ export class JsonBodyParser implements BodyParser {
21
+ name = builtinParsers.json;
22
+ private jsonParser: BodyParserMiddleware;
23
+
24
+ constructor(
25
+ @inject(RestBindings.REQUEST_BODY_PARSER_OPTIONS, {optional: true})
26
+ options: RequestBodyParserOptions = {},
27
+ ) {
28
+ const jsonOptions = getParserOptions('json', options);
29
+ jsonOptions.reviver = sanitizeJsonParse(jsonOptions.reviver);
30
+ this.jsonParser = json(jsonOptions);
31
+ }
32
+
33
+ supports(mediaType: string) {
34
+ return !!is(mediaType, '*/json', '*/*+json');
35
+ }
36
+
37
+ async parse(request: Request): Promise<RequestBody> {
38
+ let body = await invokeBodyParserMiddleware(this.jsonParser, request);
39
+ // https://github.com/expressjs/body-parser/blob/master/lib/types/json.js#L71-L76
40
+ const contentLength = request.get('content-length');
41
+ if (contentLength != null && +contentLength === 0) {
42
+ body = undefined;
43
+ }
44
+ return {value: body};
45
+ }
46
+ }
@@ -0,0 +1,42 @@
1
+ // Copyright IBM Corp. 2018. 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 {inject} from '@loopback/context';
7
+ import {raw} from 'body-parser';
8
+ import {is} from 'type-is';
9
+ import {RestBindings} from '../keys';
10
+ import {Request, RequestBodyParserOptions} from '../types';
11
+ import {
12
+ BodyParserMiddleware,
13
+ getParserOptions,
14
+ invokeBodyParserMiddleware,
15
+ builtinParsers,
16
+ } from './body-parser.helpers';
17
+ import {BodyParser, RequestBody} from './types';
18
+
19
+ /**
20
+ * Parsing the request body into Buffer
21
+ */
22
+ export class RawBodyParser implements BodyParser {
23
+ name = builtinParsers.raw;
24
+ private rawParser: BodyParserMiddleware;
25
+
26
+ constructor(
27
+ @inject(RestBindings.REQUEST_BODY_PARSER_OPTIONS, {optional: true})
28
+ options: RequestBodyParserOptions = {},
29
+ ) {
30
+ const rawOptions = getParserOptions('raw', options);
31
+ this.rawParser = raw(rawOptions);
32
+ }
33
+
34
+ supports(mediaType: string) {
35
+ return !!is(mediaType, 'application/octet-stream');
36
+ }
37
+
38
+ async parse(request: Request): Promise<RequestBody> {
39
+ const body = await invokeBodyParserMiddleware(this.rawParser, request);
40
+ return {value: body};
41
+ }
42
+ }
@@ -0,0 +1,27 @@
1
+ // Copyright IBM Corp. 2018. 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 {Request} from '../types';
7
+ import {BodyParser, RequestBody} from './types';
8
+ import {builtinParsers} from './body-parser.helpers';
9
+
10
+ /**
11
+ * A special body parser to retain request stream as is.
12
+ * It will be used by explicitly setting `x-parser` to `'stream'` in the request
13
+ * body spec.
14
+ */
15
+ export class StreamBodyParser implements BodyParser {
16
+ name = builtinParsers.stream;
17
+
18
+ supports(mediaType: string) {
19
+ // Return `false` so that this parser can only be trigged by the
20
+ // `{x-parser: 'stream'}` extension in the request body spec
21
+ return false;
22
+ }
23
+
24
+ async parse(request: Request): Promise<RequestBody> {
25
+ return {value: request};
26
+ }
27
+ }