@toa.io/norm 1.0.0-alpha.29 → 1.0.0-alpha.292
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 +45 -0
- package/package.json +10 -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 +5 -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 +4 -7
- package/src/.component/.expand/version.js +38 -28
- package/src/.component/.normalize/entity.js +7 -0
- package/src/.component/.normalize/events.js +16 -4
- package/src/.component/.normalize/index.js +4 -9
- package/src/.component/.normalize/operations.js +10 -6
- package/src/.component/.normalize/receivers.js +4 -5
- package/src/.component/collapse.js +60 -9
- package/src/.component/defaults.js +16 -10
- package/src/.component/dependencies.js +14 -10
- package/src/.component/dereference.js +20 -18
- package/src/.component/expand.js +3 -7
- package/src/.component/extensions.js +13 -9
- package/src/.component/index.js +10 -21
- package/src/.component/merge.js +25 -13
- package/src/.component/migrations.js +57 -0
- package/src/.component/normalize.js +10 -6
- package/src/.component/schema.yaml +108 -71
- package/src/.component/validate.js +37 -17
- package/src/.context/.dependencies/connectors.js +5 -9
- package/src/.context/.dependencies/describe.js +4 -5
- package/src/.context/.dependencies/extensions.js +75 -19
- package/src/.context/.dependencies/index.js +3 -9
- package/src/.context/.dependencies/resolve.js +23 -7
- package/src/.context/complete.js +1 -5
- package/src/.context/dependencies.js +2 -6
- package/src/.context/dereference.js +11 -6
- package/src/.context/expand.js +8 -6
- package/src/.context/index.js +6 -15
- package/src/.context/normalize.js +9 -7
- package/src/.context/schema.yaml +132 -11
- package/src/.context/validate.js +8 -14
- package/src/component.js +36 -17
- package/src/context.js +26 -14
- package/src/definition.js +56 -0
- package/src/entity.js +15 -0
- package/src/index.js +5 -9
- package/src/shortcuts.js +8 -13
- package/test/component/collapse.fixtures.js +30 -39
- package/test/component/collapse.test.js +90 -10
- package/test/component/dependencies.test.js +16 -14
- package/test/component/dereference.fixtures.js +15 -24
- package/test/component/dereference.test.js +18 -8
- package/test/component/dummies/extension/index.js +1 -5
- package/test/component/dummies/migrations/conflicting/migrations/0001-one.yaml +2 -0
- package/test/component/dummies/migrations/conflicting/migrations/0001-one.yml +2 -0
- package/test/component/dummies/migrations/malformed/migrations/0001-one.yaml +1 -0
- package/test/component/dummies/migrations/ordered/migrations/0001-first.yml +4 -0
- package/test/component/dummies/migrations/ordered/migrations/0002-second.yaml +4 -0
- package/test/component/dummies/migrations/ordered/migrations/0010-third.json +1 -0
- package/test/component/dummies/migrations/stateless/migrations/0001-one.yaml +2 -0
- package/test/component/expand.fixtures.js +13 -13
- package/test/component/expand.test.js +25 -10
- package/test/component/migrations.test.js +62 -0
- package/test/component/normalize.fixtures.js +3 -7
- package/test/component/normalize.test.js +86 -28
- package/test/component/validate.fixtures.js +15 -13
- package/test/component/validate.test.js +162 -109
- package/test/context/complete.fixtures.js +2 -8
- package/test/context/complete.test.js +14 -8
- package/test/context/dereference.fixtures.js +3 -9
- package/test/context/dereference.test.js +18 -7
- package/test/context/expand.fixtures.js +1 -5
- package/test/context/expand.test.js +36 -8
- package/test/context/normalize.fixtures.js +2 -7
- package/test/context/normalize.test.js +33 -9
- package/test/context/validate.fixtures.js +1 -6
- package/test/context/validate.test.js +81 -37
- package/test/definition.test.js +35 -0
- package/test/dummies/bare/index.js +1 -0
- package/test/dummies/defined/definition.js +1 -0
- package/test/dummies/defined/index.js +1 -0
- package/test/dummies/defined/package.json +1 -0
- package/test/shortcuts.fixtures.js +4 -9
- package/test/shortcuts.test.js +17 -15
- package/types/component.d.ts +17 -3
- package/types/context/declaration.d.ts +26 -3
- package/types/context.d.ts +15 -13
- package/types/entity.d.ts +7 -0
- package/types/index.d.ts +12 -3
- package/src/.context/.dependencies/load.js +0 -36
- package/test/context/dependencies.load.test.js +0 -24
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import { generate } from 'randomstring'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
const context = {
|
|
3
|
+
export const context = {
|
|
6
4
|
runtime: {
|
|
7
5
|
version: '0.0.0'
|
|
8
6
|
},
|
|
9
7
|
name: 'test',
|
|
10
8
|
description: 'context fixture',
|
|
11
9
|
version: '0.0.0',
|
|
12
|
-
packages: 'namespaces/**/*',
|
|
13
10
|
registry: 'localhost:5000',
|
|
14
11
|
compositions: [
|
|
15
12
|
{
|
|
@@ -28,5 +25,3 @@ const context = {
|
|
|
28
25
|
}
|
|
29
26
|
}
|
|
30
27
|
}
|
|
31
|
-
|
|
32
|
-
exports.context = context
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import * as definitions from '@toa.io/definitions'
|
|
2
|
+
import { it, beforeEach } from 'node:test'
|
|
3
|
+
import assert from 'node:assert/strict'
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
import clone from 'clone-deep'
|
|
6
|
+
import { generate } from 'randomstring'
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
import * as fixtures from './normalize.fixtures.js'
|
|
9
|
+
import { normalize } from '../../src/.context/index.js'
|
|
8
10
|
|
|
9
11
|
let context
|
|
10
12
|
|
|
@@ -17,8 +19,8 @@ it('should resolve local version', () => {
|
|
|
17
19
|
|
|
18
20
|
normalize(context)
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
assert.notDeepStrictEqual(context.runtime, '.')
|
|
23
|
+
assert.deepStrictEqual(context.runtime.version, definitions.version)
|
|
22
24
|
})
|
|
23
25
|
|
|
24
26
|
it('should expand registry', () => {
|
|
@@ -28,7 +30,29 @@ it('should expand registry', () => {
|
|
|
28
30
|
|
|
29
31
|
normalize(context)
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
base
|
|
33
|
+
assert.deepStrictEqual(context.registry, {
|
|
34
|
+
base,
|
|
35
|
+
platforms: ['linux/amd64', 'linux/arm/v7', 'linux/arm64']
|
|
33
36
|
})
|
|
34
37
|
})
|
|
38
|
+
|
|
39
|
+
it('should set default platforms', () => {
|
|
40
|
+
context.registry = { base: generate() }
|
|
41
|
+
|
|
42
|
+
normalize(context)
|
|
43
|
+
|
|
44
|
+
assert.deepStrictEqual(context.registry.platforms, [
|
|
45
|
+
'linux/amd64',
|
|
46
|
+
'linux/arm/v7',
|
|
47
|
+
'linux/arm64'
|
|
48
|
+
])
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('should keep platforms declared as none', () => {
|
|
52
|
+
// `platforms: ~` in the context: the runner's own platform, not the default list
|
|
53
|
+
context.registry = { base: generate(), platforms: null }
|
|
54
|
+
|
|
55
|
+
normalize(context)
|
|
56
|
+
|
|
57
|
+
assert.strictEqual(context.registry.platforms, null)
|
|
58
|
+
})
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const context = {
|
|
1
|
+
export const context = {
|
|
4
2
|
runtime: {
|
|
5
3
|
version: '0.0.0'
|
|
6
4
|
},
|
|
7
5
|
name: 'test',
|
|
8
6
|
description: 'context fixture',
|
|
9
7
|
version: '0.0.0',
|
|
10
|
-
packages: 'namespaces/**/*',
|
|
11
8
|
build: {
|
|
12
9
|
command: 'echo test'
|
|
13
10
|
},
|
|
@@ -37,5 +34,3 @@ const context = {
|
|
|
37
34
|
}
|
|
38
35
|
}
|
|
39
36
|
}
|
|
40
|
-
|
|
41
|
-
exports.context = context
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
import { describe, it, before, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
import clone from 'clone-deep'
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
import { validate } from '../../src/.context/index.js'
|
|
7
|
+
import * as fixtures from './validate.fixtures.js'
|
|
7
8
|
|
|
8
9
|
let context
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
before(() => {
|
|
12
|
+
assert.doesNotThrow(() => validate(fixtures.context))
|
|
12
13
|
})
|
|
13
14
|
|
|
14
15
|
beforeEach(() => {
|
|
@@ -18,23 +19,32 @@ beforeEach(() => {
|
|
|
18
19
|
describe('runtime', () => {
|
|
19
20
|
it('should require', () => {
|
|
20
21
|
delete context.runtime
|
|
21
|
-
|
|
22
|
+
assert.throws(
|
|
23
|
+
() => validate(context),
|
|
24
|
+
(error) => /required/.test(error.message)
|
|
25
|
+
)
|
|
22
26
|
})
|
|
23
27
|
|
|
24
28
|
it('should require registry to match uri format', () => {
|
|
25
29
|
context.runtime.registry = 'not-a-uri'
|
|
26
|
-
|
|
30
|
+
assert.throws(
|
|
31
|
+
() => validate(context),
|
|
32
|
+
(error) => /must match format/.test(error.message)
|
|
33
|
+
)
|
|
27
34
|
|
|
28
35
|
context.runtime.registry = 'http://localhost'
|
|
29
|
-
|
|
36
|
+
assert.doesNotThrow(() => validate(context))
|
|
30
37
|
})
|
|
31
38
|
|
|
32
39
|
it('should require proxy to match uri format', () => {
|
|
33
40
|
context.runtime.proxy = 'not-a-uri'
|
|
34
|
-
|
|
41
|
+
assert.throws(
|
|
42
|
+
() => validate(context),
|
|
43
|
+
(error) => /must match format/.test(error.message)
|
|
44
|
+
)
|
|
35
45
|
|
|
36
46
|
context.runtime.proxy = 'http://localhost'
|
|
37
|
-
|
|
47
|
+
assert.doesNotThrow(() => validate(context))
|
|
38
48
|
})
|
|
39
49
|
})
|
|
40
50
|
|
|
@@ -42,43 +52,77 @@ describe('registry', () => {
|
|
|
42
52
|
it('should require', () => {
|
|
43
53
|
delete context.registry
|
|
44
54
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
delete context.registry.base
|
|
50
|
-
|
|
51
|
-
expect(() => validate(context)).toThrow(/required property 'base'/)
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
it('should set default platforms', () => {
|
|
55
|
-
delete context.registry.platforms
|
|
56
|
-
|
|
57
|
-
validate(context)
|
|
58
|
-
|
|
59
|
-
expect(context.registry.platforms).toBeInstanceOf(Array)
|
|
60
|
-
expect(context.registry.platforms).toStrictEqual(['linux/amd64', 'linux/arm/v7', 'linux/arm64'])
|
|
55
|
+
assert.throws(
|
|
56
|
+
() => validate(context),
|
|
57
|
+
(error) => /required property 'registry'/.test(error.message)
|
|
58
|
+
)
|
|
61
59
|
})
|
|
62
60
|
})
|
|
63
61
|
|
|
64
62
|
it('should require name as label', () => {
|
|
65
63
|
delete context.name
|
|
66
|
-
|
|
64
|
+
assert.throws(
|
|
65
|
+
() => validate(context),
|
|
66
|
+
(error) => /required/.test(error.message)
|
|
67
|
+
)
|
|
67
68
|
|
|
68
69
|
context.name = 'foo bar'
|
|
69
|
-
|
|
70
|
+
assert.throws(
|
|
71
|
+
() => validate(context),
|
|
72
|
+
(error) => /pattern/.test(error.message)
|
|
73
|
+
)
|
|
70
74
|
|
|
71
75
|
context.name = 'foo-bar'
|
|
72
|
-
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
it('should set default packages location', () => {
|
|
76
|
-
delete context.packages
|
|
77
|
-
expect(() => validate(context)).not.toThrow()
|
|
78
|
-
expect(context.packages).toBe('components/*')
|
|
76
|
+
assert.doesNotThrow(() => validate(context))
|
|
79
77
|
})
|
|
80
78
|
|
|
81
79
|
it('should require registry url', () => {
|
|
82
80
|
delete context.registry
|
|
83
|
-
|
|
81
|
+
assert.throws(
|
|
82
|
+
() => validate(context),
|
|
83
|
+
(error) => /required/.test(error.message)
|
|
84
|
+
)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it('should allow mono replicas and resources', () => {
|
|
88
|
+
context.mono = {
|
|
89
|
+
replicas: 2,
|
|
90
|
+
resources: {
|
|
91
|
+
cpu: ['200m', '2'],
|
|
92
|
+
memory: ['256Mi', '2Gi']
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
assert.doesNotThrow(() => validate(context))
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
describe('compositions', () => {
|
|
100
|
+
it('should allow services', () => {
|
|
101
|
+
context.compositions[0].services = ['@toa.io/extensions.exposition']
|
|
102
|
+
|
|
103
|
+
assert.doesNotThrow(() => validate(context))
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('should require services to be a non-empty array of strings', () => {
|
|
107
|
+
context.compositions[0].services = []
|
|
108
|
+
assert.throws(
|
|
109
|
+
() => validate(context),
|
|
110
|
+
(error) => /fewer than 1 items/.test(error.message)
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
context.compositions[0].services = 'exposition'
|
|
114
|
+
assert.throws(
|
|
115
|
+
() => validate(context),
|
|
116
|
+
(error) => /must be array/.test(error.message)
|
|
117
|
+
)
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it('should reject an unknown property', () => {
|
|
121
|
+
context.compositions[0].compoments = ['a.b']
|
|
122
|
+
|
|
123
|
+
assert.throws(
|
|
124
|
+
() => validate(context),
|
|
125
|
+
(error) => /Property compoments is not expected to be here/.test(error.message)
|
|
126
|
+
)
|
|
127
|
+
})
|
|
84
128
|
})
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { it } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import { join } from 'node:path'
|
|
4
|
+
|
|
5
|
+
import { definition } from '../src/definition.js'
|
|
6
|
+
|
|
7
|
+
it('reads a definition.js where a package ships one', async () => {
|
|
8
|
+
const { name, module } = await definition(join(import.meta.dirname, 'dummies/defined'))
|
|
9
|
+
|
|
10
|
+
assert.equal(name, 'dummies.defined')
|
|
11
|
+
assert.equal(module.declares, true)
|
|
12
|
+
assert.equal(module.runs, undefined)
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('reads the entry where a package ships no definition.js', async () => {
|
|
16
|
+
const path = join(import.meta.dirname, '../')
|
|
17
|
+
const { name, module } = await definition(path)
|
|
18
|
+
|
|
19
|
+
assert.equal(name, '@toa.io/norm')
|
|
20
|
+
assert.ok(module.context instanceof Function)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it('names a directory without package.json by its reference', async () => {
|
|
24
|
+
const path = join(import.meta.dirname, 'dummies/bare')
|
|
25
|
+
const { name, module } = await definition(path)
|
|
26
|
+
|
|
27
|
+
assert.equal(name, path)
|
|
28
|
+
assert.equal(module.declares, true)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('loads a definition once', async () => {
|
|
32
|
+
const path = join(import.meta.dirname, 'dummies/bare')
|
|
33
|
+
|
|
34
|
+
assert.equal(await definition(path), await definition(path))
|
|
35
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const declares = true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const declares = true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const runs = true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "name": "dummies.defined", "type": "module", "main": "index.js" }
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { generate } from 'randomstring'
|
|
2
|
+
import { random } from '@toa.io/generic'
|
|
2
3
|
|
|
3
|
-
const
|
|
4
|
-
const { random } = require('@toa.io/generic')
|
|
5
|
-
|
|
6
|
-
const SHORTCUTS = {
|
|
4
|
+
export const SHORTCUTS = {
|
|
7
5
|
amqp: '@toa.io/bindings.amqp',
|
|
8
6
|
mongodb: '@toa.io/storages.mongodb'
|
|
9
7
|
}
|
|
10
8
|
|
|
11
|
-
const object = { foo: random(), bar: { baz: generate() } }
|
|
12
|
-
|
|
13
|
-
exports.object = object
|
|
14
|
-
exports.SHORTCUTS = SHORTCUTS
|
|
9
|
+
export const object = { foo: random(), bar: { baz: generate() } }
|
package/test/shortcuts.test.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import { describe, it, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
import clone from 'clone-deep'
|
|
5
|
+
import { generate } from 'randomstring'
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
import { recognize, resolve } from '../src/shortcuts.js'
|
|
8
|
+
import * as fixtures from './shortcuts.fixtures.js'
|
|
8
9
|
|
|
9
10
|
let object
|
|
10
11
|
|
|
@@ -14,16 +15,16 @@ beforeEach(() => {
|
|
|
14
15
|
|
|
15
16
|
describe('resolve', () => {
|
|
16
17
|
it('should be defined', () => {
|
|
17
|
-
|
|
18
|
+
assert.notStrictEqual(resolve, undefined)
|
|
18
19
|
})
|
|
19
20
|
|
|
20
21
|
it('should resolve', () => {
|
|
21
|
-
|
|
22
|
+
assert.ok(Object.keys(fixtures.SHORTCUTS).length > 0)
|
|
22
23
|
|
|
23
24
|
for (const [key, value] of Object.entries(fixtures.SHORTCUTS)) {
|
|
24
25
|
const resolved = resolve(key)
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
assert.deepStrictEqual(resolved, value)
|
|
27
28
|
}
|
|
28
29
|
})
|
|
29
30
|
})
|
|
@@ -32,7 +33,7 @@ describe('recognize', () => {
|
|
|
32
33
|
it('should not change unknown', () => {
|
|
33
34
|
recognize(fixtures.SHORTCUTS, object)
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
assert.deepStrictEqual(object, fixtures.object)
|
|
36
37
|
})
|
|
37
38
|
|
|
38
39
|
it('should resolve known', () => {
|
|
@@ -41,8 +42,8 @@ describe('recognize', () => {
|
|
|
41
42
|
recognize(fixtures.SHORTCUTS, object)
|
|
42
43
|
|
|
43
44
|
for (const [alias, name] of Object.entries(fixtures.SHORTCUTS)) {
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
assert.strictEqual(object[alias], undefined)
|
|
46
|
+
assert.deepStrictEqual(object[name], known[name])
|
|
46
47
|
}
|
|
47
48
|
})
|
|
48
49
|
|
|
@@ -52,9 +53,10 @@ describe('recognize', () => {
|
|
|
52
53
|
|
|
53
54
|
recognize(fixtures.SHORTCUTS, object, group)
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
assert.deepStrictEqual(object[group], known)
|
|
56
57
|
|
|
57
|
-
for (const alias of Object.keys(fixtures.SHORTCUTS))
|
|
58
|
+
for (const alias of Object.keys(fixtures.SHORTCUTS))
|
|
59
|
+
assert.strictEqual(object[alias], undefined)
|
|
58
60
|
})
|
|
59
61
|
|
|
60
62
|
it('should not overwrite group', () => {
|
|
@@ -67,7 +69,7 @@ describe('recognize', () => {
|
|
|
67
69
|
|
|
68
70
|
recognize(fixtures.SHORTCUTS, object, group)
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
assert.partialDeepStrictEqual(object[group], existing)
|
|
71
73
|
})
|
|
72
74
|
|
|
73
75
|
it('should not create empty group', () => {
|
|
@@ -75,7 +77,7 @@ describe('recognize', () => {
|
|
|
75
77
|
|
|
76
78
|
recognize(object, group)
|
|
77
79
|
|
|
78
|
-
|
|
80
|
+
assert.strictEqual(object[group], undefined)
|
|
79
81
|
})
|
|
80
82
|
|
|
81
83
|
const append = () => {
|
package/types/component.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { Locator
|
|
1
|
+
import type { Locator } from '@toa.io/core'
|
|
2
|
+
import type { operations } from '@toa.io/core/types'
|
|
2
3
|
|
|
3
4
|
type Map = {
|
|
4
5
|
[id: string]: Component
|
|
@@ -8,6 +9,7 @@ export type Operation = {
|
|
|
8
9
|
type: operations.type
|
|
9
10
|
scope?: operations.scope
|
|
10
11
|
bindings?: string[]
|
|
12
|
+
description?: string
|
|
11
13
|
input?: any
|
|
12
14
|
output?: any
|
|
13
15
|
error?: any
|
|
@@ -34,10 +36,22 @@ type Receiver = {
|
|
|
34
36
|
source?: string
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
type
|
|
38
|
-
|
|
39
|
+
type Migration = {
|
|
40
|
+
id: string
|
|
41
|
+
steps: unknown[]
|
|
42
|
+
/** the prototype it is inherited from; absent on the component's own */
|
|
43
|
+
prototype?: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type Entity = {
|
|
47
|
+
properties: Record<string, Object>
|
|
48
|
+
required?: string[]
|
|
49
|
+
/** what a record holds before anything is written to it */
|
|
50
|
+
blank?: Record<string, unknown>
|
|
39
51
|
storage?: string
|
|
40
52
|
associated?: boolean
|
|
53
|
+
custom?: boolean
|
|
54
|
+
migrations?: Migration[]
|
|
41
55
|
}
|
|
42
56
|
|
|
43
57
|
type Declaration = {
|
|
@@ -1,8 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Registry, Runtime } from '../context.js'
|
|
2
2
|
|
|
3
|
+
/** A composition as declared, before its members are resolved. */
|
|
3
4
|
interface Composition {
|
|
4
|
-
name: string
|
|
5
|
+
name: string
|
|
5
6
|
components: string[]
|
|
7
|
+
services?: string[]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface Resources {
|
|
11
|
+
cpu?: [string, string]
|
|
12
|
+
memory?: [string, string]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface Mono {
|
|
16
|
+
replicas?: number
|
|
17
|
+
resources?: Resources
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Cluster-level ingress configuration, applied to every service that declares one.
|
|
22
|
+
*/
|
|
23
|
+
export interface Ingress {
|
|
24
|
+
hosts?: string[]
|
|
25
|
+
class?: string
|
|
26
|
+
annotations?: Record<string, string>
|
|
27
|
+
default?: boolean
|
|
6
28
|
}
|
|
7
29
|
|
|
8
30
|
export interface Declaration {
|
|
@@ -11,7 +33,8 @@ export interface Declaration {
|
|
|
11
33
|
version?: string
|
|
12
34
|
runtime?: Runtime | string
|
|
13
35
|
registry?: Registry | string
|
|
14
|
-
packages?: string
|
|
15
36
|
compositions?: Composition[]
|
|
37
|
+
mono?: Mono
|
|
38
|
+
ingress?: Ingress
|
|
16
39
|
annotations?: Record<string, object>
|
|
17
40
|
}
|
package/types/context.d.ts
CHANGED
|
@@ -1,41 +1,43 @@
|
|
|
1
|
-
import { Manifest } from './component'
|
|
1
|
+
import { Manifest } from './component.js'
|
|
2
2
|
import { Locator } from '@toa.io/core'
|
|
3
|
-
import type { Declaration } from './context/declaration'
|
|
3
|
+
import type { Declaration } from './context/declaration.js'
|
|
4
4
|
|
|
5
|
-
interface Runtime{
|
|
5
|
+
interface Runtime {
|
|
6
6
|
version: string
|
|
7
7
|
registry?: string
|
|
8
8
|
proxy?: string
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
interface Registry{
|
|
11
|
+
interface Registry {
|
|
12
12
|
base?: string
|
|
13
13
|
platforms?: string[] | null
|
|
14
|
+
services?: 'build' | 'published'
|
|
14
15
|
build?: {
|
|
15
16
|
arguments?: string[]
|
|
16
17
|
run?: string
|
|
17
|
-
}
|
|
18
|
+
}
|
|
18
19
|
credentials: string
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
interface Composition{
|
|
22
|
-
name: string
|
|
23
|
-
components:
|
|
22
|
+
interface Composition {
|
|
23
|
+
name: string
|
|
24
|
+
components: Manifest[]
|
|
25
|
+
services?: string[]
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
export interface Dependency<T = undefined>{
|
|
28
|
+
export interface Dependency<T = undefined> {
|
|
27
29
|
locator: Locator
|
|
28
|
-
manifest: T
|
|
30
|
+
manifest: T
|
|
29
31
|
component: Manifest
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
interface Context extends Declaration{
|
|
34
|
+
interface Context extends Declaration {
|
|
33
35
|
runtime?: Runtime
|
|
34
36
|
environment?: string
|
|
35
37
|
registry?: Registry
|
|
36
38
|
compositions?: Composition[]
|
|
37
|
-
components?:
|
|
39
|
+
components?: Manifest[]
|
|
38
40
|
dependencies?: Record<string, Dependency[]>
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
export function context
|
|
43
|
+
export function context(path: string, environment?: string): Promise<Context>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Entity } from './component.js'
|
|
2
|
+
|
|
3
|
+
/** The schema a stored record must fit. */
|
|
4
|
+
export function schema(entity: Entity): object
|
|
5
|
+
|
|
6
|
+
/** The schema a changeset must fit: the same properties, none of them required. */
|
|
7
|
+
export function changeset(entity: Entity): object
|
package/types/index.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
export * as context from './context'
|
|
2
|
-
export * as component from './component'
|
|
1
|
+
export * as context from './context.js'
|
|
2
|
+
export * as component from './component.js'
|
|
3
3
|
|
|
4
|
-
export { Manifest } from './component'
|
|
4
|
+
export { Manifest } from './component.js'
|
|
5
|
+
export * as entity from './entity.js'
|
|
6
|
+
|
|
7
|
+
export interface Definition {
|
|
8
|
+
/** The package's name, or the reference where it has no package.json */
|
|
9
|
+
name: string
|
|
10
|
+
module: Record<string, any>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function definition(reference: string): Promise<Definition>
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { join } = require('node:path')
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @param {string} path
|
|
7
|
-
* @returns {{ metadata: object, module: object }}
|
|
8
|
-
*/
|
|
9
|
-
function load (path) {
|
|
10
|
-
const metadata = loadMetadata(path)
|
|
11
|
-
const module = loadModule(path)
|
|
12
|
-
|
|
13
|
-
return { metadata, module }
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function loadMetadata (reference) {
|
|
17
|
-
reference = join(reference, 'package.json')
|
|
18
|
-
|
|
19
|
-
try {
|
|
20
|
-
return require(reference)
|
|
21
|
-
} catch {
|
|
22
|
-
return null
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* @param {string} reference
|
|
28
|
-
* @returns {object}
|
|
29
|
-
*/
|
|
30
|
-
function loadModule (reference) {
|
|
31
|
-
const path = require.resolve(reference)
|
|
32
|
-
|
|
33
|
-
return require(path)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
exports.load = load
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { join } = require('node:path')
|
|
4
|
-
const { load } = require('../../src/.context/.dependencies/load')
|
|
5
|
-
|
|
6
|
-
it('should be', async () => {
|
|
7
|
-
expect(load).toBeInstanceOf(Function)
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
it('should load module', async () => {
|
|
11
|
-
const path = join(__dirname, '../../')
|
|
12
|
-
const { metadata, module } = load(path)
|
|
13
|
-
|
|
14
|
-
expect(metadata.name).toStrictEqual('@toa.io/norm')
|
|
15
|
-
expect(module.context).toBeInstanceOf(Function)
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
it('should return null metadata if no package.json', async () => {
|
|
19
|
-
const path = join(__dirname, '../../src')
|
|
20
|
-
const { metadata, module } = load(path)
|
|
21
|
-
|
|
22
|
-
expect(metadata).toBeNull()
|
|
23
|
-
expect(module.context).toBeInstanceOf(Function)
|
|
24
|
-
})
|