@bunup/dts 0.14.51 → 0.14.53

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.
Files changed (2) hide show
  1. package/dist/index.js +146 -20
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,15 +1,10 @@
1
1
  // src/generate.ts
2
2
  import { rm } from "node:fs/promises";
3
3
  import path3 from "node:path";
4
+ import { parse as parse3 } from "@babel/parser";
4
5
  import { isolatedDeclaration } from "oxc-transform";
5
6
  import { resolveTsImportPath } from "ts-import-resolver";
6
7
 
7
- // src/constants.ts
8
- var EMPTY_EXPORT = "export {};";
9
-
10
- // src/fake/dts-to-fake-js.ts
11
- import { parse } from "@babel/parser";
12
-
13
8
  // src/re.ts
14
9
  var IMPORT_TYPE_RE = /import\s+type\s+/g;
15
10
  var EXPORT_TYPE_RE = /export\s+type\s+/g;
@@ -148,6 +143,31 @@ function getAllImportNames(body) {
148
143
  }
149
144
  return importNames;
150
145
  }
146
+ function getNamespaceImports(body) {
147
+ const result = [];
148
+ for (const statement of body) {
149
+ if (isImportDeclaration(statement)) {
150
+ const importDecl = statement;
151
+ if (importDecl.specifiers) {
152
+ for (const specifier of importDecl.specifiers) {
153
+ if (specifier.type === "ImportNamespaceSpecifier") {
154
+ result.push({
155
+ alias: specifier.local.name,
156
+ specifier: importDecl.source.value
157
+ });
158
+ }
159
+ }
160
+ }
161
+ }
162
+ }
163
+ return result;
164
+ }
165
+
166
+ // src/constants.ts
167
+ var EMPTY_EXPORT = "export {};";
168
+
169
+ // src/fake/dts-to-fake-js.ts
170
+ import { parse } from "@babel/parser";
151
171
 
152
172
  // src/utils.ts
153
173
  import { existsSync } from "node:fs";
@@ -377,7 +397,14 @@ async function dtsToFakeJs(dtsContent) {
377
397
  const referencedNames = new Set;
378
398
  const exportedNames = new Set;
379
399
  const staticImportedVars = new Set;
400
+ const namespaceMembers = new Map;
380
401
  const result = [];
402
+ const exportAssignmentNames = new Set;
403
+ for (const stmt of parsed.program.body) {
404
+ if (stmt.type === "TSExportAssignment" && stmt.expression.type === "Identifier") {
405
+ exportAssignmentNames.add(stmt.expression.name);
406
+ }
407
+ }
381
408
  for (const name of getAllImportNames(parsed.program.body)) {
382
409
  referencedNames.add(name);
383
410
  }
@@ -413,11 +440,54 @@ async function dtsToFakeJs(dtsContent) {
413
440
  if (statement.type === "TSExportAssignment") {
414
441
  if (statement.expression.type === "Identifier") {
415
442
  result.push(`export { ${statement.expression.name} as default }`);
443
+ const members = namespaceMembers.get(statement.expression.name);
444
+ if (members) {
445
+ for (const member of members) {
446
+ if (!exportedNames.has(member)) {
447
+ result.push(`export { ${member} };`);
448
+ exportedNames.add(member);
449
+ }
450
+ }
451
+ }
416
452
  } else if (statement.expression.start && statement.expression.end) {
417
453
  result.push(`export default ${dtsContent.substring(statement.expression.start, statement.expression.end)}`);
418
454
  }
419
455
  continue;
420
456
  }
457
+ if (statement.type === "TSModuleDeclaration" && statement.body?.type === "TSModuleBlock" && statement.id?.type === "Identifier") {
458
+ const memberNames = [];
459
+ const shouldExportMembers = hasExportModifier(statement, statementText) || exportAssignmentNames.has(name ?? "");
460
+ for (const member of statement.body.body) {
461
+ if (isNullOrUndefined(member.start) || isNullOrUndefined(member.end)) {
462
+ continue;
463
+ }
464
+ const memberText = dtsContent.substring(member.start, member.end);
465
+ const memberName = getName(member, dtsContent);
466
+ if (!memberName)
467
+ continue;
468
+ memberNames.push(memberName);
469
+ referencedNames.add(memberName);
470
+ const leadingComment2 = getCommentText(member.leadingComments);
471
+ let memberTextWithComments = `${leadingComment2 ? `${leadingComment2}
472
+ ` : ""}${memberText}`;
473
+ if (hasExportModifier(member, memberText)) {
474
+ memberTextWithComments = removeExportSyntaxes(memberTextWithComments);
475
+ }
476
+ const { tokens: tokens2, extras: extras2 } = tokenizeText(memberTextWithComments, referencedNames, staticImportedVars);
477
+ for (const extra of extras2) {
478
+ result.push(extra);
479
+ }
480
+ result.push(`var ${memberName} = [${tokens2.join(", ")}];`);
481
+ if (shouldExportMembers && !exportedNames.has(memberName)) {
482
+ result.push(`export { ${memberName} };`);
483
+ exportedNames.add(memberName);
484
+ }
485
+ }
486
+ if (name) {
487
+ namespaceMembers.set(name, memberNames);
488
+ }
489
+ continue;
490
+ }
421
491
  let leadingComment = null;
422
492
  leadingComment = getCommentText(statement.leadingComments);
423
493
  let statementTextWithCommentsAttached = `${leadingComment ? `${leadingComment}
@@ -478,7 +548,7 @@ function tokenizeText(text, referencedNames, staticImportedVars) {
478
548
  }
479
549
  // src/fake/fake-js-to-dts.ts
480
550
  import { parse as parse2 } from "@babel/parser";
481
- async function fakeJsToDts(fakeJsContent) {
551
+ async function fakeJsToDts(fakeJsContent, namespaceAliasMap) {
482
552
  const parseResult = parse2(fakeJsContent, {
483
553
  sourceType: "module",
484
554
  attachComment: false
@@ -491,15 +561,18 @@ async function fakeJsToDts(fakeJsContent) {
491
561
  }
492
562
  const statementText = fakeJsContent.substring(statement.start, statement.end);
493
563
  if (isImportDeclaration(statement) || isExportAllDeclaration(statement) || isReExportStatement(statement)) {
494
- if (isImportDeclaration(statement)) {
495
- resultParts.push(statementText.replace(/\.(mjs|cjs|js)\b/g, ""));
496
- continue;
564
+ if (namespaceAliasMap?.size && isReExportStatement(statement)) {
565
+ const fixedText = fixExportSpecifiers(statement, namespaceAliasMap);
566
+ if (fixedText) {
567
+ resultParts.push(fixedText);
568
+ continue;
569
+ }
497
570
  }
498
571
  resultParts.push(statementText);
499
572
  continue;
500
573
  }
501
574
  if (statement.type === "ExpressionStatement") {
502
- const namespaceDecl = handleNamespace(statement);
575
+ const namespaceDecl = handleNamespace(statement, namespaceAliasMap);
503
576
  if (namespaceDecl) {
504
577
  resultParts.push(namespaceDecl);
505
578
  continue;
@@ -520,7 +593,7 @@ async function fakeJsToDts(fakeJsContent) {
520
593
  }
521
594
  }
522
595
  if (declaration.init?.type === "ArrayExpression") {
523
- const dtsContent = processTokenArray(declaration.init);
596
+ const dtsContent = processTokenArray(declaration.init, namespaceAliasMap);
524
597
  if (dtsContent) {
525
598
  resultParts.push(dtsContent);
526
599
  }
@@ -569,7 +642,7 @@ function convertCallExpressionToString(node) {
569
642
  }).filter(Boolean).join(", ");
570
643
  return `${callee}(${args})`;
571
644
  }
572
- function processTokenArray(arrayLiteral) {
645
+ function processTokenArray(arrayLiteral, namespaceAliasMap) {
573
646
  if (arrayLiteral.type !== "ArrayExpression") {
574
647
  return null;
575
648
  }
@@ -577,19 +650,19 @@ function processTokenArray(arrayLiteral) {
577
650
  for (const element of arrayLiteral.elements) {
578
651
  if (!element)
579
652
  continue;
580
- const processed = processTokenElement(element);
653
+ const processed = processTokenElement(element, namespaceAliasMap);
581
654
  if (processed !== null) {
582
655
  tokens.push(processed);
583
656
  }
584
657
  }
585
658
  return tokens.join("");
586
659
  }
587
- function processTokenElement(element) {
660
+ function processTokenElement(element, namespaceAliasMap) {
588
661
  if (element.type === "StringLiteral" && typeof element.value === "string") {
589
662
  return unescapeNewlinesAndTabs(element.value);
590
663
  }
591
664
  if (element.type === "Identifier") {
592
- return element.name;
665
+ return namespaceAliasMap?.get(element.name) ?? element.name;
593
666
  }
594
667
  if (element.type === "TemplateLiteral") {
595
668
  const parts = [];
@@ -597,7 +670,7 @@ function processTokenElement(element) {
597
670
  for (let i = 0;i < element.expressions.length; i++) {
598
671
  const expr = element.expressions[i];
599
672
  if (expr?.type === "Identifier") {
600
- parts.push(expr.name);
673
+ parts.push(namespaceAliasMap?.get(expr.name) ?? expr.name);
601
674
  }
602
675
  parts.push(unescapeNewlinesAndTabs(element.quasis[i + 1]?.value?.raw || ""));
603
676
  }
@@ -605,12 +678,13 @@ function processTokenElement(element) {
605
678
  }
606
679
  return null;
607
680
  }
608
- function handleNamespace(stmt) {
681
+ function handleNamespace(stmt, namespaceAliasMap) {
609
682
  const expr = stmt.expression;
610
683
  if (!expr || expr.type !== "CallExpression" || expr.callee?.type !== "Identifier" || expr.arguments?.length !== 2 || expr.arguments[0]?.type !== "Identifier" || expr.arguments[1]?.type !== "ObjectExpression") {
611
684
  return null;
612
685
  }
613
- const namespaceName = expr.arguments[0].name;
686
+ const rawName = expr.arguments[0].name;
687
+ const namespaceName = namespaceAliasMap?.get(rawName) ?? rawName;
614
688
  const properties = expr.arguments[1].properties.filter((prop) => prop.type === "ObjectProperty").map((prop) => {
615
689
  if (prop.type === "ObjectProperty" && prop.key.type === "Identifier" && prop.value.type === "ArrowFunctionExpression" && prop.value.body.type === "Identifier") {
616
690
  const keyName = prop.key.name;
@@ -626,6 +700,35 @@ function handleNamespace(stmt) {
626
700
  export { ${properties.join(", ")} };
627
701
  }`;
628
702
  }
703
+ function fixExportSpecifiers(statement, namespaceAliasMap) {
704
+ if (statement.type !== "ExportNamedDeclaration") {
705
+ return null;
706
+ }
707
+ const specifiers = statement.specifiers;
708
+ if (!specifiers?.length) {
709
+ return null;
710
+ }
711
+ let hasChange = false;
712
+ const fixedParts = [];
713
+ for (const spec of specifiers) {
714
+ if (spec.type !== "ExportSpecifier") {
715
+ return null;
716
+ }
717
+ const localName = spec.local.name;
718
+ const exportedName = spec.exported.type === "Identifier" ? spec.exported.name : spec.exported.value;
719
+ const alias = namespaceAliasMap.get(localName);
720
+ if (alias) {
721
+ hasChange = true;
722
+ fixedParts.push(alias === exportedName ? exportedName : `${alias} as ${exportedName}`);
723
+ } else {
724
+ fixedParts.push(localName === exportedName ? localName : `${localName} as ${exportedName}`);
725
+ }
726
+ }
727
+ if (!hasChange) {
728
+ return null;
729
+ }
730
+ return `export { ${fixedParts.join(", ")} };`;
731
+ }
629
732
  // src/resolver.ts
630
733
  import { dirname } from "node:path";
631
734
  import process2 from "node:process";
@@ -750,6 +853,7 @@ async function generateDts(entrypoints, options = {}) {
750
853
  tsconfig: tsconfig.filepath
751
854
  });
752
855
  let tsCompiledDist;
856
+ const namespaceAliasMap = new Map;
753
857
  try {
754
858
  const fakeJsPlugin = {
755
859
  name: "fake-js",
@@ -808,6 +912,28 @@ async function generateDts(entrypoints, options = {}) {
808
912
  }
809
913
  }
810
914
  if (declaration) {
915
+ if (!NODE_MODULES_RE.test(args.path)) {
916
+ try {
917
+ const parsed = parse3(declaration, {
918
+ sourceType: "module",
919
+ plugins: ["typescript"]
920
+ });
921
+ const nsImports = getNamespaceImports(parsed.program.body);
922
+ for (const nsImport of nsImports) {
923
+ const resolved = resolveTsImportPath({
924
+ importer: args.path,
925
+ path: nsImport.specifier,
926
+ cwd,
927
+ tsconfig: tsconfig.config
928
+ });
929
+ if (resolved) {
930
+ const stem = path3.basename(resolved).replace(/\.[^.]+$/, "");
931
+ const mangledName = `exports_${stem}`;
932
+ namespaceAliasMap.set(mangledName, nsImport.alias);
933
+ }
934
+ }
935
+ } catch {}
936
+ }
811
937
  fakeJsContent = await dtsToFakeJs(declaration);
812
938
  } else {
813
939
  fakeJsContent = EMPTY_EXPORT;
@@ -872,7 +998,7 @@ Ensure all your entrypoints match these patterns, or add them explicitly.
872
998
  const bundledFiles = [];
873
999
  for (const output of outputs) {
874
1000
  const bundledFakeJsContent = await output.text();
875
- const dtsContent = await fakeJsToDts(bundledFakeJsContent);
1001
+ const dtsContent = await fakeJsToDts(bundledFakeJsContent, namespaceAliasMap);
876
1002
  const entrypoint = output.kind === "entry-point" ? cleanPath(getOriginalEntrypointFromOutputPath(result.metafile, output.path, cwd)) : undefined;
877
1003
  const chunkFileName = output.kind === "chunk" ? replaceExtension(path3.basename(output.path), getDeclarationExtensionFromJsExtension(getExtension(output.path))) : undefined;
878
1004
  const outputPath = cleanPath(replaceExtension(cleanPath(output.path), getDeclarationExtensionFromJsExtension(getExtension(output.path))));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bunup/dts",
3
- "version": "0.14.51",
3
+ "version": "0.14.53",
4
4
  "description": "An extremely fast TypeScript declaration bundler built on Bun's native bundler.",
5
5
  "homepage": "https://github.com/bunup/dts#readme",
6
6
  "bugs": {