@toa.io/norm 1.0.0-alpha.28 → 1.0.0-alpha.283

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.
Files changed (72) hide show
  1. package/CHANGELOG.md +195 -0
  2. package/package.json +8 -7
  3. package/src/.component/.expand/bridge.js +2 -6
  4. package/src/.component/.expand/entity.js +2 -9
  5. package/src/.component/.expand/events.js +2 -6
  6. package/src/.component/.expand/extensions.js +4 -8
  7. package/src/.component/.expand/index.js +8 -19
  8. package/src/.component/.expand/operations.js +2 -9
  9. package/src/.component/.expand/properties.js +2 -6
  10. package/src/.component/.expand/receivers.js +2 -6
  11. package/src/.component/.expand/version.js +39 -27
  12. package/src/.component/.normalize/events.js +12 -5
  13. package/src/.component/.normalize/index.js +3 -9
  14. package/src/.component/.normalize/operations.js +2 -6
  15. package/src/.component/.normalize/receivers.js +1 -5
  16. package/src/.component/collapse.js +7 -6
  17. package/src/.component/defaults.js +14 -7
  18. package/src/.component/dependencies.js +7 -6
  19. package/src/.component/dereference.js +8 -7
  20. package/src/.component/expand.js +2 -15
  21. package/src/.component/extensions.js +13 -7
  22. package/src/.component/index.js +9 -21
  23. package/src/.component/merge.js +22 -9
  24. package/src/.component/normalize.js +3 -7
  25. package/src/.component/schema.yaml +82 -41
  26. package/src/.component/validate.js +15 -16
  27. package/src/.context/.dependencies/connectors.js +2 -6
  28. package/src/.context/.dependencies/describe.js +1 -5
  29. package/src/.context/.dependencies/extensions.js +55 -18
  30. package/src/.context/.dependencies/index.js +3 -9
  31. package/src/.context/.dependencies/load.js +14 -13
  32. package/src/.context/.dependencies/resolve.js +23 -6
  33. package/src/.context/complete.js +1 -5
  34. package/src/.context/dependencies.js +2 -6
  35. package/src/.context/dereference.js +9 -6
  36. package/src/.context/expand.js +8 -6
  37. package/src/.context/index.js +6 -15
  38. package/src/.context/normalize.js +2 -6
  39. package/src/.context/schema.yaml +126 -7
  40. package/src/.context/validate.js +8 -14
  41. package/src/component.js +31 -28
  42. package/src/context.js +28 -20
  43. package/src/index.js +3 -9
  44. package/src/shortcuts.js +7 -12
  45. package/test/component/collapse.fixtures.js +2 -5
  46. package/test/component/collapse.test.js +17 -10
  47. package/test/component/dependencies.test.js +12 -10
  48. package/test/component/dereference.fixtures.js +2 -7
  49. package/test/component/dereference.test.js +9 -8
  50. package/test/component/dummies/extension/index.js +1 -5
  51. package/test/component/expand.fixtures.js +13 -13
  52. package/test/component/expand.test.js +25 -10
  53. package/test/component/normalize.fixtures.js +3 -7
  54. package/test/component/normalize.test.js +27 -17
  55. package/test/component/validate.fixtures.js +1 -5
  56. package/test/component/validate.test.js +89 -90
  57. package/test/context/complete.fixtures.js +2 -8
  58. package/test/context/complete.test.js +10 -8
  59. package/test/context/dependencies.load.test.js +13 -12
  60. package/test/context/dereference.fixtures.js +3 -9
  61. package/test/context/dereference.test.js +17 -7
  62. package/test/context/expand.fixtures.js +1 -5
  63. package/test/context/expand.test.js +34 -8
  64. package/test/context/normalize.fixtures.js +2 -7
  65. package/test/context/normalize.test.js +10 -8
  66. package/test/context/validate.fixtures.js +1 -6
  67. package/test/context/validate.test.js +54 -30
  68. package/test/shortcuts.fixtures.js +4 -9
  69. package/test/shortcuts.test.js +16 -15
  70. package/types/context/declaration.d.ts +25 -2
  71. package/types/context.d.ts +5 -4
  72. package/types/index.d.ts +3 -3
@@ -1,23 +1,26 @@
1
- 'use strict'
1
+ import { createRequire } from 'node:module'
2
+ import { readFileSync } from 'node:fs'
3
+ import { join } from 'node:path'
4
+ import { pathToFileURL } from 'node:url'
2
5
 
3
- const { join } = require('node:path')
6
+ // import.meta.resolve takes no paths, and a dependency is named rather than
7
+ // written as a path
8
+ const require = createRequire(import.meta.url)
4
9
 
5
10
  /**
6
11
  * @param {string} path
7
- * @returns {{ metadata: object, module: object }}
12
+ * @returns {Promise<{ metadata: object, module: object }>}
8
13
  */
9
- function load (path) {
14
+ export async function load (path) {
10
15
  const metadata = loadMetadata(path)
11
- const module = loadModule(path)
16
+ const module = await loadModule(path)
12
17
 
13
18
  return { metadata, module }
14
19
  }
15
20
 
16
21
  function loadMetadata (reference) {
17
- reference = join(reference, 'package.json')
18
-
19
22
  try {
20
- return require(reference)
23
+ return JSON.parse(readFileSync(require.resolve(join(reference, 'package.json')), 'utf8'))
21
24
  } catch {
22
25
  return null
23
26
  }
@@ -25,12 +28,10 @@ function loadMetadata (reference) {
25
28
 
26
29
  /**
27
30
  * @param {string} reference
28
- * @returns {object}
31
+ * @returns {Promise<object>}
29
32
  */
30
- function loadModule (reference) {
33
+ async function loadModule (reference) {
31
34
  const path = require.resolve(reference)
32
35
 
33
- return require(path)
36
+ return await import(pathToFileURL(path).href)
34
37
  }
35
-
36
- exports.load = load
@@ -1,12 +1,10 @@
1
- 'use strict'
1
+ import { load } from './load.js'
2
2
 
3
- const { load } = require('./load')
4
-
5
- const resolve = (references, annotations) => {
3
+ export const resolve = async (references, annotations = {}) => {
6
4
  const dependencies = {}
7
5
 
8
6
  for (const [dependency, components] of Object.entries(references)) {
9
- const { metadata, module } = load(dependency)
7
+ const { metadata, module } = await load(dependency)
10
8
  const id = metadata.name
11
9
 
12
10
  const instances = components.map((component) => ({
@@ -24,7 +22,26 @@ const resolve = (references, annotations) => {
24
22
  }
25
23
  }
26
24
 
25
+ for (const dependency of Object.keys(annotations)) {
26
+ if (dependency in dependencies) continue
27
+
28
+ // an annotation may be keyed by a dependency id rather than by a module reference
29
+ const module = await optional(dependency)
30
+
31
+ if (module?.standalone === true) dependencies[dependency] = []
32
+ }
33
+
27
34
  return dependencies
28
35
  }
29
36
 
30
- exports.resolve = resolve
37
+ /**
38
+ * @param {string} reference
39
+ * @returns {object | null}
40
+ */
41
+ async function optional (reference) {
42
+ try {
43
+ return (await load(reference)).module
44
+ } catch {
45
+ return null
46
+ }
47
+ }
@@ -1,11 +1,9 @@
1
- 'use strict'
2
-
3
1
  /**
4
2
  * Completes missing compositions with unused components
5
3
  * @param {toa.norm.Context} context
6
4
  * @returns {void}
7
5
  */
8
- const complete = (context) => {
6
+ export const complete = (context) => {
9
7
  /** @type {Set<string>} */
10
8
  const composed = new Set()
11
9
 
@@ -29,5 +27,3 @@ const complete = (context) => {
29
27
  context.compositions.push({ name, components: [component] })
30
28
  }
31
29
  }
32
-
33
- exports.complete = complete
@@ -1,13 +1,9 @@
1
- 'use strict'
1
+ import { connectors, extensions, resolve } from './.dependencies/index.js'
2
2
 
3
- const { connectors, extensions, resolve } = require('./.dependencies')
4
-
5
- const dependencies = async (context) => {
3
+ export const dependencies = async (context) => {
6
4
  const { extensions: e, components } = await extensions(context)
7
5
  const c = connectors(context, components)
8
6
  const references = { ...c, ...e }
9
7
 
10
8
  return resolve(references, context.annotations)
11
9
  }
12
-
13
- exports.dependencies = dependencies
@@ -1,16 +1,21 @@
1
- 'use strict'
2
-
3
1
  /**
4
2
  * Resolves component IDs within compositions with Component objects
5
3
  * @param {toa.norm.Context} context
6
4
  * @returns {void}
7
5
  */
8
- const dereference = (context) => {
6
+ export const dereference = (context) => {
9
7
  const components = map(context.components)
10
8
 
11
9
  if (context.compositions !== undefined) {
12
10
  for (const composition of context.compositions) {
13
- composition.components = composition.components.map((id) => components[id])
11
+ composition.components = composition.components.map((id) => {
12
+ const component = components[id]
13
+
14
+ if (component === undefined)
15
+ throw new Error(`Composition '${composition.name}' lists an unknown component '${id}'.`)
16
+
17
+ return component
18
+ })
14
19
  }
15
20
  }
16
21
  }
@@ -27,5 +32,3 @@ const map = (components) => {
27
32
 
28
33
  return map
29
34
  }
30
-
31
- exports.dereference = dereference
@@ -1,13 +1,15 @@
1
- 'use strict'
2
-
3
- const shortcuts = require('../shortcuts')
1
+ import * as shortcuts from '../shortcuts.js'
4
2
 
5
3
  /**
6
4
  * @param {toa.norm.context.Declaration | object} context
7
5
  */
8
- const expand = (context) => {
6
+ export const expand = (context) => {
9
7
  shortcuts.recognize(shortcuts.SHORTCUTS, context, 'annotations')
10
8
  shortcuts.recognize(shortcuts.SHORTCUTS, context.annotations)
11
- }
12
9
 
13
- exports.expand = expand
10
+ // a composition names a service the way a manifest names an extension, and everything
11
+ // downstream matches it against a dependency, which is keyed by package reference
12
+ for (const composition of context.compositions ?? [])
13
+ if (composition.services !== undefined)
14
+ composition.services = composition.services.map(shortcuts.resolve)
15
+ }
@@ -1,15 +1,6 @@
1
- 'use strict'
2
-
3
- const { complete } = require('./complete')
4
- const { dependencies } = require('./dependencies')
5
- const { dereference } = require('./dereference')
6
- const { expand } = require('./expand')
7
- const { normalize } = require('./normalize')
8
- const { validate } = require('./validate')
9
-
10
- exports.complete = complete
11
- exports.dependencies = dependencies
12
- exports.dereference = dereference
13
- exports.expand = expand
14
- exports.normalize = normalize
15
- exports.validate = validate
1
+ export { complete } from './complete.js'
2
+ export { dependencies } from './dependencies.js'
3
+ export { dereference } from './dereference.js'
4
+ export { expand } from './expand.js'
5
+ export { normalize } from './normalize.js'
6
+ export { validate } from './validate.js'
@@ -1,11 +1,9 @@
1
- 'use strict'
1
+ import * as runtime from '@toa.io/runtime'
2
2
 
3
3
  /**
4
4
  * @param {toa.norm.context.Declaration | Object} context
5
5
  */
6
- const normalize = (context) => {
7
- const runtime = require('@toa.io/runtime')
8
-
6
+ export const normalize = (context) => {
9
7
  if (context.runtime === undefined) context.runtime = { version: runtime.version }
10
8
  if (typeof context.runtime === 'string') context.runtime = { version: context.runtime }
11
9
 
@@ -15,5 +13,3 @@ const normalize = (context) => {
15
13
 
16
14
  if (typeof context.registry === 'string') context.registry = { base: context.registry }
17
15
  }
18
-
19
- exports.normalize = normalize
@@ -6,12 +6,10 @@ properties:
6
6
  version:
7
7
  type: string
8
8
  name:
9
- $ref: 'definitions#/definitions/label'
10
- description:
11
9
  type: string
12
- packages:
10
+ pattern: ^([a-zA-Z]+([_a-zA-Z0-9]*[a-zA-Z0-9]+)?)(-([a-zA-Z]+([_a-zA-Z0-9]*[a-zA-Z0-9]+)?))*$
11
+ description:
13
12
  type: string
14
- default: components/*
15
13
  build:
16
14
  type: object
17
15
  properties:
@@ -46,24 +44,145 @@ properties:
46
44
  - linux/amd64
47
45
  - linux/arm/v7
48
46
  - linux/arm64
49
- required: [base, platforms]
47
+ # required: [base]
50
48
  compositions:
51
49
  type: array
52
50
  minItems: 1
53
51
  items:
54
52
  type: object
53
+ additionalProperties: false
55
54
  properties:
56
55
  name:
57
- $ref: 'definitions#/definitions/token'
56
+ type: string
57
+ pattern: ^[a-zA-Z]([a-zA-Z0-9]{1,31})?$
58
58
  image:
59
59
  type: string
60
60
  components:
61
61
  type: array
62
62
  minItems: 1
63
63
  items:
64
- $ref: 'definitions#/definitions/locator'
64
+ type: string
65
+ pattern: ^([a-zA-Z]+([_a-zA-Z0-9]*[a-zA-Z0-9]+)?)(\.([a-zA-Z]+([_a-zA-Z0-9]*[a-zA-Z0-9]+)?))$
66
+ services:
67
+ description: >
68
+ Extension services this composition runs in its own pod, named by shortcut or
69
+ package reference, rather than each as its own deployment. A service listed here
70
+ keeps its own Service and Ingress; what changes is the pod they select.
71
+ type: array
72
+ minItems: 1
73
+ items:
74
+ type: string
75
+ minLength: 1
76
+ resources:
77
+ $ref: '#/definitions/resources'
65
78
  required: [name, components]
79
+ atomicity:
80
+ description: >
81
+ Where the replicas of a component decide together: who owns what, what they have spent
82
+ between them, and which of them holds a name while it works. Absent or unreachable,
83
+ nothing is owned and whoever asked stands down; metering and locking are refused.
84
+ type: object
85
+ additionalProperties: false
86
+ properties:
87
+ redis:
88
+ description: >
89
+ One address, or an odd number of them — independent servers, not the nodes of a
90
+ cluster. A lock is taken on a quorum of them; the registry and the meter use the
91
+ first, because each of them counts on a single key.
92
+ oneOf:
93
+ - type: string
94
+ - type: array
95
+ minItems: 1
96
+ items:
97
+ type: string
98
+ interval:
99
+ description: >
100
+ How often a replica registers, in milliseconds. It has to comfortably exceed a round
101
+ trip to Redis and the jitter around it, and nothing is owned until two consecutive
102
+ intervals have agreed — so this is also how long a replica owns nothing after it
103
+ joins, restarts or stalls.
104
+ type: integer
105
+ minimum: 100
106
+ required: [redis]
107
+ outbox:
108
+ type: object
109
+ additionalProperties: false
110
+ properties:
111
+ interval:
112
+ description: >
113
+ The pump's cycle, in milliseconds. One cycle reads what is unpublished, publishes it
114
+ and marks it. In steady state it reads nothing, so this is budgeted for how fast a rare
115
+ failure heals rather than for how fast events flow.
116
+ type: integer
117
+ minimum: 100
118
+ batch:
119
+ description: >
120
+ How many rows one read brings back. A page that comes back full is read on from,
121
+ so this bounds a read rather than a cycle.
122
+ type: integer
123
+ minimum: 1
124
+ retention:
125
+ description: >
126
+ Seconds a published row is kept as a change log before it expires. A row that never
127
+ made it out has no expiry and is never reaped.
128
+ type: integer
129
+ minimum: 0
130
+ events:
131
+ description: >
132
+ Events of this context that are consumed outside it. An event is otherwise published only
133
+ where something in the context receives it.
134
+ type: array
135
+ items:
136
+ type: string
137
+ pattern: ^[a-zA-Z][a-zA-Z0-9]*\.[a-zA-Z][a-zA-Z0-9]*\.[a-zA-Z][a-zA-Z0-9]*$
138
+ mono:
139
+ type: object
140
+ additionalProperties: false
141
+ properties:
142
+ replicas:
143
+ type: integer
144
+ minimum: 1
145
+ resources:
146
+ $ref: '#/definitions/resources'
147
+ ingress:
148
+ type: object
149
+ additionalProperties: false
150
+ properties:
151
+ hosts:
152
+ type: array
153
+ minItems: 1
154
+ items:
155
+ type: string
156
+ class:
157
+ type: string
158
+ annotations:
159
+ type: object
160
+ default:
161
+ type: boolean
66
162
  annotations:
67
163
  type: object
164
+ resources:
165
+ $ref: '#/definitions/resources'
68
166
  required: [runtime, name, registry]
69
167
  additionalProperties: false
168
+
169
+ definitions:
170
+ # What a deployment may take. `null` deploys it without any, which is a decision
171
+ # rather than an omission — every deployment has to make one.
172
+ resources:
173
+ type: object
174
+ nullable: true
175
+ additionalProperties: false
176
+ properties:
177
+ cpu:
178
+ type: array
179
+ items:
180
+ type: string
181
+ minItems: 2
182
+ maxItems: 2
183
+ memory:
184
+ type: array
185
+ items:
186
+ type: string
187
+ minItems: 2
188
+ maxItems: 2
@@ -1,19 +1,13 @@
1
- 'use strict'
1
+ import { resolve } from 'node:path'
2
2
 
3
- const { resolve } = require('node:path')
3
+ import { readFileSync } from 'node:fs'
4
+ import { yaml } from '@toa.io/generic'
5
+ import * as schemas from '@toa.io/schemas'
4
6
 
5
- const { load } = require('@toa.io/yaml')
6
- const { Schema } = require('@toa.io/schema')
7
+ const path = resolve(import.meta.dirname, 'schema.yaml')
8
+ const object = yaml.load(readFileSync(path, 'utf8'))
9
+ const schema = schemas.schema(object)
7
10
 
8
- const path = resolve(__dirname, 'schema.yaml')
9
- const object = load.sync(path)
10
- const schema = new Schema(object)
11
-
12
- /**
13
- * @param {toa.norm.context.Declaration} context
14
- */
15
- const validate = (context) => {
11
+ export const validate = (context) => {
16
12
  schema.validate(context)
17
13
  }
18
-
19
- exports.validate = validate
package/src/component.js CHANGED
@@ -1,49 +1,39 @@
1
- 'use strict'
2
-
3
- const { join } = require('node:path')
4
-
5
- const { load: yaml } = require('@toa.io/yaml')
6
- const { directory: { find } } = require('@toa.io/filesystem')
7
- const { Locator } = require('@toa.io/core')
8
-
9
- const {
10
- expand,
11
- merge,
12
- validate,
13
- collapse,
14
- dereference,
15
- defaults,
16
- normalize,
17
- extensions
18
- } = require('./.component')
19
-
20
- const component = async (path) => {
1
+ import { join } from 'node:path'
2
+
3
+ import { readFile } from 'node:fs/promises'
4
+ import { yaml as jsyaml } from '@toa.io/generic'
5
+ import { find } from '@toa.io/generic'
6
+ import { Locator } from '@toa.io/core'
7
+
8
+ import { expand, merge, validate, collapse, dereference, defaults, normalize, extensions } from './.component/index.js'
9
+
10
+ export const component = async (path) => {
21
11
  const manifest = await load(path)
22
12
 
23
- normalize(manifest)
24
- validate(manifest)
25
- extensions(manifest)
13
+ await normalize(manifest, path)
14
+ await validate(manifest)
15
+ await extensions(manifest)
26
16
 
27
17
  manifest.locator = new Locator(manifest.name, manifest.namespace)
28
18
 
29
19
  return manifest
30
20
  }
31
21
 
32
- const load = async (path, base) => {
22
+ const load = async (path, base, proto = false) => {
33
23
  if (base !== undefined) path = find(path, base, MANIFEST)
34
24
 
35
25
  const file = join(path, MANIFEST)
36
- const manifest = /** @type {toa.norm.Component} */ await yaml(file) ?? {}
26
+ const manifest = await read(file) ?? {}
37
27
 
38
28
  manifest.path = path
39
29
 
40
- defaults(manifest)
30
+ defaults(manifest, proto)
41
31
  await expand(manifest)
42
32
 
43
33
  await merge(path, manifest)
44
34
 
45
35
  if (manifest.prototype !== null) {
46
- const prototype = await load(manifest.prototype, path)
36
+ const prototype = await load(manifest.prototype, path, true)
47
37
 
48
38
  collapse(manifest, prototype)
49
39
  }
@@ -56,4 +46,17 @@ const load = async (path, base) => {
56
46
 
57
47
  const MANIFEST = 'manifest.toa.yaml'
58
48
 
59
- exports.component = component
49
+
50
+
51
+ /**
52
+ * Reads a YAML file, resolving anchors into distinct objects so that
53
+ * mutating one node cannot reach another.
54
+ *
55
+ * @param {string} path
56
+ * @return {Promise<object>}
57
+ */
58
+ async function read (path) {
59
+ const object = jsyaml.load(await readFile(path, 'utf8'))
60
+
61
+ return jsyaml.load(jsyaml.dump(object, { noRefs: true, lineWidth: -1 }))
62
+ }
package/src/context.js CHANGED
@@ -1,25 +1,16 @@
1
- 'use strict'
1
+ import { resolve } from 'node:path'
2
+ import { convolve } from '@toa.io/generic'
3
+ import glob from 'fast-glob'
4
+ import { readFile } from 'node:fs/promises'
5
+ import { yaml as jsyaml } from '@toa.io/generic'
2
6
 
3
- const { resolve } = require('node:path')
4
- const { convolve } = require('@toa.io/generic')
5
- const { directory: { glob } } = require('@toa.io/filesystem')
6
- const { load } = require('@toa.io/yaml')
7
+ import { component } from './component.js'
7
8
 
8
- const { component } = require('./component')
9
+ import { dependencies, normalize, complete, dereference, expand, validate } from './.context/index.js'
9
10
 
10
- const {
11
- dependencies,
12
- normalize,
13
- complete,
14
- dereference,
15
- expand,
16
- validate
17
- } = require('./.context')
18
-
19
- const context = async (root, environment = process.env.TOA_ENV) => {
11
+ export const context = async (root, environment = process.env.TOA_ENV) => {
20
12
  const path = resolve(root, CONTEXT)
21
- const context = /** @type {toa.norm.Context} */ await load(path)
22
- const pattern = resolve(root, context.packages)
13
+ const context = /** @type {toa.norm.Context} */ await read(path)
23
14
 
24
15
  context.environment = environment
25
16
 
@@ -29,7 +20,7 @@ const context = async (root, environment = process.env.TOA_ENV) => {
29
20
 
30
21
  validate(context)
31
22
 
32
- const paths = await glob(pattern)
23
+ const paths = await glob(resolve(root, COMPONENTS), GLOB)
33
24
 
34
25
  context.components = await Promise.all(paths.map(component))
35
26
  context.dependencies = await dependencies(context)
@@ -41,5 +32,22 @@ const context = async (root, environment = process.env.TOA_ENV) => {
41
32
  }
42
33
 
43
34
  const CONTEXT = 'context.toa.yaml'
35
+ const COMPONENTS = 'components/*'
36
+
37
+
38
+ const GLOB = { onlyDirectories: true, absolute: true }
39
+
44
40
 
45
- exports.context = context
41
+
42
+ /**
43
+ * Reads a YAML file, resolving anchors into distinct objects so that
44
+ * mutating one node cannot reach another.
45
+ *
46
+ * @param {string} path
47
+ * @return {Promise<object>}
48
+ */
49
+ async function read (path) {
50
+ const object = jsyaml.load(await readFile(path, 'utf8'))
51
+
52
+ return jsyaml.load(jsyaml.dump(object, { noRefs: true, lineWidth: -1 }))
53
+ }
package/src/index.js CHANGED
@@ -1,9 +1,3 @@
1
- 'use strict'
2
-
3
- const { context } = require('./context')
4
- const { component } = require('./component')
5
-
6
- exports.shortcuts = require('./shortcuts')
7
-
8
- exports.context = context
9
- exports.component = component
1
+ export { context } from './context.js'
2
+ export { component } from './component.js'
3
+ export * as shortcuts from './shortcuts.js'
package/src/shortcuts.js CHANGED
@@ -1,6 +1,4 @@
1
- 'use strict'
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,7 +36,7 @@ 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',
43
41
  node: '@toa.io/bridges.node',
44
42
  bash: '@toa.io/bridges.bash',
@@ -48,11 +46,8 @@ const SHORTCUTS = {
48
46
  exposition: '@toa.io/extensions.exposition',
49
47
  realtime: '@toa.io/extensions.realtime',
50
48
  configuration: '@toa.io/extensions.configuration',
51
- origins: '@toa.io/extensions.origins',
52
49
  stash: '@toa.io/extensions.stash',
53
- storages: '@toa.io/extensions.storages'
50
+ storages: '@toa.io/extensions.storages',
51
+ telemetry: '@toa.io/extensions.telemetry',
52
+ introspection: '@toa.io/extensions.introspection'
54
53
  }
55
-
56
- exports.recognize = recognize
57
- exports.resolve = resolve
58
- exports.SHORTCUTS = SHORTCUTS
@@ -1,6 +1,4 @@
1
- 'use strict'
2
-
3
- const { generate } = require('randomstring')
1
+ import { generate } from 'randomstring'
4
2
 
5
3
  const entity = {
6
4
  manifest: {
@@ -88,7 +86,6 @@ const operations = {
88
86
  result: {
89
87
  prototype: {
90
88
  prototype: null,
91
- path: expect.any(String),
92
89
  operations: {
93
90
  add: {
94
91
  bridge: 'a'
@@ -131,4 +128,4 @@ const remotes = {
131
128
  }
132
129
  }
133
130
 
134
- exports.samples = { entity, operations, remotes }
131
+ export const samples = { entity, operations, remotes }