@kaoruisaac/pedelec 0.3.2 → 0.3.4

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/dist/vite.js ADDED
@@ -0,0 +1,1255 @@
1
+ import { createHash } from "node:crypto";
2
+ import { builtinModules, createRequire } from "node:module";
3
+ import { dirname, extname, isAbsolute, normalize, resolve as resolvePath } from "node:path";
4
+ import * as ts from "typescript";
5
+ import { build } from "vite";
6
+ import { PREPARED_DENO_MODULE_ARTIFACT_PROPERTY, } from "./deno-module-internal.js";
7
+ const PACKAGE_NAME = "@kaoruisaac/pedelec";
8
+ const DEFINE_DENO_MODULE_NAME = "defineDenoModule";
9
+ const ARTIFACT_HASH_VERSION = "pedelec-deno-module-artifact-v1";
10
+ const SCRIPT_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
11
+ const DECLARATION_LIKE_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".d.ts", ".json"]);
12
+ const LEGACY_NODE_BUILTIN_MODULES = new Set(builtinModules.filter((specifier) => !specifier.startsWith("node:")));
13
+ const NODE_BUILTIN_MODULES = new Set(builtinModules.map((specifier) => specifier.replace(/^node:/, "")));
14
+ const nodeRequire = createRequire(import.meta.url);
15
+ /**
16
+ * Vite build-time support for the static Deno module authoring API.
17
+ *
18
+ * The plugin deliberately keeps the generated module inside the transformed
19
+ * browser module. The SDK can consume the non-enumerable private artifact in
20
+ * a later transport phase without giving the runtime the original entry path.
21
+ */
22
+ export function pedelecVitePlugin() {
23
+ const ownersByDependency = new Map();
24
+ const dependenciesByOwner = new Map();
25
+ let resolvedConfig;
26
+ return {
27
+ name: "pedelec-deno-module",
28
+ enforce: "pre",
29
+ configResolved(config) {
30
+ resolvedConfig = config;
31
+ },
32
+ async transform(code, id) {
33
+ const sourceId = stripQueryAndHash(id);
34
+ if (!isTransformableScript(sourceId))
35
+ return null;
36
+ const sourceFile = parseSourceFile(code, sourceId);
37
+ const importedNames = findDenoModuleImportNames(sourceFile);
38
+ if (importedNames.size === 0)
39
+ return null;
40
+ const declarations = findDeclarations(sourceFile, importedNames);
41
+ if (declarations.length === 0)
42
+ return null;
43
+ const prepared = [];
44
+ const dependencies = new Set();
45
+ for (const declaration of declarations) {
46
+ const result = await prepareDeclaration(declaration, sourceId, this.resolve.bind(this), resolvedConfig);
47
+ prepared.push({ declaration, result });
48
+ for (const dependency of result.dependencies)
49
+ dependencies.add(dependency);
50
+ }
51
+ registerOwner(sourceId, dependencies, ownersByDependency, dependenciesByOwner);
52
+ const replacements = prepared.map(({ declaration, result }) => {
53
+ const objectSource = replaceSourceRange(code.slice(declaration.objectStart, declaration.objectEnd), declaration.entryStart - declaration.objectStart, declaration.entryEnd - declaration.objectStart, "undefined");
54
+ const artifactSource = JSON.stringify(result.artifact);
55
+ const replacement = [
56
+ "(() => {",
57
+ `const __pedelecModule = ${objectSource};`,
58
+ // The authoring entry is a source-tree path. It is intentionally
59
+ // removed before the object can reach any SDK transport code.
60
+ "__pedelecModule.entry = undefined;",
61
+ `Object.defineProperty(__pedelecModule, ${JSON.stringify(PREPARED_DENO_MODULE_ARTIFACT_PROPERTY)}, {`,
62
+ `value: Object.freeze(${artifactSource}), enumerable: false, writable: false, configurable: false`,
63
+ "});",
64
+ "return __pedelecModule;",
65
+ "})()",
66
+ ].join("\n");
67
+ return {
68
+ start: declaration.callStart,
69
+ end: declaration.callEnd,
70
+ replacement,
71
+ };
72
+ });
73
+ let transformed = code;
74
+ for (const replacement of replacements.sort((a, b) => b.start - a.start)) {
75
+ transformed = transformed.slice(0, replacement.start) + replacement.replacement + transformed.slice(replacement.end);
76
+ }
77
+ return {
78
+ code: transformed,
79
+ map: null,
80
+ };
81
+ },
82
+ handleHotUpdate(context) {
83
+ return invalidateOwners(context, ownersByDependency);
84
+ },
85
+ };
86
+ }
87
+ async function prepareDeclaration(declaration, importer, resolveModule, config) {
88
+ const entry = await resolveEntry(declaration, importer, resolveModule);
89
+ const diagnosticPrefix = `Deno module "${declaration.name}" entry "${declaration.entry}" imported by "${importer}"`;
90
+ let runtimeBundle;
91
+ try {
92
+ runtimeBundle = await bundleRuntime(entry, resolveModule, config);
93
+ }
94
+ catch (error) {
95
+ throw new Error(`${diagnosticPrefix}: runtime bundling failed: ${formatError(error)}`);
96
+ }
97
+ let declarationBundle;
98
+ try {
99
+ declarationBundle = await bundleDeclarations(entry, declaration.entry, importer, diagnosticPrefix, resolveModule, config);
100
+ }
101
+ catch (error) {
102
+ throw new Error(`${diagnosticPrefix}: declaration generation failed: ${formatError(error)}`);
103
+ }
104
+ if (!hasMeaningfulDeclarationSurface(declarationBundle.source)) {
105
+ throw new Error(`${diagnosticPrefix}: declaration generation produced no meaningful public exports`);
106
+ }
107
+ const normalizedRuntime = ensureSelfTypesDirective(stripBundlerLocationComments(runtimeBundle.source));
108
+ const normalizedTypes = normalizeDeclarationSource(declarationBundle.source);
109
+ validateRolledUpDeclaration(normalizedTypes, diagnosticPrefix);
110
+ const contentHash = createContentHash(normalizedRuntime, normalizedTypes);
111
+ const dependencies = new Set([...runtimeBundle.files, ...declarationBundle.files, entry]);
112
+ return {
113
+ artifact: {
114
+ format: "esm",
115
+ runtimeSource: normalizedRuntime,
116
+ typesSource: normalizedTypes,
117
+ contentHash,
118
+ },
119
+ dependencies: new Set([...dependencies].map(normalizeFile)),
120
+ };
121
+ }
122
+ async function resolveEntry(declaration, importer, resolveModule) {
123
+ if (isRemoteOrSchemeEntry(declaration.entry)) {
124
+ throw new Error(`Deno module "${declaration.name}" entry "${declaration.entry}" is not a local or package specifier; remote and scheme URLs are not supported`);
125
+ }
126
+ let result;
127
+ try {
128
+ result = await resolveHostModule(declaration.entry, importer, resolveModule);
129
+ }
130
+ catch (error) {
131
+ throw new Error(`could not resolve entry "${declaration.entry}" for Deno module "${declaration.name}" from "${importer}": ${formatError(error)}`);
132
+ }
133
+ if (!result || result.external || result.id.startsWith("\0")) {
134
+ throw new Error(`could not resolve entry "${declaration.entry}" for Deno module "${declaration.name}" from "${importer}"`);
135
+ }
136
+ return stripQueryAndHash(result.id);
137
+ }
138
+ async function bundleRuntime(entry, resolveModule, config) {
139
+ const resolverPlugin = {
140
+ name: "pedelec-deno-module-host-resolver",
141
+ enforce: "pre",
142
+ async resolveId(source, importer) {
143
+ const builtin = canonicalBuiltinSpecifier(source);
144
+ if (builtin)
145
+ return { id: builtin, external: true };
146
+ if (!importer || source.startsWith("\0"))
147
+ return null;
148
+ const resolved = await resolveHostModule(source, importer, resolveModule);
149
+ if (!resolved) {
150
+ throw new Error(`unresolved runtime dependency "${source}" from "${importer}"`);
151
+ }
152
+ if (resolved.external) {
153
+ throw new Error(`runtime dependency "${source}" from "${importer}" resolved as external`);
154
+ }
155
+ return resolved.id;
156
+ },
157
+ };
158
+ const result = await build({
159
+ configFile: false,
160
+ root: config?.root ?? dirname(entry),
161
+ publicDir: false,
162
+ logLevel: "silent",
163
+ plugins: [resolverPlugin],
164
+ resolve: {
165
+ // The outer Vite project owns aliases and plugin resolution. The small
166
+ // resolver plugin above forwards those decisions into this nested build.
167
+ conditions: config?.resolve.conditions,
168
+ mainFields: config?.resolve.mainFields,
169
+ },
170
+ build: {
171
+ write: false,
172
+ emptyOutDir: false,
173
+ minify: "oxc",
174
+ target: "esnext",
175
+ sourcemap: false,
176
+ cssCodeSplit: false,
177
+ lib: {
178
+ entry,
179
+ formats: ["es"],
180
+ fileName: () => "index.mjs",
181
+ },
182
+ rollupOptions: {
183
+ input: entry,
184
+ output: {
185
+ format: "es",
186
+ codeSplitting: false,
187
+ entryFileNames: "index.mjs",
188
+ chunkFileNames: "index-[hash].mjs",
189
+ assetFileNames: "index-[hash][extname]",
190
+ },
191
+ },
192
+ },
193
+ });
194
+ const outputBundles = Array.isArray(result) ? result : [result];
195
+ const bundles = outputBundles.filter((item) => "output" in item);
196
+ if (bundles.length !== outputBundles.length) {
197
+ throw new Error("bundler returned a watcher instead of an output bundle");
198
+ }
199
+ const outputs = bundles.flatMap((item) => item.output);
200
+ const chunks = outputs.filter((item) => item.type === "chunk");
201
+ const extraOutputs = outputs.filter((item) => item.type !== "chunk");
202
+ if (extraOutputs.length > 0) {
203
+ throw new Error(`runtime bundle produced additional outputs besides a single ESM chunk: ${extraOutputs
204
+ .map((item) => "fileName" in item ? String(item.fileName) : "unknown")
205
+ .join(", ")}`);
206
+ }
207
+ if (chunks.length !== 1) {
208
+ throw new Error(`runtime bundle produced ${chunks.length} chunks; code-splitting and secondary runtime chunks are not supported`);
209
+ }
210
+ const entryChunk = chunks[0];
211
+ if (!entryChunk.isEntry) {
212
+ throw new Error("bundler did not produce an ESM entry chunk");
213
+ }
214
+ const invalidImports = entryChunk.imports.filter((specifier) => !isCanonicalBuiltinSpecifier(specifier));
215
+ if (invalidImports.length > 0) {
216
+ throw new Error(`runtime bundle left unresolved external dependencies: ${invalidImports.join(", ")}`);
217
+ }
218
+ const invalidDynamicImports = entryChunk.dynamicImports.filter((specifier) => !isCanonicalBuiltinSpecifier(specifier));
219
+ if (invalidDynamicImports.length > 0) {
220
+ throw new Error(`runtime bundle left unresolved dynamic imports: ${invalidDynamicImports.join(", ")}`);
221
+ }
222
+ const leftoverModules = leftoverRuntimeModuleSpecifiers(entryChunk.code).filter((specifier) => !isCanonicalBuiltinSpecifier(specifier));
223
+ if (leftoverModules.length > 0) {
224
+ throw new Error(`runtime bundle left unresolved module specifiers: ${leftoverModules.join(", ")}`);
225
+ }
226
+ const files = new Set();
227
+ for (const id of entryChunk.moduleIds) {
228
+ const file = stripQueryAndHash(id);
229
+ if (!isWatchableSourceFile(file))
230
+ continue;
231
+ files.add(normalizeFile(file));
232
+ }
233
+ return { source: entryChunk.code, files };
234
+ }
235
+ async function resolveHostModule(source, importer, resolveModule) {
236
+ const resolved = await resolveModule(source, importer, { skipSelf: true });
237
+ const resolvedFile = resolved ? stripQueryAndHash(resolved.id) : null;
238
+ const needsPackageFallback = Boolean(isBareSpecifier(source) &&
239
+ resolved &&
240
+ (isOptimizedDependencyPath(resolved.id) || resolved.external || !ts.sys.fileExists(resolvedFile)));
241
+ if (!needsPackageFallback)
242
+ return resolved;
243
+ try {
244
+ return { id: nodeRequire.resolve(source, { paths: [dirname(importer)] }) };
245
+ }
246
+ catch {
247
+ return resolved;
248
+ }
249
+ }
250
+ async function bundleDeclarations(runtimeEntry, specifier, importer, diagnosticPrefix, resolveModule, config) {
251
+ const aliasOptions = createTypeScriptAliasOptions(config);
252
+ const configFile = ts.findConfigFile(dirname(runtimeEntry), ts.sys.fileExists, "tsconfig.json");
253
+ const baseOptions = configFile
254
+ ? ts.parseJsonConfigFileContent(ts.readConfigFile(configFile, ts.sys.readFile).config, ts.sys, dirname(configFile)).options
255
+ : {};
256
+ const options = {
257
+ ...baseOptions,
258
+ ...aliasOptions,
259
+ baseUrl: aliasOptions.baseUrl ?? baseOptions.baseUrl,
260
+ paths: { ...baseOptions.paths, ...aliasOptions.paths },
261
+ allowJs: true,
262
+ checkJs: false,
263
+ declaration: true,
264
+ emitDeclarationOnly: true,
265
+ declarationMap: false,
266
+ noEmit: false,
267
+ noEmitOnError: false,
268
+ isolatedDeclarations: false,
269
+ module: ts.ModuleKind.ESNext,
270
+ moduleResolution: ts.ModuleResolutionKind.Bundler,
271
+ target: ts.ScriptTarget.ES2022,
272
+ skipLibCheck: true,
273
+ types: [],
274
+ typeRoots: [],
275
+ outDir: undefined,
276
+ rootDir: undefined,
277
+ };
278
+ const host = ts.createCompilerHost(options);
279
+ const typesEntry = resolveTypesEntry(runtimeEntry, specifier, importer, options, host);
280
+ const resolutionCache = new Map();
281
+ const sourceFiles = new Set([normalizeFile(typesEntry)]);
282
+ // Local/module-owned declarations may reference more module-owned files. Once
283
+ // traversal enters a package, keep it inside that package instead of crawling
284
+ // the declarations of that package's own dependencies.
285
+ const queue = [{
286
+ fileName: normalizeFile(typesEntry),
287
+ packageBoundary: nodeModulesPackageRoot(typesEntry),
288
+ }];
289
+ while (queue.length > 0) {
290
+ const { fileName, packageBoundary } = queue.pop();
291
+ const source = readFileIfAvailable(fileName);
292
+ if (source === null) {
293
+ throw new Error(`${diagnosticPrefix}: could not read declaration source "${fileName}"`);
294
+ }
295
+ const sourceFile = parseSourceFile(source, fileName);
296
+ for (const moduleSpecifier of collectModuleSpecifiers(sourceFile)) {
297
+ if (isBuiltinSpecifier(moduleSpecifier))
298
+ continue;
299
+ if (!canResolveDeclarationDependency(moduleSpecifier, packageBoundary))
300
+ continue;
301
+ const resolved = await resolveDeclarationDependency(moduleSpecifier, fileName, options, host, resolveModule);
302
+ if (!resolved) {
303
+ throw new Error(`${diagnosticPrefix}: public declaration still depends on unresolved module "${moduleSpecifier}"`);
304
+ }
305
+ const resolvedPackageBoundary = nodeModulesPackageRoot(resolved);
306
+ if (packageBoundary !== null && resolvedPackageBoundary !== packageBoundary)
307
+ continue;
308
+ resolutionCache.set(resolutionKey(fileName, moduleSpecifier), resolved);
309
+ if (!sourceFiles.has(resolved)) {
310
+ sourceFiles.add(resolved);
311
+ if (packageBoundary === null || resolvedPackageBoundary === packageBoundary) {
312
+ queue.push({
313
+ fileName: resolved,
314
+ packageBoundary: resolvedPackageBoundary,
315
+ });
316
+ }
317
+ }
318
+ }
319
+ }
320
+ host.resolveModuleNameLiterals = (moduleLiterals, containingFile, redirectedReference, compilerOptions) => {
321
+ return moduleLiterals.map((literal) => {
322
+ const cached = resolutionCache.get(resolutionKey(containingFile, literal.text));
323
+ if (cached)
324
+ return { resolvedModule: toResolvedModule(cached) };
325
+ const packageBoundary = nodeModulesPackageRoot(containingFile);
326
+ if (isBuiltinSpecifier(literal.text) || !canResolveDeclarationDependency(literal.text, packageBoundary)) {
327
+ return { resolvedModule: undefined };
328
+ }
329
+ const resolved = ts.resolveModuleName(literal.text, containingFile, compilerOptions, host, undefined, redirectedReference);
330
+ if (packageBoundary !== null &&
331
+ resolved.resolvedModule &&
332
+ nodeModulesPackageRoot(resolved.resolvedModule.resolvedFileName) !== packageBoundary) {
333
+ return { resolvedModule: undefined };
334
+ }
335
+ return resolved;
336
+ });
337
+ };
338
+ const program = ts.createProgram([typesEntry], options, host);
339
+ const diagnostics = ts
340
+ .getPreEmitDiagnostics(program)
341
+ .filter((item) => item.category === ts.DiagnosticCategory.Error)
342
+ // Node types are not required when an implementation-only import disappears
343
+ // from declaration emit. If it survives, roll-up validation below rejects it.
344
+ .filter((item) => !isDeferredBuiltinResolutionDiagnostic(item));
345
+ if (diagnostics.length > 0) {
346
+ throw new Error(formatDiagnostics(diagnostics));
347
+ }
348
+ const emitted = new Map();
349
+ const emitResult = program.emit(undefined, (fileName, text) => emitted.set(normalizeFile(fileName), text), undefined, true);
350
+ if (emitResult.diagnostics.some((item) => item.category === ts.DiagnosticCategory.Error)) {
351
+ throw new Error(formatDiagnostics(emitResult.diagnostics));
352
+ }
353
+ const declarationSources = new Map();
354
+ for (const sourceFile of program.getSourceFiles()) {
355
+ const fileName = normalizeFile(sourceFile.fileName);
356
+ if (isTypeScriptLib(fileName) || isIgnoredProgramFile(fileName))
357
+ continue;
358
+ if (sourceFile.isDeclarationFile) {
359
+ declarationSources.set(fileName, stripDeclarationSourceMap(sourceFile.text));
360
+ }
361
+ }
362
+ for (const [fileName, text] of emitted) {
363
+ if (fileName.endsWith(".d.ts") && text.length > 0) {
364
+ declarationSources.set(fileName, stripDeclarationSourceMap(text));
365
+ }
366
+ }
367
+ const rootDeclaration = lookupDeclarationSourceKey(typesEntry, declarationSources);
368
+ if (!rootDeclaration) {
369
+ throw new Error(`TypeScript did not emit a declaration file for ${typesEntry}`);
370
+ }
371
+ const source = rollupDeclarationModules(rootDeclaration, declarationSources, options, host, diagnosticPrefix);
372
+ const files = new Set();
373
+ for (const fileName of sourceFiles)
374
+ files.add(fileName);
375
+ for (const sourceFile of program.getSourceFiles()) {
376
+ const fileName = normalizeFile(sourceFile.fileName);
377
+ if (isTypeScriptLib(fileName) || isIgnoredProgramFile(fileName))
378
+ continue;
379
+ if (isWatchableSourceFile(fileName))
380
+ files.add(fileName);
381
+ }
382
+ return { source, files };
383
+ }
384
+ function resolveTypesEntry(runtimeEntry, specifier, importer, options, host) {
385
+ if (isDeclarationSourcePath(runtimeEntry))
386
+ return normalizeFile(runtimeEntry);
387
+ const resolved = ts.resolveModuleName(specifier, importer, options, host);
388
+ const fromTypeScript = resolved.resolvedModule?.resolvedFileName;
389
+ if (fromTypeScript && !isTypeScriptLib(fromTypeScript))
390
+ return normalizeFile(fromTypeScript);
391
+ const adjacent = adjacentDeclarationPath(runtimeEntry);
392
+ if (adjacent && ts.sys.fileExists(adjacent))
393
+ return normalizeFile(adjacent);
394
+ const fromPackage = typesFromPackageMetadata(runtimeEntry, specifier);
395
+ if (fromPackage)
396
+ return fromPackage;
397
+ throw new Error(`could not resolve a declaration file for "${specifier}"`);
398
+ }
399
+ function typesFromPackageMetadata(runtimeEntry, specifier) {
400
+ if (!isNodeModulesPath(runtimeEntry))
401
+ return null;
402
+ let directory = dirname(runtimeEntry);
403
+ while (true) {
404
+ const packageJsonPath = resolvePath(directory, "package.json");
405
+ const contents = readFileIfAvailable(packageJsonPath);
406
+ if (contents) {
407
+ try {
408
+ const parsed = JSON.parse(contents);
409
+ const subpath = packageSubpath(specifier, typeof parsed.name === "string" ? parsed.name : null);
410
+ const fromExports = subpath === null ? null : typesFromExportsField(parsed.exports, subpath, directory);
411
+ if (fromExports)
412
+ return fromExports;
413
+ if (subpath === ".") {
414
+ const typeEntry = typeof parsed.types === "string" ? parsed.types : typeof parsed.typings === "string" ? parsed.typings : null;
415
+ if (typeEntry) {
416
+ const declaration = resolvePath(directory, typeEntry);
417
+ if (ts.sys.fileExists(declaration))
418
+ return normalizeFile(declaration);
419
+ }
420
+ }
421
+ }
422
+ catch {
423
+ // Malformed package metadata should not hide a later enclosing package.
424
+ }
425
+ }
426
+ const parent = dirname(directory);
427
+ if (parent === directory)
428
+ break;
429
+ directory = parent;
430
+ }
431
+ return null;
432
+ }
433
+ function packageSubpath(specifier, packageName) {
434
+ if (!packageName)
435
+ return null;
436
+ if (specifier === packageName)
437
+ return ".";
438
+ const prefix = `${packageName}/`;
439
+ if (specifier.startsWith(prefix))
440
+ return `./${specifier.slice(prefix.length)}`;
441
+ return null;
442
+ }
443
+ function typesFromExportsField(exportsField, subpath, packageDirectory) {
444
+ if (typeof exportsField === "string") {
445
+ return subpath === "." ? resolveExportTarget(exportsField, packageDirectory) : null;
446
+ }
447
+ if (!exportsField || typeof exportsField !== "object" || Array.isArray(exportsField))
448
+ return null;
449
+ const mapping = exportsField;
450
+ const target = mapping[subpath] ?? (subpath === "." ? mapping["."] : undefined);
451
+ return resolveExportTarget(target, packageDirectory);
452
+ }
453
+ function resolveExportTarget(target, packageDirectory) {
454
+ if (typeof target === "string") {
455
+ const file = resolvePath(packageDirectory, target);
456
+ return ts.sys.fileExists(file) ? normalizeFile(file) : null;
457
+ }
458
+ if (Array.isArray(target)) {
459
+ for (const item of target) {
460
+ const resolved = resolveExportTarget(item, packageDirectory);
461
+ if (resolved)
462
+ return resolved;
463
+ }
464
+ return null;
465
+ }
466
+ if (!target || typeof target !== "object")
467
+ return null;
468
+ const conditions = target;
469
+ for (const condition of ["types", "typings", "import", "default"]) {
470
+ if (condition in conditions) {
471
+ const resolved = resolveExportTarget(conditions[condition], packageDirectory);
472
+ if (resolved) {
473
+ if (condition === "types" || condition === "typings" || resolved.endsWith(".d.ts") || isDeclarationSourcePath(resolved)) {
474
+ return resolved;
475
+ }
476
+ const adjacent = adjacentDeclarationPath(resolved);
477
+ if (adjacent && ts.sys.fileExists(adjacent))
478
+ return normalizeFile(adjacent);
479
+ }
480
+ }
481
+ }
482
+ return null;
483
+ }
484
+ async function resolveDeclarationDependency(specifier, importer, options, host, resolveModule) {
485
+ const fromTypeScript = ts.resolveModuleName(specifier, importer, options, host).resolvedModule?.resolvedFileName;
486
+ if (fromTypeScript && !isTypeScriptLib(fromTypeScript) && isDeclarationLikePath(fromTypeScript)) {
487
+ return normalizeFile(fromTypeScript);
488
+ }
489
+ const viteResolved = await resolveHostModule(specifier, importer, resolveModule);
490
+ if (!viteResolved || viteResolved.external)
491
+ return null;
492
+ const resolvedId = stripQueryAndHash(viteResolved.id);
493
+ if (!isDeclarationLikePath(resolvedId))
494
+ return null;
495
+ if (isDeclarationSourcePath(resolvedId))
496
+ return normalizeFile(resolvedId);
497
+ const typesEntry = (() => {
498
+ try {
499
+ return resolveTypesEntry(resolvedId, specifier, importer, options, host);
500
+ }
501
+ catch {
502
+ const adjacent = adjacentDeclarationPath(resolvedId);
503
+ return adjacent && ts.sys.fileExists(adjacent) ? normalizeFile(adjacent) : null;
504
+ }
505
+ })();
506
+ return typesEntry;
507
+ }
508
+ function rollupDeclarationModules(rootFile, sources, options, host, diagnosticPrefix) {
509
+ const files = collectDeclarationGraph(rootFile, sources, options, host, diagnosticPrefix);
510
+ const namespaceNames = new Map();
511
+ let namespaceCount = 0;
512
+ for (const fileName of files) {
513
+ if (fileName === rootFile)
514
+ continue;
515
+ namespaceNames.set(fileName, `__PedelecDts_${namespaceCount++}`);
516
+ }
517
+ const exportedNames = computeExportedNames(files, sources, options, host, diagnosticPrefix);
518
+ const namespaceBlocks = [];
519
+ for (const fileName of files) {
520
+ if (fileName === rootFile)
521
+ continue;
522
+ namespaceBlocks.push(emitNamespaceModule(fileName, namespaceNames.get(fileName), sources, namespaceNames, exportedNames, options, host, diagnosticPrefix));
523
+ }
524
+ const rootSource = emitRootModule(rootFile, sources, namespaceNames, exportedNames, options, host, diagnosticPrefix);
525
+ const combined = [...namespaceBlocks.filter(Boolean), rootSource].join("\n").trim();
526
+ assertNoExternalModuleSpecifiers(combined, diagnosticPrefix);
527
+ return combined;
528
+ }
529
+ function collectDeclarationGraph(rootFile, sources, options, host, diagnosticPrefix) {
530
+ const ordered = [];
531
+ const visiting = new Set();
532
+ const visited = new Set();
533
+ const visit = (fileName) => {
534
+ if (visited.has(fileName) || visiting.has(fileName))
535
+ return;
536
+ visiting.add(fileName);
537
+ const source = sources.get(fileName);
538
+ if (source === undefined) {
539
+ throw new Error(`${diagnosticPrefix}: missing declaration source for "${fileName}"`);
540
+ }
541
+ const sourceFile = ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
542
+ const packageBoundary = nodeModulesPackageRoot(fileName);
543
+ for (const specifier of collectModuleSpecifiers(sourceFile)) {
544
+ if (!canResolveDeclarationDependency(specifier, packageBoundary)) {
545
+ throw new Error(`${diagnosticPrefix}: public declaration still depends on unresolved module "${specifier}"`);
546
+ }
547
+ const resolved = resolveExistingDeclaration(specifier, fileName, sources, options, host);
548
+ if (!resolved || packageBoundary !== null && nodeModulesPackageRoot(resolved) !== packageBoundary) {
549
+ throw new Error(`${diagnosticPrefix}: public declaration still depends on unresolved module "${specifier}"`);
550
+ }
551
+ visit(resolved);
552
+ }
553
+ visiting.delete(fileName);
554
+ visited.add(fileName);
555
+ ordered.push(fileName);
556
+ };
557
+ visit(rootFile);
558
+ return ordered;
559
+ }
560
+ function computeExportedNames(files, sources, options, host, diagnosticPrefix) {
561
+ const exportsByFile = new Map();
562
+ const starExports = new Map();
563
+ for (const fileName of files) {
564
+ const names = new Set();
565
+ const stars = [];
566
+ const sourceFile = ts.createSourceFile(fileName, sources.get(fileName), ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
567
+ for (const statement of sourceFile.statements) {
568
+ if (ts.isExportDeclaration(statement)) {
569
+ if (statement.moduleSpecifier && ts.isStringLiteral(statement.moduleSpecifier) && !statement.exportClause) {
570
+ const resolved = resolveExistingDeclaration(statement.moduleSpecifier.text, fileName, sources, options, host);
571
+ if (!resolved) {
572
+ throw new Error(`${diagnosticPrefix}: public declaration still depends on unresolved module "${statement.moduleSpecifier.text}"`);
573
+ }
574
+ stars.push(resolved);
575
+ continue;
576
+ }
577
+ if (statement.exportClause && ts.isNamedExports(statement.exportClause)) {
578
+ for (const element of statement.exportClause.elements)
579
+ names.add(element.name.text);
580
+ }
581
+ continue;
582
+ }
583
+ if (ts.isExportAssignment(statement)) {
584
+ names.add("default");
585
+ continue;
586
+ }
587
+ if (hasExportModifier(statement)) {
588
+ const name = declarationName(statement);
589
+ if (name)
590
+ names.add(name);
591
+ if (hasDefaultModifier(statement))
592
+ names.add("default");
593
+ }
594
+ }
595
+ exportsByFile.set(fileName, names);
596
+ starExports.set(fileName, stars);
597
+ }
598
+ let changed = true;
599
+ while (changed) {
600
+ changed = false;
601
+ for (const fileName of files) {
602
+ const names = exportsByFile.get(fileName);
603
+ for (const dependency of starExports.get(fileName) ?? []) {
604
+ for (const name of exportsByFile.get(dependency) ?? []) {
605
+ if (name === "default" || names.has(name))
606
+ continue;
607
+ names.add(name);
608
+ changed = true;
609
+ }
610
+ }
611
+ }
612
+ }
613
+ return exportsByFile;
614
+ }
615
+ function emitNamespaceModule(fileName, namespaceName, sources, namespaceNames, exportedNames, options, host, diagnosticPrefix) {
616
+ const body = emitModuleBody(fileName, sources, namespaceNames, exportedNames, options, host, diagnosticPrefix, true);
617
+ if (!body.trim())
618
+ return `declare namespace ${namespaceName} {\n}\n`;
619
+ return `declare namespace ${namespaceName} {\n${indentBlock(body)}\n}\n`;
620
+ }
621
+ function emitRootModule(fileName, sources, namespaceNames, exportedNames, options, host, diagnosticPrefix) {
622
+ return emitModuleBody(fileName, sources, namespaceNames, exportedNames, options, host, diagnosticPrefix, false);
623
+ }
624
+ function emitModuleBody(fileName, sources, namespaceNames, exportedNames, options, host, diagnosticPrefix, inNamespace) {
625
+ const sourceFile = ts.createSourceFile(fileName, sources.get(fileName), ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
626
+ const parts = [];
627
+ for (const statement of sourceFile.statements) {
628
+ if (ts.isImportDeclaration(statement) || ts.isExportDeclaration(statement) && statement.moduleSpecifier) {
629
+ parts.push(...rewriteModuleStatement(statement, fileName, sourceFile, sources, namespaceNames, exportedNames, options, host, diagnosticPrefix));
630
+ continue;
631
+ }
632
+ if (ts.isImportEqualsDeclaration(statement) && statement.moduleReference && ts.isExternalModuleReference(statement.moduleReference)) {
633
+ throw new Error(`${diagnosticPrefix}: CommonJS import= declarations cannot be bundled into a standalone declaration`);
634
+ }
635
+ if (ts.isExportAssignment(statement) && statement.isExportEquals) {
636
+ throw new Error(`${diagnosticPrefix}: CommonJS export= declarations cannot be bundled into a standalone declaration`);
637
+ }
638
+ const text = statementText(statement, sourceFile);
639
+ if (inNamespace && ts.isExportAssignment(statement) && ts.isIdentifier(statement.expression)) {
640
+ parts.push(`export { ${statement.expression.text} as default };`);
641
+ continue;
642
+ }
643
+ if (inNamespace && hasDefaultModifier(statement)) {
644
+ const name = declarationName(statement);
645
+ if (!name) {
646
+ throw new Error(`${diagnosticPrefix}: anonymous default export cannot be bundled into a standalone declaration`);
647
+ }
648
+ parts.push(adjustDeclarationForNamespace(text));
649
+ parts.push(`export { ${name} as default };`);
650
+ continue;
651
+ }
652
+ parts.push(inNamespace ? adjustDeclarationForNamespace(text) : text);
653
+ }
654
+ return parts.filter((part) => part.trim().length > 0).join("\n");
655
+ }
656
+ function rewriteModuleStatement(statement, fileName, sourceFile, sources, namespaceNames, exportedNames, options, host, diagnosticPrefix) {
657
+ const specifier = statement.moduleSpecifier && ts.isStringLiteral(statement.moduleSpecifier)
658
+ ? statement.moduleSpecifier.text
659
+ : null;
660
+ if (!specifier)
661
+ return [statementText(statement, sourceFile)];
662
+ const resolved = resolveExistingDeclaration(specifier, fileName, sources, options, host);
663
+ if (!resolved) {
664
+ throw new Error(`${diagnosticPrefix}: public declaration still depends on unresolved module "${specifier}"`);
665
+ }
666
+ const namespaceName = namespaceNames.get(resolved);
667
+ if (!namespaceName) {
668
+ throw new Error(`${diagnosticPrefix}: could not inline declaration module "${specifier}"`);
669
+ }
670
+ if (ts.isImportDeclaration(statement)) {
671
+ return rewriteImportDeclaration(statement, namespaceName, diagnosticPrefix);
672
+ }
673
+ return rewriteExportDeclaration(statement, namespaceName, exportedNames.get(resolved) ?? new Set(), diagnosticPrefix);
674
+ }
675
+ function rewriteImportDeclaration(statement, namespaceName, diagnosticPrefix) {
676
+ if (!statement.importClause) {
677
+ throw new Error(`${diagnosticPrefix}: side-effect imports cannot be bundled into a standalone declaration`);
678
+ }
679
+ const lines = [];
680
+ const clause = statement.importClause;
681
+ if (clause.name) {
682
+ lines.push(`import ${clause.name.text} = ${namespaceName}.default;`);
683
+ }
684
+ const bindings = clause.namedBindings;
685
+ if (bindings && ts.isNamespaceImport(bindings)) {
686
+ lines.push(`import ${bindings.name.text} = ${namespaceName};`);
687
+ }
688
+ else if (bindings && ts.isNamedImports(bindings)) {
689
+ for (const element of bindings.elements) {
690
+ const imported = element.propertyName?.text ?? element.name.text;
691
+ lines.push(`import ${element.name.text} = ${namespaceName}.${imported};`);
692
+ }
693
+ }
694
+ return lines;
695
+ }
696
+ function rewriteExportDeclaration(statement, namespaceName, exported, diagnosticPrefix) {
697
+ if (!statement.exportClause) {
698
+ return [...exported]
699
+ .filter((name) => name !== "default" && isIdentifierName(name))
700
+ .map((name) => `export import ${name} = ${namespaceName}.${name};`);
701
+ }
702
+ if (ts.isNamespaceExport(statement.exportClause)) {
703
+ return [`export import ${statement.exportClause.name.text} = ${namespaceName};`];
704
+ }
705
+ if (!ts.isNamedExports(statement.exportClause)) {
706
+ throw new Error(`${diagnosticPrefix}: unsupported export declaration could not be bundled`);
707
+ }
708
+ return statement.exportClause.elements.map((element) => {
709
+ const imported = element.propertyName?.text ?? element.name.text;
710
+ return `export import ${element.name.text} = ${namespaceName}.${imported};`;
711
+ });
712
+ }
713
+ function resolveExistingDeclaration(specifier, importer, sources, options, host) {
714
+ const resolved = ts.resolveModuleName(specifier, importer, options, host).resolvedModule?.resolvedFileName;
715
+ if (resolved) {
716
+ const matched = lookupDeclarationSourceKey(resolved, sources);
717
+ if (matched)
718
+ return matched;
719
+ }
720
+ if (isRelativeSpecifier(specifier)) {
721
+ for (const candidate of declarationCandidates(resolvePath(dirname(importer), specifier))) {
722
+ const matched = lookupDeclarationSourceKey(candidate, sources);
723
+ if (matched)
724
+ return matched;
725
+ }
726
+ }
727
+ return null;
728
+ }
729
+ function lookupDeclarationSourceKey(fileName, sources) {
730
+ const normalized = normalizeFile(fileName);
731
+ if (sources.has(normalized))
732
+ return normalized;
733
+ if (normalized.endsWith(".d.ts"))
734
+ return null;
735
+ const declarationPath = normalizeFile(`${withoutExtension(normalized)}.d.ts`);
736
+ if (sources.has(declarationPath))
737
+ return declarationPath;
738
+ const lower = declarationPath.toLowerCase();
739
+ return [...sources.keys()].find((key) => key.toLowerCase() === lower) ?? null;
740
+ }
741
+ function collectModuleSpecifiers(sourceFile) {
742
+ const specifiers = [];
743
+ const visit = (node) => {
744
+ if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
745
+ specifiers.push(node.moduleSpecifier.text);
746
+ }
747
+ else if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference) && node.moduleReference.expression && ts.isStringLiteral(node.moduleReference.expression)) {
748
+ specifiers.push(node.moduleReference.expression.text);
749
+ }
750
+ else if (ts.isImportTypeNode(node) && ts.isLiteralTypeNode(node.argument) && ts.isStringLiteral(node.argument.literal)) {
751
+ specifiers.push(node.argument.literal.text);
752
+ }
753
+ else if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
754
+ const argument = node.arguments[0];
755
+ if (argument && ts.isStringLiteral(argument))
756
+ specifiers.push(argument.text);
757
+ }
758
+ ts.forEachChild(node, visit);
759
+ };
760
+ visit(sourceFile);
761
+ return specifiers;
762
+ }
763
+ function statementText(statement, sourceFile) {
764
+ const start = statement.getStart(sourceFile, true);
765
+ return sourceFile.text.slice(start, statement.end).trim();
766
+ }
767
+ function adjustDeclarationForNamespace(text) {
768
+ return text
769
+ .replace(/^((?:\/\*\*[\s\S]*?\*\/\s*)*)export\s+default\s+/, "$1export ")
770
+ .replace(/^((?:\/\*\*[\s\S]*?\*\/\s*)*)export\s+declare\s+/, "$1export ")
771
+ .replace(/^((?:\/\*\*[\s\S]*?\*\/\s*)*)declare\s+/, "$1");
772
+ }
773
+ function indentBlock(text) {
774
+ return text
775
+ .split("\n")
776
+ .map((line) => (line.length === 0 ? line : ` ${line}`))
777
+ .join("\n");
778
+ }
779
+ function hasExportModifier(node) {
780
+ return (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0;
781
+ }
782
+ function hasDefaultModifier(node) {
783
+ return (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Default) !== 0;
784
+ }
785
+ function declarationName(statement) {
786
+ if (ts.isFunctionDeclaration(statement) ||
787
+ ts.isClassDeclaration(statement) ||
788
+ ts.isInterfaceDeclaration(statement) ||
789
+ ts.isTypeAliasDeclaration(statement) ||
790
+ ts.isEnumDeclaration(statement) ||
791
+ ts.isModuleDeclaration(statement)) {
792
+ return statement.name && ts.isIdentifier(statement.name) ? statement.name.text : null;
793
+ }
794
+ if (ts.isVariableStatement(statement)) {
795
+ const name = statement.declarationList.declarations[0]?.name;
796
+ return name && ts.isIdentifier(name) ? name.text : null;
797
+ }
798
+ return null;
799
+ }
800
+ function isIdentifierName(name) {
801
+ return /^[A-Za-z_$][\w$]*$/.test(name);
802
+ }
803
+ function assertNoExternalModuleSpecifiers(source, diagnosticPrefix) {
804
+ const sourceFile = ts.createSourceFile("index.d.ts", source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
805
+ const visit = (node) => {
806
+ if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
807
+ throw new Error(`${diagnosticPrefix}: rolled-up declaration still depends on module "${node.moduleSpecifier.text}"`);
808
+ }
809
+ if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference) && node.moduleReference.expression && ts.isStringLiteral(node.moduleReference.expression)) {
810
+ throw new Error(`${diagnosticPrefix}: rolled-up declaration still depends on module "${node.moduleReference.expression.text}"`);
811
+ }
812
+ if (ts.isImportTypeNode(node) && ts.isLiteralTypeNode(node.argument) && ts.isStringLiteral(node.argument.literal)) {
813
+ throw new Error(`${diagnosticPrefix}: rolled-up declaration still depends on module "${node.argument.literal.text}"`);
814
+ }
815
+ ts.forEachChild(node, visit);
816
+ };
817
+ visit(sourceFile);
818
+ }
819
+ function validateRolledUpDeclaration(source, diagnosticPrefix) {
820
+ const options = {
821
+ target: ts.ScriptTarget.ES2022,
822
+ module: ts.ModuleKind.ESNext,
823
+ // The artifact is itself a .d.ts file; skipLibCheck would skip its semantic check.
824
+ skipLibCheck: false,
825
+ noEmit: true,
826
+ noResolve: true,
827
+ types: [],
828
+ typeRoots: [],
829
+ strict: true,
830
+ };
831
+ const host = ts.createCompilerHost(options);
832
+ const fileName = resolvePath(host.getCurrentDirectory(), "__pedelec_artifact__.d.ts");
833
+ const originalGetSourceFile = host.getSourceFile.bind(host);
834
+ const originalReadFile = host.readFile.bind(host);
835
+ const originalFileExists = host.fileExists.bind(host);
836
+ host.fileExists = (name) => name.includes("__pedelec_artifact__") || originalFileExists(name);
837
+ host.readFile = (name) => (name.includes("__pedelec_artifact__") ? source : originalReadFile(name));
838
+ host.getSourceFile = (name, languageVersion, onError, shouldCreateNewSourceFile) => {
839
+ if (name.includes("__pedelec_artifact__")) {
840
+ return ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
841
+ }
842
+ return originalGetSourceFile(name, languageVersion, onError, shouldCreateNewSourceFile);
843
+ };
844
+ const program = ts.createProgram([fileName], options, host);
845
+ const diagnostics = ts
846
+ .getPreEmitDiagnostics(program)
847
+ .filter((item) => item.category === ts.DiagnosticCategory.Error)
848
+ .filter((item) => !item.file || !isTypeScriptLib(item.file.fileName));
849
+ if (diagnostics.length > 0) {
850
+ throw new Error(`${diagnosticPrefix}: rolled-up declaration is not a valid standalone public declaration: ${formatDiagnostics(diagnostics)}`);
851
+ }
852
+ }
853
+ function createTypeScriptAliasOptions(config) {
854
+ if (!config || !Array.isArray(config.resolve.alias))
855
+ return {};
856
+ const aliases = config.resolve.alias;
857
+ const paths = {};
858
+ for (const alias of aliases) {
859
+ if (typeof alias.find !== "string" || typeof alias.replacement !== "string")
860
+ continue;
861
+ const replacement = isAbsolute(alias.replacement)
862
+ ? alias.replacement
863
+ : resolvePath(config.root, alias.replacement);
864
+ const exactName = alias.find.endsWith("$") ? alias.find.slice(0, -1) : alias.find;
865
+ paths[exactName] = [replacement];
866
+ if (!alias.find.endsWith("$"))
867
+ paths[`${exactName}/*`] = [`${replacement}/*`];
868
+ }
869
+ return Object.keys(paths).length === 0 ? {} : { baseUrl: config.root, paths };
870
+ }
871
+ function isNodeModulesPath(fileName) {
872
+ return /[\\/]node_modules[\\/]/.test(fileName);
873
+ }
874
+ function declarationCandidates(path) {
875
+ const normalized = normalizeFile(path);
876
+ const withoutDts = normalized.endsWith(".d.ts") ? normalized.slice(0, -5) : normalized;
877
+ return [
878
+ normalized,
879
+ `${withoutDts}.d.ts`,
880
+ `${withoutDts}.ts`,
881
+ `${withoutDts}.tsx`,
882
+ `${withoutDts}.js`,
883
+ `${withoutDts}.jsx`,
884
+ `${withoutDts}/index.d.ts`,
885
+ ].map(normalizeFile);
886
+ }
887
+ function findDenoModuleImportNames(sourceFile) {
888
+ const names = new Set();
889
+ for (const statement of sourceFile.statements) {
890
+ if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier))
891
+ continue;
892
+ if (statement.moduleSpecifier.text !== PACKAGE_NAME || !statement.importClause || statement.importClause.isTypeOnly)
893
+ continue;
894
+ const namedBindings = statement.importClause.namedBindings;
895
+ if (!namedBindings || !ts.isNamedImports(namedBindings))
896
+ continue;
897
+ for (const element of namedBindings.elements) {
898
+ if (element.isTypeOnly || element.propertyName?.text !== DEFINE_DENO_MODULE_NAME && element.name.text !== DEFINE_DENO_MODULE_NAME)
899
+ continue;
900
+ const importedName = element.propertyName?.text ?? element.name.text;
901
+ if (importedName === DEFINE_DENO_MODULE_NAME)
902
+ names.add(element.name.text);
903
+ }
904
+ }
905
+ return names;
906
+ }
907
+ function findDeclarations(sourceFile, importedNames) {
908
+ const declarations = [];
909
+ const visit = (node) => {
910
+ if (ts.isCallExpression(node) &&
911
+ ts.isIdentifier(node.expression) &&
912
+ importedNames.has(node.expression.text) &&
913
+ !isShadowedCall(node, node.expression.text, sourceFile)) {
914
+ declarations.push(readDeclaration(node, sourceFile));
915
+ }
916
+ ts.forEachChild(node, visit);
917
+ };
918
+ ts.forEachChild(sourceFile, visit);
919
+ return declarations;
920
+ }
921
+ function isShadowedCall(node, name, sourceFile) {
922
+ let parent = node.parent;
923
+ while (parent && parent !== sourceFile) {
924
+ if (ts.isFunctionLike(parent) && parent.parameters.some((parameter) => bindingNames(parameter.name).has(name)))
925
+ return true;
926
+ if (ts.isCatchClause(parent) && parent.variableDeclaration && bindingNames(parent.variableDeclaration.name).has(name))
927
+ return true;
928
+ if (ts.isBlock(parent) && blockBindings(parent).has(name))
929
+ return true;
930
+ parent = parent.parent;
931
+ }
932
+ return false;
933
+ }
934
+ function blockBindings(block) {
935
+ const names = new Set();
936
+ for (const statement of block.statements) {
937
+ if (ts.isVariableStatement(statement)) {
938
+ for (const declaration of statement.declarationList.declarations) {
939
+ for (const name of bindingNames(declaration.name))
940
+ names.add(name);
941
+ }
942
+ }
943
+ else if ((ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) && statement.name) {
944
+ names.add(statement.name.text);
945
+ }
946
+ }
947
+ return names;
948
+ }
949
+ function bindingNames(name) {
950
+ const names = new Set();
951
+ const visit = (node) => {
952
+ if (ts.isIdentifier(node)) {
953
+ names.add(node.text);
954
+ return;
955
+ }
956
+ ts.forEachChild(node, (child) => {
957
+ if (ts.isBindingName(child))
958
+ visit(child);
959
+ });
960
+ };
961
+ visit(name);
962
+ return names;
963
+ }
964
+ function readDeclaration(node, sourceFile) {
965
+ const argument = node.arguments[0];
966
+ if (!argument || !ts.isObjectLiteralExpression(argument) || node.arguments.length !== 1) {
967
+ throw declarationError(sourceFile, node, "defineDenoModule() requires one object literal argument");
968
+ }
969
+ const values = new Map();
970
+ for (const property of argument.properties) {
971
+ if (ts.isShorthandPropertyAssignment(property)) {
972
+ values.set(property.name.text, property.name);
973
+ continue;
974
+ }
975
+ if (!ts.isPropertyAssignment(property)) {
976
+ throw declarationError(sourceFile, property, "defineDenoModule() fields must be statically readable property assignments");
977
+ }
978
+ const name = getPropertyName(property.name);
979
+ if (name)
980
+ values.set(name, property.initializer);
981
+ }
982
+ const name = readStringField(values, "name", sourceFile, node);
983
+ const description = readStringField(values, "description", sourceFile, node);
984
+ if (values.has("code")) {
985
+ throw declarationError(sourceFile, values.get("code"), "defineDenoModule() does not support inline code; use a static entry");
986
+ }
987
+ const entryExpression = values.get("entry");
988
+ if (!entryExpression)
989
+ throw declarationError(sourceFile, node, "defineDenoModule() requires an entry string literal");
990
+ if (ts.isTemplateExpression(entryExpression)) {
991
+ throw declarationError(sourceFile, entryExpression, "defineDenoModule() entry cannot contain template substitutions");
992
+ }
993
+ const entry = readStaticString(entryExpression);
994
+ if (entry === null)
995
+ throw declarationError(sourceFile, entryExpression, "defineDenoModule() entry must be a string literal");
996
+ const usage = readStringField(values, "usage", sourceFile, node);
997
+ return {
998
+ name,
999
+ description,
1000
+ entry,
1001
+ usage,
1002
+ callStart: node.getStart(sourceFile),
1003
+ callEnd: node.end,
1004
+ objectStart: argument.getStart(sourceFile),
1005
+ objectEnd: argument.end,
1006
+ entryStart: entryExpression.getStart(sourceFile),
1007
+ entryEnd: entryExpression.end,
1008
+ };
1009
+ }
1010
+ function replaceSourceRange(source, start, end, replacement) {
1011
+ return source.slice(0, start) + replacement + source.slice(end);
1012
+ }
1013
+ function readStringField(values, field, sourceFile, node) {
1014
+ const expression = values.get(field);
1015
+ const value = expression ? readStaticString(expression) : null;
1016
+ if (value === null)
1017
+ throw declarationError(sourceFile, expression ?? node, `defineDenoModule() requires a static string field: ${field}`);
1018
+ return value;
1019
+ }
1020
+ function readStaticString(expression) {
1021
+ if (ts.isStringLiteral(expression) || ts.isNoSubstitutionTemplateLiteral(expression))
1022
+ return expression.text;
1023
+ return null;
1024
+ }
1025
+ function getPropertyName(name) {
1026
+ if (ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name))
1027
+ return name.text;
1028
+ return null;
1029
+ }
1030
+ function declarationError(sourceFile, node, message) {
1031
+ const position = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
1032
+ return new Error(`${sourceFile.fileName}:${position.line + 1}:${position.character + 1}: ${message}`);
1033
+ }
1034
+ function parseSourceFile(code, id) {
1035
+ const extension = extname(id).toLowerCase();
1036
+ const scriptKind = extension === ".tsx" ? ts.ScriptKind.TSX : extension === ".jsx" ? ts.ScriptKind.JSX : extension === ".js" || extension === ".mjs" || extension === ".cjs" ? ts.ScriptKind.JS : ts.ScriptKind.TS;
1037
+ return ts.createSourceFile(id, code, ts.ScriptTarget.Latest, true, scriptKind);
1038
+ }
1039
+ function isTransformableScript(id) {
1040
+ return SCRIPT_EXTENSIONS.has(extname(id).toLowerCase());
1041
+ }
1042
+ function isRemoteOrSchemeEntry(entry) {
1043
+ return /^[a-z][a-z\d+.-]*:/i.test(entry) || entry.startsWith("//") || isAbsolute(entry);
1044
+ }
1045
+ function stripQueryAndHash(id) {
1046
+ return id.split(/[?#]/, 1)[0];
1047
+ }
1048
+ function normalizeFile(fileName) {
1049
+ return normalize(resolvePath(fileName));
1050
+ }
1051
+ function withoutExtension(fileName) {
1052
+ return fileName.endsWith(".d.ts") ? fileName.slice(0, -5) : fileName.slice(0, fileName.length - extname(fileName).length);
1053
+ }
1054
+ function adjacentDeclarationPath(fileName) {
1055
+ if (fileName.endsWith(".d.ts"))
1056
+ return fileName;
1057
+ if (!/\.(?:[cm]?[jt]sx?)$/i.test(fileName))
1058
+ return null;
1059
+ return `${fileName.replace(/\.[^.]+$/, "")}.d.ts`;
1060
+ }
1061
+ function isDeclarationSourcePath(fileName) {
1062
+ return fileName.endsWith(".d.ts") || /\.[cm]?tsx?$/i.test(fileName);
1063
+ }
1064
+ function isDeclarationLikePath(fileName) {
1065
+ const extension = fileName.endsWith(".d.ts") ? ".d.ts" : extname(fileName).toLowerCase();
1066
+ return DECLARATION_LIKE_EXTENSIONS.has(extension);
1067
+ }
1068
+ function isTypeScriptLib(fileName) {
1069
+ return /[\\/]typescript[\\/]lib[\\/]/i.test(fileName);
1070
+ }
1071
+ function isIgnoredProgramFile(fileName) {
1072
+ return /[\\/]@types[\\/]/i.test(fileName);
1073
+ }
1074
+ function isWatchableSourceFile(fileName) {
1075
+ if (!fileName || fileName.startsWith("\0") || fileName.startsWith("virtual:") || fileName.startsWith("data:"))
1076
+ return false;
1077
+ if (!isAbsolute(fileName) && !/^[A-Za-z]:[\\/]/.test(fileName))
1078
+ return false;
1079
+ return ts.sys.fileExists(fileName);
1080
+ }
1081
+ function isRelativeSpecifier(specifier) {
1082
+ return specifier.startsWith(".") || specifier.startsWith("/");
1083
+ }
1084
+ function isBareSpecifier(specifier) {
1085
+ return !isRelativeSpecifier(specifier) && !specifier.startsWith("#") && !specifier.startsWith("node:");
1086
+ }
1087
+ function isOptimizedDependencyPath(fileName) {
1088
+ return /[\\/]\.vite[\\/]deps[\\/]/.test(fileName);
1089
+ }
1090
+ function nodeModulesPackageRoot(fileName) {
1091
+ const normalized = normalizeFile(fileName);
1092
+ const segments = normalized.split(/[\\/]/);
1093
+ const nodeModulesIndex = segments.lastIndexOf("node_modules");
1094
+ if (nodeModulesIndex < 0 || nodeModulesIndex + 1 >= segments.length)
1095
+ return null;
1096
+ const packageEnd = segments[nodeModulesIndex + 1].startsWith("@") ? nodeModulesIndex + 3 : nodeModulesIndex + 2;
1097
+ if (packageEnd > segments.length)
1098
+ return null;
1099
+ return normalizeFile(segments.slice(0, packageEnd).join("/"));
1100
+ }
1101
+ function canResolveDeclarationDependency(specifier, packageBoundary) {
1102
+ if (packageBoundary === null || isRelativeSpecifier(specifier) || specifier.startsWith("#"))
1103
+ return true;
1104
+ const packageJson = readFileIfAvailable(resolvePath(packageBoundary, "package.json"));
1105
+ if (!packageJson)
1106
+ return false;
1107
+ try {
1108
+ const packageName = JSON.parse(packageJson).name;
1109
+ return typeof packageName === "string" && (specifier === packageName || specifier.startsWith(`${packageName}/`));
1110
+ }
1111
+ catch {
1112
+ return false;
1113
+ }
1114
+ }
1115
+ function isBuiltinSpecifier(specifier) {
1116
+ return canonicalBuiltinSpecifier(specifier) !== null;
1117
+ }
1118
+ function isDeferredBuiltinResolutionDiagnostic(diagnostic) {
1119
+ if (diagnostic.code !== 2307)
1120
+ return false;
1121
+ const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
1122
+ const match = /Cannot find module ['"]([^'"]+)['"]/.exec(message);
1123
+ return Boolean(match && isBuiltinSpecifier(match[1]));
1124
+ }
1125
+ function canonicalBuiltinSpecifier(specifier) {
1126
+ if (specifier.startsWith("node:")) {
1127
+ const bareSpecifier = specifier.slice("node:".length);
1128
+ return NODE_BUILTIN_MODULES.has(bareSpecifier) ? specifier : null;
1129
+ }
1130
+ return LEGACY_NODE_BUILTIN_MODULES.has(specifier) ? `node:${specifier}` : null;
1131
+ }
1132
+ function isCanonicalBuiltinSpecifier(specifier) {
1133
+ return specifier.startsWith("node:") && canonicalBuiltinSpecifier(specifier) === specifier;
1134
+ }
1135
+ function resolutionKey(importer, specifier) {
1136
+ return `${normalizeFile(importer)}::${specifier}`;
1137
+ }
1138
+ function toResolvedModule(fileName) {
1139
+ const extension = fileName.endsWith(".d.ts")
1140
+ ? ts.Extension.Dts
1141
+ : fileName.endsWith(".tsx")
1142
+ ? ts.Extension.Tsx
1143
+ : fileName.endsWith(".ts")
1144
+ ? ts.Extension.Ts
1145
+ : fileName.endsWith(".jsx")
1146
+ ? ts.Extension.Jsx
1147
+ : ts.Extension.Js;
1148
+ return {
1149
+ resolvedFileName: fileName,
1150
+ extension,
1151
+ isExternalLibraryImport: isNodeModulesPath(fileName),
1152
+ };
1153
+ }
1154
+ function readFileIfAvailable(fileName) {
1155
+ try {
1156
+ return ts.sys.fileExists(fileName) ? ts.sys.readFile(fileName) ?? null : null;
1157
+ }
1158
+ catch {
1159
+ return null;
1160
+ }
1161
+ }
1162
+ function leftoverRuntimeModuleSpecifiers(source) {
1163
+ const leftover = [];
1164
+ const sourceFile = ts.createSourceFile("runtime.mjs", source, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
1165
+ const visit = (node) => {
1166
+ if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
1167
+ leftover.push(node.moduleSpecifier.text);
1168
+ }
1169
+ else if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference) && node.moduleReference.expression && ts.isStringLiteral(node.moduleReference.expression)) {
1170
+ leftover.push(node.moduleReference.expression.text);
1171
+ }
1172
+ else if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
1173
+ const argument = node.arguments[0];
1174
+ leftover.push(argument && ts.isStringLiteralLike(argument) ? argument.text : "[unsupported dynamic import]");
1175
+ }
1176
+ ts.forEachChild(node, visit);
1177
+ };
1178
+ visit(sourceFile);
1179
+ return leftover;
1180
+ }
1181
+ function ensureSelfTypesDirective(source) {
1182
+ const directive = '// @ts-self-types="./index.d.ts"';
1183
+ const withoutExisting = source.replace(/^\s*\/\/\s*@ts-self-types=.*(?:\r?\n|$)/, "");
1184
+ return `${directive}\n${withoutExisting.trimStart()}`;
1185
+ }
1186
+ function stripBundlerLocationComments(source) {
1187
+ return source
1188
+ .replace(/^\s*\/\/\#region[^\r\n]*(?:\r?\n|$)/gm, "")
1189
+ .replace(/^\s*\/\/\#endregion[^\r\n]*(?:\r?\n|$)/gm, "");
1190
+ }
1191
+ function normalizeDeclarationSource(source) {
1192
+ return source.replace(/\r\n/g, "\n").trim() + "\n";
1193
+ }
1194
+ function stripDeclarationSourceMap(source) {
1195
+ return source.replace(/\s*\/\/#[#]?\s*sourceMappingURL=.*$/gm, "");
1196
+ }
1197
+ function hasMeaningfulDeclarationSurface(source) {
1198
+ return /\bexport\s+(?:declare\s+)?(?:function|class|const|let|var|interface|type|enum|namespace|abstract\s+class)/.test(source) ||
1199
+ /\bexport\s+default\s+(?:function|class|const|let|var|interface|type)/.test(source) ||
1200
+ /\bexport\s+import\b/.test(source) ||
1201
+ /\bexport\s*\{/.test(source) || /\bexport\s*=/.test(source);
1202
+ }
1203
+ function createContentHash(runtimeSource, typesSource) {
1204
+ return createHash("sha256")
1205
+ .update(ARTIFACT_HASH_VERSION)
1206
+ .update("\0")
1207
+ .update(runtimeSource)
1208
+ .update("\0")
1209
+ .update(typesSource)
1210
+ .digest("hex");
1211
+ }
1212
+ function formatDiagnostics(diagnostics) {
1213
+ return diagnostics
1214
+ .map((diagnostic) => ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"))
1215
+ .join("; ");
1216
+ }
1217
+ function formatError(error) {
1218
+ return error instanceof Error ? error.message : String(error);
1219
+ }
1220
+ function registerOwner(owner, dependencies, ownersByDependency, dependenciesByOwner) {
1221
+ const previous = dependenciesByOwner.get(owner);
1222
+ if (previous) {
1223
+ for (const dependency of previous) {
1224
+ const owners = ownersByDependency.get(dependency);
1225
+ owners?.delete(owner);
1226
+ if (owners?.size === 0)
1227
+ ownersByDependency.delete(dependency);
1228
+ }
1229
+ }
1230
+ dependenciesByOwner.set(owner, dependencies);
1231
+ for (const dependency of dependencies) {
1232
+ const normalizedDependency = normalizeFile(dependency);
1233
+ const owners = ownersByDependency.get(normalizedDependency) ?? new Set();
1234
+ owners.add(owner);
1235
+ ownersByDependency.set(normalizedDependency, owners);
1236
+ }
1237
+ }
1238
+ function invalidateOwners(context, ownersByDependency) {
1239
+ const changed = normalizeFile(context.file);
1240
+ const owners = ownersByDependency.get(changed);
1241
+ if (!owners || owners.size === 0)
1242
+ return;
1243
+ const modules = [];
1244
+ for (const owner of owners) {
1245
+ const module = context.server.moduleGraph.getModuleById(owner)
1246
+ ?? context.server.moduleGraph.getModuleById(normalizeFile(owner))
1247
+ ?? [...(context.server.moduleGraph.getModulesByFile(owner) ?? [])][0]
1248
+ ?? [...(context.server.moduleGraph.getModulesByFile(normalizeFile(owner)) ?? [])][0];
1249
+ if (!module)
1250
+ continue;
1251
+ context.server.moduleGraph.invalidateModule(module);
1252
+ modules.push(module);
1253
+ }
1254
+ return modules;
1255
+ }