@toa.io/norm 1.0.0-alpha.32 → 1.0.0-alpha.320
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 +298 -0
- package/package.json +9 -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 +7 -9
- package/src/.component/.expand/index.js +7 -19
- package/src/.component/.expand/operations.js +2 -9
- package/src/.component/.expand/receivers.js +4 -7
- package/src/.component/.expand/version.js +69 -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 +13 -6
- package/src/.component/.normalize/receivers.js +4 -5
- package/src/.component/collapse.js +60 -9
- package/src/.component/defaults.js +5 -11
- package/src/.component/dependencies.js +14 -10
- package/src/.component/dereference.js +5 -49
- package/src/.component/expand.js +3 -9
- package/src/.component/extensions.js +9 -10
- package/src/.component/index.js +10 -21
- package/src/.component/merge.js +25 -15
- package/src/.component/migrations.js +57 -0
- package/src/.component/normalize.js +10 -6
- package/src/.component/schema.yaml +162 -73
- package/src/.component/validate.js +63 -17
- package/src/.context/.dependencies/connectors.js +5 -9
- package/src/.context/.dependencies/describe.js +4 -5
- package/src/.context/.dependencies/extensions.js +93 -20
- package/src/.context/.dependencies/index.js +3 -9
- package/src/.context/.dependencies/resolve.js +44 -7
- package/src/.context/complete.js +1 -5
- package/src/.context/converge.js +31 -0
- package/src/.context/dependencies.js +43 -6
- package/src/.context/dereference.js +11 -6
- package/src/.context/evict.js +38 -0
- package/src/.context/expand.js +11 -6
- package/src/.context/index.js +8 -15
- package/src/.context/normalize.js +9 -7
- package/src/.context/schema.yaml +183 -11
- package/src/.context/validate.js +11 -14
- package/src/component.js +33 -14
- package/src/context.js +44 -15
- package/src/definition.js +63 -0
- package/src/entity.js +15 -0
- package/src/index.js +7 -9
- package/src/manifest.js +154 -0
- package/src/map.js +24 -0
- package/src/shortcuts.js +11 -15
- 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 +10 -98
- package/test/component/dereference.test.js +10 -14
- 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 +17 -13
- package/test/component/migrations.test.js +62 -0
- package/test/component/normalize.fixtures.js +3 -7
- package/test/component/normalize.test.js +94 -28
- package/test/component/validate.fixtures.js +17 -15
- package/test/component/validate.test.js +271 -109
- package/test/context/complete.fixtures.js +2 -8
- package/test/context/complete.test.js +14 -8
- package/test/context/converge.test.js +57 -0
- package/test/context/dereference.fixtures.js +3 -9
- package/test/context/dereference.test.js +18 -7
- package/test/context/evict.fixtures.js +39 -0
- package/test/context/evict.test.js +73 -0
- 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 +173 -35
- 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/manifest.test.js +126 -0
- package/test/shortcuts.fixtures.js +4 -9
- package/test/shortcuts.test.js +17 -15
- package/test/system.test.js +31 -0
- package/types/component.d.ts +29 -4
- package/types/context/declaration.d.ts +34 -3
- package/types/context.d.ts +27 -13
- package/types/entity.d.ts +7 -0
- package/types/index.d.ts +18 -3
- package/src/.component/.expand/properties.js +0 -14
- package/src/.context/.dependencies/load.js +0 -36
- package/test/context/dependencies.load.test.js +0 -24
package/src/map.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { contract } from '@toa.io/core'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Every component a Context has, with the version it runs and the contract of that version: its
|
|
5
|
+
* own, the ones its extensions bring, and the ones it evicts. A map is not rendered into a
|
|
6
|
+
* workload the way variables are, and an evicted component is called like any other, so it is
|
|
7
|
+
* described like any other.
|
|
8
|
+
*
|
|
9
|
+
* @param {toa.norm.Context} context
|
|
10
|
+
* @returns {Record<string, import('@toa.io/core').Contract>}
|
|
11
|
+
*/
|
|
12
|
+
export const map = (context) => {
|
|
13
|
+
const components = new Map()
|
|
14
|
+
|
|
15
|
+
for (const component of context.components ?? [])
|
|
16
|
+
components.set(component.locator.id, contract.component(component))
|
|
17
|
+
|
|
18
|
+
// what an extension brings reaches a context as an instance of what it depends on
|
|
19
|
+
for (const instances of Object.values(context.dependencies ?? {}))
|
|
20
|
+
for (const { component } of instances)
|
|
21
|
+
components.set(component.locator.id, contract.component(component))
|
|
22
|
+
|
|
23
|
+
return Object.fromEntries([...components].sort(([one], [other]) => one.localeCompare(other)))
|
|
24
|
+
}
|
package/src/shortcuts.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const { empty, merge } = require('@toa.io/generic')
|
|
1
|
+
import { empty, merge } from '@toa.io/generic'
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
4
|
* Resolves shortcuts
|
|
@@ -8,7 +6,7 @@ const { empty, merge } = require('@toa.io/generic')
|
|
|
8
6
|
* @param {string} token
|
|
9
7
|
* @returns {string}
|
|
10
8
|
*/
|
|
11
|
-
const resolve = (token) => {
|
|
9
|
+
export const resolve = (token) => {
|
|
12
10
|
if (token in SHORTCUTS) return SHORTCUTS[token]
|
|
13
11
|
else return token
|
|
14
12
|
}
|
|
@@ -20,7 +18,7 @@ const resolve = (token) => {
|
|
|
20
18
|
* @param {Object} object
|
|
21
19
|
* @param {string} [group]
|
|
22
20
|
*/
|
|
23
|
-
const recognize = (shortcuts, object, group) => {
|
|
21
|
+
export const recognize = (shortcuts, object, group) => {
|
|
24
22
|
if (object === undefined) return
|
|
25
23
|
|
|
26
24
|
const target = group === undefined ? object : {}
|
|
@@ -38,21 +36,19 @@ const recognize = (shortcuts, object, group) => {
|
|
|
38
36
|
if (group !== undefined && !empty(target)) object[group] = merge(object[group], target)
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
const SHORTCUTS = {
|
|
39
|
+
export const SHORTCUTS = {
|
|
42
40
|
amqp: '@toa.io/bindings.amqp',
|
|
41
|
+
http: '@toa.io/bindings.http',
|
|
43
42
|
node: '@toa.io/bridges.node',
|
|
44
43
|
bash: '@toa.io/bridges.bash',
|
|
45
44
|
mongodb: '@toa.io/storages.mongodb',
|
|
46
|
-
sql: '@toa.io/storages.sql',
|
|
47
|
-
queues: '@toa.io/storages.queues',
|
|
48
45
|
exposition: '@toa.io/extensions.exposition',
|
|
49
|
-
realtime: '@toa.io/extensions.realtime',
|
|
46
|
+
realtime: '@toa.io/extensions.exposition#realtime',
|
|
50
47
|
configuration: '@toa.io/extensions.configuration',
|
|
51
|
-
origins: '@toa.io/extensions.origins',
|
|
52
48
|
stash: '@toa.io/extensions.stash',
|
|
53
|
-
storages: '@toa.io/extensions.storages'
|
|
49
|
+
storages: '@toa.io/extensions.storages',
|
|
50
|
+
telemetry: '@toa.io/extensions.telemetry',
|
|
51
|
+
cadence: '@toa.io/extensions.cadence',
|
|
52
|
+
convergence: '@toa.io/extensions.convergence',
|
|
53
|
+
introspection: '@toa.io/extensions.introspection'
|
|
54
54
|
}
|
|
55
|
-
|
|
56
|
-
exports.recognize = recognize
|
|
57
|
-
exports.resolve = resolve
|
|
58
|
-
exports.SHORTCUTS = SHORTCUTS
|
|
@@ -1,55 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const { generate } = require('randomstring')
|
|
1
|
+
import { generate } from 'randomstring'
|
|
4
2
|
|
|
5
3
|
const entity = {
|
|
6
4
|
manifest: {
|
|
7
5
|
entity: {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
type: 'string'
|
|
12
|
-
},
|
|
13
|
-
bar: {
|
|
14
|
-
type: 'integer'
|
|
15
|
-
}
|
|
6
|
+
properties: {
|
|
7
|
+
foo: {
|
|
8
|
+
type: 'string'
|
|
16
9
|
},
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
bar: {
|
|
11
|
+
type: 'integer'
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
required: ['foo']
|
|
19
15
|
}
|
|
20
16
|
},
|
|
21
17
|
prototype: {
|
|
22
18
|
entity: {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
default: 'ok'
|
|
27
|
-
},
|
|
28
|
-
baz: {
|
|
29
|
-
type: 'boolean'
|
|
30
|
-
}
|
|
19
|
+
properties: {
|
|
20
|
+
foo: {
|
|
21
|
+
minLength: 1
|
|
31
22
|
},
|
|
32
|
-
|
|
33
|
-
|
|
23
|
+
baz: {
|
|
24
|
+
type: 'boolean'
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
required: ['baz']
|
|
34
28
|
}
|
|
35
29
|
},
|
|
36
30
|
result: {
|
|
37
31
|
entity: {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
default: 'ok'
|
|
43
|
-
},
|
|
44
|
-
bar: {
|
|
45
|
-
type: 'integer'
|
|
46
|
-
},
|
|
47
|
-
baz: {
|
|
48
|
-
type: 'boolean'
|
|
49
|
-
}
|
|
32
|
+
properties: {
|
|
33
|
+
foo: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
minLength: 1
|
|
50
36
|
},
|
|
51
|
-
|
|
52
|
-
|
|
37
|
+
bar: {
|
|
38
|
+
type: 'integer'
|
|
39
|
+
},
|
|
40
|
+
baz: {
|
|
41
|
+
type: 'boolean'
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
required: ['foo', 'baz']
|
|
53
45
|
}
|
|
54
46
|
}
|
|
55
47
|
}
|
|
@@ -88,7 +80,6 @@ const operations = {
|
|
|
88
80
|
result: {
|
|
89
81
|
prototype: {
|
|
90
82
|
prototype: null,
|
|
91
|
-
path: expect.any(String),
|
|
92
83
|
operations: {
|
|
93
84
|
add: {
|
|
94
85
|
bridge: 'a'
|
|
@@ -131,4 +122,4 @@ const remotes = {
|
|
|
131
122
|
}
|
|
132
123
|
}
|
|
133
124
|
|
|
134
|
-
|
|
125
|
+
export const samples = { entity, operations, remotes }
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { describe, it, 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 * as fixtures from './collapse.fixtures.js'
|
|
7
|
+
import { collapse } from '../../src/.component/index.js'
|
|
7
8
|
|
|
8
9
|
let samples
|
|
9
10
|
|
|
@@ -18,7 +19,7 @@ it('should ignore locator', () => {
|
|
|
18
19
|
|
|
19
20
|
collapse(manifest, prototype)
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
assert.deepStrictEqual(manifest, source)
|
|
22
23
|
})
|
|
23
24
|
|
|
24
25
|
it('should remove prototype property', () => {
|
|
@@ -26,7 +27,7 @@ it('should remove prototype property', () => {
|
|
|
26
27
|
|
|
27
28
|
collapse(manifest, {})
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
assert.deepStrictEqual(manifest, {})
|
|
30
31
|
})
|
|
31
32
|
|
|
32
33
|
describe('entity', () => {
|
|
@@ -34,7 +35,80 @@ describe('entity', () => {
|
|
|
34
35
|
const manifest = clone(samples.entity.manifest)
|
|
35
36
|
|
|
36
37
|
collapse(manifest, samples.entity.prototype)
|
|
37
|
-
|
|
38
|
+
assert.deepStrictEqual(manifest, samples.entity.result)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('should let a component state its own id', () => {
|
|
42
|
+
const prototype = { entity: { properties: { id: { type: 'string' }, VERSION: {} } } }
|
|
43
|
+
const manifest = { name: 'pot', entity: { properties: { id: { type: 'number' } } } }
|
|
44
|
+
|
|
45
|
+
collapse(manifest, prototype)
|
|
46
|
+
|
|
47
|
+
assert.strictEqual(manifest.entity.custom, true)
|
|
48
|
+
assert.deepStrictEqual(manifest.entity.properties.id, { type: 'number' })
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('should refuse a component that states a property the runtime writes', () => {
|
|
52
|
+
const prototype = { entity: { properties: { DELETED: { type: 'integer' } } } }
|
|
53
|
+
const manifest = {
|
|
54
|
+
name: 'pot',
|
|
55
|
+
entity: { properties: { DELETED: { type: 'integer' } } }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
assert.throws(
|
|
59
|
+
() => collapse(manifest, prototype),
|
|
60
|
+
/System property 'DELETED' cannot be overridden/
|
|
61
|
+
)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('should inherit migrations ahead of its own, under the prototype name', () => {
|
|
65
|
+
const manifest = { entity: { migrations: [{ id: '0002', steps: [] }] } }
|
|
66
|
+
const prototype = {
|
|
67
|
+
name: 'base',
|
|
68
|
+
entity: { migrations: [{ id: '0001', steps: [] }] }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
collapse(manifest, prototype)
|
|
72
|
+
|
|
73
|
+
assert.deepStrictEqual(manifest.entity.migrations, [
|
|
74
|
+
{ id: 'base:0001', steps: [], prototype: 'base' },
|
|
75
|
+
{ id: '0002', steps: [] }
|
|
76
|
+
])
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('should pass on what the prototype inherited as it is', () => {
|
|
80
|
+
const manifest = { entity: { migrations: [{ id: '0002', steps: [] }] } }
|
|
81
|
+
const prototype = {
|
|
82
|
+
name: 'base',
|
|
83
|
+
entity: {
|
|
84
|
+
migrations: [
|
|
85
|
+
{ id: 'system:0001', steps: [], prototype: 'system' },
|
|
86
|
+
{ id: '0001', steps: [] }
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
collapse(manifest, prototype)
|
|
92
|
+
|
|
93
|
+
assert.deepStrictEqual(
|
|
94
|
+
manifest.entity.migrations.map(({ id }) => id),
|
|
95
|
+
['system:0001', 'base:0001', '0002']
|
|
96
|
+
)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('should inherit migrations into a component that declares none', () => {
|
|
100
|
+
const manifest = {}
|
|
101
|
+
const prototype = {
|
|
102
|
+
name: 'base',
|
|
103
|
+
entity: { migrations: [{ id: '0001', steps: [] }] }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
collapse(manifest, prototype)
|
|
107
|
+
|
|
108
|
+
assert.deepStrictEqual(
|
|
109
|
+
manifest.entity.migrations.map(({ id }) => id),
|
|
110
|
+
['base:0001']
|
|
111
|
+
)
|
|
38
112
|
})
|
|
39
113
|
})
|
|
40
114
|
|
|
@@ -44,12 +118,12 @@ it('should ignore bindings', () => {
|
|
|
44
118
|
const manifest = clone(source)
|
|
45
119
|
|
|
46
120
|
collapse(manifest, prototype)
|
|
47
|
-
|
|
121
|
+
assert.deepStrictEqual(manifest, source)
|
|
48
122
|
|
|
49
123
|
delete manifest.bindings
|
|
50
124
|
|
|
51
125
|
collapse(manifest, prototype)
|
|
52
|
-
|
|
126
|
+
assert.deepStrictEqual(manifest, {})
|
|
53
127
|
})
|
|
54
128
|
|
|
55
129
|
it('should merge operations', () => {
|
|
@@ -57,5 +131,11 @@ it('should merge operations', () => {
|
|
|
57
131
|
const prototype = clone(samples.operations.prototype)
|
|
58
132
|
|
|
59
133
|
collapse(manifest, prototype, '/somewhere')
|
|
60
|
-
|
|
134
|
+
|
|
135
|
+
// the prototype's path is generated, so it is checked apart from the shape
|
|
136
|
+
assert.strictEqual(typeof manifest.prototype.path, 'string')
|
|
137
|
+
|
|
138
|
+
const { path, ...rest } = manifest.prototype
|
|
139
|
+
|
|
140
|
+
assert.deepStrictEqual({ ...manifest, prototype: rest }, samples.operations.result)
|
|
61
141
|
})
|
|
@@ -1,38 +1,40 @@
|
|
|
1
|
-
|
|
1
|
+
import { describe, it, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
import { resolve } from 'node:path'
|
|
5
|
+
import { dependencies } from '../../src/.component/index.js'
|
|
5
6
|
|
|
6
|
-
const NORM = resolve(
|
|
7
|
+
const NORM = resolve(import.meta.dirname, '../../')
|
|
7
8
|
|
|
8
9
|
it('should be', async () => {
|
|
9
|
-
|
|
10
|
+
assert.ok(dependencies instanceof Function)
|
|
10
11
|
})
|
|
11
12
|
|
|
12
13
|
/** @type {toa.norm.Component} */
|
|
13
14
|
let component
|
|
14
15
|
|
|
15
16
|
beforeEach(() => {
|
|
16
|
-
component = /** @type {toa.norm.Component} */ { path:
|
|
17
|
+
component = /** @type {toa.norm.Component} */ { path: import.meta.dirname }
|
|
17
18
|
})
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
for (const [_, reference] of [
|
|
20
21
|
['package id', '@toa.io/norm'],
|
|
21
22
|
['relative path', '../../']
|
|
22
|
-
])
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
])
|
|
24
|
+
describe(`${_}`, () => {
|
|
25
|
+
it('should resolve storage', async () => {
|
|
26
|
+
component.entity = { storage: reference, schema: {} }
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
dependencies(component)
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
assert.deepStrictEqual(component.entity.storage, NORM)
|
|
31
|
+
})
|
|
29
32
|
})
|
|
30
|
-
})
|
|
31
33
|
|
|
32
34
|
it('should resolve toa packages', async () => {
|
|
33
35
|
component.entity = { storage: '@toa.io/core', schema: {} }
|
|
34
36
|
|
|
35
37
|
dependencies(component)
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
assert.notStrictEqual(component.entity.storage, undefined)
|
|
38
40
|
})
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const source = {
|
|
1
|
+
export const source = {
|
|
4
2
|
entity: {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
type: 'string'
|
|
9
|
-
},
|
|
10
|
-
bar: {
|
|
11
|
-
type: 'string',
|
|
12
|
-
default: '.foo'
|
|
13
|
-
}
|
|
3
|
+
properties: {
|
|
4
|
+
foo: {
|
|
5
|
+
type: 'string'
|
|
14
6
|
}
|
|
15
7
|
}
|
|
16
8
|
},
|
|
@@ -19,42 +11,14 @@ const source = {
|
|
|
19
11
|
input: {
|
|
20
12
|
properties: {
|
|
21
13
|
foo: {
|
|
22
|
-
type: 'string'
|
|
23
|
-
default: '.'
|
|
24
|
-
},
|
|
25
|
-
bar: {
|
|
26
|
-
type: 'string',
|
|
27
|
-
default: '.foo'
|
|
28
|
-
},
|
|
29
|
-
baz1: {
|
|
30
|
-
type: 'array',
|
|
31
|
-
items: {
|
|
32
|
-
type: 'string',
|
|
33
|
-
default: '.foo'
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
baz2: {
|
|
37
|
-
type: 'array',
|
|
38
|
-
items: {
|
|
39
|
-
properties: {
|
|
40
|
-
foo: {
|
|
41
|
-
type: 'string',
|
|
42
|
-
default: '.'
|
|
43
|
-
},
|
|
44
|
-
bar: {
|
|
45
|
-
type: 'string',
|
|
46
|
-
default: '.foo'
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
14
|
+
type: 'string'
|
|
50
15
|
}
|
|
51
16
|
}
|
|
52
17
|
},
|
|
53
18
|
output: {
|
|
54
19
|
properties: {
|
|
55
20
|
bar: {
|
|
56
|
-
type: 'string'
|
|
57
|
-
default: '.foo'
|
|
21
|
+
type: 'string'
|
|
58
22
|
}
|
|
59
23
|
}
|
|
60
24
|
}
|
|
@@ -66,16 +30,11 @@ const source = {
|
|
|
66
30
|
}
|
|
67
31
|
}
|
|
68
32
|
|
|
69
|
-
const target = {
|
|
33
|
+
export const target = {
|
|
70
34
|
entity: {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
type: 'string'
|
|
75
|
-
},
|
|
76
|
-
bar: {
|
|
77
|
-
type: 'string'
|
|
78
|
-
}
|
|
35
|
+
properties: {
|
|
36
|
+
foo: {
|
|
37
|
+
type: 'string'
|
|
79
38
|
}
|
|
80
39
|
}
|
|
81
40
|
},
|
|
@@ -85,28 +44,6 @@ const target = {
|
|
|
85
44
|
properties: {
|
|
86
45
|
foo: {
|
|
87
46
|
type: 'string'
|
|
88
|
-
},
|
|
89
|
-
bar: {
|
|
90
|
-
type: 'string'
|
|
91
|
-
},
|
|
92
|
-
baz1: {
|
|
93
|
-
type: 'array',
|
|
94
|
-
items: {
|
|
95
|
-
type: 'string'
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
baz2: {
|
|
99
|
-
type: 'array',
|
|
100
|
-
items: {
|
|
101
|
-
properties: {
|
|
102
|
-
foo: {
|
|
103
|
-
type: 'string'
|
|
104
|
-
},
|
|
105
|
-
bar: {
|
|
106
|
-
type: 'string'
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
47
|
}
|
|
111
48
|
}
|
|
112
49
|
},
|
|
@@ -125,28 +62,6 @@ const target = {
|
|
|
125
62
|
properties: {
|
|
126
63
|
foo: {
|
|
127
64
|
type: 'string'
|
|
128
|
-
},
|
|
129
|
-
bar: {
|
|
130
|
-
type: 'string'
|
|
131
|
-
},
|
|
132
|
-
baz1: {
|
|
133
|
-
type: 'array',
|
|
134
|
-
items: {
|
|
135
|
-
type: 'string'
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
baz2: {
|
|
139
|
-
type: 'array',
|
|
140
|
-
items: {
|
|
141
|
-
properties: {
|
|
142
|
-
foo: {
|
|
143
|
-
type: 'string'
|
|
144
|
-
},
|
|
145
|
-
bar: {
|
|
146
|
-
type: 'string'
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
65
|
}
|
|
151
66
|
}
|
|
152
67
|
},
|
|
@@ -160,6 +75,3 @@ const target = {
|
|
|
160
75
|
}
|
|
161
76
|
}
|
|
162
77
|
}
|
|
163
|
-
|
|
164
|
-
exports.source = source
|
|
165
|
-
exports.target = target
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { it, 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 { dereference } from '../../src/.component/index.js'
|
|
7
|
+
import * as fixtures from './dereference.fixtures.js'
|
|
7
8
|
|
|
8
9
|
let source
|
|
9
10
|
|
|
@@ -14,18 +15,13 @@ beforeEach(() => {
|
|
|
14
15
|
it('should dereference', () => {
|
|
15
16
|
dereference(source)
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it('should throw on invalid schema reference', () => {
|
|
21
|
-
source.operations.transit.output.properties.baz = { type: 'string', default: '.' }
|
|
22
|
-
expect(() => dereference(source)).toThrow(/is not defined/)
|
|
23
|
-
|
|
24
|
-
source.operations.transit.output.properties.baz = { type: 'string', default: '.baz' }
|
|
25
|
-
expect(() => dereference(source)).toThrow(/is not defined/)
|
|
18
|
+
assert.deepStrictEqual(source, fixtures.target)
|
|
26
19
|
})
|
|
27
20
|
|
|
28
21
|
it('should throw on invalid forwarding', () => {
|
|
29
22
|
source.operations.create.forward = 'foo'
|
|
30
|
-
|
|
23
|
+
assert.throws(
|
|
24
|
+
() => dereference(source),
|
|
25
|
+
(error) => /is not defined/.test(error.message)
|
|
26
|
+
)
|
|
31
27
|
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
index: not a list
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[{ "delete": { "filter": {} } }]
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const source = {
|
|
4
|
-
path: '',
|
|
1
|
+
export const source = {
|
|
2
|
+
path: import.meta.dirname, // `version` hashes the component directory
|
|
5
3
|
entity: {
|
|
6
4
|
schema: {
|
|
5
|
+
type: 'object',
|
|
7
6
|
properties: {
|
|
8
|
-
foo: 'string'
|
|
7
|
+
foo: { type: 'string' }
|
|
9
8
|
}
|
|
10
9
|
},
|
|
11
10
|
storage: 'mongodb'
|
|
@@ -16,26 +15,30 @@ const source = {
|
|
|
16
15
|
bridge: 'node',
|
|
17
16
|
bindings: ['amqp'],
|
|
18
17
|
input: {
|
|
18
|
+
type: 'object',
|
|
19
19
|
properties: {
|
|
20
|
-
foo: 'integer',
|
|
20
|
+
foo: { type: 'integer' },
|
|
21
21
|
bar: {
|
|
22
22
|
type: 'array',
|
|
23
23
|
items: {
|
|
24
|
+
type: 'object',
|
|
24
25
|
properties: {
|
|
25
|
-
baz: 'string'
|
|
26
|
+
baz: { type: 'string' }
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
},
|
|
31
32
|
output: {
|
|
33
|
+
type: 'object',
|
|
32
34
|
properties: {
|
|
33
|
-
foo: 'integer',
|
|
35
|
+
foo: { type: 'integer' },
|
|
34
36
|
bar: {
|
|
35
37
|
type: 'array',
|
|
36
38
|
items: {
|
|
39
|
+
type: 'object',
|
|
37
40
|
properties: {
|
|
38
|
-
baz: 'string'
|
|
41
|
+
baz: { type: 'string' }
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
44
|
}
|
|
@@ -59,7 +62,7 @@ const source = {
|
|
|
59
62
|
}
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
const target = {
|
|
65
|
+
export const target = {
|
|
63
66
|
entity: {
|
|
64
67
|
schema: {
|
|
65
68
|
type: 'object',
|
|
@@ -133,6 +136,3 @@ const target = {
|
|
|
133
136
|
}
|
|
134
137
|
}
|
|
135
138
|
}
|
|
136
|
-
|
|
137
|
-
exports.source = source
|
|
138
|
-
exports.target = target
|