filemayor 2.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/core/categories.js +235 -0
- package/core/cleaner.js +527 -0
- package/core/config.js +562 -0
- package/core/index.js +79 -0
- package/core/organizer.js +528 -0
- package/core/reporter.js +572 -0
- package/core/scanner.js +436 -0
- package/core/security.js +317 -0
- package/core/sop-parser.js +565 -0
- package/core/watcher.js +478 -0
- package/index.js +536 -0
- package/package.json +55 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ═══════════════════════════════════════════════════════════════════
|
|
5
|
+
* FILEMAYOR CORE — CATEGORIES
|
|
6
|
+
* Extension → Category mapping with configurable overrides
|
|
7
|
+
* ═══════════════════════════════════════════════════════════════════
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
// ─── Default Category Definitions ─────────────────────────────────
|
|
13
|
+
const DEFAULT_CATEGORIES = {
|
|
14
|
+
documents: {
|
|
15
|
+
label: 'Documents',
|
|
16
|
+
extensions: [
|
|
17
|
+
'.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx',
|
|
18
|
+
'.odt', '.ods', '.odp', '.rtf', '.txt', '.csv', '.tsv',
|
|
19
|
+
'.md', '.tex', '.epub', '.mobi', '.pages', '.numbers', '.key'
|
|
20
|
+
],
|
|
21
|
+
color: '#d4af37',
|
|
22
|
+
icon: 'FileText'
|
|
23
|
+
},
|
|
24
|
+
images: {
|
|
25
|
+
label: 'Images',
|
|
26
|
+
extensions: [
|
|
27
|
+
'.jpg', '.jpeg', '.png', '.gif', '.svg', '.webp', '.bmp',
|
|
28
|
+
'.tiff', '.tif', '.ico', '.heic', '.heif', '.raw', '.cr2',
|
|
29
|
+
'.nef', '.arw', '.dng', '.psd', '.ai', '.eps', '.xcf'
|
|
30
|
+
],
|
|
31
|
+
color: '#f472b6',
|
|
32
|
+
icon: 'Image'
|
|
33
|
+
},
|
|
34
|
+
audio: {
|
|
35
|
+
label: 'Audio',
|
|
36
|
+
extensions: [
|
|
37
|
+
'.mp3', '.wav', '.flac', '.aac', '.ogg', '.m4a', '.wma',
|
|
38
|
+
'.aiff', '.alac', '.opus', '.mid', '.midi', '.pcm'
|
|
39
|
+
],
|
|
40
|
+
color: '#38bdf8',
|
|
41
|
+
icon: 'Music'
|
|
42
|
+
},
|
|
43
|
+
video: {
|
|
44
|
+
label: 'Video',
|
|
45
|
+
extensions: [
|
|
46
|
+
'.mp4', '.mkv', '.avi', '.mov', '.wmv', '.webm', '.flv',
|
|
47
|
+
'.m4v', '.mpg', '.mpeg', '.3gp', '.ts', '.vob', '.ogv'
|
|
48
|
+
],
|
|
49
|
+
color: '#a78bfa',
|
|
50
|
+
icon: 'Video'
|
|
51
|
+
},
|
|
52
|
+
archives: {
|
|
53
|
+
label: 'Archives',
|
|
54
|
+
extensions: [
|
|
55
|
+
'.zip', '.rar', '.7z', '.tar', '.gz', '.bz2', '.xz',
|
|
56
|
+
'.tgz', '.tbz2', '.lz', '.lzma', '.cab', '.iso', '.dmg',
|
|
57
|
+
'.img', '.zst', '.br'
|
|
58
|
+
],
|
|
59
|
+
color: '#34d399',
|
|
60
|
+
icon: 'Archive'
|
|
61
|
+
},
|
|
62
|
+
code: {
|
|
63
|
+
label: 'Code',
|
|
64
|
+
extensions: [
|
|
65
|
+
'.js', '.ts', '.jsx', '.tsx', '.py', '.java', '.cpp', '.c',
|
|
66
|
+
'.cs', '.go', '.rs', '.rb', '.php', '.swift', '.kt', '.scala',
|
|
67
|
+
'.lua', '.r', '.m', '.h', '.hpp', '.vue', '.svelte', '.astro',
|
|
68
|
+
'.sh', '.bash', '.zsh', '.fish', '.ps1', '.bat', '.cmd',
|
|
69
|
+
'.sql', '.graphql', '.proto', '.wasm'
|
|
70
|
+
],
|
|
71
|
+
color: '#fb923c',
|
|
72
|
+
icon: 'Code'
|
|
73
|
+
},
|
|
74
|
+
config: {
|
|
75
|
+
label: 'Config',
|
|
76
|
+
extensions: [
|
|
77
|
+
'.json', '.yaml', '.yml', '.toml', '.ini', '.cfg', '.conf',
|
|
78
|
+
'.env', '.properties', '.xml', '.plist', '.reg'
|
|
79
|
+
],
|
|
80
|
+
color: '#94a3b8',
|
|
81
|
+
icon: 'Settings'
|
|
82
|
+
},
|
|
83
|
+
fonts: {
|
|
84
|
+
label: 'Fonts',
|
|
85
|
+
extensions: [
|
|
86
|
+
'.ttf', '.otf', '.woff', '.woff2', '.eot', '.fon'
|
|
87
|
+
],
|
|
88
|
+
color: '#e879f9',
|
|
89
|
+
icon: 'Type'
|
|
90
|
+
},
|
|
91
|
+
data: {
|
|
92
|
+
label: 'Data',
|
|
93
|
+
extensions: [
|
|
94
|
+
'.db', '.sqlite', '.sqlite3', '.mdb', '.accdb', '.dbf',
|
|
95
|
+
'.parquet', '.avro', '.arrow', '.ndjson', '.jsonl',
|
|
96
|
+
'.hdf5', '.h5', '.nc', '.fits'
|
|
97
|
+
],
|
|
98
|
+
color: '#22d3ee',
|
|
99
|
+
icon: 'Database'
|
|
100
|
+
},
|
|
101
|
+
executables: {
|
|
102
|
+
label: 'Executables',
|
|
103
|
+
extensions: [
|
|
104
|
+
'.exe', '.msi', '.app', '.apk', '.deb', '.rpm', '.snap',
|
|
105
|
+
'.flatpak', '.appimage', '.pkg', '.bin', '.run',
|
|
106
|
+
'.dll', '.so', '.dylib'
|
|
107
|
+
],
|
|
108
|
+
color: '#ef4444',
|
|
109
|
+
icon: 'Cpu'
|
|
110
|
+
},
|
|
111
|
+
design: {
|
|
112
|
+
label: 'Design',
|
|
113
|
+
extensions: [
|
|
114
|
+
'.fig', '.sketch', '.xd', '.indd', '.blend', '.3ds',
|
|
115
|
+
'.obj', '.fbx', '.stl', '.gltf', '.glb', '.usdz',
|
|
116
|
+
'.dwg', '.dxf', '.step', '.stp'
|
|
117
|
+
],
|
|
118
|
+
color: '#c084fc',
|
|
119
|
+
icon: 'Palette'
|
|
120
|
+
},
|
|
121
|
+
books: {
|
|
122
|
+
label: 'Books',
|
|
123
|
+
extensions: [
|
|
124
|
+
'.epub', '.mobi', '.azw', '.azw3', '.djvu', '.cbz', '.cbr'
|
|
125
|
+
],
|
|
126
|
+
color: '#fbbf24',
|
|
127
|
+
icon: 'BookOpen'
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// ─── Extension Cache ──────────────────────────────────────────────
|
|
132
|
+
let _extensionMap = null;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Build a flat map of extension → category for O(1) lookups
|
|
136
|
+
* @param {Object} categories - Category definitions
|
|
137
|
+
* @returns {Map<string, string>} Extension to category name map
|
|
138
|
+
*/
|
|
139
|
+
function buildExtensionMap(categories = DEFAULT_CATEGORIES) {
|
|
140
|
+
const map = new Map();
|
|
141
|
+
for (const [categoryName, def] of Object.entries(categories)) {
|
|
142
|
+
for (const ext of def.extensions) {
|
|
143
|
+
map.set(ext.toLowerCase(), categoryName);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return map;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Get the category for a file extension
|
|
151
|
+
* @param {string} ext - File extension (with dot, e.g. '.pdf')
|
|
152
|
+
* @param {Object} customCategories - Optional custom categories
|
|
153
|
+
* @returns {string} Category name or 'other'
|
|
154
|
+
*/
|
|
155
|
+
function categorize(ext, customCategories = null) {
|
|
156
|
+
if (!ext) return 'other';
|
|
157
|
+
const normalized = ext.toLowerCase();
|
|
158
|
+
|
|
159
|
+
if (customCategories) {
|
|
160
|
+
const customMap = buildExtensionMap(customCategories);
|
|
161
|
+
return customMap.get(normalized) || 'other';
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Use cached map for default categories
|
|
165
|
+
if (!_extensionMap) {
|
|
166
|
+
_extensionMap = buildExtensionMap(DEFAULT_CATEGORIES);
|
|
167
|
+
}
|
|
168
|
+
return _extensionMap.get(normalized) || 'other';
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Get all registered categories with metadata
|
|
173
|
+
* @param {Object} customCategories - Optional overrides
|
|
174
|
+
* @returns {Object} Merged categories
|
|
175
|
+
*/
|
|
176
|
+
function getCategories(customCategories = null) {
|
|
177
|
+
if (!customCategories) return { ...DEFAULT_CATEGORIES };
|
|
178
|
+
return { ...DEFAULT_CATEGORIES, ...customCategories };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Get all extensions registered across all categories
|
|
183
|
+
* @returns {string[]} List of all known extensions
|
|
184
|
+
*/
|
|
185
|
+
function getAllExtensions() {
|
|
186
|
+
const all = [];
|
|
187
|
+
for (const def of Object.values(DEFAULT_CATEGORIES)) {
|
|
188
|
+
all.push(...def.extensions);
|
|
189
|
+
}
|
|
190
|
+
return all;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Merge user-defined categories with defaults
|
|
195
|
+
* @param {Object} userCategories - User category overrides
|
|
196
|
+
* @returns {Object} Merged category map
|
|
197
|
+
*/
|
|
198
|
+
function mergeCategories(userCategories) {
|
|
199
|
+
const merged = { ...DEFAULT_CATEGORIES };
|
|
200
|
+
for (const [name, def] of Object.entries(userCategories)) {
|
|
201
|
+
if (merged[name]) {
|
|
202
|
+
// Merge extensions (deduplicate)
|
|
203
|
+
const existingExts = new Set(merged[name].extensions);
|
|
204
|
+
for (const ext of (def.extensions || [])) {
|
|
205
|
+
existingExts.add(ext.toLowerCase());
|
|
206
|
+
}
|
|
207
|
+
merged[name] = {
|
|
208
|
+
...merged[name],
|
|
209
|
+
...def,
|
|
210
|
+
extensions: [...existingExts]
|
|
211
|
+
};
|
|
212
|
+
} else {
|
|
213
|
+
// New category
|
|
214
|
+
merged[name] = {
|
|
215
|
+
label: def.label || name,
|
|
216
|
+
extensions: (def.extensions || []).map(e => e.toLowerCase()),
|
|
217
|
+
color: def.color || '#6b7280',
|
|
218
|
+
icon: def.icon || 'File'
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Rebuild cache
|
|
224
|
+
_extensionMap = buildExtensionMap(merged);
|
|
225
|
+
return merged;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
module.exports = {
|
|
229
|
+
DEFAULT_CATEGORIES,
|
|
230
|
+
categorize,
|
|
231
|
+
getCategories,
|
|
232
|
+
getAllExtensions,
|
|
233
|
+
mergeCategories,
|
|
234
|
+
buildExtensionMap
|
|
235
|
+
};
|