type-registry-effect 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/821.js +628 -0
- package/LICENSE +21 -0
- package/README.md +45 -0
- package/index.d.ts +1754 -0
- package/index.js +173 -0
- package/node.d.ts +890 -0
- package/node.js +26 -0
- package/package.json +67 -0
- package/rslib-runtime.js +37 -0
- package/tsdoc-metadata.json +11 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,1754 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* type-registry-effect — platform-agnostic entry point.
|
|
3
|
+
*
|
|
4
|
+
* Provides composable Effect programs for fetching, caching, and resolving
|
|
5
|
+
* TypeScript type definitions from npm packages via the jsDelivr CDN.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* This entry point contains only platform-agnostic code. It exports:
|
|
9
|
+
*
|
|
10
|
+
* - **Namespace modules** — {@link TypeRegistry} (composable programs) and
|
|
11
|
+
* {@link VirtualPackage} (synthetic packages from local declarations).
|
|
12
|
+
* - **Schemas** — {@link PackageSpec}, {@link CacheMetadata},
|
|
13
|
+
* {@link ResolvedModule}, {@link PackageJson}, {@link FileTreeResponse}.
|
|
14
|
+
* - **Errors** — {@link CacheError}, {@link NetworkError},
|
|
15
|
+
* {@link PackageNotFoundError}, {@link ParseError},
|
|
16
|
+
* {@link ResolutionError}, {@link TimeoutError}.
|
|
17
|
+
* - **Services** — {@link CacheService}, {@link PackageFetcher},
|
|
18
|
+
* {@link TypeResolver}.
|
|
19
|
+
* - **Layers** — {@link CacheServiceLive}, {@link PackageFetcherLive},
|
|
20
|
+
* {@link TypeResolverLive}, {@link TypeRegistryLive}.
|
|
21
|
+
* - **Events** — {@link LogEventSchema}, {@link LogEvent}.
|
|
22
|
+
*
|
|
23
|
+
* For a Node.js convenience layer and Promise-returning wrappers, import
|
|
24
|
+
* from `type-registry-effect/node` instead.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* import { Effect } from "effect";
|
|
29
|
+
* import { TypeRegistry, PackageSpec, TypeRegistryLive } from "type-registry-effect";
|
|
30
|
+
* import { NodeFileSystem, NodeHttpClient } from "@effect/platform-node";
|
|
31
|
+
*
|
|
32
|
+
* const program = Effect.gen(function* () {
|
|
33
|
+
* const pkg = new PackageSpec({ name: "zod", version: "3.23.8" });
|
|
34
|
+
* yield* TypeRegistry.fetchAndCache(pkg);
|
|
35
|
+
* return yield* TypeRegistry.getVFS([pkg]);
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* const vfs = await program.pipe(
|
|
39
|
+
* Effect.provide(TypeRegistryLive),
|
|
40
|
+
* Effect.provide(NodeFileSystem.layer),
|
|
41
|
+
* Effect.provide(NodeHttpClient.layerUndici),
|
|
42
|
+
* Effect.runPromise,
|
|
43
|
+
* );
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @packageDocumentation
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
import { Context } from 'effect';
|
|
50
|
+
import { Effect } from 'effect';
|
|
51
|
+
import { Equals } from 'effect/Types';
|
|
52
|
+
import { FileSystem } from '@effect/platform';
|
|
53
|
+
import { HttpClient } from '@effect/platform';
|
|
54
|
+
import { Layer } from 'effect';
|
|
55
|
+
import { Schema } from 'effect';
|
|
56
|
+
import * as Schema_2 from 'effect/Schema';
|
|
57
|
+
import { YieldableError } from 'effect/Cause';
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Raised when a disk cache operation (read, write, delete, or list) fails.
|
|
61
|
+
*
|
|
62
|
+
* @remarks
|
|
63
|
+
* The `operation` field indicates which cache operation triggered the failure,
|
|
64
|
+
* `path` is the filesystem path involved, and `message` describes the
|
|
65
|
+
* underlying cause (e.g. permission denied, disk full). Use `Effect.catchTag`
|
|
66
|
+
* with the `"CacheError"` tag to handle this error selectively.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* import { Effect } from "effect";
|
|
71
|
+
* import type { CacheError } from "type-registry-effect";
|
|
72
|
+
* import { TypeRegistry, PackageSpec } from "type-registry-effect";
|
|
73
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
74
|
+
*
|
|
75
|
+
* const program = TypeRegistry.fetchAndCache(
|
|
76
|
+
* new PackageSpec({ name: "zod", version: "3.23.8" }),
|
|
77
|
+
* ).pipe(
|
|
78
|
+
* Effect.catchTag("CacheError", (err: CacheError) =>
|
|
79
|
+
* Effect.logWarning(`Cache ${err.operation} failed at ${err.path}: ${err.message}`),
|
|
80
|
+
* ),
|
|
81
|
+
* );
|
|
82
|
+
*
|
|
83
|
+
* await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* @see {@link CacheService}
|
|
87
|
+
* @public
|
|
88
|
+
*/
|
|
89
|
+
export declare class CacheError extends CacheErrorBase<{
|
|
90
|
+
readonly operation: "read" | "write" | "delete" | "list";
|
|
91
|
+
readonly path: string;
|
|
92
|
+
readonly message: string;
|
|
93
|
+
}> {
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @internal
|
|
98
|
+
* Exported for declaration bundling (api-extractor). When `export *` re-exports
|
|
99
|
+
* a class whose `extends` expression is an inline call like
|
|
100
|
+
* `Data.TaggedError(...)`, TypeScript emits an un-nameable `_base` symbol in
|
|
101
|
+
* the declaration file. Splitting the base into a named export gives the
|
|
102
|
+
* bundler a stable reference.
|
|
103
|
+
*
|
|
104
|
+
* @privateRemarks
|
|
105
|
+
* This base constant must remain a named export so that api-extractor can
|
|
106
|
+
* resolve the extends clause of {@link CacheError} to a stable
|
|
107
|
+
* declaration. Without it the bundled `.d.ts` would contain an anonymous
|
|
108
|
+
* `_base` symbol that cannot be referenced by downstream consumers.
|
|
109
|
+
*/
|
|
110
|
+
export declare const CacheErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
|
|
111
|
+
readonly _tag: "CacheError";
|
|
112
|
+
} & Readonly<A>;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Metadata stored alongside cached packages on disk.
|
|
116
|
+
*
|
|
117
|
+
* @remarks
|
|
118
|
+
* Each cached package directory contains a metadata file recording when it was
|
|
119
|
+
* cached and the version that was resolved. The optional `ttl` field (in
|
|
120
|
+
* milliseconds) allows per-package cache expiration policies. When `ttl` is
|
|
121
|
+
* omitted the cache entry never expires automatically.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```typescript
|
|
125
|
+
* import { CacheMetadata } from "type-registry-effect";
|
|
126
|
+
*
|
|
127
|
+
* // Metadata with an explicit 1-hour TTL
|
|
128
|
+
* const meta: CacheMetadata = {
|
|
129
|
+
* version: "3.23.8",
|
|
130
|
+
* cachedAt: Date.now(),
|
|
131
|
+
* ttl: 60 * 60 * 1000,
|
|
132
|
+
* };
|
|
133
|
+
*
|
|
134
|
+
* // Metadata that never expires
|
|
135
|
+
* const permanent: CacheMetadata = {
|
|
136
|
+
* version: "5.4.2",
|
|
137
|
+
* cachedAt: Date.now(),
|
|
138
|
+
* };
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
141
|
+
* @see {@link CacheServiceLive}
|
|
142
|
+
* @see {@link TypeRegistry.fetchAndCache}
|
|
143
|
+
* @public
|
|
144
|
+
*/
|
|
145
|
+
export declare interface CacheMetadata {
|
|
146
|
+
readonly version: string;
|
|
147
|
+
readonly cachedAt: number;
|
|
148
|
+
readonly ttl?: number | undefined;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Effect Schema for validating and encoding {@link CacheMetadata}.
|
|
153
|
+
*
|
|
154
|
+
* @see {@link CacheMetadata}
|
|
155
|
+
*/
|
|
156
|
+
export declare const CacheMetadata: Schema.Schema<CacheMetadata>;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Effect service interface for the disk-based type definition cache.
|
|
160
|
+
*
|
|
161
|
+
* @remarks
|
|
162
|
+
* Implementations store type definition files and metadata on disk using a
|
|
163
|
+
* platform-specific {@link @effect/platform#FileSystem | FileSystem} service.
|
|
164
|
+
* Platform dependencies are resolved **within the layer**, so consumers of this
|
|
165
|
+
* interface never interact with the filesystem directly.
|
|
166
|
+
*
|
|
167
|
+
* Use this tag to access cache methods inside an `Effect.gen` block. The live
|
|
168
|
+
* implementation is provided by {@link CacheServiceLive} (or the lower-level
|
|
169
|
+
* {@link makeNodeCacheLayer}).
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```typescript
|
|
173
|
+
* import { Effect } from "effect";
|
|
174
|
+
* import { CacheService } from "type-registry-effect";
|
|
175
|
+
* import type { PackageSpec } from "type-registry-effect";
|
|
176
|
+
*
|
|
177
|
+
* const program = Effect.gen(function* () {
|
|
178
|
+
* const cache = yield* CacheService;
|
|
179
|
+
* const exists = yield* cache.exists({ name: "lodash", version: "4.17.21" } as PackageSpec);
|
|
180
|
+
* console.log("cached:", exists);
|
|
181
|
+
* });
|
|
182
|
+
* ```
|
|
183
|
+
*
|
|
184
|
+
* @see {@link CacheServiceLive}
|
|
185
|
+
* @see {@link makeNodeCacheLayer}
|
|
186
|
+
*
|
|
187
|
+
* @public
|
|
188
|
+
*/
|
|
189
|
+
export declare interface CacheService {
|
|
190
|
+
/** Check whether cached type definitions exist for a package. */
|
|
191
|
+
readonly exists: (pkg: PackageSpec) => Effect.Effect<boolean, CacheError>;
|
|
192
|
+
/** Read a single cached file by relative path within the package cache directory. */
|
|
193
|
+
readonly read: (pkg: PackageSpec, filePath: string) => Effect.Effect<string, CacheError>;
|
|
194
|
+
/** Write a single file into the package cache directory, creating parent directories as needed. */
|
|
195
|
+
readonly write: (pkg: PackageSpec, filePath: string, content: string) => Effect.Effect<void, CacheError>;
|
|
196
|
+
/** List all cached file paths (relative) for a package. */
|
|
197
|
+
readonly listFiles: (pkg: PackageSpec) => Effect.Effect<ReadonlyArray<string>, CacheError>;
|
|
198
|
+
/** Read the `.metadata.json` sidecar for a cached package. */
|
|
199
|
+
readonly readMetadata: (pkg: PackageSpec) => Effect.Effect<CacheMetadata, CacheError>;
|
|
200
|
+
/** Write or overwrite the `.metadata.json` sidecar for a cached package. */
|
|
201
|
+
readonly writeMetadata: (pkg: PackageSpec, metadata: CacheMetadata) => Effect.Effect<void, CacheError>;
|
|
202
|
+
/** Build a {@link VirtualFileSystem} from the cache, suitable for an in-memory TS compiler host. */
|
|
203
|
+
readonly getVFS: (pkg: PackageSpec) => Effect.Effect<VirtualFileSystem, CacheError>;
|
|
204
|
+
/** Remove all cached data for a package, including metadata. */
|
|
205
|
+
readonly remove: (pkg: PackageSpec) => Effect.Effect<void, CacheError>;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Effect Context tag for the {@link CacheService} service.
|
|
210
|
+
*
|
|
211
|
+
* @see {@link CacheServiceLive}
|
|
212
|
+
* @see {@link makeNodeCacheLayer}
|
|
213
|
+
*/
|
|
214
|
+
export declare const CacheService: Context.Tag<CacheService, CacheService>;
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Default {@link CacheService} layer using the XDG cache directory.
|
|
218
|
+
*
|
|
219
|
+
* @remarks
|
|
220
|
+
* This is equivalent to calling {@link makeNodeCacheLayer} with no arguments.
|
|
221
|
+
* Requires a {@link @effect/platform#FileSystem | FileSystem} layer to be
|
|
222
|
+
* provided at composition time.
|
|
223
|
+
*
|
|
224
|
+
* @see {@link makeNodeCacheLayer}
|
|
225
|
+
*
|
|
226
|
+
* @public
|
|
227
|
+
*/
|
|
228
|
+
export declare const CacheServiceLive: Layer.Layer<CacheService, never, FileSystem.FileSystem>;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Remove a package and all of its cached files from the disk cache.
|
|
232
|
+
*
|
|
233
|
+
* @param pkg - The package specification to remove.
|
|
234
|
+
* @returns An Effect that succeeds with `void` once the cache entry is deleted.
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```typescript
|
|
238
|
+
* import { Effect } from "effect";
|
|
239
|
+
* import { TypeRegistry, PackageSpec } from "type-registry-effect";
|
|
240
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
241
|
+
*
|
|
242
|
+
* const program = Effect.gen(function* () {
|
|
243
|
+
* const pkg = new PackageSpec({ name: "zod", version: "3.23.8" });
|
|
244
|
+
* yield* TypeRegistry.clearCache(pkg);
|
|
245
|
+
* console.log("Cache cleared for zod@3.23.8");
|
|
246
|
+
* });
|
|
247
|
+
*
|
|
248
|
+
* await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
249
|
+
* ```
|
|
250
|
+
*
|
|
251
|
+
* @see {@link hasCached} to check existence before clearing
|
|
252
|
+
* @see {@link fetchAndCache} to repopulate the cache afterward
|
|
253
|
+
*
|
|
254
|
+
* @public
|
|
255
|
+
*/
|
|
256
|
+
declare const clearCache: (pkg: PackageSpec) => Effect.Effect<void, CacheError, CacheService>;
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Create a validated {@link LogEvent} from unknown data.
|
|
260
|
+
*
|
|
261
|
+
* @remarks
|
|
262
|
+
* Decodes `event` synchronously through {@link LogEventSchema}. Throws a
|
|
263
|
+
* parse error if the input does not conform to any variant of the schema.
|
|
264
|
+
* This is intended for internal use within the library's logging
|
|
265
|
+
* infrastructure.
|
|
266
|
+
*
|
|
267
|
+
* @param event - Raw, unvalidated event data.
|
|
268
|
+
* @returns A fully validated {@link LogEvent}.
|
|
269
|
+
* @throws `ParseError` when `event` does not match {@link LogEventSchema}.
|
|
270
|
+
*
|
|
271
|
+
* @internal
|
|
272
|
+
*/
|
|
273
|
+
export declare function createLogEvent(event: unknown): LogEvent;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Fetch type definitions for a package from the jsDelivr CDN and write them
|
|
277
|
+
* to the disk cache.
|
|
278
|
+
*
|
|
279
|
+
* @remarks
|
|
280
|
+
* The function downloads the `package.json` and every `.d.ts` file published
|
|
281
|
+
* by the package, then persists them under the {@link CacheService} storage
|
|
282
|
+
* directory. A {@link CacheMetadata} record is written alongside the files so
|
|
283
|
+
* that future cache hits can evaluate freshness.
|
|
284
|
+
*
|
|
285
|
+
* The optional `ttl` (time-to-live) is stored in the metadata and expressed
|
|
286
|
+
* in **milliseconds**. When a subsequent read finds that the cache entry is
|
|
287
|
+
* older than `ttl`, the entry is considered stale and a re-fetch is triggered
|
|
288
|
+
* by higher-level operations such as {@link getPackageVFS}.
|
|
289
|
+
*
|
|
290
|
+
* @param pkg - The package specification to fetch.
|
|
291
|
+
* @param options - Optional configuration. When provided, `options.ttl` sets
|
|
292
|
+
* the time-to-live in milliseconds for the cached entry.
|
|
293
|
+
* @returns An Effect that succeeds with `void` once all files are written.
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```typescript
|
|
297
|
+
* import { Effect } from "effect";
|
|
298
|
+
* import { TypeRegistry, PackageSpec } from "type-registry-effect";
|
|
299
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
300
|
+
*
|
|
301
|
+
* const program = Effect.gen(function* () {
|
|
302
|
+
* const pkg = new PackageSpec({ name: "lodash", version: "4.17.21" });
|
|
303
|
+
* // Cache with a 1-hour TTL
|
|
304
|
+
* yield* TypeRegistry.fetchAndCache(pkg, { ttl: 60 * 60 * 1000 });
|
|
305
|
+
* });
|
|
306
|
+
*
|
|
307
|
+
* await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
308
|
+
* ```
|
|
309
|
+
*
|
|
310
|
+
* @see {@link hasCached} to check before fetching
|
|
311
|
+
* @see {@link getPackageVFS} for a higher-level API that auto-fetches
|
|
312
|
+
*
|
|
313
|
+
* @public
|
|
314
|
+
*/
|
|
315
|
+
declare const fetchAndCache: (pkg: PackageSpec, options?: {
|
|
316
|
+
readonly ttl?: number;
|
|
317
|
+
} | undefined) => Effect.Effect<void, CacheError | NetworkError | ParseError, CacheService | PackageFetcher>;
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Schema for a single file entry in the jsDelivr flat file tree response.
|
|
321
|
+
*
|
|
322
|
+
* @remarks
|
|
323
|
+
* Each entry contains the file `name` (path relative to the package root),
|
|
324
|
+
* a content `hash` for integrity checking, a `time` timestamp string, and
|
|
325
|
+
* the file `size` in bytes. This schema is used to validate raw JSON from
|
|
326
|
+
* the jsDelivr data API before further processing.
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```typescript
|
|
330
|
+
* import { Schema } from "effect";
|
|
331
|
+
* import { FileTreeEntry } from "type-registry-effect";
|
|
332
|
+
*
|
|
333
|
+
* const decode = Schema.decodeUnknownSync(FileTreeEntry);
|
|
334
|
+
* const entry = decode({
|
|
335
|
+
* name: "/dist/index.d.ts",
|
|
336
|
+
* hash: "abc123",
|
|
337
|
+
* time: "2024-01-15T10:30:00.000Z",
|
|
338
|
+
* size: 4096,
|
|
339
|
+
* });
|
|
340
|
+
* ```
|
|
341
|
+
*
|
|
342
|
+
* @see {@link PackageFetcher.getFileTree}
|
|
343
|
+
* @public
|
|
344
|
+
*/
|
|
345
|
+
export declare const FileTreeEntry: Schema.Struct<{
|
|
346
|
+
name: typeof Schema.String;
|
|
347
|
+
hash: typeof Schema.String;
|
|
348
|
+
time: typeof Schema.String;
|
|
349
|
+
size: typeof Schema.Number;
|
|
350
|
+
}>;
|
|
351
|
+
|
|
352
|
+
export declare type FileTreeEntry = Schema.Schema.Type<typeof FileTreeEntry>;
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Schema for the jsDelivr flat file tree API response.
|
|
356
|
+
*
|
|
357
|
+
* @remarks
|
|
358
|
+
* The response includes a `default` field indicating the package's default
|
|
359
|
+
* branch/tag and a `files` array of {@link FileTreeEntry} objects. This
|
|
360
|
+
* corresponds to the `GET /v1/packages/npm/:package@:version/flat` endpoint.
|
|
361
|
+
*
|
|
362
|
+
* @example
|
|
363
|
+
* ```typescript
|
|
364
|
+
* import { Schema } from "effect";
|
|
365
|
+
* import { FileTreeResponse } from "type-registry-effect";
|
|
366
|
+
*
|
|
367
|
+
* const decode = Schema.decodeUnknownSync(FileTreeResponse);
|
|
368
|
+
* const tree = decode({
|
|
369
|
+
* default: "/dist/index.js",
|
|
370
|
+
* files: [
|
|
371
|
+
* { name: "/dist/index.js", hash: "abc123", time: "2024-01-15T10:30:00.000Z", size: 2048 },
|
|
372
|
+
* { name: "/dist/index.d.ts", hash: "def456", time: "2024-01-15T10:30:00.000Z", size: 4096 },
|
|
373
|
+
* ],
|
|
374
|
+
* });
|
|
375
|
+
* ```
|
|
376
|
+
*
|
|
377
|
+
* @see {@link PackageFetcher.getFileTree}
|
|
378
|
+
* @see {@link https://www.jsdelivr.com/docs/data.jsdelivr.com | jsDelivr Data API}
|
|
379
|
+
* @public
|
|
380
|
+
*/
|
|
381
|
+
export declare const FileTreeResponse: Schema.Struct<{
|
|
382
|
+
default: typeof Schema.String;
|
|
383
|
+
files: Schema.Array$<Schema.Struct<{
|
|
384
|
+
name: typeof Schema.String;
|
|
385
|
+
hash: typeof Schema.String;
|
|
386
|
+
time: typeof Schema.String;
|
|
387
|
+
size: typeof Schema.Number;
|
|
388
|
+
}>>;
|
|
389
|
+
}>;
|
|
390
|
+
|
|
391
|
+
export declare type FileTreeResponse = Schema.Schema.Type<typeof FileTreeResponse>;
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Return the default cache directory used by `effect-type-registry`.
|
|
395
|
+
*
|
|
396
|
+
* @remarks
|
|
397
|
+
* Resolves to `<XDG_CACHE_HOME>/effect-type-registry`. This is the path
|
|
398
|
+
* used by the built-in Node.js cache layer when no custom directory is
|
|
399
|
+
* provided.
|
|
400
|
+
*
|
|
401
|
+
* @returns Absolute path to the default cache directory
|
|
402
|
+
* (e.g. `~/.cache/effect-type-registry`).
|
|
403
|
+
*
|
|
404
|
+
* @see {@link makeNodeCacheLayer} in `"type-registry-effect/node"` which
|
|
405
|
+
* calls this function when constructing the default layer.
|
|
406
|
+
*
|
|
407
|
+
* @public
|
|
408
|
+
*/
|
|
409
|
+
export declare function getDefaultCacheDir(): string;
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Get a {@link VirtualFileSystem} for a single package, optionally fetching
|
|
413
|
+
* it from the CDN first if it is not already cached.
|
|
414
|
+
*
|
|
415
|
+
* @remarks
|
|
416
|
+
* When `autoFetch` is `true` (the default) and the package is not present in
|
|
417
|
+
* the cache, this function transparently calls {@link fetchAndCache} before
|
|
418
|
+
* building the VFS. Set `autoFetch` to `false` to restrict the operation to
|
|
419
|
+
* cached data only; a {@link PackageNotFoundError} is raised if the package
|
|
420
|
+
* is missing.
|
|
421
|
+
*
|
|
422
|
+
* The returned VFS maps file paths (relative to `node_modules/<package>`) to
|
|
423
|
+
* their string contents.
|
|
424
|
+
*
|
|
425
|
+
* @param pkg - The package specification to retrieve.
|
|
426
|
+
* @param options - Optional configuration. When provided, `options.autoFetch`
|
|
427
|
+
* controls whether to fetch from the CDN on a cache miss (default `true`),
|
|
428
|
+
* and `options.ttl` sets the time-to-live in milliseconds forwarded to
|
|
429
|
+
* {@link fetchAndCache}.
|
|
430
|
+
* @returns An Effect that succeeds with the package's {@link VirtualFileSystem}.
|
|
431
|
+
*
|
|
432
|
+
* @example
|
|
433
|
+
* ```typescript
|
|
434
|
+
* import { Effect } from "effect";
|
|
435
|
+
* import type { VirtualFileSystem } from "type-registry-effect";
|
|
436
|
+
* import { TypeRegistry, PackageSpec } from "type-registry-effect";
|
|
437
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
438
|
+
*
|
|
439
|
+
* const program = Effect.gen(function* () {
|
|
440
|
+
* const pkg = new PackageSpec({ name: "zod", version: "3.23.8" });
|
|
441
|
+
* // Auto-fetches if not cached
|
|
442
|
+
* const vfs: VirtualFileSystem = yield* TypeRegistry.getPackageVFS(pkg);
|
|
443
|
+
* console.log(`Files: ${[...vfs.keys()].join(", ")}`);
|
|
444
|
+
* return vfs;
|
|
445
|
+
* });
|
|
446
|
+
*
|
|
447
|
+
* const vfs = await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
448
|
+
* ```
|
|
449
|
+
*
|
|
450
|
+
* @see {@link getVFS} to load multiple packages at once
|
|
451
|
+
* @see {@link fetchAndCache} for the underlying fetch + write logic
|
|
452
|
+
*
|
|
453
|
+
* @public
|
|
454
|
+
*/
|
|
455
|
+
declare const getPackageVFS: (pkg: PackageSpec, options?: {
|
|
456
|
+
readonly autoFetch?: boolean;
|
|
457
|
+
readonly ttl?: number;
|
|
458
|
+
} | undefined) => Effect.Effect<VirtualFileSystem, CacheError | NetworkError | PackageNotFoundError | ParseError, CacheService | PackageFetcher>;
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Get all type entry points exported by a cached package.
|
|
462
|
+
*
|
|
463
|
+
* @remarks
|
|
464
|
+
* Reads the cached `package.json` and delegates to {@link TypeResolver} to
|
|
465
|
+
* enumerate every entry point that exposes type definitions (via `exports`,
|
|
466
|
+
* `types`, or `typings` fields). The package must already be in the cache.
|
|
467
|
+
*
|
|
468
|
+
* @param pkg - The cached package to inspect.
|
|
469
|
+
* @returns An Effect that succeeds with a read-only array of {@link ResolvedModule} entries.
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
* ```typescript
|
|
473
|
+
* import { Effect } from "effect";
|
|
474
|
+
* import type { ResolvedModule } from "type-registry-effect";
|
|
475
|
+
* import { TypeRegistry, PackageSpec } from "type-registry-effect";
|
|
476
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
477
|
+
*
|
|
478
|
+
* const program = Effect.gen(function* () {
|
|
479
|
+
* const pkg = new PackageSpec({ name: "effect", version: "3.12.5" });
|
|
480
|
+
* yield* TypeRegistry.fetchAndCache(pkg);
|
|
481
|
+
* const entries: ReadonlyArray<ResolvedModule> = yield* TypeRegistry.getTypeEntries(pkg);
|
|
482
|
+
* for (const entry of entries) {
|
|
483
|
+
* console.log(`${entry.specifier} -> ${entry.resolvedPath}`);
|
|
484
|
+
* }
|
|
485
|
+
* return entries;
|
|
486
|
+
* });
|
|
487
|
+
*
|
|
488
|
+
* const entries = await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
489
|
+
* ```
|
|
490
|
+
*
|
|
491
|
+
* @see {@link resolveImport} to resolve a single specifier
|
|
492
|
+
* @see {@link TypeResolver} for the underlying resolution service
|
|
493
|
+
*
|
|
494
|
+
* @public
|
|
495
|
+
*/
|
|
496
|
+
declare const getTypeEntries: (pkg: PackageSpec) => Effect.Effect<readonly ResolvedModule[], CacheError | ParseError | ResolutionError, CacheService | TypeResolver>;
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Get a combined {@link VirtualFileSystem} for multiple packages with
|
|
500
|
+
* graceful degradation on per-package failures.
|
|
501
|
+
*
|
|
502
|
+
* @remarks
|
|
503
|
+
* Packages are fetched concurrently with a concurrency limit of **5**.
|
|
504
|
+
* Individual package failures are caught and accumulated rather than
|
|
505
|
+
* aborting the entire batch. The operation only fails with a
|
|
506
|
+
* {@link PackageNotFoundError} when **every** requested package fails.
|
|
507
|
+
* When at least one package succeeds, the merged VFS is returned and
|
|
508
|
+
* failing packages are silently skipped.
|
|
509
|
+
*
|
|
510
|
+
* This partial-failure strategy makes the function suitable for
|
|
511
|
+
* best-effort scenarios such as editor integrations where missing type
|
|
512
|
+
* definitions for one dependency should not block the rest.
|
|
513
|
+
*
|
|
514
|
+
* @param packages - Array of package specifications to load.
|
|
515
|
+
* @param options - Optional configuration forwarded to {@link getPackageVFS}.
|
|
516
|
+
* When provided, `options.autoFetch` controls whether to fetch missing
|
|
517
|
+
* packages from the CDN (default `true`), and `options.ttl` sets the
|
|
518
|
+
* time-to-live in milliseconds for newly cached entries.
|
|
519
|
+
* @returns An Effect that succeeds with the merged {@link VirtualFileSystem}.
|
|
520
|
+
*
|
|
521
|
+
* @example
|
|
522
|
+
* ```typescript
|
|
523
|
+
* import { Effect } from "effect";
|
|
524
|
+
* import type { VirtualFileSystem } from "type-registry-effect";
|
|
525
|
+
* import { TypeRegistry, PackageSpec } from "type-registry-effect";
|
|
526
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
527
|
+
*
|
|
528
|
+
* const program = Effect.gen(function* () {
|
|
529
|
+
* const packages = [
|
|
530
|
+
* new PackageSpec({ name: "zod", version: "3.23.8" }),
|
|
531
|
+
* new PackageSpec({ name: "effect", version: "3.12.5" }),
|
|
532
|
+
* ];
|
|
533
|
+
* const vfs: VirtualFileSystem = yield* TypeRegistry.getVFS(packages);
|
|
534
|
+
* console.log(`Total VFS entries: ${vfs.size}`);
|
|
535
|
+
* return vfs;
|
|
536
|
+
* });
|
|
537
|
+
*
|
|
538
|
+
* const vfs = await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
539
|
+
* ```
|
|
540
|
+
*
|
|
541
|
+
* @see {@link getPackageVFS} for loading a single package
|
|
542
|
+
*
|
|
543
|
+
* @public
|
|
544
|
+
*/
|
|
545
|
+
declare const getVFS: (packages: readonly PackageSpec[], options?: {
|
|
546
|
+
readonly autoFetch?: boolean;
|
|
547
|
+
readonly ttl?: number;
|
|
548
|
+
} | undefined) => Effect.Effect<VirtualFileSystem, PackageNotFoundError, CacheService | PackageFetcher>;
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Check whether a package already exists in the disk cache.
|
|
552
|
+
*
|
|
553
|
+
* @remarks
|
|
554
|
+
* This performs a lightweight existence check against {@link CacheService} without
|
|
555
|
+
* reading any file contents. Use it to decide whether to fetch before calling
|
|
556
|
+
* {@link fetchAndCache}.
|
|
557
|
+
*
|
|
558
|
+
* @param pkg - The package specification to look up.
|
|
559
|
+
* @returns An Effect that succeeds with `true` when the package is cached, `false` otherwise.
|
|
560
|
+
*
|
|
561
|
+
* @example
|
|
562
|
+
* ```typescript
|
|
563
|
+
* import { Effect } from "effect";
|
|
564
|
+
* import { TypeRegistry, PackageSpec } from "type-registry-effect";
|
|
565
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
566
|
+
*
|
|
567
|
+
* const program = Effect.gen(function* () {
|
|
568
|
+
* const pkg = new PackageSpec({ name: "zod", version: "3.23.8" });
|
|
569
|
+
* const exists = yield* TypeRegistry.hasCached(pkg);
|
|
570
|
+
* console.log(`zod@3.23.8 cached: ${exists}`);
|
|
571
|
+
* return exists;
|
|
572
|
+
* });
|
|
573
|
+
*
|
|
574
|
+
* const result = await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
575
|
+
* ```
|
|
576
|
+
*
|
|
577
|
+
* @public
|
|
578
|
+
*/
|
|
579
|
+
declare const hasCached: (pkg: PackageSpec) => Effect.Effect<boolean, CacheError, CacheService>;
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* Type-safe log event inferred from {@link LogEventSchema}.
|
|
583
|
+
*
|
|
584
|
+
* @remarks
|
|
585
|
+
* This is a discriminated union — narrow it using the `event` string literal
|
|
586
|
+
* field. Each variant carries a strongly-typed `data` payload.
|
|
587
|
+
*
|
|
588
|
+
* @example
|
|
589
|
+
* ```typescript
|
|
590
|
+
* import type { LogEvent } from "type-registry-effect";
|
|
591
|
+
*
|
|
592
|
+
* function handleEvent(event: LogEvent): void {
|
|
593
|
+
* switch (event.event) {
|
|
594
|
+
* case "cache.hit":
|
|
595
|
+
* console.log(`Cache hit for ${event.data.package}@${event.data.version}`);
|
|
596
|
+
* break;
|
|
597
|
+
* case "cache.miss":
|
|
598
|
+
* console.log(`Cache miss for ${event.data.package}@${event.data.version}`);
|
|
599
|
+
* break;
|
|
600
|
+
* case "package.loaded":
|
|
601
|
+
* console.log(`Loaded ${event.data.files} files from ${event.data.source}`);
|
|
602
|
+
* break;
|
|
603
|
+
* case "packages.batch.complete":
|
|
604
|
+
* console.log(`Batch done: ${event.data.loaded}/${event.data.total} in ${event.data.durationMs}ms`);
|
|
605
|
+
* break;
|
|
606
|
+
* default:
|
|
607
|
+
* console.log(`[${event.level}] ${event.message}`);
|
|
608
|
+
* }
|
|
609
|
+
* }
|
|
610
|
+
* ```
|
|
611
|
+
*
|
|
612
|
+
* @see {@link LogEventSchema} for the runtime schema definition
|
|
613
|
+
*
|
|
614
|
+
* @public
|
|
615
|
+
*/
|
|
616
|
+
export declare type LogEvent = Schema_2.Schema.Type<typeof LogEventSchema>;
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Callback function type for receiving validated {@link LogEvent} instances.
|
|
620
|
+
*
|
|
621
|
+
* @remarks
|
|
622
|
+
* Pass an implementation of this type to logging integrations that subscribe
|
|
623
|
+
* to TypeRegistry operations. The handler is invoked synchronously with each
|
|
624
|
+
* event after it has been validated against the {@link LogEventSchema}.
|
|
625
|
+
*
|
|
626
|
+
* @see {@link LogEvent} for the event payload type
|
|
627
|
+
* @see {@link LogEventSchema} for the runtime schema
|
|
628
|
+
*
|
|
629
|
+
* @public
|
|
630
|
+
*/
|
|
631
|
+
export declare type LogEventHandler = (event: LogEvent) => void;
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* Discriminated union schema for all structured log events emitted by
|
|
635
|
+
* TypeRegistry operations.
|
|
636
|
+
*
|
|
637
|
+
* @remarks
|
|
638
|
+
* The following event types are defined:
|
|
639
|
+
*
|
|
640
|
+
* - `"package.version.resolved"` — a version reference was resolved to a pinned version.
|
|
641
|
+
* - `"cache.hit"` — a package was found in the disk cache and is fresh.
|
|
642
|
+
* - `"cache.stale"` — a cached package exceeded its TTL.
|
|
643
|
+
* - `"cache.miss"` — a package was not found in the cache.
|
|
644
|
+
* - `"package.fetch.start"` — a network fetch has begun for a package.
|
|
645
|
+
* - `"package.loaded"` — a package was successfully loaded (from cache or network).
|
|
646
|
+
* - `"package.load.failed"` — loading a package failed.
|
|
647
|
+
* - `"packages.batch.start"` — a batch operation started for multiple packages.
|
|
648
|
+
* - `"packages.batch.complete"` — a batch operation finished with summary statistics.
|
|
649
|
+
* - `"typescript.cache.created"` — a TypeScript in-memory cache was created from VFS data.
|
|
650
|
+
*
|
|
651
|
+
* Use the `event` field on the decoded value to narrow the type in a
|
|
652
|
+
* `switch`/`case` or `if` block.
|
|
653
|
+
*
|
|
654
|
+
* @see {@link LogEvent} for the inferred TypeScript type
|
|
655
|
+
* @see {@link LogEventHandler} for the callback signature
|
|
656
|
+
*
|
|
657
|
+
* @example
|
|
658
|
+
* ```typescript
|
|
659
|
+
* import type { LogEventHandler } from "type-registry-effect";
|
|
660
|
+
*
|
|
661
|
+
* const handler: LogEventHandler = (event) => {
|
|
662
|
+
* if (event.event === "package.loaded") {
|
|
663
|
+
* console.log(`Loaded ${event.data.package}@${event.data.version}`);
|
|
664
|
+
* }
|
|
665
|
+
* };
|
|
666
|
+
* ```
|
|
667
|
+
*
|
|
668
|
+
* @public
|
|
669
|
+
*/
|
|
670
|
+
export declare const LogEventSchema: Schema_2.Union<[Schema_2.Struct<{
|
|
671
|
+
event: Schema_2.Literal<["package.version.resolved"]>;
|
|
672
|
+
level: Schema_2.Literal<["info"]>;
|
|
673
|
+
message: typeof Schema_2.String;
|
|
674
|
+
timestamp: typeof Schema_2.Number;
|
|
675
|
+
fiber: Schema_2.optional<typeof Schema_2.String>;
|
|
676
|
+
data: Schema_2.Struct<{
|
|
677
|
+
package: typeof Schema_2.String;
|
|
678
|
+
requested: typeof Schema_2.String;
|
|
679
|
+
resolved: typeof Schema_2.String;
|
|
680
|
+
}>;
|
|
681
|
+
}>, Schema_2.Struct<{
|
|
682
|
+
event: Schema_2.Literal<["cache.hit"]>;
|
|
683
|
+
level: Schema_2.Literal<["info"]>;
|
|
684
|
+
message: typeof Schema_2.String;
|
|
685
|
+
timestamp: typeof Schema_2.Number;
|
|
686
|
+
fiber: Schema_2.optional<typeof Schema_2.String>;
|
|
687
|
+
data: Schema_2.Struct<{
|
|
688
|
+
package: typeof Schema_2.String;
|
|
689
|
+
version: typeof Schema_2.String;
|
|
690
|
+
ageMinutes: typeof Schema_2.Number;
|
|
691
|
+
}>;
|
|
692
|
+
}>, Schema_2.Struct<{
|
|
693
|
+
event: Schema_2.Literal<["cache.stale"]>;
|
|
694
|
+
level: Schema_2.Literal<["debug"]>;
|
|
695
|
+
message: typeof Schema_2.String;
|
|
696
|
+
timestamp: typeof Schema_2.Number;
|
|
697
|
+
fiber: Schema_2.optional<typeof Schema_2.String>;
|
|
698
|
+
data: Schema_2.Struct<{
|
|
699
|
+
package: typeof Schema_2.String;
|
|
700
|
+
version: typeof Schema_2.String;
|
|
701
|
+
ageMinutes: typeof Schema_2.Number;
|
|
702
|
+
ttlMinutes: typeof Schema_2.Number;
|
|
703
|
+
}>;
|
|
704
|
+
}>, Schema_2.Struct<{
|
|
705
|
+
event: Schema_2.Literal<["cache.miss"]>;
|
|
706
|
+
level: Schema_2.Literal<["debug"]>;
|
|
707
|
+
message: typeof Schema_2.String;
|
|
708
|
+
timestamp: typeof Schema_2.Number;
|
|
709
|
+
fiber: Schema_2.optional<typeof Schema_2.String>;
|
|
710
|
+
data: Schema_2.Struct<{
|
|
711
|
+
package: typeof Schema_2.String;
|
|
712
|
+
version: typeof Schema_2.String;
|
|
713
|
+
}>;
|
|
714
|
+
}>, Schema_2.Struct<{
|
|
715
|
+
event: Schema_2.Literal<["package.fetch.start"]>;
|
|
716
|
+
level: Schema_2.Literal<["debug"]>;
|
|
717
|
+
message: typeof Schema_2.String;
|
|
718
|
+
timestamp: typeof Schema_2.Number;
|
|
719
|
+
fiber: Schema_2.optional<typeof Schema_2.String>;
|
|
720
|
+
data: Schema_2.Struct<{
|
|
721
|
+
package: typeof Schema_2.String;
|
|
722
|
+
version: typeof Schema_2.String;
|
|
723
|
+
}>;
|
|
724
|
+
}>, Schema_2.Struct<{
|
|
725
|
+
event: Schema_2.Literal<["package.loaded"]>;
|
|
726
|
+
level: Schema_2.Literal<["info"]>;
|
|
727
|
+
message: typeof Schema_2.String;
|
|
728
|
+
timestamp: typeof Schema_2.Number;
|
|
729
|
+
fiber: Schema_2.optional<typeof Schema_2.String>;
|
|
730
|
+
data: Schema_2.Struct<{
|
|
731
|
+
package: typeof Schema_2.String;
|
|
732
|
+
version: typeof Schema_2.String;
|
|
733
|
+
files: typeof Schema_2.Number;
|
|
734
|
+
source: Schema_2.Literal<["cache", "network"]>;
|
|
735
|
+
}>;
|
|
736
|
+
}>, Schema_2.Struct<{
|
|
737
|
+
event: Schema_2.Literal<["package.load.failed"]>;
|
|
738
|
+
level: Schema_2.Literal<["warn"]>;
|
|
739
|
+
message: typeof Schema_2.String;
|
|
740
|
+
timestamp: typeof Schema_2.Number;
|
|
741
|
+
fiber: Schema_2.optional<typeof Schema_2.String>;
|
|
742
|
+
data: Schema_2.Struct<{
|
|
743
|
+
package: typeof Schema_2.String;
|
|
744
|
+
version: typeof Schema_2.String;
|
|
745
|
+
error: typeof Schema_2.String;
|
|
746
|
+
}>;
|
|
747
|
+
}>, Schema_2.Struct<{
|
|
748
|
+
event: Schema_2.Literal<["packages.batch.start"]>;
|
|
749
|
+
level: Schema_2.Literal<["debug"]>;
|
|
750
|
+
message: typeof Schema_2.String;
|
|
751
|
+
timestamp: typeof Schema_2.Number;
|
|
752
|
+
fiber: Schema_2.optional<typeof Schema_2.String>;
|
|
753
|
+
data: Schema_2.Struct<{
|
|
754
|
+
total: typeof Schema_2.Number;
|
|
755
|
+
packages: Schema_2.Array$<typeof Schema_2.String>;
|
|
756
|
+
}>;
|
|
757
|
+
}>, Schema_2.Struct<{
|
|
758
|
+
event: Schema_2.Literal<["packages.batch.complete"]>;
|
|
759
|
+
level: Schema_2.Literal<["info"]>;
|
|
760
|
+
message: typeof Schema_2.String;
|
|
761
|
+
timestamp: typeof Schema_2.Number;
|
|
762
|
+
fiber: Schema_2.optional<typeof Schema_2.String>;
|
|
763
|
+
data: Schema_2.Struct<{
|
|
764
|
+
loaded: typeof Schema_2.Number;
|
|
765
|
+
failed: typeof Schema_2.Number;
|
|
766
|
+
total: typeof Schema_2.Number;
|
|
767
|
+
totalFiles: typeof Schema_2.Number;
|
|
768
|
+
durationMs: typeof Schema_2.Number;
|
|
769
|
+
}>;
|
|
770
|
+
}>, Schema_2.Struct<{
|
|
771
|
+
event: Schema_2.Literal<["typescript.cache.created"]>;
|
|
772
|
+
level: Schema_2.Literal<["info"]>;
|
|
773
|
+
message: typeof Schema_2.String;
|
|
774
|
+
timestamp: typeof Schema_2.Number;
|
|
775
|
+
fiber: Schema_2.optional<typeof Schema_2.String>;
|
|
776
|
+
data: Schema_2.Struct<{
|
|
777
|
+
packages: Schema_2.Array$<typeof Schema_2.String>;
|
|
778
|
+
fileCount: typeof Schema_2.Number;
|
|
779
|
+
rootFiles: typeof Schema_2.Number;
|
|
780
|
+
}>;
|
|
781
|
+
}>]>;
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* Creates a {@link CacheService} layer backed by the local filesystem.
|
|
785
|
+
*
|
|
786
|
+
* @param baseDir - Optional custom cache directory. When omitted the XDG
|
|
787
|
+
* cache directory is used (see {@link getDefaultCacheDir}).
|
|
788
|
+
* @returns A `Layer` providing {@link CacheService} that requires
|
|
789
|
+
* {@link @effect/platform#FileSystem | FileSystem}.
|
|
790
|
+
*
|
|
791
|
+
* @example
|
|
792
|
+
* ```typescript
|
|
793
|
+
* import { NodeFileSystem } from "@effect/platform-node";
|
|
794
|
+
* import { Effect, Layer } from "effect";
|
|
795
|
+
* import { CacheService, makeNodeCacheLayer } from "type-registry-effect";
|
|
796
|
+
*
|
|
797
|
+
* const CustomCache = makeNodeCacheLayer("/tmp/my-type-cache");
|
|
798
|
+
* const MainLayer = Layer.provide(CustomCache, NodeFileSystem.layer);
|
|
799
|
+
*
|
|
800
|
+
* const program = Effect.gen(function* () {
|
|
801
|
+
* const cache = yield* CacheService;
|
|
802
|
+
* console.log("using custom cache dir");
|
|
803
|
+
* });
|
|
804
|
+
*
|
|
805
|
+
* Effect.runPromise(Effect.provide(program, MainLayer));
|
|
806
|
+
* ```
|
|
807
|
+
*
|
|
808
|
+
* @see {@link CacheService}
|
|
809
|
+
* @see {@link getDefaultCacheDir}
|
|
810
|
+
*
|
|
811
|
+
* @public
|
|
812
|
+
*/
|
|
813
|
+
export declare const makeNodeCacheLayer: (baseDir?: string | undefined) => Layer.Layer<CacheService, never, FileSystem.FileSystem>;
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
* Raised when an HTTP request to the jsDelivr CDN fails.
|
|
817
|
+
*
|
|
818
|
+
* @remarks
|
|
819
|
+
* The `url` field contains the request URL, `status` is the HTTP status code
|
|
820
|
+
* (when available), and `message` describes the failure. Network errors may be
|
|
821
|
+
* transient (e.g. DNS resolution, connection reset) or permanent (e.g. 403
|
|
822
|
+
* Forbidden). Use `Effect.catchTag` with the `"NetworkError"` tag to handle
|
|
823
|
+
* this error selectively.
|
|
824
|
+
*
|
|
825
|
+
* @example
|
|
826
|
+
* ```typescript
|
|
827
|
+
* import { Effect } from "effect";
|
|
828
|
+
* import type { NetworkError } from "type-registry-effect";
|
|
829
|
+
* import { TypeRegistry, PackageSpec } from "type-registry-effect";
|
|
830
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
831
|
+
*
|
|
832
|
+
* const program = TypeRegistry.fetchAndCache(
|
|
833
|
+
* new PackageSpec({ name: "zod", version: "3.23.8" }),
|
|
834
|
+
* ).pipe(
|
|
835
|
+
* Effect.catchTag("NetworkError", (err: NetworkError) =>
|
|
836
|
+
* Effect.logError(`Request to ${err.url} failed (${err.status ?? "no status"}): ${err.message}`),
|
|
837
|
+
* ),
|
|
838
|
+
* );
|
|
839
|
+
*
|
|
840
|
+
* await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
841
|
+
* ```
|
|
842
|
+
*
|
|
843
|
+
* @see {@link PackageFetcher}
|
|
844
|
+
* @public
|
|
845
|
+
*/
|
|
846
|
+
export declare class NetworkError extends NetworkErrorBase<{
|
|
847
|
+
readonly url: string;
|
|
848
|
+
readonly status?: number;
|
|
849
|
+
readonly message: string;
|
|
850
|
+
}> {
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* @internal
|
|
855
|
+
* Exported for declaration bundling (api-extractor). When `export *` re-exports
|
|
856
|
+
* a class whose `extends` expression is an inline call like
|
|
857
|
+
* `Data.TaggedError(...)`, TypeScript emits an un-nameable `_base` symbol in
|
|
858
|
+
* the declaration file. Splitting the base into a named export gives the
|
|
859
|
+
* bundler a stable reference.
|
|
860
|
+
*
|
|
861
|
+
* @privateRemarks
|
|
862
|
+
* This base constant must remain a named export so that api-extractor can
|
|
863
|
+
* resolve the extends clause of {@link NetworkError} to a stable
|
|
864
|
+
* declaration. Without it the bundled `.d.ts` would contain an anonymous
|
|
865
|
+
* `_base` symbol that cannot be referenced by downstream consumers.
|
|
866
|
+
*/
|
|
867
|
+
export declare const NetworkErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
|
|
868
|
+
readonly _tag: "NetworkError";
|
|
869
|
+
} & Readonly<A>;
|
|
870
|
+
|
|
871
|
+
/**
|
|
872
|
+
* Effect service interface for fetching type definitions and package metadata
|
|
873
|
+
* from the jsDelivr CDN.
|
|
874
|
+
*
|
|
875
|
+
* @remarks
|
|
876
|
+
* All network calls are retried up to 3 times with exponential back-off
|
|
877
|
+
* (starting at 100 ms) and are subject to a 30-second timeout. The live
|
|
878
|
+
* implementation is provided by {@link PackageFetcherLive}.
|
|
879
|
+
*
|
|
880
|
+
* @example
|
|
881
|
+
* ```typescript
|
|
882
|
+
* import { Effect } from "effect";
|
|
883
|
+
* import { PackageFetcher } from "type-registry-effect";
|
|
884
|
+
*
|
|
885
|
+
* const program = Effect.gen(function* () {
|
|
886
|
+
* const fetcher = yield* PackageFetcher;
|
|
887
|
+
* const meta = yield* fetcher.getVersions("lodash");
|
|
888
|
+
* console.log("latest:", meta.tags["latest"]);
|
|
889
|
+
* });
|
|
890
|
+
* ```
|
|
891
|
+
*
|
|
892
|
+
* @see {@link PackageFetcherLive}
|
|
893
|
+
*
|
|
894
|
+
* @public
|
|
895
|
+
*/
|
|
896
|
+
export declare interface PackageFetcher {
|
|
897
|
+
/** Fetch all published versions and dist-tags for a package. */
|
|
898
|
+
readonly getVersions: (name: string) => Effect.Effect<PackageMetadata, NetworkError | ParseError>;
|
|
899
|
+
/** Resolve a semver range or dist-tag to a concrete version string. */
|
|
900
|
+
readonly resolveVersion: (name: string, ref: string) => Effect.Effect<string, NetworkError | PackageNotFoundError>;
|
|
901
|
+
/** Retrieve the flat file tree listing for a specific package version. */
|
|
902
|
+
readonly getFileTree: (pkg: PackageSpec) => Effect.Effect<FileTreeResponse, NetworkError | ParseError>;
|
|
903
|
+
/** Download a single file from the CDN by path. */
|
|
904
|
+
readonly downloadFile: (pkg: PackageSpec, path: string) => Effect.Effect<string, NetworkError>;
|
|
905
|
+
/** Download and schema-validate the `package.json` for a package version. */
|
|
906
|
+
readonly getPackageJson: (pkg: PackageSpec) => Effect.Effect<PackageJson, NetworkError | ParseError>;
|
|
907
|
+
/** Download all TypeScript declaration files for a package version, returned as a path-to-content map. */
|
|
908
|
+
readonly getTypeFiles: (pkg: PackageSpec) => Effect.Effect<Map<string, string>, NetworkError | ParseError>;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
/**
|
|
912
|
+
* Effect Context tag for the {@link PackageFetcher} service.
|
|
913
|
+
*
|
|
914
|
+
* @see {@link PackageFetcherLive}
|
|
915
|
+
*/
|
|
916
|
+
export declare const PackageFetcher: Context.Tag<PackageFetcher, PackageFetcher>;
|
|
917
|
+
|
|
918
|
+
/**
|
|
919
|
+
* Live {@link PackageFetcher} layer that fetches package metadata and type
|
|
920
|
+
* definitions from the jsDelivr CDN.
|
|
921
|
+
*
|
|
922
|
+
* @remarks
|
|
923
|
+
* All HTTP requests are retried up to **3 times** with exponential back-off
|
|
924
|
+
* (starting at 100 ms) and time out after **30 seconds**. Requires an
|
|
925
|
+
* {@link @effect/platform#HttpClient | HttpClient} layer to be provided at
|
|
926
|
+
* composition time.
|
|
927
|
+
*
|
|
928
|
+
* @see {@link PackageFetcher}
|
|
929
|
+
*
|
|
930
|
+
* @public
|
|
931
|
+
*/
|
|
932
|
+
export declare const PackageFetcherLive: Layer.Layer<PackageFetcher, never, HttpClient.HttpClient>;
|
|
933
|
+
|
|
934
|
+
/**
|
|
935
|
+
* Schema for a validated subset of npm `package.json` fields relevant to type resolution.
|
|
936
|
+
*
|
|
937
|
+
* @remarks
|
|
938
|
+
* This schema captures only the fields the type resolver needs to locate
|
|
939
|
+
* declaration files within a published package:
|
|
940
|
+
*
|
|
941
|
+
* - **`name`** and **`version`** -- identity fields (always required).
|
|
942
|
+
* - **`types`** / **`typings`** -- legacy top-level type entry points.
|
|
943
|
+
* - **`main`** / **`module`** -- JavaScript entry points used as fallbacks
|
|
944
|
+
* when no explicit type entry is declared.
|
|
945
|
+
* - **`exports`** -- the modern Node.js conditional exports map; may be a
|
|
946
|
+
* simple string or a nested record of conditions.
|
|
947
|
+
* - **`typesVersions`** -- TypeScript path-mapping overrides keyed by TS
|
|
948
|
+
* version ranges (e.g. `">=4.0"`).
|
|
949
|
+
* - **`dependencies`** / **`peerDependencies`** / **`devDependencies`** --
|
|
950
|
+
* used to discover transitive type packages (e.g. `@types/*`).
|
|
951
|
+
*
|
|
952
|
+
* Fields outside this set are intentionally ignored to keep validation fast
|
|
953
|
+
* and the attack surface small.
|
|
954
|
+
*
|
|
955
|
+
* @example
|
|
956
|
+
* ```typescript
|
|
957
|
+
* import { Schema } from "effect";
|
|
958
|
+
* import { PackageJson } from "type-registry-effect";
|
|
959
|
+
*
|
|
960
|
+
* const decode = Schema.decodeUnknownSync(PackageJson);
|
|
961
|
+
* const pkg = decode({
|
|
962
|
+
* name: "zod",
|
|
963
|
+
* version: "3.23.8",
|
|
964
|
+
* types: "./lib/types.d.ts",
|
|
965
|
+
* main: "./lib/index.js",
|
|
966
|
+
* exports: {
|
|
967
|
+
* ".": { types: "./lib/types.d.ts", import: "./lib/index.mjs" },
|
|
968
|
+
* },
|
|
969
|
+
* });
|
|
970
|
+
* ```
|
|
971
|
+
*
|
|
972
|
+
* @see {@link TypeResolver}
|
|
973
|
+
* @public
|
|
974
|
+
*/
|
|
975
|
+
export declare const PackageJson: Schema.Struct<{
|
|
976
|
+
name: typeof Schema.String;
|
|
977
|
+
version: typeof Schema.String;
|
|
978
|
+
types: Schema.optional<typeof Schema.String>;
|
|
979
|
+
typings: Schema.optional<typeof Schema.String>;
|
|
980
|
+
main: Schema.optional<typeof Schema.String>;
|
|
981
|
+
module: Schema.optional<typeof Schema.String>;
|
|
982
|
+
exports: Schema.optional<Schema.Union<[typeof Schema.String, Schema.Record$<typeof Schema.String, typeof Schema.Unknown>]>>;
|
|
983
|
+
typesVersions: Schema.optional<Schema.Record$<typeof Schema.String, Schema.Record$<typeof Schema.String, Schema.Array$<typeof Schema.String>>>>;
|
|
984
|
+
dependencies: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
|
|
985
|
+
peerDependencies: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
|
|
986
|
+
devDependencies: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
|
|
987
|
+
}>;
|
|
988
|
+
|
|
989
|
+
export declare type PackageJson = Schema.Schema.Type<typeof PackageJson>;
|
|
990
|
+
|
|
991
|
+
/**
|
|
992
|
+
* Version and tag metadata for an npm package as returned by the jsDelivr API.
|
|
993
|
+
*
|
|
994
|
+
* @remarks
|
|
995
|
+
* The `versions` array contains every published version string. The `tags`
|
|
996
|
+
* record maps dist-tags (e.g. `"latest"`, `"next"`) to their corresponding
|
|
997
|
+
* version strings.
|
|
998
|
+
*
|
|
999
|
+
* @public
|
|
1000
|
+
*/
|
|
1001
|
+
export declare interface PackageMetadata {
|
|
1002
|
+
readonly versions: string[];
|
|
1003
|
+
readonly tags: Record<string, string>;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* Raised when a package or version does not exist on the CDN.
|
|
1008
|
+
*
|
|
1009
|
+
* @remarks
|
|
1010
|
+
* The `name` and `version` fields identify the package that could not be
|
|
1011
|
+
* found, and `message` provides additional context. This typically occurs
|
|
1012
|
+
* when a typo is present in the package name or the requested version has
|
|
1013
|
+
* not been published. Use `Effect.catchTag` with the
|
|
1014
|
+
* `"PackageNotFoundError"` tag to handle this error selectively.
|
|
1015
|
+
*
|
|
1016
|
+
* @example
|
|
1017
|
+
* ```typescript
|
|
1018
|
+
* import { Effect } from "effect";
|
|
1019
|
+
* import type { PackageNotFoundError } from "type-registry-effect";
|
|
1020
|
+
* import { TypeRegistry, PackageSpec } from "type-registry-effect";
|
|
1021
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
1022
|
+
*
|
|
1023
|
+
* const program = TypeRegistry.fetchAndCache(
|
|
1024
|
+
* new PackageSpec({ name: "nonexistent-pkg", version: "0.0.0" }),
|
|
1025
|
+
* ).pipe(
|
|
1026
|
+
* Effect.catchTag("PackageNotFoundError", (err: PackageNotFoundError) =>
|
|
1027
|
+
* Effect.logWarning(`Package ${err.name}@${err.version} not found: ${err.message}`),
|
|
1028
|
+
* ),
|
|
1029
|
+
* );
|
|
1030
|
+
*
|
|
1031
|
+
* await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
1032
|
+
* ```
|
|
1033
|
+
*
|
|
1034
|
+
* @see {@link PackageFetcher.resolveVersion}
|
|
1035
|
+
* @public
|
|
1036
|
+
*/
|
|
1037
|
+
export declare class PackageNotFoundError extends PackageNotFoundErrorBase<{
|
|
1038
|
+
readonly name: string;
|
|
1039
|
+
readonly version: string;
|
|
1040
|
+
readonly message: string;
|
|
1041
|
+
}> {
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
/**
|
|
1045
|
+
* @internal
|
|
1046
|
+
* Exported for declaration bundling (api-extractor). When `export *` re-exports
|
|
1047
|
+
* a class whose `extends` expression is an inline call like
|
|
1048
|
+
* `Data.TaggedError(...)`, TypeScript emits an un-nameable `_base` symbol in
|
|
1049
|
+
* the declaration file. Splitting the base into a named export gives the
|
|
1050
|
+
* bundler a stable reference.
|
|
1051
|
+
*
|
|
1052
|
+
* @privateRemarks
|
|
1053
|
+
* This base constant must remain a named export so that api-extractor can
|
|
1054
|
+
* resolve the extends clause of {@link PackageNotFoundError} to a stable
|
|
1055
|
+
* declaration. Without it the bundled `.d.ts` would contain an anonymous
|
|
1056
|
+
* `_base` symbol that cannot be referenced by downstream consumers.
|
|
1057
|
+
*/
|
|
1058
|
+
export declare const PackageNotFoundErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
|
|
1059
|
+
readonly _tag: "PackageNotFoundError";
|
|
1060
|
+
} & Readonly<A>;
|
|
1061
|
+
|
|
1062
|
+
/**
|
|
1063
|
+
* Immutable value object identifying a package at a specific version.
|
|
1064
|
+
*
|
|
1065
|
+
* @remarks
|
|
1066
|
+
* `PackageSpec` uses {@link https://effect.website/docs/data-types/data/#taggedclass | Data.TaggedClass}
|
|
1067
|
+
* to provide structural equality out of the box. Two `PackageSpec` instances
|
|
1068
|
+
* with the same `name` and `version` are considered equal via `Equal.equals`.
|
|
1069
|
+
* The optional `registry` field allows targeting alternative registries.
|
|
1070
|
+
*
|
|
1071
|
+
* @example
|
|
1072
|
+
* ```typescript
|
|
1073
|
+
* import { Equal } from "effect";
|
|
1074
|
+
* import type { PackageSpec } from "type-registry-effect";
|
|
1075
|
+
* import { PackageSpec as PackageSpecClass } from "type-registry-effect";
|
|
1076
|
+
*
|
|
1077
|
+
* const pkg = new PackageSpecClass({ name: "zod", version: "3.23.8" });
|
|
1078
|
+
* const same = new PackageSpecClass({ name: "zod", version: "3.23.8" });
|
|
1079
|
+
*
|
|
1080
|
+
* // Structural equality via Data.TaggedClass
|
|
1081
|
+
* console.assert(Equal.equals(pkg, same) === true);
|
|
1082
|
+
*
|
|
1083
|
+
* // String representation: "zod@3.23.8"
|
|
1084
|
+
* console.assert(pkg.toString() === "zod@3.23.8");
|
|
1085
|
+
*
|
|
1086
|
+
* // Optional registry for alternative sources
|
|
1087
|
+
* const custom = new PackageSpecClass({
|
|
1088
|
+
* name: "@myorg/types",
|
|
1089
|
+
* version: "1.0.0",
|
|
1090
|
+
* registry: "https://npm.pkg.github.com",
|
|
1091
|
+
* });
|
|
1092
|
+
* ```
|
|
1093
|
+
*
|
|
1094
|
+
* @see {@link CacheService}
|
|
1095
|
+
* @see {@link TypeRegistry}
|
|
1096
|
+
* @public
|
|
1097
|
+
*/
|
|
1098
|
+
export declare class PackageSpec extends PackageSpecBase<{
|
|
1099
|
+
readonly name: string;
|
|
1100
|
+
readonly version: string;
|
|
1101
|
+
readonly registry?: string;
|
|
1102
|
+
}> {
|
|
1103
|
+
toString(): string;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
/**
|
|
1107
|
+
* @internal
|
|
1108
|
+
* Exported for declaration bundling (api-extractor). When `export *` re-exports
|
|
1109
|
+
* a class whose `extends` expression is an inline call like
|
|
1110
|
+
* `Data.TaggedClass(...)`, TypeScript emits an un-nameable `_base` symbol in
|
|
1111
|
+
* the declaration file. Splitting the base into a named export gives the
|
|
1112
|
+
* bundler a stable reference.
|
|
1113
|
+
*
|
|
1114
|
+
* @privateRemarks
|
|
1115
|
+
* This base constant must remain a named export so that api-extractor can
|
|
1116
|
+
* resolve the extends clause of {@link PackageSpec} to a stable
|
|
1117
|
+
* declaration. Without it the bundled `.d.ts` would contain an anonymous
|
|
1118
|
+
* `_base` symbol that cannot be referenced by downstream consumers.
|
|
1119
|
+
*/
|
|
1120
|
+
export declare const PackageSpecBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Readonly<A> & {
|
|
1121
|
+
readonly _tag: "PackageSpec";
|
|
1122
|
+
};
|
|
1123
|
+
|
|
1124
|
+
/**
|
|
1125
|
+
* Raised when a CDN response fails schema validation or JSON parsing.
|
|
1126
|
+
*
|
|
1127
|
+
* @remarks
|
|
1128
|
+
* The `source` field identifies what was being parsed (e.g. `"package.json"`,
|
|
1129
|
+
* `"file-tree"`) and `message` describes the validation failure. This
|
|
1130
|
+
* typically indicates the CDN returned an unexpected response shape or
|
|
1131
|
+
* corrupted data. Use `Effect.catchTag` with the `"ParseError"` tag to
|
|
1132
|
+
* handle this error selectively.
|
|
1133
|
+
*
|
|
1134
|
+
* @example
|
|
1135
|
+
* ```typescript
|
|
1136
|
+
* import { Effect } from "effect";
|
|
1137
|
+
* import type { ParseError } from "type-registry-effect";
|
|
1138
|
+
* import { TypeRegistry, PackageSpec } from "type-registry-effect";
|
|
1139
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
1140
|
+
*
|
|
1141
|
+
* const program = TypeRegistry.fetchAndCache(
|
|
1142
|
+
* new PackageSpec({ name: "zod", version: "3.23.8" }),
|
|
1143
|
+
* ).pipe(
|
|
1144
|
+
* Effect.catchTag("ParseError", (err: ParseError) =>
|
|
1145
|
+
* Effect.logError(`Failed to parse ${err.source}: ${err.message}`),
|
|
1146
|
+
* ),
|
|
1147
|
+
* );
|
|
1148
|
+
*
|
|
1149
|
+
* await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
1150
|
+
* ```
|
|
1151
|
+
*
|
|
1152
|
+
* @see {@link PackageFetcher.getPackageJson}
|
|
1153
|
+
* @public
|
|
1154
|
+
*/
|
|
1155
|
+
export declare class ParseError extends ParseErrorBase<{
|
|
1156
|
+
readonly source: string;
|
|
1157
|
+
readonly message: string;
|
|
1158
|
+
}> {
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
/**
|
|
1162
|
+
* @internal
|
|
1163
|
+
* Exported for declaration bundling (api-extractor). When `export *` re-exports
|
|
1164
|
+
* a class whose `extends` expression is an inline call like
|
|
1165
|
+
* `Data.TaggedError(...)`, TypeScript emits an un-nameable `_base` symbol in
|
|
1166
|
+
* the declaration file. Splitting the base into a named export gives the
|
|
1167
|
+
* bundler a stable reference.
|
|
1168
|
+
*
|
|
1169
|
+
* @privateRemarks
|
|
1170
|
+
* This base constant must remain a named export so that api-extractor can
|
|
1171
|
+
* resolve the extends clause of {@link ParseError} to a stable
|
|
1172
|
+
* declaration. Without it the bundled `.d.ts` would contain an anonymous
|
|
1173
|
+
* `_base` symbol that cannot be referenced by downstream consumers.
|
|
1174
|
+
*/
|
|
1175
|
+
export declare const ParseErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
|
|
1176
|
+
readonly _tag: "ParseError";
|
|
1177
|
+
} & Readonly<A>;
|
|
1178
|
+
|
|
1179
|
+
/**
|
|
1180
|
+
* Raised when an import specifier cannot be resolved to a module within a package.
|
|
1181
|
+
*
|
|
1182
|
+
* @remarks
|
|
1183
|
+
* The `package` field is the package name, `specifier` is the import path
|
|
1184
|
+
* that could not be resolved, and `message` describes the failure cause.
|
|
1185
|
+
* This occurs when the package's exports map, `typesVersions`, or file tree
|
|
1186
|
+
* do not contain a matching entry for the requested specifier. Use
|
|
1187
|
+
* `Effect.catchTag` with the `"ResolutionError"` tag to handle this error
|
|
1188
|
+
* selectively.
|
|
1189
|
+
*
|
|
1190
|
+
* @example
|
|
1191
|
+
* ```typescript
|
|
1192
|
+
* import { Effect } from "effect";
|
|
1193
|
+
* import type { ResolutionError } from "type-registry-effect";
|
|
1194
|
+
* import { TypeResolver, PackageSpec } from "type-registry-effect";
|
|
1195
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
1196
|
+
*
|
|
1197
|
+
* const program = TypeResolver.resolveImport(
|
|
1198
|
+
* new PackageSpec({ name: "zod", version: "3.23.8" }),
|
|
1199
|
+
* "./nonexistent",
|
|
1200
|
+
* ).pipe(
|
|
1201
|
+
* Effect.catchTag("ResolutionError", (err: ResolutionError) =>
|
|
1202
|
+
* Effect.logWarning(`Cannot resolve "${err.specifier}" in ${err.package}: ${err.message}`),
|
|
1203
|
+
* ),
|
|
1204
|
+
* );
|
|
1205
|
+
*
|
|
1206
|
+
* await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
1207
|
+
* ```
|
|
1208
|
+
*
|
|
1209
|
+
* @see {@link TypeResolver.resolveImport}
|
|
1210
|
+
* @public
|
|
1211
|
+
*/
|
|
1212
|
+
export declare class ResolutionError extends ResolutionErrorBase<{
|
|
1213
|
+
readonly package: string;
|
|
1214
|
+
readonly specifier: string;
|
|
1215
|
+
readonly message: string;
|
|
1216
|
+
}> {
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
/**
|
|
1220
|
+
* @internal
|
|
1221
|
+
* Exported for declaration bundling (api-extractor). When `export *` re-exports
|
|
1222
|
+
* a class whose `extends` expression is an inline call like
|
|
1223
|
+
* `Data.TaggedError(...)`, TypeScript emits an un-nameable `_base` symbol in
|
|
1224
|
+
* the declaration file. Splitting the base into a named export gives the
|
|
1225
|
+
* bundler a stable reference.
|
|
1226
|
+
*
|
|
1227
|
+
* @privateRemarks
|
|
1228
|
+
* This base constant must remain a named export so that api-extractor can
|
|
1229
|
+
* resolve the extends clause of {@link ResolutionError} to a stable
|
|
1230
|
+
* declaration. Without it the bundled `.d.ts` would contain an anonymous
|
|
1231
|
+
* `_base` symbol that cannot be referenced by downstream consumers.
|
|
1232
|
+
*/
|
|
1233
|
+
export declare const ResolutionErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
|
|
1234
|
+
readonly _tag: "ResolutionError";
|
|
1235
|
+
} & Readonly<A>;
|
|
1236
|
+
|
|
1237
|
+
/**
|
|
1238
|
+
* Represents a resolved module path within a package.
|
|
1239
|
+
*
|
|
1240
|
+
* @remarks
|
|
1241
|
+
* After the {@link TypeResolver} walks a package's exports and file tree, each
|
|
1242
|
+
* resolvable import specifier maps to a `ResolvedModule`. The `filePath` is
|
|
1243
|
+
* relative to the package root, and `isTypeDefinition` indicates whether the
|
|
1244
|
+
* file is a `.d.ts` (or `.d.mts` / `.d.cts`) declaration file. The `package`
|
|
1245
|
+
* field links back to the originating {@link PackageSpec}.
|
|
1246
|
+
*
|
|
1247
|
+
* @example
|
|
1248
|
+
* ```typescript
|
|
1249
|
+
* import type { ResolvedModule, PackageSpec } from "type-registry-effect";
|
|
1250
|
+
* import {
|
|
1251
|
+
* ResolvedModule as ResolvedModuleClass,
|
|
1252
|
+
* PackageSpec as PackageSpecClass,
|
|
1253
|
+
* } from "type-registry-effect";
|
|
1254
|
+
*
|
|
1255
|
+
* const mod = new ResolvedModuleClass({
|
|
1256
|
+
* filePath: "dist/index.d.ts",
|
|
1257
|
+
* isTypeDefinition: true,
|
|
1258
|
+
* package: new PackageSpecClass({ name: "zod", version: "3.23.8" }),
|
|
1259
|
+
* });
|
|
1260
|
+
* ```
|
|
1261
|
+
*
|
|
1262
|
+
* @see {@link TypeResolver.resolveImport}
|
|
1263
|
+
* @see {@link TypeResolver.resolveTypeEntries}
|
|
1264
|
+
* @public
|
|
1265
|
+
*/
|
|
1266
|
+
export declare class ResolvedModule extends ResolvedModuleBase<{
|
|
1267
|
+
readonly filePath: string;
|
|
1268
|
+
readonly isTypeDefinition: boolean;
|
|
1269
|
+
readonly package: PackageSpec;
|
|
1270
|
+
}> {
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
/**
|
|
1274
|
+
* @internal
|
|
1275
|
+
* Exported for declaration bundling (api-extractor). When `export *` re-exports
|
|
1276
|
+
* a class whose `extends` expression is an inline call like
|
|
1277
|
+
* `Data.TaggedClass(...)`, TypeScript emits an un-nameable `_base` symbol in
|
|
1278
|
+
* the declaration file. Splitting the base into a named export gives the
|
|
1279
|
+
* bundler a stable reference.
|
|
1280
|
+
*
|
|
1281
|
+
* @privateRemarks
|
|
1282
|
+
* This base constant must remain a named export so that api-extractor can
|
|
1283
|
+
* resolve the extends clause of {@link ResolvedModule} to a stable
|
|
1284
|
+
* declaration. Without it the bundled `.d.ts` would contain an anonymous
|
|
1285
|
+
* `_base` symbol that cannot be referenced by downstream consumers.
|
|
1286
|
+
*/
|
|
1287
|
+
export declare const ResolvedModuleBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Readonly<A> & {
|
|
1288
|
+
readonly _tag: "ResolvedModule";
|
|
1289
|
+
};
|
|
1290
|
+
|
|
1291
|
+
/**
|
|
1292
|
+
* Resolve an import specifier (e.g. `"zod"`, `"zod/lib/types"`) against a
|
|
1293
|
+
* cached package's `package.json` exports map.
|
|
1294
|
+
*
|
|
1295
|
+
* @remarks
|
|
1296
|
+
* The package must already be present in the cache. The resolution logic
|
|
1297
|
+
* delegates to {@link TypeResolver} which interprets the `exports`, `types`,
|
|
1298
|
+
* and `typings` fields of the cached `package.json`.
|
|
1299
|
+
*
|
|
1300
|
+
* @param pkg - The cached package to resolve against.
|
|
1301
|
+
* @param specifier - The bare import specifier to resolve (e.g. `"zod"` or `"zod/lib/types"`).
|
|
1302
|
+
* @returns An Effect that succeeds with a {@link ResolvedModule} describing the resolved file.
|
|
1303
|
+
*
|
|
1304
|
+
* @example
|
|
1305
|
+
* ```typescript
|
|
1306
|
+
* import { Effect } from "effect";
|
|
1307
|
+
* import type { ResolvedModule } from "type-registry-effect";
|
|
1308
|
+
* import { TypeRegistry, PackageSpec } from "type-registry-effect";
|
|
1309
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
1310
|
+
*
|
|
1311
|
+
* const program = Effect.gen(function* () {
|
|
1312
|
+
* const pkg = new PackageSpec({ name: "zod", version: "3.23.8" });
|
|
1313
|
+
* yield* TypeRegistry.fetchAndCache(pkg);
|
|
1314
|
+
* const resolved: ResolvedModule = yield* TypeRegistry.resolveImport(pkg, "zod");
|
|
1315
|
+
* console.log(`Resolved to: ${resolved.resolvedPath}`);
|
|
1316
|
+
* return resolved;
|
|
1317
|
+
* });
|
|
1318
|
+
*
|
|
1319
|
+
* const resolved = await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
1320
|
+
* ```
|
|
1321
|
+
*
|
|
1322
|
+
* @see {@link getTypeEntries} to discover all entry points
|
|
1323
|
+
* @see {@link TypeResolver} for the underlying resolution service
|
|
1324
|
+
*
|
|
1325
|
+
* @public
|
|
1326
|
+
*/
|
|
1327
|
+
declare const resolveImport: (pkg: PackageSpec, specifier: string) => Effect.Effect<ResolvedModule, CacheError | ParseError | ResolutionError, CacheService | TypeResolver>;
|
|
1328
|
+
|
|
1329
|
+
/**
|
|
1330
|
+
* Resolve a version reference to a concrete, pinned version string.
|
|
1331
|
+
*
|
|
1332
|
+
* @remarks
|
|
1333
|
+
* Accepts any npm-style version reference — `"latest"`, a semver range
|
|
1334
|
+
* like `"^1.0.0"`, or an exact version like `"3.23.8"` — and queries the
|
|
1335
|
+
* {@link PackageFetcher} (backed by the jsDelivr API) to determine the
|
|
1336
|
+
* matching published version.
|
|
1337
|
+
*
|
|
1338
|
+
* @param name - The npm package name (e.g. `"zod"`).
|
|
1339
|
+
* @param ref - A version reference: `"latest"`, a semver range, or an exact version.
|
|
1340
|
+
* @returns An Effect that succeeds with the resolved version string (e.g. `"3.23.8"`).
|
|
1341
|
+
*
|
|
1342
|
+
* @example
|
|
1343
|
+
* ```typescript
|
|
1344
|
+
* import { Effect } from "effect";
|
|
1345
|
+
* import { TypeRegistry } from "type-registry-effect";
|
|
1346
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
1347
|
+
*
|
|
1348
|
+
* const program = Effect.gen(function* () {
|
|
1349
|
+
* const version = yield* TypeRegistry.resolveVersion("zod", "latest");
|
|
1350
|
+
* console.log(`Latest zod version: ${version}`);
|
|
1351
|
+
* return version;
|
|
1352
|
+
* });
|
|
1353
|
+
*
|
|
1354
|
+
* const version = await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
1355
|
+
* ```
|
|
1356
|
+
*
|
|
1357
|
+
* @see {@link PackageFetcher} for the underlying network service
|
|
1358
|
+
*
|
|
1359
|
+
* @public
|
|
1360
|
+
*/
|
|
1361
|
+
declare const resolveVersion: (name: string, ref: string) => Effect.Effect<string, NetworkError | PackageNotFoundError, PackageFetcher>;
|
|
1362
|
+
|
|
1363
|
+
/**
|
|
1364
|
+
* Raised when an operation exceeds its configured time limit.
|
|
1365
|
+
*
|
|
1366
|
+
* @remarks
|
|
1367
|
+
* The `operation` field describes what was being performed (e.g.
|
|
1368
|
+
* `"fetchFileTree"`, `"resolveVersion"`), `duration` is the elapsed time in
|
|
1369
|
+
* milliseconds, and `message` provides additional context. Use
|
|
1370
|
+
* `Effect.catchTag` with the `"TimeoutError"` tag to handle this error
|
|
1371
|
+
* selectively.
|
|
1372
|
+
*
|
|
1373
|
+
* @example
|
|
1374
|
+
* ```typescript
|
|
1375
|
+
* import { Effect } from "effect";
|
|
1376
|
+
* import type { TimeoutError } from "type-registry-effect";
|
|
1377
|
+
* import { TypeRegistry, PackageSpec } from "type-registry-effect";
|
|
1378
|
+
* import { NodeLayer } from "type-registry-effect/node";
|
|
1379
|
+
*
|
|
1380
|
+
* const program = TypeRegistry.fetchAndCache(
|
|
1381
|
+
* new PackageSpec({ name: "zod", version: "3.23.8" }),
|
|
1382
|
+
* ).pipe(
|
|
1383
|
+
* Effect.catchTag("TimeoutError", (err: TimeoutError) =>
|
|
1384
|
+
* Effect.logWarning(`${err.operation} timed out after ${err.duration}ms: ${err.message}`),
|
|
1385
|
+
* ),
|
|
1386
|
+
* );
|
|
1387
|
+
*
|
|
1388
|
+
* await Effect.runPromise(Effect.provide(program, NodeLayer));
|
|
1389
|
+
* ```
|
|
1390
|
+
*
|
|
1391
|
+
* @public
|
|
1392
|
+
*/
|
|
1393
|
+
export declare class TimeoutError extends TimeoutErrorBase<{
|
|
1394
|
+
readonly operation: string;
|
|
1395
|
+
readonly duration: number;
|
|
1396
|
+
readonly message: string;
|
|
1397
|
+
}> {
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
/**
|
|
1401
|
+
* @internal
|
|
1402
|
+
* Exported for declaration bundling (api-extractor). When `export *` re-exports
|
|
1403
|
+
* a class whose `extends` expression is an inline call like
|
|
1404
|
+
* `Data.TaggedError(...)`, TypeScript emits an un-nameable `_base` symbol in
|
|
1405
|
+
* the declaration file. Splitting the base into a named export gives the
|
|
1406
|
+
* bundler a stable reference.
|
|
1407
|
+
*
|
|
1408
|
+
* @privateRemarks
|
|
1409
|
+
* This base constant must remain a named export so that api-extractor can
|
|
1410
|
+
* resolve the extends clause of {@link TimeoutError} to a stable
|
|
1411
|
+
* declaration. Without it the bundled `.d.ts` would contain an anonymous
|
|
1412
|
+
* `_base` symbol that cannot be referenced by downstream consumers.
|
|
1413
|
+
*/
|
|
1414
|
+
export declare const TimeoutErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
|
|
1415
|
+
readonly _tag: "TimeoutError";
|
|
1416
|
+
} & Readonly<A>;
|
|
1417
|
+
|
|
1418
|
+
export declare namespace TypeRegistry {
|
|
1419
|
+
export {
|
|
1420
|
+
hasCached,
|
|
1421
|
+
fetchAndCache,
|
|
1422
|
+
getPackageVFS,
|
|
1423
|
+
getVFS,
|
|
1424
|
+
resolveImport,
|
|
1425
|
+
getTypeEntries,
|
|
1426
|
+
resolveVersion,
|
|
1427
|
+
clearCache
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
/**
|
|
1432
|
+
* Union of all error types that can be raised by the type-registry-effect package.
|
|
1433
|
+
*
|
|
1434
|
+
* @remarks
|
|
1435
|
+
* `TypeRegistryError` is a discriminated union over the `_tag` field. Each
|
|
1436
|
+
* variant corresponds to a specific failure mode:
|
|
1437
|
+
*
|
|
1438
|
+
* - `"CacheError"` -- disk cache operations
|
|
1439
|
+
* - `"NetworkError"` -- HTTP requests to the CDN
|
|
1440
|
+
* - `"PackageNotFoundError"` -- missing packages or versions
|
|
1441
|
+
* - `"ParseError"` -- schema validation / JSON parsing
|
|
1442
|
+
* - `"ResolutionError"` -- import specifier resolution
|
|
1443
|
+
* - `"TimeoutError"` -- operation time limits
|
|
1444
|
+
*
|
|
1445
|
+
* Use `Effect.catchTags` to exhaustively handle all variants, or
|
|
1446
|
+
* `Effect.catchTag` for selective handling of individual error types.
|
|
1447
|
+
*
|
|
1448
|
+
* @public
|
|
1449
|
+
*/
|
|
1450
|
+
export declare type TypeRegistryError = CacheError | NetworkError | PackageNotFoundError | ParseError | ResolutionError | TimeoutError;
|
|
1451
|
+
|
|
1452
|
+
/**
|
|
1453
|
+
* Composed layer providing {@link CacheService}, {@link PackageFetcher}, and
|
|
1454
|
+
* {@link TypeResolver} as a single unified layer.
|
|
1455
|
+
*
|
|
1456
|
+
* @remarks
|
|
1457
|
+
* This layer merges {@link CacheServiceLive}, {@link PackageFetcherLive}, and
|
|
1458
|
+
* {@link TypeResolverLive}. It still requires platform-specific
|
|
1459
|
+
* {@link @effect/platform#FileSystem | FileSystem} and
|
|
1460
|
+
* {@link @effect/platform#HttpClient | HttpClient} layers to be provided.
|
|
1461
|
+
* Use the Node.js platform layers to satisfy these requirements:
|
|
1462
|
+
*
|
|
1463
|
+
* @example
|
|
1464
|
+
* ```typescript
|
|
1465
|
+
* import { NodeFileSystem, NodeHttpClient } from "@effect/platform-node";
|
|
1466
|
+
* import { Effect, Layer } from "effect";
|
|
1467
|
+
* import { TypeRegistryLive } from "type-registry-effect";
|
|
1468
|
+
*
|
|
1469
|
+
* const NodeLayer = Layer.mergeAll(NodeFileSystem.layer, NodeHttpClient.layer);
|
|
1470
|
+
* const MainLayer = Layer.provide(TypeRegistryLive, NodeLayer);
|
|
1471
|
+
*
|
|
1472
|
+
* const program = Effect.gen(function* () {
|
|
1473
|
+
* // All three services are now available
|
|
1474
|
+
* console.log("registry ready");
|
|
1475
|
+
* });
|
|
1476
|
+
*
|
|
1477
|
+
* Effect.runPromise(Effect.provide(program, MainLayer));
|
|
1478
|
+
* ```
|
|
1479
|
+
*
|
|
1480
|
+
* @see {@link CacheServiceLive}
|
|
1481
|
+
* @see {@link PackageFetcherLive}
|
|
1482
|
+
* @see {@link TypeResolverLive}
|
|
1483
|
+
*
|
|
1484
|
+
* @public
|
|
1485
|
+
*/
|
|
1486
|
+
export declare const TypeRegistryLive: Layer.Layer<CacheService | PackageFetcher | TypeResolver, never, FileSystem.FileSystem | HttpClient.HttpClient>;
|
|
1487
|
+
|
|
1488
|
+
/**
|
|
1489
|
+
* Effect service interface for import resolution using `package.json` metadata.
|
|
1490
|
+
*
|
|
1491
|
+
* @remarks
|
|
1492
|
+
* Resolution is attempted in the following order:
|
|
1493
|
+
*
|
|
1494
|
+
* 1. **`exports`** -- the `"types"` condition inside the package's exports map.
|
|
1495
|
+
* 2. **`typesVersions`** -- the `"*"` entry of `typesVersions` with wildcard
|
|
1496
|
+
* matching.
|
|
1497
|
+
* 3. **`types` / `typings`** -- top-level fields pointing at the main
|
|
1498
|
+
* declaration file.
|
|
1499
|
+
* 4. **Conventional** -- extension swapping (`.js` to `.d.ts`) and
|
|
1500
|
+
* `index.d.ts` fallback.
|
|
1501
|
+
*
|
|
1502
|
+
* @example
|
|
1503
|
+
* ```typescript
|
|
1504
|
+
* import { Effect } from "effect";
|
|
1505
|
+
* import { TypeResolver } from "type-registry-effect";
|
|
1506
|
+
* import type { PackageJson } from "type-registry-effect";
|
|
1507
|
+
* import type { PackageSpec } from "type-registry-effect";
|
|
1508
|
+
*
|
|
1509
|
+
* const program = Effect.gen(function* () {
|
|
1510
|
+
* const resolver = yield* TypeResolver;
|
|
1511
|
+
* const resolved = yield* resolver.resolveMainEntry(
|
|
1512
|
+
* { name: "lodash", version: "4.17.21" } as unknown as PackageJson,
|
|
1513
|
+
* { name: "lodash", version: "4.17.21" } as PackageSpec,
|
|
1514
|
+
* );
|
|
1515
|
+
* console.log("main types:", resolved.filePath);
|
|
1516
|
+
* });
|
|
1517
|
+
* ```
|
|
1518
|
+
*
|
|
1519
|
+
* @see {@link TypeResolverLive}
|
|
1520
|
+
*
|
|
1521
|
+
* @public
|
|
1522
|
+
*/
|
|
1523
|
+
export declare interface TypeResolver {
|
|
1524
|
+
/**
|
|
1525
|
+
* Resolve a bare or deep-import specifier to a type definition path within
|
|
1526
|
+
* the package.
|
|
1527
|
+
*/
|
|
1528
|
+
readonly resolveImport: (specifier: string, packageJson: PackageJson, pkg: PackageSpec) => Effect.Effect<ResolvedModule, ResolutionError>;
|
|
1529
|
+
/**
|
|
1530
|
+
* Resolve the main (root `"."`) type entry point for a package.
|
|
1531
|
+
*/
|
|
1532
|
+
readonly resolveMainEntry: (packageJson: PackageJson, pkg: PackageSpec) => Effect.Effect<ResolvedModule, ResolutionError>;
|
|
1533
|
+
/**
|
|
1534
|
+
* Collect all type entry points declared by the package, including the main
|
|
1535
|
+
* entry and any additional sub-path exports that expose types.
|
|
1536
|
+
*/
|
|
1537
|
+
readonly resolveTypeEntries: (packageJson: PackageJson, pkg: PackageSpec) => Effect.Effect<ReadonlyArray<ResolvedModule>, ResolutionError>;
|
|
1538
|
+
/**
|
|
1539
|
+
* Given a JavaScript file path, derive the corresponding `.d.ts` / `.d.mts`
|
|
1540
|
+
* / `.d.cts` path. Returns `null` when no type definition can be inferred.
|
|
1541
|
+
*/
|
|
1542
|
+
readonly findTypeDefinition: (jsFilePath: string, packageJson: PackageJson, pkg: PackageSpec) => Effect.Effect<ResolvedModule | null, ResolutionError>;
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
/**
|
|
1546
|
+
* Effect Context tag for the {@link TypeResolver} service.
|
|
1547
|
+
*
|
|
1548
|
+
* @see {@link TypeResolverLive}
|
|
1549
|
+
*/
|
|
1550
|
+
export declare const TypeResolver: Context.Tag<TypeResolver, TypeResolver>;
|
|
1551
|
+
|
|
1552
|
+
/**
|
|
1553
|
+
* Pure {@link TypeResolver} layer with no external dependencies.
|
|
1554
|
+
*
|
|
1555
|
+
* @remarks
|
|
1556
|
+
* Resolution is performed synchronously using only the data present in the
|
|
1557
|
+
* supplied `package.json`. The resolution order is:
|
|
1558
|
+
*
|
|
1559
|
+
* 1. `exports` map (`"types"` condition, then `"import"` / `"default"`)
|
|
1560
|
+
* 2. `typesVersions["*"]` with wildcard pattern matching
|
|
1561
|
+
* 3. Top-level `types` or `typings` fields
|
|
1562
|
+
* 4. Conventional extension swapping (`.js` to `.d.ts`) and `index.d.ts`
|
|
1563
|
+
* fallback
|
|
1564
|
+
*
|
|
1565
|
+
* @see {@link TypeResolver}
|
|
1566
|
+
*
|
|
1567
|
+
* @public
|
|
1568
|
+
*/
|
|
1569
|
+
export declare const TypeResolverLive: Layer.Layer<TypeResolver>;
|
|
1570
|
+
|
|
1571
|
+
/**
|
|
1572
|
+
* A `Map<string, string>` that maps virtual file paths to their contents.
|
|
1573
|
+
*
|
|
1574
|
+
* @remarks
|
|
1575
|
+
* Keys are prefixed with `node_modules/` so the map can be fed directly into
|
|
1576
|
+
* an in-memory TypeScript compiler host. Values are the UTF-8 file contents
|
|
1577
|
+
* (typically `.d.ts` declarations).
|
|
1578
|
+
*
|
|
1579
|
+
* @example
|
|
1580
|
+
* ```typescript
|
|
1581
|
+
* import type { VirtualFileSystem } from "type-registry-effect";
|
|
1582
|
+
*
|
|
1583
|
+
* const vfs: VirtualFileSystem = new Map([
|
|
1584
|
+
* ["node_modules/lodash/index.d.ts", "declare module 'lodash' { ... }"],
|
|
1585
|
+
* ]);
|
|
1586
|
+
* ```
|
|
1587
|
+
*
|
|
1588
|
+
* @see {@link CacheService}
|
|
1589
|
+
*
|
|
1590
|
+
* @public
|
|
1591
|
+
*/
|
|
1592
|
+
export declare type VirtualFileSystem = Map<string, string>;
|
|
1593
|
+
|
|
1594
|
+
export declare namespace VirtualPackage {
|
|
1595
|
+
export {
|
|
1596
|
+
VirtualPackage_2 as VirtualPackage
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
/**
|
|
1601
|
+
* Creates virtual npm packages from TypeScript declaration content for
|
|
1602
|
+
* inclusion in a {@link VirtualFileSystem} without fetching from the CDN.
|
|
1603
|
+
*
|
|
1604
|
+
* @remarks
|
|
1605
|
+
* `VirtualPackage` is useful when you have locally-generated `.d.ts` files —
|
|
1606
|
+
* for example, output from API Extractor, hand-written ambient declarations, or
|
|
1607
|
+
* declaration files bundled alongside your own packages — and want to inject
|
|
1608
|
+
* them into the same VFS that TypeRegistry builds from remote packages.
|
|
1609
|
+
*
|
|
1610
|
+
* Instances are **transient**: they are not persisted to the disk cache and
|
|
1611
|
+
* live only as long as the VFS they produce. Call {@link VirtualPackage.generateVfs}
|
|
1612
|
+
* to obtain a VFS that can be merged with other VFS maps.
|
|
1613
|
+
*
|
|
1614
|
+
* @see {@link VirtualFileSystem} for the VFS type consumed by TypeScript tooling
|
|
1615
|
+
*
|
|
1616
|
+
* @public
|
|
1617
|
+
*/
|
|
1618
|
+
declare class VirtualPackage_2 {
|
|
1619
|
+
readonly name: string;
|
|
1620
|
+
readonly version: string;
|
|
1621
|
+
private readonly entries;
|
|
1622
|
+
constructor(name: string, version: string, entries: Map<string, string>);
|
|
1623
|
+
/**
|
|
1624
|
+
* Single-entry convenience factory.
|
|
1625
|
+
*
|
|
1626
|
+
* Creates a virtual package whose sole entry point is `index.d.ts`.
|
|
1627
|
+
*
|
|
1628
|
+
* @param name - Package name (e.g. `"@my-org/api-types"`).
|
|
1629
|
+
* @param version - Semver version string (e.g. `"1.0.0"`).
|
|
1630
|
+
* @param declarations - The full TypeScript declaration source for `index.d.ts`.
|
|
1631
|
+
* @returns A new {@link VirtualPackage} instance.
|
|
1632
|
+
*
|
|
1633
|
+
* @example
|
|
1634
|
+
* ```typescript
|
|
1635
|
+
* import type { VirtualFileSystem } from "type-registry-effect";
|
|
1636
|
+
* import { VirtualPackage } from "type-registry-effect";
|
|
1637
|
+
*
|
|
1638
|
+
* const declarations = `
|
|
1639
|
+
* export interface User {
|
|
1640
|
+
* id: string;
|
|
1641
|
+
* name: string;
|
|
1642
|
+
* }
|
|
1643
|
+
* `;
|
|
1644
|
+
*
|
|
1645
|
+
* const pkg = VirtualPackage.create("@my-org/api-types", "1.0.0", declarations);
|
|
1646
|
+
* const vfs: VirtualFileSystem = pkg.generateVfs();
|
|
1647
|
+
* console.log([...vfs.keys()]);
|
|
1648
|
+
* // ["node_modules/@my-org/api-types/package.json",
|
|
1649
|
+
* // "node_modules/@my-org/api-types/index.d.ts"]
|
|
1650
|
+
* ```
|
|
1651
|
+
*
|
|
1652
|
+
* @public
|
|
1653
|
+
*/
|
|
1654
|
+
static create(name: string, version: string, declarations: string): VirtualPackage_2;
|
|
1655
|
+
/**
|
|
1656
|
+
* Multi-entry factory.
|
|
1657
|
+
*
|
|
1658
|
+
* Creates a virtual package with multiple `.d.ts` entry point files,
|
|
1659
|
+
* producing a `package.json` that uses the `exports` map.
|
|
1660
|
+
*
|
|
1661
|
+
* @param name - Package name.
|
|
1662
|
+
* @param version - Semver version string.
|
|
1663
|
+
* @param entries - Map of file names (e.g. `"index.d.ts"`, `"testing.d.ts"`)
|
|
1664
|
+
* to their declaration source content.
|
|
1665
|
+
* @returns A new {@link VirtualPackage} instance.
|
|
1666
|
+
*
|
|
1667
|
+
* @example
|
|
1668
|
+
* ```typescript
|
|
1669
|
+
* import type { VirtualFileSystem } from "type-registry-effect";
|
|
1670
|
+
* import { VirtualPackage } from "type-registry-effect";
|
|
1671
|
+
*
|
|
1672
|
+
* const entries = new Map<string, string>([
|
|
1673
|
+
* ["index.d.ts", "export declare function run(): void;"],
|
|
1674
|
+
* ["testing.d.ts", "export declare function mock(): void;"],
|
|
1675
|
+
* ]);
|
|
1676
|
+
*
|
|
1677
|
+
* const pkg = VirtualPackage.createMultiEntry("@my-org/sdk", "2.0.0", entries);
|
|
1678
|
+
* const vfs: VirtualFileSystem = pkg.generateVfs();
|
|
1679
|
+
* console.log([...vfs.keys()]);
|
|
1680
|
+
* // ["node_modules/@my-org/sdk/package.json",
|
|
1681
|
+
* // "node_modules/@my-org/sdk/index.d.ts",
|
|
1682
|
+
* // "node_modules/@my-org/sdk/testing.d.ts"]
|
|
1683
|
+
* ```
|
|
1684
|
+
*
|
|
1685
|
+
* @public
|
|
1686
|
+
*/
|
|
1687
|
+
static createMultiEntry(name: string, version: string, entries: Map<string, string>): VirtualPackage_2;
|
|
1688
|
+
/**
|
|
1689
|
+
* Load a single `.d.ts` file from disk and create a virtual package from it.
|
|
1690
|
+
*
|
|
1691
|
+
* @remarks
|
|
1692
|
+
* Reads the file synchronously with `node:fs`. The resulting package has a
|
|
1693
|
+
* single `index.d.ts` entry whose content matches the file on disk.
|
|
1694
|
+
*
|
|
1695
|
+
* @param name - Package name.
|
|
1696
|
+
* @param version - Semver version string.
|
|
1697
|
+
* @param filePath - Absolute or relative path to a `.d.ts` file.
|
|
1698
|
+
* @returns A new {@link VirtualPackage} instance.
|
|
1699
|
+
*
|
|
1700
|
+
* @example
|
|
1701
|
+
* ```typescript
|
|
1702
|
+
* import type { VirtualFileSystem } from "type-registry-effect";
|
|
1703
|
+
* import { VirtualPackage } from "type-registry-effect";
|
|
1704
|
+
*
|
|
1705
|
+
* const pkg = VirtualPackage.fromFile(
|
|
1706
|
+
* "@my-org/api-types",
|
|
1707
|
+
* "1.0.0",
|
|
1708
|
+
* "./dist/api-types.d.ts",
|
|
1709
|
+
* );
|
|
1710
|
+
* const vfs: VirtualFileSystem = pkg.generateVfs();
|
|
1711
|
+
* ```
|
|
1712
|
+
*
|
|
1713
|
+
* @public
|
|
1714
|
+
*/
|
|
1715
|
+
static fromFile(name: string, version: string, filePath: string): VirtualPackage_2;
|
|
1716
|
+
/**
|
|
1717
|
+
* Generate the full {@link VirtualFileSystem}: a synthetic `package.json`
|
|
1718
|
+
* plus all entry `.d.ts` files, with every path prefixed by
|
|
1719
|
+
* `node_modules/<name>/`.
|
|
1720
|
+
*
|
|
1721
|
+
* @returns A {@link VirtualFileSystem} map ready to be merged with other VFS maps.
|
|
1722
|
+
*
|
|
1723
|
+
* @example
|
|
1724
|
+
* ```typescript
|
|
1725
|
+
* import type { VirtualFileSystem } from "type-registry-effect";
|
|
1726
|
+
* import { VirtualPackage } from "type-registry-effect";
|
|
1727
|
+
*
|
|
1728
|
+
* const pkg = VirtualPackage.create("my-types", "1.0.0", "export type Foo = string;");
|
|
1729
|
+
* const vfs: VirtualFileSystem = pkg.generateVfs();
|
|
1730
|
+
*
|
|
1731
|
+
* for (const [path, content] of vfs) {
|
|
1732
|
+
* console.log(`${path} (${content.length} chars)`);
|
|
1733
|
+
* }
|
|
1734
|
+
* ```
|
|
1735
|
+
*
|
|
1736
|
+
* @public
|
|
1737
|
+
*/
|
|
1738
|
+
generateVfs(): VirtualFileSystem;
|
|
1739
|
+
/**
|
|
1740
|
+
* Generate synthetic `package.json` content for the virtual package.
|
|
1741
|
+
*
|
|
1742
|
+
* @remarks
|
|
1743
|
+
* Uses the `types` field for single-entry packages and the `exports` map
|
|
1744
|
+
* for multi-entry packages so that TypeScript module resolution works
|
|
1745
|
+
* correctly against the generated VFS.
|
|
1746
|
+
*
|
|
1747
|
+
* @returns The `package.json` content as a JSON string.
|
|
1748
|
+
*
|
|
1749
|
+
* @internal
|
|
1750
|
+
*/
|
|
1751
|
+
private generatePackageJson;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
export { }
|