fileflows 1.0.0 → 1.0.2
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/README.md +37 -12
- package/cli.js +4 -3
- package/config/localVars.js +39 -1
- package/index.js +7 -2
- package/lib/fileFlowsGenerator.js +19 -4
- package/lib/fileIO.js +6 -1
- package/lib/index.js +23 -31
- package/lib/jsParser.js +6 -1
- package/lib/otherFileParser.js +4 -4
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# FileFlows CLI
|
|
2
2
|
|
|
3
3
|
A CLI tool for generating `FILE_FLOWS.md` - analyzes project files and creates comprehensive documentation showing data flow relationships.
|
|
4
4
|
|
|
5
|
-
[](https://badge.fury.io/js/fileflows)
|
|
6
6
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
7
7
|
|
|
8
8
|
## Features
|
|
@@ -17,12 +17,12 @@ A CLI tool for generating `FILE_FLOWS.md` - analyzes project files and creates c
|
|
|
17
17
|
|
|
18
18
|
### Global Installation (Recommended)
|
|
19
19
|
```bash
|
|
20
|
-
npm install -g
|
|
20
|
+
npm install -g fileflows
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### Local Installation
|
|
24
24
|
```bash
|
|
25
|
-
npm install
|
|
25
|
+
npm install fileflows
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
### Development/Direct Use
|
|
@@ -35,28 +35,37 @@ npm install @babel/parser globby
|
|
|
35
35
|
### Global Installation
|
|
36
36
|
```bash
|
|
37
37
|
# Analyze current directory (generates FILE_FLOWS.md)
|
|
38
|
-
|
|
38
|
+
fileflows
|
|
39
39
|
|
|
40
40
|
# Analyze specific directory
|
|
41
|
-
|
|
41
|
+
fileflows --dir ./src
|
|
42
42
|
|
|
43
43
|
# Custom output file
|
|
44
|
-
|
|
44
|
+
fileflows --output my-flows.md
|
|
45
45
|
|
|
46
46
|
# Show help
|
|
47
|
-
|
|
47
|
+
fileflows --help
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
### Local Installation
|
|
51
51
|
```bash
|
|
52
52
|
# Using npx
|
|
53
|
-
npx
|
|
53
|
+
npx fileflows
|
|
54
54
|
|
|
55
|
-
# Using npm scripts
|
|
56
|
-
npm run
|
|
55
|
+
# Using npm scripts (if added to package.json)
|
|
56
|
+
npm run generate
|
|
57
57
|
|
|
58
58
|
# Direct node execution
|
|
59
|
-
node node_modules/
|
|
59
|
+
node node_modules/fileflows/cli.js
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Development/Direct Use
|
|
63
|
+
```bash
|
|
64
|
+
# Clone or download the repository, then:
|
|
65
|
+
node cli.js # Analyze current directory
|
|
66
|
+
node cli.js --dir ./src # Analyze src directory
|
|
67
|
+
node cli.js --output flows.md # Custom output file
|
|
68
|
+
node cli.js --help # Show help
|
|
60
69
|
```
|
|
61
70
|
|
|
62
71
|
## How It Works
|
|
@@ -102,4 +111,20 @@ The generated `FILE_FLOWS.md` includes:
|
|
|
102
111
|
---
|
|
103
112
|
```
|
|
104
113
|
|
|
114
|
+
## Command Line Options
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
Usage: node cli.js [options]
|
|
118
|
+
|
|
119
|
+
Options:
|
|
120
|
+
--dir <path> Directory to analyze (default: current directory)
|
|
121
|
+
--output <file> Output file path (default: FILE_FLOWS.md)
|
|
122
|
+
--help, -h Show this help message
|
|
123
|
+
|
|
124
|
+
Examples:
|
|
125
|
+
node cli.js # Analyze current directory
|
|
126
|
+
node cli.js --dir ./src # Analyze src directory
|
|
127
|
+
node cli.js --output flows.md # Custom output file
|
|
128
|
+
```
|
|
129
|
+
|
|
105
130
|
This tool preserves all the sophisticated analysis capabilities of the original system while providing a clean, focused CLI interface.
|
package/cli.js
CHANGED
|
@@ -3,11 +3,9 @@
|
|
|
3
3
|
* CLI tool for generating FILE_FLOWS.md
|
|
4
4
|
* Analyzes project files and creates documentation showing data flow relationships
|
|
5
5
|
* Following NPM architecture guidelines with modular structure
|
|
6
|
+
* Refactored: Global const declarations moved to config/localVars.js
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
|
-
const generateFileFlows = require(`./lib/fileFlowsGenerator`);
|
|
9
|
-
const localVars = require(`./config/localVars`);
|
|
10
|
-
|
|
11
9
|
/**
|
|
12
10
|
* CLI usage display functionality
|
|
13
11
|
* Shows help information for the CLI tool
|
|
@@ -31,6 +29,9 @@ function showUsage() {
|
|
|
31
29
|
* Parses arguments and executes file flows generation
|
|
32
30
|
*/
|
|
33
31
|
async function main() {
|
|
32
|
+
const localVars = require(`./config/localVars`);
|
|
33
|
+
const { generateFileFlows } = localVars.getDependencies();
|
|
34
|
+
|
|
34
35
|
const args = process.argv.slice(2);
|
|
35
36
|
let rootDir = localVars.DEFAULT_ROOT_DIR;
|
|
36
37
|
let outputFile = null;
|
package/config/localVars.js
CHANGED
|
@@ -35,6 +35,42 @@ const MAX_YAML_KEYS = 5;
|
|
|
35
35
|
const MAX_SHELL_COMMANDS = 5;
|
|
36
36
|
const MAX_HTML_TAGS = 5;
|
|
37
37
|
|
|
38
|
+
// === CENTRALIZED DEPENDENCIES ===
|
|
39
|
+
// All require statements moved from global scope to centralized configuration
|
|
40
|
+
function getDependencies() {
|
|
41
|
+
return {
|
|
42
|
+
// Core library modules (from lib/index.js)
|
|
43
|
+
generateFileFlows: require(`../lib/fileFlowsGenerator`),
|
|
44
|
+
groupByDataFlow: require(`../lib/dataFlowGrouper`),
|
|
45
|
+
classifyFile: require(`../lib/fileClassifier`),
|
|
46
|
+
parseJSFile: require(`../lib/jsParser`),
|
|
47
|
+
parseOtherFile: require(`../lib/otherFileParser`),
|
|
48
|
+
extractDependencies: require(`../lib/dependencyExtractor`),
|
|
49
|
+
fileIO: require(`../lib/fileIO`),
|
|
50
|
+
graphUtils: require(`../lib/graphUtils`),
|
|
51
|
+
|
|
52
|
+
// System dependencies (from qtests-runner.js)
|
|
53
|
+
fs: require(`fs`),
|
|
54
|
+
path: require(`path`),
|
|
55
|
+
childProcess: require(`child_process`),
|
|
56
|
+
os: require(`os`),
|
|
57
|
+
|
|
58
|
+
// Testing dependencies (from qtests.config.js)
|
|
59
|
+
qtests: require(`qtests`)
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// === ENVIRONMENT VARIABLES ===
|
|
64
|
+
// Centralized environment variable access using qerrors utilities
|
|
65
|
+
const { getEnv } = require(`qerrors`);
|
|
66
|
+
|
|
67
|
+
function getEnvironmentConfig() {
|
|
68
|
+
return {
|
|
69
|
+
NODE_ENV: getEnv(`NODE_ENV`, `development`),
|
|
70
|
+
DEBUG_TESTS: getEnv(`DEBUG_TESTS`, `false`) === `true`
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
38
74
|
module.exports = {
|
|
39
75
|
CODE_EXTENSIONS,
|
|
40
76
|
ALL_EXTENSIONS,
|
|
@@ -44,5 +80,7 @@ module.exports = {
|
|
|
44
80
|
MAX_JSON_KEYS,
|
|
45
81
|
MAX_YAML_KEYS,
|
|
46
82
|
MAX_SHELL_COMMANDS,
|
|
47
|
-
MAX_HTML_TAGS
|
|
83
|
+
MAX_HTML_TAGS,
|
|
84
|
+
getDependencies,
|
|
85
|
+
getEnvironmentConfig
|
|
48
86
|
};
|
package/index.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Main entry point for the file-flows-cli NPM module
|
|
3
3
|
* Exports public functionality following NPM architecture guidelines
|
|
4
|
+
* Refactored: Global const declarations moved to config/localVars.js
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
function getMainExport() {
|
|
8
|
+
const localVars = require(`./config/localVars`);
|
|
9
|
+
const { generateFileFlows } = localVars.getDependencies();
|
|
10
|
+
return generateFileFlows;
|
|
11
|
+
}
|
|
7
12
|
|
|
8
|
-
module.exports =
|
|
13
|
+
module.exports = getMainExport();
|
|
@@ -71,13 +71,21 @@ async function generateFileFlows(rootDir = `.`, outputFile = null) {
|
|
|
71
71
|
|
|
72
72
|
files = findFiles('.');
|
|
73
73
|
} catch (error) {
|
|
74
|
-
|
|
74
|
+
require('qerrors').logError(error, 'File flow generation failed during file discovery', {
|
|
75
|
+
context: 'FILE_DISCOVERY_ERROR',
|
|
76
|
+
rootDir: ROOT,
|
|
77
|
+
outputFile: FILE_OUTPUT
|
|
78
|
+
});
|
|
75
79
|
return { filesAnalyzed: 0, flowGroups: 0, outputFile: null };
|
|
76
80
|
}
|
|
77
81
|
|
|
78
82
|
// Check if any files were found
|
|
79
83
|
if (files.length === 0) {
|
|
80
|
-
|
|
84
|
+
require('qerrors').logWarn(`No files found in directory: ${ROOT}`, 'generateFileFlows', {
|
|
85
|
+
context: 'NO_FILES_FOUND',
|
|
86
|
+
rootDir: ROOT,
|
|
87
|
+
searchExtensions: localVars.ALL_EXTENSIONS
|
|
88
|
+
});
|
|
81
89
|
return { filesAnalyzed: 0, flowGroups: 0, outputFile: null };
|
|
82
90
|
}
|
|
83
91
|
|
|
@@ -119,7 +127,9 @@ async function generateFileFlows(rootDir = `.`, outputFile = null) {
|
|
|
119
127
|
: parseOtherFile(content, relPath, ext);
|
|
120
128
|
|
|
121
129
|
for (const [label, value] of Object.entries(metadata)) {
|
|
122
|
-
|
|
130
|
+
// 🚩AI: Ensure value is always an array before calling join
|
|
131
|
+
const arrayValue = Array.isArray(value) ? value : [value];
|
|
132
|
+
if (arrayValue.length > 0) section.push(`**${label}:** ${arrayValue.join(`, `)}`);
|
|
123
133
|
}
|
|
124
134
|
|
|
125
135
|
section.push(`\n---\n`);
|
|
@@ -134,7 +144,12 @@ async function generateFileFlows(rootDir = `.`, outputFile = null) {
|
|
|
134
144
|
outputFile: FILE_OUTPUT
|
|
135
145
|
};
|
|
136
146
|
|
|
137
|
-
|
|
147
|
+
require('qerrors').logInfo(`FILE_FLOWS.md generation completed`, 'generateFileFlows', {
|
|
148
|
+
context: 'GENERATION_SUCCESS',
|
|
149
|
+
filesAnalyzed: result.filesAnalyzed,
|
|
150
|
+
flowGroups: result.flowGroups,
|
|
151
|
+
outputFile: result.outputFile
|
|
152
|
+
});
|
|
138
153
|
return result;
|
|
139
154
|
}
|
|
140
155
|
|
package/lib/fileIO.js
CHANGED
|
@@ -39,7 +39,12 @@ function safeResolvePath(rootDir, filePath) {
|
|
|
39
39
|
|
|
40
40
|
// Prevent directory traversal attacks
|
|
41
41
|
if (relative.startsWith(`..`)) {
|
|
42
|
-
|
|
42
|
+
const { createTypedError, ErrorTypes } = require('qerrors');
|
|
43
|
+
throw createTypedError(
|
|
44
|
+
`Path traversal attempt detected: ${filePath}`,
|
|
45
|
+
ErrorTypes.VALIDATION,
|
|
46
|
+
'PATH_TRAVERSAL_DETECTED'
|
|
47
|
+
);
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
return { success: true, resolvedPath: resolved };
|
package/lib/index.js
CHANGED
|
@@ -1,37 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Library aggregation module
|
|
3
3
|
* Exports all library functionality following NPM architecture guidelines
|
|
4
|
+
* Refactored: Global const declarations moved to config/localVars.js
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
// 🚩AI: MAIN_LIBRARY_EXPORTS_REGISTRY - Dependencies centralized in config/localVars.js
|
|
8
|
+
function getLibraryModules() {
|
|
9
|
+
const localVars = require(`../config/localVars`);
|
|
10
|
+
const deps = localVars.getDependencies();
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
generateFileFlows: deps.generateFileFlows,
|
|
14
|
+
groupByDataFlow: deps.groupByDataFlow,
|
|
15
|
+
classifyFile: deps.classifyFile,
|
|
16
|
+
parseJSFile: deps.parseJSFile,
|
|
17
|
+
parseOtherFile: deps.parseOtherFile,
|
|
18
|
+
extractDependencies: deps.extractDependencies,
|
|
19
|
+
safeReadFileSync: deps.fileIO.safeReadFileSync,
|
|
20
|
+
safeResolvePath: deps.fileIO.safeResolvePath,
|
|
21
|
+
buildDependencyGraph: deps.graphUtils.buildDependencyGraph,
|
|
22
|
+
findConnectedComponents: deps.graphUtils.findConnectedComponents,
|
|
23
|
+
depthFirstSearch: deps.graphUtils.depthFirstSearch,
|
|
24
|
+
groupBySimilarity: deps.graphUtils.groupBySimilarity,
|
|
25
|
+
calculateRoleScore: deps.graphUtils.calculateRoleScore
|
|
26
|
+
};
|
|
27
|
+
}
|
|
12
28
|
|
|
13
|
-
|
|
14
|
-
const { safeReadFileSync, safeResolvePath } = require(`./fileIO`);
|
|
15
|
-
const {
|
|
16
|
-
buildDependencyGraph,
|
|
17
|
-
findConnectedComponents,
|
|
18
|
-
depthFirstSearch,
|
|
19
|
-
groupBySimilarity,
|
|
20
|
-
calculateRoleScore
|
|
21
|
-
} = require(`./graphUtils`);
|
|
22
|
-
|
|
23
|
-
module.exports = {
|
|
24
|
-
generateFileFlows,
|
|
25
|
-
groupByDataFlow,
|
|
26
|
-
classifyFile,
|
|
27
|
-
parseJSFile,
|
|
28
|
-
parseOtherFile,
|
|
29
|
-
extractDependencies,
|
|
30
|
-
safeReadFileSync,
|
|
31
|
-
safeResolvePath,
|
|
32
|
-
buildDependencyGraph,
|
|
33
|
-
findConnectedComponents,
|
|
34
|
-
depthFirstSearch,
|
|
35
|
-
groupBySimilarity,
|
|
36
|
-
calculateRoleScore
|
|
37
|
-
};
|
|
29
|
+
module.exports = getLibraryModules();
|
package/lib/jsParser.js
CHANGED
|
@@ -110,7 +110,12 @@ function parseJSFile(content, filePath) {
|
|
|
110
110
|
|
|
111
111
|
visitNode(ast);
|
|
112
112
|
} catch (err) {
|
|
113
|
-
//
|
|
113
|
+
// Log parse errors for debugging but don't crash
|
|
114
|
+
require('qerrors').logWarn(`JavaScript parsing failed for ${filePath}`, 'parseJSFile', {
|
|
115
|
+
context: 'JS_PARSE_ERROR',
|
|
116
|
+
filePath: filePath,
|
|
117
|
+
errorMessage: err.message
|
|
118
|
+
});
|
|
114
119
|
}
|
|
115
120
|
|
|
116
121
|
return {
|
package/lib/otherFileParser.js
CHANGED
|
@@ -21,7 +21,7 @@ function parseOtherFile(content, relPath, ext) {
|
|
|
21
21
|
Summary: summary
|
|
22
22
|
};
|
|
23
23
|
} catch {
|
|
24
|
-
return { Keys: [], Summary: 'Malformed JSON' };
|
|
24
|
+
return { Keys: [], Summary: ['Malformed JSON'] };
|
|
25
25
|
}
|
|
26
26
|
case `md`:
|
|
27
27
|
const headings = lines
|
|
@@ -57,7 +57,7 @@ function parseOtherFile(content, relPath, ext) {
|
|
|
57
57
|
.filter(Boolean);
|
|
58
58
|
return {
|
|
59
59
|
Types: types,
|
|
60
|
-
Summary: 'GraphQL Schema'
|
|
60
|
+
Summary: ['GraphQL Schema']
|
|
61
61
|
};
|
|
62
62
|
case `sh`:
|
|
63
63
|
const commands = lines
|
|
@@ -93,10 +93,10 @@ function parseOtherFile(content, relPath, ext) {
|
|
|
93
93
|
|
|
94
94
|
return {
|
|
95
95
|
Tags: tags.slice(0, localVars.MAX_HTML_TAGS),
|
|
96
|
-
Summary: title
|
|
96
|
+
Summary: [title]
|
|
97
97
|
};
|
|
98
98
|
default:
|
|
99
|
-
return { Summary: 'Unknown file type' };
|
|
99
|
+
return { Summary: ['Unknown file type'] };
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fileflows",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "CLI tool for deploying data workflow analysis documentation",
|
|
5
5
|
"main": "cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -54,9 +54,7 @@
|
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@babel/parser": "^7.28.3",
|
|
56
56
|
"@babel/traverse": "^7.28.3",
|
|
57
|
-
"commoncontext": "^1.0.0",
|
|
58
57
|
"globby": "^14.1.0",
|
|
59
|
-
"npmcontext": "^1.0.0",
|
|
60
58
|
"qerrors": "^1.2.6",
|
|
61
59
|
"winston": "^3.17.0",
|
|
62
60
|
"winston-daily-rotate-file": "^5.0.0"
|
|
@@ -64,10 +62,12 @@
|
|
|
64
62
|
"devDependencies": {
|
|
65
63
|
"agentsqripts": "^1.0.8",
|
|
66
64
|
"arqitect": "^1.0.7",
|
|
65
|
+
"commoncontext": "^1.0.1",
|
|
67
66
|
"loqatevars": "^1.0.6",
|
|
68
67
|
"madge": "^8.0.0",
|
|
69
|
-
"
|
|
70
|
-
"
|
|
68
|
+
"npmcontext": "^1.0.1",
|
|
69
|
+
"qtests": "^1.1.9",
|
|
70
|
+
"quantumagent": "^1.0.5",
|
|
71
71
|
"repomix": "^1.2.0",
|
|
72
72
|
"unqommented": "^1.1.0"
|
|
73
73
|
}
|