susee 1.6.0 → 1.6.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/dist/index.mjs CHANGED
@@ -598,78 +598,114 @@ var utils;
598
598
  gen.findProperty = findProperty;
599
599
  })(gen = utils.gen || (utils.gen = {})); // namespace gen
600
600
  })(utils || (utils = {})); // namespace utils
601
+ const getScopeNodeLabel = (sourceFile, node, index) => {
602
+ if (ts6.isModuleDeclaration(node)) {
603
+ return `namespace:${node.name.getText(sourceFile)}`;
604
+ }
605
+ if (ts6.isClassDeclaration(node)) {
606
+ return `class:${node.name?.text ?? `anonymous-${index}`}`;
607
+ }
608
+ if (ts6.isFunctionDeclaration(node) || ts6.isFunctionExpression(node)) {
609
+ return `function:${node.name?.text ?? `anonymous-${index}`}`;
610
+ }
611
+ if (ts6.isArrowFunction(node)) {
612
+ return `arrow:${index}`;
613
+ }
614
+ if (ts6.isMethodDeclaration(node)) {
615
+ return `method:${node.name.getText(sourceFile)}`;
616
+ }
617
+ if (ts6.isBlock(node)) {
618
+ return `block:${index}`;
619
+ }
620
+ return `${ts6.SyntaxKind[node.kind].toLowerCase()}:${index}`;
621
+ };
622
+ const getScopeKey = (file, scopeStack) => {
623
+ if (scopeStack.length === 0) {
624
+ return "global";
625
+ }
626
+ return `${file}::${scopeStack.join(" > ")}`;
627
+ };
628
+ const isScopeNode = (node) => ts6.isModuleDeclaration(node) ||
629
+ ts6.isClassDeclaration(node) ||
630
+ ts6.isFunctionDeclaration(node) ||
631
+ ts6.isFunctionExpression(node) ||
632
+ ts6.isArrowFunction(node) ||
633
+ ts6.isMethodDeclaration(node) ||
634
+ ts6.isBlock(node);
635
+ const collectDeclarationNames = (node) => {
636
+ if (ts6.isVariableStatement(node)) {
637
+ return node.declarationList.declarations.flatMap((decl) => {
638
+ if (!ts6.isIdentifier(decl.name)) {
639
+ return [];
640
+ }
641
+ return [{ name: decl.name.text, positionNode: decl.name }];
642
+ });
643
+ }
644
+ if (ts6.isFunctionDeclaration(node) ||
645
+ ts6.isClassDeclaration(node) ||
646
+ ts6.isEnumDeclaration(node) ||
647
+ ts6.isInterfaceDeclaration(node) ||
648
+ ts6.isTypeAliasDeclaration(node)) {
649
+ if (node.name) {
650
+ return [{ name: node.name.text, positionNode: node.name }];
651
+ }
652
+ }
653
+ return [];
654
+ };
601
655
  const collectDuplicateDeclarations = (deps, bundledSourceFile) => {
602
656
  const duplicateNameMap = new Map();
603
- const addDuplicateDeclaration = (name, file, sourceFile, positionNode) => {
657
+ const addDuplicateDeclaration = (scopeKey, name, file, sourceFile, positionNode) => {
604
658
  const { line, character } = sourceFile.getLineAndCharacterOfPosition(positionNode.getStart(sourceFile));
605
659
  const location = {
606
660
  file,
607
661
  line: line + 1,
608
662
  column: character + 1,
609
663
  };
610
- if (!duplicateNameMap.has(name)) {
611
- duplicateNameMap.set(name, new Set([location]));
664
+ const duplicateKey = `${scopeKey}::${name}`;
665
+ if (!duplicateNameMap.has(duplicateKey)) {
666
+ duplicateNameMap.set(duplicateKey, {
667
+ name,
668
+ locations: new Set([location]),
669
+ });
612
670
  return;
613
671
  }
614
- duplicateNameMap.get(name)?.add(location);
672
+ duplicateNameMap.get(duplicateKey)?.locations.add(location);
615
673
  };
616
- const collectFile = (file, sourceFile, node, isGlobalScope = true) => {
617
- if (isGlobalScope) {
618
- if (ts6.isVariableStatement(node)) {
619
- node.declarationList.declarations.forEach((decl) => {
620
- if (ts6.isIdentifier(decl.name)) {
621
- const name = decl.name.text;
622
- addDuplicateDeclaration(name, file, sourceFile, decl.name);
623
- }
624
- });
625
- }
626
- else if (ts6.isFunctionDeclaration(node) ||
627
- ts6.isClassDeclaration(node) ||
628
- ts6.isEnumDeclaration(node) ||
629
- ts6.isInterfaceDeclaration(node) ||
630
- ts6.isTypeAliasDeclaration(node)) {
631
- const name = node.name?.text;
632
- if (name) {
633
- addDuplicateDeclaration(name, file, sourceFile, node.name);
634
- }
635
- }
636
- }
637
- if (ts6.isBlock(node) ||
638
- ts6.isFunctionDeclaration(node) ||
639
- ts6.isFunctionExpression(node) ||
640
- ts6.isArrowFunction(node) ||
641
- ts6.isMethodDeclaration(node) ||
642
- ts6.isClassDeclaration(node)) {
643
- if (ts6.isBlock(node)) {
644
- node.statements.forEach((child) => collectFile(file, sourceFile, child, false));
645
- }
646
- else {
647
- ts6.forEachChild(node, (child) => {
648
- collectFile(file, sourceFile, child, false);
649
- });
650
- }
674
+ const collectFile = (file, sourceFile, node, scopeStack = []) => {
675
+ const scopeKey = getScopeKey(file, scopeStack);
676
+ for (const declaration of collectDeclarationNames(node)) {
677
+ addDuplicateDeclaration(scopeKey, declaration.name, file, sourceFile, declaration.positionNode);
678
+ }
679
+ if (isScopeNode(node)) {
680
+ const nextScopeStack = [
681
+ ...scopeStack,
682
+ getScopeNodeLabel(sourceFile, node, node.getStart(sourceFile)),
683
+ ];
684
+ ts6.forEachChild(node, (child) => {
685
+ collectFile(file, sourceFile, child, nextScopeStack);
686
+ });
651
687
  return;
652
688
  }
653
689
  ts6.forEachChild(node, (child) => {
654
- collectFile(file, sourceFile, child, isGlobalScope);
690
+ collectFile(file, sourceFile, child, scopeStack);
655
691
  });
656
692
  };
657
693
  for (const dep of deps) {
658
694
  const sourceFile = bundledSourceFile(dep.file, dep.content);
659
- collectFile(dep.file, sourceFile, sourceFile, true);
695
+ collectFile(dep.file, sourceFile, sourceFile);
660
696
  }
661
697
  return duplicateNameMap;
662
698
  };
663
699
  const checkDuplicates = (tree, bundledSourceFile) => {
664
700
  let _err = false;
665
701
  const duplicateNameMap = collectDuplicateDeclarations(tree.depFiles, bundledSourceFile);
666
- duplicateNameMap.forEach((files, name) => {
667
- if (files.size > 1) {
702
+ duplicateNameMap.forEach(({ name, locations }) => {
703
+ if (locations.size > 1) {
668
704
  _err = true;
669
705
  console.warn(tcolor.yellow("[susee:error]"));
670
706
  console.warn(" Duplicate declarations found in your dependencies tree as follows:");
671
707
  console.warn(` - "${tcolor.magenta(name)}" declared in multiple files : `);
672
- files.forEach((f) => console.warn(` - ${f.file}:${f.line}:${f.column}`));
708
+ locations.forEach((f) => console.warn(` - ${f.file}:${f.line}:${f.column}`));
673
709
  console.info("Please rename these with different names to avoid duplicate declarations.");
674
710
  }
675
711
  });
@@ -2381,7 +2417,7 @@ async function bundle(entry) {
2381
2417
  return await bundler(entry);
2382
2418
  }
2383
2419
  //package.json
2384
- const __jsonModule__package = { "name": "susee", "version": "1.6.0", "description": "TypeScript-first bundler for library packages", "type": "module", "main": "dist/index.cjs", "types": "dist/index.d.cts", "module": "dist/index.mjs", "exports": { ".": { "import": { "types": "./dist/index.d.mts", "default": "./dist/index.mjs" }, "require": { "types": "./dist/index.d.cts", "default": "./dist/index.cjs" } } }, "bin": { "susee": "bin/susee" }, "scripts": { "build": "tsx build.ts", "lint": "biome lint ./src ./__tests__ --write", "fmt": "biome format --write", "test": "tsx --test", "coverage": "npx tsx --test --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=__tests__/coverage/lcov.info", "hooks:install": "bash scripts/install-hooks.sh", "commit": "bash scripts/commit.sh", "v:patch": "npm version patch --no-git-tag-version", "v:minor": "npm version minor --no-git-tag-version", "v:major": "npm version major --no-git-tag-version", "vercel:install": "npm i mmcov shiki tsx && bundle install", "vercel:build": "bash scripts/vercel_build.sh", "docs:dev": "bundle exec jekyll serve --profile", "docs:init": "bash scripts/setup.sh" }, "keywords": ["bundler", "susee", "suseejs"], "author": { "name": "Pho Thin Mg", "email": "phothinmg@disroot.org", "url": "https://phothinmg.github.io/" }, "license": "Apache-2.0", "files": ["package.json", "README.md", "LICENSE", "dist/**/*", "bin/**/*"], "publishConfig": { "provenance": true, "access": "public" }, "repository": { "url": "git+https://github.com/phothinmg/susee.git", "type": "git" }, "homepage": "https://susee.js.org/", "bugs": { "url": "https://github.com/phothinmg/susee/issues" }, "dependencies": { "@suseejs/color": "^0.0.9", "@suseejs/ts6": "^1.0.0", "mmcov": "^0.0.8", "shiki": "^4.3.1" }, "devDependencies": { "@biomejs/biome": "^2.4.12", "@suseejs/banner-text-plugin": "^0.0.9", "@suseejs/terser-plugin": "^0.0.9", "@suseejs/type": "^0.0.9", "@types/node": "^25.6.0", "tsx": "^4.21.0", "typescript": "^7.0.2" }, "allowScripts": { "esbuild@0.28.1": true } };
2420
+ const __jsonModule__package = { "name": "susee", "version": "1.6.2", "description": "TypeScript-first bundler for library packages", "type": "module", "main": "dist/index.cjs", "types": "dist/index.d.cts", "module": "dist/index.mjs", "exports": { ".": { "import": { "types": "./dist/index.d.mts", "default": "./dist/index.mjs" }, "require": { "types": "./dist/index.d.cts", "default": "./dist/index.cjs" } } }, "bin": { "susee": "bin/susee" }, "scripts": { "build": "tsx build.ts", "lint": "biome lint ./src ./__tests__ --write", "fmt": "biome format --write", "test": "tsx --test", "hooks:install": "bash scripts/install-hooks.sh", "commit": "bash scripts/commit.sh", "v:patch": "npm version patch --no-git-tag-version", "v:minor": "npm version minor --no-git-tag-version", "v:major": "npm version major --no-git-tag-version" }, "keywords": ["bundler", "susee", "suseejs"], "author": "Pho Thin Mg <phothinmg@disroot.org> (https://phothinmg.github.io/)", "license": "Apache-2.0", "files": ["package.json", "README.md", "LICENSE", "dist/**/*", "bin/**/*"], "publishConfig": { "provenance": true, "access": "public" }, "repository": { "url": "git+https://github.com/phothinmg/susee.git", "type": "git" }, "homepage": "https://susee.js.org/", "bugs": { "url": "https://github.com/phothinmg/susee/issues" }, "dependencies": { "@suseejs/color": "^0.0.9", "@suseejs/ts6": "^1.0.0" }, "devDependencies": { "@biomejs/biome": "^2.4.12", "@suseejs/banner-text-plugin": "^0.0.9", "@suseejs/type": "^0.0.9", "@types/node": "^25.6.0", "tsx": "^4.23.1", "typescript": "^7.0.2" }, "allowScripts": { "esbuild@0.28.1": true }, "workspaces": ["susee-docs"] };
2385
2421
  /**
2386
2422
  * Finds the path of the susee.config file if it exists.
2387
2423
  * It checks for the existence of "susee.config.ts", "susee.config.js", and "susee.config.mjs" in the current working directory.