Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ peerDependencyRules:
> test ! -f eslint.config.mjs # check eslint config is removed
> test ! -f .prettierrc.json # check prettier config is removed
> cat vite.config.ts # check oxlint and oxfmt config merged into vite.config.ts
import { defineConfig } from 'vite-plus';
import { defineConfig } from "vite-plus";

export default defineConfig({
staged: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ peerDependencyRules:
vitest: '*'

> cat vite.config.ts # check oxfmt config merged into vite.config.ts with semi/singleQuote settings
import { defineConfig } from 'vite-plus';
import { defineConfig } from "vite-plus";

export default defineConfig({
staged: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Prettier config migrated to .oxfmtrc.json

> test ! -f .prettierrc.json # check prettier config is removed
> cat vite.config.ts # check oxfmt config merged into vite.config.ts
import { defineConfig } from 'vite-plus';
import { defineConfig } from "vite-plus";

export default defineConfig({
fmt: {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/snap-tests-global/migration-prettier/snap.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ peerDependencyRules:

> test ! -f .prettierrc.json # check prettier config is removed
> cat vite.config.ts # check oxfmt config merged into vite.config.ts
import { defineConfig } from 'vite-plus';
import { defineConfig } from "vite-plus";
Comment thread
fengmk2 marked this conversation as resolved.

export default defineConfig({
staged: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"serial": true,
"ignoredPlatforms": ["win32"],
"commands": ["vp env use 20.0.0", "vp exec node --version"],
"after": ["vp env use --unset"]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"serial": true,
Comment thread
fengmk2 marked this conversation as resolved.
"env": {},
"commands": ["vp env default 20.0.0", "vp migrate --yes"],
"after": ["vp env default lts"]
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/snap-tests/bin-oxlint-wrapper/snap.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ Output

Miscellaneous
--silent Do not display any diagnostics
--no-error-on-unmatched-pattern Do not exit with an error when no files are selected for
linting (for example, after applying ignore patterns)
--threads=INT Number of threads to use. Set to 1 for using only 1 CPU core.
--print-config This option outputs the configuration to be used. When present, no
linting is performed and only config-related options are valid.
Expand Down
3 changes: 3 additions & 0 deletions packages/cli/snap-tests/check-oxlint-env/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function hello(): string {
return 'hello';
}
10 changes: 10 additions & 0 deletions packages/cli/snap-tests/check-oxlint-env/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"skipLibCheck": true
},
"include": ["src"]
}
8 changes: 8 additions & 0 deletions packages/cli/snap-tests/check-oxlint-env/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default {
lint: {
options: {
typeAware: true,
typeCheck: true,
},
},
};
2 changes: 2 additions & 0 deletions packages/cli/snap-tests/command-helper/snap.txt
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ Output

Miscellaneous
--silent Do not display any diagnostics
--no-error-on-unmatched-pattern Do not exit with an error when no files are selected for
linting (for example, after applying ignore patterns)
--threads=INT Number of threads to use. Set to 1 for using only 1 CPU core.
--print-config This option outputs the configuration to be used. When present, no
linting is performed and only config-related options are valid.
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/create/discovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ export function discoverTemplate(
if (localPackage) {
const localPackagePath = path.join(workspaceInfo.rootDir, localPackage.path);
const packageJsonPath = path.join(localPackagePath, 'package.json');
const pkg = readJsonFile<{
const pkg = readJsonFile(packageJsonPath) as {
dependencies?: Record<string, string>;
keywords?: string[];
bin?: Record<string, string> | string;
}>(packageJsonPath);
};
let binPath = '';
if (pkg.bin) {
if (typeof pkg.bin === 'string') {
Expand Down
4 changes: 3 additions & 1 deletion packages/cli/src/migration/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,9 @@ async function main() {

// Early return if already using Vite+ (only ESLint/hooks migration may be needed)
// In force-override mode (file: tgz overrides), skip this check and run full migration
const rootPkg = readNearestPackageJson<PackageDependencies>(workspaceInfoOptional.rootDir);
const rootPkg = readNearestPackageJson(
workspaceInfoOptional.rootDir,
) as PackageDependencies | null;
if (hasVitePlusDependency(rootPkg) && !isForceOverrideMode()) {
let didMigrate = false;
let installDurationMs = 0;
Expand Down
28 changes: 14 additions & 14 deletions packages/cli/src/migration/migrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,10 @@ export function detectEslintProject(
if (!fs.existsSync(packageJsonPath)) {
return { hasDependency: false };
}
const pkg = readJsonFile<{
const pkg = readJsonFile(packageJsonPath) as {
devDependencies?: Record<string, string>;
dependencies?: Record<string, string>;
}>(packageJsonPath);
};
let hasDependency = !!(pkg.devDependencies?.eslint || pkg.dependencies?.eslint);
const configs = detectConfigs(projectPath);
let configFile = configs.eslintConfig;
Expand All @@ -159,10 +159,10 @@ export function detectEslintProject(
if (!fs.existsSync(pkgJsonPath)) {
continue;
}
const wpPkg = readJsonFile<{
const wpPkg = readJsonFile(pkgJsonPath) as {
devDependencies?: Record<string, string>;
dependencies?: Record<string, string>;
}>(pkgJsonPath);
};
if (wpPkg.devDependencies?.eslint || wpPkg.dependencies?.eslint) {
hasDependency = true;
break;
Expand Down Expand Up @@ -404,10 +404,10 @@ export function detectPrettierProject(
if (!fs.existsSync(packageJsonPath)) {
return { hasDependency: false };
}
const pkg = readJsonFile<{
const pkg = readJsonFile(packageJsonPath) as {
devDependencies?: Record<string, string>;
dependencies?: Record<string, string>;
}>(packageJsonPath);
};
let hasDependency = !!(pkg.devDependencies?.prettier || pkg.dependencies?.prettier);
const configs = detectConfigs(projectPath);
const configFile = configs.prettierConfig;
Expand All @@ -419,10 +419,10 @@ export function detectPrettierProject(
if (!fs.existsSync(pkgJsonPath)) {
continue;
}
const wpPkg = readJsonFile<{
const wpPkg = readJsonFile(pkgJsonPath) as {
devDependencies?: Record<string, string>;
dependencies?: Record<string, string>;
}>(pkgJsonPath);
};
if (wpPkg.devDependencies?.prettier || wpPkg.dependencies?.prettier) {
hasDependency = true;
break;
Expand Down Expand Up @@ -498,7 +498,7 @@ export async function migratePrettierToOxfmt(
// so that `vp fmt --migrate=prettier` can read it
if (prettierConfigFile === PRETTIER_PACKAGE_JSON_CONFIG) {
const packageJsonPath = path.join(projectPath, 'package.json');
const pkg = readJsonFile<{ prettier?: unknown }>(packageJsonPath);
const pkg = readJsonFile(packageJsonPath) as { prettier?: unknown };
if (pkg.prettier) {
tempPrettierConfig = path.join(projectPath, '.prettierrc.json');
fs.writeFileSync(tempPrettierConfig, JSON.stringify(pkg.prettier, null, 2));
Expand Down Expand Up @@ -1582,7 +1582,7 @@ export function mergeViteConfigFiles(
if (configs.oxlintConfig) {
// Inject options.typeAware and options.typeCheck defaults before merging
const fullOxlintPath = path.join(projectPath, configs.oxlintConfig);
const oxlintJson = readJsonFile<{ options?: Record<string, unknown> }>(fullOxlintPath, true);
const oxlintJson = readJsonFile(fullOxlintPath, true) as { options?: Record<string, unknown> };
if (!oxlintJson.options) {
oxlintJson.options = {};
}
Expand Down Expand Up @@ -1919,7 +1919,7 @@ export function getOldHooksDir(rootDir: string): string | undefined {
if (!fs.existsSync(packageJsonPath)) {
return undefined;
}
const pkg = readJsonFile<{ scripts?: { prepare?: string } }>(packageJsonPath);
const pkg = readJsonFile(packageJsonPath) as { scripts?: { prepare?: string } };
if (!pkg.scripts?.prepare) {
return undefined;
}
Expand Down Expand Up @@ -2023,9 +2023,9 @@ export function setupGitHooks(
const hasStandaloneConfig = hasStandaloneLintStagedConfig(projectPath);
if (!stagedMerged && !hasStandaloneConfig) {
// Use lint-staged config from package.json if available, otherwise use default
const pkgData = readJsonFile<{ 'lint-staged'?: Record<string, string | string[]> }>(
packageJsonPath,
);
const pkgData = readJsonFile(packageJsonPath) as {
'lint-staged'?: Record<string, string | string[]>;
};
const stagedConfig = pkgData?.['lint-staged'] ?? DEFAULT_STAGED_CONFIG;
const updated = rewriteScripts(JSON.stringify(stagedConfig), readRulesYaml());
const finalConfig: Record<string, string | string[]> = updated
Expand Down
13 changes: 5 additions & 8 deletions packages/cli/src/utils/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@ import detectIndent from 'detect-indent';
import { detectNewline } from 'detect-newline';
import { parse as parseJsonc } from 'jsonc-parser';

export function readJsonFile<T = Record<string, unknown>>(
file: string,
allowComments?: boolean,
): T {
export function readJsonFile(file: string, allowComments?: boolean): Record<string, unknown> {
const content = fs.readFileSync(file, 'utf-8');
const parseFunction = allowComments ? parseJsonc : JSON.parse;
return parseFunction(content) as T;
return parseFunction(content);
}

export function writeJsonFile<T = Record<string, unknown>>(file: string, data: T) {
export function writeJsonFile(file: string, data: Record<string, unknown>) {
let newline = '\n';
let indent = ' ';
if (fs.existsSync(file)) {
Expand All @@ -25,11 +22,11 @@ export function writeJsonFile<T = Record<string, unknown>>(file: string, data: T
fs.writeFileSync(file, JSON.stringify(data, null, indent) + newline, 'utf-8');
}

export function editJsonFile<T = Record<string, unknown>>(
export function editJsonFile<T extends Record<string, unknown> = Record<string, unknown>>(
file: string,
callback: (content: T) => T | undefined,
) {
const json = readJsonFile<T>(file);
const json = readJsonFile(file) as T;
const newJson = callback(json);
if (newJson) {
writeJsonFile(file, newJson);
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/utils/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ export function detectPackageMetadata(
* @param currentDir - The current directory to start searching from.
* @returns The package.json content as a JSON object, or null if no package.json is found.
*/
export function readNearestPackageJson<T = Record<string, unknown>>(currentDir: string): T | null {
export function readNearestPackageJson(currentDir: string): Record<string, unknown> | null {
do {
const packageJsonPath = path.join(currentDir, 'package.json');
if (fs.existsSync(packageJsonPath)) {
return readJsonFile<T>(packageJsonPath);
return readJsonFile(packageJsonPath);
}
currentDir = path.dirname(currentDir);
} while (currentDir !== path.dirname(currentDir));
Expand Down
10 changes: 5 additions & 5 deletions packages/cli/src/utils/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ export async function detectWorkspace(rootDir: string): Promise<WorkspaceInfoOpt
const pnpmWorkspaceFile = path.join(result.rootDir, 'pnpm-workspace.yaml');
const packageJsonFile = path.join(result.rootDir, 'package.json');
if (fs.existsSync(pnpmWorkspaceFile)) {
const workspaceConfig = readYamlFile<{ packages?: string[] }>(pnpmWorkspaceFile);
const workspaceConfig = readYamlFile(pnpmWorkspaceFile) as { packages?: string[] };
if (Array.isArray(workspaceConfig.packages)) {
result.workspacePatterns = workspaceConfig.packages;
}
} else if (fs.existsSync(packageJsonFile)) {
// Check for npm/yarn/bun workspace (array or object form)
const pkg = readJsonFile<{ workspaces?: NpmWorkspaces }>(packageJsonFile);
const pkg = readJsonFile(packageJsonFile) as { workspaces?: NpmWorkspaces };
if (Array.isArray(pkg.workspaces)) {
result.workspacePatterns = pkg.workspaces;
} else if (pkg.workspaces && Array.isArray(pkg.workspaces.packages)) {
Expand All @@ -92,7 +92,7 @@ export async function detectWorkspace(rootDir: string): Promise<WorkspaceInfoOpt
result.parentDirs = Array.from(dirs).sort();

// Extract the scope from the package.json
const pkg = readJsonFile<{ name?: string }>(packageJsonFile);
const pkg = readJsonFile(packageJsonFile) as { name?: string };
if (pkg.name) {
result.monorepoScope = getScopeFromPackageName(pkg.name);
}
Expand Down Expand Up @@ -124,13 +124,13 @@ export function discoverWorkspacePackages(
);
for (const packageJsonRelativePath of packageJsonRelativePaths) {
const packageJsonPath = path.join(rootDir, packageJsonRelativePath);
const pkg = readJsonFile<{
const pkg = readJsonFile(packageJsonPath) as {
name?: string;
description?: string;
version?: string;
dependencies?: Record<string, string>;
keywords?: string[];
}>(packageJsonPath);
};
if (!pkg.name) {
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/utils/yaml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import fs from 'node:fs';

import { type Document, parseDocument, parse as parseYaml, Scalar } from 'yaml';

export function readYamlFile<T = Record<string, unknown>>(file: string): T {
export function readYamlFile(file: string): Record<string, unknown> {
const content = fs.readFileSync(file, 'utf-8');
return parseYaml(content) as T;
return parseYaml(content);
}

export type YamlDocument = Document.Parsed;
Expand Down
6 changes: 3 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@
},
"peerDependencies": {
"@arethetypeswrong/core": "^0.18.1",
"@tsdown/css": "0.21.7",
"@tsdown/exe": "0.21.7",
"@tsdown/css": "0.21.8",
"@tsdown/exe": "0.21.8",
"@types/node": "^20.19.0 || >=22.12.0",
"@vitejs/devtools": "^0.1.0",
"esbuild": "^0.27.0 || ^0.28.0",
Expand Down Expand Up @@ -219,6 +219,6 @@
"bundledVersions": {
"vite": "8.0.8",
"rolldown": "1.0.0-rc.15",
"tsdown": "0.21.7"
"tsdown": "0.21.8"
}
}
Loading
Loading