@effected/config-file 0.2.0 → 0.3.0
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/ConfigCodec.js +1 -1
- package/ConfigFile.js +5 -5
- package/ConfigMigration.js +1 -1
- package/EncryptedCodec.js +1 -1
- package/README.md +20 -0
- package/package.json +6 -6
package/ConfigCodec.js
CHANGED
|
@@ -10,7 +10,7 @@ import { Schema } from "effect";
|
|
|
10
10
|
*
|
|
11
11
|
* @public
|
|
12
12
|
*/
|
|
13
|
-
var ConfigCodecError = class extends Schema.
|
|
13
|
+
var ConfigCodecError = class extends Schema.TaggedError()("ConfigCodecError", {
|
|
14
14
|
/** The codec that failed, e.g. `"json"`. */
|
|
15
15
|
codec: Schema.String,
|
|
16
16
|
/** Which direction failed. */
|
package/ConfigFile.js
CHANGED
|
@@ -13,7 +13,7 @@ import { Context, DateTime, Effect, FileSystem, Layer, Option, Path, PubSub, Sch
|
|
|
13
13
|
*
|
|
14
14
|
* @public
|
|
15
15
|
*/
|
|
16
|
-
var ConfigFileNotFoundError = class extends Schema.
|
|
16
|
+
var ConfigFileNotFoundError = class extends Schema.TaggedError()("ConfigFileNotFoundError", {
|
|
17
17
|
/** The names of the resolvers that were probed, in order. */
|
|
18
18
|
searched: Schema.Array(Schema.String) }) {
|
|
19
19
|
get message() {
|
|
@@ -29,7 +29,7 @@ searched: Schema.Array(Schema.String) }) {
|
|
|
29
29
|
*
|
|
30
30
|
* @public
|
|
31
31
|
*/
|
|
32
|
-
var ConfigFileReadError = class extends Schema.
|
|
32
|
+
var ConfigFileReadError = class extends Schema.TaggedError()("ConfigFileReadError", {
|
|
33
33
|
/** The path that could not be read. */
|
|
34
34
|
path: Schema.String,
|
|
35
35
|
/** The underlying failure, preserved structurally. */
|
|
@@ -44,7 +44,7 @@ var ConfigFileReadError = class extends Schema.TaggedErrorClass()("ConfigFileRea
|
|
|
44
44
|
*
|
|
45
45
|
* @public
|
|
46
46
|
*/
|
|
47
|
-
var ConfigFileWriteError = class extends Schema.
|
|
47
|
+
var ConfigFileWriteError = class extends Schema.TaggedError()("ConfigFileWriteError", {
|
|
48
48
|
/** The path that could not be written. */
|
|
49
49
|
path: Schema.String,
|
|
50
50
|
/** The underlying failure, preserved structurally. */
|
|
@@ -69,7 +69,7 @@ var ConfigFileWriteError = class extends Schema.TaggedErrorClass()("ConfigFileWr
|
|
|
69
69
|
*
|
|
70
70
|
* @public
|
|
71
71
|
*/
|
|
72
|
-
var ConfigDefaultPathMissingError = class extends Schema.
|
|
72
|
+
var ConfigDefaultPathMissingError = class extends Schema.TaggedError()("ConfigDefaultPathMissingError", {}) {
|
|
73
73
|
get message() {
|
|
74
74
|
return "No `defaultPath` configured: `save` and `update` require ConfigFileOptions.defaultPath";
|
|
75
75
|
}
|
|
@@ -87,7 +87,7 @@ var ConfigDefaultPathMissingError = class extends Schema.TaggedErrorClass()("Con
|
|
|
87
87
|
*
|
|
88
88
|
* @public
|
|
89
89
|
*/
|
|
90
|
-
var ConfigValidationError = class extends Schema.
|
|
90
|
+
var ConfigValidationError = class extends Schema.TaggedError()("ConfigValidationError", {
|
|
91
91
|
/** The offending file, absent when `validate` was called on an in-memory value. */
|
|
92
92
|
path: Schema.Option(Schema.String),
|
|
93
93
|
/** The structured schema issue. Never a string. */
|
package/ConfigMigration.js
CHANGED
|
@@ -12,7 +12,7 @@ import { Effect, Schema } from "effect";
|
|
|
12
12
|
*
|
|
13
13
|
* @public
|
|
14
14
|
*/
|
|
15
|
-
var ConfigMigrationError = class extends Schema.
|
|
15
|
+
var ConfigMigrationError = class extends Schema.TaggedError()("ConfigMigrationError", {
|
|
16
16
|
/** The target version of the step that failed. `0` when reading the version failed. */
|
|
17
17
|
version: Schema.Number,
|
|
18
18
|
/** The name of the step that failed; empty when reading the version failed. */
|
package/EncryptedCodec.js
CHANGED
|
@@ -14,7 +14,7 @@ import { Duration, Effect, Exit, Schema } from "effect";
|
|
|
14
14
|
*
|
|
15
15
|
* @public
|
|
16
16
|
*/
|
|
17
|
-
var ConfigEncryptionError = class extends Schema.
|
|
17
|
+
var ConfigEncryptionError = class extends Schema.TaggedError()("ConfigEncryptionError", {
|
|
18
18
|
/** Which cryptographic stage failed. */
|
|
19
19
|
phase: Schema.Literals([
|
|
20
20
|
"key-derivation",
|
package/README.md
CHANGED
|
@@ -98,6 +98,25 @@ export const SettingsLive = ConfigFile.layer(SettingsConfig, {
|
|
|
98
98
|
});
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
+
## Reading one known path
|
|
102
|
+
|
|
103
|
+
Not every caller has a config file — some just have one path a caller already vouched for, such as a CLI's `--config` flag. `ConfigFile.read` is the one-shot escape from the service, the layer and the resolver chain: read, decode and validate a single path, with the schema and codec named per call rather than bound to a service class:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { ConfigFile, JsonCodec } from "@effected/config-file";
|
|
107
|
+
import { NodeFileSystem } from "@effect/platform-node";
|
|
108
|
+
import { Effect, Schema } from "effect";
|
|
109
|
+
|
|
110
|
+
class MyConfig extends Schema.Class<MyConfig>("MyConfig")({ port: Schema.Number }) {}
|
|
111
|
+
|
|
112
|
+
const program = ConfigFile.read("./app.config.json", { schema: MyConfig, codec: JsonCodec });
|
|
113
|
+
|
|
114
|
+
Effect.runPromise(program.pipe(Effect.provide(NodeFileSystem.layer))).then(console.log);
|
|
115
|
+
// MyConfig { port: 3000 }
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
It is deliberately read-only and discovery-free — no resolver chain, no `save`/`update`. Reach for `ConfigFile.layer` the moment either is wanted.
|
|
119
|
+
|
|
101
120
|
## Errors
|
|
102
121
|
|
|
103
122
|
Every failure is a tagged error you route on with `Effect.catchTag`. The tags exist so that recovery can differ:
|
|
@@ -166,6 +185,7 @@ export const secret = EncryptedCodec(migrating, EncryptedCodecKey.fromPassphrase
|
|
|
166
185
|
## Features
|
|
167
186
|
|
|
168
187
|
- `ConfigFile.Service` / `ConfigFile.layer` / `ConfigFile.testLayer` — a per-schema service class and its layers. `testLayer` seeds files into a temp directory and wires the *real* implementation over them, so tests exercise the actual pipeline rather than a stub that can drift from it.
|
|
188
|
+
- `ConfigFile.read` — the one-shot escape from the service: read, decode and validate one explicit path, schema and codec named per call, with no resolver chain and no write path.
|
|
169
189
|
- `ConfigResolver` — `explicitPath`, `staticDir`, `upwardWalk`, `workspaceRoot`, `gitRoot` and `systemEtc`. A resolver's error channel is `never` by contract: every filesystem failure becomes `Option.none()`, so one unreadable tier never aborts the chain.
|
|
170
190
|
- `MergeStrategy` — `firstMatch` and `layeredMerge`, combining discovered sources in priority order.
|
|
171
191
|
- `JsonCodec`, `JsoncCodec`, `YamlCodec`, `TomlCodec` — JSON, JSONC, YAML and TOML in the box, exported free-standing so an unused format's engine is tree-shaken away.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effected/config-file",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Composable config file loading for Effect: JSON, JSONC, YAML and TOML codecs, resolution strategies, and merge behaviors.",
|
|
6
6
|
"keywords": [
|
|
@@ -43,11 +43,11 @@
|
|
|
43
43
|
"./package.json": "./package.json"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
|
-
"@effected/jsonc": "
|
|
47
|
-
"@effected/toml": "
|
|
48
|
-
"@effected/walker": "
|
|
49
|
-
"@effected/yaml": "
|
|
50
|
-
"effect": "4.0.0-beta.
|
|
46
|
+
"@effected/jsonc": "^0.6.0",
|
|
47
|
+
"@effected/toml": "^0.4.0",
|
|
48
|
+
"@effected/walker": "^0.4.0",
|
|
49
|
+
"@effected/yaml": "^0.7.0",
|
|
50
|
+
"effect": "4.0.0-beta.107"
|
|
51
51
|
},
|
|
52
52
|
"engines": {
|
|
53
53
|
"node": ">=24.11.0"
|