@toa.io/extensions.configuration 1.0.0-alpha.276 → 1.0.0-alpha.277
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 +7 -0
- package/components/configuration.values/operations/create.js +4 -31
- package/components/configuration.values/operations/create.js.map +1 -1
- package/components/configuration.values/operations/fetch.d.ts +1 -1
- package/components/configuration.values/operations/fetch.js +3 -7
- package/components/configuration.values/operations/fetch.js.map +1 -1
- package/components/configuration.values/operations/get.d.ts +1 -1
- package/components/configuration.values/operations/get.js +5 -9
- package/components/configuration.values/operations/get.js.map +1 -1
- package/components/configuration.values/operations/lib/map.js +4 -9
- package/components/configuration.values/operations/lib/map.js.map +1 -1
- package/components/configuration.values/operations/lib/map.test.js +14 -14
- package/components/configuration.values/operations/lib/map.test.js.map +1 -1
- package/components/configuration.values/operations/lib/resolve.js +3 -7
- package/components/configuration.values/operations/lib/resolve.js.map +1 -1
- package/components/configuration.values/operations/list.d.ts +1 -1
- package/components/configuration.values/operations/list.js +6 -10
- package/components/configuration.values/operations/list.js.map +1 -1
- package/components/configuration.values/source/create.ts +1 -1
- package/components/configuration.values/source/fetch.ts +1 -1
- package/components/configuration.values/source/get.ts +2 -2
- package/components/configuration.values/source/lib/map.test.ts +10 -7
- package/components/configuration.values/source/lib/resolve.ts +1 -1
- package/components/configuration.values/source/list.ts +2 -2
- package/components/configuration.values/tsconfig.json +1 -0
- package/components/configuration.values/tsconfig.tsbuildinfo +1 -0
- package/cucumber.mjs +5 -0
- package/features/steps/UI.ts +7 -4
- package/package.json +8 -14
- package/source/Aspect.test.ts +27 -23
- package/source/Aspect.ts +4 -4
- package/source/Client.test.ts +24 -20
- package/source/Client.ts +2 -2
- package/source/Composition.ts +4 -4
- package/source/Factory.ts +5 -5
- package/source/Secret.test.ts +14 -11
- package/source/UI.ts +2 -2
- package/source/configuration.test.ts +21 -18
- package/source/configuration.ts +3 -3
- package/source/deployment.test.ts +20 -19
- package/source/deployment.ts +7 -6
- package/source/epoch.test.ts +8 -5
- package/source/index.ts +4 -4
- package/source/manifest.test.ts +8 -5
- package/source/manifest.ts +2 -2
- package/source/schemas.ts +1 -1
- package/transpiled/Aspect.d.ts +2 -2
- package/transpiled/Aspect.js +12 -16
- package/transpiled/Aspect.js.map +1 -1
- package/transpiled/Aspect.test.js +30 -29
- package/transpiled/Aspect.test.js.map +1 -1
- package/transpiled/Client.d.ts +1 -1
- package/transpiled/Client.js +10 -14
- package/transpiled/Client.js.map +1 -1
- package/transpiled/Client.test.js +28 -27
- package/transpiled/Client.test.js.map +1 -1
- package/transpiled/Composition.d.ts +1 -1
- package/transpiled/Composition.js +11 -16
- package/transpiled/Composition.js.map +1 -1
- package/transpiled/Factory.d.ts +1 -1
- package/transpiled/Factory.js +9 -13
- package/transpiled/Factory.js.map +1 -1
- package/transpiled/Secret.d.ts +0 -1
- package/transpiled/Secret.js +7 -11
- package/transpiled/Secret.js.map +1 -1
- package/transpiled/Secret.test.js +15 -15
- package/transpiled/Secret.test.js.map +1 -1
- package/transpiled/UI.js +14 -41
- package/transpiled/UI.js.map +1 -1
- package/transpiled/configuration.d.ts +1 -1
- package/transpiled/configuration.js +13 -42
- package/transpiled/configuration.js.map +1 -1
- package/transpiled/configuration.test.js +25 -25
- package/transpiled/configuration.test.js.map +1 -1
- package/transpiled/const.js +7 -10
- package/transpiled/const.js.map +1 -1
- package/transpiled/deployment.d.ts +1 -1
- package/transpiled/deployment.js +19 -49
- package/transpiled/deployment.js.map +1 -1
- package/transpiled/deployment.test.js +29 -31
- package/transpiled/deployment.test.js.map +1 -1
- package/transpiled/epoch.js +3 -7
- package/transpiled/epoch.js.map +1 -1
- package/transpiled/epoch.test.js +7 -7
- package/transpiled/epoch.test.js.map +1 -1
- package/transpiled/index.d.ts +4 -4
- package/transpiled/index.js +4 -12
- package/transpiled/index.js.map +1 -1
- package/transpiled/manifest.d.ts +1 -1
- package/transpiled/manifest.js +2 -29
- package/transpiled/manifest.js.map +1 -1
- package/transpiled/manifest.test.js +9 -9
- package/transpiled/manifest.test.js.map +1 -1
- package/transpiled/schemas.js +5 -31
- package/transpiled/schemas.js.map +1 -1
- package/tsconfig.json +2 -1
- package/tsconfig.tsbuildinfo +1 -0
- package/ui/dist/_app/immutable/chunks/{Cov6-56A.js → BmgElDKV.js} +1 -1
- package/ui/dist/_app/immutable/chunks/{MOpxGoVO.js → D8FpNdzZ.js} +1 -1
- package/ui/dist/_app/immutable/chunks/{Chb3af1a.js → DqEfc78C.js} +1 -1
- package/ui/dist/_app/immutable/chunks/{CDKtbN4n.js → SDlqkjtd.js} +2 -2
- package/ui/dist/_app/immutable/chunks/{E7oj41Za.js → XCuD79lA.js} +1 -1
- package/ui/dist/_app/immutable/entry/{app.B9v2AwU_.js → app.DviKj8uz.js} +2 -2
- package/ui/dist/_app/immutable/entry/start.B5sHlPUn.js +1 -0
- package/ui/dist/_app/immutable/nodes/{0.DKSa6mGa.js → 0.BEypu1s7.js} +1 -1
- package/ui/dist/_app/immutable/nodes/{1.Cnu_jAWf.js → 1.Dy5V5EUo.js} +1 -1
- package/ui/dist/_app/immutable/nodes/{2.Dg1zeC2b.js → 2.DCbpDeYM.js} +1 -1
- package/ui/dist/_app/immutable/nodes/3.10zn4N8f.js +1 -0
- package/ui/dist/_app/immutable/nodes/{4.1bG6DC_9.js → 4.DkEiu1vL.js} +1 -1
- package/ui/dist/_app/version.json +1 -1
- package/ui/dist/index.html +10 -10
- package/components/configuration.values/operations/tsconfig.tsbuildinfo +0 -1
- package/cucumber.js +0 -8
- package/transpiled/tsconfig.tsbuildinfo +0 -1
- package/ui/dist/_app/immutable/entry/start.B97KALv1.js +0 -1
- package/ui/dist/_app/immutable/nodes/3.QCbZIibO.js +0 -1
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { describe, it, beforeEach, afterEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
|
|
1
4
|
import { Locator } from '@toa.io/core'
|
|
2
5
|
import { generate } from 'randomstring'
|
|
3
|
-
import { fit, local, overridden } from './configuration'
|
|
4
|
-
import { Secret } from './Secret'
|
|
5
|
-
import { type Manifest } from './manifest'
|
|
6
|
+
import { fit, local, overridden } from './configuration.js'
|
|
7
|
+
import { Secret } from './Secret.js'
|
|
8
|
+
import { type Manifest } from './manifest.js'
|
|
6
9
|
|
|
7
10
|
let locator: Locator
|
|
8
11
|
let manifest: Manifest
|
|
@@ -26,13 +29,13 @@ afterEach(() => {
|
|
|
26
29
|
|
|
27
30
|
describe('overridden', () => {
|
|
28
31
|
it('should be false without the variable', async () => {
|
|
29
|
-
|
|
32
|
+
assert.deepStrictEqual(overridden(locator), false)
|
|
30
33
|
})
|
|
31
34
|
|
|
32
35
|
it('should be true with the variable', async () => {
|
|
33
36
|
set({})
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
assert.deepStrictEqual(overridden(locator), true)
|
|
36
39
|
})
|
|
37
40
|
})
|
|
38
41
|
|
|
@@ -42,11 +45,11 @@ describe('local', () => {
|
|
|
42
45
|
|
|
43
46
|
set(value)
|
|
44
47
|
|
|
45
|
-
|
|
48
|
+
assert.deepStrictEqual(local(locator, manifest), value)
|
|
46
49
|
})
|
|
47
50
|
|
|
48
51
|
it('should return empty object if no value set', async () => {
|
|
49
|
-
|
|
52
|
+
assert.deepStrictEqual(local(locator, manifest), {})
|
|
50
53
|
})
|
|
51
54
|
|
|
52
55
|
it('should substitute secrets', async () => {
|
|
@@ -55,9 +58,9 @@ describe('local', () => {
|
|
|
55
58
|
|
|
56
59
|
const { foo } = local(locator, manifest)
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
assert.ok(foo instanceof Secret)
|
|
62
|
+
assert.deepStrictEqual((foo as Secret).unwrap(), 'bar')
|
|
63
|
+
assert.deepStrictEqual(String(foo), '<REDACTED>')
|
|
61
64
|
})
|
|
62
65
|
|
|
63
66
|
it('should substitute secrets in defaults', async () => {
|
|
@@ -65,7 +68,7 @@ describe('local', () => {
|
|
|
65
68
|
|
|
66
69
|
set('bar', '_BAR')
|
|
67
70
|
|
|
68
|
-
|
|
71
|
+
assert.deepStrictEqual((local(locator, manifest).foo as Secret).unwrap(), 'bar')
|
|
69
72
|
})
|
|
70
73
|
|
|
71
74
|
it('should use defaults', async () => {
|
|
@@ -82,7 +85,7 @@ describe('local', () => {
|
|
|
82
85
|
|
|
83
86
|
set({ bar: [2], baz: 'foo' })
|
|
84
87
|
|
|
85
|
-
|
|
88
|
+
assert.deepStrictEqual(local(locator, manifest), { foo: 'bar', bar: [2], baz: 'foo' })
|
|
86
89
|
})
|
|
87
90
|
|
|
88
91
|
it('should validate', async () => {
|
|
@@ -96,7 +99,7 @@ describe('local', () => {
|
|
|
96
99
|
|
|
97
100
|
set({ bar: 5 })
|
|
98
101
|
|
|
99
|
-
|
|
102
|
+
assert.deepStrictEqual(local(locator, manifest), { foo: 'hello', bar: 5 })
|
|
100
103
|
})
|
|
101
104
|
})
|
|
102
105
|
|
|
@@ -115,19 +118,19 @@ describe('fit', () => {
|
|
|
115
118
|
const raw = { foo: '$FOO' }
|
|
116
119
|
const values = fit(raw, manifest)
|
|
117
120
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
assert.deepStrictEqual((values.foo as Secret).unwrap(), 'secret')
|
|
122
|
+
assert.deepStrictEqual(values.bar, 1)
|
|
123
|
+
assert.deepStrictEqual(raw, { foo: '$FOO' }) // untouched
|
|
121
124
|
})
|
|
122
125
|
|
|
123
126
|
it('should not apply the manifest defaults', async () => {
|
|
124
127
|
manifest.defaults = { foo: 'hello' }
|
|
125
128
|
|
|
126
|
-
|
|
129
|
+
assert.deepStrictEqual(fit({}, manifest), {})
|
|
127
130
|
})
|
|
128
131
|
|
|
129
132
|
it('should throw on a value not fitting the schema', async () => {
|
|
130
|
-
|
|
133
|
+
assert.throws(() => fit({ foo: { nested: true } }, manifest))
|
|
131
134
|
})
|
|
132
135
|
})
|
|
133
136
|
|
package/source/configuration.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { type Locator } from '@toa.io/core'
|
|
2
2
|
import { add } from '@toa.io/generic'
|
|
3
3
|
import * as schemas from '@toa.io/schemas'
|
|
4
|
-
import { PREFIX, SECRET_RX } from './const'
|
|
5
|
-
import { Secret } from './Secret'
|
|
4
|
+
import { PREFIX, SECRET_RX } from './const.js'
|
|
5
|
+
import { Secret } from './Secret.js'
|
|
6
6
|
import type { Schema } from '@toa.io/schemas'
|
|
7
|
-
import type { Manifest } from './manifest'
|
|
7
|
+
import type { Manifest } from './manifest.js'
|
|
8
8
|
|
|
9
9
|
/** The variable is set, so the values service is not consulted. */
|
|
10
10
|
export function overridden (locator: Locator): boolean {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { it } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
|
|
1
4
|
import { Locator } from '@toa.io/core'
|
|
2
|
-
import { type Annotation, type Instance, deployment, describe as map } from './deployment'
|
|
3
|
-
import { epoch } from './epoch'
|
|
4
|
-
import { EVENT, VALUES } from './const'
|
|
5
|
+
import { type Annotation, type Instance, deployment, describe as map } from './deployment.js'
|
|
6
|
+
import { epoch } from './epoch.js'
|
|
7
|
+
import { EVENT, VALUES } from './const.js'
|
|
5
8
|
|
|
6
9
|
const schema = {
|
|
7
10
|
type: 'object',
|
|
@@ -19,12 +22,11 @@ function instance (name: string, defaults?: Record<string, unknown>): Instance {
|
|
|
19
22
|
it('should validate annotation', async () => {
|
|
20
23
|
const wrongType = 'not ok' as unknown as Annotation
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
assert.throws(() => deployment([], wrongType), (error: any) => /object/.test(error.message))
|
|
23
26
|
})
|
|
24
27
|
|
|
25
28
|
it('should reject unknown components', async () => {
|
|
26
|
-
|
|
27
|
-
.toThrow("Component 'configuration.nope' does not request configuration")
|
|
29
|
+
assert.throws(() => deployment([instance('base')], { 'configuration.nope': {} }), (error: any) => /Component 'configuration\.nope' does not request configuration/.test(error.message))
|
|
28
30
|
})
|
|
29
31
|
|
|
30
32
|
it('should deploy the values service with the map', async () => {
|
|
@@ -33,26 +35,26 @@ it('should deploy the values service with the map', async () => {
|
|
|
33
35
|
|
|
34
36
|
const dependency = deployment(instances, annotation)
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
assert.deepStrictEqual(dependency.events, [EVENT])
|
|
39
|
+
assert.strictEqual(dependency.services?.length, 1)
|
|
38
40
|
|
|
39
41
|
const service = dependency.services![0]
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
assert.deepStrictEqual(service.group, 'configuration')
|
|
44
|
+
assert.deepStrictEqual(service.name, 'values')
|
|
45
|
+
assert.deepStrictEqual(service.components, ['configuration-values'])
|
|
44
46
|
|
|
45
47
|
const variable = service.variables!.find((variable) => variable.name === VALUES)
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
assert.notStrictEqual(variable, undefined)
|
|
50
|
+
assert.deepStrictEqual(JSON.parse(variable!.value!), map(instances, annotation))
|
|
49
51
|
})
|
|
50
52
|
|
|
51
53
|
it('should describe every component', async () => {
|
|
52
54
|
const instances = [instance('base', { foo: 'hello' }), instance('other')]
|
|
53
55
|
const values = map(instances, { 'configuration.other': { foo: 'set' } })
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
assert.deepStrictEqual(values, {
|
|
56
58
|
'configuration.base': { epoch: epoch(schema), schema, defaults: { foo: 'hello' } },
|
|
57
59
|
'configuration.other': { epoch: epoch(schema), schema, defaults: { foo: 'set' } }
|
|
58
60
|
})
|
|
@@ -61,19 +63,19 @@ it('should describe every component', async () => {
|
|
|
61
63
|
it('should prefer the context over the manifest defaults', async () => {
|
|
62
64
|
const values = map([instance('base', { foo: 'hello' })], { 'configuration.base': { foo: 'bye' } })
|
|
63
65
|
|
|
64
|
-
|
|
66
|
+
assert.deepStrictEqual(values['configuration.base'].defaults, { foo: 'bye' })
|
|
65
67
|
})
|
|
66
68
|
|
|
67
69
|
it('should not map values to the component', async () => {
|
|
68
70
|
const dependency = deployment([instance('base')], { 'configuration.base': { foo: 'set' } })
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
assert.deepStrictEqual(dependency.variables, {})
|
|
71
73
|
})
|
|
72
74
|
|
|
73
75
|
it('should map secrets to the component', async () => {
|
|
74
76
|
const dependency = deployment([instance('base')], { 'configuration.base': { key: '$KEY' } })
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
assert.deepStrictEqual(dependency.variables, {
|
|
77
79
|
'configuration-base': [{
|
|
78
80
|
name: 'TOA_CONFIGURATION__KEY',
|
|
79
81
|
secret: { name: 'toa-configuration', key: 'KEY' }
|
|
@@ -81,6 +83,5 @@ it('should map secrets to the component', async () => {
|
|
|
81
83
|
})
|
|
82
84
|
|
|
83
85
|
// the service holds the reference, not the secret
|
|
84
|
-
|
|
85
|
-
.toStrictEqual({ key: '$KEY' })
|
|
86
|
+
assert.deepStrictEqual(map([instance('base')], { 'configuration.base': { key: '$KEY' } })['configuration.base'].defaults, { key: '$KEY' })
|
|
86
87
|
})
|
package/source/deployment.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
1
2
|
import assert from 'node:assert'
|
|
2
3
|
import { type Dependency, type Resources, type Service, type Variable, type Variables } from '@toa.io/operations'
|
|
3
|
-
import { components } from './Composition'
|
|
4
|
-
import { EVENT, PREFIX, SECRET_RX, UI_PATH, UI_PORT, VALUES } from './const'
|
|
5
|
-
import { epoch } from './epoch'
|
|
6
|
-
import * as validators from './schemas'
|
|
7
|
-
import type { Manifest } from './manifest'
|
|
4
|
+
import { components } from './Composition.js'
|
|
5
|
+
import { EVENT, PREFIX, SECRET_RX, UI_PATH, UI_PORT, VALUES } from './const.js'
|
|
6
|
+
import { epoch } from './epoch.js'
|
|
7
|
+
import * as validators from './schemas.js'
|
|
8
|
+
import type { Manifest } from './manifest.js'
|
|
8
9
|
import type { context } from '@toa.io/norm'
|
|
9
10
|
|
|
10
11
|
export function deployment (instances: Instance[], annotation: Annotation = {}): Dependency {
|
|
@@ -29,7 +30,7 @@ export function deployment (instances: Instance[], annotation: Annotation = {}):
|
|
|
29
30
|
const service: Service = {
|
|
30
31
|
group: 'configuration',
|
|
31
32
|
name: 'values',
|
|
32
|
-
version:
|
|
33
|
+
version: JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version,
|
|
33
34
|
components: components().labels,
|
|
34
35
|
resources,
|
|
35
36
|
// the service that holds the values also serves the page that reads them
|
package/source/epoch.test.ts
CHANGED
|
@@ -1,26 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { it } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
|
|
4
|
+
import { epoch } from './epoch.js'
|
|
2
5
|
|
|
3
6
|
it('should be a sha256 hex', () => {
|
|
4
|
-
|
|
7
|
+
assert.match(epoch({ type: 'object' }), /^[a-f0-9]{64}$/)
|
|
5
8
|
})
|
|
6
9
|
|
|
7
10
|
it('should not depend on key order', () => {
|
|
8
11
|
const a = { type: 'object', properties: { foo: { type: 'string', default: 'x' }, bar: { type: 'number' } } }
|
|
9
12
|
const b = { properties: { bar: { type: 'number' }, foo: { default: 'x', type: 'string' } }, type: 'object' }
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
assert.deepStrictEqual(epoch(a), epoch(b))
|
|
12
15
|
})
|
|
13
16
|
|
|
14
17
|
it('should depend on values', () => {
|
|
15
18
|
const a = { type: 'object', properties: { foo: { type: 'string' } } }
|
|
16
19
|
const b = { type: 'object', properties: { foo: { type: 'number' } } }
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
assert.notDeepStrictEqual(epoch(a), epoch(b))
|
|
19
22
|
})
|
|
20
23
|
|
|
21
24
|
it('should keep array order', () => {
|
|
22
25
|
const a = { enum: [1, 2] }
|
|
23
26
|
const b = { enum: [2, 1] }
|
|
24
27
|
|
|
25
|
-
|
|
28
|
+
assert.notDeepStrictEqual(epoch(a), epoch(b))
|
|
26
29
|
})
|
package/source/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { manifest } from './manifest'
|
|
2
|
-
export { deployment, describe } from './deployment'
|
|
3
|
-
export { components } from './Composition'
|
|
4
|
-
export { Factory } from './Factory'
|
|
1
|
+
export { manifest } from './manifest.js'
|
|
2
|
+
export { deployment, describe } from './deployment.js'
|
|
3
|
+
export { components } from './Composition.js'
|
|
4
|
+
export { Factory } from './Factory.js'
|
package/source/manifest.test.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { it } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
|
|
4
|
+
import { type Manifest, manifest } from './manifest.js'
|
|
2
5
|
|
|
3
6
|
it('should validate', async () => {
|
|
4
7
|
const additional = { schema: {}, foo: 'bar' } as unknown as Manifest
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
assert.throws(() => {
|
|
7
10
|
manifest(additional)
|
|
8
|
-
})
|
|
11
|
+
}, (error: any) => /not expected/.test(error.message))
|
|
9
12
|
|
|
10
13
|
const wrongType = { schema: 'not ok' } as unknown as Manifest
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
assert.throws(() => {
|
|
13
16
|
manifest(wrongType)
|
|
14
|
-
}).
|
|
17
|
+
}, (error: any) => /object/.test(error.message))
|
|
15
18
|
})
|
package/source/manifest.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as schemas from './schemas'
|
|
2
|
-
import { type Node } from './configuration'
|
|
1
|
+
import * as schemas from './schemas.js'
|
|
2
|
+
import { type Node } from './configuration.js'
|
|
3
3
|
|
|
4
4
|
export function manifest (manifest: Manifest): Manifest {
|
|
5
5
|
schemas.manifest.validate(manifest)
|
package/source/schemas.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { resolve } from 'node:path'
|
|
|
2
2
|
import * as schemas from '@toa.io/schemas'
|
|
3
3
|
import type { Schema } from '@toa.io/schemas'
|
|
4
4
|
|
|
5
|
-
const path = resolve(
|
|
5
|
+
const path = resolve(import.meta.dirname, '../schemas')
|
|
6
6
|
const namespace = schemas.namespace(path)
|
|
7
7
|
|
|
8
8
|
export const manifest: Schema<any> = namespace.schema('manifest')
|
package/transpiled/Aspect.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Connector, type Locator, type extensions } from '@toa.io/core';
|
|
2
|
-
import type { Client } from './Client';
|
|
3
|
-
import type { Manifest } from './manifest';
|
|
2
|
+
import type { Client } from './Client.js';
|
|
3
|
+
import type { Manifest } from './manifest.js';
|
|
4
4
|
export declare class Aspect extends Connector implements extensions.Aspect {
|
|
5
5
|
readonly name = "configuration";
|
|
6
6
|
private readonly locator;
|
package/transpiled/Aspect.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const configuration_1 = require("./configuration");
|
|
7
|
-
const epoch_1 = require("./epoch");
|
|
8
|
-
class Aspect extends core_1.Connector {
|
|
1
|
+
import { console } from 'openspan';
|
|
2
|
+
import { Connector } from '@toa.io/core';
|
|
3
|
+
import { fit, local } from './configuration.js';
|
|
4
|
+
import { epoch } from './epoch.js';
|
|
5
|
+
export class Aspect extends Connector {
|
|
9
6
|
name = 'configuration';
|
|
10
7
|
locator;
|
|
11
8
|
manifest;
|
|
@@ -22,7 +19,7 @@ class Aspect extends core_1.Connector {
|
|
|
22
19
|
this.locator = locator;
|
|
23
20
|
this.manifest = manifest;
|
|
24
21
|
this.client = client;
|
|
25
|
-
this.epoch =
|
|
22
|
+
this.epoch = epoch(manifest.schema);
|
|
26
23
|
if (client !== null)
|
|
27
24
|
this.depends(client);
|
|
28
25
|
}
|
|
@@ -35,14 +32,14 @@ class Aspect extends core_1.Connector {
|
|
|
35
32
|
}
|
|
36
33
|
async open() {
|
|
37
34
|
if (this.client === null) {
|
|
38
|
-
this.value =
|
|
35
|
+
this.value = local(this.locator, this.manifest);
|
|
39
36
|
return;
|
|
40
37
|
}
|
|
41
38
|
const { configuration, created } = await this.client.fetch(this.locator.id, this.epoch);
|
|
42
|
-
this.value =
|
|
39
|
+
this.value = fit(configuration, this.manifest);
|
|
43
40
|
this.created = created;
|
|
44
41
|
this.client.subscribe(this.locator.id, this.epoch, this.listener);
|
|
45
|
-
|
|
42
|
+
console.info('Configuration resolved', { component: this.locator.id, epoch: this.epoch, created });
|
|
46
43
|
}
|
|
47
44
|
async close() {
|
|
48
45
|
this.client?.unsubscribe(this.locator.id, this.epoch, this.listener);
|
|
@@ -52,15 +49,14 @@ class Aspect extends core_1.Connector {
|
|
|
52
49
|
if (created <= this.created)
|
|
53
50
|
return;
|
|
54
51
|
try {
|
|
55
|
-
this.value =
|
|
52
|
+
this.value = fit(configuration, this.manifest);
|
|
56
53
|
this.created = created;
|
|
57
|
-
|
|
54
|
+
console.info('Configuration updated', { component: this.locator.id, epoch: this.epoch, created });
|
|
58
55
|
}
|
|
59
56
|
catch (error) {
|
|
60
57
|
// the service validated it against the schema of its epoch, so the two schemas differ
|
|
61
|
-
|
|
58
|
+
console.error('Configuration value does not match the schema', { component: this.locator.id, epoch: this.epoch, error });
|
|
62
59
|
}
|
|
63
60
|
};
|
|
64
61
|
}
|
|
65
|
-
exports.Aspect = Aspect;
|
|
66
62
|
//# sourceMappingURL=Aspect.js.map
|
package/transpiled/Aspect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Aspect.js","sourceRoot":"","sources":["../source/Aspect.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Aspect.js","sourceRoot":"","sources":["../source/Aspect.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { it, beforeEach, afterEach, mock } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
4
|
+
import { Connector, Locator } from '@toa.io/core';
|
|
5
|
+
import { generate } from 'randomstring';
|
|
6
|
+
import { Aspect } from './Aspect.js';
|
|
7
|
+
class Fake extends Connector {
|
|
8
|
+
fetch = mock.fn(async () => ({ configuration: { foo: 'served' }, created: 5 }));
|
|
9
|
+
subscribe = mock.fn();
|
|
10
|
+
unsubscribe = mock.fn();
|
|
10
11
|
}
|
|
11
12
|
const manifest = {
|
|
12
13
|
schema: {
|
|
@@ -19,47 +20,47 @@ const manifest = {
|
|
|
19
20
|
};
|
|
20
21
|
let locator;
|
|
21
22
|
beforeEach(() => {
|
|
22
|
-
locator = new
|
|
23
|
+
locator = new Locator(generate(), generate());
|
|
23
24
|
});
|
|
24
25
|
afterEach(() => {
|
|
25
26
|
delete process.env['TOA_CONFIGURATION_' + locator.uppercase];
|
|
26
27
|
});
|
|
27
28
|
it('should be named', async () => {
|
|
28
|
-
|
|
29
|
+
assert.deepStrictEqual(new Aspect(locator, manifest, null).name, 'configuration');
|
|
29
30
|
});
|
|
30
31
|
it('should resolve locally without a client', async () => {
|
|
31
32
|
process.env['TOA_CONFIGURATION_' + locator.uppercase] = JSON.stringify({ foo: 'local' });
|
|
32
|
-
const aspect = new
|
|
33
|
+
const aspect = new Aspect(locator, manifest, null);
|
|
33
34
|
await aspect.connect();
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
assert.deepStrictEqual(aspect.invoke(), { foo: 'local', bar: { baz: 'quux' } });
|
|
36
|
+
assert.deepStrictEqual(aspect.invoke(['foo']), 'local');
|
|
37
|
+
assert.deepStrictEqual(aspect.invoke(['bar', 'baz']), 'quux');
|
|
37
38
|
});
|
|
38
39
|
it('should fetch from the client and follow it', async () => {
|
|
39
40
|
const client = new Fake();
|
|
40
|
-
const aspect = new
|
|
41
|
+
const aspect = new Aspect(locator, manifest, client);
|
|
41
42
|
await aspect.connect();
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const [component, epoch] = client.fetch.mock.calls[0];
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const listener = client.subscribe.mock.calls[0][2];
|
|
43
|
+
assert.deepStrictEqual(client.connected, true);
|
|
44
|
+
assert.strictEqual(client.fetch.mock.callCount(), 1);
|
|
45
|
+
const [component, epoch] = client.fetch.mock.calls[0].arguments;
|
|
46
|
+
assert.deepStrictEqual(component, locator.id);
|
|
47
|
+
assert.match(epoch, /^[a-f0-9]{64}$/);
|
|
48
|
+
assert.deepStrictEqual(aspect.invoke(), { foo: 'served', bar: { baz: 'quux' } });
|
|
49
|
+
assert.ok(client.subscribe.mock.calls.some((call) => call.arguments.length === 3 && isDeepStrictEqual(call.arguments[0], component) && isDeepStrictEqual(call.arguments[1], epoch) && typeof call.arguments[2] === 'function'));
|
|
50
|
+
const listener = client.subscribe.mock.calls[0].arguments[2];
|
|
50
51
|
listener({ configuration: { foo: 'updated' }, created: 6 });
|
|
51
|
-
|
|
52
|
+
assert.deepStrictEqual(aspect.invoke(['foo']), 'updated');
|
|
52
53
|
// what is not newer than the held value is left alone
|
|
53
54
|
listener({ configuration: { foo: 'stale' }, created: 6 });
|
|
54
55
|
listener({ configuration: { foo: 'older' }, created: 4 });
|
|
55
|
-
|
|
56
|
+
assert.deepStrictEqual(aspect.invoke(['foo']), 'updated');
|
|
56
57
|
// a value that does not fit keeps the previous one
|
|
57
58
|
listener({ configuration: { foo: { nested: true } }, created: 7 });
|
|
58
|
-
|
|
59
|
+
assert.deepStrictEqual(aspect.invoke(['foo']), 'updated');
|
|
59
60
|
// and the one after it still applies
|
|
60
61
|
listener({ configuration: { foo: 'latest' }, created: 8 });
|
|
61
|
-
|
|
62
|
+
assert.deepStrictEqual(aspect.invoke(['foo']), 'latest');
|
|
62
63
|
await aspect.disconnect();
|
|
63
|
-
|
|
64
|
+
assert.ok(client.unsubscribe.mock.calls.some((call) => call.arguments.length === 3 && isDeepStrictEqual(call.arguments[0], component) && isDeepStrictEqual(call.arguments[1], epoch) && isDeepStrictEqual(call.arguments[2], listener)));
|
|
64
65
|
});
|
|
65
66
|
//# sourceMappingURL=Aspect.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Aspect.test.js","sourceRoot":"","sources":["../source/Aspect.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Aspect.test.js","sourceRoot":"","sources":["../source/Aspect.test.ts"],"names":[],"mappings":"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"}
|
package/transpiled/Client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Connector } from '@toa.io/core';
|
|
2
|
-
import type { Bootloader } from './Factory';
|
|
2
|
+
import type { Bootloader } from './Factory.js';
|
|
3
3
|
/**
|
|
4
4
|
* One per process: one remote to the values service and one subscription to its events,
|
|
5
5
|
* shared by every Aspect. What the Aspects ask for is collected and sent as one call;
|
package/transpiled/Client.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const openspan_1 = require("openspan");
|
|
5
|
-
const core_1 = require("@toa.io/core");
|
|
6
|
-
const const_1 = require("./const");
|
|
1
|
+
import { console } from 'openspan';
|
|
2
|
+
import { Connector, Locator } from '@toa.io/core';
|
|
3
|
+
import { EVENT, SOURCE } from './const.js';
|
|
7
4
|
/**
|
|
8
5
|
* One per process: one remote to the values service and one subscription to its events,
|
|
9
6
|
* shared by every Aspect. What the Aspects ask for is collected and sent as one call;
|
|
10
7
|
* what the service creates afterwards is handed to whoever subscribed.
|
|
11
8
|
*/
|
|
12
|
-
class Client extends
|
|
9
|
+
export class Client extends Connector {
|
|
13
10
|
/** Disconnected once, a connector keeps what it depended on, so a gone client is not reused. */
|
|
14
11
|
disposed = false;
|
|
15
12
|
boot;
|
|
@@ -53,11 +50,11 @@ class Client extends core_1.Connector {
|
|
|
53
50
|
this.listeners.get(id(component, epoch))?.delete(listener);
|
|
54
51
|
}
|
|
55
52
|
async open() {
|
|
56
|
-
this.remote = await this.boot.remote(LOCATOR,
|
|
53
|
+
this.remote = await this.boot.remote(LOCATOR, SOURCE);
|
|
57
54
|
this.depends(this.remote);
|
|
58
55
|
await this.remote.connect();
|
|
59
56
|
const subscription = new Subscription(this.deliver.bind(this));
|
|
60
|
-
const consumer = await this.boot.receive(
|
|
57
|
+
const consumer = await this.boot.receive(EVENT, subscription);
|
|
61
58
|
this.depends(consumer);
|
|
62
59
|
await consumer.connect();
|
|
63
60
|
}
|
|
@@ -96,7 +93,7 @@ class Client extends core_1.Connector {
|
|
|
96
93
|
this.settle(output);
|
|
97
94
|
}
|
|
98
95
|
catch (error) {
|
|
99
|
-
|
|
96
|
+
console.warn('Configuration fetch failed', { error });
|
|
100
97
|
}
|
|
101
98
|
finally {
|
|
102
99
|
this.flushing = false;
|
|
@@ -133,7 +130,7 @@ class Client extends core_1.Connector {
|
|
|
133
130
|
}
|
|
134
131
|
this.round++;
|
|
135
132
|
if (this.round % this.options.warn === 1)
|
|
136
|
-
|
|
133
|
+
console.warn('Waiting for configuration', { components: waiting, round: this.round });
|
|
137
134
|
}
|
|
138
135
|
backoff() {
|
|
139
136
|
return Math.min(this.options.base * Math.pow(FACTOR, this.round), this.options.max);
|
|
@@ -148,9 +145,8 @@ class Client extends core_1.Connector {
|
|
|
148
145
|
listener(value);
|
|
149
146
|
}
|
|
150
147
|
}
|
|
151
|
-
exports.Client = Client;
|
|
152
148
|
/** What the event consumer hands deliveries to. */
|
|
153
|
-
class Subscription extends
|
|
149
|
+
class Subscription extends Connector {
|
|
154
150
|
handler;
|
|
155
151
|
constructor(handler) {
|
|
156
152
|
super();
|
|
@@ -163,7 +159,7 @@ class Subscription extends core_1.Connector {
|
|
|
163
159
|
function id(component, epoch) {
|
|
164
160
|
return component + '\0' + epoch;
|
|
165
161
|
}
|
|
166
|
-
const LOCATOR = new
|
|
162
|
+
const LOCATOR = new Locator('values', 'configuration');
|
|
167
163
|
const FACTOR = 1.5;
|
|
168
164
|
const DEFAULTS = {
|
|
169
165
|
base: 1000,
|