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

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 (442) hide show
  1. package/components/context.toa.yaml +12 -0
  2. package/components/identity.bans/manifest.toa.yaml +1 -1
  3. package/components/identity.basic/manifest.toa.yaml +2 -2
  4. package/components/identity.basic/operations/authenticate.d.ts +9 -0
  5. package/components/identity.basic/operations/authenticate.js +24 -0
  6. package/components/identity.basic/operations/authenticate.js.map +1 -0
  7. package/components/identity.basic/operations/create.d.ts +10 -0
  8. package/components/identity.basic/operations/create.js +10 -0
  9. package/components/identity.basic/operations/create.js.map +1 -0
  10. package/components/identity.basic/operations/transit.d.ts +12 -0
  11. package/components/identity.basic/operations/transit.js +53 -0
  12. package/components/identity.basic/operations/transit.js.map +1 -0
  13. package/components/identity.basic/operations/tsconfig.tsbuildinfo +1 -0
  14. package/components/identity.basic/operations/types.d.ts +38 -0
  15. package/components/identity.basic/operations/types.js +3 -0
  16. package/components/identity.basic/operations/types.js.map +1 -0
  17. package/components/identity.basic/source/authenticate.ts +0 -1
  18. package/components/identity.federation/events/principal.js +22 -0
  19. package/components/identity.federation/manifest.toa.yaml +88 -0
  20. package/components/identity.federation/operations/assertions-as-values.cjs +45 -0
  21. package/components/identity.federation/operations/assertions-as-values.cjs.map +1 -0
  22. package/components/identity.federation/operations/assertions-as-values.d.cts +4 -0
  23. package/components/identity.federation/operations/authenticate.d.ts +3 -0
  24. package/components/identity.federation/operations/authenticate.js +20 -0
  25. package/components/identity.federation/operations/authenticate.js.map +1 -0
  26. package/components/identity.federation/operations/create.d.ts +10 -0
  27. package/components/identity.federation/operations/create.js +15 -0
  28. package/components/identity.federation/operations/create.js.map +1 -0
  29. package/components/identity.federation/operations/jwt.cjs +112 -0
  30. package/components/identity.federation/operations/jwt.cjs.map +1 -0
  31. package/components/identity.federation/operations/jwt.d.cts +19 -0
  32. package/components/identity.federation/operations/schemas.d.ts +43 -0
  33. package/components/identity.federation/operations/schemas.js +9 -0
  34. package/components/identity.federation/operations/schemas.js.map +1 -0
  35. package/components/identity.federation/operations/tsconfig.tsbuildinfo +1 -0
  36. package/components/identity.federation/operations/types.d.ts +51 -0
  37. package/components/identity.federation/operations/types.js +3 -0
  38. package/components/identity.federation/operations/types.js.map +1 -0
  39. package/components/identity.federation/source/assertions-as-values.cts +20 -0
  40. package/components/identity.federation/source/authenticate.ts +28 -0
  41. package/components/identity.federation/source/create.ts +26 -0
  42. package/components/identity.federation/source/jwt.cts +143 -0
  43. package/components/identity.federation/source/schemas.ts +45 -0
  44. package/components/identity.federation/source/types.ts +56 -0
  45. package/components/identity.federation/tsconfig.json +9 -0
  46. package/components/identity.roles/operations/list.d.ts +5 -0
  47. package/components/identity.roles/operations/list.js +8 -0
  48. package/components/identity.roles/operations/list.js.map +1 -0
  49. package/components/identity.roles/operations/principal.d.ts +15 -0
  50. package/components/identity.roles/operations/principal.js +8 -0
  51. package/components/identity.roles/operations/principal.js.map +1 -0
  52. package/components/identity.roles/operations/tsconfig.tsbuildinfo +1 -0
  53. package/components/identity.tokens/manifest.toa.yaml +1 -1
  54. package/components/identity.tokens/operations/authenticate.d.ts +9 -0
  55. package/components/identity.tokens/operations/authenticate.js +32 -0
  56. package/components/identity.tokens/operations/authenticate.js.map +1 -0
  57. package/components/identity.tokens/operations/decrypt.d.ts +3 -0
  58. package/components/identity.tokens/operations/decrypt.js +32 -0
  59. package/components/identity.tokens/operations/decrypt.js.map +1 -0
  60. package/components/identity.tokens/operations/encrypt.d.ts +8 -0
  61. package/components/identity.tokens/operations/encrypt.js +22 -0
  62. package/components/identity.tokens/operations/encrypt.js.map +1 -0
  63. package/components/identity.tokens/operations/revoke.d.ts +2 -0
  64. package/components/identity.tokens/operations/revoke.js +8 -0
  65. package/components/identity.tokens/operations/revoke.js.map +1 -0
  66. package/components/identity.tokens/operations/tsconfig.tsbuildinfo +1 -0
  67. package/components/identity.tokens/operations/types.d.ts +40 -0
  68. package/components/identity.tokens/operations/types.js +3 -0
  69. package/components/identity.tokens/operations/types.js.map +1 -0
  70. package/components/octets.storage/manifest.toa.yaml +1 -0
  71. package/components/octets.storage/operations/store.js +2 -2
  72. package/cucumber.js +0 -1
  73. package/documentation/components.md +25 -2
  74. package/documentation/identity.md +7 -7
  75. package/documentation/octets.md +93 -40
  76. package/documentation/protocol.md +21 -1
  77. package/documentation/query.md +1 -1
  78. package/documentation/vary.md +69 -0
  79. package/features/cors.feature +72 -0
  80. package/features/identity.feature +19 -3
  81. package/features/identity.federation.feature +125 -0
  82. package/features/octets.entries.feature +121 -0
  83. package/features/octets.feature +2 -28
  84. package/features/octets.meta.feature +65 -0
  85. package/features/octets.workflows.feature +138 -4
  86. package/features/response.feature +65 -0
  87. package/features/routes.feature +37 -0
  88. package/features/steps/Captures.ts +6 -0
  89. package/features/steps/Components.ts +18 -6
  90. package/features/steps/Gateway.ts +1 -2
  91. package/features/steps/HTTP.ts +40 -87
  92. package/features/steps/IdP.ts +120 -0
  93. package/features/steps/Parameters.ts +8 -2
  94. package/features/steps/Workspace.ts +5 -7
  95. package/features/steps/components/echo/operations/error.js +11 -0
  96. package/features/steps/components/octets.tester/manifest.toa.yaml +3 -0
  97. package/features/steps/components/octets.tester/operations/concat.js +7 -0
  98. package/features/steps/components/octets.tester/operations/echo.js +7 -0
  99. package/features/steps/components/users/manifest.toa.yaml +3 -0
  100. package/features/steps/components/users.properties/manifest.toa.yaml +13 -0
  101. package/features/steps/tsconfig.json +1 -1
  102. package/features/vary.feature +150 -0
  103. package/package.json +17 -18
  104. package/schemas/octets/delete.cos.yaml +2 -1
  105. package/schemas/octets/list.cos.yaml +2 -1
  106. package/source/Directive.test.ts +8 -2
  107. package/source/Directive.ts +19 -16
  108. package/source/Factory.ts +8 -7
  109. package/source/Gateway.ts +22 -8
  110. package/source/HTTP/Server.fixtures.ts +0 -1
  111. package/source/HTTP/Server.test.ts +61 -134
  112. package/source/HTTP/Server.ts +91 -47
  113. package/source/HTTP/formats/msgpack.ts +9 -6
  114. package/source/HTTP/formats/text.ts +1 -1
  115. package/source/HTTP/formats/yaml.ts +1 -1
  116. package/source/HTTP/messages.ts +15 -3
  117. package/source/Interception.ts +24 -0
  118. package/source/RTD/Directives.ts +2 -2
  119. package/source/RTD/Tree.ts +3 -0
  120. package/source/RTD/syntax/parse.ts +6 -6
  121. package/source/RTD/syntax/types.ts +1 -1
  122. package/source/deployment.ts +1 -2
  123. package/source/directives/auth/{Family.ts → Authorization.ts} +29 -33
  124. package/source/directives/auth/Incept.ts +1 -1
  125. package/source/directives/auth/Rule.ts +2 -2
  126. package/source/directives/auth/index.ts +2 -2
  127. package/source/directives/auth/schemes.ts +2 -1
  128. package/source/directives/auth/types.ts +9 -6
  129. package/source/directives/cache/{Family.ts → Cache.ts} +4 -5
  130. package/source/directives/cache/index.ts +2 -2
  131. package/source/directives/cache/types.ts +1 -1
  132. package/source/directives/cors/CORS.ts +54 -0
  133. package/source/directives/cors/index.ts +3 -0
  134. package/source/directives/dev/{Family.ts → Development.ts} +3 -4
  135. package/source/directives/dev/Stub.ts +4 -4
  136. package/source/directives/dev/Throw.ts +4 -4
  137. package/source/directives/dev/index.ts +2 -2
  138. package/source/directives/dev/types.ts +1 -1
  139. package/source/directives/index.ts +10 -6
  140. package/source/directives/octets/Context.ts +1 -1
  141. package/source/directives/octets/Delete.ts +50 -9
  142. package/source/directives/octets/Fetch.ts +18 -19
  143. package/source/directives/octets/List.ts +37 -7
  144. package/source/directives/octets/{Family.ts → Octets.ts} +7 -6
  145. package/source/directives/octets/Permute.ts +3 -3
  146. package/source/directives/octets/Store.ts +43 -99
  147. package/source/directives/octets/index.ts +2 -2
  148. package/source/directives/octets/schemas.ts +11 -6
  149. package/source/directives/octets/types.ts +4 -3
  150. package/source/directives/octets/workflow/Execution.ts +78 -0
  151. package/source/directives/octets/workflow/Workflow.ts +37 -0
  152. package/source/directives/octets/workflow/index.ts +1 -0
  153. package/source/directives/vary/Directive.ts +6 -0
  154. package/source/directives/vary/Embed.ts +62 -0
  155. package/source/directives/vary/Properties.ts +17 -0
  156. package/source/directives/vary/Vary.ts +48 -0
  157. package/source/directives/vary/embeddings/Embedding.ts +6 -0
  158. package/source/directives/vary/embeddings/Header.ts +30 -0
  159. package/source/directives/vary/embeddings/Language.ts +31 -0
  160. package/source/directives/vary/embeddings/index.ts +11 -0
  161. package/source/directives/vary/index.ts +3 -0
  162. package/source/io.ts +4 -0
  163. package/source/manifest.test.ts +6 -14
  164. package/source/manifest.ts +9 -6
  165. package/source/schemas.ts +7 -3
  166. package/transpiled/Annotation.d.ts +7 -0
  167. package/transpiled/Annotation.js +3 -0
  168. package/transpiled/Annotation.js.map +1 -0
  169. package/transpiled/Branch.d.ts +7 -0
  170. package/transpiled/Branch.js +3 -0
  171. package/transpiled/Branch.js.map +1 -0
  172. package/transpiled/Composition.d.ts +14 -0
  173. package/transpiled/Composition.js +43 -0
  174. package/transpiled/Composition.js.map +1 -0
  175. package/transpiled/Context.d.ts +5 -0
  176. package/transpiled/Context.js +3 -0
  177. package/transpiled/Context.js.map +1 -0
  178. package/transpiled/Directive.d.ts +31 -0
  179. package/transpiled/Directive.js +78 -0
  180. package/transpiled/Directive.js.map +1 -0
  181. package/transpiled/Endpoint.d.ts +20 -0
  182. package/transpiled/Endpoint.js +45 -0
  183. package/transpiled/Endpoint.js.map +1 -0
  184. package/transpiled/Factory.d.ts +9 -0
  185. package/transpiled/Factory.js +67 -0
  186. package/transpiled/Factory.js.map +1 -0
  187. package/transpiled/Gateway.d.ts +22 -0
  188. package/transpiled/Gateway.js +102 -0
  189. package/transpiled/Gateway.js.map +1 -0
  190. package/transpiled/HTTP/Server.d.ts +24 -0
  191. package/transpiled/HTTP/Server.fixtures.d.ts +10 -0
  192. package/transpiled/HTTP/Server.fixtures.js +31 -0
  193. package/transpiled/HTTP/Server.fixtures.js.map +1 -0
  194. package/transpiled/HTTP/Server.js +149 -0
  195. package/transpiled/HTTP/Server.js.map +1 -0
  196. package/transpiled/HTTP/exceptions.d.ts +34 -0
  197. package/transpiled/HTTP/exceptions.js +71 -0
  198. package/transpiled/HTTP/exceptions.js.map +1 -0
  199. package/transpiled/HTTP/formats/index.d.ts +10 -0
  200. package/transpiled/HTTP/formats/index.js +38 -0
  201. package/transpiled/HTTP/formats/index.js.map +1 -0
  202. package/transpiled/HTTP/formats/json.d.ts +6 -0
  203. package/transpiled/HTTP/formats/json.js +17 -0
  204. package/transpiled/HTTP/formats/json.js.map +1 -0
  205. package/transpiled/HTTP/formats/msgpack.d.ts +6 -0
  206. package/transpiled/HTTP/formats/msgpack.js +17 -0
  207. package/transpiled/HTTP/formats/msgpack.js.map +1 -0
  208. package/transpiled/HTTP/formats/text.d.ts +8 -0
  209. package/transpiled/HTTP/formats/text.js +15 -0
  210. package/transpiled/HTTP/formats/text.js.map +1 -0
  211. package/transpiled/HTTP/formats/yaml.d.ts +6 -0
  212. package/transpiled/HTTP/formats/yaml.js +41 -0
  213. package/transpiled/HTTP/formats/yaml.js.map +1 -0
  214. package/transpiled/HTTP/index.d.ts +3 -0
  215. package/transpiled/HTTP/index.js +20 -0
  216. package/transpiled/HTTP/index.js.map +1 -0
  217. package/transpiled/HTTP/messages.d.ts +33 -0
  218. package/transpiled/HTTP/messages.js +75 -0
  219. package/transpiled/HTTP/messages.js.map +1 -0
  220. package/transpiled/Interception.d.ts +9 -0
  221. package/transpiled/Interception.js +19 -0
  222. package/transpiled/Interception.js.map +1 -0
  223. package/transpiled/Mapping.d.ts +8 -0
  224. package/transpiled/Mapping.js +38 -0
  225. package/transpiled/Mapping.js.map +1 -0
  226. package/transpiled/Query.d.ts +13 -0
  227. package/transpiled/Query.js +107 -0
  228. package/transpiled/Query.js.map +1 -0
  229. package/transpiled/RTD/Context.d.ts +11 -0
  230. package/transpiled/RTD/Context.js +3 -0
  231. package/transpiled/RTD/Context.js.map +1 -0
  232. package/transpiled/RTD/Directives.d.ts +7 -0
  233. package/transpiled/RTD/Directives.js +3 -0
  234. package/transpiled/RTD/Directives.js.map +1 -0
  235. package/transpiled/RTD/Endpoint.d.ts +9 -0
  236. package/transpiled/RTD/Endpoint.js +3 -0
  237. package/transpiled/RTD/Endpoint.js.map +1 -0
  238. package/transpiled/RTD/Match.d.ts +11 -0
  239. package/transpiled/RTD/Match.js +3 -0
  240. package/transpiled/RTD/Match.js.map +1 -0
  241. package/transpiled/RTD/Method.d.ts +9 -0
  242. package/transpiled/RTD/Method.js +16 -0
  243. package/transpiled/RTD/Method.js.map +1 -0
  244. package/transpiled/RTD/Node.d.ts +21 -0
  245. package/transpiled/RTD/Node.js +61 -0
  246. package/transpiled/RTD/Node.js.map +1 -0
  247. package/transpiled/RTD/Route.d.ts +14 -0
  248. package/transpiled/RTD/Route.js +49 -0
  249. package/transpiled/RTD/Route.js.map +1 -0
  250. package/transpiled/RTD/Tree.d.ts +14 -0
  251. package/transpiled/RTD/Tree.js +42 -0
  252. package/transpiled/RTD/Tree.js.map +1 -0
  253. package/transpiled/RTD/factory.d.ts +6 -0
  254. package/transpiled/RTD/factory.js +36 -0
  255. package/transpiled/RTD/factory.js.map +1 -0
  256. package/transpiled/RTD/index.d.ts +8 -0
  257. package/transpiled/RTD/index.js +38 -0
  258. package/transpiled/RTD/index.js.map +1 -0
  259. package/transpiled/RTD/segment.d.ts +8 -0
  260. package/transpiled/RTD/segment.js +25 -0
  261. package/transpiled/RTD/segment.js.map +1 -0
  262. package/transpiled/RTD/syntax/index.d.ts +2 -0
  263. package/transpiled/RTD/syntax/index.js +19 -0
  264. package/transpiled/RTD/syntax/index.js.map +1 -0
  265. package/transpiled/RTD/syntax/parse.d.ts +4 -0
  266. package/transpiled/RTD/syntax/parse.js +128 -0
  267. package/transpiled/RTD/syntax/parse.js.map +1 -0
  268. package/transpiled/RTD/syntax/types.d.ts +41 -0
  269. package/transpiled/RTD/syntax/types.js +5 -0
  270. package/transpiled/RTD/syntax/types.js.map +1 -0
  271. package/transpiled/Remotes.d.ts +9 -0
  272. package/transpiled/Remotes.js +25 -0
  273. package/transpiled/Remotes.js.map +1 -0
  274. package/transpiled/Tenant.d.ts +13 -0
  275. package/transpiled/Tenant.js +34 -0
  276. package/transpiled/Tenant.js.map +1 -0
  277. package/transpiled/deployment.d.ts +3 -0
  278. package/transpiled/deployment.js +66 -0
  279. package/transpiled/deployment.js.map +1 -0
  280. package/transpiled/directives/auth/Anonymous.d.ts +6 -0
  281. package/transpiled/directives/auth/Anonymous.js +17 -0
  282. package/transpiled/directives/auth/Anonymous.js.map +1 -0
  283. package/transpiled/directives/auth/Authorization.d.ts +20 -0
  284. package/transpiled/directives/auth/Authorization.js +125 -0
  285. package/transpiled/directives/auth/Authorization.js.map +1 -0
  286. package/transpiled/directives/auth/Echo.d.ts +6 -0
  287. package/transpiled/directives/auth/Echo.js +13 -0
  288. package/transpiled/directives/auth/Echo.js.map +1 -0
  289. package/transpiled/directives/auth/Id.d.ts +7 -0
  290. package/transpiled/directives/auth/Id.js +17 -0
  291. package/transpiled/directives/auth/Id.js.map +1 -0
  292. package/transpiled/directives/auth/Incept.d.ts +10 -0
  293. package/transpiled/directives/auth/Incept.js +58 -0
  294. package/transpiled/directives/auth/Incept.js.map +1 -0
  295. package/transpiled/directives/auth/Role.d.ts +11 -0
  296. package/transpiled/directives/auth/Role.js +44 -0
  297. package/transpiled/directives/auth/Role.js.map +1 -0
  298. package/transpiled/directives/auth/Rule.d.ts +9 -0
  299. package/transpiled/directives/auth/Rule.js +22 -0
  300. package/transpiled/directives/auth/Rule.js.map +1 -0
  301. package/transpiled/directives/auth/Scheme.d.ts +7 -0
  302. package/transpiled/directives/auth/Scheme.js +47 -0
  303. package/transpiled/directives/auth/Scheme.js.map +1 -0
  304. package/transpiled/directives/auth/index.d.ts +2 -0
  305. package/transpiled/directives/auth/index.js +6 -0
  306. package/transpiled/directives/auth/index.js.map +1 -0
  307. package/transpiled/directives/auth/schemes.d.ts +3 -0
  308. package/transpiled/directives/auth/schemes.js +10 -0
  309. package/transpiled/directives/auth/schemes.js.map +1 -0
  310. package/transpiled/directives/auth/split.d.ts +2 -0
  311. package/transpiled/directives/auth/split.js +38 -0
  312. package/transpiled/directives/auth/split.js.map +1 -0
  313. package/transpiled/directives/auth/types.d.ts +31 -0
  314. package/transpiled/directives/auth/types.js +3 -0
  315. package/transpiled/directives/auth/types.js.map +1 -0
  316. package/transpiled/directives/cache/Cache.d.ts +11 -0
  317. package/transpiled/directives/cache/Cache.js +28 -0
  318. package/transpiled/directives/cache/Cache.js.map +1 -0
  319. package/transpiled/directives/cache/Control.d.ts +9 -0
  320. package/transpiled/directives/cache/Control.js +42 -0
  321. package/transpiled/directives/cache/Control.js.map +1 -0
  322. package/transpiled/directives/cache/Exact.d.ts +4 -0
  323. package/transpiled/directives/cache/Exact.js +11 -0
  324. package/transpiled/directives/cache/Exact.js.map +1 -0
  325. package/transpiled/directives/cache/index.d.ts +2 -0
  326. package/transpiled/directives/cache/index.js +6 -0
  327. package/transpiled/directives/cache/index.js.map +1 -0
  328. package/transpiled/directives/cache/types.d.ts +7 -0
  329. package/transpiled/directives/cache/types.js +3 -0
  330. package/transpiled/directives/cache/types.js.map +1 -0
  331. package/transpiled/directives/cors/CORS.d.ts +11 -0
  332. package/transpiled/directives/cors/CORS.js +44 -0
  333. package/transpiled/directives/cors/CORS.js.map +1 -0
  334. package/transpiled/directives/cors/index.d.ts +2 -0
  335. package/transpiled/directives/cors/index.js +6 -0
  336. package/transpiled/directives/cors/index.js.map +1 -0
  337. package/transpiled/directives/dev/Development.d.ts +9 -0
  338. package/transpiled/directives/dev/Development.js +29 -0
  339. package/transpiled/directives/dev/Development.js.map +1 -0
  340. package/transpiled/directives/dev/Stub.d.ts +7 -0
  341. package/transpiled/directives/dev/Stub.js +14 -0
  342. package/transpiled/directives/dev/Stub.js.map +1 -0
  343. package/transpiled/directives/dev/Throw.d.ts +7 -0
  344. package/transpiled/directives/dev/Throw.js +14 -0
  345. package/transpiled/directives/dev/Throw.js.map +1 -0
  346. package/transpiled/directives/dev/index.d.ts +2 -0
  347. package/transpiled/directives/dev/index.js +6 -0
  348. package/transpiled/directives/dev/index.js.map +1 -0
  349. package/transpiled/directives/dev/types.d.ts +4 -0
  350. package/transpiled/directives/dev/types.js +3 -0
  351. package/transpiled/directives/dev/types.js.map +1 -0
  352. package/transpiled/directives/index.d.ts +4 -0
  353. package/transpiled/directives/index.js +12 -0
  354. package/transpiled/directives/index.js.map +1 -0
  355. package/transpiled/directives/octets/Context.d.ts +8 -0
  356. package/transpiled/directives/octets/Context.js +40 -0
  357. package/transpiled/directives/octets/Context.js.map +1 -0
  358. package/transpiled/directives/octets/Delete.d.ts +19 -0
  359. package/transpiled/directives/octets/Delete.js +72 -0
  360. package/transpiled/directives/octets/Delete.js.map +1 -0
  361. package/transpiled/directives/octets/Fetch.d.ts +17 -0
  362. package/transpiled/directives/octets/Fetch.js +76 -0
  363. package/transpiled/directives/octets/Fetch.js.map +1 -0
  364. package/transpiled/directives/octets/List.d.ts +15 -0
  365. package/transpiled/directives/octets/List.js +65 -0
  366. package/transpiled/directives/octets/List.js.map +1 -0
  367. package/transpiled/directives/octets/Octets.d.ts +12 -0
  368. package/transpiled/directives/octets/Octets.js +51 -0
  369. package/transpiled/directives/octets/Octets.js.map +1 -0
  370. package/transpiled/directives/octets/Permute.d.ts +10 -0
  371. package/transpiled/directives/octets/Permute.js +51 -0
  372. package/transpiled/directives/octets/Permute.js.map +1 -0
  373. package/transpiled/directives/octets/Store.d.ts +22 -0
  374. package/transpiled/directives/octets/Store.js +80 -0
  375. package/transpiled/directives/octets/Store.js.map +1 -0
  376. package/transpiled/directives/octets/index.d.ts +2 -0
  377. package/transpiled/directives/octets/index.js +6 -0
  378. package/transpiled/directives/octets/index.js.map +1 -0
  379. package/transpiled/directives/octets/schemas.d.ts +11 -0
  380. package/transpiled/directives/octets/schemas.js +17 -0
  381. package/transpiled/directives/octets/schemas.js.map +1 -0
  382. package/transpiled/directives/octets/types.d.ts +10 -0
  383. package/transpiled/directives/octets/types.js +3 -0
  384. package/transpiled/directives/octets/types.js.map +1 -0
  385. package/transpiled/directives/octets/workflow/Execution.d.ts +25 -0
  386. package/transpiled/directives/octets/workflow/Execution.js +55 -0
  387. package/transpiled/directives/octets/workflow/Execution.js.map +1 -0
  388. package/transpiled/directives/octets/workflow/Workflow.d.ts +12 -0
  389. package/transpiled/directives/octets/workflow/Workflow.js +25 -0
  390. package/transpiled/directives/octets/workflow/Workflow.js.map +1 -0
  391. package/transpiled/directives/octets/workflow/index.d.ts +1 -0
  392. package/transpiled/directives/octets/workflow/index.js +6 -0
  393. package/transpiled/directives/octets/workflow/index.js.map +1 -0
  394. package/transpiled/directives/vary/Directive.d.ts +5 -0
  395. package/transpiled/directives/vary/Directive.js +3 -0
  396. package/transpiled/directives/vary/Directive.js.map +1 -0
  397. package/transpiled/directives/vary/Embed.d.ts +10 -0
  398. package/transpiled/directives/vary/Embed.js +49 -0
  399. package/transpiled/directives/vary/Embed.js.map +1 -0
  400. package/transpiled/directives/vary/Properties.d.ts +9 -0
  401. package/transpiled/directives/vary/Properties.js +16 -0
  402. package/transpiled/directives/vary/Properties.js.map +1 -0
  403. package/transpiled/directives/vary/Vary.d.ts +10 -0
  404. package/transpiled/directives/vary/Vary.js +36 -0
  405. package/transpiled/directives/vary/Vary.js.map +1 -0
  406. package/transpiled/directives/vary/embeddings/Embedding.d.ts +5 -0
  407. package/transpiled/directives/vary/embeddings/Embedding.js +3 -0
  408. package/transpiled/directives/vary/embeddings/Embedding.js.map +1 -0
  409. package/transpiled/directives/vary/embeddings/Header.d.ts +7 -0
  410. package/transpiled/directives/vary/embeddings/Header.js +26 -0
  411. package/transpiled/directives/vary/embeddings/Header.js.map +1 -0
  412. package/transpiled/directives/vary/embeddings/Language.d.ts +7 -0
  413. package/transpiled/directives/vary/embeddings/Language.js +28 -0
  414. package/transpiled/directives/vary/embeddings/Language.js.map +1 -0
  415. package/transpiled/directives/vary/embeddings/index.d.ts +5 -0
  416. package/transpiled/directives/vary/embeddings/index.js +10 -0
  417. package/transpiled/directives/vary/embeddings/index.js.map +1 -0
  418. package/transpiled/directives/vary/index.d.ts +2 -0
  419. package/transpiled/directives/vary/index.js +6 -0
  420. package/transpiled/directives/vary/index.js.map +1 -0
  421. package/transpiled/discovery.d.ts +1 -0
  422. package/transpiled/discovery.js +3 -0
  423. package/transpiled/discovery.js.map +1 -0
  424. package/transpiled/exceptions.d.ts +2 -0
  425. package/transpiled/exceptions.js +39 -0
  426. package/transpiled/exceptions.js.map +1 -0
  427. package/transpiled/index.d.ts +5 -0
  428. package/transpiled/index.js +12 -0
  429. package/transpiled/index.js.map +1 -0
  430. package/transpiled/io.d.ts +3 -0
  431. package/transpiled/io.js +3 -0
  432. package/transpiled/io.js.map +1 -0
  433. package/transpiled/manifest.d.ts +3 -0
  434. package/transpiled/manifest.js +66 -0
  435. package/transpiled/manifest.js.map +1 -0
  436. package/transpiled/root.d.ts +2 -0
  437. package/transpiled/root.js +39 -0
  438. package/transpiled/root.js.map +1 -0
  439. package/transpiled/schemas.d.ts +7 -0
  440. package/transpiled/schemas.js +14 -0
  441. package/transpiled/schemas.js.map +1 -0
  442. package/transpiled/tsconfig.tsbuildinfo +1 -0
@@ -1,32 +1,73 @@
1
+ import { Readable } from 'stream'
1
2
  import { NotFound } from '../../HTTP'
2
3
  import * as schemas from './schemas'
4
+ import { Workflow } from './workflow'
5
+ import type { Parameter } from '../../RTD'
6
+ import type { Unit } from './workflow'
3
7
  import type { Maybe } from '@toa.io/types'
4
8
  import type { Component } from '@toa.io/core'
5
- import type { Output } from '../../Directive'
6
-
9
+ import type { Output } from '../../io'
7
10
  import type { Directive, Input } from './types'
11
+ import type { Remotes } from '../../Remotes'
12
+ import type { Entry } from '@toa.io/extensions.storages'
8
13
 
9
14
  export class Delete implements Directive {
10
15
  public readonly targeted = true
11
16
 
17
+ private readonly workflow?: Workflow
12
18
  private readonly discovery: Promise<Component>
13
19
  private storage: Component | null = null
14
20
 
15
- public constructor (value: null, discovery: Promise<Component>) {
16
- schemas.remove.validate(value)
21
+ public constructor (options: Options | null, discovery: Promise<Component>, remotes: Remotes) {
22
+ schemas.remove.validate(options)
23
+
24
+ if (options?.workflow !== undefined)
25
+ this.workflow = new Workflow(options.workflow, remotes)
17
26
 
18
27
  this.discovery = discovery
19
28
  }
20
29
 
21
- public async apply (storage: string, request: Input): Promise<Output> {
30
+ public async apply (storage: string, request: Input, parameters: Parameter[]): Promise<Output> {
22
31
  this.storage ??= await this.discovery
23
32
 
24
- const input = { storage, path: request.path }
25
- const error = await this.storage.invoke<Maybe<unknown>>('delete', { input })
33
+ const entry = await this.storage.invoke<Maybe<Entry>>('get',
34
+ { input: { storage, path: request.url } })
26
35
 
27
- if (error instanceof Error)
36
+ if (entry instanceof Error)
28
37
  throw new NotFound()
29
38
 
30
- return {}
39
+ const output: Output = {}
40
+
41
+ if (this.workflow !== undefined) {
42
+ output.status = 202
43
+ output.body = Readable.from(this.execute(request, storage, entry, parameters))
44
+ } else
45
+ await this.delete(storage, request)
46
+
47
+ return output
48
+ }
49
+
50
+ private async delete (storage: string, request: Input): Promise<void> {
51
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
52
+ await this.storage!.invoke('delete',
53
+ { input: { storage, path: request.url } })
31
54
  }
55
+
56
+ // eslint-disable-next-line max-params
57
+ private async * execute
58
+ (request: Input, storage: string, entry: Entry, parameters: Parameter[]): AsyncGenerator {
59
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
60
+ for await (const chunk of this.workflow!.execute(request, storage, entry, parameters)) {
61
+ yield chunk
62
+
63
+ if (typeof chunk === 'object' && chunk !== null && 'error' in chunk)
64
+ return
65
+ }
66
+
67
+ await this.delete(storage, request)
68
+ }
69
+ }
70
+
71
+ export interface Options {
72
+ workflow?: Unit[] | Unit
32
73
  }
@@ -5,18 +5,18 @@ import type { Maybe } from '@toa.io/types'
5
5
  import type { Entry } from '@toa.io/extensions.storages'
6
6
  import type { Readable } from 'node:stream'
7
7
  import type { Component } from '@toa.io/core'
8
- import type { Output } from '../../Directive'
8
+ import type { Output } from '../../io'
9
9
 
10
10
  import type { Directive, Input } from './types'
11
11
 
12
12
  export class Fetch implements Directive {
13
13
  public readonly targeted = true
14
14
 
15
- private readonly permissions: Permissions = { blob: true, meta: false }
15
+ private readonly permissions: Required<Permissions> = { blob: true, meta: false }
16
16
  private readonly discovery: Promise<Component>
17
17
  private storage: Component = null as unknown as Component
18
18
 
19
- public constructor (permissions: Partial<Permissions> | null, discovery: Promise<Component>) {
19
+ public constructor (permissions: Permissions | null, discovery: Promise<Component>) {
20
20
  schemas.fetch.validate(permissions)
21
21
 
22
22
  Object.assign(this.permissions, permissions)
@@ -26,19 +26,22 @@ export class Fetch implements Directive {
26
26
  public async apply (storage: string, request: Input): Promise<Output> {
27
27
  this.storage ??= await this.discovery
28
28
 
29
- if (request.url.slice(-5) === ':meta')
30
- return await this.get(storage, request)
31
- else
32
- return await this.fetch(storage, request)
33
- }
29
+ const variant = posix.basename(request.url).includes('.')
30
+ const metadata = request.subtype === 'octets.entry'
34
31
 
35
- private async fetch (storage: string, request: Input): Promise<Output> {
36
- const filename = posix.basename(request.url)
37
- const variant = filename.includes('.')
32
+ if (!variant && metadata)
33
+ if (this.permissions.meta)
34
+ return this.get(storage, request)
35
+ else
36
+ throw new Forbidden('Metadata is not accessible.')
38
37
 
39
38
  if (!variant && !this.permissions.blob)
40
39
  throw new Forbidden('BLOB variant must be specified.')
41
40
 
41
+ return await this.fetch(storage, request)
42
+ }
43
+
44
+ private async fetch (storage: string, request: Input): Promise<Output> {
42
45
  if ('if-none-match' in request.headers)
43
46
  return { status: 304 }
44
47
 
@@ -58,11 +61,7 @@ export class Fetch implements Directive {
58
61
  }
59
62
 
60
63
  private async get (storage: string, request: Input): Promise<Output> {
61
- if (!this.permissions.meta)
62
- throw new Forbidden('Metadata is not accessible.')
63
-
64
- const path = request.url.slice(0, -5)
65
- const input = { storage, path }
64
+ const input = { storage, path: request.url }
66
65
  const entry = await this.storage.invoke<Maybe<Entry>>('get', { input })
67
66
 
68
67
  if (entry instanceof Error)
@@ -72,9 +71,9 @@ export class Fetch implements Directive {
72
71
  }
73
72
  }
74
73
 
75
- interface Permissions {
76
- blob: boolean
77
- meta: boolean
74
+ export interface Permissions {
75
+ blob?: boolean
76
+ meta?: boolean
78
77
  }
79
78
 
80
79
  interface FetchResult {
@@ -1,32 +1,62 @@
1
- import { NotFound } from '../../HTTP'
1
+ import { posix } from 'node:path'
2
+ import { Forbidden, NotFound } from '../../HTTP'
2
3
  import * as schemas from './schemas'
4
+ import type { Entry } from '@toa.io/extensions.storages'
3
5
  import type { Maybe } from '@toa.io/types'
4
6
  import type { Component } from '@toa.io/core'
5
- import type { Output } from '../../Directive'
7
+ import type { Output } from '../../io'
6
8
 
7
9
  import type { Directive, Input } from './types'
8
10
 
9
11
  export class List implements Directive {
10
12
  public readonly targeted = false
11
13
 
14
+ private readonly permissions: Required<Permissions> = { meta: false }
12
15
  private readonly discovery: Promise<Component>
13
16
  private storage: Component | null = null
14
17
 
15
- public constructor (value: null, discovery: Promise<Component>) {
16
- schemas.remove.validate(value)
18
+ public constructor (permissions: Permissions | null, discovery: Promise<Component>) {
19
+ schemas.list.validate(permissions)
17
20
 
21
+ Object.assign(this.permissions, permissions)
18
22
  this.discovery = discovery
19
23
  }
20
24
 
21
25
  public async apply (storage: string, request: Input): Promise<Output> {
22
26
  this.storage ??= await this.discovery
23
27
 
24
- const input = { storage, path: request.path }
25
- const list = await this.storage.invoke<Maybe<unknown>>('list', { input })
28
+ const metadata = request.subtype === 'octets.entries'
29
+
30
+ if (metadata && !this.permissions.meta)
31
+ throw new Forbidden('Metadata is not accessible.')
32
+
33
+ const input = { storage, path: request.url }
34
+ const list = await this.storage.invoke<Maybe<string[]>>('list', { input })
26
35
 
27
36
  if (list instanceof Error)
28
37
  throw new NotFound()
29
38
 
30
- return { body: list }
39
+ const body = metadata
40
+ ? await this.expand(storage, request.url, list)
41
+ : list
42
+
43
+ return { body }
31
44
  }
45
+
46
+ private async expand (storage: string, prefix: string, list: string[]):
47
+ Promise<Array<Maybe<Entry>>> {
48
+ const promises = list.map(async (id) => {
49
+ const path = posix.join(prefix, id)
50
+ const input = { storage, path }
51
+
52
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- ensured in `apply`
53
+ return this.storage!.invoke<Maybe<Entry>>('get', { input })
54
+ })
55
+
56
+ return await Promise.all(promises)
57
+ }
58
+ }
59
+
60
+ export interface Permissions {
61
+ meta?: boolean
32
62
  }
@@ -5,12 +5,14 @@ import { Fetch } from './Fetch'
5
5
  import { List } from './List'
6
6
  import { Delete } from './Delete'
7
7
  import { Permute } from './Permute'
8
+ import type { Output } from '../../io'
8
9
  import type { Component } from '@toa.io/core'
9
10
  import type { Remotes } from '../../Remotes'
10
- import type { Output, Family } from '../../Directive'
11
+ import type { Family } from '../../Directive'
11
12
  import type { Directive, Input } from './types'
13
+ import type { Parameter } from '../../RTD'
12
14
 
13
- class Octets implements Family<Directive> {
15
+ export class Octets implements Family<Directive> {
14
16
  public readonly name: string = 'octets'
15
17
  public readonly mandatory: boolean = false
16
18
 
@@ -27,7 +29,8 @@ class Octets implements Family<Directive> {
27
29
  return new Class(value, this.discovery, remotes)
28
30
  }
29
31
 
30
- public async preflight (directives: Directive[], input: Input): Promise<Output> {
32
+ public async preflight
33
+ (directives: Directive[], input: Input, parameters: Parameter[]): Promise<Output> {
31
34
  let context: Context | null = null
32
35
  let action: Directive | null = null
33
36
 
@@ -50,7 +53,7 @@ class Octets implements Family<Directive> {
50
53
  if (targeted !== action.targeted)
51
54
  throw new NotFound(`Trailing slash is ${action.targeted ? 'redundant' : 'required'}.`)
52
55
 
53
- return await action.apply(context.storage, input)
56
+ return await action.apply(context.storage, input, parameters)
54
57
  }
55
58
  }
56
59
 
@@ -64,5 +67,3 @@ const DIRECTIVES: Record<string, Constructor> = {
64
67
  }
65
68
 
66
69
  type Constructor = new (value: any, discovery: Promise<Component>, remotes: Remotes) => Directive
67
-
68
- export = new Octets()
@@ -2,7 +2,7 @@ import { NotAcceptable, NotFound } from '../../HTTP'
2
2
  import * as schemas from './schemas'
3
3
  import type { Maybe } from '@toa.io/types'
4
4
  import type { Component } from '@toa.io/core'
5
- import type { Output } from '../../Directive'
5
+ import type { Output } from '../../io'
6
6
 
7
7
  import type { Directive, Input } from './types'
8
8
 
@@ -13,7 +13,7 @@ export class Permute implements Directive {
13
13
  private storage: Component | null = null
14
14
 
15
15
  public constructor (value: null, discovery: Promise<Component>) {
16
- schemas.remove.validate(value)
16
+ schemas.permute.validate(value)
17
17
 
18
18
  this.discovery = discovery
19
19
  }
@@ -24,7 +24,7 @@ export class Permute implements Directive {
24
24
  if (request.encoder === null)
25
25
  throw new NotAcceptable()
26
26
 
27
- const path = request.path
27
+ const path = request.url
28
28
  const list = await request.parse()
29
29
  const input = { storage, path, list }
30
30
  const error = await this.storage.invoke<Maybe<unknown>>('permute', { input })
@@ -1,25 +1,23 @@
1
- import { Readable } from 'node:stream'
2
- import { posix } from 'node:path'
3
1
  import { match } from 'matchacho'
4
- import { promex } from '@toa.io/generic'
5
2
  import { BadRequest, UnsupportedMediaType } from '../../HTTP'
3
+ import { cors } from '../cors'
6
4
  import * as schemas from './schemas'
7
- import type { Maybe } from '@toa.io/types'
5
+ import { Workflow } from './workflow'
6
+ import type { Parameter } from '../../RTD'
7
+ import type { Unit } from './workflow'
8
8
  import type { Entry } from '@toa.io/extensions.storages'
9
9
  import type { Remotes } from '../../Remotes'
10
10
  import type { ErrorType } from 'error-value'
11
11
  import type { Component } from '@toa.io/core'
12
- import type { Output } from '../../Directive'
12
+ import type { Output } from '../../io'
13
13
  import type { Directive, Input } from './types'
14
14
 
15
15
  export class Store implements Directive {
16
16
  public readonly targeted = false
17
17
 
18
- private readonly accept: string | undefined
19
- private readonly workflow: Workflow | undefined
18
+ private readonly accept?: string
19
+ private readonly workflow?: Workflow
20
20
  private readonly discovery: Record<string, Promise<Component>> = {}
21
- private readonly remotes: Remotes
22
- private readonly components: Record<string, Component> = {}
23
21
  private storage: Component | null = null
24
22
 
25
23
  public constructor
@@ -31,30 +29,38 @@ export class Store implements Directive {
31
29
  Array, (types: string[]) => types.join(','),
32
30
  undefined)
33
31
 
34
- this.workflow = match(options?.workflow,
35
- Array, (units: Unit[]) => units,
36
- Object, (unit: Unit) => [unit],
37
- undefined)
32
+ if (options?.workflow !== undefined)
33
+ this.workflow = new Workflow(options.workflow, remotes)
38
34
 
39
35
  this.discovery.storage = discovery
40
- this.remotes = remotes
36
+
37
+ cors.allowHeader('content-meta')
41
38
  }
42
39
 
43
- public async apply (storage: string, request: Input): Promise<Output> {
40
+ public async apply (storage: string, request: Input, parameters: Parameter[]): Promise<Output> {
44
41
  this.storage ??= await this.discovery.storage
45
42
 
46
- const input = { storage, request, accept: this.accept }
47
- const entry = await this.storage.invoke('store', { input })
43
+ const input: StoreInput = { storage, request }
44
+ const meta = request.headers['content-meta']
45
+
46
+ if (this.accept !== undefined)
47
+ input.accept = this.accept
48
+
49
+ if (meta !== undefined)
50
+ input.meta = this.parseMeta(meta)
51
+
52
+ const entry = await this.storage.invoke<Entry>('store', { input })
48
53
 
49
54
  return match<Output>(entry,
50
55
  Error, (error: ErrorType) => this.throw(error),
51
- () => this.reply(request, storage, entry))
56
+ () => this.reply(request, storage, entry, parameters))
52
57
  }
53
58
 
54
- private reply (request: Input, storage: string, entry: Entry): Output {
59
+ // eslint-disable-next-line max-params
60
+ private reply (request: Input, storage: string, entry: Entry, parameters: Parameter[]): Output {
55
61
  const body = this.workflow === undefined
56
62
  ? entry
57
- : Readable.from(this.execute(request, storage, entry))
63
+ : this.workflow.execute(request, storage, entry, parameters)
58
64
 
59
65
  return { body }
60
66
  }
@@ -66,93 +72,31 @@ export class Store implements Directive {
66
72
  error)
67
73
  }
68
74
 
69
- /* eslint-disable no-useless-return, max-depth */
70
-
71
- /**
72
- * Execute workflow units sequentially, steps within a unit in parallel.
73
- * Yield results as soon as they come.
74
- *
75
- * If you need to change this, it may take a while.
76
- */
77
- private async * execute (request: Input, storage: string, entry: Entry): AsyncGenerator {
78
- yield entry
79
-
80
- const path = posix.join(request.path, entry.id)
81
- let interrupted = false
82
-
83
- for (const unit of this.workflow as Workflow) {
84
- if (interrupted)
85
- break
86
-
87
- const steps = Object.keys(unit)
88
-
89
- // unit result promises queue
90
- const results = Array.from(steps, promex<unknown>)
91
- let next = 0
92
-
93
- // execute steps in parallel
94
- for (const step of steps)
95
- // these promises are indirectly awaited in the yield loop
96
- void (async () => {
97
- const endpoint = unit[step]
98
- const context: Context = { storage, path, entry }
99
- const result = await this.call(endpoint, context)
100
-
101
- if (interrupted)
102
- return
103
-
104
- // as a result is received, resolve the next promise from the queue
105
- const promise = results[next++]
106
-
107
- if (result instanceof Error) {
108
- interrupted = true
109
- promise.resolve({ error: { step, ...result } })
110
-
111
- // cancel pending promises
112
- results[next].resolve(null)
113
- } else
114
- promise.resolve({ [step]: result ?? null })
115
- })().catch((e) => results[next].reject(e))
116
-
117
- // yield results from the queue as they come
118
- for (const promise of results) {
119
- const result = await promise
120
-
121
- if (result === null) // canceled promise
122
- break
123
- else
124
- yield result
125
- }
126
- }
127
- }
128
-
129
- private async call (endpoint: string, context: Context): Promise<Maybe<unknown>> {
130
- const [operation, component, namespace = 'default'] = endpoint.split('.').reverse()
131
- const key = `${namespace}.${component}`
75
+ private parseMeta (value: string | string[]): Record<string, string> {
76
+ if (Array.isArray(value))
77
+ value = value.join(',')
132
78
 
133
- this.components[key] ??= await this.discover(key, namespace, component)
79
+ const meta: Record<string, string> = {}
134
80
 
135
- return await this.components[key].invoke(operation, { input: context })
136
- }
81
+ for (const pair of value.split(',')) {
82
+ const eq = pair.indexOf('=')
83
+ const key = (eq === -1 ? pair : pair.slice(0, eq)).trim()
137
84
 
138
- private async discover (key: string, namespace: string, component: string): Promise<Component> {
139
- if (this.discovery[key] === undefined)
140
- this.discovery[key] = this.remotes.discover(namespace, component)
85
+ meta[key] = eq === -1 ? 'true' : pair.slice(eq + 1).trim()
86
+ }
141
87
 
142
- return await this.discovery[key]
88
+ return meta
143
89
  }
144
90
  }
145
91
 
146
- type Unit = Record<string, string>
147
- type Workflow = Unit[]
148
-
149
- interface Options {
150
- accept: string | string[]
151
- workflow: Workflow | Unit
92
+ export interface Options {
93
+ accept?: string | string[]
94
+ workflow?: Unit[] | Unit
152
95
  }
153
96
 
154
- interface Context {
97
+ interface StoreInput {
155
98
  storage: string
156
- path: string
157
- entry: Entry
99
+ request: Input
100
+ accept?: string
101
+ meta?: Record<string, string>
158
102
  }
@@ -1,3 +1,3 @@
1
- import Family from './Family'
1
+ import { Octets } from './Octets'
2
2
 
3
- export = Family
3
+ export const octets = new Octets()
@@ -1,12 +1,17 @@
1
1
  import { resolve } from 'node:path'
2
2
  import schemas from '@toa.io/schemas'
3
+ import type { Permissions as FetchPermissions } from './Fetch'
4
+ import type { Permissions as ListPermissions } from './List'
5
+ import type { Options as StoreOptions } from './Store'
6
+ import type { Options as DeleteOptions } from './Delete'
7
+ import type { Schema } from '@toa.io/schemas'
3
8
 
4
9
  const path = resolve(__dirname, '../../../schemas/octets')
5
10
  const namespace = schemas.namespace(path)
6
11
 
7
- export const context = namespace.schema('context')
8
- export const store = namespace.schema('store')
9
- export const fetch = namespace.schema('fetch')
10
- export const remove = namespace.schema('delete')
11
- export const list = namespace.schema('list')
12
- export const permute = namespace.schema('permute')
12
+ export const context: Schema<string> = namespace.schema('context')
13
+ export const store: Schema<StoreOptions | null> = namespace.schema('store')
14
+ export const fetch: Schema<FetchPermissions | null> = namespace.schema('fetch')
15
+ export const remove: Schema<DeleteOptions | null> = namespace.schema('delete')
16
+ export const list: Schema<ListPermissions | null> = namespace.schema('list')
17
+ export const permute: Schema<null> = namespace.schema('permute')
@@ -1,13 +1,14 @@
1
- import type * as directive from '../../Directive'
1
+ import type { Parameter } from '../../RTD'
2
+ import type * as io from '../../io'
2
3
 
3
4
  export interface Directive {
4
5
  readonly targeted: boolean
5
6
 
6
- apply: (storage: string, input: Input) => directive.Output | Promise<directive.Output>
7
+ apply: (storage: string, input: Input, parameters: Parameter[]) => io.Output | Promise<io.Output>
7
8
  }
8
9
 
9
10
  export interface Extension {
10
11
  octets?: string
11
12
  }
12
13
 
13
- export type Input = directive.Input & Extension
14
+ export type Input = io.Input & Extension
@@ -0,0 +1,78 @@
1
+ import { Readable } from 'stream'
2
+ import type { Unit } from './Workflow'
3
+ import type { Remotes } from '../../../Remotes'
4
+ import type { Component } from '@toa.io/core'
5
+ import type { Maybe } from '@toa.io/types'
6
+ import type { Entry } from '@toa.io/extensions.storages'
7
+
8
+ export class Execution extends Readable {
9
+ private readonly units: Unit[]
10
+ private readonly remotes: Remotes
11
+ private readonly context: Context
12
+ private readonly components: Record<string, Component> = {}
13
+ private readonly discovery: Record<string, Promise<Component>> = {}
14
+ private interrupted = false
15
+
16
+ public constructor (context: Context, units: Unit[], remotes: Remotes) {
17
+ super({ objectMode: true })
18
+
19
+ this.context = context
20
+ this.units = units
21
+ this.remotes = remotes
22
+
23
+ void this.run()
24
+ }
25
+
26
+ public override _read (): void {
27
+ }
28
+
29
+ private async run (): Promise<void> {
30
+ this.push(this.context.entry)
31
+
32
+ for (const unit of this.units) {
33
+ await this.execute(unit)
34
+
35
+ if (this.interrupted)
36
+ break
37
+ }
38
+
39
+ this.push(null)
40
+ }
41
+
42
+ private async execute (unit: Unit): Promise<void> {
43
+ const promises = Object.entries(unit).map(async ([step, endpoint]) => {
44
+ const result = await this.call(endpoint).catch((error: Error) => console.error(error))
45
+
46
+ if (result instanceof Error) {
47
+ this.push({ error: { step, ...result } })
48
+ this.interrupted = true
49
+ } else
50
+ this.push({ [step]: result ?? null })
51
+ })
52
+
53
+ await Promise.all(promises)
54
+ }
55
+
56
+ private async call (endpoint: string): Promise<Maybe<unknown>> {
57
+ const [operation, component, namespace = 'default'] = endpoint.split('.').reverse()
58
+ const key = `${namespace}.${component}`
59
+
60
+ this.components[key] ??= await this.discover(key, namespace, component)
61
+
62
+ return await this.components[key].invoke(operation, { input: this.context })
63
+ }
64
+
65
+ private async discover (key: string, namespace: string, component: string): Promise<Component> {
66
+ if (this.discovery[key] === undefined)
67
+ this.discovery[key] = this.remotes.discover(namespace, component)
68
+
69
+ return await this.discovery[key]
70
+ }
71
+ }
72
+
73
+ export interface Context {
74
+ storage: string
75
+ path: string
76
+ entry: Entry
77
+ parameters: Record<string, string>
78
+ }
@@ -0,0 +1,37 @@
1
+ import { posix } from 'node:path'
2
+ import { match } from 'matchacho'
3
+ import { Execution } from './Execution'
4
+ import type { Context } from './Execution'
5
+ import type { Parameter } from '../../../RTD'
6
+ import type { Input } from '../types'
7
+ import type { Entry } from '@toa.io/extensions.storages'
8
+ import type { Remotes } from '../../../Remotes'
9
+
10
+ export class Workflow {
11
+ private readonly units: Unit[]
12
+ private readonly remotes: Remotes
13
+
14
+ public constructor (units: Unit[] | Unit, remotes: Remotes) {
15
+ this.units = match<Unit[]>(units,
16
+ Array, (units: Unit[]) => units,
17
+ Object, (unit: Unit) => [unit])
18
+
19
+ this.remotes = remotes
20
+ }
21
+
22
+ // eslint-disable-next-line max-params
23
+ public execute
24
+ (request: Input, storage: string, entry: Entry, params: Parameter[]): Execution {
25
+ const path = posix.join(request.path, entry.id)
26
+ const parameters: Record<string, string> = {}
27
+
28
+ for (const { name, value } of params)
29
+ parameters[name] = value
30
+
31
+ const context: Context = { storage, path, entry, parameters }
32
+
33
+ return new Execution(context, this.units, this.remotes)
34
+ }
35
+ }
36
+
37
+ export type Unit = Record<string, string>
@@ -0,0 +1 @@
1
+ export { Workflow, type Unit } from './Workflow'
@@ -0,0 +1,6 @@
1
+ import type { Properties } from './Properties'
2
+ import type { Input } from '../../io'
3
+
4
+ export interface Directive {
5
+ preflight: (request: Input, properties: Properties) => void
6
+ }