@lowdep/dot-clean 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 +97 -0
- package/bin/dot-clean.js +287 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rushabh Shah
|
|
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,97 @@
|
|
|
1
|
+
# dot-clean
|
|
2
|
+
|
|
3
|
+
   
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
Remove `.DS_Store`, `Thumbs.db`, `desktop.ini`, and other OS-generated junk files recursively. Optionally update `.gitignore` to prevent them coming back. Zero dependencies.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install -g dot-clean
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Or without installing:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx dot-clean
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
dot-clean # Remove macOS/Windows/Linux junk in current dir
|
|
28
|
+
dot-clean ~/Documents # Clean a specific directory
|
|
29
|
+
dot-clean --dry-run # Preview without deleting
|
|
30
|
+
dot-clean --all # Remove all categories (incl. IDE/editor files)
|
|
31
|
+
dot-clean --type macos # Only macOS junk
|
|
32
|
+
dot-clean --gitignore # Also update .gitignore
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Example Output
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
dot-clean /my-project
|
|
41
|
+
Scanning for: macos, windows, linux...
|
|
42
|
+
|
|
43
|
+
✗ screenshots/.DS_Store 4.1 kB
|
|
44
|
+
✗ screenshots/.DS_Store 4.1 kB
|
|
45
|
+
✗ backup/Thumbs.db 8.0 kB
|
|
46
|
+
✗ old-files/desktop.ini 402 B
|
|
47
|
+
|
|
48
|
+
4 items removed (16.6 kB freed)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Categories
|
|
54
|
+
|
|
55
|
+
| Category | Files removed |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `macos` | `.DS_Store`, `__MACOSX/`, `.AppleDouble`, `.Spotlight-V100`, `.Trashes`, etc. |
|
|
58
|
+
| `windows` | `Thumbs.db`, `desktop.ini`, `ehthumbs.db`, `$RECYCLE.BIN`, etc. |
|
|
59
|
+
| `linux` | `.fuse_hidden*`, `.directory`, `.Trash-*`, `.nfs*` |
|
|
60
|
+
| `ide` | `.idea/`, `.vscode/`, `.classpath`, `.settings/`, etc. |
|
|
61
|
+
| `editor` | `*~`, `*.bak`, `*.orig`, `*.swp`, `*.tmp` |
|
|
62
|
+
|
|
63
|
+
Default: `macos`, `windows`, `linux`
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Options
|
|
68
|
+
|
|
69
|
+
| Flag | Description |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `--type <list>` | Comma-separated categories: `macos,windows,linux,ide,editor` |
|
|
72
|
+
| `--all` | Remove all categories |
|
|
73
|
+
| `--dry-run` | Show what would be removed, don't delete |
|
|
74
|
+
| `--gitignore` | Update `.gitignore` to prevent future junk |
|
|
75
|
+
| `--stats` | Show breakdown by category |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## License
|
|
80
|
+
|
|
81
|
+
MIT
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Keywords
|
|
86
|
+
|
|
87
|
+
`.DS_Store` · `Thumbs.db` · `desktop.ini` · `remove junk files` · `clean os files` · `delete ds_store` · `mac junk` · `cleanup` · `cross-platform` · `zero dependencies`
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
<div align="center">
|
|
92
|
+
|
|
93
|
+
**Built to solve, shared to help — Rushabh Shah 🛠️✨**
|
|
94
|
+
|
|
95
|
+
<sub>One of 40+ zero-dependency developer CLI tools — no <code>node_modules</code>, ever.</sub>
|
|
96
|
+
|
|
97
|
+
</div>
|
package/bin/dot-clean.js
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
const VERSION = '1.0.0';
|
|
8
|
+
|
|
9
|
+
// ─── ANSI ─────────────────────────────────────────────────────────────────────
|
|
10
|
+
const isTTY = process.stdout.isTTY;
|
|
11
|
+
const c = (code, t) => isTTY ? `\x1b[${code}m${t}\x1b[0m` : t;
|
|
12
|
+
const bold = t => c('1', t);
|
|
13
|
+
const dim = t => c('2', t);
|
|
14
|
+
const red = t => c('31', t);
|
|
15
|
+
const green = t => c('32', t);
|
|
16
|
+
const yellow = t => c('33', t);
|
|
17
|
+
const cyan = t => c('36', t);
|
|
18
|
+
|
|
19
|
+
// ─── Junk file definitions ────────────────────────────────────────────────────
|
|
20
|
+
const JUNK_FILES = {
|
|
21
|
+
macos: [
|
|
22
|
+
'.DS_Store', '.DS_Store?', '._*', '.AppleDouble', '.AppleDB',
|
|
23
|
+
'.AppleDesktop', '.com.apple.timemachineexclude',
|
|
24
|
+
'.DocumentRevisions-V100', '.fseventsd', '.Spotlight-V100',
|
|
25
|
+
'.TemporaryItems', '.Trashes', '.VolumeIcon.icns', '.apdisk',
|
|
26
|
+
'__MACOSX',
|
|
27
|
+
],
|
|
28
|
+
windows: [
|
|
29
|
+
'Thumbs.db', 'thumbs.db', 'ehthumbs.db', 'ehthumbs_vista.db',
|
|
30
|
+
'desktop.ini', 'Desktop.ini',
|
|
31
|
+
'$RECYCLE.BIN', 'RECYCLER', 'RECYCLED',
|
|
32
|
+
'*.lnk',
|
|
33
|
+
],
|
|
34
|
+
linux: [
|
|
35
|
+
'.fuse_hidden*', '.directory', '.Trash-*', '.nfs*',
|
|
36
|
+
],
|
|
37
|
+
ide: [
|
|
38
|
+
'.idea', '.vscode', '*.suo', '*.ntvs*', '*.njsproj', '*.sln',
|
|
39
|
+
'.project', '.classpath', '.settings', '*.swp', '*~',
|
|
40
|
+
],
|
|
41
|
+
editor: [
|
|
42
|
+
'*~', '.#*', '.*.swp', '.*.swo', '*.bak', '*.tmp', '*.orig',
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const ALL_CATEGORIES = Object.keys(JUNK_FILES);
|
|
47
|
+
|
|
48
|
+
function matchesPattern(name, pattern) {
|
|
49
|
+
if (pattern.startsWith('*.')) {
|
|
50
|
+
return name.endsWith(pattern.slice(1));
|
|
51
|
+
}
|
|
52
|
+
if (pattern.endsWith('*')) {
|
|
53
|
+
return name.startsWith(pattern.slice(0, -1));
|
|
54
|
+
}
|
|
55
|
+
if (pattern.startsWith('.*')) {
|
|
56
|
+
// .something* style
|
|
57
|
+
const prefix = pattern.slice(0, -1);
|
|
58
|
+
return name.startsWith(prefix);
|
|
59
|
+
}
|
|
60
|
+
return name === pattern;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function shouldRemove(name, categories) {
|
|
64
|
+
for (const cat of categories) {
|
|
65
|
+
const patterns = JUNK_FILES[cat] || [];
|
|
66
|
+
for (const p of patterns) {
|
|
67
|
+
if (matchesPattern(name, p)) return { match: true, category: cat };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { match: false };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ─── Recursive scanner ────────────────────────────────────────────────────────
|
|
74
|
+
function scan(dir, categories, results = []) {
|
|
75
|
+
let entries;
|
|
76
|
+
try { entries = fs.readdirSync(dir, { withFileTypes: true }); }
|
|
77
|
+
catch { return results; }
|
|
78
|
+
|
|
79
|
+
for (const e of entries) {
|
|
80
|
+
const { match, category } = shouldRemove(e.name, categories);
|
|
81
|
+
const full = path.join(dir, e.name);
|
|
82
|
+
|
|
83
|
+
if (match) {
|
|
84
|
+
let size = 0;
|
|
85
|
+
try {
|
|
86
|
+
if (e.isDirectory()) {
|
|
87
|
+
size = getDirSize(full);
|
|
88
|
+
results.push({ path: full, name: e.name, category, isDir: true, size });
|
|
89
|
+
} else {
|
|
90
|
+
size = fs.statSync(full).size;
|
|
91
|
+
results.push({ path: full, name: e.name, category, isDir: false, size });
|
|
92
|
+
}
|
|
93
|
+
} catch { /* skip inaccessible */ }
|
|
94
|
+
} else if (e.isDirectory() && !e.name.startsWith('.')) {
|
|
95
|
+
scan(full, categories, results);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return results;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function getDirSize(dir) {
|
|
103
|
+
let total = 0;
|
|
104
|
+
try {
|
|
105
|
+
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
106
|
+
const full = path.join(dir, e.name);
|
|
107
|
+
if (e.isDirectory()) total += getDirSize(full);
|
|
108
|
+
else { try { total += fs.statSync(full).size; } catch { /* skip */ } }
|
|
109
|
+
}
|
|
110
|
+
} catch { /* skip */ }
|
|
111
|
+
return total;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function formatSize(b) {
|
|
115
|
+
if (b < 1024) return `${b} B`;
|
|
116
|
+
if (b < 1024 ** 2) return `${(b / 1024).toFixed(1)} kB`;
|
|
117
|
+
return `${(b / 1024 ** 2).toFixed(1)} MB`;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function removeRecursive(p) {
|
|
121
|
+
try {
|
|
122
|
+
if (fs.statSync(p).isDirectory()) {
|
|
123
|
+
for (const e of fs.readdirSync(p)) removeRecursive(path.join(p, e));
|
|
124
|
+
fs.rmdirSync(p);
|
|
125
|
+
} else {
|
|
126
|
+
fs.unlinkSync(p);
|
|
127
|
+
}
|
|
128
|
+
return true;
|
|
129
|
+
} catch { return false; }
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ─── .gitignore updater ───────────────────────────────────────────────────────
|
|
133
|
+
const GITIGNORE_ENTRIES = {
|
|
134
|
+
macos: ['# macOS', '.DS_Store', '.AppleDouble', '.AppleDB', '__MACOSX', '.Trashes', '.Spotlight-V100'],
|
|
135
|
+
windows: ['# Windows', 'Thumbs.db', 'ehthumbs.db', 'desktop.ini', '$RECYCLE.BIN'],
|
|
136
|
+
linux: ['# Linux', '.fuse_hidden*', '.directory', '.Trash-*'],
|
|
137
|
+
editor: ['# Editor backups', '*~', '*.bak', '*.orig', '*.swp'],
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
function updateGitignore(dir, categories) {
|
|
141
|
+
const giPath = path.join(dir, '.gitignore');
|
|
142
|
+
let existing = '';
|
|
143
|
+
try { existing = fs.readFileSync(giPath, 'utf8'); } catch { /* new file */ }
|
|
144
|
+
|
|
145
|
+
const toAdd = [];
|
|
146
|
+
for (const cat of categories) {
|
|
147
|
+
const entries = GITIGNORE_ENTRIES[cat] || [];
|
|
148
|
+
for (const entry of entries) {
|
|
149
|
+
if (!existing.includes(entry)) toAdd.push(entry);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (!toAdd.length) {
|
|
154
|
+
console.log(dim(' .gitignore already up to date'));
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const addition = '\n' + toAdd.join('\n') + '\n';
|
|
159
|
+
fs.appendFileSync(giPath, addition);
|
|
160
|
+
console.log(green(` Updated .gitignore with ${toAdd.filter(e => !e.startsWith('#')).length} entries`));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// ─── CLI ──────────────────────────────────────────────────────────────────────
|
|
164
|
+
const args = process.argv.slice(2);
|
|
165
|
+
const VALUE_FLAGS = new Set(['--type']);
|
|
166
|
+
const positional = [];
|
|
167
|
+
for (let i = 0; i < args.length; i++) {
|
|
168
|
+
if (args[i].startsWith('-')) { if (VALUE_FLAGS.has(args[i])) i++; }
|
|
169
|
+
else positional.push(args[i]);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function getFlag(f) {
|
|
173
|
+
const i = args.indexOf(f);
|
|
174
|
+
return i !== -1 ? args[i + 1] : null;
|
|
175
|
+
}
|
|
176
|
+
function hasFlag(f) { return args.includes(f); }
|
|
177
|
+
|
|
178
|
+
if (hasFlag('--version') || hasFlag('-v')) {
|
|
179
|
+
console.log(`dot-clean v${VERSION}`); process.exit(0);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (hasFlag('--help') || hasFlag('-h')) {
|
|
183
|
+
console.log(`
|
|
184
|
+
${bold('dot-clean')} — Remove OS-generated junk files (.DS_Store, Thumbs.db, etc.)
|
|
185
|
+
|
|
186
|
+
${bold('USAGE')}
|
|
187
|
+
dot-clean [dir] [options]
|
|
188
|
+
|
|
189
|
+
${bold('OPTIONS')}
|
|
190
|
+
--type <list> Categories: macos,windows,linux,ide,editor (default: macos,windows,linux)
|
|
191
|
+
--all Remove all categories (macos,windows,linux,ide,editor)
|
|
192
|
+
--dry-run Show what would be removed without removing
|
|
193
|
+
--gitignore Update .gitignore to prevent future junk
|
|
194
|
+
--stats Show category breakdown
|
|
195
|
+
--version Show version
|
|
196
|
+
|
|
197
|
+
${bold('EXAMPLES')}
|
|
198
|
+
dot-clean # Remove macOS/Windows/Linux junk in .
|
|
199
|
+
dot-clean ~/Desktop # Clean a specific directory
|
|
200
|
+
dot-clean --all # Remove all junk including IDE/editor files
|
|
201
|
+
dot-clean --dry-run # Preview without deleting
|
|
202
|
+
dot-clean --gitignore # Also update .gitignore
|
|
203
|
+
dot-clean --type macos # Only remove macOS junk
|
|
204
|
+
`);
|
|
205
|
+
process.exit(0);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const targetDir = path.resolve(positional[0] || '.');
|
|
209
|
+
const dryRun = hasFlag('--dry-run');
|
|
210
|
+
const doGitignore = hasFlag('--gitignore');
|
|
211
|
+
const showStats = hasFlag('--stats');
|
|
212
|
+
|
|
213
|
+
let categories;
|
|
214
|
+
if (hasFlag('--all')) {
|
|
215
|
+
categories = ALL_CATEGORIES;
|
|
216
|
+
} else if (getFlag('--type')) {
|
|
217
|
+
categories = getFlag('--type').split(',').map(s => s.trim());
|
|
218
|
+
for (const c of categories) {
|
|
219
|
+
if (!JUNK_FILES[c]) { console.error(red(`\nUnknown type: ${c}. Valid: ${ALL_CATEGORIES.join(', ')}\n`)); process.exit(1); }
|
|
220
|
+
}
|
|
221
|
+
} else {
|
|
222
|
+
categories = ['macos', 'windows', 'linux'];
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (!fs.existsSync(targetDir)) {
|
|
226
|
+
console.error(red(`\nDirectory not found: ${targetDir}\n`)); process.exit(1);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
console.log(`\n${bold('dot-clean')} ${cyan(targetDir)}`);
|
|
230
|
+
console.log(dim(` Scanning for: ${categories.join(', ')}...\n`));
|
|
231
|
+
|
|
232
|
+
const found = scan(targetDir, categories);
|
|
233
|
+
|
|
234
|
+
if (!found.length) {
|
|
235
|
+
console.log(green(' No junk files found.\n'));
|
|
236
|
+
if (doGitignore) updateGitignore(targetDir, categories);
|
|
237
|
+
process.exit(0);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Group by category for stats
|
|
241
|
+
const byCat = {};
|
|
242
|
+
let totalSize = 0;
|
|
243
|
+
for (const f of found) {
|
|
244
|
+
if (!byCat[f.category]) byCat[f.category] = 0;
|
|
245
|
+
byCat[f.category]++;
|
|
246
|
+
totalSize += f.size;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Display files
|
|
250
|
+
for (const f of found) {
|
|
251
|
+
const rel = path.relative(targetDir, f.path);
|
|
252
|
+
const sizeFmt = dim(formatSize(f.size));
|
|
253
|
+
const type = f.isDir ? dim('/') : '';
|
|
254
|
+
if (dryRun) {
|
|
255
|
+
console.log(` ${yellow('~')} ${rel}${type} ${sizeFmt}`);
|
|
256
|
+
} else {
|
|
257
|
+
const ok = removeRecursive(f.path);
|
|
258
|
+
if (ok) {
|
|
259
|
+
console.log(` ${red('✗')} ${rel}${type} ${sizeFmt}`);
|
|
260
|
+
} else {
|
|
261
|
+
console.log(` ${yellow('!')} ${rel}${type} ${dim('(failed to remove)')}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
console.log();
|
|
267
|
+
|
|
268
|
+
if (showStats) {
|
|
269
|
+
for (const [cat, count] of Object.entries(byCat)) {
|
|
270
|
+
console.log(` ${cat.padEnd(10)} ${count} file(s)`);
|
|
271
|
+
}
|
|
272
|
+
console.log();
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const action = dryRun ? 'would remove' : 'removed';
|
|
276
|
+
console.log(dryRun
|
|
277
|
+
? yellow(` Dry run: ${found.length} item(s) ${action} (${formatSize(totalSize)} total)`)
|
|
278
|
+
: red(` ${found.length} item(s) ${action} (${formatSize(totalSize)} freed)`)
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
if (doGitignore && !dryRun) {
|
|
282
|
+
console.log();
|
|
283
|
+
updateGitignore(targetDir, categories);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
console.log();
|
|
287
|
+
process.exit(0);
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lowdep/dot-clean",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Remove .DS_Store, Thumbs.db, desktop.ini, and other OS-generated junk files recursively — zero dependencies",
|
|
5
|
+
"bin": {
|
|
6
|
+
"dot-clean": "bin/dot-clean.js"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"ds-store",
|
|
10
|
+
"thumbs-db",
|
|
11
|
+
"junk-files",
|
|
12
|
+
"cleanup",
|
|
13
|
+
"cli",
|
|
14
|
+
"macos",
|
|
15
|
+
"windows",
|
|
16
|
+
"zero-dependencies",
|
|
17
|
+
".DS_Store",
|
|
18
|
+
"Thumbs.db",
|
|
19
|
+
"desktop.ini",
|
|
20
|
+
"remove junk files",
|
|
21
|
+
"clean os files",
|
|
22
|
+
"delete ds_store",
|
|
23
|
+
"mac junk",
|
|
24
|
+
"cross-platform",
|
|
25
|
+
"zero dependencies"
|
|
26
|
+
],
|
|
27
|
+
"author": "Rushabh Shah",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=14"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"bin/"
|
|
34
|
+
],
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/Rushabh5000/dot-clean.git"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/Rushabh5000/dot-clean/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/Rushabh5000/dot-clean#readme",
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
|
+
}
|
|
46
|
+
}
|