@effected/runtimes 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BunResolver.js +79 -0
- package/DenoResolver.js +79 -0
- package/GitHub.js +220 -0
- package/LICENSE +21 -0
- package/NodeRelease.js +73 -0
- package/NodeResolver.js +114 -0
- package/NodeSchedule.js +217 -0
- package/README.md +155 -0
- package/ResolvedVersions.js +122 -0
- package/index.d.ts +737 -0
- package/index.js +9 -0
- package/internal/defaults/bun.js +855 -0
- package/internal/defaults/deno.js +1543 -0
- package/internal/defaults/node.js +4443 -0
- package/internal/feeds.js +84 -0
- package/internal/githubRuntime.js +43 -0
- package/internal/http.js +127 -0
- package/internal/releaseIndex.js +46 -0
- package/internal/resolve.js +44 -0
- package/internal/strategy.js +53 -0
- package/package.json +50 -0
- package/tsdoc-metadata.json +11 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,737 @@
|
|
|
1
|
+
import { InvalidRangeError, SemVer } from "@effected/semver";
|
|
2
|
+
import { Context, DateTime, Effect, Layer, Option, Redacted, Schema } from "effect";
|
|
3
|
+
import { HttpClient } from "effect/unstable/http";
|
|
4
|
+
//#region src/GitHub.d.ts
|
|
5
|
+
declare const AuthenticationError_base: Schema.Class<AuthenticationError, Schema.TaggedStruct<"AuthenticationError", {
|
|
6
|
+
/** How the request was authenticated when it was rejected. */
|
|
7
|
+
readonly method: Schema.Literals<readonly ["token", "anonymous"]>;
|
|
8
|
+
}>, import("effect/Cause").YieldableError>;
|
|
9
|
+
/**
|
|
10
|
+
* GitHub rejected the credentials.
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
declare class AuthenticationError extends AuthenticationError_base {}
|
|
15
|
+
declare const RateLimitError_base: Schema.Class<RateLimitError, Schema.TaggedStruct<"RateLimitError", {
|
|
16
|
+
/** Seconds to wait before retrying, when GitHub said. */
|
|
17
|
+
readonly retryAfter: Schema.optionalKey<Schema.Number>;
|
|
18
|
+
/** The request quota for the window. */
|
|
19
|
+
readonly limit: Schema.Number;
|
|
20
|
+
/** Requests left in the window. */
|
|
21
|
+
readonly remaining: Schema.Number;
|
|
22
|
+
}>, import("effect/Cause").YieldableError>;
|
|
23
|
+
/**
|
|
24
|
+
* GitHub's rate limit was exhausted.
|
|
25
|
+
*
|
|
26
|
+
* `retryAfter` is what a caller needs to back off correctly, which is why it is
|
|
27
|
+
* a structured field rather than prose in a message.
|
|
28
|
+
*
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
declare class RateLimitError extends RateLimitError_base {}
|
|
32
|
+
declare const NetworkError_base: Schema.Class<NetworkError, Schema.TaggedStruct<"NetworkError", {
|
|
33
|
+
/** The URL that failed. */
|
|
34
|
+
readonly url: Schema.String;
|
|
35
|
+
/** The HTTP status, when there was a response at all. */
|
|
36
|
+
readonly status: Schema.optionalKey<Schema.Number>;
|
|
37
|
+
/** The underlying transport failure. */
|
|
38
|
+
readonly cause: Schema.Defect;
|
|
39
|
+
}>, import("effect/Cause").YieldableError>;
|
|
40
|
+
/**
|
|
41
|
+
* A request did not complete, or completed with an unusable status.
|
|
42
|
+
*
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
declare class NetworkError extends NetworkError_base {}
|
|
46
|
+
declare const ResponseParseError_base: Schema.Class<ResponseParseError, Schema.TaggedStruct<"ResponseParseError", {
|
|
47
|
+
/** The URL whose body could not be decoded. */
|
|
48
|
+
readonly source: Schema.String;
|
|
49
|
+
/** The decoding failure. */
|
|
50
|
+
readonly cause: Schema.Defect;
|
|
51
|
+
}>, import("effect/Cause").YieldableError>;
|
|
52
|
+
/**
|
|
53
|
+
* A feed responded, but not with the shape this package expects.
|
|
54
|
+
*
|
|
55
|
+
* An operator-facing signal that an upstream feed changed.
|
|
56
|
+
*
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
declare class ResponseParseError extends ResponseParseError_base {}
|
|
60
|
+
/**
|
|
61
|
+
* Every way a fetch against a release feed can fail.
|
|
62
|
+
*
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
type GitHubError = AuthenticationError | RateLimitError | NetworkError | ResponseParseError;
|
|
66
|
+
declare const GitHubTag_base: Schema.Class<GitHubTag, Schema.Struct<{
|
|
67
|
+
readonly name: Schema.String;
|
|
68
|
+
}>, {}>;
|
|
69
|
+
/**
|
|
70
|
+
* A tag as `GET /repos/{owner}/{repo}/tags` returns it.
|
|
71
|
+
*
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
declare class GitHubTag extends GitHubTag_base {}
|
|
75
|
+
declare const GitHubRelease_base: Schema.Class<GitHubRelease, Schema.Struct<{
|
|
76
|
+
readonly tag_name: Schema.String;
|
|
77
|
+
readonly draft: Schema.Boolean;
|
|
78
|
+
readonly prerelease: Schema.Boolean;
|
|
79
|
+
readonly published_at: Schema.NullOr<Schema.String>;
|
|
80
|
+
}>, {}>;
|
|
81
|
+
/**
|
|
82
|
+
* A release as `GET /repos/{owner}/{repo}/releases` returns it.
|
|
83
|
+
*
|
|
84
|
+
* @public
|
|
85
|
+
*/
|
|
86
|
+
declare class GitHubRelease extends GitHubRelease_base {}
|
|
87
|
+
/**
|
|
88
|
+
* The shape of a GitHub credential: something that can produce request headers.
|
|
89
|
+
*
|
|
90
|
+
* Making this a service rather than a concrete token is what lets GitHub App
|
|
91
|
+
* authentication live outside this package. App auth needs JWT signing and an
|
|
92
|
+
* installation-token exchange, which means a runtime dependency — forbidden in
|
|
93
|
+
* a boundary-tier package. A consumer who needs it supplies their own
|
|
94
|
+
* `Layer<GitHubAuth>` that mints installation tokens; nothing else changes.
|
|
95
|
+
*
|
|
96
|
+
* @public
|
|
97
|
+
*/
|
|
98
|
+
interface GitHubAuthShape {
|
|
99
|
+
/** Headers to attach to each GitHub request. */
|
|
100
|
+
readonly headers: Effect.Effect<Readonly<Record<string, string>>, AuthenticationError>;
|
|
101
|
+
}
|
|
102
|
+
declare const GitHubAuth_base: Context.ServiceClass<GitHubAuth, "@effected/runtimes/GitHubAuth", GitHubAuthShape>;
|
|
103
|
+
/**
|
|
104
|
+
* How GitHub requests are authenticated.
|
|
105
|
+
*
|
|
106
|
+
* @public
|
|
107
|
+
*/
|
|
108
|
+
declare class GitHubAuth extends GitHubAuth_base {
|
|
109
|
+
/**
|
|
110
|
+
* Send no credentials. GitHub allows this, at a much lower rate limit.
|
|
111
|
+
*/
|
|
112
|
+
static readonly anonymous: Layer.Layer<GitHubAuth>;
|
|
113
|
+
/**
|
|
114
|
+
* Authenticate with a personal access token.
|
|
115
|
+
*
|
|
116
|
+
* This returns a fresh layer per call, so bind it to a constant rather than
|
|
117
|
+
* calling it inline twice — layers are memoized by reference.
|
|
118
|
+
*/
|
|
119
|
+
static readonly token: (token: Redacted.Redacted<string>) => Layer.Layer<GitHubAuth>;
|
|
120
|
+
/**
|
|
121
|
+
* Detect a credential from the environment, preferring an explicit PAT.
|
|
122
|
+
*
|
|
123
|
+
* Precedence is `GITHUB_PERSONAL_ACCESS_TOKEN`, then `GITHUB_TOKEN`, then
|
|
124
|
+
* unauthenticated — the v3 policy, kept, but read through `Config` so a test
|
|
125
|
+
* can swap the `ConfigProvider` instead of mutating `process.env`.
|
|
126
|
+
*/
|
|
127
|
+
static readonly layer: Layer.Layer<GitHubAuth>;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* How much of a paginated listing to fetch.
|
|
131
|
+
*
|
|
132
|
+
* Both fields must be positive integers. A `NaN` or fractional value is a
|
|
133
|
+
* wiring bug, not a data condition, and dies rather than failing typed.
|
|
134
|
+
*
|
|
135
|
+
* The fields are declared here rather than inherited from the engine's
|
|
136
|
+
* `PageOptions`, which is internal: a `@public` signature may not name a type a
|
|
137
|
+
* consumer cannot import.
|
|
138
|
+
*
|
|
139
|
+
* @public
|
|
140
|
+
*/
|
|
141
|
+
interface ListOptions {
|
|
142
|
+
/** Items per page. Defaults to 100, GitHub's maximum. */
|
|
143
|
+
readonly perPage?: number;
|
|
144
|
+
/** Pages to fetch. Defaults to 5, and is capped regardless. */
|
|
145
|
+
readonly pages?: number;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* The GitHub REST operations this package needs.
|
|
149
|
+
*
|
|
150
|
+
* @public
|
|
151
|
+
*/
|
|
152
|
+
interface GitHubClientShape {
|
|
153
|
+
/** List a repository's tags, newest first. */
|
|
154
|
+
readonly listTags: (owner: string, repo: string, options?: ListOptions) => Effect.Effect<ReadonlyArray<GitHubTag>, GitHubError>;
|
|
155
|
+
/** List a repository's releases, newest first. */
|
|
156
|
+
readonly listReleases: (owner: string, repo: string, options?: ListOptions) => Effect.Effect<ReadonlyArray<GitHubRelease>, GitHubError>;
|
|
157
|
+
}
|
|
158
|
+
declare const GitHubClient_base: Context.ServiceClass<GitHubClient, "@effected/runtimes/GitHubClient", GitHubClientShape>;
|
|
159
|
+
/**
|
|
160
|
+
* A GitHub REST client over `HttpClient`.
|
|
161
|
+
*
|
|
162
|
+
* v3 reached for `octokit` here, which cost two large dependency graphs to fund
|
|
163
|
+
* two GET requests. Programming against `HttpClient` from `effect` core keeps
|
|
164
|
+
* the package boundary tier and lets a consumer supply any transport.
|
|
165
|
+
*
|
|
166
|
+
* @public
|
|
167
|
+
*/
|
|
168
|
+
declare class GitHubClient extends GitHubClient_base {
|
|
169
|
+
/**
|
|
170
|
+
* The client, requiring an `HttpClient` and a `GitHubAuth` from the context.
|
|
171
|
+
*/
|
|
172
|
+
static readonly layer: Layer.Layer<GitHubClient, never, HttpClient.HttpClient | GitHubAuth>;
|
|
173
|
+
/**
|
|
174
|
+
* The client with batteries: environment-detected auth over `fetch`.
|
|
175
|
+
*
|
|
176
|
+
* The common wiring, in one import. Use {@link GitHubClient.layer} directly
|
|
177
|
+
* to supply your own credential or transport.
|
|
178
|
+
*/
|
|
179
|
+
static readonly layerDefault: Layer.Layer<GitHubClient>;
|
|
180
|
+
}
|
|
181
|
+
//#endregion
|
|
182
|
+
//#region src/ResolvedVersions.d.ts
|
|
183
|
+
/**
|
|
184
|
+
* The JavaScript runtime a resolver targets.
|
|
185
|
+
*
|
|
186
|
+
* @public
|
|
187
|
+
*/
|
|
188
|
+
declare const Runtime: Schema.Literals<readonly ["node", "bun", "deno"]>;
|
|
189
|
+
/**
|
|
190
|
+
* The JavaScript runtime a resolver targets.
|
|
191
|
+
*
|
|
192
|
+
* @public
|
|
193
|
+
*/
|
|
194
|
+
type Runtime = typeof Runtime.Type;
|
|
195
|
+
/**
|
|
196
|
+
* Where a resolution's release data came from.
|
|
197
|
+
*
|
|
198
|
+
* - `api` — a live fetch of the upstream feed succeeded.
|
|
199
|
+
* - `cache` — the bundled snapshot was used, either because the offline
|
|
200
|
+
* strategy was chosen or because the auto strategy fell back to it.
|
|
201
|
+
*
|
|
202
|
+
* This is honest provenance. In v3 the field existed, was advertised as a
|
|
203
|
+
* headline feature, and was hardcoded to `"api"` by every resolver — so a
|
|
204
|
+
* caller could not tell a live answer from a snapshot served after a silent
|
|
205
|
+
* network failure.
|
|
206
|
+
*
|
|
207
|
+
* @public
|
|
208
|
+
*/
|
|
209
|
+
declare const Source: Schema.Literals<readonly ["api", "cache"]>;
|
|
210
|
+
/**
|
|
211
|
+
* Where a resolution's release data came from.
|
|
212
|
+
*
|
|
213
|
+
* @public
|
|
214
|
+
*/
|
|
215
|
+
type Source = typeof Source.Type;
|
|
216
|
+
/**
|
|
217
|
+
* The granularity at which matching versions are grouped.
|
|
218
|
+
*
|
|
219
|
+
* - `latest` — the newest version of each major line.
|
|
220
|
+
* - `minor` — the newest patch of each minor line.
|
|
221
|
+
* - `patch` — every matching release.
|
|
222
|
+
*
|
|
223
|
+
* @public
|
|
224
|
+
*/
|
|
225
|
+
declare const Increments: Schema.Literals<readonly ["latest", "minor", "patch"]>;
|
|
226
|
+
/**
|
|
227
|
+
* The granularity at which matching versions are grouped.
|
|
228
|
+
*
|
|
229
|
+
* @public
|
|
230
|
+
*/
|
|
231
|
+
type Increments = typeof Increments.Type;
|
|
232
|
+
declare const ResolvedVersions_base: Schema.Class<ResolvedVersions, Schema.Struct<{
|
|
233
|
+
/** Whether this answer came from a live feed or the bundled snapshot. */
|
|
234
|
+
readonly source: Schema.Literals<readonly ["api", "cache"]>;
|
|
235
|
+
/** Every matching version, newest first. */
|
|
236
|
+
readonly versions: Schema.$Array<Schema.String>;
|
|
237
|
+
/** The newest matching version. Always present — an empty match is an error, not an empty result. */
|
|
238
|
+
readonly latest: Schema.String;
|
|
239
|
+
/** The newest matching LTS version. Node only, and only when one matches. */
|
|
240
|
+
readonly lts: Schema.optionalKey<Schema.String>;
|
|
241
|
+
/** The version the caller asked to treat as the default, resolved. */
|
|
242
|
+
readonly default: Schema.optionalKey<Schema.String>;
|
|
243
|
+
}>, {}>;
|
|
244
|
+
/**
|
|
245
|
+
* What every resolver returns.
|
|
246
|
+
*
|
|
247
|
+
* @public
|
|
248
|
+
*/
|
|
249
|
+
declare class ResolvedVersions extends ResolvedVersions_base {}
|
|
250
|
+
declare const NoMatchingVersionError_base: Schema.Class<NoMatchingVersionError, Schema.TaggedStruct<"NoMatchingVersionError", {
|
|
251
|
+
/** The runtime that was searched. */
|
|
252
|
+
readonly runtime: Schema.Literals<readonly ["node", "bun", "deno"]>;
|
|
253
|
+
/** The semver range that matched nothing. */
|
|
254
|
+
readonly constraint: Schema.String;
|
|
255
|
+
/** The lifecycle phases the search was restricted to. Node only. */
|
|
256
|
+
readonly phases: Schema.optionalKey<Schema.$Array<Schema.Literals<readonly ["current", "active-lts", "maintenance-lts", "end-of-life"]>>>;
|
|
257
|
+
}>, import("effect/Cause").YieldableError>;
|
|
258
|
+
/**
|
|
259
|
+
* No release matched the constraint.
|
|
260
|
+
*
|
|
261
|
+
* Distinct from an invalid constraint: `@effected/semver`'s `InvalidRangeError`
|
|
262
|
+
* says the range is malformed, this says the range is fine and nothing matched.
|
|
263
|
+
* v3 collapsed the former into the latter, so a typo in a range surfaced to the
|
|
264
|
+
* user as "no versions found".
|
|
265
|
+
*
|
|
266
|
+
* @public
|
|
267
|
+
*/
|
|
268
|
+
declare class NoMatchingVersionError extends NoMatchingVersionError_base {}
|
|
269
|
+
declare const UnresolvableDefaultError_base: Schema.Class<UnresolvableDefaultError, Schema.TaggedStruct<"UnresolvableDefaultError", {
|
|
270
|
+
/** The runtime that was searched. */
|
|
271
|
+
readonly runtime: Schema.Literals<readonly ["node", "bun", "deno"]>;
|
|
272
|
+
/** The range the caller asked to treat as the default. */
|
|
273
|
+
readonly defaultVersion: Schema.String;
|
|
274
|
+
}>, import("effect/Cause").YieldableError>;
|
|
275
|
+
/**
|
|
276
|
+
* An explicit `defaultVersion` was asked for and nothing matched it.
|
|
277
|
+
*
|
|
278
|
+
* Distinct from {@link NoMatchingVersionError}, which says the *main* range
|
|
279
|
+
* matched nothing. Here the main range resolved fine and the caller's separate
|
|
280
|
+
* default range did not.
|
|
281
|
+
*
|
|
282
|
+
* It has to be its own failure rather than a silently dropped field. `default`
|
|
283
|
+
* is `optionalKey`, so an unresolvable default could simply be omitted — and for
|
|
284
|
+
* Node, whose default falls back to the LTS pick, the caller would then be handed
|
|
285
|
+
* the LTS version as though they had asked for it. Naming a default that does not
|
|
286
|
+
* exist is a mistake, and it reaches the caller as one.
|
|
287
|
+
*
|
|
288
|
+
* @public
|
|
289
|
+
*/
|
|
290
|
+
declare class UnresolvableDefaultError extends UnresolvableDefaultError_base {}
|
|
291
|
+
declare const FreshnessError_base: Schema.Class<FreshnessError, Schema.TaggedStruct<"FreshnessError", {
|
|
292
|
+
/** The runtime whose feed could not be reached. */
|
|
293
|
+
readonly runtime: Schema.Literals<readonly ["node", "bun", "deno"]>;
|
|
294
|
+
/** The underlying transport or parse failure. */
|
|
295
|
+
readonly cause: Schema.Defect;
|
|
296
|
+
}>, import("effect/Cause").YieldableError>;
|
|
297
|
+
/**
|
|
298
|
+
* Fresh data was required and could not be obtained.
|
|
299
|
+
*
|
|
300
|
+
* Raised only by the `layerFresh` strategy, at layer construction: the caller
|
|
301
|
+
* asked for live data and said, by choosing that strategy, that a snapshot is
|
|
302
|
+
* not an acceptable substitute.
|
|
303
|
+
*
|
|
304
|
+
* @public
|
|
305
|
+
*/
|
|
306
|
+
declare class FreshnessError extends FreshnessError_base {}
|
|
307
|
+
//#endregion
|
|
308
|
+
//#region src/BunResolver.d.ts
|
|
309
|
+
declare const BunRelease_base: Schema.Class<BunRelease, Schema.Struct<{
|
|
310
|
+
/** The released version. */
|
|
311
|
+
readonly version: typeof SemVer;
|
|
312
|
+
/** When it was published. */
|
|
313
|
+
readonly date: Schema.DateTimeUtc;
|
|
314
|
+
}>, {}>;
|
|
315
|
+
/**
|
|
316
|
+
* One published Bun release.
|
|
317
|
+
*
|
|
318
|
+
* @public
|
|
319
|
+
*/
|
|
320
|
+
declare class BunRelease extends BunRelease_base {}
|
|
321
|
+
/**
|
|
322
|
+
* How to resolve Bun versions.
|
|
323
|
+
*
|
|
324
|
+
* @public
|
|
325
|
+
*/
|
|
326
|
+
declare const BunResolverOptions: Schema.Struct<{
|
|
327
|
+
/** The semver range to match. Defaults to `*`. */
|
|
328
|
+
readonly range: Schema.optionalKey<Schema.String>;
|
|
329
|
+
/** How to group matches. Defaults to `latest`. */
|
|
330
|
+
readonly increments: Schema.optionalKey<Schema.Literals<readonly ["latest", "minor", "patch"]>>;
|
|
331
|
+
/** A range whose newest match becomes the `default` field. */
|
|
332
|
+
readonly defaultVersion: Schema.optionalKey<Schema.String>;
|
|
333
|
+
}>;
|
|
334
|
+
/**
|
|
335
|
+
* How to resolve Bun versions.
|
|
336
|
+
*
|
|
337
|
+
* @public
|
|
338
|
+
*/
|
|
339
|
+
type BunResolverOptions = typeof BunResolverOptions.Type;
|
|
340
|
+
declare const BunResolver_base: Context.ServiceClass<BunResolver, "@effected/runtimes/BunResolver", {
|
|
341
|
+
readonly resolve: (options?: BunResolverOptions) => Effect.Effect<ResolvedVersions, InvalidRangeError | NoMatchingVersionError | UnresolvableDefaultError>;
|
|
342
|
+
}>;
|
|
343
|
+
/**
|
|
344
|
+
* The Bun resolver.
|
|
345
|
+
*
|
|
346
|
+
* @example
|
|
347
|
+
* ```ts
|
|
348
|
+
* import { BunResolver } from "@effected/runtimes";
|
|
349
|
+
* import { Effect } from "effect";
|
|
350
|
+
*
|
|
351
|
+
* const program = Effect.gen(function* () {
|
|
352
|
+
* const resolver = yield* BunResolver;
|
|
353
|
+
* return (yield* resolver.resolve({ range: "^1.0.0" })).latest;
|
|
354
|
+
* }).pipe(Effect.provide(BunResolver.layerOffline));
|
|
355
|
+
* ```
|
|
356
|
+
*
|
|
357
|
+
* @public
|
|
358
|
+
*/
|
|
359
|
+
declare class BunResolver extends BunResolver_base {
|
|
360
|
+
/** Try GitHub, fall back to the bundled snapshot. */
|
|
361
|
+
static readonly layer: Layer.Layer<BunResolver, never, GitHubClient>;
|
|
362
|
+
/** GitHub or nothing. Fails with `FreshnessError` when it cannot be reached. */
|
|
363
|
+
static readonly layerFresh: Layer.Layer<BunResolver, FreshnessError, GitHubClient>;
|
|
364
|
+
/** The bundled snapshot only. Performs no IO and requires nothing. */
|
|
365
|
+
static readonly layerOffline: Layer.Layer<BunResolver>;
|
|
366
|
+
}
|
|
367
|
+
//#endregion
|
|
368
|
+
//#region src/DenoResolver.d.ts
|
|
369
|
+
declare const DenoRelease_base: Schema.Class<DenoRelease, Schema.Struct<{
|
|
370
|
+
/** The released version. */
|
|
371
|
+
readonly version: typeof SemVer;
|
|
372
|
+
/** When it was published. */
|
|
373
|
+
readonly date: Schema.DateTimeUtc;
|
|
374
|
+
}>, {}>;
|
|
375
|
+
/**
|
|
376
|
+
* One published Deno release.
|
|
377
|
+
*
|
|
378
|
+
* @public
|
|
379
|
+
*/
|
|
380
|
+
declare class DenoRelease extends DenoRelease_base {}
|
|
381
|
+
/**
|
|
382
|
+
* How to resolve Deno versions.
|
|
383
|
+
*
|
|
384
|
+
* @public
|
|
385
|
+
*/
|
|
386
|
+
declare const DenoResolverOptions: Schema.Struct<{
|
|
387
|
+
/** The semver range to match. Defaults to `*`. */
|
|
388
|
+
readonly range: Schema.optionalKey<Schema.String>;
|
|
389
|
+
/** How to group matches. Defaults to `latest`. */
|
|
390
|
+
readonly increments: Schema.optionalKey<Schema.Literals<readonly ["latest", "minor", "patch"]>>;
|
|
391
|
+
/** A range whose newest match becomes the `default` field. */
|
|
392
|
+
readonly defaultVersion: Schema.optionalKey<Schema.String>;
|
|
393
|
+
}>;
|
|
394
|
+
/**
|
|
395
|
+
* How to resolve Deno versions.
|
|
396
|
+
*
|
|
397
|
+
* @public
|
|
398
|
+
*/
|
|
399
|
+
type DenoResolverOptions = typeof DenoResolverOptions.Type;
|
|
400
|
+
declare const DenoResolver_base: Context.ServiceClass<DenoResolver, "@effected/runtimes/DenoResolver", {
|
|
401
|
+
readonly resolve: (options?: DenoResolverOptions) => Effect.Effect<ResolvedVersions, InvalidRangeError | NoMatchingVersionError | UnresolvableDefaultError>;
|
|
402
|
+
}>;
|
|
403
|
+
/**
|
|
404
|
+
* The Deno resolver.
|
|
405
|
+
*
|
|
406
|
+
* @example
|
|
407
|
+
* ```ts
|
|
408
|
+
* import { DenoResolver } from "@effected/runtimes";
|
|
409
|
+
* import { Effect } from "effect";
|
|
410
|
+
*
|
|
411
|
+
* const program = Effect.gen(function* () {
|
|
412
|
+
* const resolver = yield* DenoResolver;
|
|
413
|
+
* return (yield* resolver.resolve({ range: "^2.0.0" })).latest;
|
|
414
|
+
* }).pipe(Effect.provide(DenoResolver.layerOffline));
|
|
415
|
+
* ```
|
|
416
|
+
*
|
|
417
|
+
* @public
|
|
418
|
+
*/
|
|
419
|
+
declare class DenoResolver extends DenoResolver_base {
|
|
420
|
+
/** Try GitHub, fall back to the bundled snapshot. */
|
|
421
|
+
static readonly layer: Layer.Layer<DenoResolver, never, GitHubClient>;
|
|
422
|
+
/** GitHub or nothing. Fails with `FreshnessError` when it cannot be reached. */
|
|
423
|
+
static readonly layerFresh: Layer.Layer<DenoResolver, FreshnessError, GitHubClient>;
|
|
424
|
+
/** The bundled snapshot only. Performs no IO and requires nothing. */
|
|
425
|
+
static readonly layerOffline: Layer.Layer<DenoResolver>;
|
|
426
|
+
}
|
|
427
|
+
//#endregion
|
|
428
|
+
//#region src/NodeSchedule.d.ts
|
|
429
|
+
/**
|
|
430
|
+
* Lifecycle phase of a Node.js major release line.
|
|
431
|
+
*
|
|
432
|
+
* - `current` — actively receiving features and bug fixes.
|
|
433
|
+
* - `active-lts` — Long-Term Support: bug and security fixes only.
|
|
434
|
+
* - `maintenance-lts` — critical security fixes only.
|
|
435
|
+
* - `end-of-life` — no longer maintained.
|
|
436
|
+
*
|
|
437
|
+
* @public
|
|
438
|
+
*/
|
|
439
|
+
declare const NodePhase: Schema.Literals<readonly ["current", "active-lts", "maintenance-lts", "end-of-life"]>;
|
|
440
|
+
/**
|
|
441
|
+
* Lifecycle phase of a Node.js major release line.
|
|
442
|
+
*
|
|
443
|
+
* @public
|
|
444
|
+
*/
|
|
445
|
+
type NodePhase = typeof NodePhase.Type;
|
|
446
|
+
declare const InvalidScheduleDateError_base: Schema.Class<InvalidScheduleDateError, Schema.TaggedStruct<"InvalidScheduleDateError", {
|
|
447
|
+
/** The schedule key whose entry failed, e.g. `"v20"`. */
|
|
448
|
+
readonly key: Schema.String;
|
|
449
|
+
/** The field that failed, e.g. `"start"`. */
|
|
450
|
+
readonly field: Schema.String;
|
|
451
|
+
/** The value that could not be parsed. */
|
|
452
|
+
readonly value: Schema.String;
|
|
453
|
+
}>, import("effect/Cause").YieldableError>;
|
|
454
|
+
/**
|
|
455
|
+
* A date in the release schedule could not be understood.
|
|
456
|
+
*
|
|
457
|
+
* Raised when `nodejs/Release` publishes a `schedule.json` whose dates this
|
|
458
|
+
* package cannot parse — an operator-facing signal that the upstream feed
|
|
459
|
+
* changed shape, not something a caller can recover from.
|
|
460
|
+
*
|
|
461
|
+
* @public
|
|
462
|
+
*/
|
|
463
|
+
declare class InvalidScheduleDateError extends InvalidScheduleDateError_base {}
|
|
464
|
+
/**
|
|
465
|
+
* The parts of a version that decide which release line it belongs to.
|
|
466
|
+
*
|
|
467
|
+
* Structural, so a `SemVer` satisfies it without this module naming one.
|
|
468
|
+
*
|
|
469
|
+
* @public
|
|
470
|
+
*/
|
|
471
|
+
interface NodeReleaseLine {
|
|
472
|
+
/** The major version. */
|
|
473
|
+
readonly major: number;
|
|
474
|
+
/** The minor version. Only consulted for the `0.x` lines; defaults to `0`. */
|
|
475
|
+
readonly minor?: number | undefined;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* The release-line key a version belongs to.
|
|
479
|
+
*
|
|
480
|
+
* Node's early history is the whole reason this exists. `nodejs/Release`
|
|
481
|
+
* publishes `v0.8`, `v0.10` and `v0.12` as three *separate* release lines with
|
|
482
|
+
* their own start and end dates — the major number does not identify them.
|
|
483
|
+
* Everything from `v4` on is keyed by the major alone.
|
|
484
|
+
*
|
|
485
|
+
* @example
|
|
486
|
+
* ```ts
|
|
487
|
+
* import { nodeReleaseLine } from "@effected/runtimes";
|
|
488
|
+
*
|
|
489
|
+
* nodeReleaseLine({ major: 20, minor: 11 }); // "20"
|
|
490
|
+
* nodeReleaseLine({ major: 0, minor: 12 }); // "0.12"
|
|
491
|
+
* ```
|
|
492
|
+
*
|
|
493
|
+
* @public
|
|
494
|
+
*/
|
|
495
|
+
declare const nodeReleaseLine: (version: NodeReleaseLine) => string;
|
|
496
|
+
declare const NodeScheduleEntry_base: Schema.Class<NodeScheduleEntry, Schema.Struct<{
|
|
497
|
+
/**
|
|
498
|
+
* The release line as `nodejs/Release` keys it, without the `v`: `"20"`, or
|
|
499
|
+
* `"0.10"` for the three dotted early lines.
|
|
500
|
+
*/
|
|
501
|
+
readonly line: Schema.String;
|
|
502
|
+
/** The Node.js major version number, e.g. `20`. `0` for every `0.x` line. */
|
|
503
|
+
readonly major: Schema.Number;
|
|
504
|
+
/** The minor, for the `0.x` lines that are each their own release line. */
|
|
505
|
+
readonly minor: Schema.optionalKey<Schema.Number>;
|
|
506
|
+
/** When the line was first released. */
|
|
507
|
+
readonly start: Schema.DateTimeUtc;
|
|
508
|
+
/** When the line entered Active LTS, absent if it never does (odd majors). */
|
|
509
|
+
readonly lts: Schema.optionalKey<Schema.DateTimeUtc>;
|
|
510
|
+
/** When the line entered Maintenance LTS. */
|
|
511
|
+
readonly maintenance: Schema.optionalKey<Schema.DateTimeUtc>;
|
|
512
|
+
/** When the line reaches end of life. */
|
|
513
|
+
readonly end: Schema.DateTimeUtc;
|
|
514
|
+
/** The LTS codename, e.g. `"Iron"`. Empty for lines that never got one. */
|
|
515
|
+
readonly codename: Schema.String;
|
|
516
|
+
}>, {}>;
|
|
517
|
+
/**
|
|
518
|
+
* One release line's lifecycle dates.
|
|
519
|
+
*
|
|
520
|
+
* @public
|
|
521
|
+
*/
|
|
522
|
+
declare class NodeScheduleEntry extends NodeScheduleEntry_base {}
|
|
523
|
+
/**
|
|
524
|
+
* The raw shape of `schedule.json` as `nodejs/Release` publishes it: a map of
|
|
525
|
+
* `"vNN"` to ISO date strings.
|
|
526
|
+
*
|
|
527
|
+
* @public
|
|
528
|
+
*/
|
|
529
|
+
declare const NodeScheduleData: Schema.$Record<Schema.String, Schema.Struct<{
|
|
530
|
+
readonly start: Schema.String;
|
|
531
|
+
readonly lts: Schema.optionalKey<Schema.String>;
|
|
532
|
+
readonly maintenance: Schema.optionalKey<Schema.String>;
|
|
533
|
+
readonly end: Schema.String;
|
|
534
|
+
readonly codename: Schema.optionalKey<Schema.String>;
|
|
535
|
+
}>>;
|
|
536
|
+
/**
|
|
537
|
+
* The raw shape of `schedule.json`.
|
|
538
|
+
*
|
|
539
|
+
* @public
|
|
540
|
+
*/
|
|
541
|
+
type NodeScheduleData = typeof NodeScheduleData.Type;
|
|
542
|
+
declare const NodeSchedule_base: Schema.Class<NodeSchedule, Schema.Struct<{
|
|
543
|
+
/** The known release lines, ascending by major. */
|
|
544
|
+
readonly entries: Schema.$Array<typeof NodeScheduleEntry>;
|
|
545
|
+
}>, {}>;
|
|
546
|
+
/**
|
|
547
|
+
* An immutable snapshot of the Node.js release schedule.
|
|
548
|
+
*
|
|
549
|
+
* In v3 a `Ref<NodeSchedule>` was threaded *into every `NodeRelease`* so that
|
|
550
|
+
* `release.phase()` could reach the schedule — mutable service state inside an
|
|
551
|
+
* immutable domain value, which is why `NodeRelease` could not be a data class.
|
|
552
|
+
* Here the schedule is a value the caller passes in: phase is a function of
|
|
553
|
+
* `(release, schedule, now)`, and nothing in the model is mutable.
|
|
554
|
+
*
|
|
555
|
+
* @example
|
|
556
|
+
* ```ts
|
|
557
|
+
* import { NodeSchedule } from "@effected/runtimes";
|
|
558
|
+
* import { DateTime, Effect, Option } from "effect";
|
|
559
|
+
*
|
|
560
|
+
* const program = Effect.gen(function* () {
|
|
561
|
+
* const schedule = yield* NodeSchedule.fromData({
|
|
562
|
+
* v20: { start: "2023-04-18", lts: "2023-10-24", end: "2026-04-30" },
|
|
563
|
+
* });
|
|
564
|
+
* const phase = schedule.phaseFor({ major: 20 }, DateTime.makeUnsafe("2024-01-01"));
|
|
565
|
+
* return Option.getOrNull(phase); // "active-lts"
|
|
566
|
+
* });
|
|
567
|
+
* ```
|
|
568
|
+
*
|
|
569
|
+
* @public
|
|
570
|
+
*/
|
|
571
|
+
declare class NodeSchedule extends NodeSchedule_base {
|
|
572
|
+
/**
|
|
573
|
+
* A schedule that knows nothing.
|
|
574
|
+
*
|
|
575
|
+
* `phaseFor` returns `Option.none()` for every major, which is the correct
|
|
576
|
+
* answer before a schedule has been loaded.
|
|
577
|
+
*/
|
|
578
|
+
static readonly empty: NodeSchedule;
|
|
579
|
+
/**
|
|
580
|
+
* Parse the raw `schedule.json` shape into a schedule.
|
|
581
|
+
*
|
|
582
|
+
* Keys that are not of the form `"vNN"` are skipped — the upstream file has
|
|
583
|
+
* historically carried non-version keys, and one of them is not a reason to
|
|
584
|
+
* fail the whole schedule. A key that *is* a version but whose dates do not
|
|
585
|
+
* parse fails with {@link InvalidScheduleDateError}.
|
|
586
|
+
*/
|
|
587
|
+
static readonly fromData: (data: {
|
|
588
|
+
readonly [x: string]: {
|
|
589
|
+
readonly start: string;
|
|
590
|
+
readonly lts?: string | undefined;
|
|
591
|
+
readonly maintenance?: string | undefined;
|
|
592
|
+
readonly end: string;
|
|
593
|
+
readonly codename?: string | undefined;
|
|
594
|
+
};
|
|
595
|
+
}) => Effect.Effect<NodeSchedule, InvalidScheduleDateError, never>;
|
|
596
|
+
/**
|
|
597
|
+
* The schedule entry for a version's release line, if the schedule knows it.
|
|
598
|
+
*/
|
|
599
|
+
entryFor(version: NodeReleaseLine): Option.Option<NodeScheduleEntry>;
|
|
600
|
+
/**
|
|
601
|
+
* The lifecycle phase of a version's release line at a point in time.
|
|
602
|
+
*
|
|
603
|
+
* `now` is an explicit parameter rather than a read of the wall clock, which
|
|
604
|
+
* is what makes every phase transition testable without mocking time.
|
|
605
|
+
*
|
|
606
|
+
* Returns `Option.none()` when the schedule does not know the line, or when
|
|
607
|
+
* `now` is before the line was released — an unreleased line has no phase.
|
|
608
|
+
*/
|
|
609
|
+
phaseFor(version: NodeReleaseLine, now: DateTime.Utc): Option.Option<NodePhase>;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Whether a phase counts as Long-Term Support.
|
|
613
|
+
*
|
|
614
|
+
* @public
|
|
615
|
+
*/
|
|
616
|
+
declare const isLtsPhase: (phase: NodePhase) => boolean;
|
|
617
|
+
//#endregion
|
|
618
|
+
//#region src/NodeRelease.d.ts
|
|
619
|
+
declare const NodeRelease_base: Schema.Class<NodeRelease, Schema.Struct<{
|
|
620
|
+
/** The released version. */
|
|
621
|
+
readonly version: typeof SemVer;
|
|
622
|
+
/** The npm version bundled with it. */
|
|
623
|
+
readonly npm: typeof SemVer;
|
|
624
|
+
/** When it was published. */
|
|
625
|
+
readonly date: Schema.DateTimeUtc;
|
|
626
|
+
}>, {}>;
|
|
627
|
+
/**
|
|
628
|
+
* One Node.js release.
|
|
629
|
+
*
|
|
630
|
+
* Unlike its v3 ancestor this is an ordinary immutable value. v3's `NodeRelease`
|
|
631
|
+
* carried a `Ref<NodeSchedule>` so that `release.phase()` could reach the
|
|
632
|
+
* schedule, which meant every release held shared mutable state and could not be
|
|
633
|
+
* a data class at all. Phase is now a question you ask *with* a schedule rather
|
|
634
|
+
* than a property the release drags around.
|
|
635
|
+
*
|
|
636
|
+
* @example
|
|
637
|
+
* ```ts
|
|
638
|
+
* import { NodeRelease, NodeSchedule } from "@effected/runtimes";
|
|
639
|
+
* import { DateTime, Effect } from "effect";
|
|
640
|
+
*
|
|
641
|
+
* const program = Effect.gen(function* () {
|
|
642
|
+
* const schedule = yield* NodeSchedule.fromData({
|
|
643
|
+
* v20: { start: "2023-04-18", lts: "2023-10-24", end: "2026-04-30" },
|
|
644
|
+
* });
|
|
645
|
+
* const release = NodeRelease.make({
|
|
646
|
+
* version: yield* SemVer.parse("20.11.0"),
|
|
647
|
+
* npm: yield* SemVer.parse("10.2.4"),
|
|
648
|
+
* date: DateTime.makeUnsafe("2024-01-09"),
|
|
649
|
+
* });
|
|
650
|
+
* return release.isLts(schedule, DateTime.makeUnsafe("2024-06-01")); // true
|
|
651
|
+
* });
|
|
652
|
+
* ```
|
|
653
|
+
*
|
|
654
|
+
* @public
|
|
655
|
+
*/
|
|
656
|
+
declare class NodeRelease extends NodeRelease_base {
|
|
657
|
+
/**
|
|
658
|
+
* This release's lifecycle phase at a point in time.
|
|
659
|
+
*
|
|
660
|
+
* The release line, not the major, is what the schedule is keyed by: `0.10`
|
|
661
|
+
* and `0.12` are separate lines with separate end dates, so asking by major
|
|
662
|
+
* alone would answer `0.12` with `0.8`'s schedule.
|
|
663
|
+
*
|
|
664
|
+
* `Option.none()` when the schedule does not cover this line, or when `now`
|
|
665
|
+
* predates the line's release.
|
|
666
|
+
*/
|
|
667
|
+
phase(schedule: NodeSchedule, now: DateTime.Utc): Option.Option<NodePhase>;
|
|
668
|
+
/**
|
|
669
|
+
* Whether this release is in Long-Term Support at a point in time.
|
|
670
|
+
*/
|
|
671
|
+
isLts(schedule: NodeSchedule, now: DateTime.Utc): boolean;
|
|
672
|
+
}
|
|
673
|
+
//#endregion
|
|
674
|
+
//#region src/NodeResolver.d.ts
|
|
675
|
+
/**
|
|
676
|
+
* How to resolve Node.js versions.
|
|
677
|
+
*
|
|
678
|
+
* @public
|
|
679
|
+
*/
|
|
680
|
+
declare const NodeResolverOptions: Schema.Struct<{
|
|
681
|
+
/** The semver range to match. Defaults to `*`. */
|
|
682
|
+
readonly range: Schema.optionalKey<Schema.String>;
|
|
683
|
+
/** Lifecycle phases to accept. Defaults to `current` and `active-lts`. */
|
|
684
|
+
readonly phases: Schema.optionalKey<Schema.$Array<Schema.Literals<readonly ["current", "active-lts", "maintenance-lts", "end-of-life"]>>>;
|
|
685
|
+
/** How to group matches. Defaults to `latest`. */
|
|
686
|
+
readonly increments: Schema.optionalKey<Schema.Literals<readonly ["latest", "minor", "patch"]>>;
|
|
687
|
+
/** A range whose newest match becomes the `default` field. Defaults to the LTS pick. */
|
|
688
|
+
readonly defaultVersion: Schema.optionalKey<Schema.String>;
|
|
689
|
+
/** The moment to evaluate lifecycle phases at. Defaults to now, read from `Clock`. */
|
|
690
|
+
readonly date: Schema.optionalKey<Schema.DateTimeUtc>;
|
|
691
|
+
}>;
|
|
692
|
+
/**
|
|
693
|
+
* How to resolve Node.js versions.
|
|
694
|
+
*
|
|
695
|
+
* @public
|
|
696
|
+
*/
|
|
697
|
+
type NodeResolverOptions = typeof NodeResolverOptions.Type;
|
|
698
|
+
declare const NodeResolver_base: Context.ServiceClass<NodeResolver, "@effected/runtimes/NodeResolver", {
|
|
699
|
+
readonly resolve: (options?: NodeResolverOptions) => Effect.Effect<ResolvedVersions, InvalidRangeError | NoMatchingVersionError | UnresolvableDefaultError>;
|
|
700
|
+
}>;
|
|
701
|
+
/**
|
|
702
|
+
* The Node.js resolver.
|
|
703
|
+
*
|
|
704
|
+
* @example
|
|
705
|
+
* ```ts
|
|
706
|
+
* import { NodeResolver } from "@effected/runtimes";
|
|
707
|
+
* import { Effect } from "effect";
|
|
708
|
+
*
|
|
709
|
+
* const program = Effect.gen(function* () {
|
|
710
|
+
* const resolver = yield* NodeResolver;
|
|
711
|
+
* const result = yield* resolver.resolve({ range: ">=20", phases: ["active-lts"] });
|
|
712
|
+
* return result.latest;
|
|
713
|
+
* }).pipe(Effect.provide(NodeResolver.layerOffline));
|
|
714
|
+
* ```
|
|
715
|
+
*
|
|
716
|
+
* @public
|
|
717
|
+
*/
|
|
718
|
+
declare class NodeResolver extends NodeResolver_base {
|
|
719
|
+
/**
|
|
720
|
+
* Try the live feeds, fall back to the bundled snapshot.
|
|
721
|
+
*
|
|
722
|
+
* A fallback is recorded as `source: "cache"` and logged, so a caller can
|
|
723
|
+
* always tell a live answer from a snapshot.
|
|
724
|
+
*/
|
|
725
|
+
static readonly layer: Layer.Layer<NodeResolver, never, HttpClient.HttpClient>;
|
|
726
|
+
/**
|
|
727
|
+
* Live feeds or nothing. Fails with `FreshnessError` when they cannot be reached.
|
|
728
|
+
*/
|
|
729
|
+
static readonly layerFresh: Layer.Layer<NodeResolver, FreshnessError, HttpClient.HttpClient>;
|
|
730
|
+
/**
|
|
731
|
+
* The bundled snapshot only. Performs no IO and requires nothing.
|
|
732
|
+
*/
|
|
733
|
+
static readonly layerOffline: Layer.Layer<NodeResolver>;
|
|
734
|
+
}
|
|
735
|
+
//#endregion
|
|
736
|
+
export { AuthenticationError, BunRelease, BunResolver, BunResolverOptions, DenoRelease, DenoResolver, DenoResolverOptions, FreshnessError, GitHubAuth, type GitHubAuthShape, GitHubClient, type GitHubClientShape, type GitHubError, GitHubRelease, GitHubTag, Increments, InvalidScheduleDateError, type ListOptions, NetworkError, NoMatchingVersionError, NodePhase, NodeRelease, type NodeReleaseLine, NodeResolver, NodeResolverOptions, NodeSchedule, NodeScheduleData, NodeScheduleEntry, RateLimitError, ResolvedVersions, ResponseParseError, Runtime, Source, UnresolvableDefaultError, isLtsPhase, nodeReleaseLine };
|
|
737
|
+
//# sourceMappingURL=index.d.ts.map
|