runtime-resolver 0.3.12 → 0.3.14

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 (67) hide show
  1. package/bin/runtime-resolver.d.ts +1 -0
  2. package/bin/runtime-resolver.js +29 -261
  3. package/cli/commands/resolve.js +239 -0
  4. package/cli/schemas/json-schema.js +12 -0
  5. package/cli/schemas/response.js +86 -0
  6. package/data/bun-defaults.js +850 -0
  7. package/data/deno-defaults.js +1526 -0
  8. package/data/node-defaults.js +4400 -0
  9. package/errors/AuthenticationError.js +35 -0
  10. package/errors/CacheError.js +32 -0
  11. package/errors/FreshnessError.js +38 -0
  12. package/errors/InvalidInputError.js +33 -0
  13. package/errors/NetworkError.js +34 -0
  14. package/errors/ParseError.js +33 -0
  15. package/errors/RateLimitError.js +39 -0
  16. package/errors/VersionNotFoundError.js +37 -0
  17. package/index.d.ts +2577 -2608
  18. package/index.js +158 -132
  19. package/layers/AutoBunCacheLive.js +47 -0
  20. package/layers/AutoDenoCacheLive.js +47 -0
  21. package/layers/AutoNodeCacheLive.js +58 -0
  22. package/layers/BunReleaseCacheLive.js +25 -0
  23. package/layers/BunResolverLive.js +85 -0
  24. package/layers/BunVersionFetcherLive.js +55 -0
  25. package/layers/DenoReleaseCacheLive.js +25 -0
  26. package/layers/DenoResolverLive.js +84 -0
  27. package/layers/DenoVersionFetcherLive.js +51 -0
  28. package/layers/FreshBunCacheLive.js +60 -0
  29. package/layers/FreshDenoCacheLive.js +60 -0
  30. package/layers/FreshNodeCacheLive.js +55 -0
  31. package/layers/GitHubAppAuth.js +58 -0
  32. package/layers/GitHubAutoAuth.js +70 -0
  33. package/layers/GitHubClientLive.js +130 -0
  34. package/layers/GitHubTokenAuth.js +50 -0
  35. package/layers/NodeReleaseCacheLive.js +77 -0
  36. package/layers/NodeResolverLive.js +107 -0
  37. package/layers/NodeScheduleFetcherLive.js +37 -0
  38. package/layers/NodeVersionFetcherLive.js +55 -0
  39. package/layers/OfflineBunCacheLive.js +40 -0
  40. package/layers/OfflineDenoCacheLive.js +40 -0
  41. package/layers/OfflineNodeCacheLive.js +39 -0
  42. package/layers/RuntimeCacheLive.js +78 -0
  43. package/lib/retry.js +27 -0
  44. package/lib/semver.js +21 -0
  45. package/package.json +57 -68
  46. package/schemas/bun-release.js +61 -0
  47. package/schemas/deno-release.js +61 -0
  48. package/schemas/github.js +74 -0
  49. package/schemas/node-release.js +130 -0
  50. package/schemas/node-schedule.js +110 -0
  51. package/schemas/node.js +68 -0
  52. package/services/BunReleaseCache.js +33 -0
  53. package/services/BunResolver.js +36 -0
  54. package/services/BunVersionFetcher.js +41 -0
  55. package/services/DenoReleaseCache.js +33 -0
  56. package/services/DenoResolver.js +36 -0
  57. package/services/DenoVersionFetcher.js +41 -0
  58. package/services/GitHubClient.js +40 -0
  59. package/services/NodeReleaseCache.js +41 -0
  60. package/services/NodeResolver.js +44 -0
  61. package/services/NodeScheduleFetcher.js +38 -0
  62. package/services/NodeVersionFetcher.js +39 -0
  63. package/services/OctokitInstance.js +44 -0
  64. package/tsdoc-metadata.json +11 -11
  65. package/612.js +0 -23
  66. package/711.js +0 -7554
  67. package/json-schema.js +0 -95
@@ -0,0 +1,61 @@
1
+ import { Data, DateTime, Effect } from "effect";
2
+ import { SemVer } from "semver-effect";
3
+
4
+ //#region src/schemas/bun-release.ts
5
+ /**
6
+ * A Bun release entry with a parsed {@link SemVer} version and an
7
+ * Effect {@link DateTime.DateTime} publication date.
8
+ *
9
+ * `BunRelease` extends `Data.TaggedClass` so instances support structural
10
+ * equality comparison and can be used safely inside Effect data structures.
11
+ * Construct instances via the {@link BunRelease.fromInput} factory rather than
12
+ * calling `new BunRelease(...)` directly, as the factory validates the version
13
+ * string through `SemVer.parse`.
14
+ *
15
+ * @see {@link BunReleaseCache}
16
+ * @see {@link BunResolver}
17
+ * @see {@link RuntimeReleaseInput}
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * import { Effect } from "effect";
22
+ * import type { BunRelease } from "./bun-release.js";
23
+ * import { BunRelease as BunReleaseClass } from "./bun-release.js";
24
+ *
25
+ * const program = BunReleaseClass.fromInput({ version: "1.1.0", date: "2024-03-01" }).pipe(
26
+ * Effect.map((release: BunRelease) => {
27
+ * console.log(release.version.major); // 1
28
+ * console.log(release.version.minor); // 1
29
+ * console.log(release._tag); // "BunRelease"
30
+ * }),
31
+ * );
32
+ *
33
+ * Effect.runPromise(program);
34
+ * ```
35
+ *
36
+ * @public
37
+ */
38
+ var BunRelease = class BunRelease extends Data.TaggedClass("BunRelease") {
39
+ /**
40
+ * Create a {@link BunRelease} from lean string inputs.
41
+ *
42
+ * Parses `input.version` via `SemVer.parse` and constructs the
43
+ * publication date with `DateTime.unsafeMake`. Falls back to the current
44
+ * timestamp when `input.date` is an empty string (rare in production data).
45
+ *
46
+ * @param input - A {@link RuntimeReleaseInput} object with raw string fields.
47
+ * @returns An `Effect` that succeeds with a `BunRelease` or fails with an
48
+ * `InvalidVersionError` when the version string cannot be parsed.
49
+ */
50
+ static fromInput(input) {
51
+ return Effect.gen(function* () {
52
+ return new BunRelease({
53
+ version: yield* SemVer.parse(input.version),
54
+ date: input.date ? DateTime.unsafeMake(input.date) : DateTime.unsafeMake(/* @__PURE__ */ new Date())
55
+ });
56
+ });
57
+ }
58
+ };
59
+
60
+ //#endregion
61
+ export { BunRelease };
@@ -0,0 +1,61 @@
1
+ import { Data, DateTime, Effect } from "effect";
2
+ import { SemVer } from "semver-effect";
3
+
4
+ //#region src/schemas/deno-release.ts
5
+ /**
6
+ * A Deno release entry with a parsed {@link SemVer} version and an
7
+ * Effect {@link DateTime.DateTime} publication date.
8
+ *
9
+ * `DenoRelease` extends `Data.TaggedClass` so instances support structural
10
+ * equality comparison and can be used safely inside Effect data structures.
11
+ * Construct instances via the {@link DenoRelease.fromInput} factory rather than
12
+ * calling `new DenoRelease(...)` directly, as the factory validates the version
13
+ * string through `SemVer.parse`.
14
+ *
15
+ * @see {@link DenoReleaseCache}
16
+ * @see {@link DenoResolver}
17
+ * @see {@link RuntimeReleaseInput}
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * import { Effect } from "effect";
22
+ * import type { DenoRelease } from "./deno-release.js";
23
+ * import { DenoRelease as DenoReleaseClass } from "./deno-release.js";
24
+ *
25
+ * const program = DenoReleaseClass.fromInput({ version: "1.44.0", date: "2024-05-23" }).pipe(
26
+ * Effect.map((release: DenoRelease) => {
27
+ * console.log(release.version.major); // 1
28
+ * console.log(release.version.minor); // 44
29
+ * console.log(release._tag); // "DenoRelease"
30
+ * }),
31
+ * );
32
+ *
33
+ * Effect.runPromise(program);
34
+ * ```
35
+ *
36
+ * @public
37
+ */
38
+ var DenoRelease = class DenoRelease extends Data.TaggedClass("DenoRelease") {
39
+ /**
40
+ * Create a {@link DenoRelease} from lean string inputs.
41
+ *
42
+ * Parses `input.version` via `SemVer.parse` and constructs the
43
+ * publication date with `DateTime.unsafeMake`. Falls back to the current
44
+ * timestamp when `input.date` is an empty string (rare in production data).
45
+ *
46
+ * @param input - A {@link RuntimeReleaseInput} object with raw string fields.
47
+ * @returns An `Effect` that succeeds with a `DenoRelease` or fails with an
48
+ * `InvalidVersionError` when the version string cannot be parsed.
49
+ */
50
+ static fromInput(input) {
51
+ return Effect.gen(function* () {
52
+ return new DenoRelease({
53
+ version: yield* SemVer.parse(input.version),
54
+ date: input.date ? DateTime.unsafeMake(input.date) : DateTime.unsafeMake(/* @__PURE__ */ new Date())
55
+ });
56
+ });
57
+ }
58
+ };
59
+
60
+ //#endregion
61
+ export { DenoRelease };
@@ -0,0 +1,74 @@
1
+ import { Schema } from "effect";
2
+
3
+ //#region src/schemas/github.ts
4
+ /**
5
+ * The `commit` sub-object returned for each entry in the GitHub tags API.
6
+ *
7
+ * Used as a nested field within {@link GitHubTag}.
8
+ *
9
+ * @see {@link GitHubClient}
10
+ *
11
+ * @public
12
+ */
13
+ const GitHubTagCommit = Schema.Struct({
14
+ sha: Schema.String,
15
+ url: Schema.String
16
+ });
17
+ /**
18
+ * A single tag entry as returned by the GitHub REST API
19
+ * (`GET /repos/{owner}/{repo}/tags`).
20
+ *
21
+ * Consumed by {@link GitHubClient} when fetching Bun and Deno release tags.
22
+ *
23
+ * @see {@link GitHubClient}
24
+ * @see {@link GitHubTagList}
25
+ *
26
+ * @public
27
+ */
28
+ const GitHubTag = Schema.Struct({
29
+ name: Schema.String,
30
+ zipball_url: Schema.String,
31
+ tarball_url: Schema.String,
32
+ commit: GitHubTagCommit,
33
+ node_id: Schema.String
34
+ });
35
+ /**
36
+ * The decoded response body from `GET /repos/{owner}/{repo}/tags`.
37
+ *
38
+ * @see {@link GitHubClient}
39
+ * @see {@link GitHubTag}
40
+ *
41
+ * @public
42
+ */
43
+ const GitHubTagList = Schema.Array(GitHubTag);
44
+ /**
45
+ * A single release entry as returned by the GitHub REST API
46
+ * (`GET /repos/{owner}/{repo}/releases`).
47
+ *
48
+ * Consumed by {@link GitHubClient} when fetching Deno releases that carry
49
+ * publication timestamps.
50
+ *
51
+ * @see {@link GitHubClient}
52
+ * @see {@link GitHubReleaseList}
53
+ *
54
+ * @public
55
+ */
56
+ const GitHubRelease = Schema.Struct({
57
+ tag_name: Schema.String,
58
+ name: Schema.NullOr(Schema.String),
59
+ draft: Schema.Boolean,
60
+ prerelease: Schema.Boolean,
61
+ published_at: Schema.NullOr(Schema.String)
62
+ });
63
+ /**
64
+ * The decoded response body from `GET /repos/{owner}/{repo}/releases`.
65
+ *
66
+ * @see {@link GitHubClient}
67
+ * @see {@link GitHubRelease}
68
+ *
69
+ * @public
70
+ */
71
+ const GitHubReleaseList = Schema.Array(GitHubRelease);
72
+
73
+ //#endregion
74
+ export { GitHubReleaseList, GitHubTagList };
@@ -0,0 +1,130 @@
1
+ import { DateTime, Effect, Ref, Schema } from "effect";
2
+ import { SemVer } from "semver-effect";
3
+
4
+ //#region src/schemas/node-release.ts
5
+ /**
6
+ * Lean input schema used to construct {@link NodeRelease} instances from
7
+ * bundled default data files and the Node.js dist API response.
8
+ *
9
+ * The `version` and `npm` fields are raw version strings validated by
10
+ * `SemVer.parse`; `date` is a date string accepted by
11
+ * `DateTime.unsafeMake`.
12
+ *
13
+ * @see {@link NodeRelease.fromInput}
14
+ * @see {@link NodeVersionFetcher}
15
+ *
16
+ * @public
17
+ */
18
+ const NodeReleaseInput = Schema.Struct({
19
+ version: Schema.String,
20
+ npm: Schema.String,
21
+ date: Schema.String
22
+ });
23
+ /**
24
+ * A Node.js release entry with parsed version, bundled npm version,
25
+ * publication date, and a shared reference to the Node.js release schedule.
26
+ *
27
+ * `NodeRelease` is a plain class rather than a `Data.TaggedClass` because it
28
+ * holds a `Ref<NodeSchedule>` — mutable Effect references break structural
29
+ * equality semantics, making `Data.TaggedClass` unsuitable here. The
30
+ * `_tag` field is set manually to preserve tagged-union compatibility.
31
+ *
32
+ * Use {@link NodeRelease.fromInput} to construct instances; call
33
+ * {@link NodeRelease.phase} or {@link NodeRelease.lts} to query the lifecycle
34
+ * state of the release at a given point in time.
35
+ *
36
+ * @see {@link NodeReleaseCache}
37
+ * @see {@link NodeResolver}
38
+ * @see {@link NodeSchedule}
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * import { Effect, Ref } from "effect";
43
+ * import type { NodePhase } from "./common.js";
44
+ * import type { NodeRelease } from "./node-release.js";
45
+ * import { NodeRelease as NodeReleaseClass } from "./node-release.js";
46
+ * import { NodeSchedule } from "./node-schedule.js";
47
+ *
48
+ * const program = Effect.gen(function* () {
49
+ * const schedule = NodeSchedule.fromData({
50
+ * v20: { start: "2023-04-18", lts: "2023-10-24", end: "2026-04-30" },
51
+ * });
52
+ * const scheduleRef = yield* Ref.make(schedule);
53
+ *
54
+ * const release: NodeRelease = yield* NodeReleaseClass.fromInput(
55
+ * { version: "v20.0.0", npm: "9.6.4", date: "2023-04-18" },
56
+ * scheduleRef,
57
+ * );
58
+ *
59
+ * const phase: NodePhase | null = yield* release.phase();
60
+ * const isLts: boolean = yield* release.lts();
61
+ * console.log(phase); // e.g. "active-lts"
62
+ * console.log(isLts); // true
63
+ * });
64
+ *
65
+ * Effect.runPromise(program);
66
+ * ```
67
+ *
68
+ * @public
69
+ */
70
+ var NodeRelease = class NodeRelease {
71
+ version;
72
+ npm;
73
+ date;
74
+ scheduleRef;
75
+ _tag = "NodeRelease";
76
+ constructor(version, npm, date, scheduleRef) {
77
+ this.version = version;
78
+ this.npm = npm;
79
+ this.date = date;
80
+ this.scheduleRef = scheduleRef;
81
+ }
82
+ /**
83
+ * Determine this release's lifecycle phase at the given point in time.
84
+ *
85
+ * Reads the current value of the shared `scheduleRef` and delegates to
86
+ * {@link NodeSchedule.phaseFor}. Defaults to the current wall-clock time
87
+ * when `now` is omitted.
88
+ *
89
+ * @param now - Optional reference time; defaults to `new Date()`.
90
+ * @returns An `Effect` that resolves to a {@link NodePhase} string, or
91
+ * `null` when the major version is not present in the schedule or has
92
+ * not yet been released.
93
+ */
94
+ phase(now) {
95
+ const effectiveNow = now ?? DateTime.unsafeMake(/* @__PURE__ */ new Date());
96
+ return Effect.gen(this, function* () {
97
+ return yield* (yield* Ref.get(this.scheduleRef)).phaseFor(this.version.major, effectiveNow);
98
+ });
99
+ }
100
+ /**
101
+ * Whether this release is currently in Long-Term Support.
102
+ *
103
+ * Returns `true` for both `"active-lts"` and `"maintenance-lts"` phases.
104
+ * Defaults to the current wall-clock time when `now` is omitted.
105
+ *
106
+ * @param now - Optional reference time; defaults to `new Date()`.
107
+ */
108
+ lts(now) {
109
+ return this.phase(now).pipe(Effect.map((p) => p === "active-lts" || p === "maintenance-lts"));
110
+ }
111
+ /**
112
+ * Create a {@link NodeRelease} from lean string inputs.
113
+ *
114
+ * Parses `input.version` and `input.npm` via `SemVer.parse` and
115
+ * constructs the publication date with `DateTime.unsafeMake`.
116
+ *
117
+ * @param input - A {@link NodeReleaseInput} object with raw string fields.
118
+ * @param scheduleRef - A shared `Ref<NodeSchedule>` injected by the cache layer.
119
+ * @returns An `Effect` that succeeds with a `NodeRelease` or fails with an
120
+ * `InvalidVersionError` when either version string cannot be parsed.
121
+ */
122
+ static fromInput(input, scheduleRef) {
123
+ return Effect.gen(function* () {
124
+ return new NodeRelease(yield* SemVer.parse(input.version), yield* SemVer.parse(input.npm), DateTime.unsafeMake(input.date), scheduleRef);
125
+ });
126
+ }
127
+ };
128
+
129
+ //#endregion
130
+ export { NodeRelease };
@@ -0,0 +1,110 @@
1
+ import { Data, DateTime, Effect, Option } from "effect";
2
+
3
+ //#region src/schemas/node-schedule.ts
4
+ /**
5
+ * Immutable snapshot of the Node.js release schedule.
6
+ *
7
+ * Holds a `ReadonlyArray<NodeScheduleEntry>` parsed from the raw
8
+ * {@link NodeScheduleData} fetched by {@link NodeScheduleFetcher}. A single
9
+ * `NodeSchedule` instance lives inside a `Ref<NodeSchedule>` that is shared
10
+ * across all {@link NodeRelease} instances so that schedule updates propagate
11
+ * without rebuilding the release cache.
12
+ *
13
+ * `NodeSchedule` extends `Data.TaggedClass` and therefore supports structural
14
+ * equality — two schedules built from identical data compare as equal.
15
+ *
16
+ * @see {@link NodeRelease}
17
+ * @see {@link NodeScheduleFetcher}
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * import { Effect } from "effect";
22
+ * import type { NodePhase } from "./common.js";
23
+ * import type { NodeScheduleData } from "./node-schedule.js";
24
+ * import { NodeSchedule } from "./node-schedule.js";
25
+ *
26
+ * const data: NodeScheduleData = {
27
+ * v20: {
28
+ * start: "2023-04-18",
29
+ * lts: "2023-10-24",
30
+ * maintenance: "2024-10-22",
31
+ * end: "2026-04-30",
32
+ * codename: "Iron",
33
+ * },
34
+ * };
35
+ *
36
+ * const schedule = NodeSchedule.fromData(data);
37
+ *
38
+ * const program = schedule.phaseFor(20, new Date("2024-01-01") as any).pipe(
39
+ * Effect.map((phase: NodePhase | null) => {
40
+ * console.log(phase); // "active-lts"
41
+ * }),
42
+ * );
43
+ *
44
+ * Effect.runPromise(program);
45
+ * ```
46
+ *
47
+ * @public
48
+ */
49
+ var NodeSchedule = class NodeSchedule extends Data.TaggedClass("NodeSchedule") {
50
+ /**
51
+ * Parse raw {@link NodeScheduleData} into a `NodeSchedule` instance.
52
+ *
53
+ * Iterates over every key of the form `"vNN"`, converts ISO date strings
54
+ * to `DateTime.DateTime`, and normalises missing codenames to `""`.
55
+ *
56
+ * @param data - The raw JSON object fetched from the Node.js release repo.
57
+ * @returns A fully constructed, immutable `NodeSchedule`.
58
+ */
59
+ static fromData(data) {
60
+ const entries = [];
61
+ for (const [key, value] of Object.entries(data)) {
62
+ const major = Number.parseInt(key.replace("v", ""), 10);
63
+ if (Number.isNaN(major)) continue;
64
+ entries.push({
65
+ major,
66
+ start: DateTime.unsafeMake(value.start),
67
+ lts: value.lts ? DateTime.unsafeMake(value.lts) : null,
68
+ maintenance: value.maintenance ? DateTime.unsafeMake(value.maintenance) : null,
69
+ end: DateTime.unsafeMake(value.end),
70
+ codename: value.codename ?? ""
71
+ });
72
+ }
73
+ return new NodeSchedule({ entries });
74
+ }
75
+ /**
76
+ * Determine the current {@link NodePhase} for a given major version number
77
+ * at the specified point in time.
78
+ *
79
+ * Returns `null` when the major is not present in the schedule or when
80
+ * `now` is before the release's start date.
81
+ *
82
+ * @param major - The Node.js major version number (e.g. `20`).
83
+ * @param now - The reference `DateTime` against which phases are evaluated.
84
+ */
85
+ phaseFor(major, now) {
86
+ return Effect.sync(() => {
87
+ const entry = this.entries.find((e) => e.major === major);
88
+ if (!entry) return null;
89
+ if (DateTime.lessThan(now, entry.start)) return null;
90
+ if (DateTime.greaterThanOrEqualTo(now, entry.end)) return "end-of-life";
91
+ if (entry.maintenance && DateTime.greaterThanOrEqualTo(now, entry.maintenance)) return "maintenance-lts";
92
+ if (entry.lts && DateTime.greaterThanOrEqualTo(now, entry.lts)) return "active-lts";
93
+ return "current";
94
+ });
95
+ }
96
+ /**
97
+ * Look up the {@link NodeScheduleEntry} for a given major version number.
98
+ *
99
+ * Returns `Option.none()` when the major is not present in the schedule.
100
+ *
101
+ * @param major - The Node.js major version number (e.g. `20`).
102
+ */
103
+ entryFor(major) {
104
+ const entry = this.entries.find((e) => e.major === major);
105
+ return entry ? Option.some(entry) : Option.none();
106
+ }
107
+ };
108
+
109
+ //#endregion
110
+ export { NodeSchedule };
@@ -0,0 +1,68 @@
1
+ import { Schema } from "effect";
2
+
3
+ //#region src/schemas/node.ts
4
+ /**
5
+ * A single entry in the Node.js distribution index
6
+ * (`https://nodejs.org/dist/index.json`).
7
+ *
8
+ * Decoded by {@link NodeVersionFetcherLive} when fetching the full list of
9
+ * available Node.js releases from the official distribution server.
10
+ *
11
+ * @internal
12
+ */
13
+ const NodeDistVersion = Schema.Struct({
14
+ version: Schema.String,
15
+ date: Schema.String,
16
+ files: Schema.Array(Schema.String),
17
+ npm: Schema.optional(Schema.String),
18
+ v8: Schema.optional(Schema.String),
19
+ uv: Schema.optional(Schema.String),
20
+ zlib: Schema.optional(Schema.String),
21
+ openssl: Schema.optional(Schema.String),
22
+ modules: Schema.optional(Schema.String),
23
+ lts: Schema.Union(Schema.Literal(false), Schema.String),
24
+ security: Schema.Boolean
25
+ });
26
+ /**
27
+ * The full decoded body of `https://nodejs.org/dist/index.json`.
28
+ *
29
+ * Decoded by {@link NodeVersionFetcherLive} before being mapped into
30
+ * {@link NodeRelease} instances.
31
+ *
32
+ * @internal
33
+ */
34
+ const NodeDistIndex = Schema.Array(NodeDistVersion);
35
+ /**
36
+ * A single entry in the Node.js release schedule JSON fetched by
37
+ * {@link NodeScheduleFetcherLive}.
38
+ *
39
+ * All date-like fields are optional because odd-numbered major lines
40
+ * (e.g. v21) never enter LTS.
41
+ *
42
+ * @internal
43
+ */
44
+ const ReleaseScheduleEntry = Schema.Struct({
45
+ start: Schema.String,
46
+ lts: Schema.optional(Schema.String),
47
+ maintenance: Schema.optional(Schema.String),
48
+ end: Schema.String,
49
+ codename: Schema.optional(Schema.String)
50
+ });
51
+ /**
52
+ * The full decoded body of the Node.js release schedule JSON fetched by
53
+ * {@link NodeScheduleFetcherLive}.
54
+ *
55
+ * Keyed by major version string (e.g. `"v20"`); values are
56
+ * {@link ReleaseScheduleEntry} objects. After decoding, this record is handed
57
+ * to {@link NodeSchedule.fromData} to produce an immutable
58
+ * {@link NodeSchedule}.
59
+ *
60
+ * @internal
61
+ */
62
+ const NodeReleaseSchedule = Schema.Record({
63
+ key: Schema.String,
64
+ value: ReleaseScheduleEntry
65
+ });
66
+
67
+ //#endregion
68
+ export { NodeDistIndex, NodeReleaseSchedule };
@@ -0,0 +1,33 @@
1
+ import { Context } from "effect";
2
+
3
+ //#region src/services/BunReleaseCache.ts
4
+ /**
5
+ * Specialisation of {@link RuntimeCache} for Bun release objects.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import type { BunRelease } from "runtime-resolver";
10
+ * import { BunReleaseCache, OfflineBunCacheLive } from "runtime-resolver";
11
+ * import { Effect } from "effect";
12
+ *
13
+ * const program = Effect.gen(function* () {
14
+ * const cache = yield* BunReleaseCache;
15
+ * const releases = yield* cache.releases();
16
+ * console.log(releases.length);
17
+ * });
18
+ *
19
+ * Effect.runPromise(program.pipe(Effect.provide(OfflineBunCacheLive)));
20
+ * ```
21
+ *
22
+ * @see {@link BunRelease}
23
+ * @see {@link RuntimeCache}
24
+ * @see {@link AutoBunCacheLive}
25
+ * @see {@link FreshBunCacheLive}
26
+ * @see {@link OfflineBunCacheLive}
27
+ *
28
+ * @public
29
+ */
30
+ var BunReleaseCache = class extends Context.Tag("runtime-resolver/BunReleaseCache")() {};
31
+
32
+ //#endregion
33
+ export { BunReleaseCache };
@@ -0,0 +1,36 @@
1
+ import { Context } from "effect";
2
+
3
+ //#region src/services/BunResolver.ts
4
+ /**
5
+ * Service for resolving Bun runtime versions against the cached
6
+ * release index.
7
+ *
8
+ * For a one-shot Promise-based API see {@link resolveBun}.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import type { ResolvedVersions } from "runtime-resolver";
13
+ * import { BunResolver, BunResolverLive } from "runtime-resolver";
14
+ * import { Effect } from "effect";
15
+ *
16
+ * const program = Effect.gen(function* () {
17
+ * const resolver = yield* BunResolver;
18
+ * const result = yield* resolver.resolve({ semverRange: "^1.0.0", increments: "minor" });
19
+ * console.log(result.latest);
20
+ * console.log(result.versions);
21
+ * });
22
+ *
23
+ * Effect.runPromise(program.pipe(Effect.provide(BunResolverLive)));
24
+ * ```
25
+ *
26
+ * @see {@link BunResolverLive}
27
+ * @see {@link resolveBun}
28
+ * @see {@link BunResolverOptions}
29
+ * @see {@link ResolvedVersions}
30
+ *
31
+ * @public
32
+ */
33
+ var BunResolver = class extends Context.Tag("runtime-resolver/BunResolver")() {};
34
+
35
+ //#endregion
36
+ export { BunResolver };
@@ -0,0 +1,41 @@
1
+ import { Context } from "effect";
2
+
3
+ //#region src/services/BunVersionFetcher.ts
4
+ /**
5
+ * Service for fetching Bun release data from the GitHub API.
6
+ *
7
+ * Retrieves both the parsed semver version list and the raw release input
8
+ * records needed to populate a {@link BunReleaseCache}. The live
9
+ * implementation queries the `oven-sh/bun` GitHub repository via
10
+ * {@link GitHubClient}.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import type { RuntimeReleaseInput } from "runtime-resolver";
15
+ * import { BunVersionFetcher, BunVersionFetcherLive, GitHubAutoAuth } from "runtime-resolver";
16
+ * import { Effect } from "effect";
17
+ *
18
+ * const program = Effect.gen(function* () {
19
+ * const fetcher = yield* BunVersionFetcher;
20
+ * const { versions, inputs } = yield* fetcher.fetch();
21
+ * console.log(`Fetched ${versions.length} Bun releases`);
22
+ * });
23
+ *
24
+ * Effect.runPromise(
25
+ * program.pipe(Effect.provide(BunVersionFetcherLive), Effect.provide(GitHubAutoAuth)),
26
+ * );
27
+ * ```
28
+ *
29
+ * @see {@link BunVersionFetcherLive}
30
+ * @see {@link BunReleaseCache}
31
+ * @see {@link AuthenticationError}
32
+ * @see {@link NetworkError}
33
+ * @see {@link ParseError}
34
+ * @see {@link RateLimitError}
35
+ *
36
+ * @public
37
+ */
38
+ var BunVersionFetcher = class extends Context.Tag("runtime-resolver/BunVersionFetcher")() {};
39
+
40
+ //#endregion
41
+ export { BunVersionFetcher };
@@ -0,0 +1,33 @@
1
+ import { Context } from "effect";
2
+
3
+ //#region src/services/DenoReleaseCache.ts
4
+ /**
5
+ * Specialisation of {@link RuntimeCache} for Deno release objects.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import type { DenoRelease } from "runtime-resolver";
10
+ * import { DenoReleaseCache, OfflineDenoCacheLive } from "runtime-resolver";
11
+ * import { Effect } from "effect";
12
+ *
13
+ * const program = Effect.gen(function* () {
14
+ * const cache = yield* DenoReleaseCache;
15
+ * const latest = yield* cache.latest();
16
+ * console.log(latest.version.toString());
17
+ * });
18
+ *
19
+ * Effect.runPromise(program.pipe(Effect.provide(OfflineDenoCacheLive)));
20
+ * ```
21
+ *
22
+ * @see {@link DenoRelease}
23
+ * @see {@link RuntimeCache}
24
+ * @see {@link AutoDenoCacheLive}
25
+ * @see {@link FreshDenoCacheLive}
26
+ * @see {@link OfflineDenoCacheLive}
27
+ *
28
+ * @public
29
+ */
30
+ var DenoReleaseCache = class extends Context.Tag("runtime-resolver/DenoReleaseCache")() {};
31
+
32
+ //#endregion
33
+ export { DenoReleaseCache };
@@ -0,0 +1,36 @@
1
+ import { Context } from "effect";
2
+
3
+ //#region src/services/DenoResolver.ts
4
+ /**
5
+ * Service for resolving Deno runtime versions against the cached
6
+ * release index.
7
+ *
8
+ * For a one-shot Promise-based API see {@link resolveDeno}.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import type { ResolvedVersions } from "runtime-resolver";
13
+ * import { DenoResolver, DenoResolverLive } from "runtime-resolver";
14
+ * import { Effect } from "effect";
15
+ *
16
+ * const program = Effect.gen(function* () {
17
+ * const resolver = yield* DenoResolver;
18
+ * const result = yield* resolver.resolve({ semverRange: "^2.0.0", increments: "minor" });
19
+ * console.log(result.latest);
20
+ * console.log(result.versions);
21
+ * });
22
+ *
23
+ * Effect.runPromise(program.pipe(Effect.provide(DenoResolverLive)));
24
+ * ```
25
+ *
26
+ * @see {@link DenoResolverLive}
27
+ * @see {@link resolveDeno}
28
+ * @see {@link DenoResolverOptions}
29
+ * @see {@link ResolvedVersions}
30
+ *
31
+ * @public
32
+ */
33
+ var DenoResolver = class extends Context.Tag("runtime-resolver/DenoResolver")() {};
34
+
35
+ //#endregion
36
+ export { DenoResolver };