New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-dep-analyzer

Package Overview
Dependencies
Maintainers
0
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-dep-analyzer - npm Package Compare versions

Comparing version 1.0.10 to 1.0.11

2

dist/index.d.ts

@@ -35,3 +35,5 @@ interface ComponentPathConfig {

private generateMermaidFlowchart;
private generateComponentContent;
private generateComponentMarkdown;
private generateFullMarkdown;
generateMarkDown(outputPath?: string): void;

@@ -38,0 +40,0 @@ generateDependencyTree(outputPath?: string): void;

141

dist/index.js

@@ -222,17 +222,15 @@ // src/index.ts

}
generateComponentMarkdown(componentName, data) {
const componentPathConfig = this.componentPaths.find(
(config) => data.file.includes(path.relative(this.projectRoot, config.path))
);
if (!componentPathConfig) {
console.warn(`\u8B66\u544A: \u627E\u4E0D\u5230\u5143\u4EF6 ${componentName} \u7684\u8DEF\u5F91\u914D\u7F6E`);
return "";
generateComponentContent(componentName, data, options = {}) {
const {
includeHeader = true,
includeSeparator = false
} = options;
let output = "";
if (includeHeader) {
output += `# ${componentName}
`;
}
const relativeFilePath = path.relative(this.projectRoot, data.file);
const targetDir = path.join(this.projectRoot, path.dirname(relativeFilePath));
const componentFileName = `${componentName}.md`;
const componentFilePath = path.join(targetDir, componentFileName);
let output = `# ${componentName}
`;
output += `> File Path: \`${data.file}\`
const filePath = path.relative(this.projectRoot, data.file);
output += `> File Path: \`${filePath}\`

@@ -242,42 +240,21 @@ `;

output += this.generateMermaidFlowchart(/* @__PURE__ */ new Set(), /* @__PURE__ */ new Set(), { name: componentName, data });
if (data.dependencies.length > 0) {
const dependencyGroups = this.componentPaths.reduce((groups, pathConfig) => {
const groupName = pathConfig.path.split("/").pop() || "other";
groups[groupName] = data.dependencies.filter(
(d) => d.path.startsWith(pathConfig.importPrefix)
);
return groups;
}, {});
const otherDeps = data.dependencies.filter(
(d) => !this.componentPaths.some(
(config) => d.path.startsWith(config.importPrefix)
)
output += "\n";
const dependencyGroups = this.componentPaths.reduce((groups, pathConfig) => {
const groupName = pathConfig.path.split("/").pop() || "other";
groups[groupName] = data.dependencies.filter(
(d) => d.path.startsWith(pathConfig.importPrefix)
);
Object.entries(dependencyGroups).forEach(([groupName, deps]) => {
if (deps.length > 0) {
output += `## ${groupName.charAt(0).toUpperCase() + groupName.slice(1)} Dependencies
return groups;
}, {});
Object.entries(dependencyGroups).forEach(([groupName, deps]) => {
if (deps.length > 0) {
output += `## ${groupName.charAt(0).toUpperCase() + groupName.slice(1)} Dependencies
`;
deps.forEach((dep) => {
const importsList = dep.imports.join(", ");
const relativePath = path.relative(this.projectRoot, dep.file);
output += `> - **${dep.path}**
`;
output += `> - File: \`${relativePath}\`
`;
output += `> - Imports: \`${importsList}\`
`;
});
output += "\n";
}
});
if (otherDeps.length > 0) {
output += "## Other Dependencies\n";
otherDeps.forEach((dep) => {
const importsList = dep.imports.join(", ");
const relativePath = path.relative(this.projectRoot, dep.file);
deps.forEach((dep) => {
const depPath = path.relative(this.projectRoot, dep.file);
output += `> - **${dep.path}**
`;
output += `> - File: \`${relativePath}\`
output += `> - File: \`${depPath}\`
`;
output += `> - Imports: \`${importsList}\`
output += `> - Imports: \`${dep.imports.join(", ")}\`
`;

@@ -287,3 +264,3 @@ });

}
}
});
if (data.usedInPages.length > 0) {

@@ -297,6 +274,45 @@ output += "## Used in Pages\n";

}
if (includeSeparator) {
output += "---\n\n";
}
return output;
}
generateComponentMarkdown(componentName, data) {
const componentPathConfig = this.componentPaths.find(
(config) => data.file.includes(path.relative(this.projectRoot, config.path))
);
if (!componentPathConfig) {
console.warn(`\u8B66\u544A: \u627E\u4E0D\u5230\u5143\u4EF6 ${componentName} \u7684\u8DEF\u5F91\u914D\u7F6E`);
return "";
}
const relativeFilePath = path.relative(this.projectRoot, data.file);
const targetDir = path.join(this.projectRoot, path.dirname(relativeFilePath));
const componentFileName = `${componentName}.md`;
const componentFilePath = path.join(targetDir, componentFileName);
const content = this.generateComponentContent(componentName, data, {
includeHeader: true,
includeSeparator: false
});
fs.mkdirSync(targetDir, { recursive: true });
fs.writeFileSync(componentFilePath, output, "utf8");
fs.writeFileSync(componentFilePath, content, "utf8");
return componentFilePath;
}
generateFullMarkdown() {
let output = `# ${this.name} \u5B8C\u6574\u5143\u4EF6\u6587\u6A94
`;
output += "## \u76EE\u9304\n\n";
Object.entries(this.targetUsage).sort(([nameA], [nameB]) => nameA.localeCompare(nameB)).forEach(([componentName]) => {
output += `- [${componentName}](#${componentName.toLowerCase()})
`;
});
output += "\n---\n\n";
Object.entries(this.targetUsage).sort(([nameA], [nameB]) => nameA.localeCompare(nameB)).forEach(([componentName, data]) => {
output += this.generateComponentContent(componentName, data, {
includeHeader: true,
includeSeparator: true
});
});
return output;
}
generateMarkDown(outputPath) {

@@ -316,6 +332,19 @@ console.log("\u958B\u59CB\u751F\u6210 Markdown \u5831\u544A...");

const componentFilePath = this.generateComponentMarkdown(componentName, data);
const relativeFilePath = path.relative(outputDir, componentFilePath);
const componentPathConfig = this.componentPaths.find(
(config) => componentFilePath.includes(path.relative(this.projectRoot, config.path))
);
if (!componentPathConfig) {
console.warn(`\u8B66\u544A: \u627E\u4E0D\u5230\u5143\u4EF6 ${componentName} \u7684\u8DEF\u5F91\u914D\u7F6E`);
return {
name: componentName,
path: componentFilePath,
dependencies: data.dependencies.length,
usedInPages: data.usedInPages.length
};
}
const relativePath = path.relative(this.projectRoot, componentFilePath);
const absolutePath = `/${relativePath}`;
return {
name: componentName,
path: relativeFilePath,
path: absolutePath,
dependencies: data.dependencies.length,

@@ -326,3 +355,3 @@ usedInPages: data.usedInPages.length

componentFiles.sort((a, b) => a.name.localeCompare(b.name)).forEach(({ name, path: path2, dependencies, usedInPages }) => {
indexContent += `- [${name}](./${path2})
indexContent += `- [${name}](${path2})
`;

@@ -336,5 +365,9 @@ indexContent += ` - Dependencies: ${dependencies}

fs.writeFileSync(indexPath, indexContent, "utf8");
const fullDocPath = path.join(outputDir, "full-documentation.md");
const fullDocContent = this.generateFullMarkdown();
fs.writeFileSync(fullDocPath, fullDocContent, "utf8");
console.log(`Markdown \u6587\u6A94\u5DF2\u751F\u6210\u65BC: ${outputDir}`);
console.log(`\u5206\u6790\u4E86 ${componentFiles.length} \u500B\u5143\u4EF6`);
console.log(`\u7D22\u5F15\u6587\u4EF6: ${indexPath}`);
console.log(`\u5B8C\u6574\u6587\u6A94: ${fullDocPath}`);
}

@@ -341,0 +374,0 @@ generateDependencyTree(outputPath) {

{
"name": "react-dep-analyzer",
"version": "1.0.10",
"version": "1.0.11",
"description": "分析 React 元件依賴關係和使用情況的工具",

@@ -5,0 +5,0 @@ "main": "./dist/index.js",

@@ -43,2 +43,7 @@ import fs from 'fs';

interface ComponentContentOptions {
includeHeader?: boolean;
includeSeparator?: boolean;
}
export class ComponentUsageAnalyzer {

@@ -319,27 +324,22 @@ private name: string;

private generateComponentMarkdown(
private generateComponentContent(
componentName: string,
data: ComponentUsage
data: ComponentUsage,
options: ComponentContentOptions = {}
): string {
// 找到對應的 componentPath 配置
const componentPathConfig = this.componentPaths.find(config =>
data.file.includes(path.relative(this.projectRoot, config.path))
);
const {
includeHeader = true,
includeSeparator = false
} = options;
if (!componentPathConfig) {
console.warn(`警告: 找不到元件 ${componentName} 的路徑配置`);
return '';
let output = '';
// 添加標題(可選)
if (includeHeader) {
output += `# ${componentName}\n\n`;
}
// 從完整檔案路徑中取得相對路徑部分
const relativeFilePath = path.relative(this.projectRoot, data.file);
const targetDir = path.join(this.projectRoot, path.dirname(relativeFilePath));
// 使用原始元件名稱(保持大小寫)作為檔案名
const componentFileName = `${componentName}.md`;
const componentFilePath = path.join(targetDir, componentFileName);
// 生成元件文檔內容
let output = `# ${componentName}\n`;
output += `> File Path: \`${data.file}\`\n\n`;
// 使用相對於專案根目錄的路徑
const filePath = path.relative(this.projectRoot, data.file);
output += `> File Path: \`${filePath}\`\n\n`;

@@ -349,54 +349,26 @@ // 添加元件依賴關係圖

output += this.generateMermaidFlowchart(new Set(), new Set(), { name: componentName, data });
output += '\n';
if (data.dependencies.length > 0) {
// 根據 componentPaths 配置來分組依賴
const dependencyGroups = this.componentPaths.reduce((groups, pathConfig) => {
// 使用路徑最後一段作為分組名稱(例如:components, elements)
const groupName = pathConfig.path.split('/').pop() || 'other';
// 過濾出屬於該分組的依賴
groups[groupName] = data.dependencies.filter(d =>
d.path.startsWith(pathConfig.importPrefix)
);
return groups;
}, {} as Record<string, DependencyInfo[]>);
// 找出未匹配任何已配置路徑的其他依賴
const otherDeps = data.dependencies.filter(d =>
!this.componentPaths.some(config =>
d.path.startsWith(config.importPrefix)
)
// 根據 componentPaths 配置來分組依賴
const dependencyGroups = this.componentPaths.reduce((groups, pathConfig) => {
const groupName = pathConfig.path.split('/').pop() || 'other';
groups[groupName] = data.dependencies.filter(d =>
d.path.startsWith(pathConfig.importPrefix)
);
return groups;
}, {} as Record<string, DependencyInfo[]>);
// 輸出每個分組的依賴
Object.entries(dependencyGroups).forEach(([groupName, deps]) => {
if (deps.length > 0) {
// 將分組名稱首字母大寫
output += `## ${groupName.charAt(0).toUpperCase() + groupName.slice(1)} Dependencies\n`;
deps.forEach((dep) => {
// 合併所有引用的名稱
const importsList = dep.imports.join(', ');
// 轉換為相對於專案根目錄的路徑
const relativePath = path.relative(this.projectRoot, dep.file);
// 使用引用格式輸出依賴資訊
output += `> - **${dep.path}**\n`;
output += `> - File: \`${relativePath}\`\n`;
output += `> - Imports: \`${importsList}\`\n`;
});
output += '\n';
}
});
// 輸出其他未分組的依賴
if (otherDeps.length > 0) {
output += '## Other Dependencies\n';
otherDeps.forEach((dep) => {
const importsList = dep.imports.join(', ');
const relativePath = path.relative(this.projectRoot, dep.file);
// 輸出每個分組的依賴
Object.entries(dependencyGroups).forEach(([groupName, deps]) => {
if (deps.length > 0) {
output += `## ${groupName.charAt(0).toUpperCase() + groupName.slice(1)} Dependencies\n`;
deps.forEach((dep) => {
const depPath = path.relative(this.projectRoot, dep.file);
output += `> - **${dep.path}**\n`;
output += `> - File: \`${relativePath}\`\n`;
output += `> - Imports: \`${importsList}\`\n`;
output += `> - File: \`${depPath}\`\n`;
output += `> - Imports: \`${dep.imports.join(', ')}\`\n`;
});
output += '\n';
}
}
});

@@ -412,2 +384,38 @@ // 輸出使用此元件的頁面列表

// 添加分隔線(可選)
if (includeSeparator) {
output += '---\n\n';
}
return output;
}
private generateComponentMarkdown(
componentName: string,
data: ComponentUsage
): string {
// 找到對應的 componentPath 配置
const componentPathConfig = this.componentPaths.find(config =>
data.file.includes(path.relative(this.projectRoot, config.path))
);
if (!componentPathConfig) {
console.warn(`警告: 找不到元件 ${componentName} 的路徑配置`);
return '';
}
// 從完整檔案路徑中取得相對路徑部分
const relativeFilePath = path.relative(this.projectRoot, data.file);
const targetDir = path.join(this.projectRoot, path.dirname(relativeFilePath));
// 使用原始元件名稱(保持大小寫)作為檔案名
const componentFileName = `${componentName}.md`;
const componentFilePath = path.join(targetDir, componentFileName);
// 生成元件文檔內容
const content = this.generateComponentContent(componentName, data, {
includeHeader: true,
includeSeparator: false
});
// 確保目標目錄存在

@@ -417,6 +425,32 @@ fs.mkdirSync(targetDir, { recursive: true });

// 寫入元件文檔檔案
fs.writeFileSync(componentFilePath, output, 'utf8');
fs.writeFileSync(componentFilePath, content, 'utf8');
return componentFilePath;
}
private generateFullMarkdown(): string {
let output = `# ${this.name} 完整元件文檔\n\n`;
output += '## 目錄\n\n';
// 先生成目錄
Object.entries(this.targetUsage)
.sort(([nameA], [nameB]) => nameA.localeCompare(nameB))
.forEach(([componentName]) => {
output += `- [${componentName}](#${componentName.toLowerCase()})\n`;
});
output += '\n---\n\n';
// 生成每個元件的完整文檔
Object.entries(this.targetUsage)
.sort(([nameA], [nameB]) => nameA.localeCompare(nameB))
.forEach(([componentName, data]) => {
output += this.generateComponentContent(componentName, data, {
includeHeader: true,
includeSeparator: true
});
});
return output;
}
generateMarkDown(outputPath?: string): void {

@@ -443,8 +477,25 @@ console.log('開始生成 Markdown 報告...');

const componentFilePath = this.generateComponentMarkdown(componentName, data);
const relativeFilePath = path.relative(outputDir, componentFilePath);
// 返回元件名稱和檔案路徑,用於生成索引
// 找到對應的 componentPath 配置
const componentPathConfig = this.componentPaths.find(config =>
componentFilePath.includes(path.relative(this.projectRoot, config.path))
);
if (!componentPathConfig) {
console.warn(`警告: 找不到元件 ${componentName} 的路徑配置`);
return {
name: componentName,
path: componentFilePath,
dependencies: data.dependencies.length,
usedInPages: data.usedInPages.length
};
}
// 從完整路徑中提取相對路徑部分
const relativePath = path.relative(this.projectRoot, componentFilePath);
const absolutePath = `/${relativePath}`;
return {
name: componentName,
path: relativeFilePath,
path: absolutePath,
dependencies: data.dependencies.length,

@@ -459,3 +510,3 @@ usedInPages: data.usedInPages.length

.forEach(({ name, path, dependencies, usedInPages }) => {
indexContent += `- [${name}](./${path})\n`;
indexContent += `- [${name}](${path})\n`;
indexContent += ` - Dependencies: ${dependencies}\n`;

@@ -469,5 +520,11 @@ indexContent += ` - Used in Pages: ${usedInPages}\n`;

// 生成完整文檔
const fullDocPath = path.join(outputDir, 'full-documentation.md');
const fullDocContent = this.generateFullMarkdown();
fs.writeFileSync(fullDocPath, fullDocContent, 'utf8');
console.log(`Markdown 文檔已生成於: ${outputDir}`);
console.log(`分析了 ${componentFiles.length} 個元件`);
console.log(`索引文件: ${indexPath}`);
console.log(`完整文檔: ${fullDocPath}`);
}

@@ -474,0 +531,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc