@frontmcp/uipack 1.10.8 → 1.10.9-rc.2

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/typings/index.js CHANGED
@@ -1,1033 +1,4 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // libs/uipack/src/typings/index.ts
21
- var typings_exports = {};
22
- __export(typings_exports, {
23
- DEFAULT_ALLOWED_PACKAGES: () => DEFAULT_ALLOWED_PACKAGES,
24
- DEFAULT_CACHE_OPTIONS: () => DEFAULT_CACHE_OPTIONS,
25
- DEFAULT_TYPE_CACHE_TTL: () => DEFAULT_TYPE_CACHE_TTL,
26
- DEFAULT_TYPE_FETCHER_OPTIONS: () => DEFAULT_TYPE_FETCHER_OPTIONS,
27
- MemoryTypeCache: () => MemoryTypeCache,
28
- TYPE_CACHE_PREFIX: () => TYPE_CACHE_PREFIX,
29
- TypeFetcher: () => TypeFetcher,
30
- buildTypeFiles: () => buildTypeFiles,
31
- combineDtsContents: () => combineDtsContents,
32
- createTypeFetcher: () => createTypeFetcher,
33
- dtsImportSchema: () => dtsImportSchema,
34
- dtsImportTypeSchema: () => dtsImportTypeSchema,
35
- dtsParseResultSchema: () => dtsParseResultSchema,
36
- getPackageFromSpecifier: () => getPackageFromSpecifier,
37
- getRelativeImportPath: () => getRelativeImportPath,
38
- getSubpathFromSpecifier: () => getSubpathFromSpecifier,
39
- globalTypeCache: () => globalTypeCache,
40
- isRelativeImport: () => isRelativeImport,
41
- packageResolutionSchema: () => packageResolutionSchema,
42
- parseDtsImports: () => parseDtsImports,
43
- parseImportStatement: () => parseImportStatement,
44
- safeParseBatchRequest: () => safeParseBatchRequest,
45
- safeParseTypeFetcherOptions: () => safeParseTypeFetcherOptions,
46
- typeCacheEntrySchema: () => typeCacheEntrySchema,
47
- typeCacheStatsSchema: () => typeCacheStatsSchema,
48
- typeFetchBatchRequestSchema: () => typeFetchBatchRequestSchema,
49
- typeFetchBatchResultSchema: () => typeFetchBatchResultSchema,
50
- typeFetchErrorCodeSchema: () => typeFetchErrorCodeSchema,
51
- typeFetchErrorSchema: () => typeFetchErrorSchema,
52
- typeFetchResultSchema: () => typeFetchResultSchema,
53
- typeFetcherOptionsSchema: () => typeFetcherOptionsSchema,
54
- typeFileSchema: () => typeFileSchema,
55
- urlToVirtualPath: () => urlToVirtualPath,
56
- validateBatchRequest: () => validateBatchRequest,
57
- validateTypeFetcherOptions: () => validateTypeFetcherOptions
58
- });
59
- module.exports = __toCommonJS(typings_exports);
60
-
61
- // libs/uipack/src/typings/types.ts
62
- var DEFAULT_ALLOWED_PACKAGES = ["react", "react-dom", "react/jsx-runtime", "zod", "@frontmcp/*"];
63
- var DEFAULT_TYPE_FETCHER_OPTIONS = {
64
- allowedPackages: [...DEFAULT_ALLOWED_PACKAGES],
65
- maxDepth: 4,
66
- timeout: 1e4,
67
- maxConcurrency: 5,
68
- cdnBaseUrl: "https://esm.sh"
69
- };
70
- var TYPE_CACHE_PREFIX = "types:";
71
- var DEFAULT_TYPE_CACHE_TTL = 60 * 60 * 1e3;
72
-
73
- // libs/uipack/src/typings/schemas.ts
74
- var import_lazy_zod = require("@frontmcp/lazy-zod");
75
- var typeFetchErrorCodeSchema = import_lazy_zod.z.enum([
76
- "NETWORK_ERROR",
77
- "TIMEOUT",
78
- "NO_TYPES_HEADER",
79
- "INVALID_SPECIFIER",
80
- "PACKAGE_NOT_FOUND",
81
- "PARSE_ERROR"
82
- ]);
83
- var typeFileSchema = import_lazy_zod.z.object({
84
- path: import_lazy_zod.z.string().min(1),
85
- url: import_lazy_zod.z.string(),
86
- // Allow empty string for synthesized alias files
87
- content: import_lazy_zod.z.string()
88
- }).strict();
89
- var typeFetchResultSchema = import_lazy_zod.z.object({
90
- specifier: import_lazy_zod.z.string().min(1),
91
- resolvedPackage: import_lazy_zod.z.string().min(1),
92
- subpath: import_lazy_zod.z.string().optional(),
93
- version: import_lazy_zod.z.string().min(1),
94
- content: import_lazy_zod.z.string(),
95
- files: import_lazy_zod.z.array(typeFileSchema),
96
- fetchedUrls: import_lazy_zod.z.array(import_lazy_zod.z.string().url()),
97
- fetchedAt: import_lazy_zod.z.string().datetime()
98
- }).strict();
99
- var typeFetchErrorSchema = import_lazy_zod.z.object({
100
- specifier: import_lazy_zod.z.string().min(1),
101
- code: typeFetchErrorCodeSchema,
102
- message: import_lazy_zod.z.string().min(1),
103
- url: import_lazy_zod.z.string().url().optional()
104
- }).strict();
105
- var typeFetchBatchRequestSchema = import_lazy_zod.z.object({
106
- imports: import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).min(1),
107
- maxDepth: import_lazy_zod.z.number().int().min(0).max(10).optional(),
108
- timeout: import_lazy_zod.z.number().int().min(1e3).max(6e4).optional(),
109
- maxConcurrency: import_lazy_zod.z.number().int().min(1).max(20).optional(),
110
- skipCache: import_lazy_zod.z.boolean().optional(),
111
- versionOverrides: import_lazy_zod.z.record(import_lazy_zod.z.string().min(1), import_lazy_zod.z.string().min(1)).optional()
112
- }).strict();
113
- var typeFetchBatchResultSchema = import_lazy_zod.z.object({
114
- results: import_lazy_zod.z.array(typeFetchResultSchema),
115
- errors: import_lazy_zod.z.array(typeFetchErrorSchema),
116
- totalTimeMs: import_lazy_zod.z.number().nonnegative(),
117
- cacheHits: import_lazy_zod.z.number().int().nonnegative(),
118
- networkRequests: import_lazy_zod.z.number().int().nonnegative()
119
- }).strict();
120
- var typeCacheEntrySchema = import_lazy_zod.z.object({
121
- result: typeFetchResultSchema,
122
- cachedAt: import_lazy_zod.z.number().int().positive(),
123
- size: import_lazy_zod.z.number().int().nonnegative(),
124
- accessCount: import_lazy_zod.z.number().int().nonnegative()
125
- }).strict();
126
- var typeCacheStatsSchema = import_lazy_zod.z.object({
127
- entries: import_lazy_zod.z.number().int().nonnegative(),
128
- totalSize: import_lazy_zod.z.number().nonnegative(),
129
- hits: import_lazy_zod.z.number().int().nonnegative(),
130
- misses: import_lazy_zod.z.number().int().nonnegative(),
131
- hitRate: import_lazy_zod.z.number().min(0).max(1)
132
- }).strict();
133
- var dtsImportTypeSchema = import_lazy_zod.z.enum(["import", "export", "reference", "declare-module"]);
134
- var dtsImportSchema = import_lazy_zod.z.object({
135
- type: dtsImportTypeSchema,
136
- specifier: import_lazy_zod.z.string().min(1),
137
- statement: import_lazy_zod.z.string(),
138
- line: import_lazy_zod.z.number().int().positive()
139
- }).strict();
140
- var dtsParseResultSchema = import_lazy_zod.z.object({
141
- imports: import_lazy_zod.z.array(dtsImportSchema),
142
- externalPackages: import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)),
143
- relativeImports: import_lazy_zod.z.array(import_lazy_zod.z.string())
144
- }).strict();
145
- var typeFetcherOptionsSchema = import_lazy_zod.z.object({
146
- maxDepth: import_lazy_zod.z.number().int().min(0).max(10).optional(),
147
- timeout: import_lazy_zod.z.number().int().min(1e3).max(6e4).optional(),
148
- maxConcurrency: import_lazy_zod.z.number().int().min(1).max(20).optional(),
149
- cdnBaseUrl: import_lazy_zod.z.string().url().optional()
150
- }).strict();
151
- var packageResolutionSchema = import_lazy_zod.z.object({
152
- packageName: import_lazy_zod.z.string().min(1),
153
- subpath: import_lazy_zod.z.string().optional(),
154
- version: import_lazy_zod.z.string().min(1),
155
- typesUrl: import_lazy_zod.z.string().url()
156
- }).strict();
157
- function validateBatchRequest(data) {
158
- return typeFetchBatchRequestSchema.parse(data);
159
- }
160
- function safeParseBatchRequest(data) {
161
- return typeFetchBatchRequestSchema.safeParse(data);
162
- }
163
- function validateTypeFetcherOptions(data) {
164
- return typeFetcherOptionsSchema.parse(data);
165
- }
166
- function safeParseTypeFetcherOptions(data) {
167
- return typeFetcherOptionsSchema.safeParse(data);
168
- }
169
-
170
- // libs/uipack/src/typings/cache/cache-adapter.ts
171
- var DEFAULT_CACHE_OPTIONS = {
172
- maxSize: 500,
173
- defaultTtl: 60 * 60 * 1e3,
174
- // 1 hour
175
- trackStats: true
176
- };
177
-
178
- // libs/uipack/src/typings/cache/memory-cache.ts
179
- var MemoryTypeCache = class {
180
- cache = /* @__PURE__ */ new Map();
181
- maxSize;
182
- defaultTtl;
183
- trackStats;
184
- /** Cache statistics */
185
- stats = {
186
- hits: 0,
187
- misses: 0,
188
- evictions: 0
189
- };
190
- constructor(options = {}) {
191
- const opts = { ...DEFAULT_CACHE_OPTIONS, ...options };
192
- this.maxSize = opts.maxSize;
193
- this.defaultTtl = opts.defaultTtl;
194
- this.trackStats = opts.trackStats;
195
- }
196
- /**
197
- * Get a cached entry by key.
198
- */
199
- async get(key) {
200
- const internal = this.cache.get(key);
201
- if (!internal) {
202
- if (this.trackStats) this.stats.misses++;
203
- return void 0;
204
- }
205
- if (internal.expiresAt > 0 && Date.now() > internal.expiresAt) {
206
- this.cache.delete(key);
207
- if (this.trackStats) this.stats.misses++;
208
- return void 0;
209
- }
210
- this.cache.delete(key);
211
- internal.entry.accessCount++;
212
- this.cache.set(key, internal);
213
- if (this.trackStats) this.stats.hits++;
214
- return internal.entry;
215
- }
216
- /**
217
- * Store an entry in the cache.
218
- */
219
- async set(key, entry, ttl) {
220
- if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
221
- const oldestKey = this.cache.keys().next().value;
222
- if (oldestKey) {
223
- this.cache.delete(oldestKey);
224
- if (this.trackStats) this.stats.evictions++;
225
- }
226
- }
227
- const effectiveTtl = ttl ?? this.defaultTtl;
228
- const expiresAt = effectiveTtl > 0 ? Date.now() + effectiveTtl : 0;
229
- this.cache.set(key, { entry, expiresAt });
230
- }
231
- /**
232
- * Check if a key exists in the cache.
233
- */
234
- async has(key) {
235
- const internal = this.cache.get(key);
236
- if (!internal) return false;
237
- if (internal.expiresAt > 0 && Date.now() > internal.expiresAt) {
238
- this.cache.delete(key);
239
- return false;
240
- }
241
- return true;
242
- }
243
- /**
244
- * Delete a cached entry.
245
- */
246
- async delete(key) {
247
- return this.cache.delete(key);
248
- }
249
- /**
250
- * Clear all cached entries.
251
- */
252
- async clear() {
253
- this.cache.clear();
254
- this.stats = { hits: 0, misses: 0, evictions: 0 };
255
- }
256
- /**
257
- * Get cache statistics.
258
- */
259
- async getStats() {
260
- let totalSize = 0;
261
- for (const { entry } of this.cache.values()) {
262
- totalSize += entry.size;
263
- }
264
- const total = this.stats.hits + this.stats.misses;
265
- return {
266
- entries: this.cache.size,
267
- totalSize,
268
- hits: this.stats.hits,
269
- misses: this.stats.misses,
270
- hitRate: total > 0 ? this.stats.hits / total : 0
271
- };
272
- }
273
- /**
274
- * Get current cache size.
275
- */
276
- get size() {
277
- return this.cache.size;
278
- }
279
- /**
280
- * Get number of evictions.
281
- */
282
- get evictions() {
283
- return this.stats.evictions;
284
- }
285
- /**
286
- * Clean up expired entries.
287
- * Call periodically to free memory from expired entries.
288
- *
289
- * @returns Number of entries cleaned up
290
- */
291
- cleanup() {
292
- const now = Date.now();
293
- let cleaned = 0;
294
- for (const [key, internal] of this.cache.entries()) {
295
- if (internal.expiresAt > 0 && now > internal.expiresAt) {
296
- this.cache.delete(key);
297
- cleaned++;
298
- }
299
- }
300
- return cleaned;
301
- }
302
- };
303
- var globalTypeCache = new MemoryTypeCache({
304
- maxSize: 500,
305
- defaultTtl: 60 * 60 * 1e3
306
- // 1 hour
307
- });
308
-
309
- // libs/uipack/src/typings/dts-parser.ts
310
- var IMPORT_PATTERN = /^import\s+(?:type\s+)?(?:(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+)?['"]([^'"]+)['"]/gm;
311
- var EXPORT_FROM_PATTERN = /^export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/gm;
312
- var REFERENCE_TYPES_PATTERN = /^\/\/\/\s*<reference\s+types\s*=\s*['"]([^'"]+)['"]\s*\/>/gm;
313
- var REFERENCE_PATH_PATTERN = /^\/\/\/\s*<reference\s+path\s*=\s*['"]([^'"]+)['"]\s*\/>/gm;
314
- var DECLARE_MODULE_PATTERN = /^declare\s+module\s+['"]([^'"]+)['"]/gm;
315
- function parseDtsImports(content) {
316
- const imports = [];
317
- const externalPackages = /* @__PURE__ */ new Set();
318
- const relativeImports = /* @__PURE__ */ new Set();
319
- const lines = content.split("\n");
320
- for (let i = 0; i < lines.length; i++) {
321
- const line = lines[i];
322
- const lineNum = i + 1;
323
- IMPORT_PATTERN.lastIndex = 0;
324
- let match = IMPORT_PATTERN.exec(line);
325
- if (match) {
326
- const specifier = match[1];
327
- imports.push({
328
- type: "import",
329
- specifier,
330
- statement: line.trim(),
331
- line: lineNum
332
- });
333
- categorizeSpecifier(specifier, externalPackages, relativeImports);
334
- }
335
- EXPORT_FROM_PATTERN.lastIndex = 0;
336
- match = EXPORT_FROM_PATTERN.exec(line);
337
- if (match) {
338
- const specifier = match[1];
339
- imports.push({
340
- type: "export",
341
- specifier,
342
- statement: line.trim(),
343
- line: lineNum
344
- });
345
- categorizeSpecifier(specifier, externalPackages, relativeImports);
346
- }
347
- REFERENCE_TYPES_PATTERN.lastIndex = 0;
348
- match = REFERENCE_TYPES_PATTERN.exec(line);
349
- if (match) {
350
- const specifier = match[1];
351
- imports.push({
352
- type: "reference",
353
- specifier,
354
- statement: line.trim(),
355
- line: lineNum
356
- });
357
- externalPackages.add(getPackageFromSpecifier(specifier));
358
- }
359
- REFERENCE_PATH_PATTERN.lastIndex = 0;
360
- match = REFERENCE_PATH_PATTERN.exec(line);
361
- if (match) {
362
- const specifier = match[1];
363
- imports.push({
364
- type: "reference",
365
- specifier,
366
- statement: line.trim(),
367
- line: lineNum
368
- });
369
- relativeImports.add(specifier);
370
- }
371
- DECLARE_MODULE_PATTERN.lastIndex = 0;
372
- match = DECLARE_MODULE_PATTERN.exec(line);
373
- if (match) {
374
- const specifier = match[1];
375
- imports.push({
376
- type: "declare-module",
377
- specifier,
378
- statement: line.trim(),
379
- line: lineNum
380
- });
381
- }
382
- }
383
- return {
384
- imports,
385
- externalPackages: Array.from(externalPackages),
386
- relativeImports: Array.from(relativeImports)
387
- };
388
- }
389
- function categorizeSpecifier(specifier, externalPackages, relativeImports) {
390
- if (isRelativeImport(specifier)) {
391
- relativeImports.add(specifier);
392
- } else {
393
- externalPackages.add(getPackageFromSpecifier(specifier));
394
- }
395
- }
396
- function isRelativeImport(specifier) {
397
- return specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || // Check for Windows-style paths
398
- /^[A-Za-z]:/.test(specifier);
399
- }
400
- function getPackageFromSpecifier(specifier) {
401
- if (specifier.startsWith("@")) {
402
- const parts = specifier.split("/");
403
- if (parts.length >= 2) {
404
- return `${parts[0]}/${parts[1]}`;
405
- }
406
- return specifier;
407
- }
408
- const slashIndex = specifier.indexOf("/");
409
- if (slashIndex > 0) {
410
- return specifier.substring(0, slashIndex);
411
- }
412
- return specifier;
413
- }
414
- function getSubpathFromSpecifier(specifier) {
415
- const packageName = getPackageFromSpecifier(specifier);
416
- if (specifier.length > packageName.length + 1) {
417
- return specifier.substring(packageName.length + 1);
418
- }
419
- return void 0;
420
- }
421
- var MAX_IMPORT_STATEMENT_LENGTH = 2e3;
422
- function parseImportStatement(statement) {
423
- if (statement.length > MAX_IMPORT_STATEMENT_LENGTH) {
424
- return null;
425
- }
426
- const namedMatch = /import\s+(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+['"]([^'"]+)['"]/.exec(statement);
427
- if (namedMatch) {
428
- return namedMatch[1];
429
- }
430
- const sideEffectMatch = /import\s+['"]([^'"]+)['"]/.exec(statement);
431
- if (sideEffectMatch) {
432
- return sideEffectMatch[1];
433
- }
434
- return null;
435
- }
436
- function combineDtsContents(contents) {
437
- const seenReferences = /* @__PURE__ */ new Set();
438
- const references = [];
439
- const declarations = [];
440
- for (const [url, content] of contents.entries()) {
441
- const lines = content.split("\n");
442
- let inReferences = true;
443
- for (const line of lines) {
444
- const trimmed = line.trim();
445
- if (trimmed.startsWith("///")) {
446
- if (!seenReferences.has(trimmed)) {
447
- seenReferences.add(trimmed);
448
- references.push(trimmed);
449
- }
450
- continue;
451
- }
452
- if (inReferences && trimmed === "") {
453
- continue;
454
- }
455
- inReferences = false;
456
- if (declarations.length === 0 || declarations[declarations.length - 1] !== "") {
457
- if (trimmed !== "") {
458
- if (!declarations.some((d) => d.includes(`// Source: ${url}`))) {
459
- declarations.push(`
460
- // Source: ${url}`);
461
- }
462
- }
463
- }
464
- declarations.push(line);
465
- }
466
- }
467
- const parts = [];
468
- if (references.length > 0) {
469
- parts.push(references.join("\n"));
470
- parts.push("");
471
- }
472
- parts.push(declarations.join("\n").trim());
473
- return parts.join("\n");
474
- }
475
-
476
- // libs/uipack/src/typings/type-fetcher.ts
477
- var Semaphore = class {
478
- permits;
479
- waiting = [];
480
- constructor(permits) {
481
- this.permits = permits;
482
- }
483
- async acquire() {
484
- if (this.permits > 0) {
485
- this.permits--;
486
- return;
487
- }
488
- return new Promise((resolve) => {
489
- this.waiting.push(resolve);
490
- });
491
- }
492
- release() {
493
- if (this.waiting.length > 0) {
494
- const next = this.waiting.shift();
495
- next?.();
496
- } else {
497
- this.permits++;
498
- }
499
- }
500
- };
501
- var TypeFetcher = class {
502
- maxDepth;
503
- timeout;
504
- maxConcurrency;
505
- cdnBaseUrl;
506
- fetchFn;
507
- cache;
508
- allowedPatterns;
509
- allowlistEnabled;
510
- _initialized = false;
511
- constructor(options = {}, cache) {
512
- this.maxDepth = options.maxDepth ?? 2;
513
- this.timeout = options.timeout ?? 1e4;
514
- this.maxConcurrency = options.maxConcurrency ?? 5;
515
- this.cdnBaseUrl = options.cdnBaseUrl ?? "https://esm.sh";
516
- this.fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);
517
- this.cache = cache ?? globalTypeCache;
518
- if (options.allowedPackages === false) {
519
- this.allowlistEnabled = false;
520
- this.allowedPatterns = [];
521
- } else {
522
- this.allowlistEnabled = true;
523
- this.allowedPatterns = [...DEFAULT_ALLOWED_PACKAGES, ...options.allowedPackages ?? []];
524
- }
525
- }
526
- /**
527
- * Check if a package is allowed by the allowlist.
528
- * Supports glob patterns (e.g., '@frontmcp/*' matches '@frontmcp/ui').
529
- *
530
- * @param packageName - The package name to check
531
- * @returns true if the package is allowed
532
- */
533
- isPackageAllowed(packageName) {
534
- if (!this.allowlistEnabled) {
535
- return true;
536
- }
537
- return this.allowedPatterns.some((pattern) => {
538
- if (pattern.includes("*")) {
539
- const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
540
- const regex = new RegExp(`^${escaped}$`);
541
- return regex.test(packageName);
542
- }
543
- return packageName === pattern || packageName.startsWith(pattern + "/");
544
- });
545
- }
546
- /**
547
- * Initialize the TypeFetcher by pre-loading allowed packages.
548
- * This fetches types for all allowed packages and caches them.
549
- *
550
- * @param options - Options for initialization
551
- * @returns Summary of initialization results
552
- */
553
- async initialize(options) {
554
- if (this._initialized) {
555
- const stats2 = await this.cache.getStats();
556
- return { loaded: [], failed: [], cached: stats2.entries };
557
- }
558
- const loaded = [];
559
- const failed = [];
560
- const packagesToLoad = this.allowedPatterns.filter((p) => !p.includes("*"));
561
- for (const pkg of packagesToLoad) {
562
- const result = await this.fetchBatch({
563
- imports: [`import * from "${pkg}"`],
564
- timeout: options?.timeout ?? this.timeout
565
- });
566
- if (result.results.length > 0) {
567
- loaded.push(pkg);
568
- } else if (result.errors.length > 0) {
569
- failed.push(pkg);
570
- }
571
- }
572
- this._initialized = true;
573
- const stats = await this.cache.getStats();
574
- return { loaded, failed, cached: stats.entries };
575
- }
576
- /**
577
- * Whether the fetcher has been initialized.
578
- */
579
- get initialized() {
580
- return this._initialized;
581
- }
582
- /**
583
- * Get the list of allowed package patterns.
584
- */
585
- get allowedPackagePatterns() {
586
- return this.allowedPatterns;
587
- }
588
- /**
589
- * Fetch types for a batch of import statements.
590
- *
591
- * @param request - Batch request configuration
592
- * @returns Batch result with results and errors
593
- */
594
- async fetchBatch(request) {
595
- const startTime = Date.now();
596
- const results = [];
597
- const errors = [];
598
- let cacheHits = 0;
599
- let networkRequests = 0;
600
- const maxDepth = request.maxDepth ?? this.maxDepth;
601
- const timeout = request.timeout ?? this.timeout;
602
- const maxConcurrency = request.maxConcurrency ?? this.maxConcurrency;
603
- const skipCache = request.skipCache ?? false;
604
- const versionOverrides = request.versionOverrides ?? {};
605
- const semaphore = new Semaphore(maxConcurrency);
606
- const promises = request.imports.map(async (importStatement) => {
607
- await semaphore.acquire();
608
- try {
609
- const specifier = parseImportStatement(importStatement);
610
- if (!specifier) {
611
- errors.push({
612
- specifier: importStatement,
613
- code: "INVALID_SPECIFIER",
614
- message: `Could not parse import statement: ${importStatement}`
615
- });
616
- return;
617
- }
618
- const packageName = getPackageFromSpecifier(specifier);
619
- if (!this.isPackageAllowed(packageName)) {
620
- errors.push({
621
- specifier,
622
- code: "PACKAGE_NOT_ALLOWED",
623
- message: `Package "${packageName}" is not in the allowlist`
624
- });
625
- return;
626
- }
627
- const version = versionOverrides[packageName] ?? "latest";
628
- const cacheKey = `${TYPE_CACHE_PREFIX}${packageName}@${version}`;
629
- if (!skipCache) {
630
- const cached = await this.cache.get(cacheKey);
631
- if (cached) {
632
- cacheHits++;
633
- results.push(cached.result);
634
- return;
635
- }
636
- }
637
- const result = await this.fetchTypesForSpecifier(specifier, {
638
- maxDepth,
639
- timeout,
640
- version
641
- });
642
- if (result.success) {
643
- results.push(result.data);
644
- networkRequests += result.fetchCount;
645
- const entry = {
646
- result: result.data,
647
- cachedAt: Date.now(),
648
- size: result.data.content.length,
649
- accessCount: 1
650
- };
651
- await this.cache.set(cacheKey, entry);
652
- } else {
653
- errors.push(result.error);
654
- networkRequests += result.fetchCount;
655
- }
656
- } finally {
657
- semaphore.release();
658
- }
659
- });
660
- await Promise.all(promises);
661
- return {
662
- results,
663
- errors,
664
- totalTimeMs: Date.now() - startTime,
665
- cacheHits,
666
- networkRequests
667
- };
668
- }
669
- /**
670
- * Fetch types for a single import specifier.
671
- */
672
- async fetchTypesForSpecifier(specifier, options) {
673
- let fetchCount = 0;
674
- const fetchedUrls = [];
675
- const visitedUrls = /* @__PURE__ */ new Set();
676
- const contents = /* @__PURE__ */ new Map();
677
- try {
678
- const resolution = await this.resolvePackage(specifier, options.version, options.timeout);
679
- if (!resolution) {
680
- return {
681
- success: false,
682
- error: {
683
- specifier,
684
- code: "PACKAGE_NOT_FOUND",
685
- message: `Could not resolve package: ${specifier}`
686
- },
687
- fetchCount
688
- };
689
- }
690
- fetchCount++;
691
- const fetchResult = await this.fetchRecursive(
692
- resolution.typesUrl,
693
- options.maxDepth,
694
- options.timeout,
695
- visitedUrls,
696
- contents
697
- );
698
- fetchCount += fetchResult.fetchCount;
699
- fetchedUrls.push(...fetchResult.fetchedUrls);
700
- if (!fetchResult.success) {
701
- return {
702
- success: false,
703
- error: {
704
- specifier,
705
- code: fetchResult.errorCode,
706
- message: fetchResult.errorMessage ?? "Unknown error",
707
- url: fetchResult.errorUrl
708
- },
709
- fetchCount
710
- };
711
- }
712
- const files = buildTypeFiles(contents, resolution.packageName, resolution.version, resolution.subpath);
713
- const combinedContent = combineDtsContents(contents);
714
- const result = {
715
- specifier,
716
- resolvedPackage: resolution.packageName,
717
- subpath: resolution.subpath,
718
- version: resolution.version,
719
- content: combinedContent,
720
- files,
721
- fetchedUrls,
722
- fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
723
- };
724
- return { success: true, data: result, fetchCount };
725
- } catch (error) {
726
- return {
727
- success: false,
728
- error: {
729
- specifier,
730
- code: "NETWORK_ERROR",
731
- message: error instanceof Error ? error.message : String(error)
732
- },
733
- fetchCount
734
- };
735
- }
736
- }
737
- /**
738
- * Resolve a package specifier to a types URL.
739
- * Uses path fallback: try full path, then remove last segment until found.
740
- */
741
- async resolvePackage(specifier, version, timeout) {
742
- const packageName = getPackageFromSpecifier(specifier);
743
- const subpath = getSubpathFromSpecifier(specifier);
744
- const versionSuffix = version === "latest" ? "" : `@${version}`;
745
- const baseUrl = `${this.cdnBaseUrl}/${packageName}${versionSuffix}`;
746
- const urlsToTry = subpath ? [`${baseUrl}/${subpath}`, baseUrl] : [baseUrl];
747
- for (const url of urlsToTry) {
748
- try {
749
- const response = await this.fetchWithTimeout(url, timeout, "HEAD");
750
- if (response.ok) {
751
- const typesHeader = response.headers.get("X-TypeScript-Types");
752
- if (typesHeader) {
753
- const typesUrl = typesHeader.startsWith("/") ? `${this.cdnBaseUrl}${typesHeader}` : typesHeader;
754
- const versionMatch = /@(\d+\.\d+\.\d+[^/]*)/.exec(typesUrl);
755
- const resolvedVersion = versionMatch ? versionMatch[1] : version;
756
- return {
757
- packageName,
758
- subpath,
759
- version: resolvedVersion,
760
- typesUrl
761
- };
762
- }
763
- }
764
- } catch {
765
- continue;
766
- }
767
- }
768
- return null;
769
- }
770
- /**
771
- * Recursively fetch .d.ts files.
772
- */
773
- async fetchRecursive(url, depth, timeout, visited, contents) {
774
- if (visited.has(url)) {
775
- return { success: true, fetchCount: 0, fetchedUrls: [] };
776
- }
777
- visited.add(url);
778
- let fetchCount = 1;
779
- const fetchedUrls = [url];
780
- try {
781
- const response = await this.fetchWithTimeout(url, timeout, "GET");
782
- if (!response.ok) {
783
- return {
784
- success: false,
785
- fetchCount,
786
- fetchedUrls,
787
- errorCode: "NETWORK_ERROR",
788
- errorMessage: `HTTP ${response.status}: ${response.statusText}`,
789
- errorUrl: url
790
- };
791
- }
792
- const content = await response.text();
793
- contents.set(url, content);
794
- if (depth <= 0) {
795
- return { success: true, fetchCount, fetchedUrls };
796
- }
797
- const parsed = parseDtsImports(content);
798
- for (const pkg of parsed.externalPackages) {
799
- if (pkg.startsWith("@types/") || isBuiltinModule(pkg)) {
800
- continue;
801
- }
802
- const resolution = await this.resolvePackage(pkg, "latest", timeout);
803
- fetchCount++;
804
- if (resolution && !visited.has(resolution.typesUrl)) {
805
- const result = await this.fetchRecursive(resolution.typesUrl, depth - 1, timeout, visited, contents);
806
- fetchCount += result.fetchCount;
807
- fetchedUrls.push(...result.fetchedUrls);
808
- }
809
- }
810
- for (const relativePath of parsed.relativeImports) {
811
- const resolvedUrl = resolveRelativeUrl(url, relativePath);
812
- if (resolvedUrl && !visited.has(resolvedUrl)) {
813
- const result = await this.fetchRecursive(resolvedUrl, depth - 1, timeout, visited, contents);
814
- fetchCount += result.fetchCount;
815
- fetchedUrls.push(...result.fetchedUrls);
816
- }
817
- }
818
- return { success: true, fetchCount, fetchedUrls };
819
- } catch (error) {
820
- const isTimeout = error instanceof Error && error.message.includes("timeout");
821
- return {
822
- success: false,
823
- fetchCount,
824
- fetchedUrls,
825
- errorCode: isTimeout ? "TIMEOUT" : "NETWORK_ERROR",
826
- errorMessage: error instanceof Error ? error.message : String(error),
827
- errorUrl: url
828
- };
829
- }
830
- }
831
- /**
832
- * Fetch with timeout support.
833
- */
834
- async fetchWithTimeout(url, timeout, method) {
835
- const controller = new AbortController();
836
- const timeoutId = setTimeout(() => controller.abort(), timeout);
837
- try {
838
- const response = await this.fetchFn(url, {
839
- method,
840
- signal: controller.signal,
841
- headers: {
842
- Accept: "application/typescript, text/plain, */*"
843
- }
844
- });
845
- return response;
846
- } finally {
847
- clearTimeout(timeoutId);
848
- }
849
- }
850
- };
851
- function isBuiltinModule(name) {
852
- const builtins = /* @__PURE__ */ new Set([
853
- "assert",
854
- "buffer",
855
- "child_process",
856
- "cluster",
857
- "console",
858
- "constants",
859
- "crypto",
860
- "dgram",
861
- "dns",
862
- "domain",
863
- "events",
864
- "fs",
865
- "http",
866
- "https",
867
- "module",
868
- "net",
869
- "os",
870
- "path",
871
- "punycode",
872
- "querystring",
873
- "readline",
874
- "repl",
875
- "stream",
876
- "string_decoder",
877
- "sys",
878
- "timers",
879
- "tls",
880
- "tty",
881
- "url",
882
- "util",
883
- "v8",
884
- "vm",
885
- "zlib",
886
- // Node.js prefixed modules
887
- "node:assert",
888
- "node:buffer",
889
- "node:child_process",
890
- "node:cluster",
891
- "node:console",
892
- "node:constants",
893
- "node:crypto",
894
- "node:dgram",
895
- "node:dns",
896
- "node:domain",
897
- "node:events",
898
- "node:fs",
899
- "node:http",
900
- "node:https",
901
- "node:module",
902
- "node:net",
903
- "node:os",
904
- "node:path",
905
- "node:punycode",
906
- "node:querystring",
907
- "node:readline",
908
- "node:repl",
909
- "node:stream",
910
- "node:string_decoder",
911
- "node:sys",
912
- "node:timers",
913
- "node:tls",
914
- "node:tty",
915
- "node:url",
916
- "node:util",
917
- "node:v8",
918
- "node:vm",
919
- "node:zlib"
920
- ]);
921
- return builtins.has(name);
922
- }
923
- function resolveRelativeUrl(base, relative) {
924
- try {
925
- let path = relative;
926
- if (!path.endsWith(".d.ts") && !path.endsWith(".ts")) {
927
- path = `${path}.d.ts`;
928
- }
929
- const resolved = new URL(path, base);
930
- return resolved.toString();
931
- } catch {
932
- return null;
933
- }
934
- }
935
- function buildTypeFiles(contents, packageName, version, subpath) {
936
- const files = [];
937
- for (const [url, content] of contents.entries()) {
938
- const virtualPath = urlToVirtualPath(url, packageName, version);
939
- files.push({
940
- path: virtualPath,
941
- url,
942
- content
943
- });
944
- }
945
- if (subpath) {
946
- const aliasPath = `node_modules/${packageName}/${subpath}/index.d.ts`;
947
- const aliasExists = files.some((f) => f.path === aliasPath);
948
- if (!aliasExists) {
949
- const aliasContent = `// Auto-generated alias for ${packageName}/${subpath}
1
+ "use strict";var __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from==="object"||typeof from==="function"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toCommonJS=mod=>__copyProps(__defProp({},"__esModule",{value:true}),mod);var typings_exports={};__export(typings_exports,{DEFAULT_ALLOWED_PACKAGES:()=>DEFAULT_ALLOWED_PACKAGES,DEFAULT_CACHE_OPTIONS:()=>DEFAULT_CACHE_OPTIONS,DEFAULT_TYPE_CACHE_TTL:()=>DEFAULT_TYPE_CACHE_TTL,DEFAULT_TYPE_FETCHER_OPTIONS:()=>DEFAULT_TYPE_FETCHER_OPTIONS,MemoryTypeCache:()=>MemoryTypeCache,TYPE_CACHE_PREFIX:()=>TYPE_CACHE_PREFIX,TypeFetcher:()=>TypeFetcher,buildTypeFiles:()=>buildTypeFiles,combineDtsContents:()=>combineDtsContents,createTypeFetcher:()=>createTypeFetcher,dtsImportSchema:()=>dtsImportSchema,dtsImportTypeSchema:()=>dtsImportTypeSchema,dtsParseResultSchema:()=>dtsParseResultSchema,getPackageFromSpecifier:()=>getPackageFromSpecifier,getRelativeImportPath:()=>getRelativeImportPath,getSubpathFromSpecifier:()=>getSubpathFromSpecifier,globalTypeCache:()=>globalTypeCache,isRelativeImport:()=>isRelativeImport,packageResolutionSchema:()=>packageResolutionSchema,parseDtsImports:()=>parseDtsImports,parseImportStatement:()=>parseImportStatement,safeParseBatchRequest:()=>safeParseBatchRequest,safeParseTypeFetcherOptions:()=>safeParseTypeFetcherOptions,typeCacheEntrySchema:()=>typeCacheEntrySchema,typeCacheStatsSchema:()=>typeCacheStatsSchema,typeFetchBatchRequestSchema:()=>typeFetchBatchRequestSchema,typeFetchBatchResultSchema:()=>typeFetchBatchResultSchema,typeFetchErrorCodeSchema:()=>typeFetchErrorCodeSchema,typeFetchErrorSchema:()=>typeFetchErrorSchema,typeFetchResultSchema:()=>typeFetchResultSchema,typeFetcherOptionsSchema:()=>typeFetcherOptionsSchema,typeFileSchema:()=>typeFileSchema,urlToVirtualPath:()=>urlToVirtualPath,validateBatchRequest:()=>validateBatchRequest,validateTypeFetcherOptions:()=>validateTypeFetcherOptions});module.exports=__toCommonJS(typings_exports);var DEFAULT_ALLOWED_PACKAGES=["react","react-dom","react/jsx-runtime","zod","@frontmcp/*"];var DEFAULT_TYPE_FETCHER_OPTIONS={allowedPackages:[...DEFAULT_ALLOWED_PACKAGES],maxDepth:4,timeout:1e4,maxConcurrency:5,cdnBaseUrl:"https://esm.sh"};var TYPE_CACHE_PREFIX="types:";var DEFAULT_TYPE_CACHE_TTL=60*60*1e3;var import_lazy_zod=require("@frontmcp/lazy-zod");var typeFetchErrorCodeSchema=import_lazy_zod.z.enum(["NETWORK_ERROR","TIMEOUT","NO_TYPES_HEADER","INVALID_SPECIFIER","PACKAGE_NOT_FOUND","PARSE_ERROR"]);var typeFileSchema=import_lazy_zod.z.object({path:import_lazy_zod.z.string().min(1),url:import_lazy_zod.z.string(),content:import_lazy_zod.z.string()}).strict();var typeFetchResultSchema=import_lazy_zod.z.object({specifier:import_lazy_zod.z.string().min(1),resolvedPackage:import_lazy_zod.z.string().min(1),subpath:import_lazy_zod.z.string().optional(),version:import_lazy_zod.z.string().min(1),content:import_lazy_zod.z.string(),files:import_lazy_zod.z.array(typeFileSchema),fetchedUrls:import_lazy_zod.z.array(import_lazy_zod.z.string().url()),fetchedAt:import_lazy_zod.z.string().datetime()}).strict();var typeFetchErrorSchema=import_lazy_zod.z.object({specifier:import_lazy_zod.z.string().min(1),code:typeFetchErrorCodeSchema,message:import_lazy_zod.z.string().min(1),url:import_lazy_zod.z.string().url().optional()}).strict();var typeFetchBatchRequestSchema=import_lazy_zod.z.object({imports:import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)).min(1),maxDepth:import_lazy_zod.z.number().int().min(0).max(10).optional(),timeout:import_lazy_zod.z.number().int().min(1e3).max(6e4).optional(),maxConcurrency:import_lazy_zod.z.number().int().min(1).max(20).optional(),skipCache:import_lazy_zod.z.boolean().optional(),versionOverrides:import_lazy_zod.z.record(import_lazy_zod.z.string().min(1),import_lazy_zod.z.string().min(1)).optional()}).strict();var typeFetchBatchResultSchema=import_lazy_zod.z.object({results:import_lazy_zod.z.array(typeFetchResultSchema),errors:import_lazy_zod.z.array(typeFetchErrorSchema),totalTimeMs:import_lazy_zod.z.number().nonnegative(),cacheHits:import_lazy_zod.z.number().int().nonnegative(),networkRequests:import_lazy_zod.z.number().int().nonnegative()}).strict();var typeCacheEntrySchema=import_lazy_zod.z.object({result:typeFetchResultSchema,cachedAt:import_lazy_zod.z.number().int().positive(),size:import_lazy_zod.z.number().int().nonnegative(),accessCount:import_lazy_zod.z.number().int().nonnegative()}).strict();var typeCacheStatsSchema=import_lazy_zod.z.object({entries:import_lazy_zod.z.number().int().nonnegative(),totalSize:import_lazy_zod.z.number().nonnegative(),hits:import_lazy_zod.z.number().int().nonnegative(),misses:import_lazy_zod.z.number().int().nonnegative(),hitRate:import_lazy_zod.z.number().min(0).max(1)}).strict();var dtsImportTypeSchema=import_lazy_zod.z.enum(["import","export","reference","declare-module"]);var dtsImportSchema=import_lazy_zod.z.object({type:dtsImportTypeSchema,specifier:import_lazy_zod.z.string().min(1),statement:import_lazy_zod.z.string(),line:import_lazy_zod.z.number().int().positive()}).strict();var dtsParseResultSchema=import_lazy_zod.z.object({imports:import_lazy_zod.z.array(dtsImportSchema),externalPackages:import_lazy_zod.z.array(import_lazy_zod.z.string().min(1)),relativeImports:import_lazy_zod.z.array(import_lazy_zod.z.string())}).strict();var typeFetcherOptionsSchema=import_lazy_zod.z.object({maxDepth:import_lazy_zod.z.number().int().min(0).max(10).optional(),timeout:import_lazy_zod.z.number().int().min(1e3).max(6e4).optional(),maxConcurrency:import_lazy_zod.z.number().int().min(1).max(20).optional(),cdnBaseUrl:import_lazy_zod.z.string().url().optional()}).strict();var packageResolutionSchema=import_lazy_zod.z.object({packageName:import_lazy_zod.z.string().min(1),subpath:import_lazy_zod.z.string().optional(),version:import_lazy_zod.z.string().min(1),typesUrl:import_lazy_zod.z.string().url()}).strict();function validateBatchRequest(data){return typeFetchBatchRequestSchema.parse(data)}function safeParseBatchRequest(data){return typeFetchBatchRequestSchema.safeParse(data)}function validateTypeFetcherOptions(data){return typeFetcherOptionsSchema.parse(data)}function safeParseTypeFetcherOptions(data){return typeFetcherOptionsSchema.safeParse(data)}var DEFAULT_CACHE_OPTIONS={maxSize:500,defaultTtl:60*60*1e3,trackStats:true};var MemoryTypeCache=class{cache=new Map;maxSize;defaultTtl;trackStats;stats={hits:0,misses:0,evictions:0};constructor(options={}){const opts={...DEFAULT_CACHE_OPTIONS,...options};this.maxSize=opts.maxSize;this.defaultTtl=opts.defaultTtl;this.trackStats=opts.trackStats}async get(key){const internal=this.cache.get(key);if(!internal){if(this.trackStats)this.stats.misses++;return void 0}if(internal.expiresAt>0&&Date.now()>internal.expiresAt){this.cache.delete(key);if(this.trackStats)this.stats.misses++;return void 0}this.cache.delete(key);internal.entry.accessCount++;this.cache.set(key,internal);if(this.trackStats)this.stats.hits++;return internal.entry}async set(key,entry,ttl){if(this.cache.size>=this.maxSize&&!this.cache.has(key)){const oldestKey=this.cache.keys().next().value;if(oldestKey){this.cache.delete(oldestKey);if(this.trackStats)this.stats.evictions++}}const effectiveTtl=ttl??this.defaultTtl;const expiresAt=effectiveTtl>0?Date.now()+effectiveTtl:0;this.cache.set(key,{entry,expiresAt})}async has(key){const internal=this.cache.get(key);if(!internal)return false;if(internal.expiresAt>0&&Date.now()>internal.expiresAt){this.cache.delete(key);return false}return true}async delete(key){return this.cache.delete(key)}async clear(){this.cache.clear();this.stats={hits:0,misses:0,evictions:0}}async getStats(){let totalSize=0;for(const{entry}of this.cache.values()){totalSize+=entry.size}const total=this.stats.hits+this.stats.misses;return{entries:this.cache.size,totalSize,hits:this.stats.hits,misses:this.stats.misses,hitRate:total>0?this.stats.hits/total:0}}get size(){return this.cache.size}get evictions(){return this.stats.evictions}cleanup(){const now=Date.now();let cleaned=0;for(const[key,internal]of this.cache.entries()){if(internal.expiresAt>0&&now>internal.expiresAt){this.cache.delete(key);cleaned++}}return cleaned}};var globalTypeCache=new MemoryTypeCache({maxSize:500,defaultTtl:60*60*1e3});var IMPORT_PATTERN=/^import\s+(?:type\s+)?(?:(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+)?['"]([^'"]+)['"]/gm;var EXPORT_FROM_PATTERN=/^export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/gm;var REFERENCE_TYPES_PATTERN=/^\/\/\/\s*<reference\s+types\s*=\s*['"]([^'"]+)['"]\s*\/>/gm;var REFERENCE_PATH_PATTERN=/^\/\/\/\s*<reference\s+path\s*=\s*['"]([^'"]+)['"]\s*\/>/gm;var DECLARE_MODULE_PATTERN=/^declare\s+module\s+['"]([^'"]+)['"]/gm;function parseDtsImports(content){const imports=[];const externalPackages=new Set;const relativeImports=new Set;const lines=content.split("\n");for(let i=0;i<lines.length;i++){const line=lines[i];const lineNum=i+1;IMPORT_PATTERN.lastIndex=0;let match=IMPORT_PATTERN.exec(line);if(match){const specifier=match[1];imports.push({type:"import",specifier,statement:line.trim(),line:lineNum});categorizeSpecifier(specifier,externalPackages,relativeImports)}EXPORT_FROM_PATTERN.lastIndex=0;match=EXPORT_FROM_PATTERN.exec(line);if(match){const specifier=match[1];imports.push({type:"export",specifier,statement:line.trim(),line:lineNum});categorizeSpecifier(specifier,externalPackages,relativeImports)}REFERENCE_TYPES_PATTERN.lastIndex=0;match=REFERENCE_TYPES_PATTERN.exec(line);if(match){const specifier=match[1];imports.push({type:"reference",specifier,statement:line.trim(),line:lineNum});externalPackages.add(getPackageFromSpecifier(specifier))}REFERENCE_PATH_PATTERN.lastIndex=0;match=REFERENCE_PATH_PATTERN.exec(line);if(match){const specifier=match[1];imports.push({type:"reference",specifier,statement:line.trim(),line:lineNum});relativeImports.add(specifier)}DECLARE_MODULE_PATTERN.lastIndex=0;match=DECLARE_MODULE_PATTERN.exec(line);if(match){const specifier=match[1];imports.push({type:"declare-module",specifier,statement:line.trim(),line:lineNum})}}return{imports,externalPackages:Array.from(externalPackages),relativeImports:Array.from(relativeImports)}}function categorizeSpecifier(specifier,externalPackages,relativeImports){if(isRelativeImport(specifier)){relativeImports.add(specifier)}else{externalPackages.add(getPackageFromSpecifier(specifier))}}function isRelativeImport(specifier){return specifier.startsWith("./")||specifier.startsWith("../")||specifier.startsWith("/")||/^[A-Za-z]:/.test(specifier)}function getPackageFromSpecifier(specifier){if(specifier.startsWith("@")){const parts=specifier.split("/");if(parts.length>=2){return`${parts[0]}/${parts[1]}`}return specifier}const slashIndex=specifier.indexOf("/");if(slashIndex>0){return specifier.substring(0,slashIndex)}return specifier}function getSubpathFromSpecifier(specifier){const packageName=getPackageFromSpecifier(specifier);if(specifier.length>packageName.length+1){return specifier.substring(packageName.length+1)}return void 0}var MAX_IMPORT_STATEMENT_LENGTH=2e3;function parseImportStatement(statement){if(statement.length>MAX_IMPORT_STATEMENT_LENGTH){return null}const namedMatch=/import\s+(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+['"]([^'"]+)['"]/.exec(statement);if(namedMatch){return namedMatch[1]}const sideEffectMatch=/import\s+['"]([^'"]+)['"]/.exec(statement);if(sideEffectMatch){return sideEffectMatch[1]}return null}function combineDtsContents(contents){const seenReferences=new Set;const references=[];const declarations=[];for(const[url,content]of contents.entries()){const lines=content.split("\n");let inReferences=true;for(const line of lines){const trimmed=line.trim();if(trimmed.startsWith("///")){if(!seenReferences.has(trimmed)){seenReferences.add(trimmed);references.push(trimmed)}continue}if(inReferences&&trimmed===""){continue}inReferences=false;if(declarations.length===0||declarations[declarations.length-1]!==""){if(trimmed!==""){if(!declarations.some(d=>d.includes(`// Source: ${url}`))){declarations.push(`
2
+ // Source: ${url}`)}}}declarations.push(line)}}const parts=[];if(references.length>0){parts.push(references.join("\n"));parts.push("")}parts.push(declarations.join("\n").trim());return parts.join("\n")}var Semaphore=class{permits;waiting=[];constructor(permits){this.permits=permits}async acquire(){if(this.permits>0){this.permits--;return}return new Promise(resolve=>{this.waiting.push(resolve)})}release(){if(this.waiting.length>0){const next=this.waiting.shift();next?.()}else{this.permits++}}};var TypeFetcher=class{maxDepth;timeout;maxConcurrency;cdnBaseUrl;fetchFn;cache;allowedPatterns;allowlistEnabled;_initialized=false;constructor(options={},cache){this.maxDepth=options.maxDepth??2;this.timeout=options.timeout??1e4;this.maxConcurrency=options.maxConcurrency??5;this.cdnBaseUrl=options.cdnBaseUrl??"https://esm.sh";this.fetchFn=options.fetch??globalThis.fetch.bind(globalThis);this.cache=cache??globalTypeCache;if(options.allowedPackages===false){this.allowlistEnabled=false;this.allowedPatterns=[]}else{this.allowlistEnabled=true;this.allowedPatterns=[...DEFAULT_ALLOWED_PACKAGES,...options.allowedPackages??[]]}}isPackageAllowed(packageName){if(!this.allowlistEnabled){return true}return this.allowedPatterns.some(pattern=>{if(pattern.includes("*")){const escaped=pattern.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");const regex=new RegExp(`^${escaped}$`);return regex.test(packageName)}return packageName===pattern||packageName.startsWith(pattern+"/")})}async initialize(options){if(this._initialized){const stats2=await this.cache.getStats();return{loaded:[],failed:[],cached:stats2.entries}}const loaded=[];const failed=[];const packagesToLoad=this.allowedPatterns.filter(p=>!p.includes("*"));for(const pkg of packagesToLoad){const result=await this.fetchBatch({imports:[`import * from "${pkg}"`],timeout:options?.timeout??this.timeout});if(result.results.length>0){loaded.push(pkg)}else if(result.errors.length>0){failed.push(pkg)}}this._initialized=true;const stats=await this.cache.getStats();return{loaded,failed,cached:stats.entries}}get initialized(){return this._initialized}get allowedPackagePatterns(){return this.allowedPatterns}async fetchBatch(request){const startTime=Date.now();const results=[];const errors=[];let cacheHits=0;let networkRequests=0;const maxDepth=request.maxDepth??this.maxDepth;const timeout=request.timeout??this.timeout;const maxConcurrency=request.maxConcurrency??this.maxConcurrency;const skipCache=request.skipCache??false;const versionOverrides=request.versionOverrides??{};const semaphore=new Semaphore(maxConcurrency);const promises=request.imports.map(async importStatement=>{await semaphore.acquire();try{const specifier=parseImportStatement(importStatement);if(!specifier){errors.push({specifier:importStatement,code:"INVALID_SPECIFIER",message:`Could not parse import statement: ${importStatement}`});return}const packageName=getPackageFromSpecifier(specifier);if(!this.isPackageAllowed(packageName)){errors.push({specifier,code:"PACKAGE_NOT_ALLOWED",message:`Package "${packageName}" is not in the allowlist`});return}const version=versionOverrides[packageName]??"latest";const cacheKey=`${TYPE_CACHE_PREFIX}${packageName}@${version}`;if(!skipCache){const cached=await this.cache.get(cacheKey);if(cached){cacheHits++;results.push(cached.result);return}}const result=await this.fetchTypesForSpecifier(specifier,{maxDepth,timeout,version});if(result.success){results.push(result.data);networkRequests+=result.fetchCount;const entry={result:result.data,cachedAt:Date.now(),size:result.data.content.length,accessCount:1};await this.cache.set(cacheKey,entry)}else{errors.push(result.error);networkRequests+=result.fetchCount}}finally{semaphore.release()}});await Promise.all(promises);return{results,errors,totalTimeMs:Date.now()-startTime,cacheHits,networkRequests}}async fetchTypesForSpecifier(specifier,options){let fetchCount=0;const fetchedUrls=[];const visitedUrls=new Set;const contents=new Map;try{const resolution=await this.resolvePackage(specifier,options.version,options.timeout);if(!resolution){return{success:false,error:{specifier,code:"PACKAGE_NOT_FOUND",message:`Could not resolve package: ${specifier}`},fetchCount}}fetchCount++;const fetchResult=await this.fetchRecursive(resolution.typesUrl,options.maxDepth,options.timeout,visitedUrls,contents);fetchCount+=fetchResult.fetchCount;fetchedUrls.push(...fetchResult.fetchedUrls);if(!fetchResult.success){return{success:false,error:{specifier,code:fetchResult.errorCode,message:fetchResult.errorMessage??"Unknown error",url:fetchResult.errorUrl},fetchCount}}const files=buildTypeFiles(contents,resolution.packageName,resolution.version,resolution.subpath);const combinedContent=combineDtsContents(contents);const result={specifier,resolvedPackage:resolution.packageName,subpath:resolution.subpath,version:resolution.version,content:combinedContent,files,fetchedUrls,fetchedAt:new Date().toISOString()};return{success:true,data:result,fetchCount}}catch(error){return{success:false,error:{specifier,code:"NETWORK_ERROR",message:error instanceof Error?error.message:String(error)},fetchCount}}}async resolvePackage(specifier,version,timeout){const packageName=getPackageFromSpecifier(specifier);const subpath=getSubpathFromSpecifier(specifier);const versionSuffix=version==="latest"?"":`@${version}`;const baseUrl=`${this.cdnBaseUrl}/${packageName}${versionSuffix}`;const urlsToTry=subpath?[`${baseUrl}/${subpath}`,baseUrl]:[baseUrl];for(const url of urlsToTry){try{const response=await this.fetchWithTimeout(url,timeout,"HEAD");if(response.ok){const typesHeader=response.headers.get("X-TypeScript-Types");if(typesHeader){const typesUrl=typesHeader.startsWith("/")?`${this.cdnBaseUrl}${typesHeader}`:typesHeader;const versionMatch=/@(\d+\.\d+\.\d+[^/]*)/.exec(typesUrl);const resolvedVersion=versionMatch?versionMatch[1]:version;return{packageName,subpath,version:resolvedVersion,typesUrl}}}}catch{continue}}return null}async fetchRecursive(url,depth,timeout,visited,contents){if(visited.has(url)){return{success:true,fetchCount:0,fetchedUrls:[]}}visited.add(url);let fetchCount=1;const fetchedUrls=[url];try{const response=await this.fetchWithTimeout(url,timeout,"GET");if(!response.ok){return{success:false,fetchCount,fetchedUrls,errorCode:"NETWORK_ERROR",errorMessage:`HTTP ${response.status}: ${response.statusText}`,errorUrl:url}}const content=await response.text();contents.set(url,content);if(depth<=0){return{success:true,fetchCount,fetchedUrls}}const parsed=parseDtsImports(content);for(const pkg of parsed.externalPackages){if(pkg.startsWith("@types/")||isBuiltinModule(pkg)){continue}const resolution=await this.resolvePackage(pkg,"latest",timeout);fetchCount++;if(resolution&&!visited.has(resolution.typesUrl)){const result=await this.fetchRecursive(resolution.typesUrl,depth-1,timeout,visited,contents);fetchCount+=result.fetchCount;fetchedUrls.push(...result.fetchedUrls)}}for(const relativePath of parsed.relativeImports){const resolvedUrl=resolveRelativeUrl(url,relativePath);if(resolvedUrl&&!visited.has(resolvedUrl)){const result=await this.fetchRecursive(resolvedUrl,depth-1,timeout,visited,contents);fetchCount+=result.fetchCount;fetchedUrls.push(...result.fetchedUrls)}}return{success:true,fetchCount,fetchedUrls}}catch(error){const isTimeout=error instanceof Error&&error.message.includes("timeout");return{success:false,fetchCount,fetchedUrls,errorCode:isTimeout?"TIMEOUT":"NETWORK_ERROR",errorMessage:error instanceof Error?error.message:String(error),errorUrl:url}}}async fetchWithTimeout(url,timeout,method){const controller=new AbortController;const timeoutId=setTimeout(()=>controller.abort(),timeout);try{const response=await this.fetchFn(url,{method,signal:controller.signal,headers:{Accept:"application/typescript, text/plain, */*"}});return response}finally{clearTimeout(timeoutId)}}};function isBuiltinModule(name){const builtins=new Set(["assert","buffer","child_process","cluster","console","constants","crypto","dgram","dns","domain","events","fs","http","https","module","net","os","path","punycode","querystring","readline","repl","stream","string_decoder","sys","timers","tls","tty","url","util","v8","vm","zlib","node:assert","node:buffer","node:child_process","node:cluster","node:console","node:constants","node:crypto","node:dgram","node:dns","node:domain","node:events","node:fs","node:http","node:https","node:module","node:net","node:os","node:path","node:punycode","node:querystring","node:readline","node:repl","node:stream","node:string_decoder","node:sys","node:timers","node:tls","node:tty","node:url","node:util","node:v8","node:vm","node:zlib"]);return builtins.has(name)}function resolveRelativeUrl(base,relative){try{let path=relative;if(!path.endsWith(".d.ts")&&!path.endsWith(".ts")){path=`${path}.d.ts`}const resolved=new URL(path,base);return resolved.toString()}catch{return null}}function buildTypeFiles(contents,packageName,version,subpath){const files=[];for(const[url,content]of contents.entries()){const virtualPath=urlToVirtualPath(url,packageName,version);files.push({path:virtualPath,url,content})}if(subpath){const aliasPath=`node_modules/${packageName}/${subpath}/index.d.ts`;const aliasExists=files.some(f=>f.path===aliasPath);if(!aliasExists){const aliasContent=`// Auto-generated alias for ${packageName}/${subpath}
950
3
  export * from '${getRelativeImportPath(subpath)}';
951
- `;
952
- files.push({
953
- path: aliasPath,
954
- url: "",
955
- // No actual URL - this is synthesized
956
- content: aliasContent
957
- });
958
- }
959
- }
960
- return files;
961
- }
962
- function getRelativeImportPath(subpath) {
963
- const depth = subpath.split("/").length;
964
- const prefix = "../".repeat(depth);
965
- return `${prefix}index`;
966
- }
967
- function urlToVirtualPath(url, packageName, version) {
968
- try {
969
- const urlObj = new URL(url);
970
- const pathname = urlObj.pathname;
971
- const cleanPath = pathname.replace(/^\/v\d+\//, "/");
972
- const versionedPackage = `${packageName}@${version}`;
973
- const packageIndex = cleanPath.indexOf(versionedPackage);
974
- if (packageIndex !== -1) {
975
- const afterPackageVersion = cleanPath.substring(packageIndex + versionedPackage.length);
976
- const relativePath = afterPackageVersion.startsWith("/") ? afterPackageVersion.substring(1) : afterPackageVersion;
977
- return `node_modules/${packageName}/${relativePath || "index.d.ts"}`;
978
- }
979
- const packagePattern = new RegExp(`/${escapeRegExp(packageName)}@[^/]+(/.*)?$`);
980
- const match = pathname.match(packagePattern);
981
- if (match) {
982
- const filePath = match[1] ? match[1].substring(1) : "index.d.ts";
983
- return `node_modules/${packageName}/${filePath}`;
984
- }
985
- return `node_modules/${packageName}/${pathname.split("/").pop() || "index.d.ts"}`;
986
- } catch {
987
- return `node_modules/${packageName}/index.d.ts`;
988
- }
989
- }
990
- function escapeRegExp(string) {
991
- return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
992
- }
993
- function createTypeFetcher(options, cache) {
994
- return new TypeFetcher(options, cache);
995
- }
996
- // Annotate the CommonJS export names for ESM import in node:
997
- 0 && (module.exports = {
998
- DEFAULT_ALLOWED_PACKAGES,
999
- DEFAULT_CACHE_OPTIONS,
1000
- DEFAULT_TYPE_CACHE_TTL,
1001
- DEFAULT_TYPE_FETCHER_OPTIONS,
1002
- MemoryTypeCache,
1003
- TYPE_CACHE_PREFIX,
1004
- TypeFetcher,
1005
- buildTypeFiles,
1006
- combineDtsContents,
1007
- createTypeFetcher,
1008
- dtsImportSchema,
1009
- dtsImportTypeSchema,
1010
- dtsParseResultSchema,
1011
- getPackageFromSpecifier,
1012
- getRelativeImportPath,
1013
- getSubpathFromSpecifier,
1014
- globalTypeCache,
1015
- isRelativeImport,
1016
- packageResolutionSchema,
1017
- parseDtsImports,
1018
- parseImportStatement,
1019
- safeParseBatchRequest,
1020
- safeParseTypeFetcherOptions,
1021
- typeCacheEntrySchema,
1022
- typeCacheStatsSchema,
1023
- typeFetchBatchRequestSchema,
1024
- typeFetchBatchResultSchema,
1025
- typeFetchErrorCodeSchema,
1026
- typeFetchErrorSchema,
1027
- typeFetchResultSchema,
1028
- typeFetcherOptionsSchema,
1029
- typeFileSchema,
1030
- urlToVirtualPath,
1031
- validateBatchRequest,
1032
- validateTypeFetcherOptions
1033
- });
4
+ `;files.push({path:aliasPath,url:"",content:aliasContent})}}return files}function getRelativeImportPath(subpath){const depth=subpath.split("/").length;const prefix="../".repeat(depth);return`${prefix}index`}function urlToVirtualPath(url,packageName,version){try{const urlObj=new URL(url);const pathname=urlObj.pathname;const cleanPath=pathname.replace(/^\/v\d+\//,"/");const versionedPackage=`${packageName}@${version}`;const packageIndex=cleanPath.indexOf(versionedPackage);if(packageIndex!==-1){const afterPackageVersion=cleanPath.substring(packageIndex+versionedPackage.length);const relativePath=afterPackageVersion.startsWith("/")?afterPackageVersion.substring(1):afterPackageVersion;return`node_modules/${packageName}/${relativePath||"index.d.ts"}`}const packagePattern=new RegExp(`/${escapeRegExp(packageName)}@[^/]+(/.*)?$`);const match=pathname.match(packagePattern);if(match){const filePath=match[1]?match[1].substring(1):"index.d.ts";return`node_modules/${packageName}/${filePath}`}return`node_modules/${packageName}/${pathname.split("/").pop()||"index.d.ts"}`}catch{return`node_modules/${packageName}/index.d.ts`}}function escapeRegExp(string){return string.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function createTypeFetcher(options,cache){return new TypeFetcher(options,cache)}0&&(module.exports={DEFAULT_ALLOWED_PACKAGES,DEFAULT_CACHE_OPTIONS,DEFAULT_TYPE_CACHE_TTL,DEFAULT_TYPE_FETCHER_OPTIONS,MemoryTypeCache,TYPE_CACHE_PREFIX,TypeFetcher,buildTypeFiles,combineDtsContents,createTypeFetcher,dtsImportSchema,dtsImportTypeSchema,dtsParseResultSchema,getPackageFromSpecifier,getRelativeImportPath,getSubpathFromSpecifier,globalTypeCache,isRelativeImport,packageResolutionSchema,parseDtsImports,parseImportStatement,safeParseBatchRequest,safeParseTypeFetcherOptions,typeCacheEntrySchema,typeCacheStatsSchema,typeFetchBatchRequestSchema,typeFetchBatchResultSchema,typeFetchErrorCodeSchema,typeFetchErrorSchema,typeFetchResultSchema,typeFetcherOptionsSchema,typeFileSchema,urlToVirtualPath,validateBatchRequest,validateTypeFetcherOptions});