@effected/app 0.14.0 → 0.16.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/AppConfig.js CHANGED
@@ -1,20 +1,29 @@
1
1
  import { badFilename } from "./internal/filename.js";
2
2
  import { AppDirs, XdgConfig } from "@effected/xdg";
3
3
  import { Effect, Layer } from "effect";
4
- import { ConfigFile, MergeStrategy } from "@effected/config-file";
4
+ import { ConfigFile, ConfigResolver, MergeStrategy } from "@effected/config-file";
5
5
 
6
6
  //#region src/AppConfig.ts
7
7
  const layer = (tag, options) => Layer.unwrap(Effect.gen(function* () {
8
8
  const invalid = badFilename("AppConfig.layer", options.filename);
9
9
  if (invalid !== void 0) return yield* Effect.die(invalid);
10
10
  const appDirs = yield* AppDirs;
11
+ const xdg = options.xdg !== false;
12
+ const systemEtc = options.systemEtc ?? false;
13
+ const systemEtcDir = typeof systemEtc === "object" ? systemEtc.dir : void 0;
11
14
  const resolvers = [
12
15
  ...options.resolvers ?? [],
13
- XdgConfig.resolver({ filename: options.filename }),
14
- ...options.native === false ? [] : [XdgConfig.nativeResolver({
16
+ ...xdg ? [XdgConfig.resolver({ filename: options.filename })] : [],
17
+ ...xdg && options.native !== false ? [XdgConfig.nativeResolver({
15
18
  namespace: appDirs.namespace,
16
19
  filename: options.filename
17
- })]
20
+ })] : [],
21
+ ...systemEtc === false ? [] : [ConfigResolver.systemEtc({
22
+ app: appDirs.namespace,
23
+ filename: options.filename,
24
+ ...systemEtcDir !== void 0 && { dir: systemEtcDir }
25
+ })],
26
+ ...options.resolversAfter ?? []
18
27
  ];
19
28
  return ConfigFile.layer(tag, {
20
29
  schema: options.schema,
@@ -52,14 +61,13 @@ var AppConfig = class {
52
61
  * config-file's infallible `defaultPath` slot without an `orDie` because xdg
53
62
  * resolves at layer-construction time.
54
63
  *
55
- * `options.resolvers` prepends to that chain, which covers the case this
56
- * preset otherwise could not: a CLI whose `--config` flag must outrank the
57
- * app's XDG search path. What it deliberately does not cover is a chain that
58
- * needs the XDG resolvers somewhere other than last, or no XDG resolvers at
59
- * all — an app wanting that composes `ConfigFile.layer` from
60
- * `@effected/config-file` directly and orders the whole chain itself, which
61
- * costs it only the `defaultPath` and ambient-namespace wiring this preset
62
- * does for free.
64
+ * The chain is caller-controlled at both ends: `options.resolvers` prepends,
65
+ * `options.resolversAfter` appends, `options.systemEtc` adds the `/etc`
66
+ * tier behind the XDG pair, and `options.xdg: false` removes the XDG pair
67
+ * altogether — at which point the chain is exactly the caller's own, and
68
+ * the preset is contributing the ambient namespace and `defaultPath` alone.
69
+ * Dropping to `ConfigFile.layer` directly is no longer the price of an
70
+ * unusual chain.
63
71
  *
64
72
  * **The namespace is never a parameter.** It is read from the ambient
65
73
  * `AppDirs` service at layer build time, so it is typed exactly once, in
package/index.d.ts CHANGED
@@ -292,8 +292,65 @@ interface AppConfigOptions<A, I, RR = never> {
292
292
  * The native probe sits **after** the XDG resolver, so an existing
293
293
  * `~/.config/<app>` still beats the native directory; on Linux it resolves
294
294
  * to nothing and never touches the filesystem. Pass `false` to drop it.
295
+ *
296
+ * Ignored when `xdg` is `false`: the native probe is the tail of the XDG
297
+ * fallback chain, not an independent tier.
295
298
  */
296
299
  readonly native?: boolean;
300
+ /**
301
+ * Probe the app's XDG config search path. Defaults to `true`.
302
+ *
303
+ * @remarks
304
+ * Pass `false` to build the chain from `resolvers` (and `resolversAfter`,
305
+ * and `systemEtc`) alone. The case it exists for is a CLI's
306
+ * `--config <path>` branch, where a search-path fallback defeats the flag's
307
+ * purpose: without it, a `--config` naming a file that fails to resolve
308
+ * silently loads the user's XDG config instead.
309
+ *
310
+ * It drops **both** XDG resolvers — `XdgConfig.resolver` and, since it is
311
+ * documented as sitting behind it, `XdgConfig.nativeResolver`. `native` has
312
+ * no effect while `xdg` is `false`.
313
+ *
314
+ * `defaultPath` is unaffected: `save` still writes to
315
+ * `XdgConfig.savePath(filename)`. Dropping the *discovery* tier is not a
316
+ * statement about where this app saves its config.
317
+ */
318
+ readonly xdg?: boolean;
319
+ /**
320
+ * Append the system tier — `<dir>/<namespace>/<filename>`, `/etc` by
321
+ * default — after the XDG chain. Defaults to absent (no system tier).
322
+ *
323
+ * @remarks
324
+ * `true` uses `/etc`; an object overrides the system config root, which is
325
+ * chiefly how a test points the tier at a writable directory. The app name
326
+ * is the ambient `AppDirs` namespace, never a parameter — the same rule the
327
+ * XDG resolvers follow, so the two cannot drift apart.
328
+ *
329
+ * It is appended **after** the XDG pair because a machine-wide default must
330
+ * lose to a user's own config, which is the whole convention. A chain that
331
+ * wants the system tier somewhere else passes
332
+ * `ConfigResolver.systemEtc` through `resolvers` or `resolversAfter`
333
+ * instead and leaves this absent.
334
+ */
335
+ readonly systemEtc?: boolean | {
336
+ readonly dir?: string;
337
+ };
338
+ /**
339
+ * Resolvers composed **after** every built-in tier, in priority order —
340
+ * the lowest-priority end of the chain.
341
+ *
342
+ * @remarks
343
+ * The counterpart to `resolvers`, which prepends. Together the two make the
344
+ * whole chain caller-controlled without giving up what this preset does for
345
+ * free (the ambient namespace and `defaultPath`): the built-ins can be
346
+ * surrounded, and with `xdg: false` they can be removed entirely, at which
347
+ * point the chain is exactly `[...resolvers, ...resolversAfter]`.
348
+ *
349
+ * These come last, after the system tier, so a caller who needs a different
350
+ * order around `systemEtc` leaves that option absent and passes
351
+ * `ConfigResolver.systemEtc` here in the position it wants.
352
+ */
353
+ readonly resolversAfter?: ReadonlyArray<ConfigResolver<RR>>;
297
354
  }
298
355
  /**
299
356
  * The xdg-flavored `ConfigFile` preset: discovery through the app's XDG
@@ -320,14 +377,13 @@ export declare class AppConfig {
320
377
  * config-file's infallible `defaultPath` slot without an `orDie` because xdg
321
378
  * resolves at layer-construction time.
322
379
  *
323
- * `options.resolvers` prepends to that chain, which covers the case this
324
- * preset otherwise could not: a CLI whose `--config` flag must outrank the
325
- * app's XDG search path. What it deliberately does not cover is a chain that
326
- * needs the XDG resolvers somewhere other than last, or no XDG resolvers at
327
- * all — an app wanting that composes `ConfigFile.layer` from
328
- * `@effected/config-file` directly and orders the whole chain itself, which
329
- * costs it only the `defaultPath` and ambient-namespace wiring this preset
330
- * does for free.
380
+ * The chain is caller-controlled at both ends: `options.resolvers` prepends,
381
+ * `options.resolversAfter` appends, `options.systemEtc` adds the `/etc`
382
+ * tier behind the XDG pair, and `options.xdg: false` removes the XDG pair
383
+ * altogether — at which point the chain is exactly the caller's own, and
384
+ * the preset is contributing the ambient namespace and `defaultPath` alone.
385
+ * Dropping to `ConfigFile.layer` directly is no longer the price of an
386
+ * unusual chain.
331
387
  *
332
388
  * **The namespace is never a parameter.** It is read from the ambient
333
389
  * `AppDirs` service at layer build time, so it is typed exactly once, in
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effected/app",
3
- "version": "0.14.0",
3
+ "version": "0.16.0",
4
4
  "private": false,
5
5
  "description": "The application control plane for Effect: one layer wiring XDG-namespaced directories, a migrated SQLite store, a TTL cache and a config file to the same place.",
6
6
  "keywords": [
@@ -39,10 +39,10 @@
39
39
  "./package.json": "./package.json"
40
40
  },
41
41
  "peerDependencies": {
42
- "@effected/config-file": "^0.6.0",
43
- "@effected/store": "^0.7.0",
44
- "@effected/xdg": "^0.4.0",
45
- "effect": "4.0.0-rc.112"
42
+ "@effected/config-file": "^0.8.0",
43
+ "@effected/store": "^0.8.0",
44
+ "@effected/xdg": "^0.5.0",
45
+ "effect": "4.0.0-rc.115"
46
46
  },
47
47
  "engines": {
48
48
  "node": ">=24.11.0"
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.59.0"
8
+ "packageVersion": "7.59.1"
9
9
  }
10
10
  ]
11
11
  }