vite-plugin-dts 3.7.3 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -13,11 +13,13 @@ const vueTsc = require('vue-tsc');
13
13
  const debug = require('debug');
14
14
  const kolorist = require('kolorist');
15
15
  const apiExtractor = require('@microsoft/api-extractor');
16
+ const MagicString = require('magic-string');
16
17
 
17
18
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
18
19
 
19
20
  const ts__default = /*#__PURE__*/_interopDefaultCompat(ts);
20
21
  const debug__default = /*#__PURE__*/_interopDefaultCompat(debug);
22
+ const MagicString__default = /*#__PURE__*/_interopDefaultCompat(MagicString);
21
23
 
22
24
  const windowsSlashRE = /\\+/g;
23
25
  function slash(p) {
@@ -38,7 +40,7 @@ function isRegExp(value) {
38
40
  function isPromise(value) {
39
41
  return !!value && (typeof value === "function" || typeof value === "object") && typeof value.then === "function";
40
42
  }
41
- async function wrapPromise(maybePromise) {
43
+ async function unwrapPromise(maybePromise) {
42
44
  return isPromise(maybePromise) ? await maybePromise : maybePromise;
43
45
  }
44
46
  function ensureAbsolute(path, root) {
@@ -415,46 +417,13 @@ function normalizeGlob(path) {
415
417
  }
416
418
  return path;
417
419
  }
418
- const globalDynamicTypeRE = /import\(['"][^;\n]+?['"]\)\.\w+[.()[\]<>,;\n\s]/g;
419
- const dynamicTypeRE = /import\(['"](.+)['"]\)\.(.+)([.()[\]<>,;\n\s])/;
420
- const importTypesRE = /import\s?(?:type)?\s?\{(.+)\}\s?from\s?['"].+['"]/;
421
- function transformDynamicImport(content) {
422
- const importMap = /* @__PURE__ */ new Map();
423
- const defaultMap = /* @__PURE__ */ new Map();
424
- let defaultCount = 1;
425
- content = content.replace(globalDynamicTypeRE, (str) => {
426
- const matchResult = str.match(dynamicTypeRE);
427
- const libName = matchResult[1];
428
- const importSet = importMap.get(libName) ?? importMap.set(libName, /* @__PURE__ */ new Set()).get(libName);
429
- let usedType = matchResult[2];
430
- if (usedType === "default") {
431
- usedType = defaultMap.get(libName) ?? defaultMap.set(libName, `__DTS_${defaultCount++}__`).get(libName);
432
- importSet.add(`default as ${usedType}`);
433
- } else {
434
- importSet.add(usedType);
435
- }
436
- return usedType + matchResult[3];
437
- });
438
- importMap.forEach((importSet, libName) => {
439
- const importReg = new RegExp(
440
- `import\\s?(?:type)?\\s?\\{[^;\\n]+\\}\\s?from\\s?['"]${libName}['"]`,
441
- "g"
442
- );
443
- const matchResult = content.match(importReg);
444
- if (matchResult?.[0]) {
445
- matchResult[0].match(importTypesRE)[1].trim().split(",").forEach((type) => {
446
- type && importSet.add(type.trim());
447
- });
448
- content = content.replace(
449
- matchResult[0],
450
- `import { ${Array.from(importSet).join(", ")} } from '${libName}'`
451
- );
452
- } else {
453
- content = `import { ${Array.from(importSet).join(", ")} } from '${libName}';
454
- ` + content;
420
+ function walkSourceFile(sourceFile, callback) {
421
+ function walkNode(node, parent, callback2) {
422
+ if (callback2(node, parent) !== false) {
423
+ node.forEachChild((child) => walkNode(child, node, callback2));
455
424
  }
456
- });
457
- return content;
425
+ }
426
+ sourceFile.forEachChild((child) => walkNode(child, sourceFile, callback));
458
427
  }
459
428
  function isAliasMatch(alias, importer) {
460
429
  if (isRegExp(alias.find))
@@ -465,54 +434,132 @@ function isAliasMatch(alias, importer) {
465
434
  return true;
466
435
  return importer.indexOf(alias.find) === 0 && (alias.find.endsWith("/") || importer.substring(alias.find.length)[0] === "/");
467
436
  }
468
- function ensureStartWithDot(path) {
469
- return path.startsWith(".") ? path : `./${path}`;
470
- }
471
- const globalImportRE = /(?:(?:import|export)\s?(?:type)?\s?(?:(?:\{[^;\n]+\})|(?:[^;\n]+))\s?from\s?['"][^;\n]+['"])|(?:import\(['"][^;\n]+?['"]\))/g;
472
- const staticImportRE = /(?:import|export)\s?(?:type)?\s?\{?.+\}?\s?from\s?['"](.+)['"]/;
473
- const dynamicImportRE = /import\(['"]([^;\n]+?)['"]\)/;
474
- const simpleStaticImportRE = /((?:import|export).+from\s?)['"](.+)['"]/;
475
- const simpleDynamicImportRE = /(import\()['"](.+)['"]\)/;
476
- function transformAliasImport(filePath, content, aliases, exclude = []) {
477
- if (!aliases?.length)
478
- return content;
479
- return content.replace(globalImportRE, (str) => {
480
- let matchResult = str.match(staticImportRE);
481
- let isDynamic = false;
482
- if (!matchResult) {
483
- matchResult = str.match(dynamicImportRE);
484
- isDynamic = true;
437
+ function transformAlias(importer, dir, aliases, aliasesExclude) {
438
+ if (aliases.length && !aliasesExclude.some((e) => isRegExp(e) ? e.test(importer) : String(e) === importer)) {
439
+ const matchedAlias = aliases.find((alias) => isAliasMatch(alias, importer));
440
+ if (matchedAlias) {
441
+ const replacement = node_path.isAbsolute(matchedAlias.replacement) ? normalizePath(node_path.relative(dir, matchedAlias.replacement)) : normalizePath(matchedAlias.replacement);
442
+ const endsWithSlash = typeof matchedAlias.find === "string" ? matchedAlias.find.endsWith("/") : importer.match(matchedAlias.find)[0].endsWith("/");
443
+ const truthPath = importer.replace(
444
+ matchedAlias.find,
445
+ replacement + (endsWithSlash ? "/" : "")
446
+ );
447
+ const normalizedPath = normalizePath(node_path.relative(dir, node_path.resolve(dir, truthPath)));
448
+ return normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
485
449
  }
486
- if (matchResult?.[1]) {
487
- const matchedAlias = aliases.find((alias) => isAliasMatch(alias, matchResult[1]));
488
- if (matchedAlias) {
489
- if (exclude.some((e) => isRegExp(e) ? e.test(matchResult[1]) : String(e) === matchResult[1])) {
490
- return str;
491
- }
492
- const dir = node_path.dirname(filePath);
493
- const replacement = node_path.isAbsolute(matchedAlias.replacement) ? normalizePath(node_path.relative(dir, matchedAlias.replacement)) : normalizePath(matchedAlias.replacement);
494
- const endSlash = typeof matchedAlias.find === "string" ? matchedAlias.find.endsWith("/") : matchResult[1].match(matchedAlias.find)[0].endsWith("/");
495
- const truthPath = matchResult[1].replace(
496
- matchedAlias.find,
497
- replacement + (endSlash ? "/" : "")
498
- );
499
- const normalizedPath = normalizePath(node_path.relative(dir, node_path.resolve(dir, truthPath)));
500
- return str.replace(
501
- isDynamic ? simpleDynamicImportRE : simpleStaticImportRE,
502
- `$1'${ensureStartWithDot(normalizedPath)}'${isDynamic ? ")" : ""}`
450
+ }
451
+ return importer;
452
+ }
453
+ function transformCode(options) {
454
+ const s = new MagicString__default(options.content);
455
+ const ast = ts__default.createSourceFile("a.ts", options.content, ts__default.ScriptTarget.Latest);
456
+ const dir = node_path.dirname(options.filePath);
457
+ const importMap = /* @__PURE__ */ new Map();
458
+ const usedDefault = /* @__PURE__ */ new Map();
459
+ const declareModules = [];
460
+ let indexCount = 0;
461
+ walkSourceFile(ast, (node, parent) => {
462
+ if (ts__default.isImportDeclaration(node)) {
463
+ if (!node.importClause) {
464
+ options.clearPureImport && s.remove(node.pos, node.end);
465
+ } else if (ts__default.isStringLiteral(node.moduleSpecifier) && (node.importClause.name || node.importClause.namedBindings && ts__default.isNamedImports(node.importClause.namedBindings))) {
466
+ const libName = transformAlias(
467
+ node.moduleSpecifier.text,
468
+ dir,
469
+ options.aliases,
470
+ options.aliasesExclude
503
471
  );
472
+ const importSet = importMap.get(libName) ?? importMap.set(libName, /* @__PURE__ */ new Set()).get(libName);
473
+ if (node.importClause.name && !usedDefault.has(libName)) {
474
+ const usedType = node.importClause.name.escapedText;
475
+ usedDefault.set(libName, usedType);
476
+ importSet.add(`default as ${usedType}`);
477
+ }
478
+ if (node.importClause.namedBindings && ts__default.isNamedImports(node.importClause.namedBindings)) {
479
+ node.importClause.namedBindings.elements.forEach((element) => {
480
+ importSet.add(element.name.escapedText);
481
+ });
482
+ }
483
+ s.remove(node.pos, node.end);
504
484
  }
485
+ return false;
486
+ }
487
+ if (ts__default.isImportTypeNode(node) && node.qualifier && ts__default.isLiteralTypeNode(node.argument) && ts__default.isIdentifier(node.qualifier) && ts__default.isStringLiteral(node.argument.literal)) {
488
+ const libName = transformAlias(
489
+ node.argument.literal.text,
490
+ dir,
491
+ options.aliases,
492
+ options.aliasesExclude
493
+ );
494
+ if (!options.staticImport) {
495
+ s.update(node.argument.literal.pos, node.argument.literal.end, `'${libName}'`);
496
+ return false;
497
+ }
498
+ const importSet = importMap.get(libName) ?? importMap.set(libName, /* @__PURE__ */ new Set()).get(libName);
499
+ let usedType = node.qualifier.escapedText;
500
+ if (usedType === "default") {
501
+ usedType = usedDefault.get(libName) ?? usedDefault.set(libName, `__DTS_DEFAULT_${indexCount++}__`).get(libName);
502
+ importSet.add(`default as ${usedType}`);
503
+ s.update(node.qualifier.pos, node.qualifier.end, usedType);
504
+ } else {
505
+ importSet.add(usedType);
506
+ }
507
+ if (ts__default.isImportTypeNode(parent) && parent.typeArguments && parent.typeArguments[0] === node) {
508
+ s.remove(node.pos, node.argument.end + 2);
509
+ } else {
510
+ s.update(node.pos, node.argument.end + 2, " ");
511
+ }
512
+ return !!node.typeArguments;
513
+ }
514
+ if (ts__default.isCallExpression(node) && node.expression.kind === ts__default.SyntaxKind.ImportKeyword && ts__default.isStringLiteral(node.arguments[0])) {
515
+ const libName = transformAlias(
516
+ node.arguments[0].text,
517
+ dir,
518
+ options.aliases,
519
+ options.aliasesExclude
520
+ );
521
+ s.update(node.arguments[0].pos, node.arguments[0].end, `'${libName}'`);
522
+ return false;
523
+ }
524
+ if (ts__default.isExportDeclaration(node) && node.moduleSpecifier && ts__default.isStringLiteral(node.moduleSpecifier)) {
525
+ const libName = transformAlias(
526
+ node.moduleSpecifier.text,
527
+ dir,
528
+ options.aliases,
529
+ options.aliasesExclude
530
+ );
531
+ s.update(node.moduleSpecifier.pos, node.moduleSpecifier.end, ` '${libName}'`);
532
+ return false;
533
+ }
534
+ if (ts__default.isModuleDeclaration(node)) {
535
+ declareModules.push(s.slice(node.pos, node.end + 1));
505
536
  }
506
- return str;
507
537
  });
538
+ importMap.forEach((importSet, libName) => {
539
+ s.prepend(`import { ${Array.from(importSet).join(", ")} } from '${libName}';
540
+ `);
541
+ });
542
+ return {
543
+ content: s.toString(),
544
+ declareModules
545
+ };
508
546
  }
509
- const pureImportRE = /^import\s?['"][^;\n]+?['"];?\n?/g;
510
- function removePureImport(content) {
511
- return content.replace(pureImportRE, "");
512
- }
513
- const asDefaultRE = /export\s*\{.*\w+\s*\bas\s+default\b.*\}\s*from\s*['"].+['"]/;
514
547
  function hasExportDefault(content) {
515
- return content.includes("export default") || asDefaultRE.test(content);
548
+ const ast = ts__default.createSourceFile("a.ts", content, ts__default.ScriptTarget.Latest);
549
+ let has = false;
550
+ walkSourceFile(ast, (node) => {
551
+ if (ts__default.isExportAssignment(node)) {
552
+ has = true;
553
+ } else if (ts__default.isExportDeclaration(node) && node.exportClause && ts__default.isNamedExports(node.exportClause)) {
554
+ for (const element of node.exportClause.elements) {
555
+ if (element.name.escapedText === "default") {
556
+ has = true;
557
+ }
558
+ }
559
+ }
560
+ return false;
561
+ });
562
+ return has;
516
563
  }
517
564
 
518
565
  const jsRE = /\.(m|c)?jsx?$/;
@@ -523,7 +570,8 @@ const mtjsRE = /\.m(t|j)sx?$/;
523
570
  const ctjsRE = /\.c(t|j)sx?$/;
524
571
  const fullRelativeRE = /^\.\.?\//;
525
572
  const defaultIndex = "index.d.ts";
526
- const logPrefix = kolorist.cyan("[vite:dts]");
573
+ const pluginName = "vite:dts";
574
+ const logPrefix = kolorist.cyan(`[${pluginName}]`);
527
575
  const bundleDebug = debug__default("vite-plugin-dts:bundle");
528
576
  const fixedCompilerOptions = {
529
577
  noEmit: false,
@@ -539,6 +587,7 @@ const fixedCompilerOptions = {
539
587
  const noop = () => {
540
588
  };
541
589
  const extPrefix = (file) => mtjsRE.test(file) ? "m" : ctjsRE.test(file) ? "c" : "";
590
+ const tsToDts = (path) => `${path.replace(tsRE, "")}.d.ts`;
542
591
  const regexpSymbolRE = /([$.\\+?()[\]!<=|{}^,])/g;
543
592
  const asteriskRE = /[*]+/g;
544
593
  function dtsPlugin(options = {}) {
@@ -589,8 +638,11 @@ function dtsPlugin(options = {}) {
589
638
  const outputFiles = /* @__PURE__ */ new Map();
590
639
  const rollupConfig = { ...options.rollupConfig || {} };
591
640
  rollupConfig.bundledPackages = rollupConfig.bundledPackages || options.bundledPackages || [];
641
+ const cleanPath = (path) => {
642
+ return cleanVueFileName ? path.replace(".vue.d.ts", ".d.ts") : path;
643
+ };
592
644
  return {
593
- name: "vite:dts",
645
+ name: pluginName,
594
646
  apply: "build",
595
647
  enforce: "pre",
596
648
  config(config) {
@@ -745,12 +797,16 @@ ${logPrefix} ${kolorist.yellow(
745
797
  publicRoot = normalizePath(publicRoot);
746
798
  entryRoot = entryRoot || publicRoot;
747
799
  entryRoot = ensureAbsolute(entryRoot, root);
748
- const diagnostics = program.getDeclarationDiagnostics();
800
+ const diagnostics = [
801
+ ...program.getDeclarationDiagnostics(),
802
+ ...program.getSemanticDiagnostics(),
803
+ ...program.getSyntacticDiagnostics()
804
+ ];
749
805
  if (diagnostics?.length) {
750
806
  logger.error(ts__default.formatDiagnosticsWithColorAndContext(diagnostics, host));
751
807
  }
752
808
  if (typeof afterDiagnostic === "function") {
753
- await wrapPromise(afterDiagnostic(diagnostics));
809
+ await unwrapPromise(afterDiagnostic(diagnostics));
754
810
  }
755
811
  rootNames.forEach((file) => {
756
812
  this.addWatchFile(file);
@@ -826,9 +882,10 @@ ${logPrefix} Start generate declaration files...`));
826
882
  const startTime = Date.now();
827
883
  const outDir = outDirs[0];
828
884
  const emittedFiles = /* @__PURE__ */ new Map();
885
+ const declareModules = [];
829
886
  const writeOutput = async (path, content, outDir2, record = true) => {
830
887
  if (typeof beforeWriteFile === "function") {
831
- const result = await wrapPromise(beforeWriteFile(path, content));
888
+ const result = await unwrapPromise(beforeWriteFile(path, content));
832
889
  if (result === false)
833
890
  return;
834
891
  if (result) {
@@ -872,17 +929,27 @@ ${logPrefix} Start generate declaration files...`));
872
929
  await runParallel(
873
930
  node_os.cpus().length,
874
931
  Array.from(outputFiles.entries()),
875
- async ([path, content]) => {
876
- const isMapFile = path.endsWith(".map");
877
- const baseDir = node_path.dirname(path);
932
+ async ([filePath, content]) => {
933
+ const isMapFile = filePath.endsWith(".map");
934
+ const baseDir = node_path.dirname(filePath);
878
935
  if (!isMapFile && content) {
879
- content = clearPureImport ? removePureImport(content) : content;
880
- content = transformAliasImport(path, content, aliases, aliasesExclude);
881
- content = staticImport || rollupTypes ? transformDynamicImport(content) : content;
936
+ const result = transformCode({
937
+ filePath,
938
+ content,
939
+ aliases,
940
+ aliasesExclude,
941
+ staticImport,
942
+ clearPureImport
943
+ });
944
+ content = result.content;
945
+ declareModules.push(...result.declareModules);
882
946
  }
883
- path = resolve(
947
+ filePath = resolve(
884
948
  outDir,
885
- node_path.relative(entryRoot, cleanVueFileName ? path.replace(".vue.d.ts", ".d.ts") : path)
949
+ node_path.relative(
950
+ entryRoot,
951
+ cleanVueFileName ? filePath.replace(".vue.d.ts", ".d.ts") : filePath
952
+ )
886
953
  );
887
954
  content = cleanVueFileName ? content.replace(vuePathRE, '"$1"') : content;
888
955
  if (isMapFile) {
@@ -891,17 +958,17 @@ ${logPrefix} Start generate declaration files...`));
891
958
  sourceMap.sources = sourceMap.sources.map((source) => {
892
959
  return normalizePath(
893
960
  node_path.relative(
894
- node_path.dirname(path),
961
+ node_path.dirname(filePath),
895
962
  resolve(currentDir, node_path.relative(publicRoot, baseDir), source)
896
963
  )
897
964
  );
898
965
  });
899
966
  content = JSON.stringify(sourceMap);
900
967
  } catch (e) {
901
- logger.warn(`${logPrefix} ${kolorist.yellow("Processing source map fail:")} ${path}`);
968
+ logger.warn(`${logPrefix} ${kolorist.yellow("Processing source map fail:")} ${filePath}`);
902
969
  }
903
970
  }
904
- await writeOutput(path, content, outDir);
971
+ await writeOutput(filePath, content, outDir);
905
972
  }
906
973
  );
907
974
  bundleDebug("write output");
@@ -915,9 +982,6 @@ ${logPrefix} Start generate declaration files...`));
915
982
  const entryNames = Object.keys(entries);
916
983
  const types = findTypesPath(pkg.publishConfig, pkg);
917
984
  const multiple = entryNames.length > 1;
918
- const cleanPath = (path) => {
919
- return cleanVueFileName ? path.replace(".vue.d.ts", ".d.ts") : path;
920
- };
921
985
  let typesPath = cleanPath(types ? resolve(root, types) : resolve(outDir, indexName));
922
986
  if (!multiple && !dtsRE.test(typesPath)) {
923
987
  logger.warn(
@@ -930,23 +994,23 @@ ${logPrefix} ${kolorist.yellow(
930
994
  typesPath = `${typesPath.replace(tjsRE, "")}.d.${extPrefix(typesPath)}ts`;
931
995
  }
932
996
  for (const name of entryNames) {
933
- const path = multiple ? cleanPath(resolve(outDir, `${name.replace(tsRE, "")}.d.ts`)) : typesPath;
934
- if (node_fs.existsSync(path))
997
+ const entryDtsPath = multiple ? cleanPath(resolve(outDir, tsToDts(name))) : typesPath;
998
+ if (node_fs.existsSync(entryDtsPath))
935
999
  continue;
936
- const index = cleanPath(
937
- resolve(outDir, node_path.relative(entryRoot, `${entries[name].replace(tsRE, "")}.d.ts`))
1000
+ const sourceEntry = normalizePath(
1001
+ cleanPath(resolve(outDir, node_path.relative(entryRoot, tsToDts(entries[name]))))
938
1002
  );
939
- let fromPath = normalizePath(node_path.relative(node_path.dirname(path), index));
1003
+ let fromPath = normalizePath(node_path.relative(node_path.dirname(entryDtsPath), sourceEntry));
940
1004
  fromPath = fromPath.replace(dtsRE, "");
941
1005
  fromPath = fullRelativeRE.test(fromPath) ? fromPath : `./${fromPath}`;
942
1006
  let content = `export * from '${fromPath}'
943
1007
  `;
944
- if (node_fs.existsSync(index) && hasExportDefault(await promises.readFile(index, "utf-8"))) {
1008
+ if (emittedFiles.has(sourceEntry) && hasExportDefault(emittedFiles.get(sourceEntry))) {
945
1009
  content += `import ${libName} from '${fromPath}'
946
1010
  export default ${libName}
947
1011
  `;
948
1012
  }
949
- await writeOutput(cleanPath(path), content, outDir);
1013
+ await writeOutput(cleanPath(entryDtsPath), content, outDir);
950
1014
  }
951
1015
  bundleDebug("insert index");
952
1016
  if (rollupTypes) {
@@ -964,7 +1028,7 @@ export default ${libName}
964
1028
  const compilerOptions2 = configPath ? getTsConfig(configPath, host.readFile).compilerOptions : rawCompilerOptions;
965
1029
  if (multiple) {
966
1030
  for (const name of entryNames) {
967
- const path = cleanPath(resolve(outDir, `${name.replace(tsRE, "")}.d.ts`));
1031
+ const path = cleanPath(resolve(outDir, tsToDts(name)));
968
1032
  rollupDeclarationFiles({
969
1033
  root,
970
1034
  configPath,
@@ -997,9 +1061,16 @@ export default ${libName}
997
1061
  await runParallel(node_os.cpus().length, Array.from(emittedFiles.keys()), (f) => promises.unlink(f));
998
1062
  removeDirIfEmpty(outDir);
999
1063
  emittedFiles.clear();
1000
- for (const file of rollupFiles) {
1001
- emittedFiles.set(file, await promises.readFile(file, "utf-8"));
1002
- }
1064
+ const declared = declareModules.join("\n");
1065
+ await runParallel(node_os.cpus().length, [...rollupFiles], async (filePath) => {
1066
+ await writeOutput(
1067
+ filePath,
1068
+ await promises.readFile(filePath, "utf-8") + (declared ? `
1069
+ ${declared}
1070
+ ` : ""),
1071
+ node_path.dirname(filePath)
1072
+ );
1073
+ });
1003
1074
  bundleDebug("rollup output");
1004
1075
  }
1005
1076
  }
@@ -1021,7 +1092,7 @@ export default ${libName}
1021
1092
  });
1022
1093
  }
1023
1094
  if (typeof afterBuild === "function") {
1024
- await wrapPromise(afterBuild(emittedFiles));
1095
+ await unwrapPromise(afterBuild(emittedFiles));
1025
1096
  }
1026
1097
  bundleDebug("finish");
1027
1098
  logger.info(