@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
package/src/sequence.ts CHANGED
@@ -1,20 +1,14 @@
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
- const debug = require('debug')('loopback:core:sequence');
7
- import {ServerResponse} from 'http';
8
- import {inject, Context} from '@loopback/context';
9
- import {
10
- FindRoute,
11
- InvokeMethod,
12
- ParsedRequest,
13
- Send,
14
- Reject,
15
- ParseParams,
16
- } from './internal-types';
6
+ const debug = require('debug')('loopback:rest:sequence');
7
+ import {inject, ValueOrPromise} from '@loopback/context';
8
+ import {InvokeMiddleware} from '@loopback/express';
17
9
  import {RestBindings} from './keys';
10
+ import {RequestContext} from './request-context';
11
+ import {FindRoute, InvokeMethod, ParseParams, Reject, Send} from './types';
18
12
 
19
13
  const SequenceActions = RestBindings.SequenceActions;
20
14
 
@@ -23,10 +17,9 @@ const SequenceActions = RestBindings.SequenceActions;
23
17
  * sequence of actions to handle an incoming request.
24
18
  */
25
19
  export type SequenceFunction = (
20
+ context: RequestContext,
26
21
  sequence: DefaultSequence,
27
- request: ParsedRequest,
28
- response: ServerResponse,
29
- ) => Promise<void> | void;
22
+ ) => ValueOrPromise<void>;
30
23
 
31
24
  /**
32
25
  * A sequence handler is a class implementing sequence of actions
@@ -36,15 +29,16 @@ export interface SequenceHandler {
36
29
  /**
37
30
  * Handle the request by running the configured sequence of actions.
38
31
  *
39
- * @param request The incoming HTTP request
40
- * @param response The HTTP server response where to write the result
32
+ * @param context - The request context: HTTP request and response objects,
33
+ * per-request IoC container and more.
41
34
  */
42
- handle(request: ParsedRequest, response: ServerResponse): Promise<void>;
35
+ handle(context: RequestContext): Promise<void>;
43
36
  }
44
37
 
45
38
  /**
46
39
  * The default implementation of SequenceHandler.
47
40
  *
41
+ * @remarks
48
42
  * This class implements default Sequence for the LoopBack framework.
49
43
  * Default sequence is used if user hasn't defined their own Sequence
50
44
  * for their application.
@@ -53,31 +47,36 @@ export interface SequenceHandler {
53
47
  * when the API request comes in. User defines APIs in their Application
54
48
  * Controller class.
55
49
  *
50
+ * @example
56
51
  * User can bind their own Sequence to app as shown below
57
52
  * ```ts
58
53
  * app.bind(CoreBindings.SEQUENCE).toClass(MySequence);
59
54
  * ```
60
55
  */
61
56
  export class DefaultSequence implements SequenceHandler {
57
+ /**
58
+ * Optional invoker for registered middleware in a chain.
59
+ * To be injected via SequenceActions.INVOKE_MIDDLEWARE.
60
+ */
61
+ @inject(SequenceActions.INVOKE_MIDDLEWARE, {optional: true})
62
+ protected invokeMiddleware: InvokeMiddleware = () => false;
63
+
62
64
  /**
63
65
  * Constructor: Injects findRoute, invokeMethod & logError
64
66
  * methods as promises.
65
67
  *
66
- * @param {Context} ctx The context for the sequence (injected via
67
- * RestBindings.Http.CONTEXT).
68
- * @param {FindRoute} findRoute Finds the appropriate controller method,
68
+ * @param findRoute - Finds the appropriate controller method,
69
69
  * spec and args for invocation (injected via SequenceActions.FIND_ROUTE).
70
- * @param {ParseParams} parseParams The parameter parsing function (injected
70
+ * @param parseParams - The parameter parsing function (injected
71
71
  * via SequenceActions.PARSE_PARAMS).
72
- * @param {InvokeMethod} invoke Invokes the method specified by the route
72
+ * @param invoke - Invokes the method specified by the route
73
73
  * (injected via SequenceActions.INVOKE_METHOD).
74
- * @param {Send} send The action to merge the invoke result with the response
74
+ * @param send - The action to merge the invoke result with the response
75
75
  * (injected via SequenceActions.SEND)
76
- * @param {Reject} reject The action to take if the invoke returns a rejected
76
+ * @param reject - The action to take if the invoke returns a rejected
77
77
  * promise result (injected via SequenceActions.REJECT).
78
78
  */
79
79
  constructor(
80
- @inject(RestBindings.Http.CONTEXT) public ctx: Context,
81
80
  @inject(SequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
82
81
  @inject(SequenceActions.PARSE_PARAMS) protected parseParams: ParseParams,
83
82
  @inject(SequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,
@@ -86,10 +85,11 @@ export class DefaultSequence implements SequenceHandler {
86
85
  ) {}
87
86
 
88
87
  /**
89
- * Runs the default sequence. Given a request and response, running the
90
- * sequence will produce a response or an error.
88
+ * Runs the default sequence. Given a handler context (request and response),
89
+ * running the sequence will produce a response or an error.
91
90
  *
92
91
  * Default sequence executes these steps
92
+ * - Executes middleware for CORS, OpenAPI spec endpoints
93
93
  * - Finds the appropriate controller method, swagger spec
94
94
  * and args for invocation
95
95
  * - Parses HTTP request to get API argument list
@@ -97,20 +97,27 @@ export class DefaultSequence implements SequenceHandler {
97
97
  * - Writes the result from API into the HTTP response
98
98
  * - Error is caught and logged using 'logError' if any of the above steps
99
99
  * in the sequence fails with an error.
100
- * @param req Parsed incoming HTTP request
101
- * @param res HTTP server response with result from Application controller
102
- * method invocation
100
+ *
101
+ * @param context - The request context: HTTP request and response objects,
102
+ * per-request IoC container and more.
103
103
  */
104
- async handle(req: ParsedRequest, res: ServerResponse) {
104
+ async handle(context: RequestContext): Promise<void> {
105
105
  try {
106
- const route = this.findRoute(req);
107
- const args = await this.parseParams(req, route);
106
+ const {request, response} = context;
107
+ // Invoke registered Express middleware
108
+ const finished = await this.invokeMiddleware(context);
109
+ if (finished) {
110
+ // The response been produced by the middleware chain
111
+ return;
112
+ }
113
+ const route = this.findRoute(request);
114
+ const args = await this.parseParams(request, route);
108
115
  const result = await this.invoke(route, args);
109
116
 
110
117
  debug('%s result -', route.describe(), result);
111
- this.send(res, result);
112
- } catch (err) {
113
- this.reject(res, req, err);
118
+ this.send(response, result);
119
+ } catch (error) {
120
+ this.reject(context, error);
114
121
  }
115
122
  }
116
123
  }
@@ -0,0 +1,182 @@
1
+ // Copyright IBM Corp. 2020. 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
+ ApplicationConfig,
8
+ bind,
9
+ BindingScope,
10
+ CoreBindings,
11
+ inject,
12
+ } from '@loopback/core';
13
+ import {
14
+ asSpecEnhancer,
15
+ ISpecificationExtension,
16
+ isSchemaObject,
17
+ OASEnhancer,
18
+ OpenApiSpec,
19
+ ReferenceObject,
20
+ SchemaObject,
21
+ } from '@loopback/openapi-v3';
22
+ import debugFactory from 'debug';
23
+ import compare from 'json-schema-compare';
24
+ import _ from 'lodash';
25
+
26
+ const debug = debugFactory('loopback:openapi:spec-enhancer:consolidate');
27
+
28
+ /**
29
+ * This enhancer consolidates schemas into `/components/schemas` and replaces
30
+ * instances of said schema with a $ref pointer.
31
+ *
32
+ * Please note that the title property must be set on a schema in order to be
33
+ * considered for consolidation.
34
+ *
35
+ * For example, with the following schema instance:
36
+ *
37
+ * ```json
38
+ * schema: {
39
+ * title: 'loopback.example',
40
+ * properties: {
41
+ * test: {
42
+ * type: 'string',
43
+ * },
44
+ * },
45
+ * }
46
+ * ```
47
+ *
48
+ * The consolidator will copy the schema body to
49
+ * `/components/schemas/loopback.example` and replace any instance of the schema
50
+ * with a reference to the component schema as follows:
51
+ *
52
+ * ```json
53
+ * schema: {
54
+ * $ref: '#/components/schemas/loopback.example',
55
+ * }
56
+ * ```
57
+ *
58
+ * When comparing schemas to avoid naming collisions, the description field
59
+ * is ignored.
60
+ */
61
+ @bind(asSpecEnhancer, {scope: BindingScope.SINGLETON})
62
+ export class ConsolidationEnhancer implements OASEnhancer {
63
+ name = 'consolidate';
64
+ disabled: boolean;
65
+
66
+ constructor(
67
+ @inject(CoreBindings.APPLICATION_CONFIG, {optional: true})
68
+ readonly config?: ApplicationConfig,
69
+ ) {
70
+ this.disabled = this.config?.rest?.openApiSpec?.consolidate === false;
71
+ }
72
+
73
+ modifySpec(spec: OpenApiSpec): OpenApiSpec {
74
+ return !this.disabled ? this.consolidateSchemaObjects(spec) : spec;
75
+ }
76
+
77
+ /**
78
+ * Recursively search OpenApiSpec PathsObject for SchemaObjects with title
79
+ * property. Moves reusable schema bodies to #/components/schemas and replace
80
+ * with json pointer. It handles title collisions with schema body comparision.
81
+ */
82
+ private consolidateSchemaObjects(spec: OpenApiSpec): OpenApiSpec {
83
+ // use 'paths' as crawl root
84
+ this.recursiveWalk(spec.paths, ['paths'], spec);
85
+
86
+ return spec;
87
+ }
88
+
89
+ private recursiveWalk(
90
+ rootSchema: ISpecificationExtension,
91
+ parentPath: Array<string>,
92
+ spec: OpenApiSpec,
93
+ ) {
94
+ if (this.isTraversable(rootSchema)) {
95
+ Object.entries(rootSchema).forEach(([key, subSchema]) => {
96
+ if (subSchema) {
97
+ this.recursiveWalk(subSchema, parentPath.concat(key), spec);
98
+ this.processSchema(subSchema, parentPath.concat(key), spec);
99
+ }
100
+ });
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Carry out schema consolidation after tree traversal. If 'title' property
106
+ * set then we consider current schema for consolidation. SchemaObjects with
107
+ * properties (and title set) are moved to #/components/schemas/<title> and
108
+ * replaced with ReferenceObject.
109
+ *
110
+ * Features:
111
+ * - name collision protection
112
+ *
113
+ * @param schema - current schema element to process
114
+ * @param parentPath - path object to parent
115
+ * @param spec - subject OpenApi specification
116
+ */
117
+ private processSchema(
118
+ schema: SchemaObject | ReferenceObject,
119
+ parentPath: Array<string>,
120
+ spec: OpenApiSpec,
121
+ ) {
122
+ const schemaObj = this.ifConsolidationCandidate(schema);
123
+ if (schemaObj) {
124
+ // name collison protection
125
+ let instanceNo = 1;
126
+ let title = schemaObj.title!;
127
+ let refSchema = this.getRefSchema(title, spec);
128
+ while (
129
+ refSchema &&
130
+ !compare(schemaObj as ISpecificationExtension, refSchema, {
131
+ ignore: ['description'],
132
+ })
133
+ ) {
134
+ title = `${schemaObj.title}${instanceNo++}`;
135
+ refSchema = this.getRefSchema(title, spec);
136
+ }
137
+ if (!refSchema) {
138
+ debug('Creating new component $ref with schema %j', schema);
139
+ this.patchRef(title, schema, spec);
140
+ }
141
+ debug('Creating link to $ref %j', title);
142
+ this.patchPath(title, parentPath, spec);
143
+ }
144
+ }
145
+
146
+ private getRefSchema(
147
+ name: string,
148
+ spec: OpenApiSpec,
149
+ ): ISpecificationExtension | undefined {
150
+ const schema = _.get(spec, ['components', 'schemas', name]);
151
+
152
+ return schema;
153
+ }
154
+
155
+ private patchRef(
156
+ name: string,
157
+ value: ISpecificationExtension,
158
+ spec: OpenApiSpec,
159
+ ) {
160
+ _.set(spec, ['components', 'schemas', name], value);
161
+ }
162
+
163
+ private patchPath(name: string, path: Array<string>, spec: OpenApiSpec) {
164
+ const patch = {
165
+ $ref: `#/components/schemas/${name}`,
166
+ };
167
+ _.set(spec, path, patch);
168
+ }
169
+
170
+ private ifConsolidationCandidate(
171
+ schema: SchemaObject | ReferenceObject,
172
+ ): SchemaObject | undefined {
173
+ // use title to discriminate references
174
+ return isSchemaObject(schema) && schema.properties && schema.title
175
+ ? schema
176
+ : undefined;
177
+ }
178
+
179
+ private isTraversable(schema: ISpecificationExtension): boolean {
180
+ return schema && typeof schema === 'object' ? true : false;
181
+ }
182
+ }
@@ -0,0 +1,92 @@
1
+ // Copyright IBM Corp. 2020. 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
+ bind,
8
+ BindingScope,
9
+ inject,
10
+ JSONObject,
11
+ JSONValue,
12
+ } from '@loopback/context';
13
+ import {ApplicationMetadata, CoreBindings} from '@loopback/core';
14
+ import {
15
+ asSpecEnhancer,
16
+ ContactObject,
17
+ mergeOpenAPISpec,
18
+ OASEnhancer,
19
+ OpenApiSpec,
20
+ } from '@loopback/openapi-v3';
21
+ import debugFactory from 'debug';
22
+
23
+ const debug = debugFactory('loopback:openapi:spec-enhancer:info');
24
+
25
+ /**
26
+ * An OpenAPI spec enhancer to populate `info` with application metadata
27
+ * (package.json).
28
+ */
29
+ @bind(asSpecEnhancer, {scope: BindingScope.SINGLETON})
30
+ export class InfoSpecEnhancer implements OASEnhancer {
31
+ name = 'info';
32
+
33
+ constructor(
34
+ @inject(CoreBindings.APPLICATION_METADATA, {optional: true})
35
+ readonly pkg?: ApplicationMetadata,
36
+ ) {}
37
+
38
+ modifySpec(spec: OpenApiSpec): OpenApiSpec {
39
+ if (this.pkg == null) {
40
+ debug('Application metadata is not found. Skipping spec enhancing.');
41
+ return spec;
42
+ }
43
+ const contact: ContactObject = InfoSpecEnhancer.parseAuthor(
44
+ this.pkg.author,
45
+ );
46
+ const patchSpec = {
47
+ info: {
48
+ title: this.pkg.name,
49
+ description: this.pkg.description,
50
+ version: this.pkg.version,
51
+ contact,
52
+ },
53
+ };
54
+ debug('Enhancing OpenAPI spec with %j', patchSpec);
55
+ return mergeOpenAPISpec(spec, patchSpec);
56
+ }
57
+
58
+ /**
59
+ * Parse package.json
60
+ * {@link https://docs.npmjs.com/files/package.json#people-fields-author-contributors | author}
61
+ *
62
+ * @param author - Author string or object from package.json
63
+ */
64
+ private static parseAuthor(author: JSONValue) {
65
+ let contact: ContactObject = {};
66
+ if (author == null) {
67
+ contact = {};
68
+ } else if (typeof author === 'string') {
69
+ // "Barney Rubble <b@rubble.com> (http://barnyrubble.tumblr.com/)"
70
+ const emailRegex = /<([^<>]+)>/; // <email>
71
+ const urlRegex = /\(([^()]+)\)/; // (url)
72
+ const nameRegex = /([^<>()]+)/;
73
+ contact = {
74
+ name: nameRegex.exec(author)?.[1]?.trim(),
75
+ email: emailRegex.exec(author)?.[1]?.trim(),
76
+ url: urlRegex.exec(author)?.[1]?.trim(),
77
+ };
78
+ } else if (typeof author === 'object') {
79
+ const authorObj = author as JSONObject;
80
+ contact = {
81
+ name: authorObj.name as string,
82
+ email: authorObj.email as string,
83
+ url: authorObj.url as string,
84
+ };
85
+ }
86
+ // Remove undefined/null values
87
+ for (const p in contact) {
88
+ if (contact[p] == null) delete contact[p];
89
+ }
90
+ return contact;
91
+ }
92
+ }
package/src/types.ts ADDED
@@ -0,0 +1,216 @@
1
+ // Copyright IBM Corp. 2018,2020. 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 {HandlerContext, Request, Response} from '@loopback/express';
7
+ import {ReferenceObject, SchemaObject} from '@loopback/openapi-v3';
8
+ import ajv, {Ajv, FormatDefinition, KeywordDefinition} from 'ajv';
9
+ import {
10
+ Options,
11
+ OptionsJson,
12
+ OptionsText,
13
+ OptionsUrlencoded,
14
+ } from 'body-parser';
15
+ import {ResolvedRoute, RouteEntry} from './router';
16
+
17
+ /**
18
+ * Re-export types from `./middleware`
19
+ */
20
+ export * from '@loopback/express';
21
+
22
+ /**
23
+ * Find a route matching the incoming request.
24
+ * Throw an error when no route was found.
25
+ */
26
+ export type FindRoute = (request: Request) => ResolvedRoute;
27
+
28
+ /**
29
+ *
30
+ */
31
+ export type ParseParams = (
32
+ request: Request,
33
+ route: ResolvedRoute,
34
+ ) => Promise<OperationArgs>;
35
+
36
+ /**
37
+ * Invokes a method defined in the Application Controller
38
+ *
39
+ * @param controller - Name of end-user's application controller
40
+ * class which defines the methods.
41
+ * @param method - Method name in application controller class
42
+ * @param args - Operation arguments for the method
43
+ * @returns OperationRetval Result from method invocation
44
+ */
45
+ export type InvokeMethod = (
46
+ route: RouteEntry,
47
+ args: OperationArgs,
48
+ ) => Promise<OperationRetval>;
49
+
50
+ /**
51
+ * Send the operation response back to the client.
52
+ *
53
+ * @param response - The response the response to send to.
54
+ * @param result - The operation result to send.
55
+ */
56
+ export type Send = (response: Response, result: OperationRetval) => void;
57
+
58
+ /**
59
+ * Reject the request with an error.
60
+ *
61
+ * @param handlerContext - The context object holding HTTP request, response
62
+ * and other data needed to handle an incoming HTTP request.
63
+ * @param err - The error.
64
+ */
65
+ export type Reject = (handlerContext: HandlerContext, err: Error) => void;
66
+
67
+ /**
68
+ * Log information about a failed request.
69
+ *
70
+ * @param err - The error reported by request handling code.
71
+ * @param statusCode - Status code of the HTTP response
72
+ * @param request - The request that failed.
73
+ */
74
+ export type LogError = (
75
+ err: Error,
76
+ statusCode: number,
77
+ request: Request,
78
+ ) => void;
79
+
80
+ /**
81
+ * Cache for AJV schema validators
82
+ */
83
+ export type SchemaValidatorCache = WeakMap<
84
+ SchemaObject | ReferenceObject, // First keyed by schema object
85
+ Map<string, ajv.ValidateFunction> // Second level keyed by stringified AJV options
86
+ >;
87
+
88
+ /**
89
+ * Options for AJV errors
90
+ */
91
+ export type AjvErrorOptions = {
92
+ keepErrors?: boolean;
93
+ singleError?: boolean;
94
+ };
95
+
96
+ /**
97
+ * Factory function for Ajv instances
98
+ */
99
+ export type AjvFactory = (options?: ajv.Options) => Ajv;
100
+
101
+ /**
102
+ * Ajv keyword definition with a name
103
+ */
104
+ export type AjvKeyword = KeywordDefinition & {name: string};
105
+
106
+ /**
107
+ * Ajv format definition with a name
108
+ */
109
+ export type AjvFormat = FormatDefinition & {name: string};
110
+
111
+ /**
112
+ * Options for request body validation using AJV
113
+ */
114
+ export interface RequestBodyValidationOptions extends ajv.Options {
115
+ /**
116
+ * Custom cache for compiled schemas by AJV. This setting makes it possible
117
+ * to skip the default cache.
118
+ */
119
+ compiledSchemaCache?: SchemaValidatorCache;
120
+ /**
121
+ * Enable additional AJV keywords from https://github.com/epoberezkin/ajv-keywords
122
+ * - `true`: Add all keywords from `ajv-keywords`
123
+ * - `string[]`: Add an array of keywords from `ajv-keywords`
124
+ */
125
+ ajvKeywords?: true | string[];
126
+ /**
127
+ * Enable custom error messages in JSON-Schema for AJV validator
128
+ * from https://github.com/epoberezkin/ajv-errors
129
+ * - `true`: Enable `ajv-errors`
130
+ * - `AjvErrorOptions`: Enable `ajv-errors` with options
131
+ */
132
+ ajvErrors?: true | AjvErrorOptions;
133
+ /**
134
+ * A function that transform the `ErrorObject`s reported by AJV.
135
+ * This could be used for error messages customization, localization, etc.
136
+ */
137
+ ajvErrorTransformer?: (errors: ajv.ErrorObject[]) => ajv.ErrorObject[];
138
+
139
+ /**
140
+ * A factory to create Ajv instance
141
+ */
142
+ ajvFactory?: (options: ajv.Options) => Ajv;
143
+ }
144
+
145
+ /* eslint-disable @typescript-eslint/no-explicit-any */
146
+
147
+ /**
148
+ * Options for request body parsing
149
+ * See https://github.com/expressjs/body-parser/#options
150
+ *
151
+ * Built-in parsers retrieve their own options from the request body parser
152
+ * options. The parser specific properties override common ones.
153
+ */
154
+ export interface RequestBodyParserOptions extends Options {
155
+ /**
156
+ * Options for json parser
157
+ */
158
+ json?: OptionsJson;
159
+ /**
160
+ * Options for urlencoded parser
161
+ */
162
+ urlencoded?: OptionsUrlencoded;
163
+ /**
164
+ * Options for text parser
165
+ */
166
+ text?: OptionsText;
167
+ /**
168
+ * Options for raw parser
169
+ */
170
+ raw?: Options;
171
+ /**
172
+ * Validation options for AJV, see https://github.com/epoberezkin/ajv#options
173
+ * This setting is global for all request body parsers and it cannot be
174
+ * overridden inside parser specific properties such as `json` or `text`.
175
+ */
176
+ validation?: RequestBodyValidationOptions;
177
+ /**
178
+ * Common options for all parsers
179
+ */
180
+ [name: string]: unknown;
181
+ }
182
+
183
+ export type PathParameterValues = {[key: string]: any};
184
+ export type OperationArgs = any[];
185
+
186
+ /**
187
+ * Return value of a controller method (a function implementing an operation).
188
+ * This is a type alias for "any", used to distinguish
189
+ * operation results from other "any" typed values.
190
+ */
191
+ export type OperationRetval = any;
192
+
193
+ /**
194
+ * user profile to add in session
195
+ */
196
+ export interface SessionUserProfile {
197
+ provider: string;
198
+ token: string;
199
+ email: string;
200
+ [attribute: string]: any;
201
+ }
202
+
203
+ /**
204
+ * interface to set variables in user session
205
+ */
206
+ export interface Session {
207
+ profile: SessionUserProfile;
208
+ [key: string]: any;
209
+ }
210
+
211
+ /**
212
+ * extending express request type with a session field
213
+ */
214
+ export interface RequestWithSession extends Request {
215
+ session: Session;
216
+ }