@toa.io/boot 1.0.0-alpha.288 → 1.0.0-alpha.289
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 +11 -0
- package/package.json +7 -7
- package/src/component.js +5 -0
- package/src/composition.js +5 -0
- package/src/env.js +12 -5
- package/src/events.js +3 -1
- package/src/index.js +2 -2
- package/src/span.js +2 -1
- package/src/storage.js +8 -2
- package/src/storage.test.js +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [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)
|
|
7
|
+
|
|
8
|
+
* 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)
|
|
9
|
+
|
|
10
|
+
### BREAKING CHANGES
|
|
11
|
+
|
|
12
|
+
* a component that read `process.env.TOA_*` reads `context` instead;
|
|
13
|
+
`echo(input)` no longer substitutes from the environment; a bash operation sees no
|
|
14
|
+
`TOA_*`; images no longer set `USER node` — see migrations/289.md.
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [1.0.0-alpha.288](https://github.com/toa-io/toa/compare/v1.0.0-alpha.287...v1.0.0-alpha.288) (2026-09-06)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @toa.io/boot
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/boot",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.289",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Toa Boot",
|
|
6
6
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
@@ -21,14 +21,14 @@
|
|
|
21
21
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@toa.io/atomicity": "1.0.0-alpha.
|
|
25
|
-
"@toa.io/core": "1.0.0-alpha.
|
|
26
|
-
"@toa.io/generic": "1.0.0-alpha.
|
|
27
|
-
"@toa.io/norm": "1.0.0-alpha.
|
|
28
|
-
"@toa.io/schemas": "1.0.0-alpha.
|
|
24
|
+
"@toa.io/atomicity": "1.0.0-alpha.289",
|
|
25
|
+
"@toa.io/core": "1.0.0-alpha.289",
|
|
26
|
+
"@toa.io/generic": "1.0.0-alpha.289",
|
|
27
|
+
"@toa.io/norm": "1.0.0-alpha.289",
|
|
28
|
+
"@toa.io/schemas": "1.0.0-alpha.289",
|
|
29
29
|
"clone-deep": "4.0.1",
|
|
30
30
|
"dotenv": "17.4.2",
|
|
31
31
|
"openspan": "1.0.0-alpha.286"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "4fcb482beac5896305d8084cdbc1d5fcf372d108"
|
|
34
34
|
}
|
package/src/component.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Component, Locator, State, entities } from '@toa.io/core'
|
|
2
2
|
import { entity as declaration } from '@toa.io/norm'
|
|
3
3
|
import { schema as compileSchema } from '@toa.io/schemas'
|
|
4
|
+
import { environment } from '@toa.io/generic'
|
|
4
5
|
|
|
5
6
|
import * as boot from './index.js'
|
|
6
7
|
import { span } from './span.js'
|
|
@@ -12,6 +13,10 @@ export const component = async (manifest) => {
|
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
const create = async (manifest, locator) => {
|
|
16
|
+
// what a test set after this package loaded goes to the store now, before a module of the
|
|
17
|
+
// component is imported: nothing of it is left in `process.env` for that module to read
|
|
18
|
+
environment.absorb()
|
|
19
|
+
|
|
15
20
|
await boot.extensions.load(manifest)
|
|
16
21
|
|
|
17
22
|
// the storage is told whether there will be an outbox, so the events come first
|
package/src/composition.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { console } from 'openspan'
|
|
2
2
|
import { Composition } from '@toa.io/core'
|
|
3
3
|
import { version } from '@toa.io/runtime'
|
|
4
|
+
import { environment } from '@toa.io/generic'
|
|
4
5
|
|
|
5
6
|
import * as boot from './index.js'
|
|
6
7
|
import { span } from './span.js'
|
|
7
8
|
|
|
8
9
|
export async function composition(paths, options) {
|
|
10
|
+
// what a test set after this package loaded goes to the store now, before a module of a
|
|
11
|
+
// component is imported: nothing of it is left in `process.env` for that module to read
|
|
12
|
+
environment.absorb()
|
|
13
|
+
|
|
9
14
|
options = Object.assign({}, options)
|
|
10
15
|
|
|
11
16
|
return span('boot composition', async () => {
|
package/src/env.js
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
1
2
|
import dotenv from 'dotenv'
|
|
2
|
-
import { findUp } from '@toa.io/generic'
|
|
3
|
+
import { environment, findUp } from '@toa.io/generic'
|
|
3
4
|
|
|
4
5
|
/*
|
|
5
|
-
* A local run reads what `toa env` wrote.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* A local run reads what `toa env` wrote. What the file says goes to the environment store
|
|
7
|
+
* and never into `process.env`: a `.env` is where a local run keeps its secrets, and a
|
|
8
|
+
* component's code must not find them. A variable already set is left alone, as `dotenv`
|
|
9
|
+
* left it, so what the environment says still wins — and reading the file costs nothing
|
|
10
|
+
* where there is none: a deployment has no `.env` to find.
|
|
8
11
|
*
|
|
9
12
|
* It used to be read only where `TOA_ENV` was unset, taking that one variable as proof the
|
|
10
13
|
* environment had been injected. Setting it for any other reason then dropped the file
|
|
11
14
|
* whole, and every variable in it with it.
|
|
12
15
|
*/
|
|
16
|
+
export function load(path) {
|
|
17
|
+
environment.absorbEntries(dotenv.parse(readFileSync(path, 'utf8')))
|
|
18
|
+
}
|
|
19
|
+
|
|
13
20
|
const path = findUp('.env')
|
|
14
21
|
|
|
15
|
-
if (path !== undefined)
|
|
22
|
+
if (path !== undefined) load(path)
|
package/src/events.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { environment } from '@toa.io/generic'
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* The events of this component that something consumes. An event nobody consumes is not
|
|
3
5
|
* published, so it gets no emitter and no exchange, and a component none of whose events are
|
|
@@ -12,7 +14,7 @@
|
|
|
12
14
|
export const events = (manifest) => {
|
|
13
15
|
if (manifest.events === undefined) return
|
|
14
16
|
|
|
15
|
-
const value =
|
|
17
|
+
const value = environment.get(VARIABLE + manifest.locator.uppercase)
|
|
16
18
|
|
|
17
19
|
if (value === undefined) return manifest.events
|
|
18
20
|
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// the environment is read at module scope elsewhere, so it is loaded first
|
|
2
|
-
|
|
3
|
-
import './env.js'
|
|
2
|
+
import { load as env } from './env.js'
|
|
4
3
|
|
|
5
4
|
import * as bindings from './bindings/index.js'
|
|
6
5
|
import * as bridge from './bridge.js'
|
|
@@ -29,6 +28,7 @@ import { rc } from './rc.js'
|
|
|
29
28
|
|
|
30
29
|
export {
|
|
31
30
|
call,
|
|
31
|
+
env,
|
|
32
32
|
cascade,
|
|
33
33
|
component,
|
|
34
34
|
composition,
|
package/src/span.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { console, traces } from 'openspan'
|
|
2
|
+
import { environment } from '@toa.io/generic'
|
|
2
3
|
|
|
3
|
-
const enabled =
|
|
4
|
+
const enabled = environment.get('TOA_BOOT_TRACE') === '1'
|
|
4
5
|
|
|
5
6
|
// Tracing is off until an exporter is configured, and the CLI opens its own span before
|
|
6
7
|
// any extension gets to configure one — so asking for a boot trace turns the console
|
package/src/storage.js
CHANGED
|
@@ -20,8 +20,14 @@ export const storage = async (manifest, outbox) => {
|
|
|
20
20
|
const factory = new Factory()
|
|
21
21
|
const storage = factory.storage(manifest.locator, manifest.entity, { outbox })
|
|
22
22
|
|
|
23
|
-
// a component whose structure nothing will make must not start with the structure it lacks
|
|
24
|
-
|
|
23
|
+
// a component whose structure nothing will make must not start with the structure it lacks;
|
|
24
|
+
// what it inherits was written for descendants that store, and one that stores nothing has
|
|
25
|
+
// nothing to convert
|
|
26
|
+
const own = manifest.entity.migrations?.some(
|
|
27
|
+
(migration) => migration.prototype === undefined
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
if (own === true && storage.migrates !== true)
|
|
25
31
|
throw new Error(
|
|
26
32
|
`Component '${manifest.locator.id}' declares migrations, ` +
|
|
27
33
|
`which storage '${manifest.entity.storage}' does not apply`
|
package/src/storage.test.js
CHANGED
|
@@ -30,6 +30,16 @@ it('should refuse migrations a storage does not apply', async () => {
|
|
|
30
30
|
)
|
|
31
31
|
})
|
|
32
32
|
|
|
33
|
+
it('should accept inherited migrations a storage does not apply', async () => {
|
|
34
|
+
const entity = {
|
|
35
|
+
schema,
|
|
36
|
+
storage: '@toa.io/storages.null',
|
|
37
|
+
migrations: [{ id: 'system:0001', steps: [], prototype: 'system' }]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
assert.notEqual(await storage(manifest(entity), false), undefined)
|
|
41
|
+
})
|
|
42
|
+
|
|
33
43
|
it('should accept a storage with no migrations', async () => {
|
|
34
44
|
const entity = { schema, storage: '@toa.io/storages.null' }
|
|
35
45
|
|