runtime-resolver 0.3.12 → 0.3.13

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 (128) hide show
  1. package/bin/runtime-resolver.d.ts +1 -0
  2. package/bin/runtime-resolver.js +30 -261
  3. package/bin/runtime-resolver.js.map +1 -0
  4. package/cli/commands/resolve.js +240 -0
  5. package/cli/commands/resolve.js.map +1 -0
  6. package/cli/schemas/json-schema.js +13 -0
  7. package/cli/schemas/json-schema.js.map +1 -0
  8. package/cli/schemas/response.js +87 -0
  9. package/cli/schemas/response.js.map +1 -0
  10. package/data/bun-defaults.js +851 -0
  11. package/data/bun-defaults.js.map +1 -0
  12. package/data/deno-defaults.js +1523 -0
  13. package/data/deno-defaults.js.map +1 -0
  14. package/data/node-defaults.js +4401 -0
  15. package/data/node-defaults.js.map +1 -0
  16. package/errors/AuthenticationError.js +36 -0
  17. package/errors/AuthenticationError.js.map +1 -0
  18. package/errors/CacheError.js +33 -0
  19. package/errors/CacheError.js.map +1 -0
  20. package/errors/FreshnessError.js +39 -0
  21. package/errors/FreshnessError.js.map +1 -0
  22. package/errors/InvalidInputError.js +34 -0
  23. package/errors/InvalidInputError.js.map +1 -0
  24. package/errors/NetworkError.js +35 -0
  25. package/errors/NetworkError.js.map +1 -0
  26. package/errors/ParseError.js +34 -0
  27. package/errors/ParseError.js.map +1 -0
  28. package/errors/RateLimitError.js +40 -0
  29. package/errors/RateLimitError.js.map +1 -0
  30. package/errors/VersionNotFoundError.js +38 -0
  31. package/errors/VersionNotFoundError.js.map +1 -0
  32. package/index.d.ts +2577 -2608
  33. package/index.d.ts.map +1 -0
  34. package/index.js +159 -132
  35. package/index.js.map +1 -0
  36. package/layers/AutoBunCacheLive.js +48 -0
  37. package/layers/AutoBunCacheLive.js.map +1 -0
  38. package/layers/AutoDenoCacheLive.js +48 -0
  39. package/layers/AutoDenoCacheLive.js.map +1 -0
  40. package/layers/AutoNodeCacheLive.js +59 -0
  41. package/layers/AutoNodeCacheLive.js.map +1 -0
  42. package/layers/BunReleaseCacheLive.js +26 -0
  43. package/layers/BunReleaseCacheLive.js.map +1 -0
  44. package/layers/BunResolverLive.js +86 -0
  45. package/layers/BunResolverLive.js.map +1 -0
  46. package/layers/BunVersionFetcherLive.js +56 -0
  47. package/layers/BunVersionFetcherLive.js.map +1 -0
  48. package/layers/DenoReleaseCacheLive.js +26 -0
  49. package/layers/DenoReleaseCacheLive.js.map +1 -0
  50. package/layers/DenoResolverLive.js +85 -0
  51. package/layers/DenoResolverLive.js.map +1 -0
  52. package/layers/DenoVersionFetcherLive.js +52 -0
  53. package/layers/DenoVersionFetcherLive.js.map +1 -0
  54. package/layers/FreshBunCacheLive.js +61 -0
  55. package/layers/FreshBunCacheLive.js.map +1 -0
  56. package/layers/FreshDenoCacheLive.js +61 -0
  57. package/layers/FreshDenoCacheLive.js.map +1 -0
  58. package/layers/FreshNodeCacheLive.js +56 -0
  59. package/layers/FreshNodeCacheLive.js.map +1 -0
  60. package/layers/GitHubAppAuth.js +59 -0
  61. package/layers/GitHubAppAuth.js.map +1 -0
  62. package/layers/GitHubAutoAuth.js +71 -0
  63. package/layers/GitHubAutoAuth.js.map +1 -0
  64. package/layers/GitHubClientLive.js +131 -0
  65. package/layers/GitHubClientLive.js.map +1 -0
  66. package/layers/GitHubTokenAuth.js +51 -0
  67. package/layers/GitHubTokenAuth.js.map +1 -0
  68. package/layers/NodeReleaseCacheLive.js +78 -0
  69. package/layers/NodeReleaseCacheLive.js.map +1 -0
  70. package/layers/NodeResolverLive.js +108 -0
  71. package/layers/NodeResolverLive.js.map +1 -0
  72. package/layers/NodeScheduleFetcherLive.js +38 -0
  73. package/layers/NodeScheduleFetcherLive.js.map +1 -0
  74. package/layers/NodeVersionFetcherLive.js +56 -0
  75. package/layers/NodeVersionFetcherLive.js.map +1 -0
  76. package/layers/OfflineBunCacheLive.js +41 -0
  77. package/layers/OfflineBunCacheLive.js.map +1 -0
  78. package/layers/OfflineDenoCacheLive.js +41 -0
  79. package/layers/OfflineDenoCacheLive.js.map +1 -0
  80. package/layers/OfflineNodeCacheLive.js +40 -0
  81. package/layers/OfflineNodeCacheLive.js.map +1 -0
  82. package/layers/RuntimeCacheLive.js +79 -0
  83. package/layers/RuntimeCacheLive.js.map +1 -0
  84. package/lib/retry.js +28 -0
  85. package/lib/retry.js.map +1 -0
  86. package/lib/semver.js +22 -0
  87. package/lib/semver.js.map +1 -0
  88. package/package.json +57 -68
  89. package/schemas/bun-release.js +62 -0
  90. package/schemas/bun-release.js.map +1 -0
  91. package/schemas/deno-release.js +62 -0
  92. package/schemas/deno-release.js.map +1 -0
  93. package/schemas/github.js +75 -0
  94. package/schemas/github.js.map +1 -0
  95. package/schemas/node-release.js +131 -0
  96. package/schemas/node-release.js.map +1 -0
  97. package/schemas/node-schedule.js +111 -0
  98. package/schemas/node-schedule.js.map +1 -0
  99. package/schemas/node.js +69 -0
  100. package/schemas/node.js.map +1 -0
  101. package/services/BunReleaseCache.js +34 -0
  102. package/services/BunReleaseCache.js.map +1 -0
  103. package/services/BunResolver.js +37 -0
  104. package/services/BunResolver.js.map +1 -0
  105. package/services/BunVersionFetcher.js +42 -0
  106. package/services/BunVersionFetcher.js.map +1 -0
  107. package/services/DenoReleaseCache.js +34 -0
  108. package/services/DenoReleaseCache.js.map +1 -0
  109. package/services/DenoResolver.js +37 -0
  110. package/services/DenoResolver.js.map +1 -0
  111. package/services/DenoVersionFetcher.js +42 -0
  112. package/services/DenoVersionFetcher.js.map +1 -0
  113. package/services/GitHubClient.js +41 -0
  114. package/services/GitHubClient.js.map +1 -0
  115. package/services/NodeReleaseCache.js +42 -0
  116. package/services/NodeReleaseCache.js.map +1 -0
  117. package/services/NodeResolver.js +45 -0
  118. package/services/NodeResolver.js.map +1 -0
  119. package/services/NodeScheduleFetcher.js +39 -0
  120. package/services/NodeScheduleFetcher.js.map +1 -0
  121. package/services/NodeVersionFetcher.js +40 -0
  122. package/services/NodeVersionFetcher.js.map +1 -0
  123. package/services/OctokitInstance.js +45 -0
  124. package/services/OctokitInstance.js.map +1 -0
  125. package/tsdoc-metadata.json +11 -11
  126. package/612.js +0 -23
  127. package/711.js +0 -7554
  128. package/json-schema.js +0 -95
@@ -0,0 +1,75 @@
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 };
75
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","names":[],"sources":["../../../../src/schemas/github.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\n/**\n * The `commit` sub-object returned for each entry in the GitHub tags API.\n *\n * Used as a nested field within {@link GitHubTag}.\n *\n * @see {@link GitHubClient}\n *\n * @public\n */\nexport const GitHubTagCommit = Schema.Struct({\n\tsha: Schema.String,\n\turl: Schema.String,\n});\n\n/**\n * A single tag entry as returned by the GitHub REST API\n * (`GET /repos/{owner}/{repo}/tags`).\n *\n * Consumed by {@link GitHubClient} when fetching Bun and Deno release tags.\n *\n * @see {@link GitHubClient}\n * @see {@link GitHubTagList}\n *\n * @public\n */\nexport const GitHubTag = Schema.Struct({\n\tname: Schema.String,\n\tzipball_url: Schema.String,\n\ttarball_url: Schema.String,\n\tcommit: GitHubTagCommit,\n\tnode_id: Schema.String,\n});\n\n/**\n * A single tag entry as returned by the GitHub REST API.\n *\n * @see {@link GitHubClient}\n *\n * @public\n */\nexport type GitHubTag = typeof GitHubTag.Type;\n\n/**\n * The decoded response body from `GET /repos/{owner}/{repo}/tags`.\n *\n * @see {@link GitHubClient}\n * @see {@link GitHubTag}\n *\n * @public\n */\nexport const GitHubTagList = Schema.Array(GitHubTag);\n\n/**\n * The decoded response body from `GET /repos/{owner}/{repo}/tags`.\n *\n * @see {@link GitHubClient}\n *\n * @public\n */\nexport type GitHubTagList = typeof GitHubTagList.Type;\n\n/**\n * A single release entry as returned by the GitHub REST API\n * (`GET /repos/{owner}/{repo}/releases`).\n *\n * Consumed by {@link GitHubClient} when fetching Deno releases that carry\n * publication timestamps.\n *\n * @see {@link GitHubClient}\n * @see {@link GitHubReleaseList}\n *\n * @public\n */\nexport const GitHubRelease = Schema.Struct({\n\ttag_name: Schema.String,\n\tname: Schema.NullOr(Schema.String),\n\tdraft: Schema.Boolean,\n\tprerelease: Schema.Boolean,\n\tpublished_at: Schema.NullOr(Schema.String),\n});\n\n/**\n * A single release entry as returned by the GitHub REST API.\n *\n * @see {@link GitHubClient}\n *\n * @public\n */\nexport type GitHubRelease = typeof GitHubRelease.Type;\n\n/**\n * The decoded response body from `GET /repos/{owner}/{repo}/releases`.\n *\n * @see {@link GitHubClient}\n * @see {@link GitHubRelease}\n *\n * @public\n */\nexport const GitHubReleaseList = Schema.Array(GitHubRelease);\n\n/**\n * The decoded response body from `GET /repos/{owner}/{repo}/releases`.\n *\n * @see {@link GitHubClient}\n *\n * @public\n */\nexport type GitHubReleaseList = typeof GitHubReleaseList.Type;\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,kBAAkB,OAAO,OAAO;CAC5C,KAAK,OAAO;CACZ,KAAK,OAAO;AACb,CAAC;;;;;;;;;;;;AAaD,MAAa,YAAY,OAAO,OAAO;CACtC,MAAM,OAAO;CACb,aAAa,OAAO;CACpB,aAAa,OAAO;CACpB,QAAQ;CACR,SAAS,OAAO;AACjB,CAAC;;;;;;;;;AAmBD,MAAa,gBAAgB,OAAO,MAAM,SAAS;;;;;;;;;;;;;AAuBnD,MAAa,gBAAgB,OAAO,OAAO;CAC1C,UAAU,OAAO;CACjB,MAAM,OAAO,OAAO,OAAO,MAAM;CACjC,OAAO,OAAO;CACd,YAAY,OAAO;CACnB,cAAc,OAAO,OAAO,OAAO,MAAM;AAC1C,CAAC;;;;;;;;;AAmBD,MAAa,oBAAoB,OAAO,MAAM,aAAa"}
@@ -0,0 +1,131 @@
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 };
131
+ //# sourceMappingURL=node-release.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-release.js","names":[],"sources":["../../../../src/schemas/node-release.ts"],"sourcesContent":["import { DateTime, Effect, Ref, Schema } from \"effect\";\nimport type { InvalidVersionError } from \"semver-effect\";\nimport { SemVer } from \"semver-effect\";\nimport type { NodePhase } from \"./common.js\";\nimport type { NodeSchedule } from \"./node-schedule.js\";\n\n/**\n * Lean input schema used to construct {@link NodeRelease} instances from\n * bundled default data files and the Node.js dist API response.\n *\n * The `version` and `npm` fields are raw version strings validated by\n * `SemVer.parse`; `date` is a date string accepted by\n * `DateTime.unsafeMake`.\n *\n * @see {@link NodeRelease.fromInput}\n * @see {@link NodeVersionFetcher}\n *\n * @public\n */\nexport const NodeReleaseInput = Schema.Struct({\n\tversion: Schema.String,\n\tnpm: Schema.String,\n\tdate: Schema.String,\n});\n\n/**\n * Lean input type used to construct {@link NodeRelease} instances.\n *\n * @see {@link NodeRelease.fromInput}\n *\n * @public\n */\nexport type NodeReleaseInput = typeof NodeReleaseInput.Type;\n\n/**\n * A Node.js release entry with parsed version, bundled npm version,\n * publication date, and a shared reference to the Node.js release schedule.\n *\n * `NodeRelease` is a plain class rather than a `Data.TaggedClass` because it\n * holds a `Ref<NodeSchedule>` — mutable Effect references break structural\n * equality semantics, making `Data.TaggedClass` unsuitable here. The\n * `_tag` field is set manually to preserve tagged-union compatibility.\n *\n * Use {@link NodeRelease.fromInput} to construct instances; call\n * {@link NodeRelease.phase} or {@link NodeRelease.lts} to query the lifecycle\n * state of the release at a given point in time.\n *\n * @see {@link NodeReleaseCache}\n * @see {@link NodeResolver}\n * @see {@link NodeSchedule}\n *\n * @example\n * ```typescript\n * import { Effect, Ref } from \"effect\";\n * import type { NodePhase } from \"./common.js\";\n * import type { NodeRelease } from \"./node-release.js\";\n * import { NodeRelease as NodeReleaseClass } from \"./node-release.js\";\n * import { NodeSchedule } from \"./node-schedule.js\";\n *\n * const program = Effect.gen(function* () {\n * const schedule = NodeSchedule.fromData({\n * v20: { start: \"2023-04-18\", lts: \"2023-10-24\", end: \"2026-04-30\" },\n * });\n * const scheduleRef = yield* Ref.make(schedule);\n *\n * const release: NodeRelease = yield* NodeReleaseClass.fromInput(\n * { version: \"v20.0.0\", npm: \"9.6.4\", date: \"2023-04-18\" },\n * scheduleRef,\n * );\n *\n * const phase: NodePhase | null = yield* release.phase();\n * const isLts: boolean = yield* release.lts();\n * console.log(phase); // e.g. \"active-lts\"\n * console.log(isLts); // true\n * });\n *\n * Effect.runPromise(program);\n * ```\n *\n * @public\n */\nexport class NodeRelease {\n\treadonly _tag = \"NodeRelease\" as const;\n\n\tconstructor(\n\t\treadonly version: SemVer,\n\t\treadonly npm: SemVer,\n\t\treadonly date: DateTime.DateTime,\n\t\treadonly scheduleRef: Ref.Ref<NodeSchedule>,\n\t) {}\n\n\t/**\n\t * Determine this release's lifecycle phase at the given point in time.\n\t *\n\t * Reads the current value of the shared `scheduleRef` and delegates to\n\t * {@link NodeSchedule.phaseFor}. Defaults to the current wall-clock time\n\t * when `now` is omitted.\n\t *\n\t * @param now - Optional reference time; defaults to `new Date()`.\n\t * @returns An `Effect` that resolves to a {@link NodePhase} string, or\n\t * `null` when the major version is not present in the schedule or has\n\t * not yet been released.\n\t */\n\tphase(now?: DateTime.DateTime): Effect.Effect<NodePhase | null> {\n\t\tconst effectiveNow = now ?? DateTime.unsafeMake(new Date());\n\t\treturn Effect.gen(this, function* () {\n\t\t\tconst schedule = yield* Ref.get(this.scheduleRef);\n\t\t\treturn yield* schedule.phaseFor(this.version.major, effectiveNow);\n\t\t});\n\t}\n\n\t/**\n\t * Whether this release is currently in Long-Term Support.\n\t *\n\t * Returns `true` for both `\"active-lts\"` and `\"maintenance-lts\"` phases.\n\t * Defaults to the current wall-clock time when `now` is omitted.\n\t *\n\t * @param now - Optional reference time; defaults to `new Date()`.\n\t */\n\tlts(now?: DateTime.DateTime): Effect.Effect<boolean> {\n\t\treturn this.phase(now).pipe(Effect.map((p) => p === \"active-lts\" || p === \"maintenance-lts\"));\n\t}\n\n\t/**\n\t * Create a {@link NodeRelease} from lean string inputs.\n\t *\n\t * Parses `input.version` and `input.npm` via `SemVer.parse` and\n\t * constructs the publication date with `DateTime.unsafeMake`.\n\t *\n\t * @param input - A {@link NodeReleaseInput} object with raw string fields.\n\t * @param scheduleRef - A shared `Ref<NodeSchedule>` injected by the cache layer.\n\t * @returns An `Effect` that succeeds with a `NodeRelease` or fails with an\n\t * `InvalidVersionError` when either version string cannot be parsed.\n\t */\n\tstatic fromInput(\n\t\tinput: NodeReleaseInput,\n\t\tscheduleRef: Ref.Ref<NodeSchedule>,\n\t): Effect.Effect<NodeRelease, InvalidVersionError> {\n\t\treturn Effect.gen(function* () {\n\t\t\tconst version = yield* SemVer.parse(input.version);\n\t\t\tconst npm = yield* SemVer.parse(input.npm);\n\t\t\tconst date = DateTime.unsafeMake(input.date);\n\t\t\treturn new NodeRelease(version, npm, date, scheduleRef);\n\t\t});\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAmBA,MAAa,mBAAmB,OAAO,OAAO;CAC7C,SAAS,OAAO;CAChB,KAAK,OAAO;CACZ,MAAM,OAAO;AACd,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0DD,IAAa,cAAb,MAAa,YAAY;CAId;CACA;CACA;CACA;CANV,AAAS,OAAO;CAEhB,YACC,AAAS,SACT,AAAS,KACT,AAAS,MACT,AAAS,aACR;EAJQ;EACA;EACA;EACA;CACP;;;;;;;;;;;;;CAcH,MAAM,KAA0D;EAC/D,MAAM,eAAe,OAAO,SAAS,2BAAW,IAAI,KAAK,CAAC;EAC1D,OAAO,OAAO,IAAI,MAAM,aAAa;GAEpC,OAAO,QAAO,OADU,IAAI,IAAI,KAAK,WAAW,EAC1B,CAAC,SAAS,KAAK,QAAQ,OAAO,YAAY;EACjE,CAAC;CACF;;;;;;;;;CAUA,IAAI,KAAiD;EACpD,OAAO,KAAK,MAAM,GAAG,CAAC,CAAC,KAAK,OAAO,KAAK,MAAM,MAAM,gBAAgB,MAAM,iBAAiB,CAAC;CAC7F;;;;;;;;;;;;CAaA,OAAO,UACN,OACA,aACkD;EAClD,OAAO,OAAO,IAAI,aAAa;GAI9B,OAAO,IAAI,YAAY,OAHA,OAAO,MAAM,MAAM,OAAO,GAGjB,OAFb,OAAO,MAAM,MAAM,GAAG,GAC5B,SAAS,WAAW,MAAM,IACC,GAAG,WAAW;EACvD,CAAC;CACF;AACD"}
@@ -0,0 +1,111 @@
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 };
111
+ //# sourceMappingURL=node-schedule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-schedule.js","names":[],"sources":["../../../../src/schemas/node-schedule.ts"],"sourcesContent":["import { Data, DateTime, Effect, Option } from \"effect\";\nimport type { NodePhase } from \"./common.js\";\n\n/**\n * A single entry in the Node.js release schedule, representing one major\n * release line's lifecycle dates and optional LTS codename.\n *\n * All date fields have already been converted from ISO strings to Effect\n * `DateTime.DateTime` values by {@link NodeSchedule.fromData}.\n *\n * @see {@link NodeSchedule}\n * @see {@link NodeSchedule.phaseFor}\n *\n * @public\n */\nexport interface NodeScheduleEntry {\n\treadonly major: number;\n\treadonly start: DateTime.DateTime;\n\treadonly lts: DateTime.DateTime | null;\n\treadonly maintenance: DateTime.DateTime | null;\n\treadonly end: DateTime.DateTime;\n\treadonly codename: string;\n}\n\n/**\n * Raw schedule format as fetched from the Node.js Release GitHub repository\n * (`nodejs/Release`).\n *\n * This is the intermediate type between the {@link NodeScheduleFetcher} layer\n * and the {@link NodeSchedule} class. Date values are plain ISO strings; the\n * `NodeSchedule.fromData` factory converts them to `DateTime`.\n *\n * @see {@link NodeSchedule.fromData}\n * @see {@link NodeScheduleFetcher}\n *\n * @public\n */\nexport type NodeScheduleData = Record<\n\tstring,\n\t{\n\t\treadonly start: string;\n\t\treadonly lts?: string;\n\t\treadonly maintenance?: string;\n\t\treadonly end: string;\n\t\treadonly codename?: string;\n\t}\n>;\n\n/**\n * Immutable snapshot of the Node.js release schedule.\n *\n * Holds a `ReadonlyArray<NodeScheduleEntry>` parsed from the raw\n * {@link NodeScheduleData} fetched by {@link NodeScheduleFetcher}. A single\n * `NodeSchedule` instance lives inside a `Ref<NodeSchedule>` that is shared\n * across all {@link NodeRelease} instances so that schedule updates propagate\n * without rebuilding the release cache.\n *\n * `NodeSchedule` extends `Data.TaggedClass` and therefore supports structural\n * equality — two schedules built from identical data compare as equal.\n *\n * @see {@link NodeRelease}\n * @see {@link NodeScheduleFetcher}\n *\n * @example\n * ```typescript\n * import { Effect } from \"effect\";\n * import type { NodePhase } from \"./common.js\";\n * import type { NodeScheduleData } from \"./node-schedule.js\";\n * import { NodeSchedule } from \"./node-schedule.js\";\n *\n * const data: NodeScheduleData = {\n * v20: {\n * start: \"2023-04-18\",\n * lts: \"2023-10-24\",\n * maintenance: \"2024-10-22\",\n * end: \"2026-04-30\",\n * codename: \"Iron\",\n * },\n * };\n *\n * const schedule = NodeSchedule.fromData(data);\n *\n * const program = schedule.phaseFor(20, new Date(\"2024-01-01\") as any).pipe(\n * Effect.map((phase: NodePhase | null) => {\n * console.log(phase); // \"active-lts\"\n * }),\n * );\n *\n * Effect.runPromise(program);\n * ```\n *\n * @public\n */\nexport class NodeSchedule extends Data.TaggedClass(\"NodeSchedule\")<{\n\treadonly entries: ReadonlyArray<NodeScheduleEntry>;\n}> {\n\t/**\n\t * Parse raw {@link NodeScheduleData} into a `NodeSchedule` instance.\n\t *\n\t * Iterates over every key of the form `\"vNN\"`, converts ISO date strings\n\t * to `DateTime.DateTime`, and normalises missing codenames to `\"\"`.\n\t *\n\t * @param data - The raw JSON object fetched from the Node.js release repo.\n\t * @returns A fully constructed, immutable `NodeSchedule`.\n\t */\n\tstatic fromData(data: NodeScheduleData): NodeSchedule {\n\t\tconst entries: NodeScheduleEntry[] = [];\n\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\tconst major = Number.parseInt(key.replace(\"v\", \"\"), 10);\n\t\t\tif (Number.isNaN(major)) continue;\n\t\t\tentries.push({\n\t\t\t\tmajor,\n\t\t\t\tstart: DateTime.unsafeMake(value.start),\n\t\t\t\tlts: value.lts ? DateTime.unsafeMake(value.lts) : null,\n\t\t\t\tmaintenance: value.maintenance ? DateTime.unsafeMake(value.maintenance) : null,\n\t\t\t\tend: DateTime.unsafeMake(value.end),\n\t\t\t\tcodename: value.codename ?? \"\",\n\t\t\t});\n\t\t}\n\t\treturn new NodeSchedule({ entries });\n\t}\n\n\t/**\n\t * Determine the current {@link NodePhase} for a given major version number\n\t * at the specified point in time.\n\t *\n\t * Returns `null` when the major is not present in the schedule or when\n\t * `now` is before the release's start date.\n\t *\n\t * @param major - The Node.js major version number (e.g. `20`).\n\t * @param now - The reference `DateTime` against which phases are evaluated.\n\t */\n\tphaseFor(major: number, now: DateTime.DateTime): Effect.Effect<NodePhase | null> {\n\t\treturn Effect.sync(() => {\n\t\t\tconst entry = this.entries.find((e) => e.major === major);\n\t\t\tif (!entry) return null;\n\n\t\t\tif (DateTime.lessThan(now, entry.start)) return null;\n\t\t\tif (DateTime.greaterThanOrEqualTo(now, entry.end)) return \"end-of-life\";\n\t\t\tif (entry.maintenance && DateTime.greaterThanOrEqualTo(now, entry.maintenance)) return \"maintenance-lts\";\n\t\t\tif (entry.lts && DateTime.greaterThanOrEqualTo(now, entry.lts)) return \"active-lts\";\n\t\t\treturn \"current\";\n\t\t});\n\t}\n\n\t/**\n\t * Look up the {@link NodeScheduleEntry} for a given major version number.\n\t *\n\t * Returns `Option.none()` when the major is not present in the schedule.\n\t *\n\t * @param major - The Node.js major version number (e.g. `20`).\n\t */\n\tentryFor(major: number): Option.Option<NodeScheduleEntry> {\n\t\tconst entry = this.entries.find((e) => e.major === major);\n\t\treturn entry ? Option.some(entry) : Option.none();\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6FA,IAAa,eAAb,MAAa,qBAAqB,KAAK,YAAY,cAAc,CAAC,CAE/D;;;;;;;;;;CAUF,OAAO,SAAS,MAAsC;EACrD,MAAM,UAA+B,CAAC;EACtC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,GAAG;GAChD,MAAM,QAAQ,OAAO,SAAS,IAAI,QAAQ,KAAK,EAAE,GAAG,EAAE;GACtD,IAAI,OAAO,MAAM,KAAK,GAAG;GACzB,QAAQ,KAAK;IACZ;IACA,OAAO,SAAS,WAAW,MAAM,KAAK;IACtC,KAAK,MAAM,MAAM,SAAS,WAAW,MAAM,GAAG,IAAI;IAClD,aAAa,MAAM,cAAc,SAAS,WAAW,MAAM,WAAW,IAAI;IAC1E,KAAK,SAAS,WAAW,MAAM,GAAG;IAClC,UAAU,MAAM,YAAY;GAC7B,CAAC;EACF;EACA,OAAO,IAAI,aAAa,EAAE,QAAQ,CAAC;CACpC;;;;;;;;;;;CAYA,SAAS,OAAe,KAAyD;EAChF,OAAO,OAAO,WAAW;GACxB,MAAM,QAAQ,KAAK,QAAQ,MAAM,MAAM,EAAE,UAAU,KAAK;GACxD,IAAI,CAAC,OAAO,OAAO;GAEnB,IAAI,SAAS,SAAS,KAAK,MAAM,KAAK,GAAG,OAAO;GAChD,IAAI,SAAS,qBAAqB,KAAK,MAAM,GAAG,GAAG,OAAO;GAC1D,IAAI,MAAM,eAAe,SAAS,qBAAqB,KAAK,MAAM,WAAW,GAAG,OAAO;GACvF,IAAI,MAAM,OAAO,SAAS,qBAAqB,KAAK,MAAM,GAAG,GAAG,OAAO;GACvE,OAAO;EACR,CAAC;CACF;;;;;;;;CASA,SAAS,OAAiD;EACzD,MAAM,QAAQ,KAAK,QAAQ,MAAM,MAAM,EAAE,UAAU,KAAK;EACxD,OAAO,QAAQ,OAAO,KAAK,KAAK,IAAI,OAAO,KAAK;CACjD;AACD"}
@@ -0,0 +1,69 @@
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 };
69
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","names":[],"sources":["../../../../src/schemas/node.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\n/**\n * A single entry in the Node.js distribution index\n * (`https://nodejs.org/dist/index.json`).\n *\n * Decoded by {@link NodeVersionFetcherLive} when fetching the full list of\n * available Node.js releases from the official distribution server.\n *\n * @internal\n */\nexport const NodeDistVersion = Schema.Struct({\n\tversion: Schema.String,\n\tdate: Schema.String,\n\tfiles: Schema.Array(Schema.String),\n\tnpm: Schema.optional(Schema.String),\n\tv8: Schema.optional(Schema.String),\n\tuv: Schema.optional(Schema.String),\n\tzlib: Schema.optional(Schema.String),\n\topenssl: Schema.optional(Schema.String),\n\tmodules: Schema.optional(Schema.String),\n\tlts: Schema.Union(Schema.Literal(false), Schema.String),\n\tsecurity: Schema.Boolean,\n});\n\n/**\n * The decoded type of a single entry in the Node.js distribution index.\n *\n * @internal\n */\nexport type NodeDistVersion = typeof NodeDistVersion.Type;\n\n/**\n * The full decoded body of `https://nodejs.org/dist/index.json`.\n *\n * Decoded by {@link NodeVersionFetcherLive} before being mapped into\n * {@link NodeRelease} instances.\n *\n * @internal\n */\nexport const NodeDistIndex = Schema.Array(NodeDistVersion);\n\n/**\n * The full decoded body of `https://nodejs.org/dist/index.json`.\n *\n * @internal\n */\nexport type NodeDistIndex = typeof NodeDistIndex.Type;\n\n/**\n * A single entry in the Node.js release schedule JSON fetched by\n * {@link NodeScheduleFetcherLive}.\n *\n * All date-like fields are optional because odd-numbered major lines\n * (e.g. v21) never enter LTS.\n *\n * @internal\n */\nexport const ReleaseScheduleEntry = Schema.Struct({\n\tstart: Schema.String,\n\tlts: Schema.optional(Schema.String),\n\tmaintenance: Schema.optional(Schema.String),\n\tend: Schema.String,\n\tcodename: Schema.optional(Schema.String),\n});\n\n/**\n * The decoded type of a single entry in the Node.js release schedule JSON.\n *\n * @internal\n */\nexport type ReleaseScheduleEntry = typeof ReleaseScheduleEntry.Type;\n\n/**\n * The full decoded body of the Node.js release schedule JSON fetched by\n * {@link NodeScheduleFetcherLive}.\n *\n * Keyed by major version string (e.g. `\"v20\"`); values are\n * {@link ReleaseScheduleEntry} objects. After decoding, this record is handed\n * to {@link NodeSchedule.fromData} to produce an immutable\n * {@link NodeSchedule}.\n *\n * @internal\n */\nexport const NodeReleaseSchedule = Schema.Record({\n\tkey: Schema.String,\n\tvalue: ReleaseScheduleEntry,\n});\n\n/**\n * The full decoded type of the Node.js release schedule JSON.\n *\n * @internal\n */\nexport type NodeReleaseSchedule = typeof NodeReleaseSchedule.Type;\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,kBAAkB,OAAO,OAAO;CAC5C,SAAS,OAAO;CAChB,MAAM,OAAO;CACb,OAAO,OAAO,MAAM,OAAO,MAAM;CACjC,KAAK,OAAO,SAAS,OAAO,MAAM;CAClC,IAAI,OAAO,SAAS,OAAO,MAAM;CACjC,IAAI,OAAO,SAAS,OAAO,MAAM;CACjC,MAAM,OAAO,SAAS,OAAO,MAAM;CACnC,SAAS,OAAO,SAAS,OAAO,MAAM;CACtC,SAAS,OAAO,SAAS,OAAO,MAAM;CACtC,KAAK,OAAO,MAAM,OAAO,QAAQ,KAAK,GAAG,OAAO,MAAM;CACtD,UAAU,OAAO;AAClB,CAAC;;;;;;;;;AAiBD,MAAa,gBAAgB,OAAO,MAAM,eAAe;;;;;;;;;;AAkBzD,MAAa,uBAAuB,OAAO,OAAO;CACjD,OAAO,OAAO;CACd,KAAK,OAAO,SAAS,OAAO,MAAM;CAClC,aAAa,OAAO,SAAS,OAAO,MAAM;CAC1C,KAAK,OAAO;CACZ,UAAU,OAAO,SAAS,OAAO,MAAM;AACxC,CAAC;;;;;;;;;;;;AAoBD,MAAa,sBAAsB,OAAO,OAAO;CAChD,KAAK,OAAO;CACZ,OAAO;AACR,CAAC"}
@@ -0,0 +1,34 @@
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 };
34
+ //# sourceMappingURL=BunReleaseCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BunReleaseCache.js","names":[],"sources":["../../../../src/services/BunReleaseCache.ts"],"sourcesContent":["import { Context } from \"effect\";\nimport type { BunRelease } from \"../schemas/bun-release.js\";\nimport type { RuntimeCache } from \"./RuntimeCache.js\";\n\n/**\n * Specialisation of {@link RuntimeCache} for Bun release objects.\n *\n * @example\n * ```typescript\n * import type { BunRelease } from \"runtime-resolver\";\n * import { BunReleaseCache, OfflineBunCacheLive } from \"runtime-resolver\";\n * import { Effect } from \"effect\";\n *\n * const program = Effect.gen(function* () {\n * \tconst cache = yield* BunReleaseCache;\n * \tconst releases = yield* cache.releases();\n * \tconsole.log(releases.length);\n * });\n *\n * Effect.runPromise(program.pipe(Effect.provide(OfflineBunCacheLive)));\n * ```\n *\n * @see {@link BunRelease}\n * @see {@link RuntimeCache}\n * @see {@link AutoBunCacheLive}\n * @see {@link FreshBunCacheLive}\n * @see {@link OfflineBunCacheLive}\n *\n * @public\n */\nexport class BunReleaseCache extends Context.Tag(\"runtime-resolver/BunReleaseCache\")<\n\tBunReleaseCache,\n\tRuntimeCache<BunRelease>\n>() {}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,IAAa,kBAAb,cAAqC,QAAQ,IAAI,kCAAkC,CAAC,CAGlF,CAAC,CAAC,CAAC"}
@@ -0,0 +1,37 @@
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 };
37
+ //# sourceMappingURL=BunResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BunResolver.js","names":[],"sources":["../../../../src/services/BunResolver.ts"],"sourcesContent":["import type { Effect } from \"effect\";\nimport { Context } from \"effect\";\nimport type { VersionNotFoundError } from \"../errors/VersionNotFoundError.js\";\nimport type { Increments, ResolvedVersions } from \"../schemas/common.js\";\n\n/**\n * Options accepted by {@link BunResolver.resolve}.\n *\n * All fields are optional; omitting them causes the resolver to fall back to\n * its built-in defaults (latest stable release, `\"latest\"` increment\n * granularity).\n *\n * @see {@link BunResolver}\n * @see {@link Increments}\n * @see {@link ResolvedVersions}\n *\n * @public\n */\nexport interface BunResolverOptions {\n\t/**\n\t * A semver range string used to constrain which Bun releases are\n\t * considered (e.g. `\"^1.0.0\"` or `\">=1.1.0 <2.0.0\"`).\n\t *\n\t * When omitted all cached releases are eligible.\n\t */\n\treadonly semverRange?: string;\n\n\t/**\n\t * A fallback version string returned when no release satisfies\n\t * `semverRange`. Must be a valid semver version (e.g. `\"1.0.0\"`).\n\t *\n\t * When omitted and no match is found the effect fails with\n\t * {@link VersionNotFoundError}.\n\t */\n\treadonly defaultVersion?: string;\n\n\t/**\n\t * Controls the granularity of the version list included in\n\t * {@link ResolvedVersions.versions}.\n\t *\n\t * - `\"latest\"` — only the single highest matching version.\n\t * - `\"minor\"` — the latest patch for every minor line.\n\t * - `\"patch\"` — every individual patch release.\n\t *\n\t * Defaults to `\"latest\"` when omitted.\n\t *\n\t * @see {@link Increments}\n\t */\n\treadonly increments?: Increments;\n}\n\n/**\n * Union of all typed errors that {@link BunResolver.resolve} can fail with.\n *\n * @see {@link VersionNotFoundError}\n *\n * @public\n */\nexport type BunResolverError = VersionNotFoundError;\n\n/**\n * Service for resolving Bun runtime versions against the cached\n * release index.\n *\n * For a one-shot Promise-based API see {@link resolveBun}.\n *\n * @example\n * ```typescript\n * import type { ResolvedVersions } from \"runtime-resolver\";\n * import { BunResolver, BunResolverLive } from \"runtime-resolver\";\n * import { Effect } from \"effect\";\n *\n * const program = Effect.gen(function* () {\n * \tconst resolver = yield* BunResolver;\n * \tconst result = yield* resolver.resolve({ semverRange: \"^1.0.0\", increments: \"minor\" });\n * \tconsole.log(result.latest);\n * \tconsole.log(result.versions);\n * });\n *\n * Effect.runPromise(program.pipe(Effect.provide(BunResolverLive)));\n * ```\n *\n * @see {@link BunResolverLive}\n * @see {@link resolveBun}\n * @see {@link BunResolverOptions}\n * @see {@link ResolvedVersions}\n *\n * @public\n */\nexport class BunResolver extends Context.Tag(\"runtime-resolver/BunResolver\")<\n\tBunResolver,\n\t{\n\t\t/**\n\t\t * Resolves Bun versions according to `options` and returns a\n\t\t * {@link ResolvedVersions} object containing the matching version list,\n\t\t * the latest version string, and the data source indicator.\n\t\t *\n\t\t * Fails with {@link BunResolverError} when no version can be resolved and\n\t\t * no `defaultVersion` was provided.\n\t\t *\n\t\t * @param options - Optional resolution constraints.\n\t\t *\n\t\t * @see {@link BunResolverOptions}\n\t\t */\n\t\treadonly resolve: (options?: BunResolverOptions) => Effect.Effect<ResolvedVersions, BunResolverError>;\n\t}\n>() {}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyFA,IAAa,cAAb,cAAiC,QAAQ,IAAI,8BAA8B,CAAC,CAiB1E,CAAC,CAAC,CAAC"}
@@ -0,0 +1,42 @@
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 };
42
+ //# sourceMappingURL=BunVersionFetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BunVersionFetcher.js","names":[],"sources":["../../../../src/services/BunVersionFetcher.ts"],"sourcesContent":["import type { Effect } from \"effect\";\nimport { Context } from \"effect\";\nimport type { SemVer } from \"semver-effect\";\nimport type { AuthenticationError } from \"../errors/AuthenticationError.js\";\nimport type { NetworkError } from \"../errors/NetworkError.js\";\nimport type { ParseError } from \"../errors/ParseError.js\";\nimport type { RateLimitError } from \"../errors/RateLimitError.js\";\nimport type { RuntimeReleaseInput } from \"../schemas/runtime-release.js\";\n\n/**\n * Service for fetching Bun release data from the GitHub API.\n *\n * Retrieves both the parsed semver version list and the raw release input\n * records needed to populate a {@link BunReleaseCache}. The live\n * implementation queries the `oven-sh/bun` GitHub repository via\n * {@link GitHubClient}.\n *\n * @example\n * ```typescript\n * import type { RuntimeReleaseInput } from \"runtime-resolver\";\n * import { BunVersionFetcher, BunVersionFetcherLive, GitHubAutoAuth } from \"runtime-resolver\";\n * import { Effect } from \"effect\";\n *\n * const program = Effect.gen(function* () {\n * \tconst fetcher = yield* BunVersionFetcher;\n * \tconst { versions, inputs } = yield* fetcher.fetch();\n * \tconsole.log(`Fetched ${versions.length} Bun releases`);\n * });\n *\n * Effect.runPromise(\n * \tprogram.pipe(Effect.provide(BunVersionFetcherLive), Effect.provide(GitHubAutoAuth)),\n * );\n * ```\n *\n * @see {@link BunVersionFetcherLive}\n * @see {@link BunReleaseCache}\n * @see {@link AuthenticationError}\n * @see {@link NetworkError}\n * @see {@link ParseError}\n * @see {@link RateLimitError}\n *\n * @public\n */\nexport class BunVersionFetcher extends Context.Tag(\"runtime-resolver/BunVersionFetcher\")<\n\tBunVersionFetcher,\n\t{\n\t\t/**\n\t\t * Fetches all available Bun releases from the GitHub API and returns both\n\t\t * the parsed semver version objects and the raw release input records.\n\t\t *\n\t\t * Fails with:\n\t\t * - {@link AuthenticationError} — missing or invalid GitHub credentials.\n\t\t * - {@link NetworkError} — the upstream request could not be completed.\n\t\t * - {@link ParseError} — the response payload could not be decoded.\n\t\t * - {@link RateLimitError} — the GitHub API rate limit was exceeded.\n\t\t */\n\t\treadonly fetch: () => Effect.Effect<\n\t\t\t{\n\t\t\t\treadonly versions: ReadonlyArray<SemVer>;\n\t\t\t\treadonly inputs: ReadonlyArray<RuntimeReleaseInput>;\n\t\t\t},\n\t\t\tAuthenticationError | NetworkError | ParseError | RateLimitError\n\t\t>;\n\t}\n>() {}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,IAAa,oBAAb,cAAuC,QAAQ,IAAI,oCAAoC,CAAC,CAqBtF,CAAC,CAAC,CAAC"}
@@ -0,0 +1,34 @@
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 };
34
+ //# sourceMappingURL=DenoReleaseCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DenoReleaseCache.js","names":[],"sources":["../../../../src/services/DenoReleaseCache.ts"],"sourcesContent":["import { Context } from \"effect\";\nimport type { DenoRelease } from \"../schemas/deno-release.js\";\nimport type { RuntimeCache } from \"./RuntimeCache.js\";\n\n/**\n * Specialisation of {@link RuntimeCache} for Deno release objects.\n *\n * @example\n * ```typescript\n * import type { DenoRelease } from \"runtime-resolver\";\n * import { DenoReleaseCache, OfflineDenoCacheLive } from \"runtime-resolver\";\n * import { Effect } from \"effect\";\n *\n * const program = Effect.gen(function* () {\n * \tconst cache = yield* DenoReleaseCache;\n * \tconst latest = yield* cache.latest();\n * \tconsole.log(latest.version.toString());\n * });\n *\n * Effect.runPromise(program.pipe(Effect.provide(OfflineDenoCacheLive)));\n * ```\n *\n * @see {@link DenoRelease}\n * @see {@link RuntimeCache}\n * @see {@link AutoDenoCacheLive}\n * @see {@link FreshDenoCacheLive}\n * @see {@link OfflineDenoCacheLive}\n *\n * @public\n */\nexport class DenoReleaseCache extends Context.Tag(\"runtime-resolver/DenoReleaseCache\")<\n\tDenoReleaseCache,\n\tRuntimeCache<DenoRelease>\n>() {}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,IAAa,mBAAb,cAAsC,QAAQ,IAAI,mCAAmC,CAAC,CAGpF,CAAC,CAAC,CAAC"}
@@ -0,0 +1,37 @@
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 };
37
+ //# sourceMappingURL=DenoResolver.js.map