-
Notifications
You must be signed in to change notification settings - Fork 830
Expand file tree
/
Copy pathshadcn-lint.js
More file actions
executable file
·113 lines (95 loc) · 3.65 KB
/
Copy pathshadcn-lint.js
File metadata and controls
executable file
·113 lines (95 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env node
import fs from 'node:fs';
import path from 'node:path';
import process from 'node:process';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const repoRoot = path.resolve(__dirname, '..');
const examplesRoot = path.join(repoRoot, 'examples');
const standardReactPackagePath = path.join(repoRoot, 'standard', 'packages', 'react', 'package.json');
const defaultExampleDirs = ['shadcn-event-calendar', 'shadcn-scheduler'];
const exampleDirs = [...defaultExampleDirs, ...process.argv.slice(2)];
const forbiddenInjectedPackages = ['@fullcalendar/react', '@fullcalendar/react-scheduler'];
function readJson(filePath) {
try {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
} catch (error) {
throw new Error(`Failed to read ${filePath}: ${error.message}`);
}
}
function resolvePackageRoot(exampleDir) {
return path.isAbsolute(exampleDir) ? exampleDir : path.join(examplesRoot, exampleDir);
}
function assert(condition, message, errors) {
if (!condition) {
errors.push(message);
}
}
function resolveRealpath(filePath) {
try {
return fs.realpathSync(filePath);
} catch (error) {
throw new Error(`Failed to resolve ${filePath}: ${error.message}`);
}
}
const standardReactPackage = readJson(standardReactPackagePath);
const expectedReactVersion = standardReactPackage.devDependencies?.react;
const expectedReactDomVersion = standardReactPackage.devDependencies?.['react-dom'];
const standardNodeModules = path.join(repoRoot, 'standard', 'packages', 'react', 'node_modules');
const errors = [];
for (const exampleDir of exampleDirs) {
const exampleRoot = resolvePackageRoot(exampleDir);
const packageJsonPath = path.join(exampleRoot, 'package.json');
if (!fs.existsSync(packageJsonPath)) {
errors.push(`Missing package.json for example directory: ${exampleDir}`);
continue;
}
const packageJson = readJson(packageJsonPath);
for (const packageName of forbiddenInjectedPackages) {
const injectedMeta = packageJson.dependenciesMeta?.[packageName];
assert(
injectedMeta?.injected !== true,
`${packageJsonPath}: dependenciesMeta[${JSON.stringify(packageName)}].injected must not be true`,
errors,
);
}
assert(
packageJson.dependencies?.react === expectedReactVersion,
`${packageJsonPath}: react version must exactly match ${JSON.stringify(expectedReactVersion)} from ${standardReactPackagePath}`,
errors,
);
assert(
packageJson.dependencies?.['react-dom'] === expectedReactDomVersion,
`${packageJsonPath}: react-dom version must exactly match ${JSON.stringify(expectedReactDomVersion)} from ${standardReactPackagePath}`,
errors,
);
}
if (errors.length > 0) {
console.error(errors.join('\n'));
process.exitCode = 1;
} else {
for (const exampleDir of exampleDirs) {
const exampleRoot = resolvePackageRoot(exampleDir);
const exampleNodeModules = path.join(exampleRoot, 'node_modules');
for (const packageName of ['react', 'react-dom']) {
try {
const exampleResolved = resolveRealpath(path.join(exampleNodeModules, packageName));
const standardResolved = resolveRealpath(path.join(standardNodeModules, packageName));
assert(
exampleResolved === standardResolved,
`${path.join(exampleRoot, 'node_modules', packageName)} resolves to ${exampleResolved}, expected ${standardResolved}`,
errors,
);
} catch (error) {
errors.push(error.message);
}
}
}
if (errors.length > 0) {
console.error(errors.join('\n'));
process.exitCode = 1;
} else {
console.log('shadcn-lint: ok');
}
}