@toa.io/extensions.exposition 1.0.0-alpha.113 → 1.0.0-alpha.115
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.
- package/features/flow.feature +52 -0
- package/features/octets.location.feature +40 -0
- package/features/octets.workflows.feature +36 -17
- package/features/steps/components/octets.tester/manifest.toa.yaml +1 -0
- package/features/steps/components/octets.tester/operations/echo.js +1 -1
- package/features/steps/components/octets.tester/operations/id.js +7 -0
- package/package.json +2 -2
- package/source/directives/flow/Compose.ts +29 -5
- package/source/directives/octets/Delete.ts +10 -6
- package/source/directives/octets/Put.ts +8 -2
- package/source/directives/octets/Workflow.ts +8 -2
- package/source/directives/octets/workflows/Workflow.ts +14 -6
- package/source/directives/octets/workflows/index.ts +1 -1
- package/transpiled/directives/flow/Compose.d.ts +2 -1
- package/transpiled/directives/flow/Compose.js +24 -4
- package/transpiled/directives/flow/Compose.js.map +1 -1
- package/transpiled/directives/octets/Delete.js +7 -4
- package/transpiled/directives/octets/Delete.js.map +1 -1
- package/transpiled/directives/octets/Put.js +6 -1
- package/transpiled/directives/octets/Put.js.map +1 -1
- package/transpiled/directives/octets/Workflow.js +6 -1
- package/transpiled/directives/octets/Workflow.js.map +1 -1
- package/transpiled/directives/octets/workflows/Workflow.d.ts +6 -2
- package/transpiled/directives/octets/workflows/Workflow.js +8 -5
- package/transpiled/directives/octets/workflows/Workflow.js.map +1 -1
- package/transpiled/directives/octets/workflows/index.d.ts +1 -1
- package/transpiled/directives/octets/workflows/index.js.map +1 -1
- package/transpiled/tsconfig.tsbuildinfo +1 -1
package/features/flow.feature
CHANGED
|
@@ -94,3 +94,55 @@ Feature: Request flow
|
|
|
94
94
|
- 1
|
|
95
95
|
- 2
|
|
96
96
|
"""
|
|
97
|
+
|
|
98
|
+
Scenario: Composing with multiple possible shapes
|
|
99
|
+
Given the `sequences` is running with the following manifest:
|
|
100
|
+
"""yaml
|
|
101
|
+
exposition:
|
|
102
|
+
/:
|
|
103
|
+
flow:compose:
|
|
104
|
+
- a: $[0].b.c
|
|
105
|
+
- b: $[0]
|
|
106
|
+
POST: numbers
|
|
107
|
+
"""
|
|
108
|
+
When the following request is received:
|
|
109
|
+
"""
|
|
110
|
+
POST /sequences/ HTTP/1.1
|
|
111
|
+
host: nex.toa.io
|
|
112
|
+
content-type: text/plain
|
|
113
|
+
accept: application/yaml
|
|
114
|
+
|
|
115
|
+
3
|
|
116
|
+
"""
|
|
117
|
+
Then the following reply is sent:
|
|
118
|
+
"""
|
|
119
|
+
201 Created
|
|
120
|
+
content-type: application/yaml
|
|
121
|
+
|
|
122
|
+
b: 0
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
Scenario: Composing with text value
|
|
126
|
+
Given the `sequences` is running with the following manifest:
|
|
127
|
+
"""yaml
|
|
128
|
+
exposition:
|
|
129
|
+
/:
|
|
130
|
+
flow:compose: $[1]
|
|
131
|
+
POST: numbers
|
|
132
|
+
"""
|
|
133
|
+
When the following request is received:
|
|
134
|
+
"""
|
|
135
|
+
POST /sequences/ HTTP/1.1
|
|
136
|
+
host: nex.toa.io
|
|
137
|
+
content-type: text/plain
|
|
138
|
+
accept: application/yaml
|
|
139
|
+
|
|
140
|
+
3
|
|
141
|
+
"""
|
|
142
|
+
Then the following reply is sent:
|
|
143
|
+
"""
|
|
144
|
+
201 Created
|
|
145
|
+
content-type: application/yaml
|
|
146
|
+
|
|
147
|
+
1
|
|
148
|
+
"""
|
|
@@ -41,3 +41,43 @@ Feature: Octets location
|
|
|
41
41
|
| location |
|
|
42
42
|
| ./bar |
|
|
43
43
|
| /foo/bar/ |
|
|
44
|
+
|
|
45
|
+
Scenario: Executing a workflow with specified location
|
|
46
|
+
Given the `octets.tester` is running
|
|
47
|
+
And the annotation:
|
|
48
|
+
"""yaml
|
|
49
|
+
/:
|
|
50
|
+
auth:anonymous: true
|
|
51
|
+
octets:context: octets
|
|
52
|
+
POST:
|
|
53
|
+
octets:put:
|
|
54
|
+
location: /hello/world/
|
|
55
|
+
workflow:
|
|
56
|
+
echo: octets.tester.echo
|
|
57
|
+
io:output: true
|
|
58
|
+
"""
|
|
59
|
+
When the stream of `lenna.ascii` is received with the following headers:
|
|
60
|
+
"""
|
|
61
|
+
POST / HTTP/1.1
|
|
62
|
+
host: nex.toa.io
|
|
63
|
+
accept: application/yaml, multipart/yaml
|
|
64
|
+
content-type: application/octet-stream
|
|
65
|
+
"""
|
|
66
|
+
Then the following reply is sent:
|
|
67
|
+
"""
|
|
68
|
+
201 Created
|
|
69
|
+
content-type: multipart/yaml; boundary=cut
|
|
70
|
+
|
|
71
|
+
--cut
|
|
72
|
+
|
|
73
|
+
id: ${{ id }}
|
|
74
|
+
type: application/octet-stream
|
|
75
|
+
size: 8169
|
|
76
|
+
--cut
|
|
77
|
+
|
|
78
|
+
step: echo
|
|
79
|
+
status: completed
|
|
80
|
+
output:
|
|
81
|
+
path: /hello/world/${{ id }}
|
|
82
|
+
--cut--
|
|
83
|
+
"""
|
|
@@ -109,7 +109,7 @@ Feature: Octets storage workflows
|
|
|
109
109
|
content-type: multipart/yaml; boundary=cut
|
|
110
110
|
|
|
111
111
|
--cut
|
|
112
|
-
id:
|
|
112
|
+
id: ${{ id }}
|
|
113
113
|
type: application/octet-stream
|
|
114
114
|
size: 8169
|
|
115
115
|
--cut
|
|
@@ -135,27 +135,32 @@ Feature: Octets storage workflows
|
|
|
135
135
|
octets:context: octets
|
|
136
136
|
POST:
|
|
137
137
|
octets:put: ~
|
|
138
|
+
io:output: true
|
|
138
139
|
/*:
|
|
139
140
|
GET:
|
|
140
141
|
octets:get: ~
|
|
141
142
|
DELETE:
|
|
142
143
|
octets:delete:
|
|
143
144
|
workflow:
|
|
144
|
-
echo: octets.tester.
|
|
145
|
+
echo: octets.tester.id
|
|
146
|
+
io:output: true
|
|
145
147
|
"""
|
|
146
148
|
When the stream of `lenna.ascii` is received with the following headers:
|
|
147
149
|
"""
|
|
148
150
|
POST / HTTP/1.1
|
|
149
151
|
host: nex.toa.io
|
|
150
152
|
content-type: application/octet-stream
|
|
153
|
+
accept: application/yaml
|
|
151
154
|
"""
|
|
152
155
|
Then the following reply is sent:
|
|
153
156
|
"""
|
|
154
157
|
201 Created
|
|
158
|
+
|
|
159
|
+
id: ${{ id }}
|
|
155
160
|
"""
|
|
156
161
|
When the following request is received:
|
|
157
162
|
"""
|
|
158
|
-
DELETE
|
|
163
|
+
DELETE /${{ id }} HTTP/1.1
|
|
159
164
|
host: nex.toa.io
|
|
160
165
|
accept: application/yaml, multipart/yaml
|
|
161
166
|
"""
|
|
@@ -167,12 +172,12 @@ Feature: Octets storage workflows
|
|
|
167
172
|
--cut
|
|
168
173
|
step: echo
|
|
169
174
|
status: completed
|
|
170
|
-
output:
|
|
175
|
+
output: ${{ id }}
|
|
171
176
|
--cut--
|
|
172
177
|
"""
|
|
173
178
|
When the following request is received:
|
|
174
179
|
"""
|
|
175
|
-
GET
|
|
180
|
+
GET /${{ id }} HTTP/1.1
|
|
176
181
|
host: nex.toa.io
|
|
177
182
|
"""
|
|
178
183
|
Then the following reply is sent:
|
|
@@ -189,6 +194,7 @@ Feature: Octets storage workflows
|
|
|
189
194
|
octets:context: octets
|
|
190
195
|
POST:
|
|
191
196
|
octets:put: ~
|
|
197
|
+
io:output: true
|
|
192
198
|
/*:
|
|
193
199
|
GET:
|
|
194
200
|
octets:get: ~
|
|
@@ -196,20 +202,24 @@ Feature: Octets storage workflows
|
|
|
196
202
|
octets:delete:
|
|
197
203
|
workflow:
|
|
198
204
|
err: octets.tester.err
|
|
205
|
+
io:output: true
|
|
199
206
|
"""
|
|
200
207
|
When the stream of `lenna.ascii` is received with the following headers:
|
|
201
208
|
"""
|
|
202
209
|
POST / HTTP/1.1
|
|
203
210
|
host: nex.toa.io
|
|
204
211
|
content-type: application/octet-stream
|
|
212
|
+
accept: application/yaml
|
|
205
213
|
"""
|
|
206
214
|
Then the following reply is sent:
|
|
207
215
|
"""
|
|
208
216
|
201 Created
|
|
217
|
+
|
|
218
|
+
id: ${{ id }}
|
|
209
219
|
"""
|
|
210
220
|
When the following request is received:
|
|
211
221
|
"""
|
|
212
|
-
DELETE
|
|
222
|
+
DELETE /${{ id }} HTTP/1.1
|
|
213
223
|
host: nex.toa.io
|
|
214
224
|
accept: application/yaml, multipart/yaml
|
|
215
225
|
"""
|
|
@@ -229,7 +239,7 @@ Feature: Octets storage workflows
|
|
|
229
239
|
"""
|
|
230
240
|
When the following request is received:
|
|
231
241
|
"""
|
|
232
|
-
GET
|
|
242
|
+
GET /${{ id }} HTTP/1.1
|
|
233
243
|
host: nex.toa.io
|
|
234
244
|
"""
|
|
235
245
|
Then the following reply is sent:
|
|
@@ -249,6 +259,7 @@ Feature: Octets storage workflows
|
|
|
249
259
|
octets:put:
|
|
250
260
|
workflow:
|
|
251
261
|
concat: octets.tester.concat
|
|
262
|
+
io:output: true
|
|
252
263
|
"""
|
|
253
264
|
When the stream of `lenna.ascii` is received with the following headers:
|
|
254
265
|
"""
|
|
@@ -264,7 +275,7 @@ Feature: Octets storage workflows
|
|
|
264
275
|
|
|
265
276
|
--cut
|
|
266
277
|
|
|
267
|
-
id:
|
|
278
|
+
id: ${{ id }}
|
|
268
279
|
type: application/octet-stream
|
|
269
280
|
size: 8169
|
|
270
281
|
--cut
|
|
@@ -287,6 +298,7 @@ Feature: Octets storage workflows
|
|
|
287
298
|
octets:put:
|
|
288
299
|
workflow:
|
|
289
300
|
authority: octets.tester.authority
|
|
301
|
+
io:output: true
|
|
290
302
|
"""
|
|
291
303
|
When the stream of `lenna.ascii` is received with the following headers:
|
|
292
304
|
"""
|
|
@@ -302,7 +314,7 @@ Feature: Octets storage workflows
|
|
|
302
314
|
|
|
303
315
|
--cut
|
|
304
316
|
|
|
305
|
-
id:
|
|
317
|
+
id: ${{ id }}
|
|
306
318
|
type: application/octet-stream
|
|
307
319
|
size: 8169
|
|
308
320
|
--cut
|
|
@@ -322,24 +334,29 @@ Feature: Octets storage workflows
|
|
|
322
334
|
octets:context: octets
|
|
323
335
|
POST:
|
|
324
336
|
octets:put: ~
|
|
337
|
+
io:output: true
|
|
325
338
|
/*:
|
|
326
339
|
DELETE:
|
|
327
340
|
octets:workflow:
|
|
328
|
-
|
|
341
|
+
id: octets.tester.id
|
|
342
|
+
io:output: true
|
|
329
343
|
"""
|
|
330
344
|
When the stream of `lenna.ascii` is received with the following headers:
|
|
331
345
|
"""
|
|
332
346
|
POST / HTTP/1.1
|
|
333
347
|
host: nex.toa.io
|
|
334
348
|
content-type: application/octet-stream
|
|
349
|
+
accept: application/yaml
|
|
335
350
|
"""
|
|
336
351
|
Then the following reply is sent:
|
|
337
352
|
"""
|
|
338
353
|
201 Created
|
|
354
|
+
|
|
355
|
+
id: ${{ id }}
|
|
339
356
|
"""
|
|
340
357
|
When the following request is received:
|
|
341
358
|
"""
|
|
342
|
-
DELETE
|
|
359
|
+
DELETE /${{ id }} HTTP/1.1
|
|
343
360
|
host: nex.toa.io
|
|
344
361
|
accept: application/yaml, multipart/yaml
|
|
345
362
|
"""
|
|
@@ -350,9 +367,9 @@ Feature: Octets storage workflows
|
|
|
350
367
|
|
|
351
368
|
--cut
|
|
352
369
|
|
|
353
|
-
step:
|
|
370
|
+
step: id
|
|
354
371
|
status: completed
|
|
355
|
-
output:
|
|
372
|
+
output: ${{ id }}
|
|
356
373
|
|
|
357
374
|
--cut--
|
|
358
375
|
"""
|
|
@@ -369,6 +386,7 @@ Feature: Octets storage workflows
|
|
|
369
386
|
workflow:
|
|
370
387
|
- foo: octets.tester.foo
|
|
371
388
|
- yield: octets.tester.yield
|
|
389
|
+
io:output: true
|
|
372
390
|
"""
|
|
373
391
|
When the stream of `lenna.ascii` is received with the following headers:
|
|
374
392
|
"""
|
|
@@ -384,7 +402,7 @@ Feature: Octets storage workflows
|
|
|
384
402
|
|
|
385
403
|
--cut
|
|
386
404
|
|
|
387
|
-
id:
|
|
405
|
+
id: ${{ id }}
|
|
388
406
|
type: application/octet-stream
|
|
389
407
|
|
|
390
408
|
--cut
|
|
@@ -421,6 +439,7 @@ Feature: Octets storage workflows
|
|
|
421
439
|
octets:put:
|
|
422
440
|
workflow:
|
|
423
441
|
yield: octets.tester.yex
|
|
442
|
+
io:output: true
|
|
424
443
|
"""
|
|
425
444
|
When the stream of `lenna.ascii` is received with the following headers:
|
|
426
445
|
"""
|
|
@@ -436,7 +455,7 @@ Feature: Octets storage workflows
|
|
|
436
455
|
|
|
437
456
|
--cut
|
|
438
457
|
|
|
439
|
-
id:
|
|
458
|
+
id: ${{ id }}
|
|
440
459
|
type: application/octet-stream
|
|
441
460
|
|
|
442
461
|
--cut
|
|
@@ -464,12 +483,12 @@ Feature: Octets storage workflows
|
|
|
464
483
|
/:
|
|
465
484
|
auth:anonymous: true
|
|
466
485
|
octets:context: octets
|
|
486
|
+
io:output: true
|
|
467
487
|
POST:
|
|
468
488
|
octets:put:
|
|
469
489
|
workflow:
|
|
470
490
|
foo: task:octets.tester.foo
|
|
471
491
|
/*:
|
|
472
|
-
io:output: true
|
|
473
492
|
GET:
|
|
474
493
|
octets:get:
|
|
475
494
|
meta: true
|
|
@@ -488,7 +507,7 @@ Feature: Octets storage workflows
|
|
|
488
507
|
|
|
489
508
|
--cut
|
|
490
509
|
|
|
491
|
-
id:
|
|
510
|
+
id: ${{ id }}
|
|
492
511
|
|
|
493
512
|
--cut
|
|
494
513
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/extensions.exposition",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.115",
|
|
4
4
|
"description": "Toa Exposition",
|
|
5
5
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/toa-io/toa#readme",
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
"@types/negotiator": "0.6.1",
|
|
62
62
|
"jest-esbuild": "0.3.0"
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "2965b14fe8aef97227d19fd11803b37982732cc3"
|
|
65
65
|
}
|
|
@@ -7,10 +7,10 @@ import type { Input as Context } from '../../io'
|
|
|
7
7
|
import type { OutgoingMessage } from '../../HTTP'
|
|
8
8
|
|
|
9
9
|
export class Compose implements Directive {
|
|
10
|
-
private readonly
|
|
10
|
+
private readonly expressions: Expression[]
|
|
11
11
|
|
|
12
12
|
public constructor (composition: any) {
|
|
13
|
-
this.
|
|
13
|
+
this.expressions = build(composition)
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
public attach (context: Context): void {
|
|
@@ -28,7 +28,7 @@ export class Compose implements Directive {
|
|
|
28
28
|
|
|
29
29
|
const $ = await this.compose(message.body)
|
|
30
30
|
|
|
31
|
-
message.body = this.
|
|
31
|
+
message.body = this.execute($)
|
|
32
32
|
})
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -41,11 +41,35 @@ export class Compose implements Directive {
|
|
|
41
41
|
|
|
42
42
|
return $
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
private execute ($: unknown[]): unknown {
|
|
46
|
+
let exception: Error | undefined
|
|
47
|
+
|
|
48
|
+
for (const expression of this.expressions)
|
|
49
|
+
try {
|
|
50
|
+
return expression($)
|
|
51
|
+
} catch (e: unknown) {
|
|
52
|
+
exception = e as Error
|
|
53
|
+
console.debug('Chunks composition failed', { cause: exception.message })
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
throw exception!
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function build (composition: any): Expression[] {
|
|
61
|
+
return Array.isArray(composition)
|
|
62
|
+
? composition.map((variant) => compile(variant))
|
|
63
|
+
: [compile(composition)]
|
|
44
64
|
}
|
|
45
65
|
|
|
46
|
-
function compile (composition: object): Expression {
|
|
66
|
+
function compile (composition: object | string): Expression {
|
|
67
|
+
const text = typeof composition === 'string'
|
|
68
|
+
? `return ${composition}`
|
|
69
|
+
: `return ${json(composition)}`
|
|
70
|
+
|
|
47
71
|
// eslint-disable-next-line @typescript-eslint/no-implied-eval,no-new-func
|
|
48
|
-
return new Function('$',
|
|
72
|
+
return new Function('$', text) as Expression
|
|
49
73
|
}
|
|
50
74
|
|
|
51
75
|
function json (node: object | string): string {
|
|
@@ -4,7 +4,7 @@ import * as schemas from './schemas'
|
|
|
4
4
|
import { Workflow } from './workflows'
|
|
5
5
|
import { Directive } from './Directive'
|
|
6
6
|
import type { Parameter } from '../../RTD'
|
|
7
|
-
import type { Unit } from './workflows'
|
|
7
|
+
import type { Unit, Location } from './workflows'
|
|
8
8
|
import type { Maybe } from '@toa.io/types'
|
|
9
9
|
import type { Component } from '@toa.io/core'
|
|
10
10
|
import type { Output } from '../../io'
|
|
@@ -17,7 +17,7 @@ export class Delete extends Directive {
|
|
|
17
17
|
|
|
18
18
|
private readonly workflow?: Workflow
|
|
19
19
|
private readonly discovery: Promise<Component>
|
|
20
|
-
private storage
|
|
20
|
+
private storage!: Component
|
|
21
21
|
|
|
22
22
|
public constructor (options: Options | null, discovery: Promise<Component>, remotes: Remotes) {
|
|
23
23
|
super()
|
|
@@ -55,8 +55,7 @@ export class Delete extends Directive {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
private async delete (storage: string, input: Input): Promise<void> {
|
|
58
|
-
|
|
59
|
-
await this.storage!.invoke('delete',
|
|
58
|
+
await this.storage.invoke('delete',
|
|
60
59
|
{
|
|
61
60
|
input: {
|
|
62
61
|
storage,
|
|
@@ -68,8 +67,13 @@ export class Delete extends Directive {
|
|
|
68
67
|
// eslint-disable-next-line max-params
|
|
69
68
|
private async * execute
|
|
70
69
|
(input: Input, storage: string, entry: Entry, parameters: Parameter[]): AsyncGenerator {
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
const location: Location = {
|
|
71
|
+
storage,
|
|
72
|
+
authority: input.authority,
|
|
73
|
+
path: input.request.url
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
for await (const chunk of this.workflow!.execute(location, entry, parameters)) {
|
|
73
77
|
yield chunk
|
|
74
78
|
|
|
75
79
|
if (typeof chunk === 'object' && chunk !== null && 'error' in chunk)
|
|
@@ -8,7 +8,7 @@ import { Directive } from './Directive'
|
|
|
8
8
|
import { toBytes } from './bytes'
|
|
9
9
|
import type { Readable } from 'stream'
|
|
10
10
|
import type { Parameter } from '../../RTD'
|
|
11
|
-
import type { Unit } from './workflows'
|
|
11
|
+
import type { Unit, Location } from './workflows'
|
|
12
12
|
import type { Entry } from '@toa.io/extensions.storages'
|
|
13
13
|
import type { Remotes } from '../../Remotes'
|
|
14
14
|
import type { Err } from 'error-value'
|
|
@@ -94,7 +94,13 @@ export class Put extends Directive {
|
|
|
94
94
|
|
|
95
95
|
stream.push(entry)
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
const location: Location = {
|
|
98
|
+
storage,
|
|
99
|
+
authority: input.authority,
|
|
100
|
+
path: this.location ?? input.request.url
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
this.workflow!.execute(location, entry, parameters).pipe(stream)
|
|
98
104
|
|
|
99
105
|
return stream
|
|
100
106
|
}
|
|
@@ -2,7 +2,7 @@ import { NotFound } from '../../HTTP'
|
|
|
2
2
|
import * as schemas from './schemas'
|
|
3
3
|
import { Workflow } from './workflows'
|
|
4
4
|
import { Directive } from './Directive'
|
|
5
|
-
import type { Unit } from './workflows'
|
|
5
|
+
import type { Unit, Location } from './workflows'
|
|
6
6
|
import type { Input } from './types'
|
|
7
7
|
import type { Component } from '@toa.io/core'
|
|
8
8
|
import type { Output } from '../../io'
|
|
@@ -40,9 +40,15 @@ export class WorkflowDirective extends Directive {
|
|
|
40
40
|
if (entry instanceof Error)
|
|
41
41
|
throw new NotFound()
|
|
42
42
|
|
|
43
|
+
const location: Location = {
|
|
44
|
+
storage,
|
|
45
|
+
authority: input.authority,
|
|
46
|
+
path: input.request.url
|
|
47
|
+
}
|
|
48
|
+
|
|
43
49
|
return {
|
|
44
50
|
status: 202,
|
|
45
|
-
body: this.workflow.execute(
|
|
51
|
+
body: this.workflow.execute(location, entry, parameters)
|
|
46
52
|
}
|
|
47
53
|
}
|
|
48
54
|
}
|
|
@@ -4,7 +4,6 @@ import { Execution } from './Execution'
|
|
|
4
4
|
import type { Entry } from '@toa.io/extensions.storages'
|
|
5
5
|
import type { Context } from './Execution'
|
|
6
6
|
import type { Parameter } from '../../../RTD'
|
|
7
|
-
import type { Input } from '../types'
|
|
8
7
|
import type { Remotes } from '../../../Remotes'
|
|
9
8
|
|
|
10
9
|
export class Workflow {
|
|
@@ -19,19 +18,28 @@ export class Workflow {
|
|
|
19
18
|
this.remotes = remotes
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
public execute (input: Input, storage: string, entry: Entry, params: Parameter[]): Execution {
|
|
24
|
-
const path = posix.join(input.request.url, entry.id)
|
|
25
|
-
const authority = input.authority
|
|
21
|
+
public execute (location: Location, entry: Entry, params: Parameter[]): Execution {
|
|
26
22
|
const parameters: Record<string, string> = {}
|
|
27
23
|
|
|
28
24
|
for (const { name, value } of params)
|
|
29
25
|
parameters[name] = value
|
|
30
26
|
|
|
31
|
-
const context: Context = {
|
|
27
|
+
const context: Context = {
|
|
28
|
+
authority: location.authority,
|
|
29
|
+
storage: location.storage,
|
|
30
|
+
path: posix.join(location.path, entry.id),
|
|
31
|
+
entry,
|
|
32
|
+
parameters
|
|
33
|
+
}
|
|
32
34
|
|
|
33
35
|
return new Execution(context, this.units, this.remotes)
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
export interface Location {
|
|
40
|
+
storage: string
|
|
41
|
+
authority: string
|
|
42
|
+
path: string
|
|
43
|
+
}
|
|
44
|
+
|
|
37
45
|
export type Unit = Record<string, string>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Workflow, type Unit } from './Workflow'
|
|
1
|
+
export { Workflow, type Unit, type Location } from './Workflow'
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { Directive } from './types';
|
|
2
2
|
import type { Input as Context } from '../../io';
|
|
3
3
|
export declare class Compose implements Directive {
|
|
4
|
-
private readonly
|
|
4
|
+
private readonly expressions;
|
|
5
5
|
constructor(composition: any);
|
|
6
6
|
attach(context: Context): void;
|
|
7
7
|
private compose;
|
|
8
|
+
private execute;
|
|
8
9
|
}
|
|
@@ -29,9 +29,9 @@ const assert = __importStar(require("node:assert"));
|
|
|
29
29
|
const node_stream_1 = require("node:stream");
|
|
30
30
|
const openspan_1 = require("openspan");
|
|
31
31
|
class Compose {
|
|
32
|
-
|
|
32
|
+
expressions;
|
|
33
33
|
constructor(composition) {
|
|
34
|
-
this.
|
|
34
|
+
this.expressions = build(composition);
|
|
35
35
|
}
|
|
36
36
|
attach(context) {
|
|
37
37
|
context.pipelines.response.push(async (message) => {
|
|
@@ -43,7 +43,7 @@ class Compose {
|
|
|
43
43
|
// @ts-expect-error -- objectMode is not defined in the type definition
|
|
44
44
|
assert.ok(message.body._readableState.objectMode, 'Response stream is not in object mode');
|
|
45
45
|
const $ = await this.compose(message.body);
|
|
46
|
-
message.body = this.
|
|
46
|
+
message.body = this.execute($);
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
async compose(stream) {
|
|
@@ -52,11 +52,31 @@ class Compose {
|
|
|
52
52
|
await (0, node_events_1.once)(stream, 'end');
|
|
53
53
|
return $;
|
|
54
54
|
}
|
|
55
|
+
execute($) {
|
|
56
|
+
let exception;
|
|
57
|
+
for (const expression of this.expressions)
|
|
58
|
+
try {
|
|
59
|
+
return expression($);
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
exception = e;
|
|
63
|
+
openspan_1.console.debug('Chunks composition failed', { cause: exception.message });
|
|
64
|
+
}
|
|
65
|
+
throw exception;
|
|
66
|
+
}
|
|
55
67
|
}
|
|
56
68
|
exports.Compose = Compose;
|
|
69
|
+
function build(composition) {
|
|
70
|
+
return Array.isArray(composition)
|
|
71
|
+
? composition.map((variant) => compile(variant))
|
|
72
|
+
: [compile(composition)];
|
|
73
|
+
}
|
|
57
74
|
function compile(composition) {
|
|
75
|
+
const text = typeof composition === 'string'
|
|
76
|
+
? `return ${composition}`
|
|
77
|
+
: `return ${json(composition)}`;
|
|
58
78
|
// eslint-disable-next-line @typescript-eslint/no-implied-eval,no-new-func
|
|
59
|
-
return new Function('$',
|
|
79
|
+
return new Function('$', text);
|
|
60
80
|
}
|
|
61
81
|
function json(node) {
|
|
62
82
|
if (typeof node === 'string')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Compose.js","sourceRoot":"","sources":["../../../source/directives/flow/Compose.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAkC;AAClC,oDAAqC;AACrC,6CAAsC;AACtC,uCAAkC;AAKlC,MAAa,OAAO;IACD,
|
|
1
|
+
{"version":3,"file":"Compose.js","sourceRoot":"","sources":["../../../source/directives/flow/Compose.ts"],"names":[],"mappings":"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"}
|