ezctx 1.0.0
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/LICENSE +21 -0
- package/README.md +108 -0
- package/dist/config.type.d.ts +9 -0
- package/dist/config.type.d.ts.map +1 -0
- package/dist/config.type.js +2 -0
- package/dist/config.type.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/index.type.d.ts +2 -0
- package/dist/index.type.d.ts.map +1 -0
- package/dist/index.type.js +8 -0
- package/dist/index.type.js.map +1 -0
- package/dist/test.d.ts +2 -0
- package/dist/test.d.ts.map +1 -0
- package/dist/test.js +21 -0
- package/dist/test.js.map +1 -0
- package/dist/utils/buildGraph.d.ts +13 -0
- package/dist/utils/buildGraph.d.ts.map +1 -0
- package/dist/utils/buildGraph.js +38 -0
- package/dist/utils/buildGraph.js.map +1 -0
- package/dist/utils/getConfig.d.ts +2 -0
- package/dist/utils/getConfig.d.ts.map +1 -0
- package/dist/utils/getConfig.js +4 -0
- package/dist/utils/getConfig.js.map +1 -0
- package/dist/utils/loadConfig.d.ts +10 -0
- package/dist/utils/loadConfig.d.ts.map +1 -0
- package/dist/utils/loadConfig.js +63 -0
- package/dist/utils/loadConfig.js.map +1 -0
- package/dist/utils/outputFormatter.d.ts +12 -0
- package/dist/utils/outputFormatter.d.ts.map +1 -0
- package/dist/utils/outputFormatter.js +30 -0
- package/dist/utils/outputFormatter.js.map +1 -0
- package/dist/utils/stringFormatter.d.ts +12 -0
- package/dist/utils/stringFormatter.d.ts.map +1 -0
- package/dist/utils/stringFormatter.js +17 -0
- package/dist/utils/stringFormatter.js.map +1 -0
- package/dist/utils/utils.type.d.ts +9 -0
- package/dist/utils/utils.type.d.ts.map +1 -0
- package/dist/utils/utils.type.js +2 -0
- package/dist/utils/utils.type.js.map +1 -0
- package/dist/utils/visualizeGraph.d.ts +11 -0
- package/dist/utils/visualizeGraph.d.ts.map +1 -0
- package/dist/utils/visualizeGraph.js +27 -0
- package/dist/utils/visualizeGraph.js.map +1 -0
- package/dist/utils/writeFiles.d.ts +16 -0
- package/dist/utils/writeFiles.d.ts.map +1 -0
- package/dist/utils/writeFiles.js +52 -0
- package/dist/utils/writeFiles.js.map +1 -0
- package/dist/utils/writeOutput.d.ts +16 -0
- package/dist/utils/writeOutput.d.ts.map +1 -0
- package/dist/utils/writeOutput.js +56 -0
- package/dist/utils/writeOutput.js.map +1 -0
- package/package.json +30 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 arhayashi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# ezctx
|
|
2
|
+
|
|
3
|
+
**ezctx** (short for _easy context_) puts all of your source code into one or several `.txt` file(s), allowing you to easily paste it into an external AI platform instead of having to tediously upload each individual file.
|
|
4
|
+
|
|
5
|
+
In addition, this program adds a graph/visualization of your project's files/directories to the first output `.txt` file, helping the AI map your project.
|
|
6
|
+
|
|
7
|
+
This program's "bundling" behavior can be modied by adding a configuration file. See below for usage, description, and configuration options.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
npx ezctx
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
- Node.js version must support the promised-based `fs` API.
|
|
16
|
+
- The program outputs the `.txt` file(s) wherever the command was executed.
|
|
17
|
+
|
|
18
|
+
## Description
|
|
19
|
+
|
|
20
|
+
_To view an example of this program's output, see [ezctx_1.txt](https://github.com/arhayashi/ezctx/blob/main/ezctx_1.txt)_.
|
|
21
|
+
|
|
22
|
+
When running this program, please ensure that your project has read and write permissions enabled or an error will be thrown.
|
|
23
|
+
|
|
24
|
+
### Default Behavior
|
|
25
|
+
|
|
26
|
+
This section will describe the program's **default** behavior and some of the ways it can be modified using the [configuration](#configuration) file.
|
|
27
|
+
|
|
28
|
+
This program recursively writes your projects's source code into a singular `.txt` file so that you can easily access all your source code in a central location. Because this program does not require an npm installation, you can use it with projects that use different languages outside of the Node.js/npm ecosystem.
|
|
29
|
+
|
|
30
|
+
For instance, if you `cd` into a directory, `my_project`, executing `npx ezctx` will produce `my_project/ezctx_1.txt` containing all of your project's source code. If you need the outputted `.txt` file to be smaller, you can change the configuration's `chunkSize` which will ensure that each output file is no larger than `chunkSize`. This may result in serveral output `.txt` files in the format `ezctx_{i}.txt` where `i` corresponds to the `nth` output file. Note that if there are multiple output `.txt` files, they will live under the `ezctx` directory. Otherwise, the singular output `.txt` file will live wherever the `npx ezctx` commands was executed. These default behaviors can be modified in the program's [configuration](#configuration).
|
|
31
|
+
|
|
32
|
+
This program runs on a _file-by-file_ basis to ensure that the size of the content in the current source code file plus the content in the current output `.txt` file is less than `chunkSize`. Effectively, this means that if one of your source code files is greater than `chunkSize`, it will not be added to an output `.txt` file.
|
|
33
|
+
|
|
34
|
+
### Output File
|
|
35
|
+
|
|
36
|
+
Before writing your project's source code to the output `.txt` file(s), this program creates a visualization of your project's files/directories from a recursively created graph. This visualization is added only to the first outputted `.txt` file. For example, the visualization of _this program_ looks like the below and is the first item written to the `ezctx_1.txt` output.
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
*** project structure ***
|
|
40
|
+
|
|
41
|
+
\ezctx
|
|
42
|
+
|__.ezctxrc.json
|
|
43
|
+
|__README.md
|
|
44
|
+
|__src/
|
|
45
|
+
|__config.type.ts
|
|
46
|
+
|__index.ts
|
|
47
|
+
|__utils/
|
|
48
|
+
|__buildGraph.ts
|
|
49
|
+
|__loadConfig.ts
|
|
50
|
+
|__outputFormatter.ts
|
|
51
|
+
|__stringFormatter.ts
|
|
52
|
+
|__utils.type.ts
|
|
53
|
+
|__visualizeGraph.ts
|
|
54
|
+
|__writeOutput.ts
|
|
55
|
+
|__tsconfig.json
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Additionally, when writing each of your project's files to the output `.txt` file(s), they will be in the format defined below and will go under your project's visualization.
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
*** {file_name_1} ***
|
|
63
|
+
|
|
64
|
+
// ...
|
|
65
|
+
|
|
66
|
+
*** {file_name_2} ***
|
|
67
|
+
|
|
68
|
+
// ...
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Configuration
|
|
73
|
+
|
|
74
|
+
To modify this program's default "bundling" behavior, add a `JSON` file in the same directory where the `npx ezctx` command will be executed. This configuration file must contain the substring "ezctx" within its name, like `ezctx.config.json`, `.ezctxrc.json`, or `ezctx.json`. The modifiable configuration fields are defined below.
|
|
75
|
+
|
|
76
|
+
### Configuration Options
|
|
77
|
+
|
|
78
|
+
| Field | Type | Description |
|
|
79
|
+
| ------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
80
|
+
| `chunkSize` | `number` | The maximum size (in bytes) of each output `.txt` file. This program's recursive process occurs on a file-by-file basis, so if a file's size is larger than `chunkSize`, it will not be included in the output `.txt` file(s). |
|
|
81
|
+
| `defaultIgnores` | `boolean` | Wether to use the program's default ignores. If `true`, the user defined `ignores` will be merged with the program's default `ignores` (see the default config below). If `false`, only the user defined `ignores` will be used. |
|
|
82
|
+
| `ignores` | `string[]` | The files/directories that will not be included in the output `.txt` file(s). |
|
|
83
|
+
| `outDir` | `string` | The name of the directory where the output `.txt` file(s) will live under. |
|
|
84
|
+
| `outDirSingleEmit` | `boolean` | Applies when there is only a single output `.txt` file. If `true`, the outputted `.txt` file will live under `outDir`. If `false`, it will be placed wherever the `npx ezctx` command was executed. |
|
|
85
|
+
| `outFile` | `string` | The name of each output `.txt` file. Add `{i}` to denote where the file's numbering should go within its name. If `{i}` is not included, the file's numbering (along with an underscore) will be added to the end of the file's name by default (see the default config below). |
|
|
86
|
+
|
|
87
|
+
### Default Configuration
|
|
88
|
+
|
|
89
|
+
If no configuration file is defined, or a field is omitted, the default configuration/corresponding field (defined below) will be used instead.
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
{
|
|
93
|
+
chunkSize: Infinity,
|
|
94
|
+
defaultIgnores: true,
|
|
95
|
+
ignores: [
|
|
96
|
+
"node_modules",
|
|
97
|
+
"package-lock.json",
|
|
98
|
+
"package.json",
|
|
99
|
+
".git",
|
|
100
|
+
".gitignore",
|
|
101
|
+
".DS_Store",
|
|
102
|
+
".vscode",
|
|
103
|
+
],
|
|
104
|
+
outDir: "ezctx",
|
|
105
|
+
outDirSingleEmit: false,
|
|
106
|
+
outFile: "ezctx_{i}.txt"
|
|
107
|
+
}
|
|
108
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.type.d.ts","sourceRoot":"","sources":["../src/config.type.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,MAAM,GAAG;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.type.js","sourceRoot":"","sources":["../src/config.type.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import * as fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import buildGraph from "./utils/buildGraph.js";
|
|
5
|
+
import visualizeGraph from "./utils/visualizeGraph.js";
|
|
6
|
+
import writeOutput from "./utils/writeOutput.js";
|
|
7
|
+
import loadConfig from "./utils/loadConfig.js";
|
|
8
|
+
import outputFormatter from "./utils/outputFormatter.js";
|
|
9
|
+
try {
|
|
10
|
+
// loads in the configs
|
|
11
|
+
const config = await loadConfig();
|
|
12
|
+
const ignores = config["ignores"];
|
|
13
|
+
const outDir = config["outDir"];
|
|
14
|
+
const outDirSingleEmit = config["outDirSingleEmit"];
|
|
15
|
+
const outFile = config["outFile"];
|
|
16
|
+
const chunkSize = config["chunkSize"];
|
|
17
|
+
// builds graph
|
|
18
|
+
let graph = await buildGraph(process.cwd(), ignores);
|
|
19
|
+
// creates visualization from the graph
|
|
20
|
+
const visualization = "*** project structure ***\n\n" + visualizeGraph(graph) + "\n";
|
|
21
|
+
// creates output directory; removes previous ones
|
|
22
|
+
const finalOutDir = path.join(process.cwd(), outDir);
|
|
23
|
+
await fs.rm(finalOutDir, { recursive: true, force: true });
|
|
24
|
+
await fs.mkdir(finalOutDir, { recursive: true });
|
|
25
|
+
// creates output path;
|
|
26
|
+
const finalOutPath = path.join(finalOutDir, outFile);
|
|
27
|
+
// creates path of the first output file
|
|
28
|
+
const firstFinalOutPath = outputFormatter(finalOutPath, 1);
|
|
29
|
+
// writes the visualization to the first output file
|
|
30
|
+
await fs.writeFile(firstFinalOutPath, visualization, {
|
|
31
|
+
flag: "w+",
|
|
32
|
+
});
|
|
33
|
+
// count object to access number of output files
|
|
34
|
+
// from outside the writeOutput function
|
|
35
|
+
const count = { count: 1 };
|
|
36
|
+
// adds file contents to output
|
|
37
|
+
await writeOutput(graph, finalOutPath, chunkSize, count);
|
|
38
|
+
// creates path for single emits
|
|
39
|
+
const singleEmitOutPath = path.join(process.cwd(), path.basename(firstFinalOutPath));
|
|
40
|
+
// detects if only a single output file and emits it
|
|
41
|
+
// in the working directory instead of the outDir
|
|
42
|
+
if (count.count === 1 && !outDirSingleEmit) {
|
|
43
|
+
// creates path of the first output file for single emits
|
|
44
|
+
await fs.rename(firstFinalOutPath, singleEmitOutPath);
|
|
45
|
+
await fs.rm(finalOutDir, { recursive: true, force: true });
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
await fs.rm(singleEmitOutPath, { force: true });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (error instanceof Error) {
|
|
53
|
+
console.log(error.message);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
console.log(error);
|
|
57
|
+
}
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,UAAU,MAAM,uBAAuB,CAAC;AAC/C,OAAO,cAAc,MAAM,2BAA2B,CAAC;AACvD,OAAO,WAAW,MAAM,wBAAwB,CAAC;AACjD,OAAO,UAAU,MAAM,uBAAuB,CAAC;AAC/C,OAAO,eAAe,MAAM,4BAA4B,CAAC;AAIzD,IAAI,CAAC;IACD,uBAAuB;IACvB,MAAM,MAAM,GAAW,MAAM,UAAU,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAa,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAW,MAAM,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,gBAAgB,GAAY,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAW,MAAM,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAW,MAAM,CAAC,WAAW,CAAC,CAAC;IAE9C,eAAe;IACf,IAAI,KAAK,GAAa,MAAM,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;IAE/D,uCAAuC;IACvC,MAAM,aAAa,GACf,+BAA+B,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IAEnE,kDAAkD;IAClD,MAAM,WAAW,GAAW,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;IAC7D,MAAM,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEjD,uBAAuB;IACvB,MAAM,YAAY,GAAW,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC7D,wCAAwC;IACxC,MAAM,iBAAiB,GAAW,eAAe,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAEnE,oDAAoD;IACpD,MAAM,EAAE,CAAC,SAAS,CAAC,iBAAiB,EAAE,aAAa,EAAE;QACjD,IAAI,EAAE,IAAI;KACb,CAAC,CAAC;IAEH,gDAAgD;IAChD,wCAAwC;IACxC,MAAM,KAAK,GAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAC9C,+BAA+B;IAC/B,MAAM,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAEzD,gCAAgC;IAChC,MAAM,iBAAiB,GAAW,IAAI,CAAC,IAAI,CACvC,OAAO,CAAC,GAAG,EAAE,EACb,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CACnC,CAAC;IACF,oDAAoD;IACpD,iDAAiD;IACjD,IAAI,KAAK,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACzC,yDAAyD;QACzD,MAAM,EAAE,CAAC,MAAM,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;QACtD,MAAM,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;SAAM,CAAC;QACJ,MAAM,EAAE,CAAC,EAAE,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;AACL,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACb,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.type.d.ts","sourceRoot":"","sources":["../src/index.type.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.type.js","sourceRoot":"","sources":["../src/index.type.ts"],"names":[],"mappings":";AAAA,uBAAuB;AACvB,oBAAoB;AACpB,oBAAoB;AACpB,oBAAoB;AACpB,qCAAqC;AACrC,KAAK"}
|
package/dist/test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../test.ts"],"names":[],"mappings":""}
|
package/dist/test.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// const INDENT = " ";
|
|
2
|
+
// const SUB_CONTENT = "|____";
|
|
3
|
+
export {};
|
|
4
|
+
// function printStructure(file: string, type: "dir" | "file"): string {
|
|
5
|
+
// return "t";
|
|
6
|
+
// }
|
|
7
|
+
/*
|
|
8
|
+
|
|
9
|
+
***PROJECT_STRUCTURE***
|
|
10
|
+
|
|
11
|
+
path
|
|
12
|
+
|____hello world
|
|
13
|
+
|____hello world
|
|
14
|
+
|____test
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
**********************
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
*/
|
|
21
|
+
//# sourceMappingURL=test.js.map
|
package/dist/test.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../test.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,+BAA+B;;AAG/B,wEAAwE;AACxE,kBAAkB;AAClB,IAAI;AAEJ;;;;;;;;;;;;;EAaE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FileNode } from "./utils.type.js";
|
|
2
|
+
/**
|
|
3
|
+
* Recursively constructs a graph of the project starting from the path
|
|
4
|
+
* given by dirPath.
|
|
5
|
+
*
|
|
6
|
+
* @param dirPath Path where the graph should start
|
|
7
|
+
* @param ignores Directories/filters to ignore
|
|
8
|
+
* @param maxDepth Max depth to recurse to prevent infinite recursion
|
|
9
|
+
* @param depth Current depth
|
|
10
|
+
* @returns FileNode object
|
|
11
|
+
*/
|
|
12
|
+
export default function buildGraph(dirPath: string, ignores?: string[], maxDepth?: number, depth?: number): Promise<FileNode>;
|
|
13
|
+
//# sourceMappingURL=buildGraph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildGraph.d.ts","sourceRoot":"","sources":["../../src/utils/buildGraph.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;;;;;;GASG;AACH,wBAA8B,UAAU,CACpC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,MAAM,EAAO,EACtB,QAAQ,GAAE,MAAa,EACvB,KAAK,GAAE,MAAU,GAClB,OAAO,CAAC,QAAQ,CAAC,CAyCnB"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Recursively constructs a graph of the project starting from the path
|
|
5
|
+
* given by dirPath.
|
|
6
|
+
*
|
|
7
|
+
* @param dirPath Path where the graph should start
|
|
8
|
+
* @param ignores Directories/filters to ignore
|
|
9
|
+
* @param maxDepth Max depth to recurse to prevent infinite recursion
|
|
10
|
+
* @param depth Current depth
|
|
11
|
+
* @returns FileNode object
|
|
12
|
+
*/
|
|
13
|
+
export default async function buildGraph(dirPath, ignores = [], maxDepth = 1000, depth = 0) {
|
|
14
|
+
// gets name of directory/file
|
|
15
|
+
const name = path.basename(dirPath);
|
|
16
|
+
// get stats about directory/file
|
|
17
|
+
const stats = await fs.stat(dirPath);
|
|
18
|
+
// creates a new node
|
|
19
|
+
const fileNode = {
|
|
20
|
+
name,
|
|
21
|
+
path: dirPath,
|
|
22
|
+
type: stats.isDirectory() ? "directory" : "file",
|
|
23
|
+
depth,
|
|
24
|
+
size: stats.size,
|
|
25
|
+
};
|
|
26
|
+
// recursively adds children nodes
|
|
27
|
+
if (stats.isDirectory() && depth < maxDepth) {
|
|
28
|
+
// gets all the files/directories within the current one
|
|
29
|
+
const entries = await fs.readdir(dirPath);
|
|
30
|
+
// filter out ignores files/directories
|
|
31
|
+
let filteredEntries = entries.filter((entry) => !ignores.includes(entry));
|
|
32
|
+
// add sub-directories and their files
|
|
33
|
+
// as a children property to the parent node
|
|
34
|
+
fileNode.children = await Promise.all(filteredEntries.map((entry) => buildGraph(path.join(dirPath, entry), ignores, maxDepth, depth + 1)));
|
|
35
|
+
}
|
|
36
|
+
return fileNode;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=buildGraph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildGraph.js","sourceRoot":"","sources":["../../src/utils/buildGraph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,UAAU,CACpC,OAAe,EACf,UAAoB,EAAE,EACtB,WAAmB,IAAI,EACvB,QAAgB,CAAC;IAEjB,8BAA8B;IAC9B,MAAM,IAAI,GAAW,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE5C,iCAAiC;IACjC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAErC,qBAAqB;IACrB,MAAM,QAAQ,GAAa;QACvB,IAAI;QACJ,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM;QAChD,KAAK;QACL,IAAI,EAAE,KAAK,CAAC,IAAI;KACnB,CAAC;IAEF,kCAAkC;IAClC,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC;QAC1C,wDAAwD;QACxD,MAAM,OAAO,GAAa,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAEpD,uCAAuC;QACvC,IAAI,eAAe,GAAa,OAAO,CAAC,MAAM,CAC1C,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CACtC,CAAC;QAEF,sCAAsC;QACtC,4CAA4C;QAC5C,QAAQ,CAAC,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAC1B,UAAU,CACN,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,EACzB,OAAO,EACP,QAAQ,EACR,KAAK,GAAG,CAAC,CACZ,CACJ,CACJ,CAAC;IACN,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getConfig.d.ts","sourceRoot":"","sources":["../../src/utils/getConfig.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getConfig.js","sourceRoot":"","sources":["../../src/utils/getConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;AACtC,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Config } from "../config.type.js";
|
|
2
|
+
/**
|
|
3
|
+
* Loads in the user's config and merges it with default config
|
|
4
|
+
* to fill undefined fields. Assumes the user's config is in the
|
|
5
|
+
* same directory as process.cwd(), contains "ezctx", and is a JSON file.
|
|
6
|
+
*
|
|
7
|
+
* @returns Config
|
|
8
|
+
*/
|
|
9
|
+
export default function loadConfig(): Promise<Config>;
|
|
10
|
+
//# sourceMappingURL=loadConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadConfig.d.ts","sourceRoot":"","sources":["../../src/utils/loadConfig.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAwBhD;;;;;;GAMG;AACH,wBAA8B,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CA8C1D"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import outputFormatter from "./outputFormatter.js";
|
|
3
|
+
// default ignores
|
|
4
|
+
const _defaultIgnores = [
|
|
5
|
+
"node_modules",
|
|
6
|
+
"package-lock.json",
|
|
7
|
+
"package.json",
|
|
8
|
+
".git",
|
|
9
|
+
".gitignore",
|
|
10
|
+
".DS_Store",
|
|
11
|
+
".vscode",
|
|
12
|
+
];
|
|
13
|
+
// default config
|
|
14
|
+
const defaultConfig = {
|
|
15
|
+
chunkSize: Infinity,
|
|
16
|
+
defaultIgnores: true,
|
|
17
|
+
ignores: _defaultIgnores,
|
|
18
|
+
outDir: "ezctx",
|
|
19
|
+
outDirSingleEmit: false,
|
|
20
|
+
outFile: "ezctx_{i}.txt",
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Loads in the user's config and merges it with default config
|
|
24
|
+
* to fill undefined fields. Assumes the user's config is in the
|
|
25
|
+
* same directory as process.cwd(), contains "ezctx", and is a JSON file.
|
|
26
|
+
*
|
|
27
|
+
* @returns Config
|
|
28
|
+
*/
|
|
29
|
+
export default async function loadConfig() {
|
|
30
|
+
// searches for a user-defined config
|
|
31
|
+
let userConfig;
|
|
32
|
+
const userConfigName = (await fs.readdir(process.cwd())).find((file) => file.includes("ezctx"));
|
|
33
|
+
if (userConfigName) {
|
|
34
|
+
userConfig = JSON.parse(await fs.readFile(userConfigName, "utf-8"));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
userConfig = defaultConfig;
|
|
38
|
+
}
|
|
39
|
+
// merges the program's default ignores with
|
|
40
|
+
// the user-defined ignores
|
|
41
|
+
// stores the merged ignores
|
|
42
|
+
let mergedIgnores;
|
|
43
|
+
if (userConfig.defaultIgnores === undefined || userConfig.defaultIgnores) {
|
|
44
|
+
mergedIgnores = [..._defaultIgnores, ...(userConfig.ignores || [])];
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
mergedIgnores = [...(userConfig.ignores || [])];
|
|
48
|
+
}
|
|
49
|
+
// add program's output directory and output file to ignores
|
|
50
|
+
// to prevent duplicate writes
|
|
51
|
+
mergedIgnores.push(userConfig.outDir || defaultConfig.outDir);
|
|
52
|
+
mergedIgnores.push(userConfig.outFile
|
|
53
|
+
? outputFormatter(userConfig.outFile, 1)
|
|
54
|
+
: outputFormatter(defaultConfig.outFile, 1));
|
|
55
|
+
// creates merged config
|
|
56
|
+
const mergedConfig = {
|
|
57
|
+
...defaultConfig,
|
|
58
|
+
...Object.fromEntries(Object.entries(userConfig).filter(([_, value]) => value !== undefined)),
|
|
59
|
+
ignores: mergedIgnores,
|
|
60
|
+
};
|
|
61
|
+
return mergedConfig;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=loadConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadConfig.js","sourceRoot":"","sources":["../../src/utils/loadConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC,OAAO,eAAe,MAAM,sBAAsB,CAAC;AAEnD,kBAAkB;AAClB,MAAM,eAAe,GAAa;IAC9B,cAAc;IACd,mBAAmB;IACnB,cAAc;IACd,MAAM;IACN,YAAY;IACZ,WAAW;IACX,SAAS;CACZ,CAAC;AAEF,iBAAiB;AACjB,MAAM,aAAa,GAAW;IAC1B,SAAS,EAAE,QAAQ;IACnB,cAAc,EAAE,IAAI;IACpB,OAAO,EAAE,eAAe;IACxB,MAAM,EAAE,OAAO;IACf,gBAAgB,EAAE,KAAK;IACvB,OAAO,EAAE,eAAe;CAC3B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,UAAU;IACpC,qCAAqC;IACrC,IAAI,UAA2B,CAAC;IAChC,MAAM,cAAc,GAAuB,CACvC,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAClC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAEzC,IAAI,cAAc,EAAE,CAAC;QACjB,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;IACxE,CAAC;SAAM,CAAC;QACJ,UAAU,GAAG,aAAa,CAAC;IAC/B,CAAC;IAED,4CAA4C;IAC5C,2BAA2B;IAE3B,4BAA4B;IAC5B,IAAI,aAAuB,CAAC;IAE5B,IAAI,UAAU,CAAC,cAAc,KAAK,SAAS,IAAI,UAAU,CAAC,cAAc,EAAE,CAAC;QACvE,aAAa,GAAG,CAAC,GAAG,eAAe,EAAE,GAAG,CAAC,UAAU,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IACxE,CAAC;SAAM,CAAC;QACJ,aAAa,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,4DAA4D;IAC5D,8BAA8B;IAC9B,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9D,aAAa,CAAC,IAAI,CACd,UAAU,CAAC,OAAO;QACd,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;QACxC,CAAC,CAAC,eAAe,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAClD,CAAC;IAEF,wBAAwB;IACxB,MAAM,YAAY,GAAW;QACzB,GAAG,aAAa;QAChB,GAAG,MAAM,CAAC,WAAW,CACjB,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAC7B,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CACtC,CACJ;QACD,OAAO,EAAE,aAAa;KACzB,CAAC;IAEF,OAAO,YAAY,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Takes in a path or file and embeds the current file count
|
|
3
|
+
* within the output file defined in the config. If the raw
|
|
4
|
+
* output file does not define a place to embed the count, this
|
|
5
|
+
* program defaulty adds "_{count}" before the file name.
|
|
6
|
+
*
|
|
7
|
+
* @param outFile The raw output file format defined in the config
|
|
8
|
+
* @param count The nth output file that is being created
|
|
9
|
+
* @returns A formatted path/file name with the count embedded
|
|
10
|
+
*/
|
|
11
|
+
export default function outputFormatter(outputPath: string, count: number): string;
|
|
12
|
+
//# sourceMappingURL=outputFormatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputFormatter.d.ts","sourceRoot":"","sources":["../../src/utils/outputFormatter.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,MAAM,CAAC,OAAO,UAAU,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,GACd,MAAM,CAqBR"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
/**
|
|
3
|
+
* Takes in a path or file and embeds the current file count
|
|
4
|
+
* within the output file defined in the config. If the raw
|
|
5
|
+
* output file does not define a place to embed the count, this
|
|
6
|
+
* program defaulty adds "_{count}" before the file name.
|
|
7
|
+
*
|
|
8
|
+
* @param outFile The raw output file format defined in the config
|
|
9
|
+
* @param count The nth output file that is being created
|
|
10
|
+
* @returns A formatted path/file name with the count embedded
|
|
11
|
+
*/
|
|
12
|
+
export default function outputFormatter(outputPath, count) {
|
|
13
|
+
// extracts the file name
|
|
14
|
+
const fileName = path.basename(outputPath);
|
|
15
|
+
// extracts the file dirname
|
|
16
|
+
const dirName = path.dirname(outputPath);
|
|
17
|
+
// gets index of the section to replace with the
|
|
18
|
+
// current file count
|
|
19
|
+
const index = fileName.indexOf("{i}");
|
|
20
|
+
if (index == -1) {
|
|
21
|
+
// if not defined, add default count
|
|
22
|
+
const fileNameParts = fileName.split(".");
|
|
23
|
+
const finalOutputFile = fileNameParts[0] + `_${count}.` + fileNameParts[1];
|
|
24
|
+
return path.join(dirName, finalOutputFile);
|
|
25
|
+
}
|
|
26
|
+
// otherwise, replace the {i} with the current file count
|
|
27
|
+
const finalOutputFile = fileName.substring(0, index) + count + fileName.substring(index + 3);
|
|
28
|
+
return path.join(dirName, finalOutputFile);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=outputFormatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputFormatter.js","sourceRoot":"","sources":["../../src/utils/outputFormatter.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;GASG;AAEH,MAAM,CAAC,OAAO,UAAU,eAAe,CACnC,UAAkB,EAClB,KAAa;IAEb,yBAAyB;IACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC3C,4BAA4B;IAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACzC,gDAAgD;IAChD,qBAAqB;IACrB,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAEtC,IAAI,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC;QACd,oCAAoC;QACpC,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,eAAe,GACjB,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAC/C,CAAC;IAED,yDAAyD;IACzD,MAAM,eAAe,GACjB,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACzE,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats a given resource by adding spacing and lines
|
|
3
|
+
* to ensure that it is properly placed when creating a
|
|
4
|
+
* visualization of the project's structure
|
|
5
|
+
*
|
|
6
|
+
* @param depth Current depth within the graph
|
|
7
|
+
* @param name Name of the file/directory
|
|
8
|
+
* @param type Type of the given resource
|
|
9
|
+
* @returns A formatted string of the resource
|
|
10
|
+
*/
|
|
11
|
+
export default function stringFormatter(depth: number, name: string, type: "directory" | "file"): string;
|
|
12
|
+
//# sourceMappingURL=stringFormatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stringFormatter.d.ts","sourceRoot":"","sources":["../../src/utils/stringFormatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,OAAO,UAAU,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,WAAW,GAAG,MAAM,GAC3B,MAAM,CAKR"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats a given resource by adding spacing and lines
|
|
3
|
+
* to ensure that it is properly placed when creating a
|
|
4
|
+
* visualization of the project's structure
|
|
5
|
+
*
|
|
6
|
+
* @param depth Current depth within the graph
|
|
7
|
+
* @param name Name of the file/directory
|
|
8
|
+
* @param type Type of the given resource
|
|
9
|
+
* @returns A formatted string of the resource
|
|
10
|
+
*/
|
|
11
|
+
export default function stringFormatter(depth, name, type) {
|
|
12
|
+
return depth == 0
|
|
13
|
+
? `\\${name}\n`
|
|
14
|
+
: ` `.repeat(depth - 1) +
|
|
15
|
+
`|__${name}${type === "directory" ? "/" : ""}\n`;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=stringFormatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stringFormatter.js","sourceRoot":"","sources":["../../src/utils/stringFormatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,OAAO,UAAU,eAAe,CACnC,KAAa,EACb,IAAY,EACZ,IAA0B;IAE1B,OAAO,KAAK,IAAI,CAAC;QACb,CAAC,CAAC,KAAK,IAAI,IAAI;QACf,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;YACnB,MAAM,IAAI,GAAG,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.type.d.ts","sourceRoot":"","sources":["../../src/utils/utils.type.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,QAAQ,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,EAAE,CAAC;CACrC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.type.js","sourceRoot":"","sources":["../../src/utils/utils.type.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FileNode } from "./utils.type.js";
|
|
2
|
+
/**
|
|
3
|
+
* Recursively creates a visualization of the project's graph.
|
|
4
|
+
* Uses stringFormatter.ts to format each directory/file
|
|
5
|
+
*
|
|
6
|
+
* @param graph Project's graph
|
|
7
|
+
* @param output Store's recursive output
|
|
8
|
+
* @returns A visualization of the given graph
|
|
9
|
+
*/
|
|
10
|
+
export default function visualizeGraph(graph: FileNode | FileNode[] | undefined, output?: string): string;
|
|
11
|
+
//# sourceMappingURL=visualizeGraph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visualizeGraph.d.ts","sourceRoot":"","sources":["../../src/utils/visualizeGraph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGhD;;;;;;;GAOG;AAEH,MAAM,CAAC,OAAO,UAAU,cAAc,CAClC,KAAK,EAAE,QAAQ,GAAG,QAAQ,EAAE,GAAG,SAAS,EACxC,MAAM,GAAE,MAAW,GACpB,MAAM,CAgBR"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import stringFormatter from "./stringFormatter.js";
|
|
2
|
+
/**
|
|
3
|
+
* Recursively creates a visualization of the project's graph.
|
|
4
|
+
* Uses stringFormatter.ts to format each directory/file
|
|
5
|
+
*
|
|
6
|
+
* @param graph Project's graph
|
|
7
|
+
* @param output Store's recursive output
|
|
8
|
+
* @returns A visualization of the given graph
|
|
9
|
+
*/
|
|
10
|
+
export default function visualizeGraph(graph, output = "") {
|
|
11
|
+
// if graph is undefined, reach end/tip
|
|
12
|
+
if (!graph)
|
|
13
|
+
return output;
|
|
14
|
+
// if not array, it's the root or a child within an array
|
|
15
|
+
if (!Array.isArray(graph)) {
|
|
16
|
+
output += stringFormatter(graph.depth, graph.name, graph.type);
|
|
17
|
+
output = visualizeGraph(graph.children, output);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
graph.forEach((child) => {
|
|
21
|
+
output += stringFormatter(child.depth, child.name, child.type);
|
|
22
|
+
output = visualizeGraph(child.children, output);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return output;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=visualizeGraph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visualizeGraph.js","sourceRoot":"","sources":["../../src/utils/visualizeGraph.ts"],"names":[],"mappings":"AACA,OAAO,eAAe,MAAM,sBAAsB,CAAC;AAEnD;;;;;;;GAOG;AAEH,MAAM,CAAC,OAAO,UAAU,cAAc,CAClC,KAAwC,EACxC,SAAiB,EAAE;IAEnB,uCAAuC;IACvC,IAAI,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC;IAE1B,yDAAyD;IACzD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/D,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpD,CAAC;SAAM,CAAC;QACJ,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,MAAM,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/D,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACP,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FileNode } from "./utils.type.js";
|
|
2
|
+
/**
|
|
3
|
+
* Recursively adds content to the output files while ensuring
|
|
4
|
+
* that the size of each output file is less than the given chunkSize.
|
|
5
|
+
* If it is, it starts a new output file with the file namen given in
|
|
6
|
+
* outputPath.
|
|
7
|
+
*
|
|
8
|
+
* @param {FileNode | FileNode[] | undefined} graph Project's graph
|
|
9
|
+
* @param {string} outputPath The path to write output to
|
|
10
|
+
* @param {number} chunkSize The max size of each output file
|
|
11
|
+
* @param {number} count The count of the current output file
|
|
12
|
+
*/
|
|
13
|
+
export default function writeFiles(graph: FileNode | FileNode[] | undefined, outputPath: string, chunkSize: number, count?: {
|
|
14
|
+
count: number;
|
|
15
|
+
}): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=writeFiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeFiles.d.ts","sourceRoot":"","sources":["../../src/utils/writeFiles.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGhD;;;;;;;;;;GAUG;AAEH,wBAA8B,UAAU,CACpC,KAAK,EAAE,QAAQ,GAAG,QAAQ,EAAE,GAAG,SAAS,EACxC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAiB,GACxC,OAAO,CAAC,IAAI,CAAC,CAsCf"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import outputFormatter from "./outputFormatter.js";
|
|
3
|
+
/**
|
|
4
|
+
* Recursively adds content to the output files while ensuring
|
|
5
|
+
* that the size of each output file is less than the given chunkSize.
|
|
6
|
+
* If it is, it starts a new output file with the file namen given in
|
|
7
|
+
* outputPath.
|
|
8
|
+
*
|
|
9
|
+
* @param {FileNode | FileNode[] | undefined} graph Project's graph
|
|
10
|
+
* @param {string} outputPath The path to write output to
|
|
11
|
+
* @param {number} chunkSize The max size of each output file
|
|
12
|
+
* @param {number} count The count of the current output file
|
|
13
|
+
*/
|
|
14
|
+
export default async function writeFiles(graph, outputPath, chunkSize, count = { count: 1 }) {
|
|
15
|
+
// if graph is null/undefined, reach tip
|
|
16
|
+
if (!graph)
|
|
17
|
+
return;
|
|
18
|
+
// turn current node into array to handle empty directories
|
|
19
|
+
const nodes = Array.isArray(graph) ? graph : [graph];
|
|
20
|
+
// recursively adds each nodes' file content to the output
|
|
21
|
+
for (const node of nodes) {
|
|
22
|
+
if (node.type === "directory") {
|
|
23
|
+
await writeFiles(node.children, outputPath, chunkSize, count);
|
|
24
|
+
}
|
|
25
|
+
else if (node.type === "file") {
|
|
26
|
+
// get file's content and add formatting
|
|
27
|
+
const content = "*** " +
|
|
28
|
+
node.name +
|
|
29
|
+
" ***" +
|
|
30
|
+
"\n\n" +
|
|
31
|
+
(await fs.readFile(node.path)) +
|
|
32
|
+
"\n";
|
|
33
|
+
// get the correct output path
|
|
34
|
+
let currentPath = outputFormatter(outputPath, count.count);
|
|
35
|
+
// get the size of the current content
|
|
36
|
+
const contentSize = Buffer.byteLength(content, "utf-8");
|
|
37
|
+
// try-catch block because the currentPath may be exist on disk
|
|
38
|
+
// ie. first time writing to this output file
|
|
39
|
+
try {
|
|
40
|
+
// get size of current output file
|
|
41
|
+
const { size } = await fs.stat(currentPath);
|
|
42
|
+
// ensures that the chunkSize condition is respected
|
|
43
|
+
if (size > 0 && contentSize + size > chunkSize) {
|
|
44
|
+
currentPath = outputFormatter(outputPath, ++count.count);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) { }
|
|
48
|
+
await fs.writeFile(currentPath, content, { flag: "a" });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=writeFiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeFiles.js","sourceRoot":"","sources":["../../src/utils/writeFiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEvC,OAAO,eAAe,MAAM,sBAAsB,CAAC;AAEnD;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,UAAU,CACpC,KAAwC,EACxC,UAAkB,EAClB,SAAiB,EACjB,QAA2B,EAAE,KAAK,EAAE,CAAC,EAAE;IAEvC,wCAAwC;IACxC,IAAI,CAAC,KAAK;QAAE,OAAO;IAEnB,2DAA2D;IAC3D,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAErD,0DAA0D;IAC1D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC5B,MAAM,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAClE,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC9B,wCAAwC;YACxC,MAAM,OAAO,GACT,MAAM;gBACN,IAAI,CAAC,IAAI;gBACT,MAAM;gBACN,MAAM;gBACN,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC9B,IAAI,CAAC;YACT,+BAA+B;YAC/B,IAAI,WAAW,GAAG,eAAe,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YAC3D,sCAAsC;YACtC,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxD,+DAA+D;YAC/D,6CAA6C;YAC7C,IAAI,CAAC;gBACD,kCAAkC;gBAClC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAC5C,oDAAoD;gBACpD,IAAI,IAAI,GAAG,CAAC,IAAI,WAAW,GAAG,IAAI,GAAG,SAAS,EAAE,CAAC;oBAC7C,WAAW,GAAG,eAAe,CAAC,UAAU,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;gBAC7D,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC,CAAA,CAAC;YAElB,MAAM,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5D,CAAC;IACL,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FileNode } from "./utils.type.js";
|
|
2
|
+
/**
|
|
3
|
+
* Recursively adds content to the output files while ensuring
|
|
4
|
+
* that the size of each output file is less than the given chunkSize.
|
|
5
|
+
* If it is, it starts a new output file with the file namen given in
|
|
6
|
+
* outputPath. Stores the count as an object to have it persist.
|
|
7
|
+
*
|
|
8
|
+
* @param graph Project's graph
|
|
9
|
+
* @param outputPath The path to write output to
|
|
10
|
+
* @param chunkSize The max size of each output file
|
|
11
|
+
* @param count The count of the current output file
|
|
12
|
+
*/
|
|
13
|
+
export default function writeOutput(graph: FileNode | FileNode[] | undefined, outputPath: string, chunkSize: number, count: {
|
|
14
|
+
count: number;
|
|
15
|
+
}): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=writeOutput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeOutput.d.ts","sourceRoot":"","sources":["../../src/utils/writeOutput.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGhD;;;;;;;;;;GAUG;AAEH,wBAA8B,WAAW,CACrC,KAAK,EAAE,QAAQ,GAAG,QAAQ,EAAE,GAAG,SAAS,EACxC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACzB,OAAO,CAAC,IAAI,CAAC,CA2Cf"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import outputFormatter from "./outputFormatter.js";
|
|
3
|
+
/**
|
|
4
|
+
* Recursively adds content to the output files while ensuring
|
|
5
|
+
* that the size of each output file is less than the given chunkSize.
|
|
6
|
+
* If it is, it starts a new output file with the file namen given in
|
|
7
|
+
* outputPath. Stores the count as an object to have it persist.
|
|
8
|
+
*
|
|
9
|
+
* @param graph Project's graph
|
|
10
|
+
* @param outputPath The path to write output to
|
|
11
|
+
* @param chunkSize The max size of each output file
|
|
12
|
+
* @param count The count of the current output file
|
|
13
|
+
*/
|
|
14
|
+
export default async function writeOutput(graph, outputPath, chunkSize, count) {
|
|
15
|
+
// if graph is null/undefined, reach tip
|
|
16
|
+
if (!graph)
|
|
17
|
+
return;
|
|
18
|
+
// turn current node into array to handle empty directories
|
|
19
|
+
const nodes = Array.isArray(graph) ? graph : [graph];
|
|
20
|
+
// recursively adds each nodes' file content to the output
|
|
21
|
+
for (const node of nodes) {
|
|
22
|
+
if (node.type === "directory") {
|
|
23
|
+
await writeOutput(node.children, outputPath, chunkSize, count);
|
|
24
|
+
}
|
|
25
|
+
else if (node.type === "file") {
|
|
26
|
+
// get file's content and add formatting
|
|
27
|
+
const content = "*** " +
|
|
28
|
+
node.name +
|
|
29
|
+
" ***" +
|
|
30
|
+
"\n\n" +
|
|
31
|
+
(await fs.readFile(node.path)) +
|
|
32
|
+
"\n";
|
|
33
|
+
// get the correct output path
|
|
34
|
+
let currentOutputPath = outputFormatter(outputPath, count.count);
|
|
35
|
+
// get the size of the current content
|
|
36
|
+
const contentSize = Buffer.byteLength(content, "utf-8");
|
|
37
|
+
// try-catch block because the currentOutputPath may not exist on disk
|
|
38
|
+
// ie. first time writing to this output file
|
|
39
|
+
try {
|
|
40
|
+
// get size of current output file
|
|
41
|
+
const { size } = await fs.stat(currentOutputPath);
|
|
42
|
+
// if the size of the current content is bigger
|
|
43
|
+
// than chunk size, skip file
|
|
44
|
+
if (contentSize > chunkSize)
|
|
45
|
+
return;
|
|
46
|
+
// ensures that the chunkSize condition is respected
|
|
47
|
+
if (size > 0 && contentSize + size > chunkSize) {
|
|
48
|
+
currentOutputPath = outputFormatter(outputPath, ++count.count);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (error) { }
|
|
52
|
+
await fs.writeFile(currentOutputPath, content, { flag: "a" });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=writeOutput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeOutput.js","sourceRoot":"","sources":["../../src/utils/writeOutput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEvC,OAAO,eAAe,MAAM,sBAAsB,CAAC;AAEnD;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,WAAW,CACrC,KAAwC,EACxC,UAAkB,EAClB,SAAiB,EACjB,KAAwB;IAExB,wCAAwC;IACxC,IAAI,CAAC,KAAK;QAAE,OAAO;IAEnB,2DAA2D;IAC3D,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAErD,0DAA0D;IAC1D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC5B,MAAM,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QACnE,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC9B,wCAAwC;YACxC,MAAM,OAAO,GACT,MAAM;gBACN,IAAI,CAAC,IAAI;gBACT,MAAM;gBACN,MAAM;gBACN,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC9B,IAAI,CAAC;YACT,+BAA+B;YAC/B,IAAI,iBAAiB,GAAG,eAAe,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;YACjE,sCAAsC;YACtC,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxD,sEAAsE;YACtE,6CAA6C;YAC7C,IAAI,CAAC;gBACD,kCAAkC;gBAClC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;gBAElD,+CAA+C;gBAC/C,6BAA6B;gBAC7B,IAAI,WAAW,GAAG,SAAS;oBAAE,OAAO;gBAEpC,oDAAoD;gBACpD,IAAI,IAAI,GAAG,CAAC,IAAI,WAAW,GAAG,IAAI,GAAG,SAAS,EAAE,CAAC;oBAC7C,iBAAiB,GAAG,eAAe,CAAC,UAAU,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;gBACnE,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC,CAAA,CAAC;YAElB,MAAM,EAAE,CAAC,SAAS,CAAC,iBAAiB,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QAClE,CAAC;IACL,CAAC;AACL,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ezctx",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Puts all of your source code into one or several `.txt` file(s), allowing you to easily paste it into an external AI platform instead of having to tediously upload each individual file.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "zye123",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "dist/index.ts",
|
|
9
|
+
"bin": "./dist/index.js",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/arhayashi/ezctx.git"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/arhayashi/ezctx#readme",
|
|
15
|
+
"scripts": {
|
|
16
|
+
"ezctx": "npx tsc && node ./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/node": "^24.10.1",
|
|
20
|
+
"typescript": "^5.9.3"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"context",
|
|
24
|
+
"ai",
|
|
25
|
+
"bundler"
|
|
26
|
+
],
|
|
27
|
+
"files": [
|
|
28
|
+
"/dist"
|
|
29
|
+
]
|
|
30
|
+
}
|