Don't have an account? `, still links as before. Re-index React projects after upgrading.
- In JavaScript and TypeScript, a name imported from a package your `package.json` lists no longer links to a project symbol that only shares its name when `tsconfig.json` or `jsconfig.json` has a catch-all path alias, like `"*": ["./typings/*"]` or `"*": ["src/*", "node_modules/*"]`, or an alias that points the package at a file in `node_modules`, like `"lit/decorators": ["./node_modules/lit/decorators.js"]`. Such an alias made every package look like part of the project, so `import { Typography } from '@mui/material'` was linked to the project's own `Typography` and every lit `@property()` decorator to an unrelated class's `property` field, and `codegraph callers`, impact and `codegraph affected` listed code that never used them. An import the alias does map to a file of your project, like a `.d.ts` you keep for an untyped package or `components/Button` through `"*": ["src/*"]`, links as before. Re-index affected projects after upgrading.
+- In JavaScript and TypeScript, a `tsconfig.json` or `jsconfig.json` path alias with text on both sides of its `*`, like `"@x/*/index": ["widgets/*/index"]`, no longer matches an import that leaves nothing for the `*`, like `@x/index`. Before, the one `/` in `@x/index` counted for both sides, so the import and every call through it linked to `widgets/index`, a file it never named; now the alias is skipped there, as TypeScript skips it, and a less specific alias can still match. Re-index affected projects after upgrading. Thanks @Dashsoap.
- In JavaScript and TypeScript, a function the file imports from a package and passes along as a value, like react-router's `Link` in `styled(Link)`, lodash's `noop` in `createContext({ onClose: noop })` or chart.js's `Legend` in `Chart.register(Legend)`, no longer links to a project function that only shares its name. Before, whenever the project had exactly one function of that name, every such value linked to it: outline's breadcrumbs, menus and document lists showed up among the callers of an email template's `Link`, and a test's own `noop` stub in cord-field among the code the app's contexts use, so `codegraph callers`, impact and `codegraph_explore` followed references that never happen. A function the file declares itself, including one that hides the import inside a function, and one imported from a file of your project link as before. Re-index JavaScript and TypeScript projects after upgrading.
- In JavaScript and TypeScript, a function a file loads with a dynamic import from Node or a package, like `const { createServer } = await import('node:http')`, `const { default: chalk } = await import('chalk')` or `import('node:fs/promises').then(({ readFile }) => …)`, no longer links to a project function that only shares its name. Before, vite's call to Node's `createServer` showed up among the callers of vite's own `createServer`. The import counts only where it is in scope, so the rest of the file links as before, and a dynamic import of your own project's module still leads to that module. Thanks @Ancienttwo for the report. (#2491)
- In JavaScript and TypeScript, code outside your tests no longer links to a Jest or Vitest manual mock under `__mocks__/`. Before, when an import of a workspace package couldn't be followed, a call like `formatLabel(name)` linked by name to the mock beside it instead of the package's own function, so the real function lost its callers, and the same happened to rendered components and event handlers. Production code is now matched as if the mocks weren't there, so it reaches the real function, and adding or deleting a mock leaves it alone. Tests, other mocks, and a file that imports a mock by its path, like a `jest.setup.ts`, still reach the mock. Thanks @Y-Osawa2022 for the report and @danusha2345. (#2455)
diff --git a/__tests__/path-alias-overlap.test.ts b/__tests__/path-alias-overlap.test.ts
new file mode 100644
index 000000000..a8aed8f8b
--- /dev/null
+++ b/__tests__/path-alias-overlap.test.ts
@@ -0,0 +1,96 @@
+/**
+ * A `paths` wildcard whose prefix and suffix overlap.
+ *
+ * `"@x/*\/index"` splits into the prefix `@x/` and the suffix `/index`. An
+ * import of `@x/index` starts with the one and ends with the other, but only
+ * by counting its single `/` twice: nothing is left for `*`. tsc's
+ * `isPatternMatch` asks for a specifier at least as long as the prefix and the
+ * suffix together, so it skips the pattern there. The resolver took the empty
+ * capture instead and linked the import, and every call through it, to
+ * `widgets/index` — a file the import never named.
+ */
+import { describe, it, expect, afterEach } from 'vitest';
+import * as fs from 'fs';
+import * as os from 'os';
+import * as path from 'path';
+import { CodeGraph } from '../src';
+import { applyAliases, loadProjectAliases } from '../src/resolution/path-aliases';
+
+let dirs: string[] = [];
+let graphs: CodeGraph[] = [];
+afterEach(() => {
+ for (const graph of graphs) graph.close();
+ for (const dir of dirs) fs.rmSync(dir, { recursive: true, force: true });
+ graphs = [];
+ dirs = [];
+});
+
+const project = (files: Record