@toa.io/extensions.configuration 0.20.0-dev.34 → 0.20.0-dev.36
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/package.json +16 -9
- package/readme.md +19 -27
- package/schemas/annotation.cos.yaml +1 -0
- package/schemas/manifest.cos.yaml +2 -0
- package/source/Aspect.test.ts +15 -0
- package/source/Aspect.ts +23 -0
- package/source/Factory.ts +12 -0
- package/source/configuration.test.ts +89 -0
- package/source/configuration.ts +52 -0
- package/source/deployment.test.ts +21 -0
- package/source/deployment.ts +69 -0
- package/source/index.ts +3 -0
- package/source/manifest.test.ts +15 -0
- package/source/manifest.ts +15 -0
- package/source/schemas.ts +8 -0
- package/tsconfig.json +9 -0
- package/docs/discussion.md +0 -109
- package/source/.deployment/index.js +0 -7
- package/source/.deployment/secrets.js +0 -35
- package/source/.deployment/variables.js +0 -23
- package/source/.manifest/.normalize/verbose.js +0 -51
- package/source/.manifest/index.js +0 -7
- package/source/.manifest/normalize.js +0 -16
- package/source/.manifest/schema.yaml +0 -9
- package/source/.manifest/validate.js +0 -13
- package/source/.provider/env.js +0 -19
- package/source/.provider/form.js +0 -20
- package/source/.provider/index.js +0 -7
- package/source/annotation.fixtures.js +0 -39
- package/source/annotation.js +0 -36
- package/source/annotation.test.js +0 -43
- package/source/aspect.fixtures.js +0 -32
- package/source/aspect.js +0 -36
- package/source/aspect.test.js +0 -76
- package/source/configuration.js +0 -19
- package/source/deployment.fixtures.js +0 -38
- package/source/deployment.js +0 -20
- package/source/deployment.test.js +0 -70
- package/source/factory.js +0 -39
- package/source/factory.test.js +0 -22
- package/source/index.js +0 -13
- package/source/manifest.js +0 -13
- package/source/manifest.test.js +0 -123
- package/source/provider.js +0 -119
- package/source/provider.test.js +0 -130
- package/source/secrets.js +0 -28
- package/source/secrets.test.js +0 -47
- package/types/aspect.d.ts +0 -11
- package/types/factory.d.ts +0 -12
- package/types/provider.d.ts +0 -22
- /package/{docs → notes}/consistency.md +0 -0
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { remap } = require('@toa.io/generic')
|
|
4
|
-
|
|
5
|
-
const verbose = (node) => {
|
|
6
|
-
const isObject = node.properties !== undefined
|
|
7
|
-
const isValue = node.type !== undefined && node.type !== 'object'
|
|
8
|
-
const isProperties = node[SYM] === 1
|
|
9
|
-
|
|
10
|
-
if (!isObject && !isValue && !isProperties) return convert(node)
|
|
11
|
-
|
|
12
|
-
return node
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const convert = (node) => {
|
|
16
|
-
const properties = remap(node, property)
|
|
17
|
-
|
|
18
|
-
properties[SYM] = 1
|
|
19
|
-
|
|
20
|
-
return { type: 'object', properties, additionalProperties: false }
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function property (node) {
|
|
24
|
-
if (node === null) return { type: 'null', default: null }
|
|
25
|
-
|
|
26
|
-
const type = Array.isArray(node) ? 'array' : typeof node
|
|
27
|
-
|
|
28
|
-
if (type === 'object') return node
|
|
29
|
-
if (type === 'array') return array(node)
|
|
30
|
-
|
|
31
|
-
return { type, default: node }
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const array = (array) => {
|
|
35
|
-
if (array.length === 0) throw new Error('Configuration: cannot resolve concise array items type because it\'s empty')
|
|
36
|
-
|
|
37
|
-
const type = typeof array[0]
|
|
38
|
-
|
|
39
|
-
const schema = {
|
|
40
|
-
type: 'array',
|
|
41
|
-
default: array
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (array.length === 1) schema.items = array[0]
|
|
45
|
-
|
|
46
|
-
return schema
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const SYM = Symbol()
|
|
50
|
-
|
|
51
|
-
exports.verbose = verbose
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { traverse } = require('@toa.io/generic')
|
|
4
|
-
const { verbose } = require('./.normalize/verbose')
|
|
5
|
-
|
|
6
|
-
const normalize = (manifest) => {
|
|
7
|
-
if (manifest.properties === undefined) manifest = expand(manifest)
|
|
8
|
-
|
|
9
|
-
return manifest
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const expand = (concise) => {
|
|
13
|
-
return traverse(concise, verbose)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
exports.normalize = normalize
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
$schema: https://json-schema.org/draft/2019-09/schema
|
|
2
|
-
$id: https://schemas.toa.io/0.0.0/extensions/configuration/manifest
|
|
3
|
-
|
|
4
|
-
$ref: 'https://schemas.toa.io/0.0.0/definitions#/definitions/schema'
|
|
5
|
-
type: object
|
|
6
|
-
properties:
|
|
7
|
-
type:
|
|
8
|
-
const: object
|
|
9
|
-
default: object
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const path = require('path')
|
|
4
|
-
|
|
5
|
-
const { Schema } = require('@toa.io/schema')
|
|
6
|
-
const { load } = require('@toa.io/yaml')
|
|
7
|
-
|
|
8
|
-
const schema = load.sync(path.resolve(__dirname, 'schema.yaml'))
|
|
9
|
-
const validator = new Schema(schema)
|
|
10
|
-
|
|
11
|
-
const validate = (declaration) => validator.validate(declaration)
|
|
12
|
-
|
|
13
|
-
exports.validate = validate
|
package/source/.provider/env.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { map } = require('@toa.io/generic')
|
|
4
|
-
|
|
5
|
-
function env (object) {
|
|
6
|
-
return map(object,
|
|
7
|
-
/**
|
|
8
|
-
* @type {toa.generic.map.transform<string>}
|
|
9
|
-
*/
|
|
10
|
-
(value) => {
|
|
11
|
-
if (typeof value !== 'string') return
|
|
12
|
-
|
|
13
|
-
return value.replaceAll(RX, (match, variable) => process.env[variable] ?? match)
|
|
14
|
-
})
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const RX = /\${(?<variable>[A-Z0-9_]{1,32})}/g
|
|
18
|
-
|
|
19
|
-
exports.env = env
|
package/source/.provider/form.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { traverse } = require('@toa.io/generic')
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @param {toa.schema.JSON | Object} schema
|
|
7
|
-
* @return {Object}
|
|
8
|
-
*/
|
|
9
|
-
const form = (schema) => {
|
|
10
|
-
const defaults = (node) => {
|
|
11
|
-
if (node.type === 'object' && node.properties !== undefined) return { ...node.properties }
|
|
12
|
-
if (node.default !== undefined) return node.default
|
|
13
|
-
|
|
14
|
-
return null
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return traverse(schema, defaults)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
exports.form = form
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { generate } = require('randomstring')
|
|
4
|
-
const { Locator } = require('@toa.io/core')
|
|
5
|
-
const { random } = require('@toa.io/generic')
|
|
6
|
-
|
|
7
|
-
const instance = () => {
|
|
8
|
-
const name = generate()
|
|
9
|
-
const namespace = generate()
|
|
10
|
-
const locator = new Locator(name, namespace)
|
|
11
|
-
|
|
12
|
-
const manifest = {
|
|
13
|
-
type: 'object',
|
|
14
|
-
properties: {
|
|
15
|
-
foo: {
|
|
16
|
-
type: 'number',
|
|
17
|
-
default: 1
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return { locator, manifest }
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** @type {toa.norm.context.dependencies.Instance[]} */
|
|
26
|
-
const instances = []
|
|
27
|
-
|
|
28
|
-
for (let i = 0; i < random(5) + 5; i++) instances.push(instance())
|
|
29
|
-
|
|
30
|
-
/** @type {Object} */
|
|
31
|
-
const annotation = {}
|
|
32
|
-
|
|
33
|
-
for (let i = 0; i < random(instances.length - 1) + 1; i++) {
|
|
34
|
-
const instance = instances[i]
|
|
35
|
-
annotation[instance.locator.id] = { foo: random() }
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
exports.instances = instances
|
|
39
|
-
exports.annotation = annotation
|
package/source/annotation.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { Schema } = require('@toa.io/schema')
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @param {Object} annotation
|
|
7
|
-
* @param {toa.norm.context.dependencies.Instance[]} instances
|
|
8
|
-
*/
|
|
9
|
-
const annotation = (annotation, instances) => {
|
|
10
|
-
const keys = Object.keys(annotation)
|
|
11
|
-
|
|
12
|
-
check(keys, instances)
|
|
13
|
-
|
|
14
|
-
for (const instance of instances) {
|
|
15
|
-
const object = annotation[instance.locator.id] ?? {}
|
|
16
|
-
const schema = new Schema(instance.manifest)
|
|
17
|
-
|
|
18
|
-
schema.validate(object)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return annotation
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @param {string[]} keys
|
|
26
|
-
* @param {toa.norm.context.dependencies.Instance[]} instances
|
|
27
|
-
*/
|
|
28
|
-
const check = (keys, instances) => {
|
|
29
|
-
const ids = instances.map((instance) => instance.locator.id)
|
|
30
|
-
|
|
31
|
-
for (const key of keys) {
|
|
32
|
-
if (!ids.includes(key)) throw new Error(`Configuration Schema '${key}' is not defined`)
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
exports.annotation = annotation
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const clone = require('clone-deep')
|
|
4
|
-
const { generate } = require('randomstring')
|
|
5
|
-
const { sample } = require('@toa.io/generic')
|
|
6
|
-
|
|
7
|
-
const fixtures = require('./annotation.fixtures')
|
|
8
|
-
const { annotation } = require('../')
|
|
9
|
-
|
|
10
|
-
let input
|
|
11
|
-
/** @type {toa.norm.context.dependencies.Instance[]} */ let instances
|
|
12
|
-
|
|
13
|
-
const call = () => annotation(input, instances)
|
|
14
|
-
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
input = clone(fixtures.annotation)
|
|
17
|
-
instances = clone(fixtures.instances)
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it('sample must be valid', () => {
|
|
21
|
-
expect(call).not.toThrow()
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
it('should must be a function', () => {
|
|
25
|
-
expect(annotation).toBeDefined()
|
|
26
|
-
expect(annotation).toBeInstanceOf(Function)
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
it('should throw on non-existent component', () => {
|
|
30
|
-
input[generate()] = {}
|
|
31
|
-
|
|
32
|
-
expect(call).toThrow(/Configuration Schema/)
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it('should throw if object doesn\'t match schema', () => {
|
|
36
|
-
const keys = Object.keys(input)
|
|
37
|
-
const key = sample(keys)
|
|
38
|
-
const object = input[key]
|
|
39
|
-
|
|
40
|
-
object.foo = generate()
|
|
41
|
-
|
|
42
|
-
expect(call).toThrow(/foo must be number/)
|
|
43
|
-
})
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { generate } = require('randomstring')
|
|
4
|
-
|
|
5
|
-
const schema = {
|
|
6
|
-
type: 'object',
|
|
7
|
-
properties: {
|
|
8
|
-
foo: {
|
|
9
|
-
type: 'string',
|
|
10
|
-
default: generate()
|
|
11
|
-
},
|
|
12
|
-
bar: {
|
|
13
|
-
type: 'object',
|
|
14
|
-
properties: {
|
|
15
|
-
baz: {
|
|
16
|
-
type: 'number',
|
|
17
|
-
default: 1
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const concise = {
|
|
25
|
-
foo: schema.properties.foo.default,
|
|
26
|
-
bar: {
|
|
27
|
-
baz: schema.properties.bar.properties.baz.default
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
exports.schema = schema
|
|
32
|
-
exports.concise = concise
|
package/source/aspect.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { Connector } = require('@toa.io/core')
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @implements {toa.extensions.configuration.Aspect}
|
|
7
|
-
*/
|
|
8
|
-
class Aspect extends Connector {
|
|
9
|
-
/** @readonly */
|
|
10
|
-
name = 'configuration'
|
|
11
|
-
|
|
12
|
-
/** @type {toa.core.Reflection} */
|
|
13
|
-
#refection
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @param {toa.core.Reflection} reflection
|
|
17
|
-
*/
|
|
18
|
-
constructor (reflection) {
|
|
19
|
-
super()
|
|
20
|
-
|
|
21
|
-
this.#refection = reflection
|
|
22
|
-
|
|
23
|
-
this.depends(reflection)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
invoke (path) {
|
|
27
|
-
/** @type {any} */
|
|
28
|
-
let cursor = this.#refection.value
|
|
29
|
-
|
|
30
|
-
if (path !== undefined) for (const segment of path) cursor = cursor[segment]
|
|
31
|
-
|
|
32
|
-
return cursor
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
exports.Aspect = Aspect
|
package/source/aspect.test.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { Locator } = require('@toa.io/core')
|
|
4
|
-
const { encode } = require('@toa.io/generic')
|
|
5
|
-
|
|
6
|
-
const fixtures = require('./aspect.fixtures')
|
|
7
|
-
const { Factory } = require('../')
|
|
8
|
-
const { generate } = require('randomstring')
|
|
9
|
-
|
|
10
|
-
const factory = new Factory()
|
|
11
|
-
|
|
12
|
-
/** @type {toa.extensions.configuration.Aspect} */
|
|
13
|
-
let aspect
|
|
14
|
-
|
|
15
|
-
/** @type {toa.core.Locator} */
|
|
16
|
-
let locator
|
|
17
|
-
|
|
18
|
-
describe('defaults', () => {
|
|
19
|
-
beforeEach(async () => {
|
|
20
|
-
const namespace = generate()
|
|
21
|
-
const name = generate()
|
|
22
|
-
|
|
23
|
-
locator = new Locator(name, namespace)
|
|
24
|
-
|
|
25
|
-
aspect = factory.aspect(locator, fixtures.schema)
|
|
26
|
-
|
|
27
|
-
await aspect.connect()
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
it('should return schema defaults', () => {
|
|
31
|
-
const foo = aspect.invoke(['foo'])
|
|
32
|
-
|
|
33
|
-
expect(foo).toStrictEqual(fixtures.schema.properties.foo.default)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
it('should return nested values', () => {
|
|
37
|
-
const baz = aspect.invoke(['bar', 'baz'])
|
|
38
|
-
|
|
39
|
-
expect(baz).toStrictEqual(fixtures.schema.properties.bar.properties.baz.default)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('should expose configuration tree', () => {
|
|
43
|
-
const configuration = aspect.invoke()
|
|
44
|
-
|
|
45
|
-
expect(configuration).toStrictEqual({
|
|
46
|
-
foo: fixtures.schema.properties.foo.default,
|
|
47
|
-
bar: {
|
|
48
|
-
baz: fixtures.schema.properties.bar.properties.baz.default
|
|
49
|
-
}
|
|
50
|
-
})
|
|
51
|
-
})
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
describe('resolution', () => {
|
|
55
|
-
let object
|
|
56
|
-
let varname
|
|
57
|
-
|
|
58
|
-
beforeEach(() => {
|
|
59
|
-
object = { foo: generate() }
|
|
60
|
-
|
|
61
|
-
varname = 'TOA_CONFIGURATION_' + locator.uppercase
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('should resolve configuration object from environment variable', async () => {
|
|
65
|
-
process.env[varname] = encode(object)
|
|
66
|
-
|
|
67
|
-
aspect = factory.aspect(locator, fixtures.schema)
|
|
68
|
-
|
|
69
|
-
await aspect.connect()
|
|
70
|
-
|
|
71
|
-
const configuration = aspect.invoke()
|
|
72
|
-
|
|
73
|
-
expect(configuration.foo).toStrictEqual(object.foo)
|
|
74
|
-
expect(configuration.bar.baz).toStrictEqual(fixtures.schema.properties.bar.properties.baz.default)
|
|
75
|
-
})
|
|
76
|
-
})
|
package/source/configuration.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { Reflection } = require('@toa.io/core')
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @implements {toa.core.Reflection}
|
|
7
|
-
*/
|
|
8
|
-
class Configuration extends Reflection {
|
|
9
|
-
/**
|
|
10
|
-
* @param {toa.extensions.configuration.Provider} provider
|
|
11
|
-
*/
|
|
12
|
-
constructor (provider) {
|
|
13
|
-
super(provider.source)
|
|
14
|
-
|
|
15
|
-
this.depends(provider)
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
exports.Configuration = Configuration
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { generate } = require('randomstring')
|
|
4
|
-
|
|
5
|
-
const { Locator } = require('@toa.io/core')
|
|
6
|
-
const { random } = require('@toa.io/generic')
|
|
7
|
-
|
|
8
|
-
const component = () => {
|
|
9
|
-
const namespace = generate()
|
|
10
|
-
const name = generate()
|
|
11
|
-
|
|
12
|
-
return { locator: new Locator(name, namespace) }
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** @type {toa.norm.context.dependencies.Instance[]} */
|
|
16
|
-
const components = []
|
|
17
|
-
const annotations = {}
|
|
18
|
-
|
|
19
|
-
const annotate = (component) => {
|
|
20
|
-
const key = component.locator.id
|
|
21
|
-
|
|
22
|
-
annotations[key] = { [generate()]: generate() }
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
for (let i = 0; i < random(10) + 5; i++) components.push(component())
|
|
26
|
-
for (let i = 0; i < components.length; i++) if (i % 2 === 0) annotate(components[i])
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* @param {string} id
|
|
30
|
-
* @returns {toa.norm.context.dependencies.Instance}
|
|
31
|
-
*/
|
|
32
|
-
const find = (id) => {
|
|
33
|
-
return components.find((component) => component.locator.id === id)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
exports.components = components
|
|
37
|
-
exports.annotations = annotations
|
|
38
|
-
exports.find = find
|
package/source/deployment.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { merge } = require('@toa.io/generic')
|
|
4
|
-
const get = require('./.deployment')
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @param {toa.norm.context.dependencies.Instance[]} components
|
|
8
|
-
* @param {object} annotations
|
|
9
|
-
* @return {toa.deployment.dependency.Declaration}
|
|
10
|
-
*/
|
|
11
|
-
const deployment = (components, annotations) => {
|
|
12
|
-
const variables = get.variables(components, annotations)
|
|
13
|
-
const secrets = get.secrets(components, annotations)
|
|
14
|
-
|
|
15
|
-
merge(variables, secrets)
|
|
16
|
-
|
|
17
|
-
return { variables }
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
exports.deployment = deployment
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const clone = require('clone-deep')
|
|
4
|
-
const { encode, sample } = require('@toa.io/generic')
|
|
5
|
-
|
|
6
|
-
const fixtures = require('./deployment.fixtures')
|
|
7
|
-
const { deployment } = require('../')
|
|
8
|
-
const { generate } = require('randomstring')
|
|
9
|
-
|
|
10
|
-
/** @type {toa.deployment.dependency.Declaration} */
|
|
11
|
-
let declaration
|
|
12
|
-
|
|
13
|
-
beforeAll(() => {
|
|
14
|
-
declaration = deployment(fixtures.components, fixtures.annotations)
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
it('should exist', () => {
|
|
18
|
-
expect(deployment).toBeDefined()
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('should declare variables', () => {
|
|
22
|
-
expect(declaration.variables).toBeDefined()
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it('should map configurations', () => {
|
|
26
|
-
const keys = Object.keys(fixtures.annotations)
|
|
27
|
-
|
|
28
|
-
expect(keys.length).toBeGreaterThan(0)
|
|
29
|
-
|
|
30
|
-
for (const [id, annotations] of Object.entries(fixtures.annotations)) {
|
|
31
|
-
const component = fixtures.find(id)
|
|
32
|
-
const variables = declaration.variables[component.locator.label]
|
|
33
|
-
const encoded = encode(annotations)
|
|
34
|
-
|
|
35
|
-
expect(component).toBeDefined()
|
|
36
|
-
expect(variables).toBeDefined()
|
|
37
|
-
expect(variables).toBeInstanceOf(Array)
|
|
38
|
-
expect(variables.length).toStrictEqual(1)
|
|
39
|
-
|
|
40
|
-
const env = variables[0]
|
|
41
|
-
|
|
42
|
-
expect(env.name).toBeDefined()
|
|
43
|
-
expect(env.name).toStrictEqual('TOA_CONFIGURATION_' + component.locator.uppercase)
|
|
44
|
-
expect(env.value).toBeDefined()
|
|
45
|
-
expect(env.value).toStrictEqual(encoded)
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('should declare secrets', async () => {
|
|
50
|
-
const annotations = clone(fixtures.annotations)
|
|
51
|
-
const component = sample(fixtures.components)
|
|
52
|
-
const id = component.locator.id
|
|
53
|
-
const key = generate()
|
|
54
|
-
const name = generate().substring(0, 16).toUpperCase()
|
|
55
|
-
const value = '$' + name
|
|
56
|
-
|
|
57
|
-
if (annotations[id] === undefined) annotations[id] = {}
|
|
58
|
-
|
|
59
|
-
annotations[id][key] = value
|
|
60
|
-
|
|
61
|
-
declaration = deployment(fixtures.components, annotations)
|
|
62
|
-
|
|
63
|
-
const variables = declaration.variables[component.locator.label]
|
|
64
|
-
|
|
65
|
-
expect(variables).toBeDefined()
|
|
66
|
-
|
|
67
|
-
const secret = variables.find((variable) => variable.name === 'TOA_CONFIGURATION__' + name)
|
|
68
|
-
|
|
69
|
-
expect(secret).toBeDefined()
|
|
70
|
-
})
|
package/source/factory.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { Schema } = require('@toa.io/schema')
|
|
4
|
-
const { Aspect } = require('./aspect')
|
|
5
|
-
const { Configuration } = require('./configuration')
|
|
6
|
-
const { Provider } = require('./provider')
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @implements {toa.extensions.configuration.Factory}
|
|
10
|
-
*/
|
|
11
|
-
class Factory {
|
|
12
|
-
/**
|
|
13
|
-
* @param {toa.core.Locator} locator
|
|
14
|
-
* @param {toa.schema.JSON | Object} annotation
|
|
15
|
-
* @return {toa.extensions.configuration.Aspect}
|
|
16
|
-
*/
|
|
17
|
-
aspect (locator, annotation) {
|
|
18
|
-
const schema = new Schema(annotation)
|
|
19
|
-
const provider = new Provider(locator, schema)
|
|
20
|
-
const configuration = new Configuration(provider)
|
|
21
|
-
|
|
22
|
-
return new Aspect(configuration)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
provider (component) {
|
|
26
|
-
const locator = component.locator
|
|
27
|
-
const declaration = component.extensions?.[ID]
|
|
28
|
-
|
|
29
|
-
if (declaration === undefined) throw new Error(`Configuration extension not found in '${locator.id}'`)
|
|
30
|
-
|
|
31
|
-
const schema = new Schema(declaration)
|
|
32
|
-
|
|
33
|
-
return new Provider(locator, schema)
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const ID = require('../package.json').name
|
|
38
|
-
|
|
39
|
-
exports.Factory = Factory
|
package/source/factory.test.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { Factory } = require('../')
|
|
4
|
-
|
|
5
|
-
it('should export', () => {
|
|
6
|
-
expect(Factory).toBeInstanceOf(Function)
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
/** @type {toa.extensions.configuration.Factory} */
|
|
10
|
-
let factory
|
|
11
|
-
|
|
12
|
-
beforeAll(async () => {
|
|
13
|
-
factory = new Factory()
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it('should expose context', () => {
|
|
17
|
-
expect(factory.aspect).toBeInstanceOf(Function)
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it('should expose provider', () => {
|
|
21
|
-
expect(factory.provider).toBeInstanceOf(Function)
|
|
22
|
-
})
|
package/source/index.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { manifest } = require('./manifest')
|
|
4
|
-
const { annotation } = require('./annotation')
|
|
5
|
-
const { deployment } = require('./deployment')
|
|
6
|
-
|
|
7
|
-
const { Factory } = require('./factory')
|
|
8
|
-
|
|
9
|
-
exports.manifest = manifest
|
|
10
|
-
exports.annotation = annotation
|
|
11
|
-
exports.deployment = deployment
|
|
12
|
-
|
|
13
|
-
exports.Factory = Factory
|
package/source/manifest.js
DELETED