@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 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 [resolveKey, invalidateKey] = Effect.runSync(Effect.cachedInvalidateWithTTL(keyEffect(keySource), Duration.infinity));
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 { ConfigCodecError, ConfigEncryptionError, ConfigMigrationError } from "@effected/config-file";
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
- type SecretError = ConfigCodecError | ConfigMigrationError | ConfigEncryptionError;
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.0",
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.24.0",
50
+ "@effected/yaml": "^0.25.0",
51
51
  "effect": "^4.0.0"
52
52
  },
53
53
  "engines": {