@toa.io/pointer 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 ADDED
@@ -0,0 +1,35 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ # [1.0.0-alpha.292](https://github.com/toa-io/toa/compare/v1.0.0-alpha.291...v1.0.0-alpha.292) (2026-09-07)
7
+
8
+ **Note:** Version bump only for package @toa.io/pointer
9
+
10
+
11
+
12
+
13
+
14
+ # [1.0.0-alpha.291](https://github.com/toa-io/toa/compare/v1.0.0-alpha.290...v1.0.0-alpha.291) (2026-09-07)
15
+
16
+ **Note:** Version bump only for package @toa.io/pointer
17
+
18
+
19
+
20
+
21
+
22
+ # [1.0.0-alpha.289](https://github.com/toa-io/toa/compare/v1.0.0-alpha.288...v1.0.0-alpha.289) (2026-09-07)
23
+
24
+ * A deploy moves only what changed, and a component sees none of the runtime's environment (#1073) ([f38e3db](https://github.com/toa-io/toa/commit/f38e3db533f24db866c57bfa1ef294eff1eaf499)), closes [#1073](https://github.com/toa-io/toa/issues/1073) [#1064](https://github.com/toa-io/toa/issues/1064) [#1066](https://github.com/toa-io/toa/issues/1066) [#1067](https://github.com/toa-io/toa/issues/1067) [#1068](https://github.com/toa-io/toa/issues/1068) [#1069](https://github.com/toa-io/toa/issues/1069) [#1071](https://github.com/toa-io/toa/issues/1071) [#1070](https://github.com/toa-io/toa/issues/1070) [#1072](https://github.com/toa-io/toa/issues/1072)
25
+
26
+ ### BREAKING CHANGES
27
+
28
+ * a component that read `process.env.TOA_*` reads `context` instead;
29
+ `echo(input)` no longer substitutes from the environment; a bash operation sees no
30
+ `TOA_*`; images no longer set `USER node` — see migrations/289.md.
31
+
32
+
33
+ # [1.0.0-alpha.287](https://github.com/toa-io/toa/compare/v1.0.0-alpha.286...v1.0.0-alpha.287) (2026-09-06)
34
+
35
+ **Note:** Version bump only for package @toa.io/pointer
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@toa.io/pointer",
3
- "version": "1.0.0-alpha.29",
3
+ "version": "1.0.0-alpha.292",
4
+ "type": "module",
4
5
  "description": "Toa Pointer",
5
6
  "homepage": "https://toa.io",
6
7
  "author": {
@@ -16,7 +17,7 @@
16
17
  "url": "https://github.com/toa-io/toa/issues"
17
18
  },
18
19
  "engines": {
19
- "node": ">= 18.0.0"
20
+ "node": ">= 24.0.0"
20
21
  },
21
22
  "publishConfig": {
22
23
  "access": "public"
@@ -24,15 +25,11 @@
24
25
  "main": "transpiled/index.js",
25
26
  "types": "transpiled/index.d.ts",
26
27
  "dependencies": {
27
- "@toa.io/generic": "1.0.0-alpha.29",
28
- "@toa.io/schemas": "1.0.0-alpha.29"
28
+ "@toa.io/generic": "1.0.0-alpha.292",
29
+ "@toa.io/schemas": "1.0.0-alpha.292"
29
30
  },
30
31
  "scripts": {
31
32
  "transpile": "tsc"
32
33
  },
33
- "jest": {
34
- "preset": "ts-jest",
35
- "testEnvironment": "node"
36
- },
37
- "gitHead": "186d0e17c12a9016b8076edf925963cbb32b9219"
34
+ "gitHead": "0f6aa3ad9dbec86bb632a7975ea61d1dde1d8fc5"
38
35
  }
package/readme.md CHANGED
@@ -72,7 +72,7 @@ amqp:
72
72
  URL resolution for the example above is as follows:
73
73
 
74
74
  | Selector | Result | Description |
75
- |-------------------|--------------------------------------|--------------------|
75
+ | ----------------- | ------------------------------------ | ------------------ |
76
76
  | `dummies.dummy` | `amqp://d1.rmq.example.com` | Exact match |
77
77
  | `dummies.another` | `amqp://all-dummies.rmq.example.com` | Partial match |
78
78
  | `what.ever` | `amqp://default.rmq.example.com` | No match (default) |
@@ -1,2 +1,14 @@
1
- .: [uri]
2
- /^[a-zA-Z0-9]{1,32}(\.[a-zA-Z0-9]{1,32}){0,3}$/: [uri]
1
+ properties:
2
+ .:
3
+ type: array
4
+ items:
5
+ type: string
6
+ format: uri
7
+ additionalProperties: false
8
+ type: object
9
+ patternProperties:
10
+ ^[a-zA-Z0-9]{1,32}(\.[a-zA-Z0-9]{1,32}){0,3}$:
11
+ type: array
12
+ items:
13
+ type: string
14
+ format: uri
@@ -1,17 +1,17 @@
1
- import { nameVariable, nameSecret } from './naming'
2
- import { resolveRecord } from './resolve'
1
+ import { nameVariable, nameSecret } from './naming.js'
2
+ import { resolveRecord } from './resolve.js'
3
3
  import type { Variables, Variable } from '@toa.io/operations'
4
4
 
5
5
  export class Deployment {
6
6
  private readonly id: string
7
7
  private readonly annotation: URIMap
8
8
 
9
- public constructor (id: string, annotation: URIMap) {
9
+ public constructor(id: string, annotation: URIMap) {
10
10
  this.id = id
11
11
  this.annotation = annotation
12
12
  }
13
13
 
14
- public export (requests: Request[]): Variables {
14
+ public export(requests: Request[]): Variables {
15
15
  const variables: Variables = {}
16
16
 
17
17
  for (const request of requests)
@@ -20,7 +20,7 @@ export class Deployment {
20
20
  return variables
21
21
  }
22
22
 
23
- private createVariables (selectors: string[]): Variable[] {
23
+ private createVariables(selectors: string[]): Variable[] {
24
24
  const variables: Variable[] = []
25
25
 
26
26
  for (const selector of selectors) {
@@ -33,7 +33,7 @@ export class Deployment {
33
33
  return variables
34
34
  }
35
35
 
36
- private createVariable (selector: string): Variable {
36
+ private createVariable(selector: string): Variable {
37
37
  const name = nameVariable(this.id, selector)
38
38
  const { references } = this.resolveRecord(selector)
39
39
  const value = references.join(' ')
@@ -41,17 +41,13 @@ export class Deployment {
41
41
  return { name, value }
42
42
  }
43
43
 
44
- private createSecrets (selector: string): Variable[] {
44
+ private createSecrets(selector: string): Variable[] {
45
45
  const variables: Variable[] = []
46
46
  const { key, references } = this.resolveRecord(selector)
47
47
 
48
48
  const protocol = new URL(references[0]).protocol
49
49
 
50
- if (insecureProtocols.includes(protocol))
51
- return []
52
-
53
- if (protocol in specialProtocols)
54
- return specialProtocols[protocol](references)
50
+ if (insecureProtocols.includes(protocol)) return []
55
51
 
56
52
  for (const token of ['username', 'password']) {
57
53
  const varName = nameVariable(this.id, selector, token)
@@ -69,7 +65,7 @@ export class Deployment {
69
65
  return variables
70
66
  }
71
67
 
72
- private resolveRecord (selector: string): AnnotationRecord {
68
+ private resolveRecord(selector: string): AnnotationRecord {
73
69
  return resolveRecord(this.annotation, selector)
74
70
  }
75
71
  }
@@ -86,21 +82,4 @@ export interface AnnotationRecord {
86
82
 
87
83
  const insecureProtocols = ['http:', 'https:', 'redis:']
88
84
 
89
- const specialProtocols: Record<string, (references: string[]) => Variable[]> = {
90
- 'pubsub:': (references: string[]) => {
91
- const path = new URL(references[0]).pathname
92
- const [, , project] = path.split('/')
93
- const name = nameVariable('ORIGINS_PUBSUB_', project)
94
-
95
- return [{
96
- name,
97
- secret: {
98
- name: 'toa-origins-pubsub',
99
- key: project,
100
- optional: true
101
- }
102
- } satisfies Variable]
103
- }
104
- }
105
-
106
85
  export type URIMap = Record<string, string[]>
@@ -1,18 +1,20 @@
1
- import { normalize } from './annotation'
1
+ import { describe, it } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+
4
+ import { normalize } from './annotation.js'
2
5
 
3
6
  describe('normalize', () => {
4
7
  it('should expand default shards', async () => {
5
8
  const declaration = 'amqp://rmq{0-2}.example.com'
6
9
  const annotation = normalize(declaration)
7
10
 
8
- expect(annotation)
9
- .toStrictEqual({
10
- '.': [
11
- 'amqp://rmq0.example.com',
12
- 'amqp://rmq1.example.com',
13
- 'amqp://rmq2.example.com'
14
- ]
15
- })
11
+ assert.deepStrictEqual(annotation, {
12
+ '.': [
13
+ 'amqp://rmq0.example.com',
14
+ 'amqp://rmq1.example.com',
15
+ 'amqp://rmq2.example.com'
16
+ ]
17
+ })
16
18
  })
17
19
 
18
20
  it('should expand shards within array', async () => {
@@ -22,15 +24,14 @@ describe('normalize', () => {
22
24
 
23
25
  const annotation = normalize(declaration)
24
26
 
25
- expect(annotation)
26
- .toStrictEqual({
27
- foo: [
28
- 'amqp://rmq.example.com',
29
- 'amqp://rmq0.example.com',
30
- 'amqp://rmq1.example.com',
31
- 'amqp://rmq2.example.com'
32
- ]
33
- })
27
+ assert.deepStrictEqual(annotation, {
28
+ foo: [
29
+ 'amqp://rmq.example.com',
30
+ 'amqp://rmq0.example.com',
31
+ 'amqp://rmq1.example.com',
32
+ 'amqp://rmq2.example.com'
33
+ ]
34
+ })
34
35
  })
35
36
  })
36
37
 
@@ -38,29 +39,34 @@ describe('validation', () => {
38
39
  it('should pass', async () => {
39
40
  const declaration = 'http://localhost'
40
41
 
41
- expect(() => normalize(declaration))
42
- .not.toThrow()
42
+ assert.doesNotThrow(() => normalize(declaration))
43
43
  })
44
44
 
45
45
  it('should throw if non-uri', async () => {
46
46
  const declaration = 'non uri'
47
47
 
48
- expect(() => normalize(declaration))
49
- .toThrow('must match format')
48
+ assert.throws(
49
+ () => normalize(declaration),
50
+ (error: any) => /must match format/.test(error.message)
51
+ )
50
52
  })
51
53
 
52
- it.each(['user:pass', 'user', ':pass'])('should throw if uri has credentials',
53
- async (credentials) => {
54
+ for (const credentials of ['user:pass', 'user', ':pass'])
55
+ it('should throw if uri has credentials', async () => {
54
56
  const declaration = `http://${credentials}@localhost`
55
57
 
56
- expect(() => normalize(declaration))
57
- .toThrow('must not contain credentials')
58
+ assert.throws(
59
+ () => normalize(declaration),
60
+ (error: any) => /must not contain credentials/.test(error.message)
61
+ )
58
62
  })
59
63
 
60
64
  it('should throw if key is not deployable', async () => {
61
65
  const declaration = { 'foo bar': 'http://localhost' }
62
66
 
63
- expect(() => normalize(declaration))
64
- .toThrow('not expected')
67
+ assert.throws(
68
+ () => normalize(declaration),
69
+ (error: any) => /not expected/.test(error.message)
70
+ )
65
71
  })
66
72
  })
@@ -2,9 +2,9 @@ import { resolve } from 'node:path'
2
2
  import * as schemas from '@toa.io/schemas'
3
3
  import { shards } from '@toa.io/generic'
4
4
  import type { Schema } from '@toa.io/schemas'
5
- import type { URIMap } from './Deployment'
5
+ import type { URIMap } from './Deployment.js'
6
6
 
7
- export function normalize (declaration: Declaration): URIMap {
7
+ export function normalize(declaration: Declaration): URIMap {
8
8
  const map: URIMap = {}
9
9
 
10
10
  if (declaration === undefined) return map
@@ -21,27 +21,31 @@ export function normalize (declaration: Declaration): URIMap {
21
21
  return map
22
22
  }
23
23
 
24
- function format (values: string[]): string[] {
24
+ function format(values: string[]): string[] {
25
25
  return values.map(shards).flat()
26
26
  }
27
27
 
28
- function validate (map: URIMap): void {
28
+ function validate(map: URIMap): void {
29
29
  schema.validate(map)
30
30
 
31
- for (const uris of Object.values(map))
32
- for (const uri of uris)
33
- checkCredentials(uri)
31
+ for (const uris of Object.values(map)) for (const uri of uris) checkCredentials(uri)
34
32
  }
35
33
 
36
- function checkCredentials (uri: string): void {
34
+ function checkCredentials(uri: string): void {
37
35
  const url = new URL(uri)
38
36
 
39
37
  if (url.username !== '' || url.password !== '')
40
- throw new Error(`Pointer URI '${uri}' must not contain credentials. ` +
41
- 'Please refer to the "Credentials" section of the documentation for more information.')
38
+ throw new Error(
39
+ `Pointer URI '${uri}' must not contain credentials. ` +
40
+ 'Please refer to the "Credentials" section of the documentation for more information.'
41
+ )
42
42
  }
43
43
 
44
- const path = resolve(__dirname, '../schemas/urimap.cos.yaml')
44
+ const path = resolve(import.meta.dirname, '../schemas/urimap.cos.yaml')
45
45
  const schema: Schema<URIMap> = schemas.schema(path)
46
46
 
47
- export type Declaration = string | string[] | Record<string, string | string[]> | undefined
47
+ export type Declaration =
48
+ | string
49
+ | string[]
50
+ | Record<string, string | string[]>
51
+ | undefined
@@ -1,7 +1,11 @@
1
+ import { it } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import { isDeepStrictEqual } from 'node:util'
4
+
1
5
  import { generate } from 'randomstring'
2
- import { createVariables } from './createVariables'
6
+ import { createVariables } from './createVariables.js'
3
7
  import type { Variable, Variables } from '@toa.io/operations'
4
- import type { Request } from './Deployment'
8
+ import type { Request } from './Deployment.js'
5
9
 
6
10
  it('should create from selector', async () => {
7
11
  const id = generate()
@@ -11,14 +15,15 @@ it('should create from selector', async () => {
11
15
  const variables = createVariables(id, annotation, [request])
12
16
 
13
17
  const expectation: Variables = {
14
- [request.group]: [{
15
- name: `TOA_${id.toUpperCase()}_${selector.toUpperCase()}`,
16
- value: annotation[selector]
17
- }]
18
+ [request.group]: [
19
+ {
20
+ name: `TOA_${id.toUpperCase()}_${selector.toUpperCase()}`,
21
+ value: annotation[selector]
22
+ }
23
+ ]
18
24
  }
19
25
 
20
- expect(variables)
21
- .toStrictEqual(expectation)
26
+ assert.deepStrictEqual(variables, expectation)
22
27
  })
23
28
 
24
29
  it('should create from partial match', async () => {
@@ -30,18 +35,15 @@ it('should create from partial match', async () => {
30
35
  const variables = createVariables(id, annotation, [request])
31
36
 
32
37
  const expectation: Variables = {
33
- [request.group]: [{
34
- name: `TOA_${id.toUpperCase()}_${
35
- selector
36
- .replace('.', '_')
37
- .toUpperCase()
38
- }`,
39
- value: annotation[key]
40
- }]
38
+ [request.group]: [
39
+ {
40
+ name: `TOA_${id.toUpperCase()}_${selector.replace('.', '_').toUpperCase()}`,
41
+ value: annotation[key]
42
+ }
43
+ ]
41
44
  }
42
45
 
43
- expect(variables)
44
- .toStrictEqual(expectation)
46
+ assert.deepStrictEqual(variables, expectation)
45
47
  })
46
48
 
47
49
  it('should create from default', async () => {
@@ -52,14 +54,15 @@ it('should create from default', async () => {
52
54
  const variables = createVariables(id, annotation, [request])
53
55
 
54
56
  const expectation: Variables = {
55
- [request.group]: [{
56
- name: `TOA_${id.toUpperCase()}_${selector.toUpperCase()}`,
57
- value: annotation
58
- }]
57
+ [request.group]: [
58
+ {
59
+ name: `TOA_${id.toUpperCase()}_${selector.toUpperCase()}`,
60
+ value: annotation
61
+ }
62
+ ]
59
63
  }
60
64
 
61
- expect(variables)
62
- .toStrictEqual(expectation)
65
+ assert.deepStrictEqual(variables, expectation)
63
66
  })
64
67
 
65
68
  it('should create from array', async () => {
@@ -71,14 +74,15 @@ it('should create from array', async () => {
71
74
  const variables = createVariables(id, annotation, [request])
72
75
 
73
76
  const expectation: Variables = {
74
- [request.group]: [{
75
- name: `TOA_${id.toUpperCase()}_${selector.toUpperCase()}`,
76
- value: values.join(' ')
77
- }]
77
+ [request.group]: [
78
+ {
79
+ name: `TOA_${id.toUpperCase()}_${selector.toUpperCase()}`,
80
+ value: values.join(' ')
81
+ }
82
+ ]
78
83
  }
79
84
 
80
- expect(variables)
81
- .toStrictEqual(expectation)
85
+ assert.deepStrictEqual(variables, expectation)
82
86
  })
83
87
 
84
88
  it('should create from default array', async () => {
@@ -90,14 +94,15 @@ it('should create from default array', async () => {
90
94
  const variables = createVariables(id, annotation, [request])
91
95
 
92
96
  const expectation: Variables = {
93
- [request.group]: [{
94
- name: `TOA_${id.toUpperCase()}_${selector.toUpperCase()}`,
95
- value: values.join(' ')
96
- }]
97
+ [request.group]: [
98
+ {
99
+ name: `TOA_${id.toUpperCase()}_${selector.toUpperCase()}`,
100
+ value: values.join(' ')
101
+ }
102
+ ]
97
103
  }
98
104
 
99
- expect(variables)
100
- .toStrictEqual(expectation)
105
+ assert.deepStrictEqual(variables, expectation)
101
106
  })
102
107
 
103
108
  it('should throw if selector cannot be resolved', async () => {
@@ -106,8 +111,10 @@ it('should throw if selector cannot be resolved', async () => {
106
111
  const annotation = {}
107
112
  const request: Request = { group: generate(), selectors: [selector] }
108
113
 
109
- expect(() => createVariables(id, annotation, [request]))
110
- .toThrow('cannot be resolved.')
114
+ assert.throws(
115
+ () => createVariables(id, annotation, [request]),
116
+ (error: any) => /cannot be resolved\./.test(error.message)
117
+ )
111
118
  })
112
119
 
113
120
  it('should create credential secrets for annotation keys', async () => {
@@ -135,35 +142,30 @@ it('should create credential secrets for annotation keys', async () => {
135
142
  const secrets2 = createExpectedSecrets(id, namespace, selector2)
136
143
  const secrets3 = createExpectedSecrets(id, '.', selector3)
137
144
 
138
- const expectation: Variables = {
139
- [group]: expect.arrayContaining([
140
- ...secrets1,
141
- ...secrets2,
142
- ...secrets3
143
- ])
144
- }
145
+ const expected = [...secrets1, ...secrets2, ...secrets3]
145
146
 
146
- expect(variables).toStrictEqual(expectation)
147
+ // the group holds every expected secret, in whatever order it built them
148
+ for (const secret of expected)
149
+ assert.ok(variables[group].some((one: any) => isDeepStrictEqual(one, secret)))
147
150
  })
148
151
 
149
- it.each([
150
- 'http:', 'redis:'
151
- ])('should not create credetial secrets for %s', async (protocol) => {
152
- const id = generate()
153
- const selector = generate()
154
- const annotation = { [selector]: uri(protocol) }
155
- const request: Request = { group: generate(), selectors: [selector] }
156
- const variables = createVariables(id, annotation, [request])
152
+ for (const protocol of ['http:', 'redis:'])
153
+ it(`should not create credetial secrets for ${protocol}`, async () => {
154
+ const id = generate()
155
+ const selector = generate()
156
+ const annotation = { [selector]: uri(protocol) }
157
+ const request: Request = { group: generate(), selectors: [selector] }
158
+ const variables = createVariables(id, annotation, [request])
157
159
 
158
- for (const variable of variables[request.group])
159
- expect(variable.secret).toBeUndefined()
160
- })
160
+ for (const variable of variables[request.group])
161
+ assert.strictEqual(variable.secret, undefined)
162
+ })
161
163
 
162
- function uri (protocol = 'http:'): string {
164
+ function uri(protocol = 'http:'): string {
163
165
  return protocol + '//host-' + generate()
164
166
  }
165
167
 
166
- function createExpectedSecrets (id: string, key: string, selector: string): Variable[] {
168
+ function createExpectedSecrets(id: string, key: string, selector: string): Variable[] {
167
169
  key = key === '.' ? '.default' : '-' + key.replaceAll('.', '-')
168
170
  selector = selector.replaceAll('.', '_').toUpperCase()
169
171
 
@@ -1,10 +1,13 @@
1
- import { Deployment, type Request } from './Deployment'
2
- import { normalize } from './annotation'
1
+ import { Deployment, type Request } from './Deployment.js'
2
+ import { normalize } from './annotation.js'
3
3
  import type { Variables } from '@toa.io/operations'
4
- import type { Declaration } from './annotation'
4
+ import type { Declaration } from './annotation.js'
5
5
 
6
- export function createVariables
7
- (id: string, declaration: Declaration, requests: Request[]): Variables {
6
+ export function createVariables(
7
+ id: string,
8
+ declaration: Declaration,
9
+ requests: Request[]
10
+ ): Variables {
8
11
  const annotation = normalize(declaration)
9
12
  const deployment = new Deployment(id, annotation)
10
13
 
package/source/index.ts CHANGED
@@ -1,7 +1,7 @@
1
- export { createVariables } from './createVariables'
2
- export { resolve, resolveRecord } from './resolve'
3
- export { normalize } from './annotation'
4
- export * as naming from './naming'
1
+ export { createVariables } from './createVariables.js'
2
+ export { resolve, resolveRecord } from './resolve.js'
3
+ export { normalize } from './annotation.js'
4
+ export * as naming from './naming.js'
5
5
 
6
- export type { Declaration } from './annotation'
7
- export type { Request, URIMap } from './Deployment'
6
+ export type { Declaration } from './annotation.js'
7
+ export type { Request, URIMap } from './Deployment.js'
package/source/naming.ts CHANGED
@@ -1,11 +1,7 @@
1
- export function nameVariable (...segments: string[]): string {
2
- return 'TOA_' + segments.join('_')
3
- .replaceAll(/[-.]/g, '_')
4
- .toUpperCase()
1
+ export function nameVariable(...segments: string[]): string {
2
+ return 'TOA_' + segments.join('_').replaceAll(/[-.]/g, '_').toUpperCase()
5
3
  }
6
4
 
7
- export function nameSecret (...segments: string[]): string {
8
- return 'toa-' + segments.join('-')
9
- .replaceAll('.', '-')
10
- .replace(/--$/, '.default')
5
+ export function nameSecret(...segments: string[]): string {
6
+ return 'toa-' + segments.join('-').replaceAll('.', '-').replace(/--$/, '.default')
11
7
  }
package/source/resolve.ts CHANGED
@@ -1,21 +1,20 @@
1
- import { nameVariable } from './naming'
2
- import { type AnnotationRecord, type URIMap } from './Deployment'
1
+ import { nameVariable } from './naming.js'
2
+ import { type AnnotationRecord, type URIMap } from './Deployment.js'
3
+ import { environment } from '@toa.io/generic'
3
4
 
4
- export function resolve (id: string, selector: string): string[] {
5
+ export function resolve(id: string, selector: string): string[] {
5
6
  const variable = nameVariable(id, selector)
6
- const value = process.env[variable]
7
+ const value = environment.get(variable)
7
8
 
8
- if (value === undefined)
9
- throw new Error(`${variable} is not set.`)
9
+ if (value === undefined) throw new Error(`${variable} is not set.`)
10
10
 
11
11
  const urls = value.split(' ')
12
12
 
13
13
  return withCredentials(variable, urls)
14
14
  }
15
15
 
16
- export function resolveRecord (uris: URIMap, selector: string): AnnotationRecord {
17
- if (selector in uris)
18
- return getRecord(uris, selector)
16
+ export function resolveRecord(uris: URIMap, selector: string): AnnotationRecord {
17
+ if (selector in uris) return getRecord(uris, selector)
19
18
 
20
19
  const segments = selector.split('.')
21
20
 
@@ -25,20 +24,18 @@ export function resolveRecord (uris: URIMap, selector: string): AnnotationRecord
25
24
  if (current in uris) return getRecord(uris, current)
26
25
  }
27
26
 
28
- if ('.' in uris)
29
- return getRecord(uris, '.')
30
- else
31
- throw new Error(`Selector '${selector}' cannot be resolved.`)
27
+ if ('.' in uris) return getRecord(uris, '.')
28
+ else throw new Error(`Selector '${selector}' cannot be resolved.`)
32
29
  }
33
30
 
34
- function withCredentials (variable: string, urls: string[]): string[] {
35
- const username = process.env[variable + '_USERNAME'] ?? ''
36
- const password = process.env[variable + '_PASSWORD'] ?? ''
31
+ function withCredentials(variable: string, urls: string[]): string[] {
32
+ const username = environment.get(variable + '_USERNAME') ?? ''
33
+ const password = environment.get(variable + '_PASSWORD') ?? ''
37
34
 
38
35
  return urls.map((url) => addCredentials(url, username, password))
39
36
  }
40
37
 
41
- function addCredentials (ref: string, username: string, password: string): string {
38
+ function addCredentials(ref: string, username: string, password: string): string {
42
39
  const url = new URL(ref)
43
40
 
44
41
  url.username = username
@@ -47,7 +44,7 @@ function addCredentials (ref: string, username: string, password: string): strin
47
44
  return url.href
48
45
  }
49
46
 
50
- function getRecord (uris: URIMap, key: string): AnnotationRecord {
47
+ function getRecord(uris: URIMap, key: string): AnnotationRecord {
51
48
  return {
52
49
  key,
53
50
  references: uris[key]