mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-03 02:21:44 +00:00
* fix(typescript): resolve tsconfig `paths` aliases on Windows `rebaseTarget` turns a `paths` target that `path.resolve` produced back into a repo-relative one, and it recognised the wildcard suffix only as `/*`. On Windows the resolved target is `C:\repo\src\*`, so the check never matched, the bare-`*` branch stripped the star, `path.relative` ate the trailing backslash, and every alias target came back as `src*`. `substituteStar` then built `srclib/date` from `@/lib/date`, nothing resolved, and every alias import was dropped as external — no IMPORTS/CALLS edge for anything reached through `@/`, so `impact` answered UNKNOWN for a repo's whole shared layer. Normalise the separator before looking at the suffix. `tsconfig-index.test.ts` already asserts the `src/*` shape and fails 4 of 13 cases on Windows without this; it only ever ran on Ubuntu, so add it to the cross-platform lane. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(typescript): make `paths` rebasing assertable from any runner `rebaseTarget` reads the platform separator, but the only suite covering it builds real directories — so on Ubuntu it sees `/` whatever the code does with `\`, and only the windows-latest lane can fail it. That is how an alias bug affecting every Windows install reached a green CI in the first place. Thread an injectable `pathApi` through `rebaseTarget` and `repoRelative` — the seam `isInside` and the `\\?\` prefix guard already use — and add a fixture-free suite that pins the win32 and POSIX branches explicitly. Deleting the separator normalisation now fails on every runner rather than only on windows-latest. Registered beside its fixture sibling in the cross-platform lane so the two halves of the same rule stay discoverable as one group. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(typescript): emit a bare `*` for a repo-root `paths` target A target naming the repo ROOT — `"*": ["./*"]` under `"baseUrl": "."` — rebases to an EMPTY repo-relative prefix, so only the suffix survived and the encoding came out as `/*`. `substituteStar` turns that into `/lib/date`, and `resolveFile` matches repo-relative keys without stripping a leading slash, so the indexed `lib/date.ts` misses and the alias is dropped as external. Emit the bare `*` for that case instead, which substitutes to `lib/date` and resolves. This is the shipped POSIX encoding as much as the Windows one, and it is what the Windows path emitted by accident before the separator was normalised — so the normalisation does not narrow what already resolved there. The common `"@/*": ["./src/*"]` is untouched: it has a real prefix and stays `src/*`. Pinned at all three levels the encoding passes through: the rebaser, on both path flavours; the loader, through a real fixture; and resolution, where `*` finds the file and `/*` does not. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs(test): say why the root-wildcard fixture declares no `baseUrl` The comment introduced the fixture as `"baseUrl": "."`, which the loader encodes as `''`, while the fixture passes `null` — a different scope, since `null` means the config declares no baseUrl at all and takes the paths arm alone. `null` is the right fixture and the comment was the wrong half: with `''` the baseUrl arm resolves `packages/utils/src/index` by itself, so the negative case would return null for a reason unrelated to the target encoding. Verified by substitution — `''` makes that assertion report the file instead. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
83 lines
4.2 KiB
TypeScript
83 lines
4.2 KiB
TypeScript
/**
|
|
* `rebaseTarget` — `paths` target rebasing, across both path flavours.
|
|
*
|
|
* The fixture suite (`tsconfig-index.test.ts`) builds real directories, so it
|
|
* only ever sees the HOST separator: its `…/*` assertions are green on Ubuntu
|
|
* whatever `rebaseTarget` does with a backslash, and only the windows-latest
|
|
* lane can fail them. That is how the alias bug survived a green CI in the
|
|
* first place. Injecting `pathApi` — the seam `isInside` and the `\\?\` prefix
|
|
* guard already use — makes both platform branches assertable from any runner,
|
|
* so deleting the separator normalisation fails here on Ubuntu too.
|
|
*
|
|
* Two behaviours are pinned:
|
|
*
|
|
* - `path.resolve` emits `C:\repo\src\*` on Windows, so the `endsWith('/*')`
|
|
* check never matched, the bare-`*` branch ate the trailing separator, and
|
|
* every alias target came back as `src*` — `substituteStar` then produced
|
|
* `srclib/date`, which matches no file, so the common Vite/shadcn
|
|
* `"@/*": ["./src/*"]` resolved to nothing on Windows.
|
|
* - a repo-ROOT target (`"*": ["./*"]` under `baseUrl: "."`) rebases to an
|
|
* EMPTY prefix, and `${''}${'/*'}` is `/*`. `substituteStar('/*', 'lib/date')`
|
|
* yields `/lib/date`, and `resolveFile` matches repo-relative keys without
|
|
* a leading slash, so the alias went external. The bare `*` is the encoding
|
|
* that substitutes correctly, on both platforms.
|
|
*/
|
|
import { describe, it, expect } from 'vitest';
|
|
import path from 'node:path';
|
|
import { _rebaseTargetForTests as rebaseTarget } from '../../src/core/ingestion/languages/typescript/tsconfig.js';
|
|
|
|
describe('rebaseTarget — Windows separator normalisation', () => {
|
|
it('rebases the Vite/shadcn `@/*` target to `src/*`, not `src*`', () => {
|
|
// What `path.win32.resolve('C:\\repo', './src/*')` hands the rebaser.
|
|
expect(rebaseTarget('C:\\repo', 'C:\\repo\\src\\*', path.win32)).toBe('src/*');
|
|
});
|
|
|
|
it('rebases a nested monorepo target', () => {
|
|
expect(rebaseTarget('C:\\repo', 'C:\\repo\\packages\\ui\\src\\*', path.win32)).toBe(
|
|
'packages/ui/src/*',
|
|
);
|
|
});
|
|
|
|
it('leaves a starless target alone', () => {
|
|
expect(rebaseTarget('C:\\repo', 'C:\\repo\\src\\exact.ts', path.win32)).toBe('src/exact.ts');
|
|
});
|
|
|
|
it('produces the identical result on POSIX', () => {
|
|
// The normalisation is a no-op here — `split('/').join('/')` is identity —
|
|
// so these are the OLD values as much as the new ones. Pinning them keeps
|
|
// the Windows fix from being paid for with a POSIX regression.
|
|
expect(rebaseTarget('/repo', '/repo/src/*', path.posix)).toBe('src/*');
|
|
expect(rebaseTarget('/repo', '/repo/packages/ui/src/*', path.posix)).toBe('packages/ui/src/*');
|
|
expect(rebaseTarget('/repo', '/repo/src/exact.ts', path.posix)).toBe('src/exact.ts');
|
|
});
|
|
|
|
it('defaults to the platform-bound path module', () => {
|
|
const root = path.resolve('repo');
|
|
expect(rebaseTarget(root, path.resolve(root, './src/*'))).toBe('src/*');
|
|
});
|
|
});
|
|
|
|
describe('rebaseTarget — repo-root wildcard', () => {
|
|
it('emits a bare `*` rather than `/*` for a root target', () => {
|
|
// `"baseUrl": "."` with `"*": ["./*"]` — the target resolves to the repo
|
|
// root itself, so the repo-relative prefix is empty and only the suffix is
|
|
// left. `/*` substitutes to `/lib/date`, which no indexed key matches.
|
|
expect(rebaseTarget('/repo', '/repo/*', path.posix)).toBe('*');
|
|
expect(rebaseTarget('C:\\repo', 'C:\\repo\\*', path.win32)).toBe('*');
|
|
});
|
|
|
|
it('still emits `/*` once the target is one directory in', () => {
|
|
// The bare `*` is the empty-prefix case ONLY; a real prefix keeps its
|
|
// separator or `src*` comes back, which is the bug above wearing a
|
|
// different hat.
|
|
expect(rebaseTarget('/repo', '/repo/src/*', path.posix)).toBe('src/*');
|
|
expect(rebaseTarget('C:\\repo', 'C:\\repo\\src\\*', path.win32)).toBe('src/*');
|
|
});
|
|
|
|
it('leaves a starless root target as the empty prefix', () => {
|
|
// `resolveFile('')` is `null`, which is the honest answer for a target
|
|
// naming the repo root and no file. Unchanged by the wildcard rule.
|
|
expect(rebaseTarget('/repo', '/repo', path.posix)).toBe('');
|
|
expect(rebaseTarget('C:\\repo', 'C:\\repo', path.win32)).toBe('');
|
|
});
|
|
});
|