@toa.io/norm 1.0.0-alpha.28 → 1.0.0-alpha.282
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 +184 -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 +81 -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 +11 -10
- 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 +1 -5
- package/src/.context/expand.js +2 -6
- package/src/.context/index.js +6 -15
- package/src/.context/normalize.js +2 -6
- package/src/.context/schema.yaml +115 -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 +8 -7
- package/test/context/expand.fixtures.js +1 -5
- package/test/context/expand.test.js +9 -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 +31 -30
- package/test/shortcuts.fixtures.js +4 -9
- package/test/shortcuts.test.js +16 -15
- package/types/context/declaration.d.ts +23 -2
- package/types/context.d.ts +2 -2
- package/types/index.d.ts +3 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
+
|
|
6
|
+
# [1.0.0-alpha.282](https://github.com/toa-io/toa/compare/v1.0.0-alpha.281...v1.0.0-alpha.282) (2026-09-03)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @toa.io/norm
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [1.0.0-alpha.278](https://github.com/toa-io/toa/compare/v1.0.0-alpha.277...v1.0.0-alpha.278) (2026-09-03)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @toa.io/norm
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# [1.0.0-alpha.277](https://github.com/toa-io/toa/compare/v1.0.0-alpha.276...v1.0.0-alpha.277) (2026-09-03)
|
|
23
|
+
|
|
24
|
+
### Bug Fixes
|
|
25
|
+
|
|
26
|
+
* read a manifest the way js-yaml read one before ([fcea1b2](https://github.com/toa-io/toa/commit/fcea1b21996d6efa6c3198acbfc9f70f1ce0c35c))
|
|
27
|
+
* settle what the module loader made asynchronous ([d4ab9df](https://github.com/toa-io/toa/commit/d4ab9dfb09e382da311dba08f52214e7645f4a6c))
|
|
28
|
+
* what the loader resolves, and what it will not ([1b8a02f](https://github.com/toa-io/toa/commit/1b8a02ff0a5e0f18ee62e3f71bc81116f86f9af1))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# [1.0.0-alpha.274](https://github.com/toa-io/toa/compare/v1.0.0-alpha.273...v1.0.0-alpha.274) (2026-09-02)
|
|
32
|
+
|
|
33
|
+
**Note:** Version bump only for package @toa.io/norm
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# [1.0.0-alpha.273](https://github.com/toa-io/toa/compare/v1.0.0-alpha.272...v1.0.0-alpha.273) (2026-09-02)
|
|
40
|
+
|
|
41
|
+
**Note:** Version bump only for package @toa.io/norm
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# [1.0.0-alpha.272](https://github.com/toa-io/toa/compare/v1.0.0-alpha.271...v1.0.0-alpha.272) (2026-09-01)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Bug Fixes
|
|
51
|
+
|
|
52
|
+
* **atomicity:** honour a cluster, and let it be unreachable ([c475d66](https://github.com/toa-io/toa/commit/c475d663ddf7329d86da517ccceee4cb03280e95))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
* feat(atomicity)!: take a quorum of independent servers ([862562f](https://github.com/toa-io/toa/commit/862562f24d77ec00127dbbd88d43802b208c643b))
|
|
56
|
+
* refactor(atomicity)!: take one Redis, not a cluster ([b0a4770](https://github.com/toa-io/toa/commit/b0a4770dff5dfe8fee4b9ae637a4dd297454fcd4))
|
|
57
|
+
* refactor(atomicity)!: take the lock manager from the stash ([4fd91eb](https://github.com/toa-io/toa/commit/4fd91eb2fdb68f7b87aaf16d182794bbc567ba57))
|
|
58
|
+
* refactor(core)!: pump the outbox in one cycle ([bf590fe](https://github.com/toa-io/toa/commit/bf590fe8ed59c701b5fd1a91ba4874685b79242f))
|
|
59
|
+
* refactor(atomicity)!: rename the connector and free it of the outbox ([21f1a41](https://github.com/toa-io/toa/commit/21f1a41aceafcfd35c7620014062fe46b54afa95))
|
|
60
|
+
* feat(core)!: commit events with the state that produced them ([1eb68cc](https://github.com/toa-io/toa/commit/1eb68cc435dbfa03faa16009fceb866693d22e1a)), closes [#20](https://github.com/toa-io/toa/issues/20)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
### Features
|
|
64
|
+
|
|
65
|
+
* **atomicity:** make the interval a setting, and stop repeating n-and-i ([5c3a6d1](https://github.com/toa-io/toa/commit/5c3a6d1533751a21b7eb7d9c737f1a270bf5a5ae))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### BREAKING CHANGES
|
|
69
|
+
|
|
70
|
+
* `atomicity.redis` accepts a list again, of independent servers rather
|
|
71
|
+
than cluster nodes, and refuses an even number of them.
|
|
72
|
+
|
|
73
|
+
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
74
|
+
* `atomicity.redis` is a string. A list is refused at export.
|
|
75
|
+
|
|
76
|
+
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
77
|
+
* `context.stash.lock` is gone; lock through `context.atom` instead.
|
|
78
|
+
A stash pointer resolving to several addresses now uses the first.
|
|
79
|
+
|
|
80
|
+
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
81
|
+
* `Storage.outbox.pending` takes a fourth argument, the id to
|
|
82
|
+
continue from.
|
|
83
|
+
|
|
84
|
+
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
85
|
+
* `@toa.io/partitions.redis` is now `@toa.io/atomicity`, and its
|
|
86
|
+
`lanes(total)` is `slots(total)`. Redis is declared as `atomicity` in the context
|
|
87
|
+
rather than `outbox.redis`, and read from `TOA_ATOMICITY_REDIS`.
|
|
88
|
+
`TOA_OUTBOX_PARTITION_INTERVAL` is `TOA_ATOMICITY_INTERVAL`.
|
|
89
|
+
|
|
90
|
+
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
91
|
+
* `event.changeset` is removed; use `origin` and `state`. `State`
|
|
92
|
+
takes an `Outbox` in place of an `Emission`. `difference` is dropped from
|
|
93
|
+
`@toa.io/generic` along with its last caller.
|
|
94
|
+
|
|
95
|
+
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# [1.0.0-alpha.270](https://github.com/toa-io/toa/compare/v1.0.0-alpha.269...v1.0.0-alpha.270) (2026-08-31)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
### Bug Fixes
|
|
105
|
+
|
|
106
|
+
* **norm:** resolve annotations keyed by a dependency id ([e2860cd](https://github.com/toa-io/toa/commit/e2860cd2cc93dd3a135c092db1d943f80648ee56))
|
|
107
|
+
* **norm:** return the hash after hashing a file ([35058bd](https://github.com/toa-io/toa/commit/35058bdaae19f367197ea5b800742349e507ab11))
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
### Performance Improvements
|
|
111
|
+
|
|
112
|
+
* **boot:** stop paying for what a composition does not need to start ([1619c27](https://github.com/toa-io/toa/commit/1619c2743072f4706939ce72f3074e615d26a91e))
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# [1.0.0-alpha.266](https://github.com/toa-io/toa/compare/v1.0.0-alpha.265...v1.0.0-alpha.266) (2026-08-29)
|
|
119
|
+
|
|
120
|
+
**Note:** Version bump only for package @toa.io/norm
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# [1.0.0-alpha.265](https://github.com/toa-io/toa/compare/v1.0.0-alpha.264...v1.0.0-alpha.265) (2026-08-29)
|
|
127
|
+
|
|
128
|
+
**Note:** Version bump only for package @toa.io/norm
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# [1.0.0-alpha.264](https://github.com/toa-io/toa/compare/v1.0.0-alpha.263...v1.0.0-alpha.264) (2026-08-29)
|
|
135
|
+
|
|
136
|
+
**Note:** Version bump only for package @toa.io/norm
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# [1.0.0-alpha.263](https://github.com/toa-io/toa/compare/v1.0.0-alpha.262...v1.0.0-alpha.263) (2026-08-29)
|
|
143
|
+
|
|
144
|
+
**Note:** Version bump only for package @toa.io/norm
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
# [1.0.0-alpha.262](https://github.com/toa-io/toa/compare/v1.0.0-alpha.261...v1.0.0-alpha.262) (2026-08-28)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
### Features
|
|
154
|
+
|
|
155
|
+
* **introspection:** add the introspection extension ([a07ed86](https://github.com/toa-io/toa/commit/a07ed8651404258d544f3b6d8236e58cf4da09ac))
|
|
156
|
+
* **operations:** let a service claim a path prefix on the host ([02677d1](https://github.com/toa-io/toa/commit/02677d17fcd4222b07c3be458d93bcc496a016a8))
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
# [1.0.0-alpha.259](https://github.com/toa-io/toa/compare/v1.0.0-alpha.258...v1.0.0-alpha.259) (2026-08-24)
|
|
163
|
+
|
|
164
|
+
**Note:** Version bump only for package @toa.io/norm
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# [1.0.0-alpha.257](https://github.com/toa-io/toa/compare/v1.0.0-alpha.256...v1.0.0-alpha.257) (2026-08-24)
|
|
171
|
+
|
|
172
|
+
**Note:** Version bump only for package @toa.io/norm
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
# [1.0.0-alpha.256](https://github.com/toa-io/toa/compare/v1.0.0-alpha.255...v1.0.0-alpha.256) (2026-08-23)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
### Features
|
|
182
|
+
|
|
183
|
+
* add toa mono and discover components at components/* ([787a111](https://github.com/toa-io/toa/commit/787a111c8f83e56ebc734801c97106c585d034ea))
|
|
184
|
+
* deploy a single mono image with toa deploy --mono ([a7f14f9](https://github.com/toa-io/toa/commit/a7f14f9877a280e9c74d16c195028b35d74fb15a))
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/norm",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.282",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "Toa declarations normalization and validation",
|
|
5
6
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
6
7
|
"homepage": "https://github.com/toa-io/toa#readme",
|
|
@@ -20,11 +21,11 @@
|
|
|
20
21
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
21
22
|
},
|
|
22
23
|
"dependencies": {
|
|
23
|
-
"@toa.io/core": "1.0.0-alpha.
|
|
24
|
-
"@toa.io/generic": "1.0.0-alpha.
|
|
25
|
-
"@toa.io/
|
|
26
|
-
"
|
|
27
|
-
"
|
|
24
|
+
"@toa.io/core": "1.0.0-alpha.282",
|
|
25
|
+
"@toa.io/generic": "1.0.0-alpha.282",
|
|
26
|
+
"@toa.io/schemas": "1.0.0-alpha.282",
|
|
27
|
+
"fast-glob": "3.3.3",
|
|
28
|
+
"js-yaml": "5.4.1"
|
|
28
29
|
},
|
|
29
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "4007c814725dd015d3bbebb9a28e28a247645c4f"
|
|
30
31
|
}
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { resolve } from '../../shortcuts.js'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const { resolve } = require('../../shortcuts')
|
|
6
|
-
|
|
7
|
-
function entity (manifest) {
|
|
3
|
+
export function entity (manifest) {
|
|
8
4
|
if (!('entity' in manifest)) return
|
|
9
|
-
if ('schema' in manifest.entity) manifest.entity.schema = expand(manifest.entity.schema)
|
|
10
5
|
|
|
11
6
|
manifest.entity.storage = resolve(manifest.entity.storage)
|
|
12
7
|
}
|
|
13
|
-
|
|
14
|
-
exports.entity = entity
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { resolve } from '../../shortcuts.js'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function events (manifest) {
|
|
3
|
+
export function events (manifest) {
|
|
6
4
|
if (manifest.events === undefined) return
|
|
7
5
|
|
|
8
6
|
for (const event of Object.values(manifest.events)) {
|
|
@@ -10,5 +8,3 @@ function events (manifest) {
|
|
|
10
8
|
if (event.bridge !== undefined) event.bridge = resolve(event.bridge)
|
|
11
9
|
}
|
|
12
10
|
}
|
|
13
|
-
|
|
14
|
-
exports.events = events
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { recognize } from '../../shortcuts.js'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function extensions (manifest) {
|
|
3
|
+
export function extensions (manifest) {
|
|
6
4
|
recognize(SHORTCUTS, manifest, 'extensions')
|
|
7
5
|
recognize(SHORTCUTS, manifest.extensions)
|
|
8
6
|
}
|
|
@@ -10,11 +8,9 @@ function extensions (manifest) {
|
|
|
10
8
|
const SHORTCUTS = {
|
|
11
9
|
exposition: '@toa.io/extensions.exposition',
|
|
12
10
|
realtime: '@toa.io/extensions.realtime',
|
|
13
|
-
origins: '@toa.io/extensions.origins',
|
|
14
11
|
configuration: '@toa.io/extensions.configuration',
|
|
15
12
|
state: '@toa.io/extensions.state',
|
|
16
13
|
stash: '@toa.io/extensions.stash',
|
|
17
|
-
storages: '@toa.io/extensions.storages'
|
|
14
|
+
storages: '@toa.io/extensions.storages',
|
|
15
|
+
introspection: '@toa.io/extensions.introspection'
|
|
18
16
|
}
|
|
19
|
-
|
|
20
|
-
exports.extensions = extensions
|
|
@@ -1,19 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const { receivers } = require('./receivers')
|
|
10
|
-
const { version } = require('./version')
|
|
11
|
-
|
|
12
|
-
exports.bridge = bridge
|
|
13
|
-
exports.entity = entity
|
|
14
|
-
exports.events = events
|
|
15
|
-
exports.extensions = extensions
|
|
16
|
-
exports.operations = operations
|
|
17
|
-
exports.properties = properties
|
|
18
|
-
exports.receivers = receivers
|
|
19
|
-
exports.version = version
|
|
1
|
+
export { bridge } from './bridge.js'
|
|
2
|
+
export { entity } from './entity.js'
|
|
3
|
+
export { events } from './events.js'
|
|
4
|
+
export { extensions } from './extensions.js'
|
|
5
|
+
export { operations } from './operations.js'
|
|
6
|
+
export { properties } from './properties.js'
|
|
7
|
+
export { receivers } from './receivers.js'
|
|
8
|
+
export { version } from './version.js'
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { resolve } from '../../shortcuts.js'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
const { resolve } = require('../../shortcuts')
|
|
5
|
-
|
|
6
|
-
function operations (manifest) {
|
|
3
|
+
export function operations (manifest) {
|
|
7
4
|
if (manifest.operations === undefined) return
|
|
8
5
|
|
|
9
6
|
for (const operation of Object.values(manifest.operations)) {
|
|
10
|
-
if (operation.input !== undefined) operation.input = expand(operation.input)
|
|
11
|
-
if (operation.output !== undefined) operation.output = expand(operation.output)
|
|
12
7
|
if (operation.bridge !== undefined) operation.bridge = resolve(operation.bridge)
|
|
13
8
|
|
|
14
9
|
if (operation.bindings !== undefined && operation.bindings !== null) {
|
|
@@ -16,5 +11,3 @@ function operations (manifest) {
|
|
|
16
11
|
}
|
|
17
12
|
}
|
|
18
13
|
}
|
|
19
|
-
|
|
20
|
-
exports.operations = operations
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { recognize } from '../../shortcuts.js'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function properties (manifest) {
|
|
3
|
+
export function properties (manifest) {
|
|
6
4
|
recognize(SHORTCUTS, manifest, 'properties')
|
|
7
5
|
recognize(SHORTCUTS, manifest.properties)
|
|
8
6
|
}
|
|
@@ -10,5 +8,3 @@ function properties (manifest) {
|
|
|
10
8
|
const SHORTCUTS = {
|
|
11
9
|
queues: '@toa.io/storages.queues'
|
|
12
10
|
}
|
|
13
|
-
|
|
14
|
-
exports.properties = properties
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { resolve } from '../../shortcuts.js'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function receivers (manifest) {
|
|
3
|
+
export function receivers (manifest) {
|
|
6
4
|
if (manifest.receivers === undefined) return
|
|
7
5
|
|
|
8
6
|
for (const [locator, receiver] of Object.entries(manifest.receivers)) {
|
|
@@ -12,5 +10,3 @@ function receivers (manifest) {
|
|
|
12
10
|
if (receiver.bridge !== undefined) receiver.bridge = resolve(receiver.bridge)
|
|
13
11
|
}
|
|
14
12
|
}
|
|
15
|
-
|
|
16
|
-
exports.receivers = receivers
|
|
@@ -1,45 +1,57 @@
|
|
|
1
|
-
|
|
1
|
+
import { join } from 'node:path'
|
|
2
|
+
import { createHash } from 'node:crypto'
|
|
3
|
+
import fs from 'node:fs/promises'
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
const { createHash } = require('node:crypto')
|
|
5
|
-
const fs = require('node:fs/promises')
|
|
6
|
-
const { createReadStream } = require('node:fs')
|
|
7
|
-
const { once } = require('node:events')
|
|
8
|
-
|
|
9
|
-
async function version (manifest) {
|
|
5
|
+
export async function version (manifest) {
|
|
10
6
|
manifest.version ??= await hash(manifest.path)
|
|
11
7
|
}
|
|
12
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Identifies a build of a component: it becomes the tag of its image, so it must be the
|
|
11
|
+
* same for the same sources and different for different ones — on any machine.
|
|
12
|
+
*
|
|
13
|
+
* What the image excludes cannot change it: `node_modules` is in the `.dockerignore` the
|
|
14
|
+
* build writes (see `operations/src/deployment/images/image.js`), so hashing it would only
|
|
15
|
+
* retag an identical image after a local install.
|
|
16
|
+
*/
|
|
13
17
|
async function hash (path) {
|
|
14
|
-
const
|
|
18
|
+
const files = (await list(path)).sort()
|
|
19
|
+
const digests = await Promise.all(files.map((file) => digest(join(path, file))))
|
|
20
|
+
const total = createHash('sha256')
|
|
21
|
+
|
|
22
|
+
// the path is part of it: moving a file changes the build even if no content did
|
|
23
|
+
for (let i = 0; i < files.length; i++)
|
|
24
|
+
total.update(files[i]).update(digests[i])
|
|
15
25
|
|
|
16
|
-
return
|
|
26
|
+
return total.digest('hex').slice(0, 8)
|
|
17
27
|
}
|
|
18
28
|
|
|
19
29
|
/**
|
|
20
|
-
* @param {string}
|
|
21
|
-
* @param {
|
|
30
|
+
* @param {string} root
|
|
31
|
+
* @param {string} [path] relative
|
|
32
|
+
* @param {string[]} [acc]
|
|
33
|
+
* @returns {Promise<string[]>} paths relative to `root`
|
|
22
34
|
*/
|
|
23
|
-
async function
|
|
24
|
-
const
|
|
35
|
+
async function list (root, path = '', acc = []) {
|
|
36
|
+
const entries = await fs.readdir(join(root, path), { withFileTypes: true })
|
|
25
37
|
|
|
26
|
-
|
|
27
|
-
|
|
38
|
+
for (const entry of entries) {
|
|
39
|
+
if (EXCLUDED.has(entry.name))
|
|
40
|
+
continue
|
|
28
41
|
|
|
29
|
-
|
|
42
|
+
const relative = path === '' ? entry.name : `${path}/${entry.name}`
|
|
30
43
|
|
|
31
|
-
|
|
44
|
+
if (entry.isDirectory())
|
|
45
|
+
await list(root, relative, acc)
|
|
46
|
+
else if (entry.isFile())
|
|
47
|
+
acc.push(relative)
|
|
32
48
|
}
|
|
33
49
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
for await (const entry of entries) {
|
|
38
|
-
await hashd(join(path, entry.name), hash)
|
|
39
|
-
}
|
|
50
|
+
return acc
|
|
51
|
+
}
|
|
40
52
|
|
|
41
|
-
|
|
42
|
-
|
|
53
|
+
async function digest (path) {
|
|
54
|
+
return createHash('sha256').update(await fs.readFile(path)).digest()
|
|
43
55
|
}
|
|
44
56
|
|
|
45
|
-
|
|
57
|
+
const EXCLUDED = new Set(['node_modules', '.git'])
|
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const events = (component) => {
|
|
1
|
+
export const events = async (component) => {
|
|
4
2
|
if (component.events === undefined) return
|
|
5
3
|
|
|
6
|
-
const binding = component.bindings
|
|
4
|
+
const binding = await asynchronous(component.bindings)
|
|
7
5
|
|
|
8
6
|
for (const event of Object.values(component.events)) {
|
|
9
7
|
if (event.binding === undefined) event.binding = binding
|
|
10
8
|
}
|
|
11
9
|
}
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
/** The first binding that carries events, which only its module can say. */
|
|
12
|
+
async function asynchronous (bindings) {
|
|
13
|
+
for (const binding of bindings) {
|
|
14
|
+
const { properties } = await import(binding)
|
|
15
|
+
|
|
16
|
+
if (properties.async === true) return binding
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return undefined
|
|
20
|
+
}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const { operations } = require('./operations')
|
|
5
|
-
const { receivers } = require('./receivers')
|
|
6
|
-
|
|
7
|
-
exports.events = events
|
|
8
|
-
exports.operations = operations
|
|
9
|
-
exports.receivers = receivers
|
|
1
|
+
export { events } from './events.js'
|
|
2
|
+
export { operations } from './operations.js'
|
|
3
|
+
export { receivers } from './receivers.js'
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const operations = (component) => {
|
|
1
|
+
export const operations = (component) => {
|
|
4
2
|
if (component.operations === undefined) return
|
|
5
3
|
|
|
6
4
|
for (const [endpoint, operation] of Object.entries(component.operations)) {
|
|
7
|
-
if (operation.
|
|
5
|
+
if (operation.scope === 'none')
|
|
8
6
|
operation.query = false
|
|
9
7
|
|
|
10
8
|
if (operation.bindings === undefined) operation.bindings = component.bindings
|
|
@@ -12,5 +10,3 @@ const operations = (component) => {
|
|
|
12
10
|
if (operation.virtual === true) delete component.operations[endpoint]
|
|
13
11
|
}
|
|
14
12
|
}
|
|
15
|
-
|
|
16
|
-
exports.operations = operations
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
function receivers (component) {
|
|
1
|
+
export function receivers (component) {
|
|
4
2
|
if (component.receivers === undefined) return
|
|
5
3
|
|
|
6
4
|
const receivers = component.receivers
|
|
@@ -18,5 +16,3 @@ function receivers (component) {
|
|
|
18
16
|
receivers[newKey] = value
|
|
19
17
|
}
|
|
20
18
|
}
|
|
21
|
-
|
|
22
|
-
exports.receivers = receivers
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { merge } from '@toa.io/generic'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
const collapse = (manifest, prototype) => {
|
|
3
|
+
export const collapse = (manifest, prototype) => {
|
|
6
4
|
delete manifest.prototype
|
|
7
5
|
|
|
8
6
|
if (prototype.operations) {
|
|
@@ -42,7 +40,10 @@ const collapse = (manifest, prototype) => {
|
|
|
42
40
|
delete prototype.entity.schema.properties.id
|
|
43
41
|
}
|
|
44
42
|
|
|
43
|
+
if (prototype.events !== undefined && manifest.events !== undefined)
|
|
44
|
+
for (const event of Object.keys(prototype.events))
|
|
45
|
+
if (event in manifest.events)
|
|
46
|
+
delete prototype.events[event]
|
|
47
|
+
|
|
45
48
|
merge(manifest, { entity, events, extensions })
|
|
46
49
|
}
|
|
47
|
-
|
|
48
|
-
exports.collapse = collapse
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const { hash } = require('@toa.io/generic')
|
|
4
|
-
const assert = require('node:assert')
|
|
1
|
+
import { hash } from '@toa.io/generic'
|
|
5
2
|
|
|
6
3
|
// these defaults are required before validation
|
|
7
|
-
const defaults = (manifest) => {
|
|
8
|
-
if (manifest.name === undefined)
|
|
4
|
+
export const defaults = (manifest, proto) => {
|
|
5
|
+
if (manifest.name === undefined)
|
|
6
|
+
if (proto) manifest.name = protoName(manifest)
|
|
7
|
+
else nameAfterDir(manifest)
|
|
8
|
+
|
|
9
9
|
if (manifest.bindings === undefined) manifest.bindings = ['@toa.io/bindings.amqp']
|
|
10
10
|
if (manifest.bridge === undefined) manifest.bridge = '@toa.io/bridges.node'
|
|
11
11
|
|
|
@@ -24,4 +24,11 @@ function protoName (manifest) {
|
|
|
24
24
|
return 'proto' + hash(manifest.path)
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
function nameAfterDir (manifest) {
|
|
28
|
+
const parts = manifest.path.split('/')
|
|
29
|
+
const dirname = parts[parts.length - 1]
|
|
30
|
+
const [name, namespace] = dirname.split('.').reverse()
|
|
31
|
+
|
|
32
|
+
manifest.name = name
|
|
33
|
+
manifest.namespace = namespace
|
|
34
|
+
}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
import { createRequire } from 'node:module'
|
|
2
|
+
import { join, dirname } from 'node:path'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
// import.meta.resolve takes no paths, and a storage is resolved against the
|
|
5
|
+
// component that names it
|
|
6
|
+
const require = createRequire(import.meta.url)
|
|
4
7
|
|
|
5
8
|
/**
|
|
6
9
|
* @param {toa.norm.Component} component
|
|
7
10
|
*/
|
|
8
|
-
const dependencies = (component) => {
|
|
11
|
+
export const dependencies = (component) => {
|
|
9
12
|
if ('entity' in component) component.entity.storage = resolve(component.path, component.entity.storage)
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
function resolve (root, reference) {
|
|
13
|
-
const paths = [root,
|
|
16
|
+
const paths = [root, import.meta.dirname]
|
|
14
17
|
const options = { paths }
|
|
15
18
|
|
|
16
19
|
let path
|
|
@@ -25,5 +28,3 @@ function resolve (root, reference) {
|
|
|
25
28
|
|
|
26
29
|
return dirname(path)
|
|
27
30
|
}
|
|
28
|
-
|
|
29
|
-
exports.dependencies = dependencies
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { merge } from '@toa.io/generic'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
const dereference = (manifest) => {
|
|
3
|
+
export const dereference = (manifest) => {
|
|
6
4
|
// schemas
|
|
7
5
|
const resolver = createResolver(manifest.entity?.schema?.properties)
|
|
8
6
|
|
|
@@ -25,7 +23,12 @@ const createResolver = (properties) => (property) => {
|
|
|
25
23
|
function operations (manifest, resolver) {
|
|
26
24
|
for (const operation of Object.values(manifest.operations)) {
|
|
27
25
|
if (operation.input !== undefined) operation.input = schema(operation.input, resolver)
|
|
28
|
-
|
|
26
|
+
|
|
27
|
+
if (operation.output !== undefined)
|
|
28
|
+
if (Array.isArray(operation.output) && operation.output.length === 1)
|
|
29
|
+
operation.output = [schema(operation.output[0], resolver)]
|
|
30
|
+
else
|
|
31
|
+
operation.output = schema(operation.output, resolver)
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
// forwarding
|
|
@@ -72,5 +75,3 @@ const forward = (operation, operations) => {
|
|
|
72
75
|
|
|
73
76
|
merge(operation, real)
|
|
74
77
|
}
|
|
75
|
-
|
|
76
|
-
exports.dereference = dereference
|