@xylabs/ts-scripts-yarn3 6.4.2 → 6.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/deplint.mjs +51 -7
- package/dist/actions/deplint.mjs.map +1 -1
- package/dist/actions/index.mjs +51 -7
- package/dist/actions/index.mjs.map +1 -1
- package/dist/bin/xy.mjs +51 -7
- package/dist/bin/xy.mjs.map +1 -1
- package/dist/index.mjs +51 -7
- package/dist/index.mjs.map +1 -1
- package/dist/xy/index.mjs +51 -7
- package/dist/xy/index.mjs.map +1 -1
- package/dist/xy/xy.mjs +51 -7
- package/dist/xy/xy.mjs.map +1 -1
- package/dist/xy/xyLintCommands.mjs +51 -7
- package/dist/xy/xyLintCommands.mjs.map +1 -1
- package/package.json +4 -5
package/dist/actions/deplint.mjs
CHANGED
|
@@ -45,7 +45,7 @@ function getBasePackageName(importName) {
|
|
|
45
45
|
}
|
|
46
46
|
return importName.split("/")[0];
|
|
47
47
|
}
|
|
48
|
-
function getImportsFromFile(filePath, importPaths) {
|
|
48
|
+
function getImportsFromFile(filePath, importPaths, typeImportPaths) {
|
|
49
49
|
const sourceCode = fs.readFileSync(filePath, "utf8");
|
|
50
50
|
const sourceFile = ts.createSourceFile(
|
|
51
51
|
path.basename(filePath),
|
|
@@ -54,24 +54,41 @@ function getImportsFromFile(filePath, importPaths) {
|
|
|
54
54
|
true
|
|
55
55
|
);
|
|
56
56
|
const imports = [];
|
|
57
|
+
const typeImports = [];
|
|
57
58
|
function visit(node) {
|
|
58
59
|
if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
|
|
59
60
|
const moduleSpecifier = node.moduleSpecifier?.getFullText();
|
|
61
|
+
const isTypeImport = ts.isImportDeclaration(node) ? node.importClause?.isTypeOnly ?? false : false;
|
|
60
62
|
if (moduleSpecifier) {
|
|
61
63
|
const trimmed = moduleSpecifier.split("'").at(1) ?? moduleSpecifier;
|
|
64
|
+
if (isTypeImport) {
|
|
65
|
+
typeImports.push(trimmed);
|
|
66
|
+
} else {
|
|
67
|
+
imports.push(trimmed);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
} else if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
|
71
|
+
const [arg] = node.arguments;
|
|
72
|
+
if (ts.isStringLiteral(arg)) {
|
|
73
|
+
const trimmed = arg.text;
|
|
62
74
|
imports.push(trimmed);
|
|
63
75
|
}
|
|
64
76
|
}
|
|
65
77
|
ts.forEachChild(node, visit);
|
|
66
78
|
}
|
|
67
79
|
visit(sourceFile);
|
|
68
|
-
const importsStartsWithExcludes = [".", "#", "node:"
|
|
80
|
+
const importsStartsWithExcludes = [".", "#", "node:"];
|
|
69
81
|
const cleanedImports = imports.filter((imp) => !importsStartsWithExcludes.some((exc) => imp.startsWith(exc))).map(getBasePackageName);
|
|
82
|
+
const cleanedTypeImports = typeImports.filter((imp) => !importsStartsWithExcludes.some((exc) => imp.startsWith(exc))).map(getBasePackageName);
|
|
70
83
|
for (const imp of cleanedImports) {
|
|
71
84
|
importPaths[imp] = importPaths[imp] || [];
|
|
72
85
|
importPaths[imp].push(filePath);
|
|
73
86
|
}
|
|
74
|
-
|
|
87
|
+
for (const imp of cleanedTypeImports) {
|
|
88
|
+
typeImportPaths[imp] = typeImportPaths[imp] || [];
|
|
89
|
+
typeImportPaths[imp].push(filePath);
|
|
90
|
+
}
|
|
91
|
+
return [cleanedImports, cleanedTypeImports];
|
|
75
92
|
}
|
|
76
93
|
function findFilesByGlob(cwd, pattern) {
|
|
77
94
|
return globSync(pattern, { cwd, absolute: true });
|
|
@@ -91,10 +108,17 @@ function findFiles(path2) {
|
|
|
91
108
|
}
|
|
92
109
|
function getExternalImportsFromFiles({ prodSourceFiles, devSourceFiles }) {
|
|
93
110
|
const prodImportPaths = {};
|
|
94
|
-
const
|
|
111
|
+
const prodTypeImportPaths = {};
|
|
112
|
+
const prodImportPairs = prodSourceFiles.map((path2) => getImportsFromFile(path2, prodImportPaths, prodTypeImportPaths));
|
|
113
|
+
const prodImports = prodImportPairs.flatMap((pair) => pair[0]);
|
|
114
|
+
const prodTypeImports = prodImportPairs.flatMap((pair) => pair[1]);
|
|
95
115
|
const devImportPaths = {};
|
|
96
|
-
const
|
|
116
|
+
const devTypeImportPaths = {};
|
|
117
|
+
const devImportPairs = devSourceFiles.map((path2) => getImportsFromFile(path2, devImportPaths, devTypeImportPaths));
|
|
118
|
+
const devImports = devImportPairs.flatMap((pair) => pair[0]);
|
|
119
|
+
const devTypeImports = devImportPairs.flatMap((pair) => pair[1]);
|
|
97
120
|
const externalProdImports = prodImports.filter((imp) => !imp.startsWith(".") && !imp.startsWith("#") && !imp.startsWith("node:"));
|
|
121
|
+
const externalProdTypeImports = prodTypeImports.filter((imp) => !imp.startsWith(".") && !imp.startsWith("#") && !imp.startsWith("node:"));
|
|
98
122
|
const externalDevImports = devImports.filter((imp) => !imp.startsWith(".") && !imp.startsWith("#") && !imp.startsWith("node:"));
|
|
99
123
|
return {
|
|
100
124
|
prodImports,
|
|
@@ -102,7 +126,10 @@ function getExternalImportsFromFiles({ prodSourceFiles, devSourceFiles }) {
|
|
|
102
126
|
prodImportPaths,
|
|
103
127
|
devImportPaths,
|
|
104
128
|
externalProdImports,
|
|
105
|
-
externalDevImports
|
|
129
|
+
externalDevImports,
|
|
130
|
+
prodTypeImports,
|
|
131
|
+
devTypeImports,
|
|
132
|
+
externalProdTypeImports
|
|
106
133
|
};
|
|
107
134
|
}
|
|
108
135
|
function check({
|
|
@@ -114,6 +141,7 @@ function check({
|
|
|
114
141
|
const { prodSourceFiles, devSourceFiles } = findFiles(location);
|
|
115
142
|
const {
|
|
116
143
|
prodImportPaths,
|
|
144
|
+
externalProdTypeImports,
|
|
117
145
|
devImportPaths,
|
|
118
146
|
externalProdImports,
|
|
119
147
|
externalDevImports
|
|
@@ -126,6 +154,15 @@ function check({
|
|
|
126
154
|
let unlistedDependencies = 0;
|
|
127
155
|
let unlistedDevDependencies = 0;
|
|
128
156
|
let unusedDependencies = 0;
|
|
157
|
+
let typesInDependencies = 0;
|
|
158
|
+
for (const imp of externalProdTypeImports) {
|
|
159
|
+
if (!dependencies.includes(imp) && !peerDependencies.includes(imp) && !devDependencies.includes(imp) && !devDependencies.includes(`@types/${imp}`)) {
|
|
160
|
+
unlistedDependencies++;
|
|
161
|
+
console.log(`[${chalk.blue(name)}] Missing dependency in package.json: ${chalk.red(imp)}`);
|
|
162
|
+
console.log(` ${prodImportPaths[imp].join("\n")}`);
|
|
163
|
+
console.log("");
|
|
164
|
+
}
|
|
165
|
+
}
|
|
129
166
|
for (const imp of externalProdImports) {
|
|
130
167
|
if (!dependencies.includes(imp) && !peerDependencies.includes(imp)) {
|
|
131
168
|
unlistedDependencies++;
|
|
@@ -135,6 +172,13 @@ function check({
|
|
|
135
172
|
}
|
|
136
173
|
}
|
|
137
174
|
for (const dep of dependencies) {
|
|
175
|
+
if (dep.startsWith("@types/")) {
|
|
176
|
+
typesInDependencies++;
|
|
177
|
+
console.log(`[${chalk.blue(name)}] @types in dependencies in package.json: ${chalk.red(dep)}`);
|
|
178
|
+
console.log(` ${location}/package.json
|
|
179
|
+
`);
|
|
180
|
+
console.log("");
|
|
181
|
+
}
|
|
138
182
|
if (!externalProdImports.includes(dep)) {
|
|
139
183
|
unusedDependencies++;
|
|
140
184
|
console.log(`[${chalk.blue(name)}] Unused dependency in package.json: ${chalk.red(dep)}`);
|
|
@@ -163,7 +207,7 @@ function check({
|
|
|
163
207
|
}
|
|
164
208
|
}
|
|
165
209
|
}
|
|
166
|
-
const totalErrors = unlistedDependencies + unlistedDevDependencies + unusedDependencies;
|
|
210
|
+
const totalErrors = unlistedDependencies + unlistedDevDependencies + unusedDependencies + typesInDependencies;
|
|
167
211
|
return totalErrors;
|
|
168
212
|
}
|
|
169
213
|
var deplint = ({ pkg }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/actions/deplint.ts","../../src/lib/yarn/workspace/yarnWorkspaces.ts","../../src/lib/yarn/workspace/yarnWorkspace.ts"],"sourcesContent":["/* eslint-disable max-statements */\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport chalk from 'chalk'\nimport { globSync } from 'glob'\nimport ts from 'typescript'\n\nimport { yarnWorkspace, yarnWorkspaces } from '../lib/index.ts'\n\nfunction getDependenciesFromPackageJson(packageJsonPath: string) {\n const packageJsonFullPath = path.resolve(packageJsonPath)\n const rawContent = fs.readFileSync(packageJsonFullPath, 'utf8')\n const packageJson = JSON.parse(rawContent)\n\n const dependencies = packageJson.dependencies\n ? Object.keys(packageJson.dependencies)\n : []\n\n const devDependencies = packageJson.devDependencies\n ? Object.keys(packageJson.devDependencies)\n : []\n\n const peerDependencies = packageJson.peerDependencies\n ? Object.keys(packageJson.peerDependencies)\n : []\n\n return {\n dependencies, devDependencies, peerDependencies,\n }\n}\n\nfunction getBasePackageName(importName: string) {\n if (importName.startsWith('@')) {\n const parts = importName.split('/')\n return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : importName\n }\n return importName.split('/')[0]\n}\n\nfunction getImportsFromFile(filePath: string, importPaths: Record<string, string[]>) {\n const sourceCode = fs.readFileSync(filePath, 'utf8')\n\n const sourceFile = ts.createSourceFile(\n path.basename(filePath),\n sourceCode,\n ts.ScriptTarget.Latest,\n true,\n )\n\n const imports: string[] = []\n\n function visit(node: ts.Node) {\n if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {\n const moduleSpecifier = (node.moduleSpecifier)?.getFullText()\n if (moduleSpecifier) {\n const trimmed = moduleSpecifier.split(\"'\").at(1) ?? moduleSpecifier\n imports.push(trimmed)\n }\n }\n ts.forEachChild(node, visit)\n }\n\n visit(sourceFile)\n\n const importsStartsWithExcludes = ['.', '#', 'node:', '@types/']\n\n const cleanedImports = imports.filter(imp => !importsStartsWithExcludes.some(exc => imp.startsWith(exc))).map(getBasePackageName)\n\n for (const imp of cleanedImports) {\n importPaths[imp] = importPaths[imp] || []\n importPaths[imp].push(filePath)\n }\n\n return cleanedImports\n}\n\nfunction findFilesByGlob(cwd: string, pattern: string) {\n return globSync(pattern, { cwd, absolute: true })\n}\n\nfunction findFiles(path: string) {\n const allSourceInclude = ['./src/**/*.{ts,tsx}']\n const prodExcludeEndswith = ['.spec.ts', '.stories.tsx']\n const prodExcludeIncludes = ['/spec/', '/stories/', '/scripts/']\n const allSourceFiles = allSourceInclude.flatMap(pattern => findFilesByGlob(path, pattern))\n\n const prodSourceFiles = allSourceFiles.filter(file => !prodExcludeEndswith.some(ext => file.endsWith(ext))\n && !prodExcludeIncludes.some(excl => file.includes(excl)))\n\n const devSourceFiles = allSourceFiles.filter(file => !prodSourceFiles.includes(file))\n return {\n allSourceFiles, prodSourceFiles, devSourceFiles,\n }\n}\n\nfunction getExternalImportsFromFiles({ prodSourceFiles, devSourceFiles }: { devSourceFiles: string[]; prodSourceFiles: string[] }) {\n const prodImportPaths: Record<string, string[]> = {}\n const prodImports = prodSourceFiles.flatMap(path => getImportsFromFile(path, prodImportPaths))\n const devImportPaths: Record<string, string[]> = {}\n const devImports = devSourceFiles.flatMap(path => getImportsFromFile(path, devImportPaths))\n const externalProdImports = prodImports.filter(imp => !imp.startsWith('.') && !imp.startsWith('#') && !imp.startsWith('node:'))\n const externalDevImports = devImports.filter(imp => !imp.startsWith('.') && !imp.startsWith('#') && !imp.startsWith('node:'))\n return {\n prodImports, devImports, prodImportPaths, devImportPaths, externalProdImports, externalDevImports,\n }\n}\n\nfunction check({\n name, location, devDeps = false, peerDeps = false,\n}: { devDeps?: boolean; location: string; name: string; peerDeps?: boolean }) {\n const { prodSourceFiles, devSourceFiles } = findFiles(location)\n const {\n prodImportPaths, devImportPaths, externalProdImports, externalDevImports,\n } = getExternalImportsFromFiles({ prodSourceFiles, devSourceFiles })\n\n const {\n dependencies, devDependencies, peerDependencies,\n } = getDependenciesFromPackageJson(`${location}/package.json`)\n\n let unlistedDependencies = 0\n let unlistedDevDependencies = 0\n let unusedDependencies = 0\n\n for (const imp of externalProdImports) {\n if (!dependencies.includes(imp) && !peerDependencies.includes(imp)) {\n unlistedDependencies++\n console.log(`[${chalk.blue(name)}] Missing dependency in package.json: ${chalk.red(imp)}`)\n console.log(` ${prodImportPaths[imp].join('\\n')}`)\n console.log('')\n }\n }\n\n for (const dep of dependencies) {\n if (!externalProdImports.includes(dep)) {\n unusedDependencies++\n console.log(`[${chalk.blue(name)}] Unused dependency in package.json: ${chalk.red(dep)}`)\n console.log(` ${location}/package.json\\n`)\n console.log('')\n }\n }\n\n if (peerDeps) {\n for (const dep of peerDependencies) {\n if (!externalProdImports.includes(dep)) {\n unusedDependencies++\n console.log(`[${chalk.blue(name)}] Unused peerDependency in package.json: ${chalk.red(dep)}`)\n console.log(` ${location}/package.json\\n`)\n console.log('')\n }\n }\n }\n\n if (devDeps) {\n for (const imp of externalDevImports) {\n if (!devDependencies.includes(imp)) {\n unlistedDevDependencies++\n console.log(`[${chalk.blue(name)}] Missing devDependency in package.json: ${chalk.red(imp)}`)\n console.log(` Found in: ${devImportPaths[imp].join(', ')}`)\n }\n }\n }\n\n const totalErrors = unlistedDependencies + unlistedDevDependencies + unusedDependencies\n\n return totalErrors\n}\n\nexport const deplint = ({ pkg }: { pkg: string }) => {\n if (pkg) {\n const { location, name } = yarnWorkspace(pkg)\n\n console.log(`Running Deplint for ${name}`)\n check({\n name, location, devDeps: true,\n })\n } else {\n const workspaces = yarnWorkspaces()\n\n console.log('Deplint Started...')\n\n let totalErrors = 0\n\n for (const workspace of workspaces) {\n totalErrors += check(workspace)\n }\n\n if (totalErrors > 0) {\n console.log(`Found ${chalk.red(totalErrors)} unlisted imports.`)\n } else {\n console.log(`No unlisted imports found. ${chalk.green('✔')}`)\n }\n }\n return 0\n}\n","import { spawnSync } from 'node:child_process'\n\nimport type { Workspace } from './Workspace.ts'\n\nexport const yarnWorkspaces = (): Workspace[] => {\n const result = spawnSync('yarn', ['workspaces', 'list', '--json', '--recursive'], { encoding: 'utf8', shell: true })\n if (result.error) {\n throw result.error\n }\n return (\n result.stdout\n .toString()\n // NOTE: This probably doesn't work on Windows\n // TODO: Replace /r/n with /n first\n .split('\\n')\n .slice(0, -1)\n .map((item) => {\n return JSON.parse(item)\n })\n )\n}\n","import type { Workspace } from './Workspace.ts'\nimport { yarnWorkspaces } from './yarnWorkspaces.ts'\n\nexport const yarnWorkspace = (pkg: string): Workspace => {\n const workspace = yarnWorkspaces().find(({ name }) => name === pkg)\n if (!workspace) throw new Error(`Workspace ${pkg} not found`)\n return workspace\n}\n"],"mappings":"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","names":["path"]}
|
|
1
|
+
{"version":3,"sources":["../../src/actions/deplint.ts","../../src/lib/yarn/workspace/yarnWorkspaces.ts","../../src/lib/yarn/workspace/yarnWorkspace.ts"],"sourcesContent":["/* eslint-disable complexity */\n/* eslint-disable max-statements */\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport chalk from 'chalk'\nimport { globSync } from 'glob'\nimport ts from 'typescript'\n\nimport { yarnWorkspace, yarnWorkspaces } from '../lib/index.ts'\n\nfunction getDependenciesFromPackageJson(packageJsonPath: string) {\n const packageJsonFullPath = path.resolve(packageJsonPath)\n const rawContent = fs.readFileSync(packageJsonFullPath, 'utf8')\n const packageJson = JSON.parse(rawContent)\n\n const dependencies = packageJson.dependencies\n ? Object.keys(packageJson.dependencies)\n : []\n\n const devDependencies = packageJson.devDependencies\n ? Object.keys(packageJson.devDependencies)\n : []\n\n const peerDependencies = packageJson.peerDependencies\n ? Object.keys(packageJson.peerDependencies)\n : []\n\n return {\n dependencies, devDependencies, peerDependencies,\n }\n}\n\nfunction getBasePackageName(importName: string) {\n if (importName.startsWith('@')) {\n const parts = importName.split('/')\n return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : importName\n }\n return importName.split('/')[0]\n}\n\nfunction getImportsFromFile(filePath: string, importPaths: Record<string, string[]>, typeImportPaths: Record<string, string[]>) {\n const sourceCode = fs.readFileSync(filePath, 'utf8')\n\n const sourceFile = ts.createSourceFile(\n path.basename(filePath),\n sourceCode,\n ts.ScriptTarget.Latest,\n true,\n )\n\n const imports: string[] = []\n const typeImports: string[] = []\n\n function visit(node: ts.Node) {\n if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {\n const moduleSpecifier = (node.moduleSpecifier)?.getFullText()\n const isTypeImport = ts.isImportDeclaration(node) ? (node.importClause?.isTypeOnly ?? false) : false\n if (moduleSpecifier) {\n const trimmed = moduleSpecifier.split(\"'\").at(1) ?? moduleSpecifier\n if (isTypeImport) {\n typeImports.push(trimmed)\n } else {\n imports.push(trimmed)\n }\n }\n } else if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {\n const [arg] = node.arguments\n if (ts.isStringLiteral(arg)) {\n const trimmed = arg.text\n imports.push(trimmed)\n }\n }\n ts.forEachChild(node, visit)\n }\n\n visit(sourceFile)\n\n const importsStartsWithExcludes = ['.', '#', 'node:']\n\n const cleanedImports = imports.filter(imp => !importsStartsWithExcludes.some(exc => imp.startsWith(exc))).map(getBasePackageName)\n const cleanedTypeImports = typeImports.filter(imp => !importsStartsWithExcludes.some(exc => imp.startsWith(exc))).map(getBasePackageName)\n\n for (const imp of cleanedImports) {\n importPaths[imp] = importPaths[imp] || []\n importPaths[imp].push(filePath)\n }\n\n for (const imp of cleanedTypeImports) {\n typeImportPaths[imp] = typeImportPaths[imp] || []\n typeImportPaths[imp].push(filePath)\n }\n\n return [cleanedImports, cleanedTypeImports]\n}\n\nfunction findFilesByGlob(cwd: string, pattern: string) {\n return globSync(pattern, { cwd, absolute: true })\n}\n\nfunction findFiles(path: string) {\n const allSourceInclude = ['./src/**/*.{ts,tsx}']\n const prodExcludeEndswith = ['.spec.ts', '.stories.tsx']\n const prodExcludeIncludes = ['/spec/', '/stories/', '/scripts/']\n const allSourceFiles = allSourceInclude.flatMap(pattern => findFilesByGlob(path, pattern))\n\n const prodSourceFiles = allSourceFiles.filter(file => !prodExcludeEndswith.some(ext => file.endsWith(ext))\n && !prodExcludeIncludes.some(excl => file.includes(excl)))\n\n const devSourceFiles = allSourceFiles.filter(file => !prodSourceFiles.includes(file))\n return {\n allSourceFiles, prodSourceFiles, devSourceFiles,\n }\n}\n\nfunction getExternalImportsFromFiles({ prodSourceFiles, devSourceFiles }: { devSourceFiles: string[]; prodSourceFiles: string[] }) {\n const prodImportPaths: Record<string, string[]> = {}\n const prodTypeImportPaths: Record<string, string[]> = {}\n const prodImportPairs = prodSourceFiles.map(path => getImportsFromFile(path, prodImportPaths, prodTypeImportPaths))\n const prodImports = prodImportPairs.flatMap(pair => pair[0])\n const prodTypeImports = prodImportPairs.flatMap(pair => pair[1])\n\n const devImportPaths: Record<string, string[]> = {}\n const devTypeImportPaths: Record<string, string[]> = {}\n const devImportPairs = devSourceFiles.map(path => getImportsFromFile(path, devImportPaths, devTypeImportPaths))\n const devImports = devImportPairs.flatMap(pair => pair[0])\n const devTypeImports = devImportPairs.flatMap(pair => pair[1])\n\n const externalProdImports = prodImports.filter(imp => !imp.startsWith('.') && !imp.startsWith('#') && !imp.startsWith('node:'))\n const externalProdTypeImports = prodTypeImports.filter(imp => !imp.startsWith('.') && !imp.startsWith('#') && !imp.startsWith('node:'))\n const externalDevImports = devImports.filter(imp => !imp.startsWith('.') && !imp.startsWith('#') && !imp.startsWith('node:'))\n return {\n prodImports, devImports, prodImportPaths, devImportPaths, externalProdImports, externalDevImports, prodTypeImports, devTypeImports, externalProdTypeImports,\n }\n}\n\nfunction check({\n name, location, devDeps = false, peerDeps = false,\n}: { devDeps?: boolean; location: string; name: string; peerDeps?: boolean }) {\n const { prodSourceFiles, devSourceFiles } = findFiles(location)\n const {\n prodImportPaths, externalProdTypeImports, devImportPaths, externalProdImports, externalDevImports,\n } = getExternalImportsFromFiles({ prodSourceFiles, devSourceFiles })\n\n const {\n dependencies, devDependencies, peerDependencies,\n } = getDependenciesFromPackageJson(`${location}/package.json`)\n\n let unlistedDependencies = 0\n let unlistedDevDependencies = 0\n let unusedDependencies = 0\n let typesInDependencies = 0\n\n for (const imp of externalProdTypeImports) {\n if (!dependencies.includes(imp) && !peerDependencies.includes(imp) && !devDependencies.includes(imp) && !devDependencies.includes(`@types/${imp}`)) {\n unlistedDependencies++\n console.log(`[${chalk.blue(name)}] Missing dependency in package.json: ${chalk.red(imp)}`)\n console.log(` ${prodImportPaths[imp].join('\\n')}`)\n console.log('')\n }\n }\n\n for (const imp of externalProdImports) {\n if (!dependencies.includes(imp) && !peerDependencies.includes(imp)) {\n unlistedDependencies++\n console.log(`[${chalk.blue(name)}] Missing dependency in package.json: ${chalk.red(imp)}`)\n console.log(` ${prodImportPaths[imp].join('\\n')}`)\n console.log('')\n }\n }\n\n for (const dep of dependencies) {\n if (dep.startsWith('@types/')) {\n typesInDependencies++\n console.log(`[${chalk.blue(name)}] @types in dependencies in package.json: ${chalk.red(dep)}`)\n console.log(` ${location}/package.json\\n`)\n console.log('')\n }\n if (!externalProdImports.includes(dep)) {\n unusedDependencies++\n console.log(`[${chalk.blue(name)}] Unused dependency in package.json: ${chalk.red(dep)}`)\n console.log(` ${location}/package.json\\n`)\n console.log('')\n }\n }\n\n if (peerDeps) {\n for (const dep of peerDependencies) {\n if (!externalProdImports.includes(dep)) {\n unusedDependencies++\n console.log(`[${chalk.blue(name)}] Unused peerDependency in package.json: ${chalk.red(dep)}`)\n console.log(` ${location}/package.json\\n`)\n console.log('')\n }\n }\n }\n\n if (devDeps) {\n for (const imp of externalDevImports) {\n if (!devDependencies.includes(imp)) {\n unlistedDevDependencies++\n console.log(`[${chalk.blue(name)}] Missing devDependency in package.json: ${chalk.red(imp)}`)\n console.log(` Found in: ${devImportPaths[imp].join(', ')}`)\n }\n }\n }\n\n const totalErrors = unlistedDependencies + unlistedDevDependencies + unusedDependencies + typesInDependencies\n\n return totalErrors\n}\n\nexport const deplint = ({ pkg }: { pkg: string }) => {\n if (pkg) {\n const { location, name } = yarnWorkspace(pkg)\n\n console.log(`Running Deplint for ${name}`)\n check({\n name, location, devDeps: true,\n })\n } else {\n const workspaces = yarnWorkspaces()\n\n console.log('Deplint Started...')\n\n let totalErrors = 0\n\n for (const workspace of workspaces) {\n totalErrors += check(workspace)\n }\n\n if (totalErrors > 0) {\n console.log(`Found ${chalk.red(totalErrors)} unlisted imports.`)\n } else {\n console.log(`No unlisted imports found. ${chalk.green('✔')}`)\n }\n }\n return 0\n}\n","import { spawnSync } from 'node:child_process'\n\nimport type { Workspace } from './Workspace.ts'\n\nexport const yarnWorkspaces = (): Workspace[] => {\n const result = spawnSync('yarn', ['workspaces', 'list', '--json', '--recursive'], { encoding: 'utf8', shell: true })\n if (result.error) {\n throw result.error\n }\n return (\n result.stdout\n .toString()\n // NOTE: This probably doesn't work on Windows\n // TODO: Replace /r/n with /n first\n .split('\\n')\n .slice(0, -1)\n .map((item) => {\n return JSON.parse(item)\n })\n )\n}\n","import type { Workspace } from './Workspace.ts'\nimport { yarnWorkspaces } from './yarnWorkspaces.ts'\n\nexport const yarnWorkspace = (pkg: string): Workspace => {\n const workspace = yarnWorkspaces().find(({ name }) => name === pkg)\n if (!workspace) throw new Error(`Workspace ${pkg} not found`)\n return workspace\n}\n"],"mappings":"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","names":["path"]}
|
package/dist/actions/index.mjs
CHANGED
|
@@ -697,7 +697,7 @@ function getBasePackageName(importName) {
|
|
|
697
697
|
}
|
|
698
698
|
return importName.split("/")[0];
|
|
699
699
|
}
|
|
700
|
-
function getImportsFromFile(filePath, importPaths) {
|
|
700
|
+
function getImportsFromFile(filePath, importPaths, typeImportPaths) {
|
|
701
701
|
const sourceCode = fs2.readFileSync(filePath, "utf8");
|
|
702
702
|
const sourceFile = ts.createSourceFile(
|
|
703
703
|
path3.basename(filePath),
|
|
@@ -706,24 +706,41 @@ function getImportsFromFile(filePath, importPaths) {
|
|
|
706
706
|
true
|
|
707
707
|
);
|
|
708
708
|
const imports = [];
|
|
709
|
+
const typeImports = [];
|
|
709
710
|
function visit(node) {
|
|
710
711
|
if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
|
|
711
712
|
const moduleSpecifier = node.moduleSpecifier?.getFullText();
|
|
713
|
+
const isTypeImport = ts.isImportDeclaration(node) ? node.importClause?.isTypeOnly ?? false : false;
|
|
712
714
|
if (moduleSpecifier) {
|
|
713
715
|
const trimmed = moduleSpecifier.split("'").at(1) ?? moduleSpecifier;
|
|
716
|
+
if (isTypeImport) {
|
|
717
|
+
typeImports.push(trimmed);
|
|
718
|
+
} else {
|
|
719
|
+
imports.push(trimmed);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
} else if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
|
|
723
|
+
const [arg] = node.arguments;
|
|
724
|
+
if (ts.isStringLiteral(arg)) {
|
|
725
|
+
const trimmed = arg.text;
|
|
714
726
|
imports.push(trimmed);
|
|
715
727
|
}
|
|
716
728
|
}
|
|
717
729
|
ts.forEachChild(node, visit);
|
|
718
730
|
}
|
|
719
731
|
visit(sourceFile);
|
|
720
|
-
const importsStartsWithExcludes = [".", "#", "node:"
|
|
732
|
+
const importsStartsWithExcludes = [".", "#", "node:"];
|
|
721
733
|
const cleanedImports = imports.filter((imp) => !importsStartsWithExcludes.some((exc) => imp.startsWith(exc))).map(getBasePackageName);
|
|
734
|
+
const cleanedTypeImports = typeImports.filter((imp) => !importsStartsWithExcludes.some((exc) => imp.startsWith(exc))).map(getBasePackageName);
|
|
722
735
|
for (const imp of cleanedImports) {
|
|
723
736
|
importPaths[imp] = importPaths[imp] || [];
|
|
724
737
|
importPaths[imp].push(filePath);
|
|
725
738
|
}
|
|
726
|
-
|
|
739
|
+
for (const imp of cleanedTypeImports) {
|
|
740
|
+
typeImportPaths[imp] = typeImportPaths[imp] || [];
|
|
741
|
+
typeImportPaths[imp].push(filePath);
|
|
742
|
+
}
|
|
743
|
+
return [cleanedImports, cleanedTypeImports];
|
|
727
744
|
}
|
|
728
745
|
function findFilesByGlob(cwd4, pattern) {
|
|
729
746
|
return globSync(pattern, { cwd: cwd4, absolute: true });
|
|
@@ -743,10 +760,17 @@ function findFiles(path9) {
|
|
|
743
760
|
}
|
|
744
761
|
function getExternalImportsFromFiles({ prodSourceFiles, devSourceFiles }) {
|
|
745
762
|
const prodImportPaths = {};
|
|
746
|
-
const
|
|
763
|
+
const prodTypeImportPaths = {};
|
|
764
|
+
const prodImportPairs = prodSourceFiles.map((path9) => getImportsFromFile(path9, prodImportPaths, prodTypeImportPaths));
|
|
765
|
+
const prodImports = prodImportPairs.flatMap((pair) => pair[0]);
|
|
766
|
+
const prodTypeImports = prodImportPairs.flatMap((pair) => pair[1]);
|
|
747
767
|
const devImportPaths = {};
|
|
748
|
-
const
|
|
768
|
+
const devTypeImportPaths = {};
|
|
769
|
+
const devImportPairs = devSourceFiles.map((path9) => getImportsFromFile(path9, devImportPaths, devTypeImportPaths));
|
|
770
|
+
const devImports = devImportPairs.flatMap((pair) => pair[0]);
|
|
771
|
+
const devTypeImports = devImportPairs.flatMap((pair) => pair[1]);
|
|
749
772
|
const externalProdImports = prodImports.filter((imp) => !imp.startsWith(".") && !imp.startsWith("#") && !imp.startsWith("node:"));
|
|
773
|
+
const externalProdTypeImports = prodTypeImports.filter((imp) => !imp.startsWith(".") && !imp.startsWith("#") && !imp.startsWith("node:"));
|
|
750
774
|
const externalDevImports = devImports.filter((imp) => !imp.startsWith(".") && !imp.startsWith("#") && !imp.startsWith("node:"));
|
|
751
775
|
return {
|
|
752
776
|
prodImports,
|
|
@@ -754,7 +778,10 @@ function getExternalImportsFromFiles({ prodSourceFiles, devSourceFiles }) {
|
|
|
754
778
|
prodImportPaths,
|
|
755
779
|
devImportPaths,
|
|
756
780
|
externalProdImports,
|
|
757
|
-
externalDevImports
|
|
781
|
+
externalDevImports,
|
|
782
|
+
prodTypeImports,
|
|
783
|
+
devTypeImports,
|
|
784
|
+
externalProdTypeImports
|
|
758
785
|
};
|
|
759
786
|
}
|
|
760
787
|
function check({
|
|
@@ -766,6 +793,7 @@ function check({
|
|
|
766
793
|
const { prodSourceFiles, devSourceFiles } = findFiles(location);
|
|
767
794
|
const {
|
|
768
795
|
prodImportPaths,
|
|
796
|
+
externalProdTypeImports,
|
|
769
797
|
devImportPaths,
|
|
770
798
|
externalProdImports,
|
|
771
799
|
externalDevImports
|
|
@@ -778,6 +806,15 @@ function check({
|
|
|
778
806
|
let unlistedDependencies = 0;
|
|
779
807
|
let unlistedDevDependencies = 0;
|
|
780
808
|
let unusedDependencies = 0;
|
|
809
|
+
let typesInDependencies = 0;
|
|
810
|
+
for (const imp of externalProdTypeImports) {
|
|
811
|
+
if (!dependencies.includes(imp) && !peerDependencies.includes(imp) && !devDependencies.includes(imp) && !devDependencies.includes(`@types/${imp}`)) {
|
|
812
|
+
unlistedDependencies++;
|
|
813
|
+
console.log(`[${chalk13.blue(name)}] Missing dependency in package.json: ${chalk13.red(imp)}`);
|
|
814
|
+
console.log(` ${prodImportPaths[imp].join("\n")}`);
|
|
815
|
+
console.log("");
|
|
816
|
+
}
|
|
817
|
+
}
|
|
781
818
|
for (const imp of externalProdImports) {
|
|
782
819
|
if (!dependencies.includes(imp) && !peerDependencies.includes(imp)) {
|
|
783
820
|
unlistedDependencies++;
|
|
@@ -787,6 +824,13 @@ function check({
|
|
|
787
824
|
}
|
|
788
825
|
}
|
|
789
826
|
for (const dep of dependencies) {
|
|
827
|
+
if (dep.startsWith("@types/")) {
|
|
828
|
+
typesInDependencies++;
|
|
829
|
+
console.log(`[${chalk13.blue(name)}] @types in dependencies in package.json: ${chalk13.red(dep)}`);
|
|
830
|
+
console.log(` ${location}/package.json
|
|
831
|
+
`);
|
|
832
|
+
console.log("");
|
|
833
|
+
}
|
|
790
834
|
if (!externalProdImports.includes(dep)) {
|
|
791
835
|
unusedDependencies++;
|
|
792
836
|
console.log(`[${chalk13.blue(name)}] Unused dependency in package.json: ${chalk13.red(dep)}`);
|
|
@@ -815,7 +859,7 @@ function check({
|
|
|
815
859
|
}
|
|
816
860
|
}
|
|
817
861
|
}
|
|
818
|
-
const totalErrors = unlistedDependencies + unlistedDevDependencies + unusedDependencies;
|
|
862
|
+
const totalErrors = unlistedDependencies + unlistedDevDependencies + unusedDependencies + typesInDependencies;
|
|
819
863
|
return totalErrors;
|
|
820
864
|
}
|
|
821
865
|
var deplint = ({ pkg }) => {
|