Skip to content

Commit 299a3f8

Browse files
authored
Merge branch 'main' into fix/1502-rewrite-tsconfig-types
2 parents bc97a7a + 5439608 commit 299a3f8

411 files changed

Lines changed: 14503 additions & 4736 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/renovate.json

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,13 @@
1111
],
1212
"packageRules": [
1313
{
14-
"description": "Ignore selected npm package updates",
14+
"description": "Disable all npm updates (lockfile updates fail because vite/patches/* is gitignored)",
1515
"matchManagers": ["npm"],
16-
"matchPackageNames": [
17-
"rolldown",
18-
"/^oxc-.*/",
19-
"@oxc-node/*",
20-
"@oxc-project/*",
21-
"@vitejs/devtools",
22-
"oxfmt",
23-
"oxlint",
24-
"oxlint-tsgolint",
25-
"tsdown",
26-
"vite",
27-
"vitest",
28-
"vitest-dev"
29-
],
3016
"enabled": false
3117
},
3218
{
33-
"description": "Ignore oxc crate updates",
19+
"description": "Disable all cargo updates (lockfile updates fail because rolldown/ is gitignored)",
3420
"matchManagers": ["cargo"],
35-
"matchPackageNames": ["/^oxc([_-].*)?$/"],
36-
"enabled": false
37-
},
38-
{
39-
"matchDepNames": [
40-
"fspy",
41-
"vite_glob",
42-
"vite_path",
43-
"vite_str",
44-
"vite_task",
45-
"vite_workspace"
46-
],
4721
"enabled": false
4822
}
4923
]
Lines changed: 107 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,79 @@ import path from 'node:path';
44
const ROOT = process.cwd();
55
const META_DIR = process.env.UPGRADE_DEPS_META_DIR;
66

7-
const isFullSha = (s) => /^[0-9a-f]{40}$/.test(s);
7+
type Change = {
8+
old: string | null;
9+
new: string;
10+
tag?: string;
11+
};
12+
13+
type GitHubTag = {
14+
name?: unknown;
15+
commit?: {
16+
sha?: unknown;
17+
};
18+
};
19+
20+
type LatestTag = {
21+
sha: string;
22+
tag: string;
23+
};
824

9-
/** @type {Map<string, { old: string | null, new: string, tag?: string }>} */
10-
const changes = new Map();
25+
type NpmLatestResponse = {
26+
version?: unknown;
27+
};
1128

12-
function recordChange(name, oldValue, newValue, tag) {
13-
const entry = { old: oldValue ?? null, new: newValue };
29+
type UpstreamVersions = {
30+
rolldown: {
31+
hash: string;
32+
};
33+
vite: {
34+
hash: string;
35+
};
36+
};
37+
38+
type PnpmWorkspaceVersions = {
39+
vitest: string;
40+
tsdown: string;
41+
oxcNodeCli: string;
42+
oxcNodeCore: string;
43+
oxfmt: string;
44+
oxlint: string;
45+
oxlintTsgolint: string;
46+
oxcProjectRuntime: string;
47+
oxcProjectTypes: string;
48+
oxcMinify: string;
49+
oxcParser: string;
50+
oxcTransform: string;
51+
};
52+
53+
type PnpmWorkspaceEntry = {
54+
name: string;
55+
pattern: RegExp;
56+
replacement: string;
57+
newVersion: string;
58+
};
59+
60+
type PackageJson = {
61+
devDependencies?: Record<string, string>;
62+
peerDependencies?: Record<string, string>;
63+
};
64+
65+
const isFullSha = (s: string): boolean => /^[0-9a-f]{40}$/.test(s);
66+
67+
const changes = new Map<string, Change>();
68+
69+
function readJsonFile(filePath: string) {
70+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
71+
}
72+
73+
function recordChange(
74+
name: string,
75+
oldValue: string | null | undefined,
76+
newValue: string,
77+
tag?: string,
78+
) {
79+
const entry: Change = { old: oldValue ?? null, new: newValue };
1480
if (tag) {
1581
entry.tag = tag;
1682
}
@@ -23,7 +89,7 @@ function recordChange(name, oldValue, newValue, tag) {
2389
}
2490

2591
// ============ GitHub API ============
26-
async function getLatestTag(owner, repo) {
92+
async function getLatestTag(owner: string, repo: string): Promise<LatestTag> {
2793
const res = await fetch(`https://api.github.com/repos/${owner}/${repo}/tags?per_page=1`, {
2894
headers: {
2995
Authorization: `token ${process.env.GITHUB_TOKEN}`,
@@ -33,45 +99,46 @@ async function getLatestTag(owner, repo) {
3399
if (!res.ok) {
34100
throw new Error(`Failed to fetch tags for ${owner}/${repo}: ${res.status} ${res.statusText}`);
35101
}
36-
const tags = await res.json();
102+
const tags = (await res.json()) as GitHubTag[];
37103
if (!Array.isArray(tags) || !tags.length) {
38104
throw new Error(`No tags found for ${owner}/${repo}`);
39105
}
40-
if (!tags[0]?.commit?.sha || !tags[0]?.name) {
106+
const [latest] = tags;
107+
if (typeof latest?.commit?.sha !== 'string' || typeof latest.name !== 'string') {
41108
throw new Error(`Invalid tag structure for ${owner}/${repo}: missing SHA or name`);
42109
}
43-
console.log(`${repo} -> ${tags[0].name} (${tags[0].commit.sha.slice(0, 7)})`);
44-
return { sha: tags[0].commit.sha, tag: tags[0].name };
110+
console.log(`${repo} -> ${latest.name} (${latest.commit.sha.slice(0, 7)})`);
111+
return { sha: latest.commit.sha, tag: latest.name };
45112
}
46113

47114
// ============ npm Registry ============
48-
async function getLatestNpmVersion(packageName) {
115+
async function getLatestNpmVersion(packageName: string): Promise<string> {
49116
const res = await fetch(`https://registry.npmjs.org/${packageName}/latest`);
50117
if (!res.ok) {
51118
throw new Error(
52119
`Failed to fetch npm version for ${packageName}: ${res.status} ${res.statusText}`,
53120
);
54121
}
55-
const data = await res.json();
56-
if (!data?.version) {
122+
const data = (await res.json()) as NpmLatestResponse;
123+
if (typeof data.version !== 'string') {
57124
throw new Error(`Invalid npm response for ${packageName}: missing version field`);
58125
}
59126
return data.version;
60127
}
61128

62129
// ============ Update .upstream-versions.json ============
63-
async function updateUpstreamVersions() {
130+
async function updateUpstreamVersions(): Promise<void> {
64131
const filePath = path.join(ROOT, 'packages/tools/.upstream-versions.json');
65-
const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
132+
const data: UpstreamVersions = readJsonFile(filePath);
66133

67134
const oldRolldownHash = data.rolldown.hash;
68-
const oldViteHash = data['vite'].hash;
135+
const oldViteHash = data.vite.hash;
69136
const [rolldown, vite] = await Promise.all([
70137
getLatestTag('rolldown', 'rolldown'),
71138
getLatestTag('vitejs', 'vite'),
72139
]);
73140
data.rolldown.hash = rolldown.sha;
74-
data['vite'].hash = vite.sha;
141+
data.vite.hash = vite.sha;
75142
recordChange('rolldown', oldRolldownHash, rolldown.sha, rolldown.tag);
76143
recordChange('vite', oldViteHash, vite.sha, vite.tag);
77144

@@ -80,12 +147,12 @@ async function updateUpstreamVersions() {
80147
}
81148

82149
// ============ Update pnpm-workspace.yaml ============
83-
async function updatePnpmWorkspace(versions) {
150+
async function updatePnpmWorkspace(versions: PnpmWorkspaceVersions): Promise<void> {
84151
const filePath = path.join(ROOT, 'pnpm-workspace.yaml');
85152
let content = fs.readFileSync(filePath, 'utf8');
86153

87154
// oxlint's trailing \n in the pattern disambiguates from oxlint-tsgolint.
88-
const entries = [
155+
const entries: PnpmWorkspaceEntry[] = [
89156
{
90157
name: 'vitest',
91158
pattern: /vitest-dev: npm:vitest@\^([\d.]+(?:-[\w.]+)?)/,
@@ -161,15 +228,15 @@ async function updatePnpmWorkspace(versions) {
161228
];
162229

163230
for (const { name, pattern, replacement, newVersion } of entries) {
164-
let oldVersion;
165-
content = content.replace(pattern, (_match, captured) => {
231+
let oldVersion: string | undefined;
232+
content = content.replace(pattern, (_match: string, captured: string) => {
166233
oldVersion = captured;
167234
return replacement;
168235
});
169236
if (oldVersion === undefined) {
170237
throw new Error(
171238
`Failed to match ${name} in pnpm-workspace.yaml — the pattern ${pattern} is stale, ` +
172-
`please update it in .github/scripts/upgrade-deps.mjs`,
239+
`please update it in .github/scripts/upgrade-deps.ts`,
173240
);
174241
}
175242
recordChange(name, oldVersion, newVersion);
@@ -180,20 +247,24 @@ async function updatePnpmWorkspace(versions) {
180247
}
181248

182249
// ============ Update packages/test/package.json ============
183-
async function updateTestPackage(vitestVersion) {
250+
async function updateTestPackage(vitestVersion: string): Promise<void> {
184251
const filePath = path.join(ROOT, 'packages/test/package.json');
185-
const pkg = JSON.parse(fs.readFileSync(filePath, 'utf8'));
252+
const pkg: PackageJson = readJsonFile(filePath);
253+
const devDependencies = pkg.devDependencies;
254+
if (!devDependencies) {
255+
throw new Error('packages/test/package.json is missing devDependencies');
256+
}
186257

187258
// Update all @vitest/* devDependencies
188-
for (const dep of Object.keys(pkg.devDependencies)) {
259+
for (const dep of Object.keys(devDependencies)) {
189260
if (dep.startsWith('@vitest/')) {
190-
pkg.devDependencies[dep] = vitestVersion;
261+
devDependencies[dep] = vitestVersion;
191262
}
192263
}
193264

194265
// Update vitest-dev devDependency
195-
if (pkg.devDependencies['vitest-dev']) {
196-
pkg.devDependencies['vitest-dev'] = `^${vitestVersion}`;
266+
if (devDependencies['vitest-dev']) {
267+
devDependencies['vitest-dev'] = `^${vitestVersion}`;
197268
}
198269

199270
// Update @vitest/ui peerDependency if present
@@ -206,23 +277,24 @@ async function updateTestPackage(vitestVersion) {
206277
}
207278

208279
// ============ Update packages/core/package.json ============
209-
async function updateCorePackage(devtoolsVersion) {
280+
async function updateCorePackage(devtoolsVersion: string): Promise<void> {
210281
const filePath = path.join(ROOT, 'packages/core/package.json');
211-
const pkg = JSON.parse(fs.readFileSync(filePath, 'utf8'));
282+
const pkg: PackageJson = readJsonFile(filePath);
212283

213-
const currentDevtools = pkg.devDependencies?.['@vitejs/devtools'];
284+
const devDependencies = pkg.devDependencies;
285+
const currentDevtools = devDependencies?.['@vitejs/devtools'];
214286
if (!currentDevtools) {
215287
return;
216288
}
217-
pkg.devDependencies['@vitejs/devtools'] = `^${devtoolsVersion}`;
289+
devDependencies['@vitejs/devtools'] = `^${devtoolsVersion}`;
218290
recordChange('@vitejs/devtools', currentDevtools.replace(/^[\^~]/, ''), devtoolsVersion);
219291

220292
fs.writeFileSync(filePath, JSON.stringify(pkg, null, 2) + '\n');
221293
console.log('Updated packages/core/package.json');
222294
}
223295

224296
// ============ Write metadata files for PR description ============
225-
function writeMetaFiles() {
297+
function writeMetaFiles(): void {
226298
if (!META_DIR) {
227299
return;
228300
}
@@ -238,7 +310,7 @@ function writeMetaFiles() {
238310
const changed = [...changes.entries()].filter(([, v]) => v.old !== v.new);
239311
const unchanged = [...changes.entries()].filter(([, v]) => v.old === v.new);
240312

241-
const formatVersion = (v) => {
313+
const formatVersion = (v: Change): string => {
242314
if (v.tag) {
243315
return `${v.tag} (${v.new.slice(0, 7)})`;
244316
}
@@ -247,7 +319,7 @@ function writeMetaFiles() {
247319
}
248320
return v.new;
249321
};
250-
const formatOld = (v) => {
322+
const formatOld = (v: Change): string => {
251323
if (!v.old) {
252324
return '(unset)';
253325
}

.github/workflows/ci.yml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ jobs:
175175
# cargo clippy --all-targets --all-features -- -D warnings
176176
# RUSTDOCFLAGS='-D warnings' cargo doc --no-deps --document-private-items
177177
178-
- uses: crate-ci/typos@7c572958218557a3272c2d6719629443b5cc26fd # v1.45.2
178+
- uses: crate-ci/typos@bbaefadf97b0ec5fdc942684b647f1a6ab250274 # v1.46.0
179179
with:
180180
files: .
181181

@@ -663,9 +663,29 @@ jobs:
663663
with:
664664
drive-size: 12GB
665665
drive-format: ReFS
666+
# Route TEMP/TMP onto the Dev Drive (ReFS) so `tmpdir()` from
667+
# `packages/tools/src/snap-test.ts` lives on a filesystem that
668+
# cleanly resolves pnpm's junction reparse points. NTFS-on-C:
669+
# preserves the junction-target backslashes during resolution,
670+
# which produces mixed `\` / `/` paths that break Node's ESM
671+
# subpath-import walk-up (`#module-sync-enabled` inside
672+
# `@voidzero-dev/vite-plus-core` → `ERR_PACKAGE_IMPORT_NOT_DEFINED`
673+
# during `vp fmt --write` in the
674+
# `new-create-vite-migrates-eslint-prettier` snap test).
666675
env-mapping: |
667676
CARGO_HOME,{{ DEV_DRIVE }}/.cargo
668677
RUSTUP_HOME,{{ DEV_DRIVE }}/.rustup
678+
TEMP,{{ DEV_DRIVE }}/Temp
679+
TMP,{{ DEV_DRIVE }}/Temp
680+
681+
- name: Create TEMP/TMP on Dev Drive
682+
if: runner.os == 'Windows'
683+
# `setup-dev-drive` only mounts the drive; it doesn't create the
684+
# dir we point TEMP/TMP at. Anything that calls `os.tmpdir()` /
685+
# `lstat($TEMP)` before this dir exists fails (e.g. the bootstrap
686+
# CLI installer's `lstat 'E:\Temp'` ENOENT).
687+
shell: bash
688+
run: mkdir -p "$TEMP" "$TMP"
669689

670690
- uses: oxc-project/setup-rust@23f38cfb0c04af97a055f76acee94d5be71c7c82 # v1.0.16
671691
with:

.github/workflows/e2e-test.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,14 @@ jobs:
265265
node-version: 24
266266
command: |
267267
vp run build
268-
vp check --fix
269-
vp run check
268+
# Report-only: oxlint 1.63 drops the `eslint-` prefix from plugin names
269+
# (https://github.com/oxc-project/oxc/pull/21806), invalidating vinext's existing
270+
# `oxlint-disable-next-line eslint-plugin-react-hooks/...` directive, and tightens
271+
# a couple of unused-import checks. vinext can only update its source after a
272+
# vite-plus release ships these oxlint changes, so don't fail the matrix on the
273+
# surfaced errors yet.
274+
vp check --fix || true
275+
vp run check || true
270276
vp run test
271277
- name: reactive-resume
272278
node-version: 24

0 commit comments

Comments
 (0)