make-folder-txt 2.2.6 → 2.2.7
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/bin/make-folder-txt.js +87 -38
- package/make-folder-txt.txt +88 -71
- package/package.json +1 -1
package/bin/make-folder-txt.js
CHANGED
|
@@ -87,6 +87,7 @@ function collectFiles(
|
|
|
87
87
|
rootName = "",
|
|
88
88
|
txtIgnore = new Set(),
|
|
89
89
|
force = false,
|
|
90
|
+
rootOnlyInclude = false,
|
|
90
91
|
} = options;
|
|
91
92
|
|
|
92
93
|
let entries;
|
|
@@ -129,27 +130,36 @@ function collectFiles(
|
|
|
129
130
|
const childInSelectedFolder = inSelectedFolder || onlyFolders.has(entry.name);
|
|
130
131
|
const childLines = [];
|
|
131
132
|
const childFiles = [];
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
133
|
+
|
|
134
|
+
// If rootOnlyInclude is true, only include root-level items
|
|
135
|
+
let child;
|
|
136
|
+
if (rootOnlyInclude && dir !== rootDir) {
|
|
137
|
+
// Don't recurse into subdirectories when rootOnlyInclude is true
|
|
138
|
+
child = { lines: [], filePaths: [], hasIncluded: false };
|
|
139
|
+
} else {
|
|
140
|
+
child = collectFiles(
|
|
141
|
+
childPath,
|
|
142
|
+
rootDir,
|
|
143
|
+
ignoreDirs,
|
|
144
|
+
ignoreFiles,
|
|
145
|
+
onlyFolders,
|
|
146
|
+
onlyFiles,
|
|
147
|
+
{
|
|
148
|
+
indent: childIndent,
|
|
149
|
+
lines: childLines,
|
|
150
|
+
filePaths: childFiles,
|
|
151
|
+
inSelectedFolder: childInSelectedFolder,
|
|
152
|
+
hasOnlyFilters,
|
|
153
|
+
rootName,
|
|
154
|
+
txtIgnore,
|
|
155
|
+
force,
|
|
156
|
+
rootOnlyInclude,
|
|
157
|
+
},
|
|
158
|
+
);
|
|
159
|
+
}
|
|
150
160
|
|
|
151
161
|
const explicitlySelectedFolder = hasOnlyFilters && onlyFolders.has(entry.name);
|
|
152
|
-
const shouldIncludeDir = !hasOnlyFilters || child.hasIncluded || explicitlySelectedFolder;
|
|
162
|
+
const shouldIncludeDir = !hasOnlyFilters || (rootOnlyInclude ? false : child.hasIncluded) || explicitlySelectedFolder;
|
|
153
163
|
|
|
154
164
|
if (shouldIncludeDir) {
|
|
155
165
|
lines.push(`${indent}${connector}${entry.name}/`);
|
|
@@ -170,7 +180,12 @@ function collectFiles(
|
|
|
170
180
|
// Ignore .txt files that match the folder name (e.g., foldername.txt) unless force is enabled
|
|
171
181
|
if (!force && entry.name.endsWith('.txt') && entry.name === `${rootName}.txt`) return;
|
|
172
182
|
|
|
173
|
-
|
|
183
|
+
// Check if this file matches any of the onlyFiles patterns
|
|
184
|
+
const shouldIncludeFile = !hasOnlyFilters || inSelectedFolder ||
|
|
185
|
+
onlyFiles.has(entry.name) ||
|
|
186
|
+
onlyFiles.has(relPathForIgnore) ||
|
|
187
|
+
onlyFiles.has(`/${relPathForIgnore}`);
|
|
188
|
+
|
|
174
189
|
if (!shouldIncludeFile) return;
|
|
175
190
|
|
|
176
191
|
lines.push(`${indent}${connector}${entry.name}`);
|
|
@@ -816,6 +831,7 @@ Dump an entire project folder into a single readable .txt file.
|
|
|
816
831
|
let noSkipFlag = false;
|
|
817
832
|
let splitMethod = null; // 'folder', 'file', 'size'
|
|
818
833
|
let splitSize = null; // size in bytes
|
|
834
|
+
let rootOnlyInclude = false; // For /include flag
|
|
819
835
|
|
|
820
836
|
for (let i = 0; i < args.length; i += 1) {
|
|
821
837
|
const arg = args[i];
|
|
@@ -908,14 +924,21 @@ Dump an entire project folder into a single readable .txt file.
|
|
|
908
924
|
if (arg === "--ignore-folder" || arg === "-ifo") {
|
|
909
925
|
let consumed = 0;
|
|
910
926
|
while (i + 1 < args.length && !args[i + 1].startsWith("-")) {
|
|
911
|
-
// Normalize the folder name: remove backslashes, trailing slashes, and leading ./
|
|
912
927
|
let folderName = args[i + 1];
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
928
|
+
|
|
929
|
+
// Check for /folder syntax (root-only include)
|
|
930
|
+
if (folderName.startsWith("/")) {
|
|
931
|
+
const cleanFolderName = folderName.slice(1); // Remove leading /
|
|
932
|
+
onlyFolders.add(cleanFolderName);
|
|
933
|
+
rootOnlyInclude = true;
|
|
934
|
+
i += 1;
|
|
935
|
+
consumed += 1;
|
|
936
|
+
} else {
|
|
937
|
+
// Normal folder path (could be nested like folder/subfolder)
|
|
938
|
+
onlyFolders.add(folderName);
|
|
939
|
+
i += 1;
|
|
940
|
+
consumed += 1;
|
|
941
|
+
}
|
|
919
942
|
}
|
|
920
943
|
if (consumed === 0) {
|
|
921
944
|
console.error("Error: --ignore-folder requires at least one folder name.");
|
|
@@ -932,12 +955,16 @@ Dump an entire project folder into a single readable .txt file.
|
|
|
932
955
|
console.error("Error: --ignore-folder requires a folder name.");
|
|
933
956
|
process.exit(1);
|
|
934
957
|
}
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
958
|
+
|
|
959
|
+
// Check for /folder syntax (root-only include)
|
|
960
|
+
if (value.startsWith("/")) {
|
|
961
|
+
const cleanFolderName = value.slice(1); // Remove leading /
|
|
962
|
+
onlyFolders.add(cleanFolderName);
|
|
963
|
+
rootOnlyInclude = true;
|
|
964
|
+
} else {
|
|
965
|
+
// Normal folder path (could be nested like folder/subfolder)
|
|
966
|
+
onlyFolders.add(value);
|
|
967
|
+
}
|
|
941
968
|
continue;
|
|
942
969
|
}
|
|
943
970
|
|
|
@@ -1006,9 +1033,21 @@ Dump an entire project folder into a single readable .txt file.
|
|
|
1006
1033
|
if (arg === "--only-file" || arg === "-ofi") {
|
|
1007
1034
|
let consumed = 0;
|
|
1008
1035
|
while (i + 1 < args.length && !args[i + 1].startsWith("-")) {
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1036
|
+
let fileName = args[i + 1];
|
|
1037
|
+
|
|
1038
|
+
// Check for /file syntax (root-only include)
|
|
1039
|
+
if (fileName.startsWith("/")) {
|
|
1040
|
+
const cleanFileName = fileName.slice(1); // Remove leading /
|
|
1041
|
+
onlyFiles.add(cleanFileName);
|
|
1042
|
+
rootOnlyInclude = true;
|
|
1043
|
+
i += 1;
|
|
1044
|
+
consumed += 1;
|
|
1045
|
+
} else {
|
|
1046
|
+
// Normal file path (could be nested like folder/file.ext)
|
|
1047
|
+
onlyFiles.add(fileName);
|
|
1048
|
+
i += 1;
|
|
1049
|
+
consumed += 1;
|
|
1050
|
+
}
|
|
1012
1051
|
}
|
|
1013
1052
|
if (consumed === 0) {
|
|
1014
1053
|
console.error("Error: --only-file requires at least one file name.");
|
|
@@ -1025,7 +1064,16 @@ Dump an entire project folder into a single readable .txt file.
|
|
|
1025
1064
|
console.error("Error: --only-file requires a file name.");
|
|
1026
1065
|
process.exit(1);
|
|
1027
1066
|
}
|
|
1028
|
-
|
|
1067
|
+
|
|
1068
|
+
// Check for /file syntax (root-only include)
|
|
1069
|
+
if (value.startsWith("/")) {
|
|
1070
|
+
const cleanFileName = value.slice(1); // Remove leading /
|
|
1071
|
+
onlyFiles.add(cleanFileName);
|
|
1072
|
+
rootOnlyInclude = true;
|
|
1073
|
+
} else {
|
|
1074
|
+
// Normal file path (could be nested like folder/file.ext)
|
|
1075
|
+
onlyFiles.add(value);
|
|
1076
|
+
}
|
|
1029
1077
|
continue;
|
|
1030
1078
|
}
|
|
1031
1079
|
|
|
@@ -1065,7 +1113,8 @@ Dump an entire project folder into a single readable .txt file.
|
|
|
1065
1113
|
rootName,
|
|
1066
1114
|
txtIgnore,
|
|
1067
1115
|
force: forceFlag,
|
|
1068
|
-
hasOnlyFilters: onlyFolders.size > 0 || onlyFiles.size > 0
|
|
1116
|
+
hasOnlyFilters: onlyFolders.size > 0 || onlyFiles.size > 0,
|
|
1117
|
+
rootOnlyInclude
|
|
1069
1118
|
}
|
|
1070
1119
|
);
|
|
1071
1120
|
|
package/make-folder-txt.txt
CHANGED
|
@@ -10,9 +10,8 @@ Root: C:\Programming\make-folder-txt
|
|
|
10
10
|
make-folder-txt/
|
|
11
11
|
├── bin/
|
|
12
12
|
│ └── make-folder-txt.js
|
|
13
|
-
├── package.json
|
|
14
13
|
|
|
15
|
-
Total files:
|
|
14
|
+
Total files: 1
|
|
16
15
|
|
|
17
16
|
================================================================================
|
|
18
17
|
FILE CONTENTS
|
|
@@ -110,6 +109,7 @@ function collectFiles(
|
|
|
110
109
|
rootName = "",
|
|
111
110
|
txtIgnore = new Set(),
|
|
112
111
|
force = false,
|
|
112
|
+
rootOnlyInclude = false,
|
|
113
113
|
} = options;
|
|
114
114
|
|
|
115
115
|
let entries;
|
|
@@ -152,27 +152,36 @@ function collectFiles(
|
|
|
152
152
|
const childInSelectedFolder = inSelectedFolder || onlyFolders.has(entry.name);
|
|
153
153
|
const childLines = [];
|
|
154
154
|
const childFiles = [];
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
155
|
+
|
|
156
|
+
// If rootOnlyInclude is true, only include root-level items
|
|
157
|
+
let child;
|
|
158
|
+
if (rootOnlyInclude && dir !== rootDir) {
|
|
159
|
+
// Don't recurse into subdirectories when rootOnlyInclude is true
|
|
160
|
+
child = { lines: [], filePaths: [], hasIncluded: false };
|
|
161
|
+
} else {
|
|
162
|
+
child = collectFiles(
|
|
163
|
+
childPath,
|
|
164
|
+
rootDir,
|
|
165
|
+
ignoreDirs,
|
|
166
|
+
ignoreFiles,
|
|
167
|
+
onlyFolders,
|
|
168
|
+
onlyFiles,
|
|
169
|
+
{
|
|
170
|
+
indent: childIndent,
|
|
171
|
+
lines: childLines,
|
|
172
|
+
filePaths: childFiles,
|
|
173
|
+
inSelectedFolder: childInSelectedFolder,
|
|
174
|
+
hasOnlyFilters,
|
|
175
|
+
rootName,
|
|
176
|
+
txtIgnore,
|
|
177
|
+
force,
|
|
178
|
+
rootOnlyInclude,
|
|
179
|
+
},
|
|
180
|
+
);
|
|
181
|
+
}
|
|
173
182
|
|
|
174
183
|
const explicitlySelectedFolder = hasOnlyFilters && onlyFolders.has(entry.name);
|
|
175
|
-
const shouldIncludeDir = !hasOnlyFilters || child.hasIncluded || explicitlySelectedFolder;
|
|
184
|
+
const shouldIncludeDir = !hasOnlyFilters || (rootOnlyInclude ? false : child.hasIncluded) || explicitlySelectedFolder;
|
|
176
185
|
|
|
177
186
|
if (shouldIncludeDir) {
|
|
178
187
|
lines.push(`${indent}${connector}${entry.name}/`);
|
|
@@ -193,7 +202,12 @@ function collectFiles(
|
|
|
193
202
|
// Ignore .txt files that match the folder name (e.g., foldername.txt) unless force is enabled
|
|
194
203
|
if (!force && entry.name.endsWith('.txt') && entry.name === `${rootName}.txt`) return;
|
|
195
204
|
|
|
196
|
-
|
|
205
|
+
// Check if this file matches any of the onlyFiles patterns
|
|
206
|
+
const shouldIncludeFile = !hasOnlyFilters || inSelectedFolder ||
|
|
207
|
+
onlyFiles.has(entry.name) ||
|
|
208
|
+
onlyFiles.has(relPathForIgnore) ||
|
|
209
|
+
onlyFiles.has(`/${relPathForIgnore}`);
|
|
210
|
+
|
|
197
211
|
if (!shouldIncludeFile) return;
|
|
198
212
|
|
|
199
213
|
lines.push(`${indent}${connector}${entry.name}`);
|
|
@@ -839,6 +853,7 @@ Dump an entire project folder into a single readable .txt file.
|
|
|
839
853
|
let noSkipFlag = false;
|
|
840
854
|
let splitMethod = null; // 'folder', 'file', 'size'
|
|
841
855
|
let splitSize = null; // size in bytes
|
|
856
|
+
let rootOnlyInclude = false; // For /include flag
|
|
842
857
|
|
|
843
858
|
for (let i = 0; i < args.length; i += 1) {
|
|
844
859
|
const arg = args[i];
|
|
@@ -931,14 +946,21 @@ Dump an entire project folder into a single readable .txt file.
|
|
|
931
946
|
if (arg === "--ignore-folder" || arg === "-ifo") {
|
|
932
947
|
let consumed = 0;
|
|
933
948
|
while (i + 1 < args.length && !args[i + 1].startsWith("-")) {
|
|
934
|
-
// Normalize the folder name: remove backslashes, trailing slashes, and leading ./
|
|
935
949
|
let folderName = args[i + 1];
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
950
|
+
|
|
951
|
+
// Check for /folder syntax (root-only include)
|
|
952
|
+
if (folderName.startsWith("/")) {
|
|
953
|
+
const cleanFolderName = folderName.slice(1); // Remove leading /
|
|
954
|
+
onlyFolders.add(cleanFolderName);
|
|
955
|
+
rootOnlyInclude = true;
|
|
956
|
+
i += 1;
|
|
957
|
+
consumed += 1;
|
|
958
|
+
} else {
|
|
959
|
+
// Normal folder path (could be nested like folder/subfolder)
|
|
960
|
+
onlyFolders.add(folderName);
|
|
961
|
+
i += 1;
|
|
962
|
+
consumed += 1;
|
|
963
|
+
}
|
|
942
964
|
}
|
|
943
965
|
if (consumed === 0) {
|
|
944
966
|
console.error("Error: --ignore-folder requires at least one folder name.");
|
|
@@ -955,12 +977,16 @@ Dump an entire project folder into a single readable .txt file.
|
|
|
955
977
|
console.error("Error: --ignore-folder requires a folder name.");
|
|
956
978
|
process.exit(1);
|
|
957
979
|
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
980
|
+
|
|
981
|
+
// Check for /folder syntax (root-only include)
|
|
982
|
+
if (value.startsWith("/")) {
|
|
983
|
+
const cleanFolderName = value.slice(1); // Remove leading /
|
|
984
|
+
onlyFolders.add(cleanFolderName);
|
|
985
|
+
rootOnlyInclude = true;
|
|
986
|
+
} else {
|
|
987
|
+
// Normal folder path (could be nested like folder/subfolder)
|
|
988
|
+
onlyFolders.add(value);
|
|
989
|
+
}
|
|
964
990
|
continue;
|
|
965
991
|
}
|
|
966
992
|
|
|
@@ -1029,9 +1055,21 @@ Dump an entire project folder into a single readable .txt file.
|
|
|
1029
1055
|
if (arg === "--only-file" || arg === "-ofi") {
|
|
1030
1056
|
let consumed = 0;
|
|
1031
1057
|
while (i + 1 < args.length && !args[i + 1].startsWith("-")) {
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1058
|
+
let fileName = args[i + 1];
|
|
1059
|
+
|
|
1060
|
+
// Check for /file syntax (root-only include)
|
|
1061
|
+
if (fileName.startsWith("/")) {
|
|
1062
|
+
const cleanFileName = fileName.slice(1); // Remove leading /
|
|
1063
|
+
onlyFiles.add(cleanFileName);
|
|
1064
|
+
rootOnlyInclude = true;
|
|
1065
|
+
i += 1;
|
|
1066
|
+
consumed += 1;
|
|
1067
|
+
} else {
|
|
1068
|
+
// Normal file path (could be nested like folder/file.ext)
|
|
1069
|
+
onlyFiles.add(fileName);
|
|
1070
|
+
i += 1;
|
|
1071
|
+
consumed += 1;
|
|
1072
|
+
}
|
|
1035
1073
|
}
|
|
1036
1074
|
if (consumed === 0) {
|
|
1037
1075
|
console.error("Error: --only-file requires at least one file name.");
|
|
@@ -1048,7 +1086,16 @@ Dump an entire project folder into a single readable .txt file.
|
|
|
1048
1086
|
console.error("Error: --only-file requires a file name.");
|
|
1049
1087
|
process.exit(1);
|
|
1050
1088
|
}
|
|
1051
|
-
|
|
1089
|
+
|
|
1090
|
+
// Check for /file syntax (root-only include)
|
|
1091
|
+
if (value.startsWith("/")) {
|
|
1092
|
+
const cleanFileName = value.slice(1); // Remove leading /
|
|
1093
|
+
onlyFiles.add(cleanFileName);
|
|
1094
|
+
rootOnlyInclude = true;
|
|
1095
|
+
} else {
|
|
1096
|
+
// Normal file path (could be nested like folder/file.ext)
|
|
1097
|
+
onlyFiles.add(value);
|
|
1098
|
+
}
|
|
1052
1099
|
continue;
|
|
1053
1100
|
}
|
|
1054
1101
|
|
|
@@ -1088,7 +1135,8 @@ Dump an entire project folder into a single readable .txt file.
|
|
|
1088
1135
|
rootName,
|
|
1089
1136
|
txtIgnore,
|
|
1090
1137
|
force: forceFlag,
|
|
1091
|
-
hasOnlyFilters: onlyFolders.size > 0 || onlyFiles.size > 0
|
|
1138
|
+
hasOnlyFilters: onlyFolders.size > 0 || onlyFiles.size > 0,
|
|
1139
|
+
rootOnlyInclude
|
|
1092
1140
|
}
|
|
1093
1141
|
);
|
|
1094
1142
|
|
|
@@ -1201,37 +1249,6 @@ main().catch(err => {
|
|
|
1201
1249
|
});
|
|
1202
1250
|
|
|
1203
1251
|
|
|
1204
|
-
--------------------------------------------------------------------------------
|
|
1205
|
-
FILE: /package.json
|
|
1206
|
-
--------------------------------------------------------------------------------
|
|
1207
|
-
{
|
|
1208
|
-
"name": "make-folder-txt",
|
|
1209
|
-
"version": "2.2.5",
|
|
1210
|
-
"description": "Generate a single .txt file containing the full folder structure and file contents of any project, ignoring node_modules and other junk.",
|
|
1211
|
-
"main": "bin/make-folder-txt.js",
|
|
1212
|
-
"bin": {
|
|
1213
|
-
"make-folder-txt": "bin/make-folder-txt.js"
|
|
1214
|
-
},
|
|
1215
|
-
"scripts": {
|
|
1216
|
-
"test": "echo \"No tests yet\" && exit 0"
|
|
1217
|
-
},
|
|
1218
|
-
"keywords": [
|
|
1219
|
-
"folder",
|
|
1220
|
-
"dump",
|
|
1221
|
-
"project",
|
|
1222
|
-
"structure",
|
|
1223
|
-
"txt",
|
|
1224
|
-
"cli",
|
|
1225
|
-
"export"
|
|
1226
|
-
],
|
|
1227
|
-
"author": "Muhammad Saad Amin",
|
|
1228
|
-
"license": "MIT",
|
|
1229
|
-
"engines": {
|
|
1230
|
-
"node": ">=14.0.0"
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
1252
|
================================================================================
|
|
1236
1253
|
END OF FOLDER: make-folder-txt
|
|
1237
1254
|
================================================================================
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "make-folder-txt",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.7",
|
|
4
4
|
"description": "Generate a single .txt file containing the full folder structure and file contents of any project, ignoring node_modules and other junk.",
|
|
5
5
|
"main": "bin/make-folder-txt.js",
|
|
6
6
|
"bin": {
|