@effected/config-file 0.19.0 → 0.19.1
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/EncryptedCodec.js +1 -2
- package/README.md +3 -2
- package/index.d.ts +37 -0
- package/package.json +2 -2
package/EncryptedCodec.js
CHANGED
|
@@ -107,8 +107,7 @@ const keyEffect = (keySource) => keySource._tag === "CryptoKey" ? keySource.key
|
|
|
107
107
|
*/
|
|
108
108
|
function EncryptedCodec(inner, keySource) {
|
|
109
109
|
const name = `encrypted(${inner.name})`;
|
|
110
|
-
const
|
|
111
|
-
const getKey = Effect.onExit(resolveKey, (exit) => Exit.isSuccess(exit) ? Effect.void : invalidateKey);
|
|
110
|
+
const getKey = Effect.runSync(Effect.cachedWithTTL(keyEffect(keySource), (exit) => Exit.isSuccess(exit) ? Duration.infinity : Duration.zero));
|
|
112
111
|
return {
|
|
113
112
|
name,
|
|
114
113
|
parse: (raw) => Effect.gen(function* () {
|
package/README.md
CHANGED
|
@@ -190,7 +190,7 @@ One install covers every format, and you still pay only for the parser you name.
|
|
|
190
190
|
Codecs compose. `EncryptedCodec` wraps any codec with AES-GCM, and `ConfigMigration.make` wraps any codec so parsed content is brought up to the latest version. Each *widens* the error channel rather than flattening its failures into the inner codec's error, and a decorated codec plugs into `ConfigFile.layer`, `ConfigFile.testLayer` and `ConfigFile.read` like any other: their error unions widen with it. A service key names the widened error as its third type argument:
|
|
191
191
|
|
|
192
192
|
```ts
|
|
193
|
-
import type {
|
|
193
|
+
import type { ConfigCodec } from "@effected/config-file";
|
|
194
194
|
import {
|
|
195
195
|
ConfigFile,
|
|
196
196
|
ConfigMigration,
|
|
@@ -217,7 +217,8 @@ const migrating = ConfigMigration.make({
|
|
|
217
217
|
export const secret = EncryptedCodec(migrating, EncryptedCodecKey.fromPassphrase("hunter2", new Uint8Array(16)));
|
|
218
218
|
|
|
219
219
|
const Settings = Schema.Struct({ port: Schema.Number });
|
|
220
|
-
|
|
220
|
+
// Read back from the codec value: ConfigCodecError | ConfigMigrationError | ConfigEncryptionError.
|
|
221
|
+
type SecretError = ConfigCodec.ErrorOf<typeof secret>;
|
|
221
222
|
|
|
222
223
|
class SecretSettings extends ConfigFile.Service<SecretSettings, typeof Settings.Type, SecretError>()(
|
|
223
224
|
"app/SecretSettings",
|
package/index.d.ts
CHANGED
|
@@ -66,6 +66,43 @@ interface ConfigCodec<E = ConfigCodecError> {
|
|
|
66
66
|
/** Turn a document back into file content. */
|
|
67
67
|
readonly stringify: (value: unknown) => Effect.Effect<string, E>;
|
|
68
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Type-level helpers over the `ConfigCodec` interface.
|
|
71
|
+
*
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
declare namespace ConfigCodec {
|
|
75
|
+
/**
|
|
76
|
+
* The error channel of a codec value, read back from its type.
|
|
77
|
+
*
|
|
78
|
+
* @remarks
|
|
79
|
+
* A decorated codec's error union is already on the value —
|
|
80
|
+
* `EncryptedCodec(...)` over `ConfigMigration.make(...)` is a
|
|
81
|
+
* `ConfigCodec<ConfigCodecError | ConfigEncryptionError | ConfigMigrationError>`
|
|
82
|
+
* — and a `ConfigFile.Service` key has to name the same union as its third
|
|
83
|
+
* type argument. Spelling it out by hand drifts the moment the codec
|
|
84
|
+
* changes; `ConfigCodec.ErrorOf<typeof codec>` cannot.
|
|
85
|
+
*
|
|
86
|
+
* Anything that is not a `ConfigCodec` resolves to `never`.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* import type { ConfigCodec } from "@effected/config-file";
|
|
91
|
+
* import { ConfigFile, ConfigMigration, EncryptedCodec, EncryptedCodecKey, JsonCodec } from "@effected/config-file";
|
|
92
|
+
*
|
|
93
|
+
* const codec = EncryptedCodec(
|
|
94
|
+
* ConfigMigration.make({ codec: JsonCodec, migrations: [] }),
|
|
95
|
+
* EncryptedCodecKey.fromPassphrase("hunter2", new Uint8Array(16)),
|
|
96
|
+
* );
|
|
97
|
+
*
|
|
98
|
+
* // Stays in sync with the codec: ConfigCodecError | ConfigMigrationError | ConfigEncryptionError.
|
|
99
|
+
* class Secrets extends ConfigFile.Service<Secrets, { port: number }, ConfigCodec.ErrorOf<typeof codec>>()(
|
|
100
|
+
* "app/Secrets",
|
|
101
|
+
* ) {}
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
type ErrorOf<C> = C extends ConfigCodec<infer E> ? E : never;
|
|
105
|
+
}
|
|
69
106
|
/**
|
|
70
107
|
* A reference to one configuration source that contributed to a load.
|
|
71
108
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effected/config-file",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.1",
|
|
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": [
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"@effected/jsonc": "^0.20.0",
|
|
48
48
|
"@effected/toml": "^0.16.0",
|
|
49
49
|
"@effected/walker": "^0.19.0",
|
|
50
|
-
"@effected/yaml": "^0.
|
|
50
|
+
"@effected/yaml": "^0.25.0",
|
|
51
51
|
"effect": "^4.0.0"
|
|
52
52
|
},
|
|
53
53
|
"engines": {
|