@toa.io/extensions.exposition 1.0.0-alpha.2 → 1.0.0-alpha.21

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 (383) hide show
  1. package/components/identity.bans/manifest.toa.yaml +15 -6
  2. package/components/identity.bans/operations/transit.d.ts +14 -0
  3. package/components/identity.bans/operations/transit.js +11 -0
  4. package/components/identity.bans/operations/transit.js.map +1 -0
  5. package/components/identity.bans/operations/tsconfig.tsbuildinfo +1 -0
  6. package/components/identity.bans/source/transit.ts +21 -0
  7. package/components/identity.bans/tsconfig.json +9 -0
  8. package/components/identity.basic/manifest.toa.yaml +5 -1
  9. package/components/identity.basic/operations/tsconfig.tsbuildinfo +1 -1
  10. package/components/identity.federation/manifest.toa.yaml +13 -7
  11. package/components/identity.federation/operations/authenticate.js +4 -4
  12. package/components/identity.federation/operations/authenticate.js.map +1 -1
  13. package/components/identity.federation/operations/create.js +4 -4
  14. package/components/identity.federation/operations/create.js.map +1 -1
  15. package/components/identity.federation/operations/{assertions-as-values.cjs → lib/assertions-as-values.js} +1 -1
  16. package/components/identity.federation/operations/lib/assertions-as-values.js.map +1 -0
  17. package/components/identity.federation/operations/{jwt.d.cts → lib/jwt.d.ts} +5 -4
  18. package/components/identity.federation/operations/{jwt.cjs → lib/jwt.js} +35 -11
  19. package/components/identity.federation/operations/lib/jwt.js.map +1 -0
  20. package/components/identity.federation/operations/schemas.d.ts +16 -0
  21. package/components/identity.federation/operations/tsconfig.tsbuildinfo +1 -1
  22. package/components/identity.federation/operations/types.d.ts +1 -1
  23. package/components/identity.federation/source/authenticate.ts +2 -2
  24. package/components/identity.federation/source/create.ts +2 -2
  25. package/components/identity.federation/source/{assertions-as-values.cts → lib/assertions-as-values.ts} +1 -2
  26. package/components/identity.federation/source/lib/jwt.test.ts +56 -0
  27. package/components/identity.federation/source/{jwt.cts → lib/jwt.ts} +57 -29
  28. package/components/identity.federation/source/schemas.ts +16 -0
  29. package/components/identity.federation/source/types.ts +1 -1
  30. package/components/identity.federation/tsconfig.json +2 -2
  31. package/components/identity.roles/manifest.toa.yaml +18 -5
  32. package/components/identity.roles/operations/grant.d.ts +10 -0
  33. package/components/identity.roles/operations/grant.js +21 -0
  34. package/components/identity.roles/operations/grant.js.map +1 -0
  35. package/components/identity.roles/operations/lib/Entity.d.ts +5 -0
  36. package/components/identity.roles/operations/lib/Entity.js +3 -0
  37. package/components/identity.roles/operations/lib/Entity.js.map +1 -0
  38. package/components/identity.roles/operations/list.d.ts +1 -4
  39. package/components/identity.roles/operations/list.js.map +1 -1
  40. package/components/identity.roles/operations/principal.d.ts +4 -6
  41. package/components/identity.roles/operations/principal.js +6 -1
  42. package/components/identity.roles/operations/principal.js.map +1 -1
  43. package/components/identity.roles/operations/tsconfig.tsbuildinfo +1 -1
  44. package/components/identity.roles/source/grant.ts +32 -0
  45. package/components/identity.roles/source/lib/Entity.ts +5 -0
  46. package/components/identity.roles/source/list.ts +2 -4
  47. package/components/identity.roles/source/principal.ts +10 -8
  48. package/components/identity.tokens/manifest.toa.yaml +12 -3
  49. package/components/identity.tokens/operations/authenticate.js +5 -2
  50. package/components/identity.tokens/operations/authenticate.js.map +1 -1
  51. package/components/identity.tokens/operations/encrypt.js +4 -1
  52. package/components/identity.tokens/operations/encrypt.js.map +1 -1
  53. package/components/identity.tokens/operations/tsconfig.tsbuildinfo +1 -1
  54. package/components/identity.tokens/operations/types.d.ts +1 -2
  55. package/components/identity.tokens/receivers/identity.bans.created.js +3 -0
  56. package/components/identity.tokens/source/authenticate.ts +5 -2
  57. package/components/identity.tokens/source/encrypt.test.ts +22 -1
  58. package/components/identity.tokens/source/encrypt.ts +4 -1
  59. package/components/identity.tokens/source/types.ts +1 -2
  60. package/components/octets.storage/operations/store.js +1 -1
  61. package/documentation/access.md +27 -16
  62. package/documentation/cache.md +8 -1
  63. package/documentation/components.md +55 -23
  64. package/documentation/identity.md +7 -0
  65. package/documentation/io.md +56 -0
  66. package/documentation/octets.md +12 -0
  67. package/documentation/protocol.md +3 -0
  68. package/documentation/query.md +50 -5
  69. package/documentation/require.md +15 -0
  70. package/documentation/tree.md +22 -4
  71. package/documentation/vary.md +9 -3
  72. package/features/access.feature +28 -49
  73. package/features/annotation.feature +1 -0
  74. package/features/body.feature +3 -1
  75. package/features/cache.feature +39 -0
  76. package/features/cors.feature +2 -2
  77. package/features/directives.feature +2 -0
  78. package/features/dynamic.feature +14 -7
  79. package/features/errors.feature +7 -4
  80. package/features/etag.feature +97 -0
  81. package/features/identity.bans.feature +128 -0
  82. package/features/identity.basic.feature +68 -3
  83. package/features/identity.federation.feature +78 -5
  84. package/features/identity.roles.feature +205 -1
  85. package/features/identity.tokens.feature +98 -0
  86. package/features/io.feature +196 -0
  87. package/features/octets.entries.feature +3 -1
  88. package/features/octets.feature +32 -10
  89. package/features/octets.meta.feature +4 -3
  90. package/features/octets.workflows.feature +39 -0
  91. package/features/queries.feature +9 -1
  92. package/features/require.feature +64 -0
  93. package/features/response.feature +7 -1
  94. package/features/routes.feature +17 -10
  95. package/features/steps/Database.ts +17 -10
  96. package/features/steps/Gateway.ts +3 -0
  97. package/features/steps/IdP.ts +55 -21
  98. package/features/steps/components/echo/manifest.toa.yaml +5 -0
  99. package/features/steps/components/echo/operations/identity.js +7 -0
  100. package/features/steps/components/greeter/manifest.toa.yaml +1 -0
  101. package/features/steps/components/octets.tester/manifest.toa.yaml +1 -0
  102. package/features/steps/components/pots/manifest.toa.yaml +12 -3
  103. package/features/steps/components/sequences/manifest.toa.yaml +1 -0
  104. package/features/steps/components/users.properties/manifest.toa.yaml +2 -1
  105. package/features/timing.feature +66 -0
  106. package/features/vary.feature +56 -3
  107. package/package.json +13 -14
  108. package/readme.md +7 -6
  109. package/schemas/annotation.cos.yaml +1 -0
  110. package/schemas/io/input.cos.yaml +3 -0
  111. package/schemas/io/message.cos.yaml +5 -0
  112. package/schemas/io/output.cos.yaml +5 -0
  113. package/schemas/octets/workflow.cos.yaml +12 -0
  114. package/schemas/querystring.cos.yaml +1 -0
  115. package/source/Annotation.ts +1 -0
  116. package/source/Context.ts +6 -4
  117. package/source/Directive.test.ts +7 -7
  118. package/source/Directive.ts +19 -46
  119. package/source/Endpoint.ts +53 -6
  120. package/source/Factory.ts +17 -7
  121. package/source/Gateway.ts +40 -51
  122. package/source/HTTP/Context.ts +67 -0
  123. package/source/HTTP/Server.test.ts +1 -1
  124. package/source/HTTP/Server.ts +61 -96
  125. package/source/HTTP/Timing.ts +40 -0
  126. package/source/HTTP/exceptions.ts +1 -1
  127. package/source/HTTP/index.ts +1 -0
  128. package/source/HTTP/messages.test.ts +27 -8
  129. package/source/HTTP/messages.ts +32 -48
  130. package/source/Mapping.ts +7 -8
  131. package/source/RTD/Context.ts +7 -10
  132. package/source/RTD/Directives.ts +28 -4
  133. package/source/RTD/Endpoint.ts +6 -4
  134. package/source/RTD/Match.ts +2 -7
  135. package/source/RTD/Method.ts +7 -13
  136. package/source/RTD/Node.ts +13 -14
  137. package/source/RTD/Tree.ts +17 -16
  138. package/source/RTD/factory.ts +3 -6
  139. package/source/Tenant.ts +0 -8
  140. package/source/deployment.ts +6 -0
  141. package/source/directives/auth/Anonymous.ts +3 -2
  142. package/source/directives/auth/Authorization.ts +17 -14
  143. package/source/directives/auth/Delegate.ts +35 -0
  144. package/source/directives/auth/Incept.ts +11 -6
  145. package/source/directives/auth/Role.test.ts +53 -6
  146. package/source/directives/auth/Role.ts +27 -17
  147. package/source/directives/auth/Scheme.ts +2 -2
  148. package/source/directives/auth/types.ts +1 -1
  149. package/source/directives/cache/Cache.ts +5 -5
  150. package/source/directives/cache/Control.ts +48 -22
  151. package/source/directives/cache/types.ts +1 -1
  152. package/source/directives/cors/CORS.ts +18 -10
  153. package/source/directives/dev/Development.ts +4 -4
  154. package/source/directives/index.ts +6 -4
  155. package/source/directives/io/Directive.ts +11 -0
  156. package/source/directives/io/IO.ts +43 -0
  157. package/source/directives/io/Input.ts +50 -0
  158. package/source/directives/io/Message.ts +1 -0
  159. package/source/directives/io/Output.ts +69 -0
  160. package/source/directives/io/index.ts +3 -0
  161. package/source/directives/io/schemas.ts +12 -0
  162. package/source/directives/octets/Context.ts +5 -4
  163. package/source/directives/octets/Delete.ts +25 -13
  164. package/source/directives/octets/Directive.ts +10 -0
  165. package/source/directives/octets/Fetch.ts +33 -17
  166. package/source/directives/octets/List.ts +18 -8
  167. package/source/directives/octets/Octets.ts +12 -8
  168. package/source/directives/octets/Permute.ts +16 -9
  169. package/source/directives/octets/Store.ts +43 -19
  170. package/source/directives/octets/Workflow.ts +48 -0
  171. package/source/directives/octets/schemas.test.ts +21 -0
  172. package/source/directives/octets/schemas.ts +2 -0
  173. package/source/directives/octets/types.ts +0 -7
  174. package/source/directives/octets/{workflow → workflows}/Execution.ts +0 -2
  175. package/source/directives/octets/{workflow → workflows}/Workflow.ts +2 -2
  176. package/source/directives/require/Directive.ts +5 -0
  177. package/source/directives/require/Headers.ts +20 -0
  178. package/source/directives/require/Require.ts +28 -0
  179. package/source/directives/require/index.ts +3 -0
  180. package/source/directives/vary/Directive.ts +2 -1
  181. package/source/directives/vary/Embed.ts +14 -8
  182. package/source/directives/vary/Vary.ts +8 -6
  183. package/source/directives/vary/embeddings/Embedding.ts +2 -1
  184. package/source/directives/vary/embeddings/Header.ts +9 -7
  185. package/source/directives/vary/embeddings/Language.ts +2 -2
  186. package/source/directives/vary/embeddings/Parameter.ts +14 -0
  187. package/source/directives/vary/embeddings/index.ts +3 -3
  188. package/source/exceptions.ts +22 -11
  189. package/source/io.ts +2 -2
  190. package/source/root.ts +5 -0
  191. package/transpiled/Annotation.d.ts +1 -0
  192. package/transpiled/Context.d.ts +6 -4
  193. package/transpiled/Directive.d.ts +8 -21
  194. package/transpiled/Directive.js +11 -14
  195. package/transpiled/Directive.js.map +1 -1
  196. package/transpiled/Endpoint.d.ts +7 -5
  197. package/transpiled/Endpoint.js +58 -2
  198. package/transpiled/Endpoint.js.map +1 -1
  199. package/transpiled/Factory.js +8 -2
  200. package/transpiled/Factory.js.map +1 -1
  201. package/transpiled/Gateway.d.ts +4 -8
  202. package/transpiled/Gateway.js +23 -33
  203. package/transpiled/Gateway.js.map +1 -1
  204. package/transpiled/HTTP/Context.d.ts +24 -0
  205. package/transpiled/HTTP/Context.js +47 -0
  206. package/transpiled/HTTP/Context.js.map +1 -0
  207. package/transpiled/HTTP/Server.d.ts +8 -7
  208. package/transpiled/HTTP/Server.js +69 -77
  209. package/transpiled/HTTP/Server.js.map +1 -1
  210. package/transpiled/HTTP/Timing.d.ts +10 -0
  211. package/transpiled/HTTP/Timing.js +29 -0
  212. package/transpiled/HTTP/Timing.js.map +1 -0
  213. package/transpiled/HTTP/exceptions.d.ts +1 -1
  214. package/transpiled/HTTP/exceptions.js.map +1 -1
  215. package/transpiled/HTTP/index.d.ts +1 -0
  216. package/transpiled/HTTP/index.js +1 -0
  217. package/transpiled/HTTP/index.js.map +1 -1
  218. package/transpiled/HTTP/messages.d.ts +7 -21
  219. package/transpiled/HTTP/messages.js +24 -26
  220. package/transpiled/HTTP/messages.js.map +1 -1
  221. package/transpiled/Mapping.js +7 -7
  222. package/transpiled/Mapping.js.map +1 -1
  223. package/transpiled/RTD/Context.d.ts +7 -6
  224. package/transpiled/RTD/Directives.d.ts +19 -4
  225. package/transpiled/RTD/Endpoint.d.ts +6 -4
  226. package/transpiled/RTD/Match.d.ts +2 -4
  227. package/transpiled/RTD/Method.d.ts +7 -7
  228. package/transpiled/RTD/Method.js.map +1 -1
  229. package/transpiled/RTD/Node.d.ts +4 -6
  230. package/transpiled/RTD/Node.js +2 -1
  231. package/transpiled/RTD/Node.js.map +1 -1
  232. package/transpiled/RTD/Tree.d.ts +6 -6
  233. package/transpiled/RTD/Tree.js +4 -1
  234. package/transpiled/RTD/Tree.js.map +1 -1
  235. package/transpiled/RTD/factory.d.ts +2 -4
  236. package/transpiled/RTD/factory.js +1 -1
  237. package/transpiled/RTD/factory.js.map +1 -1
  238. package/transpiled/Tenant.d.ts +0 -1
  239. package/transpiled/Tenant.js +0 -6
  240. package/transpiled/Tenant.js.map +1 -1
  241. package/transpiled/deployment.js +5 -0
  242. package/transpiled/deployment.js.map +1 -1
  243. package/transpiled/directives/auth/Anonymous.js +3 -4
  244. package/transpiled/directives/auth/Anonymous.js.map +1 -1
  245. package/transpiled/directives/auth/Authorization.d.ts +2 -3
  246. package/transpiled/directives/auth/Authorization.js +10 -8
  247. package/transpiled/directives/auth/Authorization.js.map +1 -1
  248. package/transpiled/directives/auth/Delegate.d.ts +8 -0
  249. package/transpiled/directives/auth/Delegate.js +29 -0
  250. package/transpiled/directives/auth/Delegate.js.map +1 -0
  251. package/transpiled/directives/auth/Incept.d.ts +1 -1
  252. package/transpiled/directives/auth/Incept.js +11 -6
  253. package/transpiled/directives/auth/Incept.js.map +1 -1
  254. package/transpiled/directives/auth/Role.d.ts +4 -1
  255. package/transpiled/directives/auth/Role.js +25 -17
  256. package/transpiled/directives/auth/Role.js.map +1 -1
  257. package/transpiled/directives/auth/Scheme.js +2 -2
  258. package/transpiled/directives/auth/Scheme.js.map +1 -1
  259. package/transpiled/directives/cache/Cache.d.ts +3 -3
  260. package/transpiled/directives/cache/Cache.js +3 -3
  261. package/transpiled/directives/cache/Cache.js.map +1 -1
  262. package/transpiled/directives/cache/Control.d.ts +5 -4
  263. package/transpiled/directives/cache/Control.js +32 -15
  264. package/transpiled/directives/cache/Control.js.map +1 -1
  265. package/transpiled/directives/cache/types.d.ts +1 -1
  266. package/transpiled/directives/cors/CORS.d.ts +2 -3
  267. package/transpiled/directives/cors/CORS.js +17 -10
  268. package/transpiled/directives/cors/CORS.js.map +1 -1
  269. package/transpiled/directives/dev/Development.d.ts +3 -3
  270. package/transpiled/directives/dev/Development.js +1 -1
  271. package/transpiled/directives/dev/Development.js.map +1 -1
  272. package/transpiled/directives/index.d.ts +2 -2
  273. package/transpiled/directives/index.js +5 -3
  274. package/transpiled/directives/index.js.map +1 -1
  275. package/transpiled/directives/io/Directive.d.ts +8 -0
  276. package/transpiled/directives/io/Directive.js +3 -0
  277. package/transpiled/directives/io/Directive.js.map +1 -0
  278. package/transpiled/directives/io/IO.d.ts +9 -0
  279. package/transpiled/directives/io/IO.js +33 -0
  280. package/transpiled/directives/io/IO.js.map +1 -0
  281. package/transpiled/directives/io/Input.d.ts +11 -0
  282. package/transpiled/directives/io/Input.js +63 -0
  283. package/transpiled/directives/io/Input.js.map +1 -0
  284. package/transpiled/directives/io/Message.d.ts +1 -0
  285. package/transpiled/directives/io/Message.js +3 -0
  286. package/transpiled/directives/io/Message.js.map +1 -0
  287. package/transpiled/directives/io/Output.d.ts +13 -0
  288. package/transpiled/directives/io/Output.js +76 -0
  289. package/transpiled/directives/io/Output.js.map +1 -0
  290. package/transpiled/directives/io/index.d.ts +2 -0
  291. package/transpiled/directives/io/index.js +6 -0
  292. package/transpiled/directives/io/index.js.map +1 -0
  293. package/transpiled/directives/io/schemas.d.ts +7 -0
  294. package/transpiled/directives/io/schemas.js +14 -0
  295. package/transpiled/directives/io/schemas.js.map +1 -0
  296. package/transpiled/directives/octets/Context.d.ts +4 -4
  297. package/transpiled/directives/octets/Context.js +4 -2
  298. package/transpiled/directives/octets/Context.js.map +1 -1
  299. package/transpiled/directives/octets/Delete.d.ts +5 -4
  300. package/transpiled/directives/octets/Delete.js +24 -12
  301. package/transpiled/directives/octets/Delete.js.map +1 -1
  302. package/transpiled/directives/octets/Directive.d.ts +8 -0
  303. package/transpiled/directives/octets/Directive.js +8 -0
  304. package/transpiled/directives/octets/Directive.js.map +1 -0
  305. package/transpiled/directives/octets/Fetch.d.ts +4 -3
  306. package/transpiled/directives/octets/Fetch.js +31 -15
  307. package/transpiled/directives/octets/Fetch.js.map +1 -1
  308. package/transpiled/directives/octets/List.d.ts +4 -3
  309. package/transpiled/directives/octets/List.js +16 -7
  310. package/transpiled/directives/octets/List.js.map +1 -1
  311. package/transpiled/directives/octets/Octets.d.ts +4 -4
  312. package/transpiled/directives/octets/Octets.js +8 -4
  313. package/transpiled/directives/octets/Octets.js.map +1 -1
  314. package/transpiled/directives/octets/Permute.d.ts +4 -3
  315. package/transpiled/directives/octets/Permute.js +14 -7
  316. package/transpiled/directives/octets/Permute.js.map +1 -1
  317. package/transpiled/directives/octets/Store.d.ts +6 -4
  318. package/transpiled/directives/octets/Store.js +28 -13
  319. package/transpiled/directives/octets/Store.js.map +1 -1
  320. package/transpiled/directives/octets/Workflow.d.ts +15 -0
  321. package/transpiled/directives/octets/Workflow.js +59 -0
  322. package/transpiled/directives/octets/Workflow.js.map +1 -0
  323. package/transpiled/directives/octets/schemas.d.ts +2 -0
  324. package/transpiled/directives/octets/schemas.js +2 -1
  325. package/transpiled/directives/octets/schemas.js.map +1 -1
  326. package/transpiled/directives/octets/types.d.ts +0 -5
  327. package/transpiled/directives/octets/{workflow → workflows}/Execution.js +0 -1
  328. package/transpiled/directives/octets/workflows/Execution.js.map +1 -0
  329. package/transpiled/directives/octets/{workflow → workflows}/Workflow.d.ts +1 -1
  330. package/transpiled/directives/octets/{workflow → workflows}/Workflow.js +2 -2
  331. package/transpiled/directives/octets/workflows/Workflow.js.map +1 -0
  332. package/transpiled/directives/octets/workflows/index.js.map +1 -0
  333. package/transpiled/directives/require/Directive.d.ts +4 -0
  334. package/transpiled/directives/require/Directive.js +3 -0
  335. package/transpiled/directives/require/Directive.js.map +1 -0
  336. package/transpiled/directives/require/Headers.d.ts +7 -0
  337. package/transpiled/directives/require/Headers.js +19 -0
  338. package/transpiled/directives/require/Headers.js.map +1 -0
  339. package/transpiled/directives/require/Require.d.ts +9 -0
  340. package/transpiled/directives/require/Require.js +27 -0
  341. package/transpiled/directives/require/Require.js.map +1 -0
  342. package/transpiled/directives/require/index.d.ts +2 -0
  343. package/transpiled/directives/require/index.js +6 -0
  344. package/transpiled/directives/require/index.js.map +1 -0
  345. package/transpiled/directives/vary/Directive.d.ts +2 -1
  346. package/transpiled/directives/vary/Embed.d.ts +2 -1
  347. package/transpiled/directives/vary/Embed.js +8 -6
  348. package/transpiled/directives/vary/Embed.js.map +1 -1
  349. package/transpiled/directives/vary/Vary.d.ts +3 -3
  350. package/transpiled/directives/vary/Vary.js +4 -4
  351. package/transpiled/directives/vary/Vary.js.map +1 -1
  352. package/transpiled/directives/vary/embeddings/Embedding.d.ts +2 -1
  353. package/transpiled/directives/vary/embeddings/Header.js +9 -7
  354. package/transpiled/directives/vary/embeddings/Header.js.map +1 -1
  355. package/transpiled/directives/vary/embeddings/Language.js +2 -2
  356. package/transpiled/directives/vary/embeddings/Language.js.map +1 -1
  357. package/transpiled/directives/vary/embeddings/Parameter.d.ts +7 -0
  358. package/transpiled/directives/vary/embeddings/Parameter.js +14 -0
  359. package/transpiled/directives/vary/embeddings/Parameter.js.map +1 -0
  360. package/transpiled/directives/vary/embeddings/index.d.ts +2 -2
  361. package/transpiled/directives/vary/embeddings/index.js +5 -3
  362. package/transpiled/directives/vary/embeddings/index.js.map +1 -1
  363. package/transpiled/exceptions.d.ts +3 -2
  364. package/transpiled/exceptions.js +13 -7
  365. package/transpiled/exceptions.js.map +1 -1
  366. package/transpiled/io.d.ts +2 -2
  367. package/transpiled/root.js +5 -0
  368. package/transpiled/root.js.map +1 -1
  369. package/transpiled/tsconfig.tsbuildinfo +1 -1
  370. package/components/identity.federation/operations/assertions-as-values.cjs.map +0 -1
  371. package/components/identity.federation/operations/jwt.cjs.map +0 -1
  372. package/source/HTTP/Server.fixtures.ts +0 -40
  373. package/transpiled/HTTP/Server.fixtures.d.ts +0 -10
  374. package/transpiled/HTTP/Server.fixtures.js +0 -31
  375. package/transpiled/HTTP/Server.fixtures.js.map +0 -1
  376. package/transpiled/directives/octets/workflow/Execution.js.map +0 -1
  377. package/transpiled/directives/octets/workflow/Workflow.js.map +0 -1
  378. package/transpiled/directives/octets/workflow/index.js.map +0 -1
  379. /package/components/identity.federation/operations/{assertions-as-values.d.cts → lib/assertions-as-values.d.ts} +0 -0
  380. /package/source/directives/octets/{workflow → workflows}/index.ts +0 -0
  381. /package/transpiled/directives/octets/{workflow → workflows}/Execution.d.ts +0 -0
  382. /package/transpiled/directives/octets/{workflow → workflows}/index.d.ts +0 -0
  383. /package/transpiled/directives/octets/{workflow → workflows}/index.js +0 -0
@@ -1,17 +1,18 @@
1
1
  import { Readable } from 'stream'
2
2
  import { NotFound } from '../../HTTP'
3
3
  import * as schemas from './schemas'
4
- import { Workflow } from './workflow'
4
+ import { Workflow } from './workflows'
5
+ import { Directive } from './Directive'
5
6
  import type { Parameter } from '../../RTD'
6
- import type { Unit } from './workflow'
7
+ import type { Unit } from './workflows'
7
8
  import type { Maybe } from '@toa.io/types'
8
9
  import type { Component } from '@toa.io/core'
9
10
  import type { Output } from '../../io'
10
- import type { Directive, Input } from './types'
11
+ import type { Input } from './types'
11
12
  import type { Remotes } from '../../Remotes'
12
13
  import type { Entry } from '@toa.io/extensions.storages'
13
14
 
14
- export class Delete implements Directive {
15
+ export class Delete extends Directive {
15
16
  public readonly targeted = true
16
17
 
17
18
  private readonly workflow?: Workflow
@@ -19,6 +20,7 @@ export class Delete implements Directive {
19
20
  private storage: Component | null = null
20
21
 
21
22
  public constructor (options: Options | null, discovery: Promise<Component>, remotes: Remotes) {
23
+ super()
22
24
  schemas.remove.validate(options)
23
25
 
24
26
  if (options?.workflow !== undefined)
@@ -27,11 +29,16 @@ export class Delete implements Directive {
27
29
  this.discovery = discovery
28
30
  }
29
31
 
30
- public async apply (storage: string, request: Input, parameters: Parameter[]): Promise<Output> {
32
+ public async apply (storage: string, input: Input, parameters: Parameter[]): Promise<Output> {
31
33
  this.storage ??= await this.discovery
32
34
 
33
35
  const entry = await this.storage.invoke<Maybe<Entry>>('get',
34
- { input: { storage, path: request.url } })
36
+ {
37
+ input: {
38
+ storage,
39
+ path: input.request.url
40
+ }
41
+ })
35
42
 
36
43
  if (entry instanceof Error)
37
44
  throw new NotFound()
@@ -40,31 +47,36 @@ export class Delete implements Directive {
40
47
 
41
48
  if (this.workflow !== undefined) {
42
49
  output.status = 202
43
- output.body = Readable.from(this.execute(request, storage, entry, parameters))
50
+ output.body = Readable.from(this.execute(input, storage, entry, parameters))
44
51
  } else
45
- await this.delete(storage, request)
52
+ await this.delete(storage, input)
46
53
 
47
54
  return output
48
55
  }
49
56
 
50
- private async delete (storage: string, request: Input): Promise<void> {
57
+ private async delete (storage: string, input: Input): Promise<void> {
51
58
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
52
59
  await this.storage!.invoke('delete',
53
- { input: { storage, path: request.url } })
60
+ {
61
+ input: {
62
+ storage,
63
+ path: input.request.url
64
+ }
65
+ })
54
66
  }
55
67
 
56
68
  // eslint-disable-next-line max-params
57
69
  private async * execute
58
- (request: Input, storage: string, entry: Entry, parameters: Parameter[]): AsyncGenerator {
70
+ (input: Input, storage: string, entry: Entry, parameters: Parameter[]): AsyncGenerator {
59
71
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
60
- for await (const chunk of this.workflow!.execute(request, storage, entry, parameters)) {
72
+ for await (const chunk of this.workflow!.execute(input, storage, entry, parameters)) {
61
73
  yield chunk
62
74
 
63
75
  if (typeof chunk === 'object' && chunk !== null && 'error' in chunk)
64
76
  return
65
77
  }
66
78
 
67
- await this.delete(storage, request)
79
+ await this.delete(storage, input)
68
80
  }
69
81
  }
70
82
 
@@ -0,0 +1,10 @@
1
+ import type { Input } from './types'
2
+ import type { Parameter } from '../../RTD'
3
+ import type * as io from '../../io'
4
+
5
+ export abstract class Directive {
6
+ public readonly name = 'octets.' + this.constructor.name.toLowerCase()
7
+ public abstract readonly targeted: boolean
8
+
9
+ public abstract apply (storage: string, input: Input, parameters: Parameter[]): Promise<io.Output>
10
+ }
@@ -1,52 +1,61 @@
1
1
  import { posix } from 'node:path'
2
2
  import { Forbidden, NotFound } from '../../HTTP'
3
3
  import * as schemas from './schemas'
4
+ import { Directive } from './Directive'
4
5
  import type { Maybe } from '@toa.io/types'
5
6
  import type { Entry } from '@toa.io/extensions.storages'
6
7
  import type { Readable } from 'node:stream'
7
8
  import type { Component } from '@toa.io/core'
8
9
  import type { Output } from '../../io'
10
+ import type { Input } from './types'
9
11
 
10
- import type { Directive, Input } from './types'
11
-
12
- export class Fetch implements Directive {
12
+ export class Fetch extends Directive {
13
13
  public readonly targeted = true
14
14
 
15
- private readonly permissions: Required<Permissions> = { blob: true, meta: false }
15
+ private readonly permissions: Required<Permissions> = {
16
+ blob: true,
17
+ meta: false
18
+ }
19
+
16
20
  private readonly discovery: Promise<Component>
17
21
  private storage: Component = null as unknown as Component
18
22
 
19
23
  public constructor (permissions: Permissions | null, discovery: Promise<Component>) {
24
+ super()
20
25
  schemas.fetch.validate(permissions)
21
26
 
22
27
  Object.assign(this.permissions, permissions)
23
28
  this.discovery = discovery
24
29
  }
25
30
 
26
- public async apply (storage: string, request: Input): Promise<Output> {
31
+ public async apply (storage: string, input: Input): Promise<Output> {
27
32
  this.storage ??= await this.discovery
28
33
 
29
- const variant = posix.basename(request.url).includes('.')
30
- const metadata = request.subtype === 'octets.entry'
34
+ const variant = posix.basename(input.request.url).includes('.')
35
+ const metadata = input.subtype === 'octets.entry'
31
36
 
32
37
  if (!variant && metadata)
33
38
  if (this.permissions.meta)
34
- return this.get(storage, request)
39
+ return this.get(storage, input)
35
40
  else
36
41
  throw new Forbidden('Metadata is not accessible.')
37
42
 
38
43
  if (!variant && !this.permissions.blob)
39
44
  throw new Forbidden('BLOB variant must be specified.')
40
45
 
41
- return await this.fetch(storage, request)
46
+ return await this.fetch(storage, input)
42
47
  }
43
48
 
44
- private async fetch (storage: string, request: Input): Promise<Output> {
45
- if ('if-none-match' in request.headers)
49
+ private async fetch (storage: string, input: Input): Promise<Output> {
50
+ if ('if-none-match' in input.request.headers)
46
51
  return { status: 304 }
47
52
 
48
- const input = { storage, path: request.url }
49
- const result = await this.storage.invoke<Maybe<FetchResult>>('fetch', { input })
53
+ const result = await this.storage.invoke<Maybe<FetchResult>>('fetch', {
54
+ input: {
55
+ storage,
56
+ path: input.request.url
57
+ }
58
+ })
50
59
 
51
60
  if (result instanceof Error)
52
61
  throw new NotFound()
@@ -57,12 +66,19 @@ export class Fetch implements Directive {
57
66
  etag: result.checksum
58
67
  })
59
68
 
60
- return { headers, body: result.stream }
69
+ return {
70
+ headers,
71
+ body: result.stream
72
+ }
61
73
  }
62
74
 
63
- private async get (storage: string, request: Input): Promise<Output> {
64
- const input = { storage, path: request.url }
65
- const entry = await this.storage.invoke<Maybe<Entry>>('get', { input })
75
+ private async get (storage: string, input: Input): Promise<Output> {
76
+ const entry = await this.storage.invoke<Maybe<Entry>>('get', {
77
+ input: {
78
+ storage,
79
+ path: input.request.url
80
+ }
81
+ })
66
82
 
67
83
  if (entry instanceof Error)
68
84
  throw new NotFound()
@@ -1,14 +1,15 @@
1
1
  import { posix } from 'node:path'
2
2
  import { Forbidden, NotFound } from '../../HTTP'
3
3
  import * as schemas from './schemas'
4
+ import { Directive } from './Directive'
4
5
  import type { Entry } from '@toa.io/extensions.storages'
5
6
  import type { Maybe } from '@toa.io/types'
6
7
  import type { Component } from '@toa.io/core'
7
8
  import type { Output } from '../../io'
8
9
 
9
- import type { Directive, Input } from './types'
10
+ import type { Input } from './types'
10
11
 
11
- export class List implements Directive {
12
+ export class List extends Directive {
12
13
  public readonly targeted = false
13
14
 
14
15
  private readonly permissions: Required<Permissions> = { meta: false }
@@ -16,28 +17,33 @@ export class List implements Directive {
16
17
  private storage: Component | null = null
17
18
 
18
19
  public constructor (permissions: Permissions | null, discovery: Promise<Component>) {
20
+ super()
19
21
  schemas.list.validate(permissions)
20
22
 
21
23
  Object.assign(this.permissions, permissions)
22
24
  this.discovery = discovery
23
25
  }
24
26
 
25
- public async apply (storage: string, request: Input): Promise<Output> {
27
+ public async apply (storage: string, input: Input): Promise<Output> {
26
28
  this.storage ??= await this.discovery
27
29
 
28
- const metadata = request.subtype === 'octets.entries'
30
+ const metadata = input.subtype === 'octets.entries'
29
31
 
30
32
  if (metadata && !this.permissions.meta)
31
33
  throw new Forbidden('Metadata is not accessible.')
32
34
 
33
- const input = { storage, path: request.url }
34
- const list = await this.storage.invoke<Maybe<string[]>>('list', { input })
35
+ const list = await this.storage.invoke<Maybe<string[]>>('list', {
36
+ input: {
37
+ storage,
38
+ path: input.request.url
39
+ }
40
+ })
35
41
 
36
42
  if (list instanceof Error)
37
43
  throw new NotFound()
38
44
 
39
45
  const body = metadata
40
- ? await this.expand(storage, request.url, list)
46
+ ? await this.expand(storage, input.request.url, list)
41
47
  : list
42
48
 
43
49
  return { body }
@@ -47,7 +53,11 @@ export class List implements Directive {
47
53
  Promise<Array<Maybe<Entry>>> {
48
54
  const promises = list.map(async (id) => {
49
55
  const path = posix.join(prefix, id)
50
- const input = { storage, path }
56
+
57
+ const input = {
58
+ storage,
59
+ path
60
+ }
51
61
 
52
62
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- ensured in `apply`
53
63
  return this.storage!.invoke<Maybe<Entry>>('get', { input })
@@ -5,14 +5,15 @@ import { Fetch } from './Fetch'
5
5
  import { List } from './List'
6
6
  import { Delete } from './Delete'
7
7
  import { Permute } from './Permute'
8
+ import { WorkflowDirective } from './Workflow'
9
+ import type { Directive } from './Directive'
8
10
  import type { Output } from '../../io'
9
11
  import type { Component } from '@toa.io/core'
10
12
  import type { Remotes } from '../../Remotes'
11
- import type { Family } from '../../Directive'
12
- import type { Directive, Input } from './types'
13
- import type { Parameter } from '../../RTD'
13
+ import type { Parameter, DirectiveFamily } from '../../RTD'
14
+ import type { Input } from './types'
14
15
 
15
- export class Octets implements Family<Directive> {
16
+ export class Octets implements DirectiveFamily<Directive> {
16
17
  public readonly name: string = 'octets'
17
18
  public readonly mandatory: boolean = false
18
19
 
@@ -22,7 +23,7 @@ export class Octets implements Family<Directive> {
22
23
  const Class = DIRECTIVES[name]
23
24
 
24
25
  if (Class === undefined)
25
- throw new Error(`Directive '${name}' is not provided by the '${this.name}' family.`)
26
+ throw new Error(`Directive 'octets:${name}' is not implemented.`)
26
27
 
27
28
  this.discovery ??= remotes.discover('octets', 'storage')
28
29
 
@@ -45,15 +46,17 @@ export class Octets implements Family<Directive> {
45
46
  if (action === null)
46
47
  return null
47
48
 
49
+ // noinspection PointlessBooleanExpressionJS
48
50
  if (context === null)
49
51
  throw new Error('Octets context is not defined.')
50
52
 
51
- const targeted = input.path[input.path.length - 1] !== '/'
53
+ const targeted = input.request.url[input.request.url.length - 1] !== '/'
52
54
 
53
55
  if (targeted !== action.targeted)
54
56
  throw new NotFound(`Trailing slash is ${action.targeted ? 'redundant' : 'required'}.`)
55
57
 
56
- return await action.apply(context.storage, input, parameters)
58
+ // noinspection JSObjectNullOrUndefined
59
+ return await input.timing.capture(action.name, action.apply(context.storage, input, parameters))
57
60
  }
58
61
  }
59
62
 
@@ -63,7 +66,8 @@ const DIRECTIVES: Record<string, Constructor> = {
63
66
  fetch: Fetch,
64
67
  list: List,
65
68
  delete: Delete,
66
- permute: Permute
69
+ permute: Permute,
70
+ workflow: WorkflowDirective
67
71
  }
68
72
 
69
73
  type Constructor = new (value: any, discovery: Promise<Component>, remotes: Remotes) => Directive
@@ -1,33 +1,40 @@
1
1
  import { NotAcceptable, NotFound } from '../../HTTP'
2
2
  import * as schemas from './schemas'
3
+ import { Directive } from './Directive'
3
4
  import type { Maybe } from '@toa.io/types'
4
5
  import type { Component } from '@toa.io/core'
5
6
  import type { Output } from '../../io'
7
+ import type { Input } from './types'
6
8
 
7
- import type { Directive, Input } from './types'
8
-
9
- export class Permute implements Directive {
9
+ export class Permute extends Directive {
10
10
  public readonly targeted = false
11
11
 
12
12
  private readonly discovery: Promise<Component>
13
13
  private storage: Component | null = null
14
14
 
15
15
  public constructor (value: null, discovery: Promise<Component>) {
16
+ super()
16
17
  schemas.permute.validate(value)
17
18
 
18
19
  this.discovery = discovery
19
20
  }
20
21
 
21
- public async apply (storage: string, request: Input): Promise<Output> {
22
+ public async apply (storage: string, input: Input): Promise<Output> {
22
23
  this.storage ??= await this.discovery
23
24
 
24
- if (request.encoder === null)
25
+ if (input.encoder === null)
25
26
  throw new NotAcceptable()
26
27
 
27
- const path = request.url
28
- const list = await request.parse()
29
- const input = { storage, path, list }
30
- const error = await this.storage.invoke<Maybe<unknown>>('permute', { input })
28
+ const path = input.request.url
29
+ const list = await input.body()
30
+
31
+ const error = await this.storage.invoke<Maybe<unknown>>('permute', {
32
+ input: {
33
+ storage,
34
+ path,
35
+ list
36
+ }
37
+ })
31
38
 
32
39
  if (error instanceof Error)
33
40
  throw new NotFound()
@@ -1,18 +1,21 @@
1
+ import { PassThrough } from 'node:stream'
1
2
  import { match } from 'matchacho'
2
3
  import { BadRequest, UnsupportedMediaType } from '../../HTTP'
3
4
  import { cors } from '../cors'
4
5
  import * as schemas from './schemas'
5
- import { Workflow } from './workflow'
6
+ import { Workflow } from './workflows'
7
+ import { Directive } from './Directive'
8
+ import type { Readable } from 'stream'
6
9
  import type { Parameter } from '../../RTD'
7
- import type { Unit } from './workflow'
10
+ import type { Unit } from './workflows'
8
11
  import type { Entry } from '@toa.io/extensions.storages'
9
12
  import type { Remotes } from '../../Remotes'
10
13
  import type { ErrorType } from 'error-value'
11
14
  import type { Component } from '@toa.io/core'
12
15
  import type { Output } from '../../io'
13
- import type { Directive, Input } from './types'
16
+ import type { Input } from './types'
14
17
 
15
- export class Store implements Directive {
18
+ export class Store extends Directive {
16
19
  public readonly targeted = false
17
20
 
18
21
  private readonly accept?: string
@@ -22,6 +25,7 @@ export class Store implements Directive {
22
25
 
23
26
  public constructor
24
27
  (options: Options | null, discovery: Promise<Component>, remotes: Remotes) {
28
+ super()
25
29
  schemas.store.validate(options)
26
30
 
27
31
  this.accept = match(options?.accept,
@@ -34,37 +38,55 @@ export class Store implements Directive {
34
38
 
35
39
  this.discovery.storage = discovery
36
40
 
37
- cors.allowHeader('content-meta')
41
+ cors.allow('content-meta')
38
42
  }
39
43
 
40
- public async apply (storage: string, request: Input, parameters: Parameter[]): Promise<Output> {
44
+ public async apply (storage: string, input: Input, parameters: Parameter[]): Promise<Output> {
41
45
  this.storage ??= await this.discovery.storage
42
46
 
43
- const input: StoreInput = { storage, request }
44
- const meta = request.headers['content-meta']
47
+ const request: StoreRequest = {
48
+ input: {
49
+ storage,
50
+ request: input.request
51
+ }
52
+ }
53
+
54
+ const meta = input.request.headers['content-meta']
45
55
 
46
56
  if (this.accept !== undefined)
47
- input.accept = this.accept
57
+ request.input.accept = this.accept
48
58
 
49
59
  if (meta !== undefined)
50
- input.meta = this.parseMeta(meta)
60
+ request.input.meta = this.parseMeta(meta)
51
61
 
52
- const entry = await this.storage.invoke<Entry>('store', { input })
62
+ const entry = await this.storage.invoke<Entry>('store', request)
53
63
 
54
64
  return match<Output>(entry,
55
65
  Error, (error: ErrorType) => this.throw(error),
56
- () => this.reply(request, storage, entry, parameters))
66
+ () => this.reply(input, storage, entry, parameters))
57
67
  }
58
68
 
59
69
  // eslint-disable-next-line max-params
60
- private reply (request: Input, storage: string, entry: Entry, parameters: Parameter[]): Output {
70
+ private reply (input: Input, storage: string, entry: Entry, parameters: Parameter[]): Output {
61
71
  const body = this.workflow === undefined
62
72
  ? entry
63
- : this.workflow.execute(request, storage, entry, parameters)
73
+ : this.execute(input, storage, entry, parameters)
64
74
 
65
75
  return { body }
66
76
  }
67
77
 
78
+ // eslint-disable-next-line max-params
79
+ private execute
80
+ (input: Input, storage: string, entry: Entry, parameters: Parameter[]): Readable {
81
+ const stream = new PassThrough({ objectMode: true })
82
+
83
+ stream.push(entry)
84
+
85
+ this.workflow!.execute(input, storage, entry, parameters).pipe(stream)
86
+
87
+ return stream
88
+ }
89
+
68
90
  private throw (error: ErrorType): never {
69
91
  throw match(error.code,
70
92
  'NOT_ACCEPTABLE', () => new UnsupportedMediaType(),
@@ -94,9 +116,11 @@ export interface Options {
94
116
  workflow?: Unit[] | Unit
95
117
  }
96
118
 
97
- interface StoreInput {
98
- storage: string
99
- request: Input
100
- accept?: string
101
- meta?: Record<string, string>
119
+ interface StoreRequest {
120
+ input: {
121
+ storage: string
122
+ request: Input['request']
123
+ accept?: string
124
+ meta?: Record<string, string>
125
+ }
102
126
  }
@@ -0,0 +1,48 @@
1
+ import { NotFound } from '../../HTTP'
2
+ import * as schemas from './schemas'
3
+ import { Workflow } from './workflows'
4
+ import { Directive } from './Directive'
5
+ import type { Unit } from './workflows'
6
+ import type { Input } from './types'
7
+ import type { Component } from '@toa.io/core'
8
+ import type { Output } from '../../io'
9
+ import type { Remotes } from '../../Remotes'
10
+ import type { Maybe } from '@toa.io/types'
11
+ import type { Entry } from '@toa.io/extensions.storages'
12
+ import type { Parameter } from '../../RTD'
13
+
14
+ export class WorkflowDirective extends Directive {
15
+ public readonly targeted = true
16
+
17
+ private readonly workflow: Workflow
18
+ private readonly discovery: Promise<Component>
19
+ private storage: Component | null = null
20
+
21
+ public constructor (units: Unit[] | Unit, discovery: Promise<Component>, remotes: Remotes) {
22
+ super()
23
+ schemas.workflow.validate(units)
24
+
25
+ this.workflow = new Workflow(units, remotes)
26
+ this.discovery = discovery
27
+ }
28
+
29
+ public async apply (storage: string, input: Input, parameters: Parameter[]): Promise<Output> {
30
+ this.storage ??= await this.discovery
31
+
32
+ const entry = await this.storage.invoke<Maybe<Entry>>('get',
33
+ {
34
+ input: {
35
+ storage,
36
+ path: input.request.url
37
+ }
38
+ })
39
+
40
+ if (entry instanceof Error)
41
+ throw new NotFound()
42
+
43
+ return {
44
+ status: 202,
45
+ body: this.workflow.execute(input, storage, entry, parameters)
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,21 @@
1
+ import * as schemas from './schemas'
2
+
3
+ describe('workflow', () => {
4
+ const ok = [
5
+ { echo: 'hello world' },
6
+ [{ echo: 'hello world' }, { ok: 'ok' }]
7
+ ]
8
+
9
+ const oh = [
10
+ { echo: [] },
11
+ { echo: 'hello world', ok: { not: 'ok' } }
12
+ ]
13
+
14
+ it.each(ok)('should be valid', (workflow) => {
15
+ expect(() => schemas.workflow.validate(workflow)).not.toThrow()
16
+ })
17
+
18
+ it.each(oh)('should not be valid', (workflow) => {
19
+ expect(() => schemas.workflow.validate(workflow)).toThrow()
20
+ })
21
+ })
@@ -5,6 +5,7 @@ import type { Permissions as ListPermissions } from './List'
5
5
  import type { Options as StoreOptions } from './Store'
6
6
  import type { Options as DeleteOptions } from './Delete'
7
7
  import type { Schema } from '@toa.io/schemas'
8
+ import type { Unit } from './workflows'
8
9
 
9
10
  const path = resolve(__dirname, '../../../schemas/octets')
10
11
  const namespace = schemas.namespace(path)
@@ -15,3 +16,4 @@ export const fetch: Schema<FetchPermissions | null> = namespace.schema('fetch')
15
16
  export const remove: Schema<DeleteOptions | null> = namespace.schema('delete')
16
17
  export const list: Schema<ListPermissions | null> = namespace.schema('list')
17
18
  export const permute: Schema<null> = namespace.schema('permute')
19
+ export const workflow: Schema<Unit[] | Unit> = namespace.schema('workflow')
@@ -1,12 +1,5 @@
1
- import type { Parameter } from '../../RTD'
2
1
  import type * as io from '../../io'
3
2
 
4
- export interface Directive {
5
- readonly targeted: boolean
6
-
7
- apply: (storage: string, input: Input, parameters: Parameter[]) => io.Output | Promise<io.Output>
8
- }
9
-
10
3
  export interface Extension {
11
4
  octets?: string
12
5
  }
@@ -27,8 +27,6 @@ export class Execution extends Readable {
27
27
  }
28
28
 
29
29
  private async run (): Promise<void> {
30
- this.push(this.context.entry)
31
-
32
30
  for (const unit of this.units) {
33
31
  await this.execute(unit)
34
32
 
@@ -21,8 +21,8 @@ export class Workflow {
21
21
 
22
22
  // eslint-disable-next-line max-params
23
23
  public execute
24
- (request: Input, storage: string, entry: Entry, params: Parameter[]): Execution {
25
- const path = posix.join(request.path, entry.id)
24
+ (input: Input, storage: string, entry: Entry, params: Parameter[]): Execution {
25
+ const path = posix.join(input.request.url, entry.id)
26
26
  const parameters: Record<string, string> = {}
27
27
 
28
28
  for (const { name, value } of params)
@@ -0,0 +1,5 @@
1
+ import type { Input } from '../../io'
2
+
3
+ export interface Directive {
4
+ preflight: (context: Input) => void
5
+ }
@@ -0,0 +1,20 @@
1
+ import { BadRequest } from '../../HTTP'
2
+ import type { Input } from '../../io'
3
+ import type { Directive } from './Directive'
4
+
5
+ export class Headers implements Directive {
6
+ private readonly headers: string[]
7
+
8
+ public constructor (headers: string[]) {
9
+ if (!Array.isArray(headers))
10
+ headers = [headers]
11
+
12
+ this.headers = headers
13
+ }
14
+
15
+ public preflight (context: Input): void {
16
+ for (const header of this.headers)
17
+ if (context.request.headers[header] === undefined)
18
+ throw new BadRequest(`Header required: ${header}`)
19
+ }
20
+ }