Skip to content

Commit f8935cb

Browse files
authored
Merge pull request #302 from z0ffy/feature/check-nuxt
refactor(utils): enhance `isNuxtProject` checks with directory traversal and plugin validation
2 parents 0e6dfe6 + d37624d commit f8935cb

2 files changed

Lines changed: 90 additions & 19 deletions

File tree

src/__tests__/plugin.spec.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import {expect, describe, it, vi, beforeEach, afterEach} from "vitest";
22
import type {Rollup, Plugin} from 'vite';
3+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
4+
import { tmpdir } from 'node:os';
5+
import { join } from 'node:path';
36

47
import {
58
formatTime,
@@ -587,13 +590,54 @@ describe('is utils - additional tests', () => {
587590
});
588591

589592
describe('isNuxtProject', () => {
593+
const mkTmp = () => mkdtempSync(join(tmpdir(), 'vite-bundle-obfuscator-'));
594+
595+
const writePackageJson = (root: string, pkg: any) => {
596+
writeFileSync(join(root, 'package.json'), JSON.stringify(pkg), 'utf-8');
597+
};
598+
590599
it('should return false for non-nuxt project', () => {
591600
expect(isNuxtProject({root: process.cwd()})).toBe(false);
592601
});
593602

594603
it('should use process.cwd() when root is not provided', () => {
595604
expect(isNuxtProject({})).toBe(false);
596605
});
606+
607+
it('should return true when package.json depends on nuxt', () => {
608+
const root = mkTmp();
609+
try {
610+
writePackageJson(root, { dependencies: { nuxt: '^3.0.0' } });
611+
expect(isNuxtProject({root})).toBe(true);
612+
} finally {
613+
rmSync(root, { recursive: true, force: true });
614+
}
615+
});
616+
617+
it('should return true when nuxt.config exists', () => {
618+
const root = mkTmp();
619+
try {
620+
writeFileSync(join(root, 'nuxt.config.ts'), 'export default {}', 'utf-8');
621+
expect(isNuxtProject({root})).toBe(true);
622+
} finally {
623+
rmSync(root, { recursive: true, force: true });
624+
}
625+
});
626+
627+
it('should detect nuxt when root points inside .nuxt directory', () => {
628+
const root = mkTmp();
629+
try {
630+
writePackageJson(root, { devDependencies: { nuxt: '^3.0.0' } });
631+
mkdirSync(join(root, '.nuxt'), { recursive: true });
632+
expect(isNuxtProject({root: join(root, '.nuxt')})).toBe(true);
633+
} finally {
634+
rmSync(root, { recursive: true, force: true });
635+
}
636+
});
637+
638+
it('should return true when nuxt plugin is present', () => {
639+
expect(isNuxtProject({ plugins: [{ name: 'nuxt:config' }] } as any)).toBe(true);
640+
});
597641
});
598642
});
599643

@@ -1070,4 +1114,3 @@ describe('viteBundleObfuscator plugin', () => {
10701114
});
10711115
});
10721116
});
1073-

src/utils/is.ts

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { existsSync, readFileSync } from 'node:fs';
2-
import { resolve } from 'node:path';
2+
import { dirname, resolve } from 'node:path';
33

44
const { toString } = Object.prototype;
55

@@ -57,26 +57,54 @@ export function isLibMode(config: { build?: { lib?: any } }): boolean {
5757
return !!config.build?.lib;
5858
}
5959

60-
export function isNuxtProject(config: { root?: string }): boolean {
61-
const root = config.root || process.cwd();
62-
const packageJsonPath = resolve(root, 'package.json');
63-
64-
if (existsSync(packageJsonPath)) {
65-
try {
66-
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
67-
const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };
68-
if (dependencies.nuxt) return true;
69-
} catch {
70-
/* empty */
71-
}
60+
function hasNuxtDependency(packageJsonPath: string): boolean {
61+
if (!existsSync(packageJsonPath)) return false;
62+
try {
63+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
64+
const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };
65+
return !!dependencies?.nuxt;
66+
} catch {
67+
return false;
7268
}
69+
}
7370

74-
const nuxtPaths = [
71+
function hasNuxtConfigFile(root: string): boolean {
72+
return [
7573
resolve(root, 'nuxt.config.js'),
7674
resolve(root, 'nuxt.config.ts'),
77-
resolve(root, '.nuxt'),
78-
resolve(root, '.output'),
79-
];
75+
resolve(root, 'nuxt.config.mjs'),
76+
resolve(root, 'nuxt.config.cjs'),
77+
].some(p => existsSync(p));
78+
}
79+
80+
function* walkUpDirs(startDir: string): Generator<string> {
81+
let current = startDir;
82+
while (true) {
83+
yield current;
84+
const parent = dirname(current);
85+
if (parent === current) break;
86+
current = parent;
87+
}
88+
}
89+
90+
function hasNuxtPlugins(config: any): boolean {
91+
const plugins = config?.plugins;
92+
if (!Array.isArray(plugins)) return false;
93+
return plugins.some(p => typeof p?.name === 'string' && (p.name === 'nuxt' || p.name.startsWith('nuxt:')));
94+
}
95+
96+
export function isNuxtProject(config: { root?: string; plugins?: any } = {}): boolean {
97+
if (hasNuxtPlugins(config)) return true;
8098

81-
return nuxtPaths.some(path => existsSync(path));
99+
const startDir = config.root || process.cwd();
100+
101+
for (const dir of walkUpDirs(startDir)) {
102+
if (hasNuxtConfigFile(dir)) return true;
103+
const packageJsonPath = resolve(dir, 'package.json');
104+
if (existsSync(packageJsonPath)) {
105+
return hasNuxtDependency(packageJsonPath);
106+
}
107+
}
108+
109+
return false;
82110
}

0 commit comments

Comments
 (0)