@toa.io/norm 1.0.0-alpha.28 → 1.0.0-alpha.283
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/CHANGELOG.md +195 -0
- package/package.json +8 -7
- package/src/.component/.expand/bridge.js +2 -6
- package/src/.component/.expand/entity.js +2 -9
- package/src/.component/.expand/events.js +2 -6
- package/src/.component/.expand/extensions.js +4 -8
- package/src/.component/.expand/index.js +8 -19
- package/src/.component/.expand/operations.js +2 -9
- package/src/.component/.expand/properties.js +2 -6
- package/src/.component/.expand/receivers.js +2 -6
- package/src/.component/.expand/version.js +39 -27
- package/src/.component/.normalize/events.js +12 -5
- package/src/.component/.normalize/index.js +3 -9
- package/src/.component/.normalize/operations.js +2 -6
- package/src/.component/.normalize/receivers.js +1 -5
- package/src/.component/collapse.js +7 -6
- package/src/.component/defaults.js +14 -7
- package/src/.component/dependencies.js +7 -6
- package/src/.component/dereference.js +8 -7
- package/src/.component/expand.js +2 -15
- package/src/.component/extensions.js +13 -7
- package/src/.component/index.js +9 -21
- package/src/.component/merge.js +22 -9
- package/src/.component/normalize.js +3 -7
- package/src/.component/schema.yaml +82 -41
- package/src/.component/validate.js +15 -16
- package/src/.context/.dependencies/connectors.js +2 -6
- package/src/.context/.dependencies/describe.js +1 -5
- package/src/.context/.dependencies/extensions.js +55 -18
- package/src/.context/.dependencies/index.js +3 -9
- package/src/.context/.dependencies/load.js +14 -13
- package/src/.context/.dependencies/resolve.js +23 -6
- package/src/.context/complete.js +1 -5
- package/src/.context/dependencies.js +2 -6
- package/src/.context/dereference.js +9 -6
- package/src/.context/expand.js +8 -6
- package/src/.context/index.js +6 -15
- package/src/.context/normalize.js +2 -6
- package/src/.context/schema.yaml +126 -7
- package/src/.context/validate.js +8 -14
- package/src/component.js +31 -28
- package/src/context.js +28 -20
- package/src/index.js +3 -9
- package/src/shortcuts.js +7 -12
- package/test/component/collapse.fixtures.js +2 -5
- package/test/component/collapse.test.js +17 -10
- package/test/component/dependencies.test.js +12 -10
- package/test/component/dereference.fixtures.js +2 -7
- package/test/component/dereference.test.js +9 -8
- package/test/component/dummies/extension/index.js +1 -5
- package/test/component/expand.fixtures.js +13 -13
- package/test/component/expand.test.js +25 -10
- package/test/component/normalize.fixtures.js +3 -7
- package/test/component/normalize.test.js +27 -17
- package/test/component/validate.fixtures.js +1 -5
- package/test/component/validate.test.js +89 -90
- package/test/context/complete.fixtures.js +2 -8
- package/test/context/complete.test.js +10 -8
- package/test/context/dependencies.load.test.js +13 -12
- package/test/context/dereference.fixtures.js +3 -9
- package/test/context/dereference.test.js +17 -7
- package/test/context/expand.fixtures.js +1 -5
- package/test/context/expand.test.js +34 -8
- package/test/context/normalize.fixtures.js +2 -7
- package/test/context/normalize.test.js +10 -8
- package/test/context/validate.fixtures.js +1 -6
- package/test/context/validate.test.js +54 -30
- package/test/shortcuts.fixtures.js +4 -9
- package/test/shortcuts.test.js +16 -15
- package/types/context/declaration.d.ts +25 -2
- package/types/context.d.ts +5 -4
- package/types/index.d.ts +3 -3
package/src/.component/expand.js
CHANGED
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { entity, bridge, operations, events, receivers, extensions, properties, version } from './.expand/index.js'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
entity,
|
|
5
|
-
bridge,
|
|
6
|
-
operations,
|
|
7
|
-
events,
|
|
8
|
-
receivers,
|
|
9
|
-
extensions,
|
|
10
|
-
properties,
|
|
11
|
-
version
|
|
12
|
-
} = require('./.expand')
|
|
13
|
-
|
|
14
|
-
async function expand (manifest) {
|
|
3
|
+
export async function expand (manifest) {
|
|
15
4
|
entity(manifest)
|
|
16
5
|
bridge(manifest)
|
|
17
6
|
operations(manifest)
|
|
@@ -22,5 +11,3 @@ async function expand (manifest) {
|
|
|
22
11
|
|
|
23
12
|
await version(manifest)
|
|
24
13
|
}
|
|
25
|
-
|
|
26
|
-
exports.expand = expand
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { find } from '@toa.io/generic'
|
|
2
|
+
import { resolve } from '../shortcuts.js'
|
|
2
3
|
|
|
3
|
-
const
|
|
4
|
-
const { resolve } = require('../shortcuts')
|
|
4
|
+
const cache = {}
|
|
5
5
|
|
|
6
|
-
const extensions = (manifest) => {
|
|
7
|
-
|
|
6
|
+
export const extensions = async (manifest) => {
|
|
7
|
+
manifest.extensions = Object.assign({}, PREDEFINED, manifest.extensions)
|
|
8
8
|
|
|
9
9
|
const extensions = manifest.extensions
|
|
10
10
|
|
|
@@ -14,7 +14,9 @@ const extensions = (manifest) => {
|
|
|
14
14
|
// relative path
|
|
15
15
|
if (key[0] === '.') key = find(key, manifest.path)
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
cache[key] ??= import(key)
|
|
18
|
+
|
|
19
|
+
const extension = await cache[key]
|
|
18
20
|
|
|
19
21
|
if (extension.manifest !== undefined) {
|
|
20
22
|
declaration = extension.manifest(declaration, manifest)
|
|
@@ -29,4 +31,8 @@ const extensions = (manifest) => {
|
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
const PREDEFINED = {
|
|
35
|
+
'@toa.io/extensions.telemetry': null,
|
|
36
|
+
'@toa.io/extensions.fetch': null,
|
|
37
|
+
'@toa.io/extensions.introspection': null
|
|
38
|
+
}
|
package/src/.component/index.js
CHANGED
|
@@ -1,21 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const { validate } = require('./validate')
|
|
11
|
-
const { extensions } = require('./extensions')
|
|
12
|
-
|
|
13
|
-
exports.collapse = collapse
|
|
14
|
-
exports.defaults = defaults
|
|
15
|
-
exports.dependencies = dependencies
|
|
16
|
-
exports.dereference = dereference
|
|
17
|
-
exports.expand = expand
|
|
18
|
-
exports.merge = merge
|
|
19
|
-
exports.normalize = normalize
|
|
20
|
-
exports.validate = validate
|
|
21
|
-
exports.extensions = extensions
|
|
1
|
+
export { collapse } from './collapse.js'
|
|
2
|
+
export { defaults } from './defaults.js'
|
|
3
|
+
export { dependencies } from './dependencies.js'
|
|
4
|
+
export { dereference } from './dereference.js'
|
|
5
|
+
export { expand } from './expand.js'
|
|
6
|
+
export { merge } from './merge.js'
|
|
7
|
+
export { normalize } from './normalize.js'
|
|
8
|
+
export { validate } from './validate.js'
|
|
9
|
+
export { extensions } from './extensions.js'
|
package/src/.component/merge.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const { merge } = require('@toa.io/generic')
|
|
1
|
+
import { merge } from '@toa.io/generic'
|
|
4
2
|
|
|
5
3
|
const bridge = async (root, manifest) => {
|
|
6
4
|
await Promise.all([
|
|
7
5
|
define(root, manifest, 'operations'),
|
|
8
6
|
define(root, manifest, 'events'),
|
|
9
|
-
define(root, manifest, 'receivers')
|
|
7
|
+
define(root, manifest, 'receivers'),
|
|
8
|
+
define(root, manifest, 'guards')
|
|
10
9
|
])
|
|
11
10
|
}
|
|
12
11
|
|
|
@@ -19,7 +18,7 @@ const define = async (root, manifest, property) => {
|
|
|
19
18
|
if (item.bridge === undefined || item.bridge === manifest.bridge) continue // default bridge later
|
|
20
19
|
|
|
21
20
|
const bridge = item.bridge || manifest.bridge
|
|
22
|
-
const { define } =
|
|
21
|
+
const { define } = await req(bridge)
|
|
23
22
|
const definition = await define[singular](root, endpoint)
|
|
24
23
|
|
|
25
24
|
merge(item, definition)
|
|
@@ -44,18 +43,32 @@ const define = async (root, manifest, property) => {
|
|
|
44
43
|
|
|
45
44
|
const declared = manifest[property][endpoint]
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
try {
|
|
47
|
+
if (declared === undefined) manifest[property][endpoint] = item
|
|
48
|
+
else merge(declared, item)
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error(`Error merging ${singular} '${endpoint}' in ${root}`)
|
|
51
|
+
throw error
|
|
52
|
+
}
|
|
49
53
|
}
|
|
50
54
|
}
|
|
51
55
|
}
|
|
52
56
|
|
|
57
|
+
const cache = {}
|
|
58
|
+
|
|
59
|
+
// the promise is what is remembered, so a bridge is loaded once
|
|
60
|
+
function req (mod) {
|
|
61
|
+
cache[mod] ??= import(mod)
|
|
62
|
+
|
|
63
|
+
return cache[mod]
|
|
64
|
+
}
|
|
65
|
+
|
|
53
66
|
const scan = async (bridge, root, property) => {
|
|
54
|
-
const { define } =
|
|
67
|
+
const { define } = await req(bridge)
|
|
55
68
|
|
|
56
69
|
if (property in define)
|
|
57
70
|
return define[property](root)
|
|
58
71
|
else return undefined
|
|
59
72
|
}
|
|
60
73
|
|
|
61
|
-
|
|
74
|
+
export { bridge as merge }
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { events, operations, receivers } from './.normalize/index.js'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
const normalize = (component) => {
|
|
3
|
+
export const normalize = async (component) => {
|
|
6
4
|
operations(component)
|
|
7
|
-
events(component)
|
|
5
|
+
await events(component)
|
|
8
6
|
receivers(component)
|
|
9
7
|
}
|
|
10
|
-
|
|
11
|
-
exports.normalize = normalize
|
|
@@ -8,7 +8,7 @@ definitions:
|
|
|
8
8
|
binding:
|
|
9
9
|
type: string
|
|
10
10
|
not:
|
|
11
|
-
const:
|
|
11
|
+
const: "@toa.io/bindings.loop" # loop is for system use only
|
|
12
12
|
|
|
13
13
|
type: object
|
|
14
14
|
properties:
|
|
@@ -17,19 +17,19 @@ properties:
|
|
|
17
17
|
nullable: true
|
|
18
18
|
properties:
|
|
19
19
|
prototype:
|
|
20
|
-
$ref:
|
|
20
|
+
$ref: "#/properties/prototype"
|
|
21
21
|
path:
|
|
22
22
|
type: string
|
|
23
23
|
operations:
|
|
24
24
|
type: object
|
|
25
25
|
propertyNames:
|
|
26
|
-
$ref:
|
|
26
|
+
$ref: "#/definitions/name"
|
|
27
27
|
patternProperties:
|
|
28
|
-
|
|
28
|
+
".*":
|
|
29
29
|
type: object
|
|
30
30
|
properties:
|
|
31
31
|
bridge:
|
|
32
|
-
$ref:
|
|
32
|
+
$ref: "#/properties/bridge"
|
|
33
33
|
|
|
34
34
|
path:
|
|
35
35
|
type: string
|
|
@@ -38,19 +38,23 @@ properties:
|
|
|
38
38
|
type: object
|
|
39
39
|
properties:
|
|
40
40
|
id:
|
|
41
|
-
|
|
41
|
+
type: string
|
|
42
|
+
pattern: ^([a-zA-Z]+([_a-zA-Z0-9]*[a-zA-Z0-9]+)?)(\.([a-zA-Z]+([_a-zA-Z0-9]*[a-zA-Z0-9]+)?))$
|
|
42
43
|
label:
|
|
43
|
-
|
|
44
|
+
type: string
|
|
45
|
+
pattern: ^([a-zA-Z]+([_a-zA-Z0-9]*[a-zA-Z0-9]+)?)(-([a-zA-Z]+([_a-zA-Z0-9]*[a-zA-Z0-9]+)?))*$
|
|
44
46
|
|
|
45
47
|
name:
|
|
46
|
-
|
|
48
|
+
type: string
|
|
49
|
+
pattern: ^[a-zA-Z]([a-zA-Z0-9]{1,31})?$
|
|
47
50
|
|
|
48
51
|
namespace:
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
type: string
|
|
53
|
+
pattern: ^[a-zA-Z]([a-zA-Z0-9]{1,31})?$
|
|
54
|
+
default: "default"
|
|
51
55
|
not:
|
|
52
56
|
oneOf:
|
|
53
|
-
- const:
|
|
57
|
+
- const: "system"
|
|
54
58
|
|
|
55
59
|
version:
|
|
56
60
|
type: string
|
|
@@ -60,15 +64,17 @@ properties:
|
|
|
60
64
|
properties:
|
|
61
65
|
image:
|
|
62
66
|
type: string
|
|
67
|
+
run:
|
|
68
|
+
type: string
|
|
63
69
|
|
|
64
70
|
entity:
|
|
65
71
|
type: object
|
|
66
72
|
properties:
|
|
67
73
|
storage:
|
|
68
74
|
type: string
|
|
69
|
-
default:
|
|
75
|
+
default: "@toa.io/storages.mongodb"
|
|
70
76
|
schema:
|
|
71
|
-
$ref:
|
|
77
|
+
$ref: https://json-schema.org/draft/2019-09/schema
|
|
72
78
|
type: object
|
|
73
79
|
properties:
|
|
74
80
|
type:
|
|
@@ -78,24 +84,24 @@ properties:
|
|
|
78
84
|
type: object
|
|
79
85
|
propertyNames:
|
|
80
86
|
oneOf:
|
|
81
|
-
- $ref:
|
|
87
|
+
- $ref: "#/definitions/name"
|
|
82
88
|
- enum: [_version, _created, _updated, _deleted]
|
|
83
89
|
unique:
|
|
84
90
|
type: object
|
|
85
91
|
patternProperties:
|
|
86
|
-
|
|
92
|
+
".*":
|
|
87
93
|
type: array
|
|
88
94
|
items:
|
|
89
95
|
type: string
|
|
90
96
|
index:
|
|
91
97
|
type: object
|
|
92
98
|
patternProperties:
|
|
93
|
-
|
|
99
|
+
".*":
|
|
94
100
|
type: object
|
|
95
101
|
patternProperties:
|
|
96
|
-
|
|
102
|
+
".*":
|
|
97
103
|
type: string
|
|
98
|
-
enum: [asc, desc, hash]
|
|
104
|
+
enum: [asc, desc, hash, text]
|
|
99
105
|
associated:
|
|
100
106
|
type: boolean
|
|
101
107
|
default: false
|
|
@@ -109,7 +115,7 @@ properties:
|
|
|
109
115
|
type: array
|
|
110
116
|
uniqueItems: true
|
|
111
117
|
items:
|
|
112
|
-
$ref:
|
|
118
|
+
$ref: "#/definitions/binding"
|
|
113
119
|
|
|
114
120
|
bridge:
|
|
115
121
|
type: string
|
|
@@ -117,27 +123,41 @@ properties:
|
|
|
117
123
|
operations:
|
|
118
124
|
type: object
|
|
119
125
|
propertyNames:
|
|
120
|
-
$ref:
|
|
126
|
+
$ref: "#/definitions/name"
|
|
121
127
|
patternProperties:
|
|
122
|
-
|
|
128
|
+
".*":
|
|
123
129
|
type: object
|
|
124
130
|
properties:
|
|
125
131
|
type:
|
|
126
|
-
enum:
|
|
132
|
+
enum:
|
|
133
|
+
[
|
|
134
|
+
transition,
|
|
135
|
+
observation,
|
|
136
|
+
assignment,
|
|
137
|
+
computation,
|
|
138
|
+
effect,
|
|
139
|
+
unmanaged,
|
|
140
|
+
]
|
|
127
141
|
scope:
|
|
128
|
-
enum: [object, objects, changeset, none]
|
|
142
|
+
enum: [object, objects, changeset, stream, none]
|
|
129
143
|
concurrency:
|
|
130
144
|
enum: [none, retry]
|
|
131
145
|
forward:
|
|
132
|
-
$ref:
|
|
146
|
+
$ref: "#/definitions/name"
|
|
133
147
|
bridge:
|
|
134
148
|
type: string
|
|
135
149
|
bindings:
|
|
136
|
-
$ref:
|
|
150
|
+
$ref: "#/properties/bindings"
|
|
137
151
|
input:
|
|
138
|
-
$ref:
|
|
152
|
+
$ref: https://json-schema.org/draft/2019-09/schema
|
|
139
153
|
output:
|
|
140
|
-
$ref:
|
|
154
|
+
$ref: https://json-schema.org/draft/2019-09/schema
|
|
155
|
+
default: {}
|
|
156
|
+
errors:
|
|
157
|
+
# what a reply may carry as a code: the error schema allows either
|
|
158
|
+
type: array
|
|
159
|
+
items:
|
|
160
|
+
type: [string, integer]
|
|
141
161
|
query:
|
|
142
162
|
type: boolean
|
|
143
163
|
required: [type, scope, bindings]
|
|
@@ -149,8 +169,8 @@ properties:
|
|
|
149
169
|
then:
|
|
150
170
|
properties:
|
|
151
171
|
scope:
|
|
152
|
-
enum: [object]
|
|
153
|
-
if: #
|
|
172
|
+
enum: [object, objects]
|
|
173
|
+
if: # not query: false
|
|
154
174
|
not:
|
|
155
175
|
properties:
|
|
156
176
|
query:
|
|
@@ -158,6 +178,17 @@ properties:
|
|
|
158
178
|
required: [query]
|
|
159
179
|
then:
|
|
160
180
|
required: [concurrency]
|
|
181
|
+
- if: # transition and scope=objects
|
|
182
|
+
properties:
|
|
183
|
+
type:
|
|
184
|
+
const: transition
|
|
185
|
+
scope:
|
|
186
|
+
const: objects
|
|
187
|
+
then:
|
|
188
|
+
properties:
|
|
189
|
+
query:
|
|
190
|
+
not:
|
|
191
|
+
const: false
|
|
161
192
|
- if: # not transition
|
|
162
193
|
not:
|
|
163
194
|
properties:
|
|
@@ -174,7 +205,7 @@ properties:
|
|
|
174
205
|
then:
|
|
175
206
|
properties:
|
|
176
207
|
scope:
|
|
177
|
-
enum: [object, objects, none]
|
|
208
|
+
enum: [object, objects, stream, none]
|
|
178
209
|
query:
|
|
179
210
|
not:
|
|
180
211
|
const: false
|
|
@@ -189,7 +220,7 @@ properties:
|
|
|
189
220
|
- if: # computation
|
|
190
221
|
properties:
|
|
191
222
|
type:
|
|
192
|
-
|
|
223
|
+
enum: [computation, unmanaged]
|
|
193
224
|
then:
|
|
194
225
|
properties:
|
|
195
226
|
scope:
|
|
@@ -205,20 +236,17 @@ properties:
|
|
|
205
236
|
then:
|
|
206
237
|
properties:
|
|
207
238
|
scope:
|
|
208
|
-
const: none
|
|
209
239
|
default: none
|
|
210
|
-
|
|
211
|
-
const: false
|
|
212
|
-
default: false
|
|
240
|
+
enum: [object, objects, stream, none]
|
|
213
241
|
additionalProperties: false
|
|
214
242
|
additionalProperties: false
|
|
215
243
|
|
|
216
244
|
events:
|
|
217
245
|
type: object
|
|
218
246
|
propertyNames:
|
|
219
|
-
$ref:
|
|
247
|
+
$ref: "#/definitions/name"
|
|
220
248
|
patternProperties:
|
|
221
|
-
|
|
249
|
+
".*":
|
|
222
250
|
type: object
|
|
223
251
|
properties:
|
|
224
252
|
bridge:
|
|
@@ -226,7 +254,7 @@ properties:
|
|
|
226
254
|
path:
|
|
227
255
|
type: string
|
|
228
256
|
binding:
|
|
229
|
-
$ref:
|
|
257
|
+
$ref: "#/definitions/binding"
|
|
230
258
|
conditioned:
|
|
231
259
|
type: boolean
|
|
232
260
|
default: false
|
|
@@ -239,17 +267,17 @@ properties:
|
|
|
239
267
|
receivers:
|
|
240
268
|
type: object
|
|
241
269
|
patternProperties:
|
|
242
|
-
|
|
270
|
+
".*":
|
|
243
271
|
type: object
|
|
244
272
|
properties:
|
|
245
273
|
operation:
|
|
246
|
-
$ref:
|
|
274
|
+
$ref: "#/definitions/name"
|
|
247
275
|
bridge:
|
|
248
276
|
type: string
|
|
249
277
|
binding:
|
|
250
278
|
type: string
|
|
251
279
|
source:
|
|
252
|
-
$ref:
|
|
280
|
+
$ref: "#/definitions/name"
|
|
253
281
|
not:
|
|
254
282
|
const: context
|
|
255
283
|
path:
|
|
@@ -260,9 +288,22 @@ properties:
|
|
|
260
288
|
adaptive:
|
|
261
289
|
type: boolean
|
|
262
290
|
default: false
|
|
291
|
+
arguments:
|
|
292
|
+
type: array
|
|
263
293
|
required: [operation]
|
|
264
294
|
additionalProperties: false
|
|
265
295
|
|
|
296
|
+
guards:
|
|
297
|
+
type: object
|
|
298
|
+
patternProperties:
|
|
299
|
+
".*":
|
|
300
|
+
type: object
|
|
301
|
+
properties:
|
|
302
|
+
bridge: { type: string }
|
|
303
|
+
path: { type: string }
|
|
304
|
+
required: [bridge, path]
|
|
305
|
+
additionalProperties: false
|
|
306
|
+
|
|
266
307
|
extensions:
|
|
267
308
|
type: object
|
|
268
309
|
|
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
|
|
1
|
+
import path from 'node:path'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { readFileSync } from 'node:fs'
|
|
4
|
+
import { yaml } from '@toa.io/generic'
|
|
5
|
+
import * as schemas from '@toa.io/schemas'
|
|
4
6
|
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
+
const object = yaml.load(readFileSync(path.resolve(import.meta.dirname, 'schema.yaml'), 'utf8'))
|
|
8
|
+
const schema = schemas.schema(object)
|
|
7
9
|
|
|
8
|
-
const
|
|
9
|
-
const schema = new Schema(object)
|
|
10
|
-
|
|
11
|
-
const validate = (manifest) => {
|
|
10
|
+
export const validate = async (manifest) => {
|
|
12
11
|
const error = schema.fit(manifest)
|
|
13
12
|
|
|
14
|
-
if (error) throw
|
|
13
|
+
if (error) throw error
|
|
15
14
|
|
|
16
|
-
if (manifest.events !== undefined) events(manifest)
|
|
15
|
+
if (manifest.events !== undefined) await events(manifest)
|
|
17
16
|
if (manifest.receivers !== undefined) receivers(manifest)
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
const events = (manifest) => {
|
|
19
|
+
const events = async (manifest) => {
|
|
21
20
|
for (const [label, event] of Object.entries(manifest.events)) {
|
|
22
|
-
|
|
21
|
+
const { properties } = await import(event.binding)
|
|
22
|
+
|
|
23
|
+
if (properties.async !== true) {
|
|
23
24
|
throw new Error(`Event '${label}' binding '${event.binding}' is not async`)
|
|
24
25
|
}
|
|
25
26
|
}
|
|
@@ -32,11 +33,9 @@ const receivers = (manifest) => {
|
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
if (!TYPES.has(manifest.operations[receiver.operation].type)) {
|
|
35
|
-
throw new Error(`Receiver '${locator}' must refer to an operation of
|
|
36
|
+
throw new Error(`Receiver '${locator}' must refer to an operation of the allowed types: ${Array.from(TYPES).join(', ')}`)
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
const TYPES = new Set(['transition', 'effect'])
|
|
41
|
-
|
|
42
|
-
exports.validate = validate
|
|
41
|
+
const TYPES = new Set(['transition', 'assignment', 'effect', 'unmanaged'])
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { resolve } from 'node:path'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
const connectors = (context, extracted) => {
|
|
3
|
+
export const connectors = (context, extracted) => {
|
|
6
4
|
const connectors = {}
|
|
7
5
|
|
|
8
6
|
const components = (context.components === undefined
|
|
@@ -47,5 +45,3 @@ const connectors = (context, extracted) => {
|
|
|
47
45
|
|
|
48
46
|
return connectors
|
|
49
47
|
}
|
|
50
|
-
|
|
51
|
-
exports.connectors = connectors
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* @param {toa.norm.Component} component
|
|
5
3
|
* @param {Object} manifest
|
|
6
4
|
* @returns {toa.norm.context.dependencies.Instance}
|
|
7
5
|
*/
|
|
8
|
-
const describe = (component, manifest = undefined) => ({ locator: component.locator, manifest })
|
|
9
|
-
|
|
10
|
-
exports.describe = describe
|
|
6
|
+
export const describe = (component, manifest = undefined) => ({ locator: component.locator, manifest })
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
import { component as load } from '../../component.js'
|
|
2
|
+
import { load as loadDependency } from './load.js'
|
|
2
3
|
|
|
3
|
-
const extensions = async (context) => {
|
|
4
|
+
export const extensions = async (context) => {
|
|
4
5
|
const extensions = {}
|
|
5
6
|
const components = context.components?.slice() ?? []
|
|
6
|
-
|
|
7
|
+
|
|
8
|
+
// an extension a composition runs may be referenced by no component of this context,
|
|
9
|
+
// and its own components must be extracted all the same
|
|
10
|
+
const declared = await extractDeclaredServices(context, extensions)
|
|
11
|
+
|
|
12
|
+
const extracted = declared.concat(
|
|
13
|
+
await extractExtensionComponents(components.concat(declared), extensions, context.annotations))
|
|
7
14
|
|
|
8
15
|
components.push(...extracted)
|
|
9
16
|
|
|
@@ -20,8 +27,25 @@ const extensions = async (context) => {
|
|
|
20
27
|
return { extensions, components: extracted }
|
|
21
28
|
}
|
|
22
29
|
|
|
23
|
-
async function
|
|
24
|
-
const
|
|
30
|
+
async function extractDeclaredServices (context, extensions) {
|
|
31
|
+
const extracted = []
|
|
32
|
+
|
|
33
|
+
for (const composition of context.compositions ?? [])
|
|
34
|
+
for (const reference of composition.services ?? []) {
|
|
35
|
+
if (reference in extensions) continue
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
extracted.push(...await extract(reference, extensions, context.annotations))
|
|
39
|
+
} catch (e) {
|
|
40
|
+
throw new Error(`Composition '${composition.name}' lists '${reference}', ` +
|
|
41
|
+
`which cannot be resolved: ${e.message}`, { cause: e })
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return extracted
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function extractExtensionComponents (components, extensions, annotations) {
|
|
25
49
|
|
|
26
50
|
const extracted = []
|
|
27
51
|
|
|
@@ -31,26 +55,39 @@ async function extractExtensionComponents (components, extensions) {
|
|
|
31
55
|
for (const reference of Object.keys(component.extensions)) {
|
|
32
56
|
if (reference in extensions) continue
|
|
33
57
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const mod = require(reference)
|
|
37
|
-
|
|
38
|
-
if (mod.components === undefined) continue
|
|
39
|
-
|
|
40
|
-
for (const path of mod.components().paths) {
|
|
41
|
-
const component = await load(path)
|
|
42
|
-
|
|
43
|
-
extracted.push(component)
|
|
44
|
-
}
|
|
58
|
+
extracted.push(...await extract(reference, extensions, annotations))
|
|
45
59
|
}
|
|
46
60
|
}
|
|
47
61
|
|
|
48
62
|
if (extracted.length === 0)
|
|
49
63
|
return extracted
|
|
50
64
|
|
|
51
|
-
const deeper = await extractExtensionComponents(extracted, extensions)
|
|
65
|
+
const deeper = await extractExtensionComponents(extracted, extensions, annotations)
|
|
52
66
|
|
|
53
67
|
return extracted.concat(deeper)
|
|
54
68
|
}
|
|
55
69
|
|
|
56
|
-
|
|
70
|
+
/**
|
|
71
|
+
* The components an extension contributes, if it contributes any.
|
|
72
|
+
*
|
|
73
|
+
* @param {string} reference
|
|
74
|
+
* @param {object} extensions
|
|
75
|
+
* @param {object} [annotations]
|
|
76
|
+
* @returns {Promise<Array<toa.norm.Component>>}
|
|
77
|
+
*/
|
|
78
|
+
async function extract (reference, extensions, annotations) {
|
|
79
|
+
extensions[reference] = []
|
|
80
|
+
|
|
81
|
+
const { metadata, module: mod } = await loadDependency(reference)
|
|
82
|
+
|
|
83
|
+
if (mod.components === undefined) return []
|
|
84
|
+
|
|
85
|
+
// the annotation decides whether an extension contributes components at all
|
|
86
|
+
const annotation = annotations?.[metadata?.name ?? reference]
|
|
87
|
+
const extracted = []
|
|
88
|
+
|
|
89
|
+
for (const path of mod.components(annotation).paths)
|
|
90
|
+
extracted.push(await load(path))
|
|
91
|
+
|
|
92
|
+
return extracted
|
|
93
|
+
}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const { extensions } = require('./extensions')
|
|
5
|
-
const { resolve } = require('./resolve')
|
|
6
|
-
|
|
7
|
-
exports.connectors = connectors
|
|
8
|
-
exports.extensions = extensions
|
|
9
|
-
exports.resolve = resolve
|
|
1
|
+
export { connectors } from './connectors.js'
|
|
2
|
+
export { extensions } from './extensions.js'
|
|
3
|
+
export { resolve } from './resolve.js'
|