runtime-resolver 0.3.22 → 1.0.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.
Files changed (68) hide show
  1. package/README.md +34 -35
  2. package/bin/runtime-resolver.js +12 -31
  3. package/command.js +120 -0
  4. package/layers.js +61 -0
  5. package/output.js +55 -0
  6. package/package.json +6 -18
  7. package/report.js +24 -0
  8. package/cli/commands/resolve.js +0 -242
  9. package/cli/schemas/json-schema.js +0 -12
  10. package/cli/schemas/response.js +0 -86
  11. package/data/bun-defaults.js +0 -850
  12. package/data/deno-defaults.js +0 -1538
  13. package/data/node-defaults.js +0 -4435
  14. package/errors/AuthenticationError.js +0 -35
  15. package/errors/CacheError.js +0 -32
  16. package/errors/FreshnessError.js +0 -38
  17. package/errors/InvalidInputError.js +0 -33
  18. package/errors/NetworkError.js +0 -34
  19. package/errors/ParseError.js +0 -33
  20. package/errors/RateLimitError.js +0 -37
  21. package/errors/VersionNotFoundError.js +0 -37
  22. package/index.d.ts +0 -2574
  23. package/index.js +0 -166
  24. package/layers/AutoBunCacheLive.js +0 -47
  25. package/layers/AutoDenoCacheLive.js +0 -47
  26. package/layers/AutoNodeCacheLive.js +0 -58
  27. package/layers/BunReleaseCacheLive.js +0 -25
  28. package/layers/BunResolverLive.js +0 -85
  29. package/layers/BunVersionFetcherLive.js +0 -55
  30. package/layers/DenoReleaseCacheLive.js +0 -25
  31. package/layers/DenoResolverLive.js +0 -84
  32. package/layers/DenoVersionFetcherLive.js +0 -51
  33. package/layers/FreshBunCacheLive.js +0 -60
  34. package/layers/FreshDenoCacheLive.js +0 -60
  35. package/layers/FreshNodeCacheLive.js +0 -55
  36. package/layers/GitHubAppAuth.js +0 -58
  37. package/layers/GitHubAutoAuth.js +0 -70
  38. package/layers/GitHubClientLive.js +0 -130
  39. package/layers/GitHubTokenAuth.js +0 -50
  40. package/layers/NodeReleaseCacheLive.js +0 -77
  41. package/layers/NodeResolverLive.js +0 -107
  42. package/layers/NodeScheduleFetcherLive.js +0 -37
  43. package/layers/NodeVersionFetcherLive.js +0 -55
  44. package/layers/OfflineBunCacheLive.js +0 -40
  45. package/layers/OfflineDenoCacheLive.js +0 -40
  46. package/layers/OfflineNodeCacheLive.js +0 -39
  47. package/layers/RuntimeCacheLive.js +0 -78
  48. package/lib/retry.js +0 -27
  49. package/lib/semver.js +0 -21
  50. package/schemas/bun-release.js +0 -63
  51. package/schemas/deno-release.js +0 -63
  52. package/schemas/github.js +0 -74
  53. package/schemas/node-release.js +0 -133
  54. package/schemas/node-schedule.js +0 -110
  55. package/schemas/node.js +0 -68
  56. package/services/BunReleaseCache.js +0 -33
  57. package/services/BunResolver.js +0 -36
  58. package/services/BunVersionFetcher.js +0 -41
  59. package/services/DenoReleaseCache.js +0 -33
  60. package/services/DenoResolver.js +0 -36
  61. package/services/DenoVersionFetcher.js +0 -41
  62. package/services/GitHubClient.js +0 -40
  63. package/services/NodeReleaseCache.js +0 -41
  64. package/services/NodeResolver.js +0 -44
  65. package/services/NodeScheduleFetcher.js +0 -38
  66. package/services/NodeVersionFetcher.js +0 -39
  67. package/services/OctokitInstance.js +0 -44
  68. package/tsdoc-metadata.json +0 -11
package/index.d.ts DELETED
@@ -1,2574 +0,0 @@
1
- import { Context, DateTime, Effect, Layer, Option, Ref, Schema } from "effect";
2
- import { EmptyCacheError, InvalidRangeError, InvalidVersionError, SemVer, UnsatisfiedRangeError, VersionCache } from "semver-effect";
3
- //#region src/schemas/common.d.ts
4
- /**
5
- * Discriminates which JavaScript runtime a resolver targets.
6
- *
7
- * @see {@link resolveNode}
8
- * @see {@link resolveBun}
9
- * @see {@link resolveDeno}
10
- *
11
- * @public
12
- */
13
- declare const Runtime: Schema.Literal<["node", "bun", "deno"]>;
14
- /**
15
- * Discriminates which JavaScript runtime a resolver targets.
16
- *
17
- * @see {@link resolveNode}
18
- * @see {@link resolveBun}
19
- * @see {@link resolveDeno}
20
- *
21
- * @public
22
- */
23
- type Runtime = typeof Runtime.Type;
24
- /**
25
- * Indicates whether a `ResolvedVersions` result was served from
26
- * a live API call or a local cache.
27
- *
28
- * @public
29
- */
30
- declare const Source: Schema.Literal<["api", "cache"]>;
31
- /**
32
- * Indicates whether a `ResolvedVersions` result was served from
33
- * a live API call or a local cache.
34
- *
35
- * @public
36
- */
37
- type Source = typeof Source.Type;
38
- /**
39
- * The primary return type produced by every runtime resolver.
40
- *
41
- * Contains the full list of matching versions, the latest version string, and
42
- * optional `lts` / `default` version strings depending on the runtime.
43
- * The `source` field indicates whether the data came from a live API call or
44
- * a cached snapshot.
45
- *
46
- * @see {@link resolveNode}
47
- * @see {@link resolveBun}
48
- * @see {@link resolveDeno}
49
- *
50
- * @example
51
- * ```typescript
52
- * import { Effect } from "effect";
53
- * import type { ResolvedVersions } from "./common.js";
54
- * import { resolveNode } from "../resolvers/node.js";
55
- *
56
- * const program: Effect.Effect<ResolvedVersions> = resolveNode(">=20");
57
- *
58
- * Effect.runPromise(program).then((result: ResolvedVersions) => {
59
- * console.log(result.latest); // e.g. "22.3.0"
60
- * console.log(result.source); // "api" | "cache"
61
- * console.log(result.versions); // ["22.3.0", "22.2.0", ...]
62
- * });
63
- * ```
64
- *
65
- * @public
66
- */
67
- declare const ResolvedVersions: Schema.Struct<{
68
- source: Schema.Literal<["api", "cache"]>;
69
- versions: Schema.Array$<typeof Schema.String>;
70
- latest: typeof Schema.String;
71
- lts: Schema.optional<typeof Schema.String>;
72
- default: Schema.optional<typeof Schema.String>;
73
- }>;
74
- /**
75
- * The primary return type produced by every runtime resolver.
76
- *
77
- * @see {@link resolveNode}
78
- * @see {@link resolveBun}
79
- * @see {@link resolveDeno}
80
- *
81
- * @public
82
- */
83
- type ResolvedVersions = typeof ResolvedVersions.Type;
84
- /**
85
- * Lifecycle phase of a Node.js major release line, derived from the official
86
- * Node.js release schedule.
87
- *
88
- * - `"current"` — actively receiving features and bug fixes.
89
- * - `"active-lts"` — Long-Term Support; stable, receiving only bug and
90
- * security fixes.
91
- * - `"maintenance-lts"` — critical security fixes only.
92
- * - `"end-of-life"` — no longer maintained.
93
- *
94
- * @see {@link NodeRelease.phase}
95
- *
96
- * @public
97
- */
98
- declare const NodePhase: Schema.Literal<["current", "active-lts", "maintenance-lts", "end-of-life"]>;
99
- /**
100
- * Lifecycle phase of a Node.js major release line.
101
- *
102
- * @see {@link NodeRelease.phase}
103
- *
104
- * @public
105
- */
106
- type NodePhase = typeof NodePhase.Type;
107
- /**
108
- * Controls the granularity at which matching versions are grouped when a
109
- * resolver returns multiple results.
110
- *
111
- * - `"latest"` — return only the single highest matching version.
112
- * - `"minor"` — return the latest patch for every minor line.
113
- * - `"patch"` — return every individual patch release.
114
- *
115
- * @public
116
- */
117
- declare const Increments: Schema.Literal<["latest", "minor", "patch"]>;
118
- /**
119
- * Controls the granularity at which matching versions are grouped.
120
- *
121
- * @public
122
- */
123
- type Increments = typeof Increments.Type;
124
- //#endregion
125
- //#region src/errors/VersionNotFoundError.d.ts
126
- declare const VersionNotFoundError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
127
- readonly _tag: "VersionNotFoundError";
128
- } & Readonly<A>;
129
- /**
130
- * Raised when no published version satisfies the requested constraint.
131
- *
132
- * This error is produced by {@link NodeResolver}, {@link BunResolver}, and
133
- * {@link DenoResolver} after the full list of available versions has been
134
- * fetched and filtered but no entry matches the caller-supplied semver
135
- * constraint. The `runtime` field identifies which runtime was queried and
136
- * `constraint` echoes the range string that was provided.
137
- *
138
- * @see {@link NodeResolver}
139
- * @see {@link BunResolver}
140
- * @see {@link DenoResolver}
141
- *
142
- * @example
143
- * ```typescript
144
- * import { Effect } from "effect";
145
- * import type { VersionNotFoundError } from "./VersionNotFoundError.js";
146
- * import { resolveNode } from "../resolvers/node.js";
147
- *
148
- * const program = resolveNode(">=999").pipe(
149
- * Effect.catchTag("VersionNotFoundError", (err: VersionNotFoundError) =>
150
- * Effect.logError(
151
- * `No ${err.runtime} version matched "${err.constraint}": ${err.message}`
152
- * ).pipe(Effect.andThen(Effect.fail(err)))
153
- * )
154
- * );
155
- * ```
156
- *
157
- * @public
158
- */
159
- declare class VersionNotFoundError extends VersionNotFoundError_base<{
160
- readonly runtime: Runtime;
161
- readonly constraint: string;
162
- readonly message: string;
163
- }> {}
164
- //#endregion
165
- //#region src/services/BunResolver.d.ts
166
- /**
167
- * Options accepted by `BunResolver.resolve`.
168
- *
169
- * All fields are optional; omitting them causes the resolver to fall back to
170
- * its built-in defaults (latest stable release, `"latest"` increment
171
- * granularity).
172
- *
173
- * @see {@link BunResolver}
174
- * @see {@link (Increments:type)}
175
- * @see {@link (ResolvedVersions:type)}
176
- *
177
- * @public
178
- */
179
- interface BunResolverOptions {
180
- /**
181
- * A semver range string used to constrain which Bun releases are
182
- * considered (e.g. `"^1.0.0"` or `">=1.1.0 <2.0.0"`).
183
- *
184
- * When omitted all cached releases are eligible.
185
- */
186
- readonly semverRange?: string;
187
- /**
188
- * A fallback version string returned when no release satisfies
189
- * `semverRange`. Must be a valid semver version (e.g. `"1.0.0"`).
190
- *
191
- * When omitted and no match is found the effect fails with
192
- * {@link VersionNotFoundError}.
193
- */
194
- readonly defaultVersion?: string;
195
- /**
196
- * Controls the granularity of the version list included in
197
- * the `versions` field of {@link (ResolvedVersions:type)}.
198
- *
199
- * - `"latest"` — only the single highest matching version.
200
- * - `"minor"` — the latest patch for every minor line.
201
- * - `"patch"` — every individual patch release.
202
- *
203
- * Defaults to `"latest"` when omitted.
204
- *
205
- * @see {@link (Increments:type)}
206
- */
207
- readonly increments?: Increments;
208
- }
209
- /**
210
- * Union of all typed errors that `BunResolver.resolve` can fail with.
211
- *
212
- * @see {@link VersionNotFoundError}
213
- *
214
- * @public
215
- */
216
- type BunResolverError = VersionNotFoundError;
217
- declare const BunResolver_base: Context.TagClass<BunResolver, "runtime-resolver/BunResolver", {
218
- /**
219
- * Resolves Bun versions according to `options` and returns a
220
- * {@link (ResolvedVersions:type)} object containing the matching version list,
221
- * the latest version string, and the data source indicator.
222
- *
223
- * Fails with {@link BunResolverError} when no version can be resolved and
224
- * no `defaultVersion` was provided.
225
- *
226
- * @param options - Optional resolution constraints.
227
- *
228
- * @see {@link BunResolverOptions}
229
- */
230
- readonly resolve: (options?: BunResolverOptions) => Effect.Effect<ResolvedVersions, BunResolverError>;
231
- }>;
232
- /**
233
- * Service for resolving Bun runtime versions against the cached
234
- * release index.
235
- *
236
- * For a one-shot Promise-based API see {@link resolveBun}.
237
- *
238
- * @example
239
- * ```typescript
240
- * import type { ResolvedVersions } from "runtime-resolver";
241
- * import { BunResolver, BunResolverLive } from "runtime-resolver";
242
- * import { Effect } from "effect";
243
- *
244
- * const program = Effect.gen(function* () {
245
- * const resolver = yield* BunResolver;
246
- * const result = yield* resolver.resolve({ semverRange: "^1.0.0", increments: "minor" });
247
- * console.log(result.latest);
248
- * console.log(result.versions);
249
- * });
250
- *
251
- * Effect.runPromise(program.pipe(Effect.provide(BunResolverLive)));
252
- * ```
253
- *
254
- * @see {@link BunResolverLive}
255
- * @see {@link resolveBun}
256
- * @see {@link BunResolverOptions}
257
- * @see {@link (ResolvedVersions:type)}
258
- *
259
- * @public
260
- */
261
- declare class BunResolver extends BunResolver_base {}
262
- //#endregion
263
- //#region src/services/DenoResolver.d.ts
264
- /**
265
- * Options accepted by `DenoResolver.resolve`.
266
- *
267
- * All fields are optional; omitting them causes the resolver to fall back to
268
- * its built-in defaults (latest stable release, `"latest"` increment
269
- * granularity).
270
- *
271
- * @see {@link DenoResolver}
272
- * @see {@link (Increments:type)}
273
- * @see {@link (ResolvedVersions:type)}
274
- *
275
- * @public
276
- */
277
- interface DenoResolverOptions {
278
- /**
279
- * A semver range string used to constrain which Deno releases are
280
- * considered (e.g. `"^2.0.0"` or `">=1.40.0 <2.0.0"`).
281
- *
282
- * When omitted all cached releases are eligible.
283
- */
284
- readonly semverRange?: string;
285
- /**
286
- * A fallback version string returned when no release satisfies
287
- * `semverRange`. Must be a valid semver version (e.g. `"2.0.0"`).
288
- *
289
- * When omitted and no match is found the effect fails with
290
- * {@link VersionNotFoundError}.
291
- */
292
- readonly defaultVersion?: string;
293
- /**
294
- * Controls the granularity of the version list included in
295
- * the `versions` field of {@link (ResolvedVersions:type)}.
296
- *
297
- * - `"latest"` — only the single highest matching version.
298
- * - `"minor"` — the latest patch for every minor line.
299
- * - `"patch"` — every individual patch release.
300
- *
301
- * Defaults to `"latest"` when omitted.
302
- *
303
- * @see {@link (Increments:type)}
304
- */
305
- readonly increments?: Increments;
306
- }
307
- /**
308
- * Union of all typed errors that `DenoResolver.resolve` can fail with.
309
- *
310
- * @see {@link VersionNotFoundError}
311
- *
312
- * @public
313
- */
314
- type DenoResolverError = VersionNotFoundError;
315
- declare const DenoResolver_base: Context.TagClass<DenoResolver, "runtime-resolver/DenoResolver", {
316
- /**
317
- * Resolves Deno versions according to `options` and returns a
318
- * {@link (ResolvedVersions:type)} object containing the matching version list,
319
- * the latest version string, and the data source indicator.
320
- *
321
- * Fails with {@link DenoResolverError} when no version can be resolved and
322
- * no `defaultVersion` was provided.
323
- *
324
- * @param options - Optional resolution constraints.
325
- *
326
- * @see {@link DenoResolverOptions}
327
- */
328
- readonly resolve: (options?: DenoResolverOptions) => Effect.Effect<ResolvedVersions, DenoResolverError>;
329
- }>;
330
- /**
331
- * Service for resolving Deno runtime versions against the cached
332
- * release index.
333
- *
334
- * For a one-shot Promise-based API see {@link resolveDeno}.
335
- *
336
- * @example
337
- * ```typescript
338
- * import type { ResolvedVersions } from "runtime-resolver";
339
- * import { DenoResolver, DenoResolverLive } from "runtime-resolver";
340
- * import { Effect } from "effect";
341
- *
342
- * const program = Effect.gen(function* () {
343
- * const resolver = yield* DenoResolver;
344
- * const result = yield* resolver.resolve({ semverRange: "^2.0.0", increments: "minor" });
345
- * console.log(result.latest);
346
- * console.log(result.versions);
347
- * });
348
- *
349
- * Effect.runPromise(program.pipe(Effect.provide(DenoResolverLive)));
350
- * ```
351
- *
352
- * @see {@link DenoResolverLive}
353
- * @see {@link resolveDeno}
354
- * @see {@link DenoResolverOptions}
355
- * @see {@link (ResolvedVersions:type)}
356
- *
357
- * @public
358
- */
359
- declare class DenoResolver extends DenoResolver_base {}
360
- //#endregion
361
- //#region src/services/NodeResolver.d.ts
362
- /**
363
- * Options accepted by `NodeResolver.resolve`.
364
- *
365
- * All fields are optional; omitting them causes the resolver to fall back to
366
- * its built-in defaults (all lifecycle phases, latest stable release,
367
- * `"latest"` increment granularity, current wall-clock date).
368
- *
369
- * @see {@link NodeResolver}
370
- * @see {@link (NodePhase:type)}
371
- * @see {@link (Increments:type)}
372
- * @see {@link (ResolvedVersions:type)}
373
- *
374
- * @public
375
- */
376
- interface NodeResolverOptions {
377
- /**
378
- * A semver range string used to constrain which Node.js releases are
379
- * considered (e.g. `"^20.0.0"` or `">=18.0.0 <22.0.0"`).
380
- *
381
- * When omitted all cached releases are eligible.
382
- */
383
- readonly semverRange?: string;
384
- /**
385
- * A fallback version string returned when no release satisfies
386
- * `semverRange`. Must be a valid semver version (e.g. `"20.0.0"`).
387
- *
388
- * When omitted and no match is found the effect fails with
389
- * {@link VersionNotFoundError}.
390
- */
391
- readonly defaultVersion?: string;
392
- /**
393
- * Restricts resolution to releases whose lifecycle phase is included in
394
- * this list. For example, passing `["active-lts"]` excludes `"current"`
395
- * and `"maintenance-lts"` releases from consideration.
396
- *
397
- * When omitted all phases are eligible.
398
- *
399
- * @see {@link (NodePhase:type)}
400
- */
401
- readonly phases?: ReadonlyArray<NodePhase>;
402
- /**
403
- * Controls the granularity of the version list included in
404
- * the `versions` field of {@link (ResolvedVersions:type)}.
405
- *
406
- * - `"latest"` — only the single highest matching version.
407
- * - `"minor"` — the latest patch for every minor line.
408
- * - `"patch"` — every individual patch release.
409
- *
410
- * Defaults to `"latest"` when omitted.
411
- *
412
- * @see {@link (Increments:type)}
413
- */
414
- readonly increments?: Increments;
415
- /**
416
- * Reference date used when evaluating Node.js lifecycle phases. Releases
417
- * whose LTS or end-of-life boundaries fall relative to this date are
418
- * classified accordingly.
419
- *
420
- * When omitted the current wall-clock date is used.
421
- */
422
- readonly date?: Date;
423
- }
424
- /**
425
- * Union of all typed errors that `NodeResolver.resolve` can fail with.
426
- *
427
- * @see {@link VersionNotFoundError}
428
- *
429
- * @public
430
- */
431
- type NodeResolverError = VersionNotFoundError;
432
- declare const NodeResolver_base: Context.TagClass<NodeResolver, "runtime-resolver/NodeResolver", {
433
- /**
434
- * Resolves Node.js versions according to `options` and returns a
435
- * {@link (ResolvedVersions:type)} object containing the matching version list,
436
- * the latest version string, optional LTS version string, and the data
437
- * source indicator.
438
- *
439
- * Fails with {@link NodeResolverError} when no version can be resolved and
440
- * no `defaultVersion` was provided.
441
- *
442
- * @param options - Optional resolution constraints.
443
- *
444
- * @see {@link NodeResolverOptions}
445
- */
446
- readonly resolve: (options?: NodeResolverOptions) => Effect.Effect<ResolvedVersions, NodeResolverError>;
447
- }>;
448
- /**
449
- * Service for resolving Node.js runtime versions against the cached
450
- * release index.
451
- *
452
- * Unlike {@link BunResolver} and {@link DenoResolver}, this service is
453
- * lifecycle-aware: results can be filtered by {@link (NodePhase:type)} and evaluated
454
- * against a specific reference date.
455
- *
456
- * For a one-shot Promise-based API see {@link resolveNode}.
457
- *
458
- * @example
459
- * ```typescript
460
- * import type { ResolvedVersions } from "runtime-resolver";
461
- * import { NodeResolver, NodeResolverLive } from "runtime-resolver";
462
- * import { Effect } from "effect";
463
- *
464
- * const program = Effect.gen(function* () {
465
- * const resolver = yield* NodeResolver;
466
- * const result = yield* resolver.resolve({
467
- * semverRange: "^20.0.0",
468
- * phases: ["active-lts"],
469
- * increments: "minor",
470
- * });
471
- * console.log(result.latest);
472
- * console.log(result.lts);
473
- * });
474
- *
475
- * Effect.runPromise(program.pipe(Effect.provide(NodeResolverLive)));
476
- * ```
477
- *
478
- * @see {@link NodeResolverLive}
479
- * @see {@link resolveNode}
480
- * @see {@link NodeResolverOptions}
481
- * @see {@link (ResolvedVersions:type)}
482
- *
483
- * @public
484
- */
485
- declare class NodeResolver extends NodeResolver_base {}
486
- //#endregion
487
- //#region src/errors/AuthenticationError.d.ts
488
- declare const AuthenticationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
489
- readonly _tag: "AuthenticationError";
490
- } & Readonly<A>;
491
- /**
492
- * Raised when a GitHub authentication attempt fails.
493
- *
494
- * This error is produced by the {@link GitHubTokenAuth} and
495
- * {@link GitHubAppAuth} layers when the supplied credentials are rejected by
496
- * the GitHub API or when required configuration values (e.g. a token or app
497
- * private key) are missing from the environment.
498
- *
499
- * @see {@link GitHubTokenAuth}
500
- * @see {@link GitHubAppAuth}
501
- *
502
- * @example
503
- * ```typescript
504
- * import { Effect } from "effect";
505
- * import type { AuthenticationError } from "./AuthenticationError.js";
506
- * import { resolveNode } from "../resolvers/node.js";
507
- *
508
- * const program = resolveNode(">=20").pipe(
509
- * Effect.catchTag("AuthenticationError", (err: AuthenticationError) =>
510
- * Effect.logError(
511
- * `Auth failed via ${err.method}: ${err.message}`
512
- * ).pipe(Effect.andThen(Effect.fail(err)))
513
- * )
514
- * );
515
- * ```
516
- *
517
- * @public
518
- */
519
- declare class AuthenticationError extends AuthenticationError_base<{
520
- readonly method: "token" | "app";
521
- readonly message: string;
522
- }> {}
523
- //#endregion
524
- //#region src/errors/CacheError.d.ts
525
- declare const CacheError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
526
- readonly _tag: "CacheError";
527
- } & Readonly<A>;
528
- /**
529
- * Raised when a cache read or write operation fails.
530
- *
531
- * This error surfaces when the local on-disk version cache cannot be accessed
532
- * or updated. The `operation` field distinguishes between failures that occur
533
- * while loading cached data (`"read"`) and failures that occur while
534
- * persisting new data (`"write"`).
535
- *
536
- * @example
537
- * ```typescript
538
- * import { Effect } from "effect";
539
- * import type { CacheError } from "./CacheError.js";
540
- * import { resolveNode } from "../resolvers/node.js";
541
- *
542
- * const program = resolveNode(">=20").pipe(
543
- * Effect.catchTag("CacheError", (err: CacheError) =>
544
- * Effect.logWarning(
545
- * `Cache ${err.operation} failed: ${err.message}`
546
- * ).pipe(Effect.andThen(Effect.fail(err)))
547
- * )
548
- * );
549
- * ```
550
- *
551
- * @public
552
- */
553
- declare class CacheError extends CacheError_base<{
554
- readonly operation: "read" | "write";
555
- readonly message: string;
556
- }> {}
557
- //#endregion
558
- //#region src/errors/FreshnessError.d.ts
559
- declare const FreshnessError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
560
- readonly _tag: "FreshnessError";
561
- } & Readonly<A>;
562
- /**
563
- * Raised when a cache freshness check cannot be completed.
564
- *
565
- * Each runtime cache layer ({@link FreshBunCacheLive}, {@link FreshDenoCacheLive},
566
- * {@link FreshNodeCacheLive}) validates whether locally stored version data is
567
- * still current before returning it. This error is produced when that
568
- * validation fails — for example, when the upstream API is unreachable during
569
- * an `"api"` freshness check, or when the cached timestamp is corrupt during
570
- * an `"auto"` or `"cache"` check.
571
- *
572
- * @see {@link FreshBunCacheLive}
573
- * @see {@link FreshDenoCacheLive}
574
- * @see {@link FreshNodeCacheLive}
575
- *
576
- * @example
577
- * ```typescript
578
- * import { Effect } from "effect";
579
- * import type { FreshnessError } from "./FreshnessError.js";
580
- * import { resolveNode } from "../resolvers/node.js";
581
- *
582
- * const program = resolveNode(">=20").pipe(
583
- * Effect.catchTag("FreshnessError", (err: FreshnessError) =>
584
- * Effect.logWarning(
585
- * `Freshness check (${err.strategy}) failed: ${err.message}`
586
- * ).pipe(Effect.andThen(Effect.fail(err)))
587
- * )
588
- * );
589
- * ```
590
- *
591
- * @public
592
- */
593
- declare class FreshnessError extends FreshnessError_base<{
594
- readonly strategy: "auto" | "api" | "cache";
595
- readonly message: string;
596
- }> {}
597
- //#endregion
598
- //#region src/errors/InvalidInputError.d.ts
599
- declare const InvalidInputError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
600
- readonly _tag: "InvalidInputError";
601
- } & Readonly<A>;
602
- /**
603
- * Raised when a caller-supplied value fails validation.
604
- *
605
- * This error is produced at the boundary where user-provided inputs (such as
606
- * version constraint strings or runtime identifiers) are decoded against their
607
- * expected schemas. The `field` identifies which input was invalid, `value`
608
- * carries the raw string that was rejected, and `message` explains the
609
- * specific violation.
610
- *
611
- * @example
612
- * ```typescript
613
- * import { Effect } from "effect";
614
- * import type { InvalidInputError } from "./InvalidInputError.js";
615
- * import { resolveNode } from "../resolvers/node.js";
616
- *
617
- * const program = resolveNode("not-a-semver-range").pipe(
618
- * Effect.catchTag("InvalidInputError", (err: InvalidInputError) =>
619
- * Effect.logError(
620
- * `Invalid value for "${err.field}": ${err.value} — ${err.message}`
621
- * ).pipe(Effect.andThen(Effect.fail(err)))
622
- * )
623
- * );
624
- * ```
625
- *
626
- * @public
627
- */
628
- declare class InvalidInputError extends InvalidInputError_base<{
629
- readonly field: string;
630
- readonly value: string;
631
- readonly message: string;
632
- }> {}
633
- //#endregion
634
- //#region src/errors/NetworkError.d.ts
635
- declare const NetworkError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
636
- readonly _tag: "NetworkError";
637
- } & Readonly<A>;
638
- /**
639
- * Raised when an HTTP request to an upstream API fails.
640
- *
641
- * This error is produced when a fetch to a runtime release API (e.g. the
642
- * Node.js release index, the Deno release feed, or the Bun GitHub releases
643
- * endpoint) either does not receive a response or receives a non-successful
644
- * HTTP status code. When a status code is available it is included in the
645
- * `status` field; for connection-level failures (timeouts, DNS errors) that
646
- * field is absent.
647
- *
648
- * @example
649
- * ```typescript
650
- * import { Effect } from "effect";
651
- * import type { NetworkError } from "./NetworkError.js";
652
- * import { resolveNode } from "../resolvers/node.js";
653
- *
654
- * const program = resolveNode(">=20").pipe(
655
- * Effect.catchTag("NetworkError", (err: NetworkError) =>
656
- * Effect.logError(
657
- * `Request to ${err.url} failed${err.status != null ? ` with status ${err.status}` : ""}: ${err.message}`
658
- * ).pipe(Effect.andThen(Effect.fail(err)))
659
- * )
660
- * );
661
- * ```
662
- *
663
- * @public
664
- */
665
- declare class NetworkError extends NetworkError_base<{
666
- readonly url: string;
667
- readonly status?: number;
668
- readonly message: string;
669
- }> {}
670
- //#endregion
671
- //#region src/errors/ParseError.d.ts
672
- declare const ParseError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
673
- readonly _tag: "ParseError";
674
- } & Readonly<A>;
675
- /**
676
- * Raised when the body of an upstream API response cannot be decoded.
677
- *
678
- * This error is produced after a successful HTTP response is received but
679
- * its payload does not match the expected shape — for example, when a release
680
- * index returns malformed JSON or when a required field is missing from the
681
- * response structure. The `source` field identifies the URL or data source
682
- * that produced the unparseable content.
683
- *
684
- * @example
685
- * ```typescript
686
- * import { Effect } from "effect";
687
- * import type { ParseError } from "./ParseError.js";
688
- * import { resolveNode } from "../resolvers/node.js";
689
- *
690
- * const program = resolveNode(">=20").pipe(
691
- * Effect.catchTag("ParseError", (err: ParseError) =>
692
- * Effect.logError(
693
- * `Failed to parse response from ${err.source}: ${err.message}`
694
- * ).pipe(Effect.andThen(Effect.fail(err)))
695
- * )
696
- * );
697
- * ```
698
- *
699
- * @public
700
- */
701
- declare class ParseError extends ParseError_base<{
702
- readonly source: string;
703
- readonly message: string;
704
- }> {}
705
- //#endregion
706
- //#region src/errors/RateLimitError.d.ts
707
- declare const RateLimitError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
708
- readonly _tag: "RateLimitError";
709
- } & Readonly<A>;
710
- /**
711
- * Raised when a GitHub API rate limit is exceeded.
712
- *
713
- * The `limit` and `remaining` fields reflect the values returned in the
714
- * `X-RateLimit-Limit` and `X-RateLimit-Remaining` response headers. When the
715
- * API indicates how long to wait before the quota resets, that duration (in
716
- * seconds) is available via `retryAfter`.
717
- *
718
- * Use `retryOnRateLimit` to automatically retry an effect with
719
- * exponential backoff whenever this error is encountered.
720
- *
721
- * @example
722
- * ```typescript
723
- * import { Effect } from "effect";
724
- * import type { RateLimitError } from "./RateLimitError.js";
725
- * import { resolveNode } from "../resolvers/node.js";
726
- *
727
- * const program = resolveNode(">=20").pipe(
728
- * Effect.catchTag("RateLimitError", (err: RateLimitError) =>
729
- * Effect.logWarning(
730
- * `Rate limit hit (${err.remaining}/${err.limit} remaining)` +
731
- * (err.retryAfter != null ? `, retry after ${err.retryAfter}s` : "") +
732
- * `: ${err.message}`
733
- * ).pipe(Effect.andThen(Effect.fail(err)))
734
- * )
735
- * );
736
- * ```
737
- *
738
- * @public
739
- */
740
- declare class RateLimitError extends RateLimitError_base<{
741
- readonly retryAfter?: number;
742
- readonly limit: number;
743
- readonly remaining: number;
744
- readonly message: string;
745
- }> {}
746
- //#endregion
747
- //#region src/schemas/runtime-release.d.ts
748
- /**
749
- * Structural base constraint shared by {@link BunRelease}, {@link DenoRelease},
750
- * and {@link NodeRelease}.
751
- *
752
- * Enables the generic `RuntimeCache<R extends RuntimeRelease>` service to
753
- * operate over any runtime release type without coupling to a concrete class.
754
- *
755
- * @see {@link RuntimeCache}
756
- * @see {@link BunRelease}
757
- * @see {@link DenoRelease}
758
- * @see {@link NodeRelease}
759
- *
760
- * @public
761
- */
762
- interface RuntimeRelease {
763
- readonly _tag: string;
764
- readonly version: SemVer;
765
- readonly date: DateTime.DateTime;
766
- }
767
- /**
768
- * Lean input schema used to construct {@link BunRelease} and
769
- * {@link DenoRelease} instances from bundled default data files.
770
- *
771
- * Both Bun and Deno source their offline snapshots from JSON/TS data files
772
- * whose entries conform to this shape. The `version` and `date` fields are
773
- * plain strings that are subsequently parsed by `SemVer.parse` and
774
- * `DateTime.unsafeMake` respectively.
775
- *
776
- * @see {@link BunRelease.fromInput}
777
- * @see {@link DenoRelease.fromInput}
778
- *
779
- * @public
780
- */
781
- declare const RuntimeReleaseInput: Schema.Struct<{
782
- version: typeof Schema.String;
783
- date: typeof Schema.String;
784
- }>;
785
- /**
786
- * Lean input type used to construct {@link BunRelease} and {@link DenoRelease}
787
- * instances from bundled default data files.
788
- *
789
- * @see {@link BunRelease.fromInput}
790
- * @see {@link DenoRelease.fromInput}
791
- *
792
- * @public
793
- */
794
- type RuntimeReleaseInput = typeof RuntimeReleaseInput.Type;
795
- //#endregion
796
- //#region src/schemas/bun-release.d.ts
797
- declare const BunRelease_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Readonly<A> & {
798
- readonly _tag: "BunRelease";
799
- };
800
- /**
801
- * A Bun release entry with a parsed `SemVer` version and an
802
- * Effect `DateTime.DateTime` publication date.
803
- *
804
- * `BunRelease` extends `Data.TaggedClass` so instances support structural
805
- * equality comparison and can be used safely inside Effect data structures.
806
- * Construct instances via the {@link BunRelease.fromInput} factory rather than
807
- * calling `new BunRelease(...)` directly, as the factory validates the version
808
- * string through `SemVer.parse`.
809
- *
810
- * @see {@link BunReleaseCache}
811
- * @see {@link BunResolver}
812
- * @see `RuntimeReleaseInput`
813
- *
814
- * @example
815
- * ```typescript
816
- * import { Effect } from "effect";
817
- * import type { BunRelease } from "./bun-release.js";
818
- * import { BunRelease as BunReleaseClass } from "./bun-release.js";
819
- *
820
- * const program = BunReleaseClass.fromInput({ version: "1.1.0", date: "2024-03-01" }).pipe(
821
- * Effect.map((release: BunRelease) => {
822
- * console.log(release.version.major); // 1
823
- * console.log(release.version.minor); // 1
824
- * console.log(release._tag); // "BunRelease"
825
- * }),
826
- * );
827
- *
828
- * Effect.runPromise(program);
829
- * ```
830
- *
831
- * @public
832
- */
833
- declare class BunRelease extends BunRelease_base<{
834
- readonly version: SemVer;
835
- readonly date: DateTime.DateTime;
836
- }> {
837
- /**
838
- * Create a {@link BunRelease} from lean string inputs.
839
- *
840
- * Parses `input.version` via `SemVer.parse` and constructs the
841
- * publication date with `DateTime.unsafeMake`. Falls back to the current
842
- * timestamp when `input.date` is an empty string (rare in production data).
843
- *
844
- * @param input - A `RuntimeReleaseInput` object with raw string fields.
845
- * @returns An `Effect` that succeeds with a `BunRelease` or fails with an
846
- * `InvalidVersionError` when the version string cannot be parsed.
847
- */
848
- static fromInput(input: RuntimeReleaseInput): Effect.Effect<BunRelease, InvalidVersionError>;
849
- }
850
- //#endregion
851
- //#region src/services/RuntimeCache.d.ts
852
- /**
853
- * Generic in-memory cache service for a typed runtime release collection,
854
- * built on top of semver-effect's version cache primitives.
855
- *
856
- * Concrete instantiations are {@link BunReleaseCache}, {@link DenoReleaseCache},
857
- * and {@link NodeReleaseCache}. The canonical factory function for obtaining a
858
- * `RuntimeCache` implementation is {@link createRuntimeCache}.
859
- *
860
- * @typeParam R - A {@link RuntimeRelease} subtype specific to the runtime
861
- * (e.g. `BunRelease`, `DenoRelease`, `NodeRelease`).
862
- *
863
- * @example
864
- * ```typescript
865
- * import type { BunRelease } from "runtime-resolver";
866
- * import { BunReleaseCache, OfflineBunCacheLive } from "runtime-resolver";
867
- * import { Effect } from "effect";
868
- *
869
- * const program = Effect.gen(function* () {
870
- * const cache = yield* BunReleaseCache;
871
- * const latest = yield* cache.latest();
872
- * console.log(latest.version.toString());
873
- * });
874
- *
875
- * Effect.runPromise(program.pipe(Effect.provide(OfflineBunCacheLive)));
876
- * ```
877
- *
878
- * @see {@link BunReleaseCache}
879
- * @see {@link DenoReleaseCache}
880
- * @see {@link NodeReleaseCache}
881
- * @see {@link createRuntimeCache}
882
- *
883
- * @public
884
- */
885
- interface RuntimeCache<R extends RuntimeRelease> {
886
- /**
887
- * Populates the cache with the given array of typed release objects,
888
- * replacing any previously loaded entries.
889
- *
890
- * @param releases - The full set of releases to store.
891
- */
892
- readonly load: (releases: ReadonlyArray<R>) => Effect.Effect<void>;
893
- /**
894
- * Finds the single best-matching release for the given semver range string,
895
- * preferring the highest satisfying version.
896
- *
897
- * Fails with `InvalidRangeError` when `range` is not a valid semver
898
- * range expression, or with `UnsatisfiedRangeError` when no cached
899
- * release satisfies the range.
900
- *
901
- * @param range - A semver range string (e.g. `">=1.0.0 <2.0.0"`).
902
- */
903
- readonly resolve: (range: string) => Effect.Effect<R, InvalidRangeError | UnsatisfiedRangeError>;
904
- /**
905
- * Returns the complete list of all releases currently held in the cache,
906
- * in the order they were loaded.
907
- */
908
- readonly releases: () => Effect.Effect<ReadonlyArray<R>>;
909
- /**
910
- * Returns all cached releases whose version satisfies the given semver
911
- * range string.
912
- *
913
- * Fails with `InvalidRangeError` when `range` is not a valid semver
914
- * range expression.
915
- *
916
- * @param range - A semver range string (e.g. `"^20.0.0"`).
917
- */
918
- readonly filter: (range: string) => Effect.Effect<ReadonlyArray<R>, InvalidRangeError>;
919
- /**
920
- * Returns the release with the highest version among all entries in the
921
- * cache.
922
- *
923
- * Fails with `EmptyCacheError` when the cache contains no releases.
924
- */
925
- readonly latest: () => Effect.Effect<R, EmptyCacheError>;
926
- /**
927
- * Returns one release per major version line, each being the highest
928
- * available version within that major line.
929
- *
930
- * Returns an empty array when the cache is empty.
931
- */
932
- readonly latestByMajor: () => Effect.Effect<ReadonlyArray<R>>;
933
- /**
934
- * Returns one release per minor version line, each being the highest
935
- * available patch version within that minor line.
936
- *
937
- * Returns an empty array when the cache is empty.
938
- */
939
- readonly latestByMinor: () => Effect.Effect<ReadonlyArray<R>>;
940
- }
941
- //#endregion
942
- //#region src/services/BunReleaseCache.d.ts
943
- declare const BunReleaseCache_base: Context.TagClass<BunReleaseCache, "runtime-resolver/BunReleaseCache", RuntimeCache<BunRelease>>;
944
- /**
945
- * Specialisation of {@link RuntimeCache} for Bun release objects.
946
- *
947
- * @example
948
- * ```typescript
949
- * import type { BunRelease } from "runtime-resolver";
950
- * import { BunReleaseCache, OfflineBunCacheLive } from "runtime-resolver";
951
- * import { Effect } from "effect";
952
- *
953
- * const program = Effect.gen(function* () {
954
- * const cache = yield* BunReleaseCache;
955
- * const releases = yield* cache.releases();
956
- * console.log(releases.length);
957
- * });
958
- *
959
- * Effect.runPromise(program.pipe(Effect.provide(OfflineBunCacheLive)));
960
- * ```
961
- *
962
- * @see {@link BunRelease}
963
- * @see {@link RuntimeCache}
964
- * @see {@link AutoBunCacheLive}
965
- * @see {@link FreshBunCacheLive}
966
- * @see {@link OfflineBunCacheLive}
967
- *
968
- * @public
969
- */
970
- declare class BunReleaseCache extends BunReleaseCache_base {}
971
- //#endregion
972
- //#region src/services/BunVersionFetcher.d.ts
973
- declare const BunVersionFetcher_base: Context.TagClass<BunVersionFetcher, "runtime-resolver/BunVersionFetcher", {
974
- /**
975
- * Fetches all available Bun releases from the GitHub API and returns both
976
- * the parsed semver version objects and the raw release input records.
977
- *
978
- * Fails with:
979
- * - {@link AuthenticationError} — missing or invalid GitHub credentials.
980
- * - {@link NetworkError} — the upstream request could not be completed.
981
- * - {@link ParseError} — the response payload could not be decoded.
982
- * - {@link RateLimitError} — the GitHub API rate limit was exceeded.
983
- */
984
- readonly fetch: () => Effect.Effect<{
985
- readonly versions: ReadonlyArray<SemVer>;
986
- readonly inputs: ReadonlyArray<RuntimeReleaseInput>;
987
- }, AuthenticationError | NetworkError | ParseError | RateLimitError>;
988
- }>;
989
- /**
990
- * Service for fetching Bun release data from the GitHub API.
991
- *
992
- * Retrieves both the parsed semver version list and the raw release input
993
- * records needed to populate a {@link BunReleaseCache}. The live
994
- * implementation queries the `oven-sh/bun` GitHub repository via
995
- * {@link GitHubClient}.
996
- *
997
- * @example
998
- * ```typescript
999
- * import type { RuntimeReleaseInput } from "runtime-resolver";
1000
- * import { BunVersionFetcher, BunVersionFetcherLive, GitHubAutoAuth } from "runtime-resolver";
1001
- * import { Effect } from "effect";
1002
- *
1003
- * const program = Effect.gen(function* () {
1004
- * const fetcher = yield* BunVersionFetcher;
1005
- * const { versions, inputs } = yield* fetcher.fetch();
1006
- * console.log(`Fetched ${versions.length} Bun releases`);
1007
- * });
1008
- *
1009
- * Effect.runPromise(
1010
- * program.pipe(Effect.provide(BunVersionFetcherLive), Effect.provide(GitHubAutoAuth)),
1011
- * );
1012
- * ```
1013
- *
1014
- * @see {@link BunVersionFetcherLive}
1015
- * @see {@link BunReleaseCache}
1016
- * @see {@link AuthenticationError}
1017
- * @see {@link NetworkError}
1018
- * @see {@link ParseError}
1019
- * @see {@link RateLimitError}
1020
- *
1021
- * @public
1022
- */
1023
- declare class BunVersionFetcher extends BunVersionFetcher_base {}
1024
- //#endregion
1025
- //#region src/layers/AutoBunCacheLive.d.ts
1026
- /**
1027
- * Provides the {@link BunReleaseCache} service using the "Auto" cache strategy.
1028
- *
1029
- * Attempts to fetch live release data from the GitHub API via
1030
- * {@link BunVersionFetcher}. If the fetch fails for any reason — authentication
1031
- * errors, network errors, parse errors, or rate-limit errors — it silently falls
1032
- * back to the bundled default release data so the layer always succeeds.
1033
- *
1034
- * Use this strategy when you want the freshest data when available but can
1035
- * tolerate slightly stale bundled data in degraded environments.
1036
- *
1037
- * The three Bun cache strategy layers are:
1038
- * - `AutoBunCacheLive` — tries API first, falls back to bundled defaults on any error
1039
- * - {@link FreshBunCacheLive} — requires live API data, fails with `FreshnessError` if unavailable
1040
- * - {@link OfflineBunCacheLive} — uses only bundled defaults, no network I/O
1041
- *
1042
- * @see {@link BunReleaseCache}
1043
- * @see {@link FreshBunCacheLive}
1044
- * @see {@link OfflineBunCacheLive}
1045
- * @public
1046
- */
1047
- declare const AutoBunCacheLive: Layer.Layer<BunReleaseCache, never, BunVersionFetcher>;
1048
- //#endregion
1049
- //#region src/schemas/deno-release.d.ts
1050
- declare const DenoRelease_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Readonly<A> & {
1051
- readonly _tag: "DenoRelease";
1052
- };
1053
- /**
1054
- * A Deno release entry with a parsed `SemVer` version and an
1055
- * Effect `DateTime.DateTime` publication date.
1056
- *
1057
- * `DenoRelease` extends `Data.TaggedClass` so instances support structural
1058
- * equality comparison and can be used safely inside Effect data structures.
1059
- * Construct instances via the {@link DenoRelease.fromInput} factory rather than
1060
- * calling `new DenoRelease(...)` directly, as the factory validates the version
1061
- * string through `SemVer.parse`.
1062
- *
1063
- * @see {@link DenoReleaseCache}
1064
- * @see {@link DenoResolver}
1065
- * @see `RuntimeReleaseInput`
1066
- *
1067
- * @example
1068
- * ```typescript
1069
- * import { Effect } from "effect";
1070
- * import type { DenoRelease } from "./deno-release.js";
1071
- * import { DenoRelease as DenoReleaseClass } from "./deno-release.js";
1072
- *
1073
- * const program = DenoReleaseClass.fromInput({ version: "1.44.0", date: "2024-05-23" }).pipe(
1074
- * Effect.map((release: DenoRelease) => {
1075
- * console.log(release.version.major); // 1
1076
- * console.log(release.version.minor); // 44
1077
- * console.log(release._tag); // "DenoRelease"
1078
- * }),
1079
- * );
1080
- *
1081
- * Effect.runPromise(program);
1082
- * ```
1083
- *
1084
- * @public
1085
- */
1086
- declare class DenoRelease extends DenoRelease_base<{
1087
- readonly version: SemVer;
1088
- readonly date: DateTime.DateTime;
1089
- }> {
1090
- /**
1091
- * Create a {@link DenoRelease} from lean string inputs.
1092
- *
1093
- * Parses `input.version` via `SemVer.parse` and constructs the
1094
- * publication date with `DateTime.unsafeMake`. Falls back to the current
1095
- * timestamp when `input.date` is an empty string (rare in production data).
1096
- *
1097
- * @param input - A `RuntimeReleaseInput` object with raw string fields.
1098
- * @returns An `Effect` that succeeds with a `DenoRelease` or fails with an
1099
- * `InvalidVersionError` when the version string cannot be parsed.
1100
- */
1101
- static fromInput(input: RuntimeReleaseInput): Effect.Effect<DenoRelease, InvalidVersionError>;
1102
- }
1103
- //#endregion
1104
- //#region src/services/DenoReleaseCache.d.ts
1105
- declare const DenoReleaseCache_base: Context.TagClass<DenoReleaseCache, "runtime-resolver/DenoReleaseCache", RuntimeCache<DenoRelease>>;
1106
- /**
1107
- * Specialisation of {@link RuntimeCache} for Deno release objects.
1108
- *
1109
- * @example
1110
- * ```typescript
1111
- * import type { DenoRelease } from "runtime-resolver";
1112
- * import { DenoReleaseCache, OfflineDenoCacheLive } from "runtime-resolver";
1113
- * import { Effect } from "effect";
1114
- *
1115
- * const program = Effect.gen(function* () {
1116
- * const cache = yield* DenoReleaseCache;
1117
- * const latest = yield* cache.latest();
1118
- * console.log(latest.version.toString());
1119
- * });
1120
- *
1121
- * Effect.runPromise(program.pipe(Effect.provide(OfflineDenoCacheLive)));
1122
- * ```
1123
- *
1124
- * @see {@link DenoRelease}
1125
- * @see {@link RuntimeCache}
1126
- * @see {@link AutoDenoCacheLive}
1127
- * @see {@link FreshDenoCacheLive}
1128
- * @see {@link OfflineDenoCacheLive}
1129
- *
1130
- * @public
1131
- */
1132
- declare class DenoReleaseCache extends DenoReleaseCache_base {}
1133
- //#endregion
1134
- //#region src/services/DenoVersionFetcher.d.ts
1135
- declare const DenoVersionFetcher_base: Context.TagClass<DenoVersionFetcher, "runtime-resolver/DenoVersionFetcher", {
1136
- /**
1137
- * Fetches all available Deno releases from the GitHub API and returns both
1138
- * the parsed semver version objects and the raw release input records.
1139
- *
1140
- * Fails with:
1141
- * - {@link AuthenticationError} — missing or invalid GitHub credentials.
1142
- * - {@link NetworkError} — the upstream request could not be completed.
1143
- * - {@link ParseError} — the response payload could not be decoded.
1144
- * - {@link RateLimitError} — the GitHub API rate limit was exceeded.
1145
- */
1146
- readonly fetch: () => Effect.Effect<{
1147
- readonly versions: ReadonlyArray<SemVer>;
1148
- readonly inputs: ReadonlyArray<RuntimeReleaseInput>;
1149
- }, AuthenticationError | NetworkError | ParseError | RateLimitError>;
1150
- }>;
1151
- /**
1152
- * Service for fetching Deno release data from the GitHub API.
1153
- *
1154
- * Retrieves both the parsed semver version list and the raw release input
1155
- * records needed to populate a {@link DenoReleaseCache}. The live
1156
- * implementation queries the `denoland/deno` GitHub repository via
1157
- * {@link GitHubClient}.
1158
- *
1159
- * @example
1160
- * ```typescript
1161
- * import type { RuntimeReleaseInput } from "runtime-resolver";
1162
- * import { DenoVersionFetcher, DenoVersionFetcherLive, GitHubAutoAuth } from "runtime-resolver";
1163
- * import { Effect } from "effect";
1164
- *
1165
- * const program = Effect.gen(function* () {
1166
- * const fetcher = yield* DenoVersionFetcher;
1167
- * const { versions, inputs } = yield* fetcher.fetch();
1168
- * console.log(`Fetched ${versions.length} Deno releases`);
1169
- * });
1170
- *
1171
- * Effect.runPromise(
1172
- * program.pipe(Effect.provide(DenoVersionFetcherLive), Effect.provide(GitHubAutoAuth)),
1173
- * );
1174
- * ```
1175
- *
1176
- * @see {@link DenoVersionFetcherLive}
1177
- * @see {@link DenoReleaseCache}
1178
- * @see {@link AuthenticationError}
1179
- * @see {@link NetworkError}
1180
- * @see {@link ParseError}
1181
- * @see {@link RateLimitError}
1182
- *
1183
- * @public
1184
- */
1185
- declare class DenoVersionFetcher extends DenoVersionFetcher_base {}
1186
- //#endregion
1187
- //#region src/layers/AutoDenoCacheLive.d.ts
1188
- /**
1189
- * Provides the {@link DenoReleaseCache} service using the "Auto" cache strategy.
1190
- *
1191
- * Attempts to fetch live release data from the GitHub API via
1192
- * {@link DenoVersionFetcher}. If the fetch fails for any reason — authentication
1193
- * errors, network errors, parse errors, or rate-limit errors — it silently falls
1194
- * back to the bundled default release data so the layer always succeeds.
1195
- *
1196
- * Use this strategy when you want the freshest data when available but can
1197
- * tolerate slightly stale bundled data in degraded environments.
1198
- *
1199
- * The three Deno cache strategy layers are:
1200
- * - `AutoDenoCacheLive` — tries API first, falls back to bundled defaults on any error
1201
- * - {@link FreshDenoCacheLive} — requires live API data, fails with `FreshnessError` if unavailable
1202
- * - {@link OfflineDenoCacheLive} — uses only bundled defaults, no network I/O
1203
- *
1204
- * @see {@link DenoReleaseCache}
1205
- * @see {@link FreshDenoCacheLive}
1206
- * @see {@link OfflineDenoCacheLive}
1207
- * @public
1208
- */
1209
- declare const AutoDenoCacheLive: Layer.Layer<DenoReleaseCache, never, DenoVersionFetcher>;
1210
- //#endregion
1211
- //#region src/schemas/node-schedule.d.ts
1212
- /**
1213
- * A single entry in the Node.js release schedule, representing one major
1214
- * release line's lifecycle dates and optional LTS codename.
1215
- *
1216
- * All date fields have already been converted from ISO strings to Effect
1217
- * `DateTime.DateTime` values by {@link NodeSchedule.fromData}.
1218
- *
1219
- * @see {@link NodeSchedule}
1220
- * @see {@link NodeSchedule.phaseFor}
1221
- *
1222
- * @public
1223
- */
1224
- interface NodeScheduleEntry {
1225
- readonly major: number;
1226
- readonly start: DateTime.DateTime;
1227
- readonly lts: DateTime.DateTime | null;
1228
- readonly maintenance: DateTime.DateTime | null;
1229
- readonly end: DateTime.DateTime;
1230
- readonly codename: string;
1231
- }
1232
- /**
1233
- * Raw schedule format as fetched from the Node.js Release GitHub repository
1234
- * (`nodejs/Release`).
1235
- *
1236
- * This is the intermediate type between the {@link NodeScheduleFetcher} layer
1237
- * and the {@link NodeSchedule} class. Date values are plain ISO strings; the
1238
- * `NodeSchedule.fromData` factory converts them to `DateTime`.
1239
- *
1240
- * @see {@link NodeSchedule.fromData}
1241
- * @see {@link NodeScheduleFetcher}
1242
- *
1243
- * @public
1244
- */
1245
- type NodeScheduleData = Record<string, {
1246
- readonly start: string;
1247
- readonly lts?: string;
1248
- readonly maintenance?: string;
1249
- readonly end: string;
1250
- readonly codename?: string;
1251
- }>;
1252
- declare const NodeSchedule_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Readonly<A> & {
1253
- readonly _tag: "NodeSchedule";
1254
- };
1255
- /**
1256
- * Immutable snapshot of the Node.js release schedule.
1257
- *
1258
- * Holds a `ReadonlyArray<NodeScheduleEntry>` parsed from the raw
1259
- * {@link NodeScheduleData} fetched by {@link NodeScheduleFetcher}. A single
1260
- * `NodeSchedule` instance lives inside a `Ref<NodeSchedule>` that is shared
1261
- * across all {@link NodeRelease} instances so that schedule updates propagate
1262
- * without rebuilding the release cache.
1263
- *
1264
- * `NodeSchedule` extends `Data.TaggedClass` and therefore supports structural
1265
- * equality — two schedules built from identical data compare as equal.
1266
- *
1267
- * @see {@link NodeRelease}
1268
- * @see {@link NodeScheduleFetcher}
1269
- *
1270
- * @example
1271
- * ```typescript
1272
- * import { Effect } from "effect";
1273
- * import type { NodePhase } from "./common.js";
1274
- * import type { NodeScheduleData } from "./node-schedule.js";
1275
- * import { NodeSchedule } from "./node-schedule.js";
1276
- *
1277
- * const data: NodeScheduleData = {
1278
- * v20: {
1279
- * start: "2023-04-18",
1280
- * lts: "2023-10-24",
1281
- * maintenance: "2024-10-22",
1282
- * end: "2026-04-30",
1283
- * codename: "Iron",
1284
- * },
1285
- * };
1286
- *
1287
- * const schedule = NodeSchedule.fromData(data);
1288
- *
1289
- * const program = schedule.phaseFor(20, new Date("2024-01-01") as any).pipe(
1290
- * Effect.map((phase: NodePhase | null) => {
1291
- * console.log(phase); // "active-lts"
1292
- * }),
1293
- * );
1294
- *
1295
- * Effect.runPromise(program);
1296
- * ```
1297
- *
1298
- * @public
1299
- */
1300
- declare class NodeSchedule extends NodeSchedule_base<{
1301
- readonly entries: ReadonlyArray<NodeScheduleEntry>;
1302
- }> {
1303
- /**
1304
- * Parse raw {@link NodeScheduleData} into a `NodeSchedule` instance.
1305
- *
1306
- * Iterates over every key of the form `"vNN"`, converts ISO date strings
1307
- * to `DateTime.DateTime`, and normalises missing codenames to `""`.
1308
- *
1309
- * @param data - The raw JSON object fetched from the Node.js release repo.
1310
- * @returns A fully constructed, immutable `NodeSchedule`.
1311
- */
1312
- static fromData(data: NodeScheduleData): NodeSchedule;
1313
- /**
1314
- * Determine the current {@link (NodePhase:type)} for a given major version number
1315
- * at the specified point in time.
1316
- *
1317
- * Returns `null` when the major is not present in the schedule or when
1318
- * `now` is before the release's start date.
1319
- *
1320
- * @param major - The Node.js major version number (e.g. `20`).
1321
- * @param now - The reference `DateTime` against which phases are evaluated.
1322
- */
1323
- phaseFor(major: number, now: DateTime.DateTime): Effect.Effect<NodePhase | null>;
1324
- /**
1325
- * Look up the {@link NodeScheduleEntry} for a given major version number.
1326
- *
1327
- * Returns `Option.none()` when the major is not present in the schedule.
1328
- *
1329
- * @param major - The Node.js major version number (e.g. `20`).
1330
- */
1331
- entryFor(major: number): Option.Option<NodeScheduleEntry>;
1332
- }
1333
- //#endregion
1334
- //#region src/schemas/node-release.d.ts
1335
- /**
1336
- * Lean input schema used to construct {@link NodeRelease} instances from
1337
- * bundled default data files and the Node.js dist API response.
1338
- *
1339
- * The `version` and `npm` fields are raw version strings validated by
1340
- * `SemVer.parse`; `date` is a date string accepted by
1341
- * `DateTime.unsafeMake`.
1342
- *
1343
- * @see {@link NodeRelease.fromInput}
1344
- * @see {@link NodeVersionFetcher}
1345
- *
1346
- * @public
1347
- */
1348
- declare const NodeReleaseInput: Schema.Struct<{
1349
- version: typeof Schema.String;
1350
- npm: typeof Schema.String;
1351
- date: typeof Schema.String;
1352
- }>;
1353
- /**
1354
- * Lean input type used to construct {@link NodeRelease} instances.
1355
- *
1356
- * @see {@link NodeRelease.fromInput}
1357
- *
1358
- * @public
1359
- */
1360
- type NodeReleaseInput = typeof NodeReleaseInput.Type;
1361
- /**
1362
- * A Node.js release entry with parsed version, bundled npm version,
1363
- * publication date, and a shared reference to the Node.js release schedule.
1364
- *
1365
- * `NodeRelease` is a plain class rather than a `Data.TaggedClass` because it
1366
- * holds a `Ref<NodeSchedule>` — mutable Effect references break structural
1367
- * equality semantics, making `Data.TaggedClass` unsuitable here. The
1368
- * `_tag` field is set manually to preserve tagged-union compatibility.
1369
- *
1370
- * Use {@link NodeRelease.fromInput} to construct instances; call
1371
- * {@link NodeRelease.phase} or {@link NodeRelease.lts} to query the lifecycle
1372
- * state of the release at a given point in time.
1373
- *
1374
- * @see {@link NodeReleaseCache}
1375
- * @see {@link NodeResolver}
1376
- * @see {@link NodeSchedule}
1377
- *
1378
- * @example
1379
- * ```typescript
1380
- * import { Effect, Ref } from "effect";
1381
- * import type { NodePhase } from "./common.js";
1382
- * import type { NodeRelease } from "./node-release.js";
1383
- * import { NodeRelease as NodeReleaseClass } from "./node-release.js";
1384
- * import { NodeSchedule } from "./node-schedule.js";
1385
- *
1386
- * const program = Effect.gen(function* () {
1387
- * const schedule = NodeSchedule.fromData({
1388
- * v20: { start: "2023-04-18", lts: "2023-10-24", end: "2026-04-30" },
1389
- * });
1390
- * const scheduleRef = yield* Ref.make(schedule);
1391
- *
1392
- * const release: NodeRelease = yield* NodeReleaseClass.fromInput(
1393
- * { version: "v20.0.0", npm: "9.6.4", date: "2023-04-18" },
1394
- * scheduleRef,
1395
- * );
1396
- *
1397
- * const phase: NodePhase | null = yield* release.phase();
1398
- * const isLts: boolean = yield* release.lts();
1399
- * console.log(phase); // e.g. "active-lts"
1400
- * console.log(isLts); // true
1401
- * });
1402
- *
1403
- * Effect.runPromise(program);
1404
- * ```
1405
- *
1406
- * @public
1407
- */
1408
- declare class NodeRelease {
1409
- readonly version: SemVer;
1410
- readonly npm: SemVer;
1411
- readonly date: DateTime.DateTime;
1412
- readonly scheduleRef: Ref.Ref<NodeSchedule>;
1413
- readonly _tag: "NodeRelease";
1414
- constructor(version: SemVer, npm: SemVer, date: DateTime.DateTime, scheduleRef: Ref.Ref<NodeSchedule>);
1415
- /**
1416
- * Determine this release's lifecycle phase at the given point in time.
1417
- *
1418
- * Reads the current value of the shared `scheduleRef` and delegates to
1419
- * {@link NodeSchedule.phaseFor}. Defaults to the current wall-clock time
1420
- * when `now` is omitted.
1421
- *
1422
- * @param now - Optional reference time; defaults to `new Date()`.
1423
- * @returns An `Effect` that resolves to a `NodePhase` string, or
1424
- * `null` when the major version is not present in the schedule or has
1425
- * not yet been released.
1426
- */
1427
- phase(now?: DateTime.DateTime): Effect.Effect<NodePhase | null>;
1428
- /**
1429
- * Whether this release is currently in Long-Term Support.
1430
- *
1431
- * Returns `true` for both `"active-lts"` and `"maintenance-lts"` phases.
1432
- * Defaults to the current wall-clock time when `now` is omitted.
1433
- *
1434
- * @param now - Optional reference time; defaults to `new Date()`.
1435
- */
1436
- lts(now?: DateTime.DateTime): Effect.Effect<boolean>;
1437
- /**
1438
- * Create a {@link NodeRelease} from lean string inputs.
1439
- *
1440
- * Parses `input.version` and `input.npm` via `SemVer.parse` and
1441
- * constructs the publication date with `DateTime.unsafeMake`.
1442
- *
1443
- * @param input - A {@link (NodeReleaseInput:type)} object with raw string fields.
1444
- * @param scheduleRef - A shared `Ref<NodeSchedule>` injected by the cache layer.
1445
- * @returns An `Effect` that succeeds with a `NodeRelease` or fails with an
1446
- * `InvalidVersionError` when either version string cannot be parsed.
1447
- */
1448
- static fromInput(input: NodeReleaseInput, scheduleRef: Ref.Ref<NodeSchedule>): Effect.Effect<NodeRelease, InvalidVersionError>;
1449
- }
1450
- //#endregion
1451
- //#region src/services/NodeReleaseCache.d.ts
1452
- declare const NodeReleaseCache_base: Context.TagClass<NodeReleaseCache, "runtime-resolver/NodeReleaseCache", RuntimeCache<NodeRelease> & {
1453
- /**
1454
- * Merges Node.js release-schedule data into the cache, updating lifecycle
1455
- * phase information (LTS dates, end-of-life dates, etc.) for every major
1456
- * release line.
1457
- *
1458
- * @param data - Parsed schedule payload, typically fetched via
1459
- * {@link NodeScheduleFetcher}.
1460
- *
1461
- * @see {@link NodeScheduleData}
1462
- */
1463
- readonly updateSchedule: (data: NodeScheduleData) => Effect.Effect<void>;
1464
- /**
1465
- * Populates the cache from raw {@link (NodeReleaseInput:type)} records (as
1466
- * returned by the Node.js release index JSON) rather than from already-
1467
- * decoded {@link NodeRelease} objects.
1468
- *
1469
- * Prefer this over `load` when consuming data directly from the Node.js
1470
- * distribution server.
1471
- *
1472
- * @param inputs - An array of un-decoded release index entries.
1473
- *
1474
- * @see {@link (NodeReleaseInput:type)}
1475
- */
1476
- readonly loadFromInputs: (inputs: ReadonlyArray<NodeReleaseInput>) => Effect.Effect<void>;
1477
- /**
1478
- * Returns all cached releases whose lifecycle phase is `"active-lts"` or
1479
- * `"maintenance-lts"` as of the given point in time.
1480
- *
1481
- * When `now` is omitted the current wall-clock time is used.
1482
- *
1483
- * @param now - Optional reference timestamp for phase evaluation.
1484
- *
1485
- * @see {@link NodeRelease}
1486
- */
1487
- readonly ltsReleases: (now?: DateTime.DateTime) => Effect.Effect<ReadonlyArray<NodeRelease>>;
1488
- /**
1489
- * Returns all cached releases whose lifecycle phase is `"current"` as of
1490
- * the given point in time.
1491
- *
1492
- * When `now` is omitted the current wall-clock time is used.
1493
- *
1494
- * @param now - Optional reference timestamp for phase evaluation.
1495
- *
1496
- * @see {@link NodeRelease}
1497
- */
1498
- readonly currentReleases: (now?: DateTime.DateTime) => Effect.Effect<ReadonlyArray<NodeRelease>>;
1499
- }>;
1500
- /**
1501
- * Node.js-specific cache service that extends {@link RuntimeCache} with
1502
- * additional operations for lifecycle schedule data and LTS / current
1503
- * release filtering.
1504
- *
1505
- * Unlike the Bun and Deno equivalents this service is not a plain type alias
1506
- * — it adds four Node-specific methods on top of the generic cache contract.
1507
- *
1508
- * @example
1509
- * ```typescript
1510
- * import type { NodeRelease } from "runtime-resolver";
1511
- * import { NodeReleaseCache, OfflineNodeCacheLive } from "runtime-resolver";
1512
- * import { Effect } from "effect";
1513
- *
1514
- * const program = Effect.gen(function* () {
1515
- * const cache = yield* NodeReleaseCache;
1516
- * const lts = yield* cache.ltsReleases();
1517
- * for (const release of lts) {
1518
- * console.log(release.version.toString(), release.phase);
1519
- * }
1520
- * });
1521
- *
1522
- * Effect.runPromise(program.pipe(Effect.provide(OfflineNodeCacheLive)));
1523
- * ```
1524
- *
1525
- * @see {@link NodeRelease}
1526
- * @see {@link NodeScheduleData}
1527
- * @see {@link RuntimeCache}
1528
- * @see {@link AutoNodeCacheLive}
1529
- * @see {@link FreshNodeCacheLive}
1530
- * @see {@link OfflineNodeCacheLive}
1531
- *
1532
- * @public
1533
- */
1534
- declare class NodeReleaseCache extends NodeReleaseCache_base {}
1535
- //#endregion
1536
- //#region src/services/NodeScheduleFetcher.d.ts
1537
- declare const NodeScheduleFetcher_base: Context.TagClass<NodeScheduleFetcher, "runtime-resolver/NodeScheduleFetcher", {
1538
- /**
1539
- * Fetches and decodes the Node.js release schedule JSON, returning a
1540
- * typed {@link NodeScheduleData} map keyed by major release line.
1541
- *
1542
- * Fails with:
1543
- * - {@link NetworkError} — the upstream request could not be completed.
1544
- * - {@link ParseError} — the response payload could not be decoded.
1545
- */
1546
- readonly fetch: () => Effect.Effect<NodeScheduleData, NetworkError | ParseError>;
1547
- }>;
1548
- /**
1549
- * Service for fetching the official Node.js release schedule.
1550
- *
1551
- * The schedule maps each major release line to its LTS start date and
1552
- * end-of-life date, and is used by {@link NodeReleaseCache} to assign
1553
- * lifecycle phases to individual releases. The live implementation fetches
1554
- * from the `nodejs/Release` GitHub repository via a plain HTTP request.
1555
- *
1556
- * @example
1557
- * ```typescript
1558
- * import type { NodeScheduleData } from "runtime-resolver";
1559
- * import { NodeScheduleFetcher, NodeScheduleFetcherLive } from "runtime-resolver";
1560
- * import { Effect } from "effect";
1561
- *
1562
- * const program = Effect.gen(function* () {
1563
- * const fetcher = yield* NodeScheduleFetcher;
1564
- * const schedule = yield* fetcher.fetch();
1565
- * console.log(Object.keys(schedule).length, "major release lines");
1566
- * });
1567
- *
1568
- * Effect.runPromise(program.pipe(Effect.provide(NodeScheduleFetcherLive)));
1569
- * ```
1570
- *
1571
- * @see {@link NodeScheduleFetcherLive}
1572
- * @see {@link NodeReleaseCache}
1573
- * @see {@link NodeScheduleData}
1574
- * @see {@link NetworkError}
1575
- * @see {@link ParseError}
1576
- *
1577
- * @public
1578
- */
1579
- declare class NodeScheduleFetcher extends NodeScheduleFetcher_base {}
1580
- //#endregion
1581
- //#region src/services/NodeVersionFetcher.d.ts
1582
- declare const NodeVersionFetcher_base: Context.TagClass<NodeVersionFetcher, "runtime-resolver/NodeVersionFetcher", {
1583
- /**
1584
- * Fetches all available Node.js releases from the distribution index and
1585
- * returns both the parsed semver version objects and the raw release input
1586
- * records.
1587
- *
1588
- * Fails with:
1589
- * - {@link NetworkError} — the upstream request could not be completed.
1590
- * - {@link ParseError} — the response payload could not be decoded.
1591
- */
1592
- readonly fetch: () => Effect.Effect<{
1593
- readonly versions: ReadonlyArray<SemVer>;
1594
- readonly inputs: ReadonlyArray<NodeReleaseInput>;
1595
- }, NetworkError | ParseError>;
1596
- }>;
1597
- /**
1598
- * Service for fetching Node.js release data from the official
1599
- * Node.js distribution index.
1600
- *
1601
- * Retrieves both the parsed semver version list and the raw
1602
- * {@link (NodeReleaseInput:type)} records needed to populate a
1603
- * {@link NodeReleaseCache}. The live implementation fetches from
1604
- * `https://nodejs.org/dist/index.json` via a plain HTTP request — no GitHub
1605
- * credentials are required.
1606
- *
1607
- * @example
1608
- * ```typescript
1609
- * import type { NodeReleaseInput } from "runtime-resolver";
1610
- * import { NodeVersionFetcher, NodeVersionFetcherLive } from "runtime-resolver";
1611
- * import { Effect } from "effect";
1612
- *
1613
- * const program = Effect.gen(function* () {
1614
- * const fetcher = yield* NodeVersionFetcher;
1615
- * const { versions, inputs } = yield* fetcher.fetch();
1616
- * console.log(`Fetched ${versions.length} Node.js releases`);
1617
- * });
1618
- *
1619
- * Effect.runPromise(program.pipe(Effect.provide(NodeVersionFetcherLive)));
1620
- * ```
1621
- *
1622
- * @see {@link NodeVersionFetcherLive}
1623
- * @see {@link NodeReleaseCache}
1624
- * @see {@link NetworkError}
1625
- * @see {@link ParseError}
1626
- *
1627
- * @public
1628
- */
1629
- declare class NodeVersionFetcher extends NodeVersionFetcher_base {}
1630
- //#endregion
1631
- //#region src/layers/AutoNodeCacheLive.d.ts
1632
- /**
1633
- * Provides the {@link NodeReleaseCache} service using the "Auto" cache strategy.
1634
- *
1635
- * Attempts to fetch live release data from `nodejs.org/dist/index.json` via
1636
- * {@link NodeVersionFetcher} and the release schedule from the `nodejs/Release`
1637
- * repository via {@link NodeScheduleFetcher}. If either fetch fails — due to
1638
- * network errors or parse errors — the layer silently falls back to bundled
1639
- * default data (both version list and schedule) so it always succeeds.
1640
- *
1641
- * Node.js requires both a version fetcher and a schedule fetcher because LTS and
1642
- * maintenance phase information is tracked separately from the version index.
1643
- *
1644
- * The three Node cache strategy layers are:
1645
- * - `AutoNodeCacheLive` — tries API first, falls back to bundled defaults on any error
1646
- * - {@link FreshNodeCacheLive} — requires live API data, fails with `FreshnessError` if unavailable
1647
- * - {@link OfflineNodeCacheLive} — uses only bundled defaults, no network I/O
1648
- *
1649
- * @see {@link NodeReleaseCache}
1650
- * @see {@link FreshNodeCacheLive}
1651
- * @see {@link OfflineNodeCacheLive}
1652
- * @public
1653
- */
1654
- declare const AutoNodeCacheLive: Layer.Layer<NodeReleaseCache, never, NodeVersionFetcher | NodeScheduleFetcher>;
1655
- //#endregion
1656
- //#region src/layers/BunReleaseCacheLive.d.ts
1657
- /**
1658
- * Low-level layer that constructs the {@link BunReleaseCache} service backed by
1659
- * a `SemVerVersionCache` instance from `semver-effect`.
1660
- *
1661
- * This layer wires up the cache storage but does not populate it with any
1662
- * release data. Callers are responsible for loading releases after construction.
1663
- * In normal usage you should prefer the higher-level cache strategy layers
1664
- * instead of using this layer directly:
1665
- * - {@link AutoBunCacheLive} — API with fallback to bundled defaults
1666
- * - {@link FreshBunCacheLive} — API only, fails if unavailable
1667
- * - {@link OfflineBunCacheLive} — bundled defaults only
1668
- *
1669
- * @see {@link BunReleaseCache}
1670
- * @see {@link createRuntimeCache}
1671
- * @internal
1672
- */
1673
- declare const BunReleaseCacheLive: Layer.Layer<BunReleaseCache, never, VersionCache>;
1674
- //#endregion
1675
- //#region src/layers/BunResolverLive.d.ts
1676
- /**
1677
- * Provides the {@link BunResolver} service backed by a {@link BunReleaseCache}.
1678
- *
1679
- * This layer composes with any of the three Bun cache strategy layers to form
1680
- * a complete resolver stack. It implements semver range filtering and increment
1681
- * grouping (latest per major, latest per minor, or all patch versions) using
1682
- * the releases already loaded into the cache.
1683
- *
1684
- * @example
1685
- * ```ts
1686
- * import { BunResolverLive, AutoBunCacheLive, BunVersionFetcherLive, GitHubClientLive, GitHubAutoAuth } from "runtime-resolver";
1687
- * import type { ResolvedVersions } from "runtime-resolver";
1688
- * import { BunResolver } from "runtime-resolver";
1689
- * import { Effect, Layer } from "effect";
1690
- *
1691
- * const GitHubLayer = GitHubClientLive.pipe(Layer.provide(GitHubAutoAuth));
1692
- * const CacheLayer = AutoBunCacheLive.pipe(Layer.provide(BunVersionFetcherLive.pipe(Layer.provide(GitHubLayer))));
1693
- * const ResolverLayer = BunResolverLive.pipe(Layer.provide(CacheLayer));
1694
- *
1695
- * const program = Effect.gen(function* () {
1696
- * const resolver = yield* BunResolver;
1697
- * const result = yield* resolver.resolve({ semverRange: "^1.0.0" });
1698
- * console.log(result.latest);
1699
- * });
1700
- *
1701
- * Effect.runPromise(program.pipe(Effect.provide(ResolverLayer)));
1702
- * ```
1703
- *
1704
- * @see {@link BunResolver}
1705
- * @see {@link BunReleaseCache}
1706
- * @see {@link AutoBunCacheLive}
1707
- * @see {@link FreshBunCacheLive}
1708
- * @see {@link OfflineBunCacheLive}
1709
- * @public
1710
- */
1711
- declare const BunResolverLive: Layer.Layer<BunResolver, never, BunReleaseCache>;
1712
- //#endregion
1713
- //#region src/schemas/github.d.ts
1714
- /**
1715
- * A single tag entry as returned by the GitHub REST API
1716
- * (`GET /repos/{owner}/{repo}/tags`).
1717
- *
1718
- * Consumed by {@link GitHubClient} when fetching Bun and Deno release tags.
1719
- *
1720
- * @see {@link GitHubClient}
1721
- * @see `GitHubTagList`
1722
- *
1723
- * @public
1724
- */
1725
- declare const GitHubTag: Schema.Struct<{
1726
- name: typeof Schema.String;
1727
- zipball_url: typeof Schema.String;
1728
- tarball_url: typeof Schema.String;
1729
- commit: Schema.Struct<{
1730
- sha: typeof Schema.String;
1731
- url: typeof Schema.String;
1732
- }>;
1733
- node_id: typeof Schema.String;
1734
- }>;
1735
- /**
1736
- * A single tag entry as returned by the GitHub REST API.
1737
- *
1738
- * @see {@link GitHubClient}
1739
- *
1740
- * @public
1741
- */
1742
- type GitHubTag = typeof GitHubTag.Type;
1743
- /**
1744
- * A single release entry as returned by the GitHub REST API
1745
- * (`GET /repos/{owner}/{repo}/releases`).
1746
- *
1747
- * Consumed by {@link GitHubClient} when fetching Deno releases that carry
1748
- * publication timestamps.
1749
- *
1750
- * @see {@link GitHubClient}
1751
- * @see `GitHubReleaseList`
1752
- *
1753
- * @public
1754
- */
1755
- declare const GitHubRelease: Schema.Struct<{
1756
- tag_name: typeof Schema.String;
1757
- name: Schema.NullOr<typeof Schema.String>;
1758
- draft: typeof Schema.Boolean;
1759
- prerelease: typeof Schema.Boolean;
1760
- published_at: Schema.NullOr<typeof Schema.String>;
1761
- }>;
1762
- /**
1763
- * A single release entry as returned by the GitHub REST API.
1764
- *
1765
- * @see {@link GitHubClient}
1766
- *
1767
- * @public
1768
- */
1769
- type GitHubRelease = typeof GitHubRelease.Type;
1770
- //#endregion
1771
- //#region src/services/GitHubClient.d.ts
1772
- /**
1773
- * Pagination options shared by all list operations on {@link GitHubClient}.
1774
- *
1775
- * @see {@link GitHubClient}
1776
- *
1777
- * @public
1778
- */
1779
- interface ListOptions {
1780
- /**
1781
- * Number of items to request per page. Defaults to the GitHub API maximum
1782
- * of `100` when omitted.
1783
- */
1784
- readonly perPage?: number;
1785
- /**
1786
- * Maximum number of pages to fetch. When omitted all pages are fetched
1787
- * until the API returns an empty result set.
1788
- */
1789
- readonly pages?: number;
1790
- }
1791
- declare const GitHubClient_base: Context.TagClass<GitHubClient, "runtime-resolver/GitHubClient", {
1792
- /**
1793
- * Lists all git tags for the given repository, automatically paginating
1794
- * through results according to `options`.
1795
- *
1796
- * Fails with:
1797
- * - {@link AuthenticationError} — missing or invalid GitHub credentials.
1798
- * - {@link NetworkError} — the upstream request could not be completed.
1799
- * - {@link RateLimitError} — the GitHub API rate limit was exceeded.
1800
- * - {@link ParseError} — a response page could not be decoded.
1801
- *
1802
- * @param owner - GitHub organisation or user name (e.g. `"oven-sh"`).
1803
- * @param repo - Repository name (e.g. `"bun"`).
1804
- * @param options - Optional pagination controls.
1805
- */
1806
- readonly listTags: (owner: string, repo: string, options?: ListOptions) => Effect.Effect<ReadonlyArray<GitHubTag>, AuthenticationError | NetworkError | RateLimitError | ParseError>;
1807
- /**
1808
- * Lists all GitHub Releases for the given repository, automatically
1809
- * paginating through results according to `options`.
1810
- *
1811
- * Fails with:
1812
- * - {@link AuthenticationError} — missing or invalid GitHub credentials.
1813
- * - {@link NetworkError} — the upstream request could not be completed.
1814
- * - {@link RateLimitError} — the GitHub API rate limit was exceeded.
1815
- * - {@link ParseError} — a response page could not be decoded.
1816
- *
1817
- * @param owner - GitHub organisation or user name (e.g. `"denoland"`).
1818
- * @param repo - Repository name (e.g. `"deno"`).
1819
- * @param options - Optional pagination controls.
1820
- */
1821
- readonly listReleases: (owner: string, repo: string, options?: ListOptions) => Effect.Effect<ReadonlyArray<GitHubRelease>, AuthenticationError | NetworkError | RateLimitError | ParseError>;
1822
- /**
1823
- * Fetches arbitrary JSON from `url` and decodes it with the provided
1824
- * schema, returning the typed result.
1825
- *
1826
- * Useful for endpoints outside the standard Octokit REST methods (e.g.
1827
- * raw GitHub content URLs).
1828
- *
1829
- * Fails with:
1830
- * - {@link NetworkError} — the upstream request could not be completed.
1831
- * - {@link ParseError} — the response body could not be decoded by `schema`.
1832
- *
1833
- * @typeParam A - The decoded output type produced by `schema`.
1834
- * @param url - Fully qualified URL to fetch.
1835
- * @param schema - An object with a `decode` method compatible with
1836
- * Effect Schema's `decodeUnknown`.
1837
- */
1838
- readonly getJson: <A>(url: string, schema: {
1839
- readonly decode: (input: unknown) => Effect.Effect<A, ParseError>;
1840
- }) => Effect.Effect<A, NetworkError | ParseError>;
1841
- }>;
1842
- /**
1843
- * Service for GitHub REST API operations used by the version
1844
- * fetcher services.
1845
- *
1846
- * Abstracts over pagination and authentication so that higher-level services
1847
- * such as {@link BunVersionFetcher}, {@link DenoVersionFetcher}, and
1848
- * {@link NodeScheduleFetcher} remain independent of the underlying HTTP
1849
- * transport. The live implementation is provided by {@link GitHubClientLive}
1850
- * and requires an {@link OctokitInstance} in its dependency graph.
1851
- *
1852
- * @example
1853
- * ```typescript
1854
- * import type { GitHubTag } from "runtime-resolver";
1855
- * import { GitHubClient, GitHubClientLive, GitHubAutoAuth } from "runtime-resolver";
1856
- * import { Effect } from "effect";
1857
- *
1858
- * const program = Effect.gen(function* () {
1859
- * const client = yield* GitHubClient;
1860
- * const tags = yield* client.listTags("oven-sh", "bun", { perPage: 100 });
1861
- * console.log(`Found ${tags.length} tags`);
1862
- * });
1863
- *
1864
- * Effect.runPromise(
1865
- * program.pipe(Effect.provide(GitHubClientLive), Effect.provide(GitHubAutoAuth)),
1866
- * );
1867
- * ```
1868
- *
1869
- * @see {@link GitHubClientLive}
1870
- * @see {@link OctokitInstance}
1871
- * @see {@link ListOptions}
1872
- *
1873
- * @public
1874
- */
1875
- declare class GitHubClient extends GitHubClient_base {}
1876
- //#endregion
1877
- //#region src/layers/BunVersionFetcherLive.d.ts
1878
- /**
1879
- * Provides the {@link BunVersionFetcher} service using the live GitHub API.
1880
- *
1881
- * Fetches Bun releases from the `oven-sh/bun` GitHub repository using the
1882
- * provided {@link GitHubClient}. Draft releases and pre-releases are excluded.
1883
- * Tag names are normalized by stripping the `bun-` prefix and any leading `v`
1884
- * or `V` before parsing as semver.
1885
- *
1886
- * This layer is a required dependency of {@link AutoBunCacheLive} and
1887
- * {@link FreshBunCacheLive}. It is not needed by {@link OfflineBunCacheLive}.
1888
- *
1889
- * @see {@link BunVersionFetcher}
1890
- * @see {@link GitHubClient}
1891
- * @see {@link AutoBunCacheLive}
1892
- * @see {@link FreshBunCacheLive}
1893
- * @public
1894
- */
1895
- declare const BunVersionFetcherLive: Layer.Layer<BunVersionFetcher, never, GitHubClient>;
1896
- //#endregion
1897
- //#region src/layers/DenoReleaseCacheLive.d.ts
1898
- /**
1899
- * Low-level layer that constructs the {@link DenoReleaseCache} service backed by
1900
- * a `SemVerVersionCache` instance from `semver-effect`.
1901
- *
1902
- * This layer wires up the cache storage but does not populate it with any
1903
- * release data. Callers are responsible for loading releases after construction.
1904
- * In normal usage you should prefer the higher-level cache strategy layers
1905
- * instead of using this layer directly:
1906
- * - {@link AutoDenoCacheLive} — API with fallback to bundled defaults
1907
- * - {@link FreshDenoCacheLive} — API only, fails if unavailable
1908
- * - {@link OfflineDenoCacheLive} — bundled defaults only
1909
- *
1910
- * @see {@link DenoReleaseCache}
1911
- * @see {@link createRuntimeCache}
1912
- * @internal
1913
- */
1914
- declare const DenoReleaseCacheLive: Layer.Layer<DenoReleaseCache, never, VersionCache>;
1915
- //#endregion
1916
- //#region src/layers/DenoResolverLive.d.ts
1917
- /**
1918
- * Provides the {@link DenoResolver} service backed by a {@link DenoReleaseCache}.
1919
- *
1920
- * This layer composes with any of the three Deno cache strategy layers to form
1921
- * a complete resolver stack. It implements semver range filtering and increment
1922
- * grouping (latest per major, latest per minor, or all patch versions) using
1923
- * the releases already loaded into the cache.
1924
- *
1925
- * @example
1926
- * ```ts
1927
- * import { DenoResolverLive, AutoDenoCacheLive, DenoVersionFetcherLive, GitHubClientLive, GitHubAutoAuth } from "runtime-resolver";
1928
- * import { DenoResolver } from "runtime-resolver";
1929
- * import { Effect, Layer } from "effect";
1930
- *
1931
- * const GitHubLayer = GitHubClientLive.pipe(Layer.provide(GitHubAutoAuth));
1932
- * const CacheLayer = AutoDenoCacheLive.pipe(Layer.provide(DenoVersionFetcherLive.pipe(Layer.provide(GitHubLayer))));
1933
- * const ResolverLayer = DenoResolverLive.pipe(Layer.provide(CacheLayer));
1934
- *
1935
- * const program = Effect.gen(function* () {
1936
- * const resolver = yield* DenoResolver;
1937
- * const result = yield* resolver.resolve({ semverRange: "^2.0.0" });
1938
- * console.log(result.latest);
1939
- * });
1940
- *
1941
- * Effect.runPromise(program.pipe(Effect.provide(ResolverLayer)));
1942
- * ```
1943
- *
1944
- * @see {@link DenoResolver}
1945
- * @see {@link DenoReleaseCache}
1946
- * @see {@link AutoDenoCacheLive}
1947
- * @see {@link FreshDenoCacheLive}
1948
- * @see {@link OfflineDenoCacheLive}
1949
- * @public
1950
- */
1951
- declare const DenoResolverLive: Layer.Layer<DenoResolver, never, DenoReleaseCache>;
1952
- //#endregion
1953
- //#region src/layers/DenoVersionFetcherLive.d.ts
1954
- /**
1955
- * Provides the {@link DenoVersionFetcher} service using the live GitHub API.
1956
- *
1957
- * Fetches Deno releases from the `denoland/deno` GitHub repository using the
1958
- * provided {@link GitHubClient}. Draft releases and pre-releases are excluded.
1959
- * Tag names are normalized by stripping any leading `v` before parsing as
1960
- * semver.
1961
- *
1962
- * This layer is a required dependency of {@link AutoDenoCacheLive} and
1963
- * {@link FreshDenoCacheLive}. It is not needed by {@link OfflineDenoCacheLive}.
1964
- *
1965
- * @see {@link DenoVersionFetcher}
1966
- * @see {@link GitHubClient}
1967
- * @see {@link AutoDenoCacheLive}
1968
- * @see {@link FreshDenoCacheLive}
1969
- * @public
1970
- */
1971
- declare const DenoVersionFetcherLive: Layer.Layer<DenoVersionFetcher, never, GitHubClient>;
1972
- //#endregion
1973
- //#region src/layers/FreshBunCacheLive.d.ts
1974
- /**
1975
- * Provides the {@link BunReleaseCache} service using the "Fresh" cache strategy.
1976
- *
1977
- * Requires live release data from the GitHub API via {@link BunVersionFetcher}.
1978
- * If the fetch fails for any reason — authentication errors, network errors,
1979
- * parse errors, or rate-limit errors — the layer fails with a `FreshnessError`
1980
- * rather than falling back to stale data.
1981
- *
1982
- * Use this strategy in contexts where working with outdated version data would
1983
- * be incorrect or misleading, such as CI pipelines or tooling that must reflect
1984
- * the true current state of Bun releases.
1985
- *
1986
- * The three Bun cache strategy layers are:
1987
- * - {@link AutoBunCacheLive} — tries API first, falls back to bundled defaults on any error
1988
- * - `FreshBunCacheLive` — requires live API data, fails with `FreshnessError` if unavailable
1989
- * - {@link OfflineBunCacheLive} — uses only bundled defaults, no network I/O
1990
- *
1991
- * @see {@link BunReleaseCache}
1992
- * @see {@link AutoBunCacheLive}
1993
- * @see {@link OfflineBunCacheLive}
1994
- * @public
1995
- */
1996
- declare const FreshBunCacheLive: Layer.Layer<BunReleaseCache, FreshnessError, BunVersionFetcher>;
1997
- //#endregion
1998
- //#region src/layers/FreshDenoCacheLive.d.ts
1999
- /**
2000
- * Provides the {@link DenoReleaseCache} service using the "Fresh" cache strategy.
2001
- *
2002
- * Requires live release data from the GitHub API via {@link DenoVersionFetcher}.
2003
- * If the fetch fails for any reason — authentication errors, network errors,
2004
- * parse errors, or rate-limit errors — the layer fails with a `FreshnessError`
2005
- * rather than falling back to stale data.
2006
- *
2007
- * Use this strategy in contexts where working with outdated version data would
2008
- * be incorrect or misleading, such as CI pipelines or tooling that must reflect
2009
- * the true current state of Deno releases.
2010
- *
2011
- * The three Deno cache strategy layers are:
2012
- * - {@link AutoDenoCacheLive} — tries API first, falls back to bundled defaults on any error
2013
- * - `FreshDenoCacheLive` — requires live API data, fails with `FreshnessError` if unavailable
2014
- * - {@link OfflineDenoCacheLive} — uses only bundled defaults, no network I/O
2015
- *
2016
- * @see {@link DenoReleaseCache}
2017
- * @see {@link AutoDenoCacheLive}
2018
- * @see {@link OfflineDenoCacheLive}
2019
- * @public
2020
- */
2021
- declare const FreshDenoCacheLive: Layer.Layer<DenoReleaseCache, FreshnessError, DenoVersionFetcher>;
2022
- //#endregion
2023
- //#region src/layers/FreshNodeCacheLive.d.ts
2024
- /**
2025
- * Provides the {@link NodeReleaseCache} service using the "Fresh" cache strategy.
2026
- *
2027
- * Requires live release data from `nodejs.org/dist/index.json` via
2028
- * {@link NodeVersionFetcher} and the release schedule from the `nodejs/Release`
2029
- * repository via {@link NodeScheduleFetcher}. If either fetch fails — due to
2030
- * network errors or parse errors — the layer fails with a `FreshnessError`
2031
- * rather than falling back to stale data.
2032
- *
2033
- * Use this strategy in contexts where working with outdated version data would
2034
- * be incorrect or misleading, such as CI pipelines or tooling that must reflect
2035
- * the true current state of Node.js releases and LTS schedule.
2036
- *
2037
- * The three Node cache strategy layers are:
2038
- * - {@link AutoNodeCacheLive} — tries API first, falls back to bundled defaults on any error
2039
- * - `FreshNodeCacheLive` — requires live API data, fails with `FreshnessError` if unavailable
2040
- * - {@link OfflineNodeCacheLive} — uses only bundled defaults, no network I/O
2041
- *
2042
- * @see {@link NodeReleaseCache}
2043
- * @see {@link AutoNodeCacheLive}
2044
- * @see {@link OfflineNodeCacheLive}
2045
- * @public
2046
- */
2047
- declare const FreshNodeCacheLive: Layer.Layer<NodeReleaseCache, FreshnessError, NodeVersionFetcher | NodeScheduleFetcher>;
2048
- //#endregion
2049
- //#region src/services/OctokitInstance.d.ts
2050
- declare const OctokitInstance_base: Context.TagClass<OctokitInstance, "runtime-resolver/OctokitInstance", {
2051
- readonly rest: {
2052
- readonly repos: {
2053
- /**
2054
- * Lists git tags for a repository, corresponding to
2055
- * `GET /repos/{owner}/{repo}/tags`.
2056
- *
2057
- * @param params - Owner, repo, and optional pagination parameters.
2058
- */
2059
- readonly listTags: (params: {
2060
- owner: string;
2061
- repo: string;
2062
- per_page?: number;
2063
- page?: number;
2064
- }) => Promise<{
2065
- data: Array<unknown>;
2066
- }>;
2067
- /**
2068
- * Lists GitHub Releases for a repository, corresponding to
2069
- * `GET /repos/{owner}/{repo}/releases`.
2070
- *
2071
- * @param params - Owner, repo, and optional pagination parameters.
2072
- */
2073
- readonly listReleases: (params: {
2074
- owner: string;
2075
- repo: string;
2076
- per_page?: number;
2077
- page?: number;
2078
- }) => Promise<{
2079
- data: Array<unknown>;
2080
- }>;
2081
- };
2082
- };
2083
- }>;
2084
- /**
2085
- * Thin wrapper around the subset of Octokit's REST client used by
2086
- * {@link GitHubClient}.
2087
- *
2088
- * Exposing only the repository methods actually consumed by this library
2089
- * keeps the surface area narrow and makes the interface straightforward to
2090
- * stub in tests without pulling in the full Octokit type.
2091
- *
2092
- * An `OctokitInstance` is provided to the dependency graph by one of the
2093
- * three authentication layers: {@link GitHubTokenAuth}, {@link GitHubAppAuth},
2094
- * or {@link GitHubAutoAuth}.
2095
- *
2096
- * @example
2097
- * ```typescript
2098
- * import { OctokitInstance, GitHubClientLive, GitHubAutoAuth } from "runtime-resolver";
2099
- * import { Effect } from "effect";
2100
- *
2101
- * const program = Effect.gen(function* () {
2102
- * const octokit = yield* OctokitInstance;
2103
- * const response = await octokit.rest.repos.listTags({
2104
- * owner: "oven-sh",
2105
- * repo: "bun",
2106
- * per_page: 10,
2107
- * });
2108
- * console.log(response.data.length);
2109
- * });
2110
- *
2111
- * Effect.runPromise(program.pipe(Effect.provide(GitHubAutoAuth)));
2112
- * ```
2113
- *
2114
- * @see {@link GitHubClientLive}
2115
- * @see {@link GitHubTokenAuth}
2116
- * @see {@link GitHubAppAuth}
2117
- * @see {@link GitHubAutoAuth}
2118
- *
2119
- * @public
2120
- */
2121
- declare class OctokitInstance extends OctokitInstance_base {}
2122
- //#endregion
2123
- //#region src/layers/GitHubAppAuth.d.ts
2124
- /**
2125
- * Configuration required to authenticate as a GitHub App installation.
2126
- *
2127
- * @see {@link GitHubAppAuth}
2128
- * @public
2129
- */
2130
- interface GitHubAppAuthConfig {
2131
- readonly appId: string;
2132
- readonly privateKey: string;
2133
- readonly installationId?: number;
2134
- }
2135
- /**
2136
- * Provides an {@link OctokitInstance} authenticated as a GitHub App installation.
2137
- *
2138
- * Accepts a {@link GitHubAppAuthConfig} and uses `@octokit/auth-app` to obtain
2139
- * an installation access token. If `installationId` is omitted, the first
2140
- * installation returned by the GitHub API is used automatically (suitable for
2141
- * apps with a single installation). If authentication fails for any reason the
2142
- * layer fails with an `AuthenticationError`.
2143
- *
2144
- * Use this auth method when your integration runs as a GitHub App rather than
2145
- * as an individual user or a CI token.
2146
- *
2147
- * @param config - App credentials and optional installation ID.
2148
- *
2149
- * @see {@link GitHubAppAuthConfig}
2150
- * @see {@link OctokitInstance}
2151
- * @see {@link GitHubAutoAuth}
2152
- * @see {@link GitHubTokenAuth}
2153
- * @public
2154
- */
2155
- declare const GitHubAppAuth: (config: GitHubAppAuthConfig) => Layer.Layer<OctokitInstance, AuthenticationError>;
2156
- //#endregion
2157
- //#region src/layers/GitHubAutoAuth.d.ts
2158
- /**
2159
- * Provides an {@link OctokitInstance} by auto-detecting the available
2160
- * authentication credentials from environment variables at layer construction
2161
- * time.
2162
- *
2163
- * Credentials are evaluated in the following priority order:
2164
- * 1. **GitHub App** — when both `GITHUB_APP_ID` and `GITHUB_APP_PRIVATE_KEY`
2165
- * are set, authenticates as a GitHub App installation via {@link GitHubAppAuth}.
2166
- * `GITHUB_APP_INSTALLATION_ID` is optional; if absent the first installation
2167
- * is used automatically.
2168
- * 2. **Personal Access Token** — when `GITHUB_PERSONAL_ACCESS_TOKEN` is set,
2169
- * authenticates with that token.
2170
- * 3. **`GITHUB_TOKEN`** — when `GITHUB_TOKEN` is set (e.g., the default token
2171
- * injected in GitHub Actions), authenticates with that token.
2172
- * 4. **Unauthenticated** — falls back to an unauthenticated Octokit instance
2173
- * when no credentials are found (lower rate limits apply).
2174
- *
2175
- * If both App and token credentials are present, App auth takes precedence and
2176
- * a warning is logged. This layer fails with `AuthenticationError` only when
2177
- * App credentials are present but the App authentication itself fails.
2178
- *
2179
- * Use this layer as the default auth strategy in most applications. Switch to
2180
- * {@link GitHubTokenAuth} or {@link GitHubAppAuth} when you need explicit control
2181
- * over which credential source is used.
2182
- *
2183
- * @example
2184
- * ```ts
2185
- * import { GitHubClientLive, GitHubAutoAuth } from "runtime-resolver";
2186
- * import { Layer } from "effect";
2187
- *
2188
- * const GitHubLayer = GitHubClientLive.pipe(Layer.provide(GitHubAutoAuth));
2189
- * ```
2190
- *
2191
- * @see {@link OctokitInstance}
2192
- * @see {@link GitHubTokenAuth}
2193
- * @see {@link GitHubAppAuth}
2194
- * @public
2195
- */
2196
- declare const GitHubAutoAuth: Layer.Layer<OctokitInstance, AuthenticationError>;
2197
- //#endregion
2198
- //#region src/layers/GitHubClientLive.d.ts
2199
- /**
2200
- * Provides the {@link GitHubClient} service backed by an {@link OctokitInstance}.
2201
- *
2202
- * This layer wraps an Octokit instance and exposes a typed, Effect-native API
2203
- * for listing GitHub releases, listing tags, and fetching arbitrary JSON from
2204
- * URLs. HTTP errors are mapped to typed domain errors (`NetworkError`,
2205
- * `RateLimitError`, `AuthenticationError`) so they can be handled precisely in
2206
- * calling code.
2207
- *
2208
- * Pair this layer with one of the auth layers to form a complete GitHub
2209
- * integration stack:
2210
- * - {@link GitHubAutoAuth} — auto-detects auth from environment variables
2211
- * - {@link GitHubTokenAuth} — authenticates using a personal access token
2212
- * - {@link GitHubAppAuth} — authenticates as a GitHub App installation
2213
- *
2214
- * @see {@link GitHubClient}
2215
- * @see {@link OctokitInstance}
2216
- * @see {@link GitHubAutoAuth}
2217
- * @public
2218
- */
2219
- declare const GitHubClientLive: Layer.Layer<GitHubClient, never, OctokitInstance>;
2220
- //#endregion
2221
- //#region src/layers/GitHubTokenAuth.d.ts
2222
- /**
2223
- * Provides an {@link OctokitInstance} authenticated with a GitHub personal
2224
- * access token read from the environment at layer construction time.
2225
- *
2226
- * The token is resolved by checking, in order:
2227
- * 1. `GITHUB_PERSONAL_ACCESS_TOKEN` environment variable
2228
- * 2. `GITHUB_TOKEN` environment variable
2229
- *
2230
- * If neither variable is set the layer constructs an unauthenticated Octokit
2231
- * instance (lower rate limits apply). This layer never fails.
2232
- *
2233
- * Use {@link GitHubTokenAuthFromToken} when you have the token value available
2234
- * programmatically at construction time.
2235
- *
2236
- * @see {@link OctokitInstance}
2237
- * @see {@link GitHubTokenAuthFromToken}
2238
- * @see {@link GitHubAutoAuth}
2239
- * @see {@link GitHubAppAuth}
2240
- * @public
2241
- */
2242
- declare const GitHubTokenAuth: Layer.Layer<OctokitInstance>;
2243
- /**
2244
- * Provides an {@link OctokitInstance} authenticated with the given personal
2245
- * access token string.
2246
- *
2247
- * Use this variant when the token is available as a value in your program
2248
- * rather than read from an environment variable. The resulting layer never
2249
- * fails.
2250
- *
2251
- * @param token - A GitHub personal access token string.
2252
- *
2253
- * @see {@link OctokitInstance}
2254
- * @see {@link GitHubTokenAuth}
2255
- * @see {@link GitHubAutoAuth}
2256
- * @see {@link GitHubAppAuth}
2257
- * @public
2258
- */
2259
- declare const GitHubTokenAuthFromToken: (token: string) => Layer.Layer<OctokitInstance>;
2260
- //#endregion
2261
- //#region src/layers/NodeReleaseCacheLive.d.ts
2262
- /**
2263
- * Low-level layer that constructs the {@link NodeReleaseCache} service backed by
2264
- * a `SemVerVersionCache` instance from `semver-effect`.
2265
- *
2266
- * This layer is more complex than the Bun and Deno equivalents because it manages
2267
- * additional LTS schedule state via an internal `Ref`. The schedule is stored
2268
- * separately from the version list so that calling `updateSchedule` can
2269
- * transparently rebuild all release objects with the latest phase information
2270
- * without reloading data from the network.
2271
- *
2272
- * This layer wires up the cache storage but does not populate it with any
2273
- * release data. Callers are responsible for calling `updateSchedule` and
2274
- * `loadFromInputs` after construction. In normal usage you should prefer the
2275
- * higher-level cache strategy layers instead of using this layer directly:
2276
- * - {@link AutoNodeCacheLive} — API with fallback to bundled defaults
2277
- * - {@link FreshNodeCacheLive} — API only, fails if unavailable
2278
- * - {@link OfflineNodeCacheLive} — bundled defaults only
2279
- *
2280
- * @see {@link NodeReleaseCache}
2281
- * @see {@link createRuntimeCache}
2282
- * @internal
2283
- */
2284
- declare const NodeReleaseCacheLive: Layer.Layer<NodeReleaseCache, never, VersionCache>;
2285
- //#endregion
2286
- //#region src/layers/NodeResolverLive.d.ts
2287
- /**
2288
- * Provides the {@link NodeResolver} service backed by a {@link NodeReleaseCache}.
2289
- *
2290
- * This layer composes with any of the three Node cache strategy layers to form
2291
- * a complete resolver stack. In addition to semver range filtering and increment
2292
- * grouping, it supports filtering by Node.js release phase (e.g., `"current"`,
2293
- * `"active-lts"`, `"maintenance-lts"`, `"end-of-life"`) and automatically
2294
- * determines the current LTS version from the loaded schedule data.
2295
- *
2296
- * @example
2297
- * ```ts
2298
- * import {
2299
- * NodeResolverLive, AutoNodeCacheLive,
2300
- * NodeVersionFetcherLive, NodeScheduleFetcherLive,
2301
- * GitHubClientLive, GitHubAutoAuth,
2302
- * } from "runtime-resolver";
2303
- * import { NodeResolver } from "runtime-resolver";
2304
- * import { Effect, Layer } from "effect";
2305
- *
2306
- * const GitHubLayer = GitHubClientLive.pipe(Layer.provide(GitHubAutoAuth));
2307
- * const FetchersLayer = Layer.merge(
2308
- * NodeVersionFetcherLive.pipe(Layer.provide(GitHubLayer)),
2309
- * NodeScheduleFetcherLive.pipe(Layer.provide(GitHubLayer)),
2310
- * );
2311
- * const CacheLayer = AutoNodeCacheLive.pipe(Layer.provide(FetchersLayer));
2312
- * const ResolverLayer = NodeResolverLive.pipe(Layer.provide(CacheLayer));
2313
- *
2314
- * const program = Effect.gen(function* () {
2315
- * const resolver = yield* NodeResolver;
2316
- * // Resolve only active-LTS and maintenance-LTS releases in the ^20 range
2317
- * const result = yield* resolver.resolve({
2318
- * semverRange: "^20.0.0",
2319
- * phases: ["active-lts", "maintenance-lts"],
2320
- * });
2321
- * console.log(result.lts);
2322
- * });
2323
- *
2324
- * Effect.runPromise(program.pipe(Effect.provide(ResolverLayer)));
2325
- * ```
2326
- *
2327
- * @see {@link NodeResolver}
2328
- * @see {@link NodeReleaseCache}
2329
- * @see {@link AutoNodeCacheLive}
2330
- * @see {@link FreshNodeCacheLive}
2331
- * @see {@link OfflineNodeCacheLive}
2332
- * @public
2333
- */
2334
- declare const NodeResolverLive: Layer.Layer<NodeResolver, never, NodeReleaseCache>;
2335
- //#endregion
2336
- //#region src/layers/NodeScheduleFetcherLive.d.ts
2337
- /**
2338
- * Provides the {@link NodeScheduleFetcher} service using the live Node.js release schedule.
2339
- *
2340
- * Fetches the Node.js release schedule from the raw GitHub content URL for
2341
- * `nodejs/Release` (`schedule.json` on the `main` branch) using the HTTP client
2342
- * on the provided {@link GitHubClient} service. The schedule data maps major
2343
- * version codenames to their start, LTS, and end-of-life dates and is used by
2344
- * {@link NodeReleaseCache} to compute per-release lifecycle phases.
2345
- *
2346
- * This layer is a required dependency of {@link AutoNodeCacheLive} and
2347
- * {@link FreshNodeCacheLive}. It is not needed by {@link OfflineNodeCacheLive}.
2348
- *
2349
- * @see {@link NodeScheduleFetcher}
2350
- * @see {@link GitHubClient}
2351
- * @see {@link AutoNodeCacheLive}
2352
- * @see {@link FreshNodeCacheLive}
2353
- * @public
2354
- */
2355
- declare const NodeScheduleFetcherLive: Layer.Layer<NodeScheduleFetcher, never, GitHubClient>;
2356
- //#endregion
2357
- //#region src/layers/NodeVersionFetcherLive.d.ts
2358
- /**
2359
- * Provides the {@link NodeVersionFetcher} service using the live Node.js dist index.
2360
- *
2361
- * Fetches the full Node.js version list from `https://nodejs.org/dist/index.json`
2362
- * using the HTTP client on the provided {@link GitHubClient} service. Version
2363
- * strings are normalized by stripping the leading `v` before parsing as semver.
2364
- * Entries with non-string `npm` fields (present in very old releases prior to
2365
- * v0.6.3) are substituted with the sentinel version `"0.0.0"`.
2366
- *
2367
- * This layer is a required dependency of {@link AutoNodeCacheLive} and
2368
- * {@link FreshNodeCacheLive}. It is not needed by {@link OfflineNodeCacheLive}.
2369
- *
2370
- * @see {@link NodeVersionFetcher}
2371
- * @see {@link GitHubClient}
2372
- * @see {@link AutoNodeCacheLive}
2373
- * @see {@link FreshNodeCacheLive}
2374
- * @public
2375
- */
2376
- declare const NodeVersionFetcherLive: Layer.Layer<NodeVersionFetcher, never, GitHubClient>;
2377
- //#endregion
2378
- //#region src/layers/OfflineBunCacheLive.d.ts
2379
- /**
2380
- * Provides the {@link BunReleaseCache} service using the "Offline" cache strategy.
2381
- *
2382
- * Uses only the bundled default Bun release data that was baked in at build time.
2383
- * Makes no network requests and has no runtime dependencies. This layer always
2384
- * succeeds immediately.
2385
- *
2386
- * Use this strategy in environments where network access is unavailable or
2387
- * undesirable (e.g., air-gapped systems, hermetic test environments, or any
2388
- * context where version data from the bundle is sufficient).
2389
- *
2390
- * The three Bun cache strategy layers are:
2391
- * - {@link AutoBunCacheLive} — tries API first, falls back to bundled defaults on any error
2392
- * - {@link FreshBunCacheLive} — requires live API data, fails with `FreshnessError` if unavailable
2393
- * - `OfflineBunCacheLive` — uses only bundled defaults, no network I/O
2394
- *
2395
- * @see {@link BunReleaseCache}
2396
- * @see {@link AutoBunCacheLive}
2397
- * @see {@link FreshBunCacheLive}
2398
- * @public
2399
- */
2400
- declare const OfflineBunCacheLive: Layer.Layer<BunReleaseCache>;
2401
- //#endregion
2402
- //#region src/layers/OfflineDenoCacheLive.d.ts
2403
- /**
2404
- * Provides the {@link DenoReleaseCache} service using the "Offline" cache strategy.
2405
- *
2406
- * Uses only the bundled default Deno release data that was baked in at build time.
2407
- * Makes no network requests and has no runtime dependencies. This layer always
2408
- * succeeds immediately.
2409
- *
2410
- * Use this strategy in environments where network access is unavailable or
2411
- * undesirable (e.g., air-gapped systems, hermetic test environments, or any
2412
- * context where version data from the bundle is sufficient).
2413
- *
2414
- * The three Deno cache strategy layers are:
2415
- * - {@link AutoDenoCacheLive} — tries API first, falls back to bundled defaults on any error
2416
- * - {@link FreshDenoCacheLive} — requires live API data, fails with `FreshnessError` if unavailable
2417
- * - `OfflineDenoCacheLive` — uses only bundled defaults, no network I/O
2418
- *
2419
- * @see {@link DenoReleaseCache}
2420
- * @see {@link AutoDenoCacheLive}
2421
- * @see {@link FreshDenoCacheLive}
2422
- * @public
2423
- */
2424
- declare const OfflineDenoCacheLive: Layer.Layer<DenoReleaseCache>;
2425
- //#endregion
2426
- //#region src/layers/OfflineNodeCacheLive.d.ts
2427
- /**
2428
- * Provides the {@link NodeReleaseCache} service using the "Offline" cache strategy.
2429
- *
2430
- * Uses only the bundled default Node.js release data and schedule data that were
2431
- * baked in at build time. Makes no network requests and has no runtime
2432
- * dependencies. This layer always succeeds immediately.
2433
- *
2434
- * Use this strategy in environments where network access is unavailable or
2435
- * undesirable (e.g., air-gapped systems, hermetic test environments, or any
2436
- * context where version data from the bundle is sufficient).
2437
- *
2438
- * The three Node cache strategy layers are:
2439
- * - {@link AutoNodeCacheLive} — tries API first, falls back to bundled defaults on any error
2440
- * - {@link FreshNodeCacheLive} — requires live API data, fails with `FreshnessError` if unavailable
2441
- * - `OfflineNodeCacheLive` — uses only bundled defaults, no network I/O
2442
- *
2443
- * @see {@link NodeReleaseCache}
2444
- * @see {@link AutoNodeCacheLive}
2445
- * @see {@link FreshNodeCacheLive}
2446
- * @public
2447
- */
2448
- declare const OfflineNodeCacheLive: Layer.Layer<NodeReleaseCache>;
2449
- //#endregion
2450
- //#region src/layers/RuntimeCacheLive.d.ts
2451
- /**
2452
- * Factory that creates a {@link RuntimeCache} implementation backed by
2453
- * `semver-effect`'s `VersionCache`.
2454
- *
2455
- * The returned `Effect` must be executed within an Effect context that provides
2456
- * a `SemVerVersionCache` service (i.e., it requires `SemVerVersionCache` in its
2457
- * environment). The cache maintains an internal lookup map from version string
2458
- * to the full release object so that resolved semver versions can be
2459
- * round-tripped back to their typed release records.
2460
- *
2461
- * This factory is used internally by {@link BunReleaseCacheLive},
2462
- * {@link DenoReleaseCacheLive}, and {@link NodeReleaseCacheLive} to build their
2463
- * respective cache service implementations. Prefer those higher-level layers
2464
- * over calling this factory directly.
2465
- *
2466
- * Note: `load` is not concurrency-safe. Callers must not invoke it concurrently.
2467
- * In practice this constraint is upheld because `load` is only called from layer
2468
- * setup and `NodeReleaseCacheLive.loadFromInputs`, both of which are serialized
2469
- * by the Effect runtime.
2470
- *
2471
- * @typeParam R - The runtime release type stored in the cache. Must extend
2472
- * {@link RuntimeRelease}.
2473
- *
2474
- * @see {@link RuntimeCache}
2475
- * @see {@link BunReleaseCacheLive}
2476
- * @see {@link DenoReleaseCacheLive}
2477
- * @see {@link NodeReleaseCacheLive}
2478
- * @public
2479
- */
2480
- declare const createRuntimeCache: <R extends RuntimeRelease>() => Effect.Effect<RuntimeCache<R>, never, VersionCache>;
2481
- //#endregion
2482
- //#region src/index.d.ts
2483
- /**
2484
- * Resolve Node.js versions matching the given options.
2485
- *
2486
- * Fetches release data from the Node.js GitHub repository and the official
2487
- * release schedule API, then filters and ranks versions according to
2488
- * `options`. Authentication is read from `GITHUB_PERSONAL_ACCESS_TOKEN` or
2489
- * `GITHUB_TOKEN` environment variables. Falls back to a build-time offline
2490
- * cache when the network is unavailable.
2491
- *
2492
- * @param options - Filtering and ranking options. See {@link NodeResolverOptions}.
2493
- * @returns A promise that resolves to a `ResolvedVersions` object
2494
- * containing the matched version list, the highest matching version as
2495
- * `latest`, and optional `lts` / `default` strings.
2496
- *
2497
- * @example
2498
- * ```ts
2499
- * import type { ResolvedVersions } from "runtime-resolver";
2500
- * import { resolveNode } from "runtime-resolver";
2501
- *
2502
- * const result: ResolvedVersions = await resolveNode({
2503
- * semverRange: ">=20.0.0",
2504
- * phases: ["active-lts"],
2505
- * });
2506
- * console.log(result.latest); // e.g. "22.11.0"
2507
- * console.log(result.versions); // all matching versions
2508
- * ```
2509
- *
2510
- * @see {@link NodeResolver} for the Effect-based API
2511
- * @see {@link NodeResolverOptions} for available options
2512
- *
2513
- * @public
2514
- */
2515
- declare const resolveNode: (options?: NodeResolverOptions) => Promise<ResolvedVersions>;
2516
- /**
2517
- * Resolve Bun versions matching the given options.
2518
- *
2519
- * Fetches release data from the Bun GitHub repository, then filters and ranks
2520
- * versions according to `options`. Authentication is read from
2521
- * `GITHUB_PERSONAL_ACCESS_TOKEN` or `GITHUB_TOKEN` environment variables.
2522
- * Falls back to a build-time offline cache when the network is unavailable.
2523
- *
2524
- * @param options - Filtering and ranking options. See {@link BunResolverOptions}.
2525
- * @returns A promise that resolves to a `ResolvedVersions` object
2526
- * containing the matched version list and the highest matching version as
2527
- * `latest`.
2528
- *
2529
- * @example
2530
- * ```ts
2531
- * import type { ResolvedVersions } from "runtime-resolver";
2532
- * import { resolveBun } from "runtime-resolver";
2533
- *
2534
- * const result: ResolvedVersions = await resolveBun({ semverRange: "^1.0.0" });
2535
- * console.log(result.latest);
2536
- * ```
2537
- *
2538
- * @see {@link BunResolver} for the Effect-based API
2539
- * @see {@link BunResolverOptions} for available options
2540
- *
2541
- * @public
2542
- */
2543
- declare const resolveBun: (options?: BunResolverOptions) => Promise<ResolvedVersions>;
2544
- /**
2545
- * Resolve Deno versions matching the given options.
2546
- *
2547
- * Fetches release data from the Deno GitHub repository, then filters and ranks
2548
- * versions according to `options`. Authentication is read from
2549
- * `GITHUB_PERSONAL_ACCESS_TOKEN` or `GITHUB_TOKEN` environment variables.
2550
- * Falls back to a build-time offline cache when the network is unavailable.
2551
- *
2552
- * @param options - Filtering and ranking options. See {@link DenoResolverOptions}.
2553
- * @returns A promise that resolves to a `ResolvedVersions` object
2554
- * containing the matched version list and the highest matching version as
2555
- * `latest`.
2556
- *
2557
- * @example
2558
- * ```ts
2559
- * import type { ResolvedVersions } from "runtime-resolver";
2560
- * import { resolveDeno } from "runtime-resolver";
2561
- *
2562
- * const result: ResolvedVersions = await resolveDeno({ semverRange: "^2.0.0" });
2563
- * console.log(result.latest);
2564
- * ```
2565
- *
2566
- * @see {@link DenoResolver} for the Effect-based API
2567
- * @see {@link DenoResolverOptions} for available options
2568
- *
2569
- * @public
2570
- */
2571
- declare const resolveDeno: (options?: DenoResolverOptions) => Promise<ResolvedVersions>;
2572
- //#endregion
2573
- export { AuthenticationError, AutoBunCacheLive, AutoDenoCacheLive, AutoNodeCacheLive, BunRelease, BunReleaseCache, BunReleaseCacheLive, BunResolver, type BunResolverError, BunResolverLive, type BunResolverOptions, BunVersionFetcher, BunVersionFetcherLive, CacheError, DenoRelease, DenoReleaseCache, DenoReleaseCacheLive, DenoResolver, type DenoResolverError, DenoResolverLive, type DenoResolverOptions, DenoVersionFetcher, DenoVersionFetcherLive, FreshBunCacheLive, FreshDenoCacheLive, FreshNodeCacheLive, FreshnessError, GitHubAppAuth, type GitHubAppAuthConfig, GitHubAutoAuth, GitHubClient, GitHubClientLive, type GitHubRelease, type GitHubTag, GitHubTokenAuth, GitHubTokenAuthFromToken, type Increments, InvalidInputError, type ListOptions, NetworkError, type NodePhase, NodeRelease, NodeReleaseCache, NodeReleaseCacheLive, type NodeReleaseInput, NodeResolver, type NodeResolverError, NodeResolverLive, type NodeResolverOptions, NodeSchedule, type NodeScheduleData, type NodeScheduleEntry, NodeScheduleFetcher, NodeScheduleFetcherLive, NodeVersionFetcher, NodeVersionFetcherLive, OctokitInstance, OfflineBunCacheLive, OfflineDenoCacheLive, OfflineNodeCacheLive, ParseError, RateLimitError, type ResolvedVersions, type Runtime, type RuntimeCache, type RuntimeRelease, type RuntimeReleaseInput, type Source, VersionNotFoundError, createRuntimeCache, resolveBun, resolveDeno, resolveNode };
2574
- //# sourceMappingURL=index.d.ts.map