@tushar-br/editing-pack 1.0.109

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # @tusharbr
package/index.js ADDED
@@ -0,0 +1,13 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const storageDir = path.join(__dirname, 'storage');
5
+
6
+ // આ ફાઈલ તમારા સ્ટોરેજ ફોલ્ડરમાં કઈ ફાઈલો છે તેનું લિસ્ટ આપશે
7
+ module.exports = {
8
+ getFiles: () => {
9
+ if (!fs.existsSync(storageDir)) return [];
10
+ return fs.readdirSync(storageDir);
11
+ },
12
+ storagePath: storageDir
13
+ };
package/install.js ADDED
@@ -0,0 +1,218 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const { execSync } = require('child_process');
7
+
8
+ const stagingArea = path.join(__dirname, 'staging_area');
9
+ const targetBase = process.env.INIT_CWD || process.cwd();
10
+ const outputFolder = targetBase;
11
+ const syncStatePath = path.join(outputFolder, '.extraction_state.json');
12
+
13
+ process.stdout.write('\x1b[2J\x1b[0;0H');
14
+ console.log(`\x1b[36m\x1b[1m _______ _ _ _____ _ _ _____
15
+ |__ __| | | |/ ____| | | | /\\ | __ \\
16
+ | | | | | | (___ | |__| | / \\ | |__) |
17
+ | | | | | |\\___ \\| __ | / /\\ \\ | _ /
18
+ | | | |__| |____) | | | |/ ____ \\| | \\ \\
19
+ |_| \\____/|_____/|_| |_/_/ \\_\\_| \\_\\\x1b[0m\n`);
20
+ console.log("\x1b[36m\x1b[1m[ TUSHAR CLOUD - SECURE FILE EXTRACTION ]\x1b[0m\n");
21
+
22
+ // Process Deletions First
23
+ const ignorePath = path.join(stagingArea, '.cloud_ignore.json');
24
+ if (fs.existsSync(ignorePath)) {
25
+ try {
26
+ const ignoredFiles = JSON.parse(fs.readFileSync(ignorePath, 'utf8'));
27
+ let deletedCount = 0;
28
+ for (const rel of ignoredFiles) {
29
+ const targetDel = path.join(outputFolder, rel);
30
+ if (fs.existsSync(targetDel)) {
31
+ if (fs.statSync(targetDel).isDirectory()) fs.rmSync(targetDel, { recursive: true, force: true });
32
+ else fs.unlinkSync(targetDel);
33
+ deletedCount++;
34
+ }
35
+ }
36
+ if (deletedCount > 0) {
37
+ console.log(`\x1b[31m🗑️ Synced Deletions: Removed ${deletedCount} files from local storage.\x1b[0m`);
38
+ }
39
+ fs.unlinkSync(ignorePath); // Remove so it doesn't get extracted
40
+ } catch (e) { }
41
+ }
42
+
43
+ function getFolderFingerprint(dir) {
44
+ if (!fs.existsSync(dir)) return '';
45
+ let results = [];
46
+ const files = fs.readdirSync(dir);
47
+ files.forEach(file => {
48
+ const fullPath = path.join(dir, file);
49
+ const stat = fs.statSync(fullPath);
50
+ if (stat.isDirectory()) {
51
+ // Limited depth or skip for fingerprinting efficiency
52
+ } else {
53
+ results.push({ p: path.relative(dir, fullPath), s: stat.size });
54
+ }
55
+ });
56
+ results.sort((a, b) => a.p.localeCompare(b.p));
57
+ return JSON.stringify(results);
58
+ }
59
+
60
+ let totalSize = 0;
61
+ let transferredSize = 0;
62
+ const startTime = Date.now();
63
+
64
+ function getFolderSize(dir) {
65
+ let size = 0;
66
+ if (!fs.existsSync(dir)) return 0;
67
+ const files = fs.readdirSync(dir);
68
+ for (const file of files) {
69
+ const filePath = path.join(dir, file);
70
+ const stats = fs.statSync(filePath);
71
+ if (stats.isDirectory()) size += getFolderSize(filePath);
72
+ else size += stats.size;
73
+ }
74
+ return size;
75
+ }
76
+
77
+ function formatSize(bytes) {
78
+ if (bytes === 0) return '0 B';
79
+ const k = 1024;
80
+ const sizes = ['B', 'KB', 'MB', 'GB'];
81
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
82
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
83
+ }
84
+
85
+ function formatTime(ms) {
86
+ const totalSeconds = Math.floor(ms / 1000);
87
+ const minutes = Math.floor(totalSeconds / 60);
88
+ const seconds = totalSeconds % 60;
89
+ return `${minutes}m ${seconds}s`;
90
+ }
91
+
92
+ function drawUI(fileName) {
93
+ const elapsed = Date.now() - startTime;
94
+ const percent = totalSize > 0 ? (transferredSize / totalSize) * 100 : 0;
95
+ const speed = transferredSize / (elapsed / 1000); // bytes per second
96
+ const remainingSize = totalSize - transferredSize;
97
+ const remainingTime = speed > 0 ? (remainingSize / speed) * 1000 : 0;
98
+
99
+ const barWidth = 30;
100
+ const filled = Math.round((percent / 100) * barWidth);
101
+ const bar = "█".repeat(filled) + "░".repeat(barWidth - filled);
102
+
103
+ // Clear previous 6 lines
104
+ process.stdout.write('\x1b[6A\x1b[2K');
105
+
106
+ console.log(`\x1b[33mProgress: [${bar}] ${percent.toFixed(1)}%\x1b[0m`);
107
+ console.log(`\x1b[32mSpeed: ${(speed / (1024 * 1024)).toFixed(2)} MB/s\x1b[0m`);
108
+ console.log(`\x1b[90mName: ${fileName.substring(0, 40)}${fileName.length > 40 ? '...' : ''}\x1b[0m`);
109
+ console.log(`\x1b[96mTime elapsed: ${formatTime(elapsed)} | Remaining: ~${formatTime(remainingTime)}\x1b[0m`);
110
+ console.log(`\x1b[37mData: ${formatSize(transferredSize)} / ${formatSize(totalSize)}\x1b[0m`);
111
+ console.log("");
112
+ }
113
+
114
+ function copyRecursiveSync(src, dest) {
115
+ const stats = fs.statSync(src);
116
+ if (stats.isDirectory()) {
117
+ if (!fs.existsSync(dest)) fs.mkdirSync(dest);
118
+ fs.readdirSync(src).forEach(child => copyRecursiveSync(path.join(src, child), path.join(dest, child)));
119
+ } else {
120
+ // Check if this is a split part
121
+ const partMatch = src.match(/(.*)\.ts_part_\d+$/);
122
+ if (partMatch) {
123
+ const originalName = path.basename(partMatch[1]);
124
+ const targetPath = path.join(path.dirname(dest), originalName);
125
+
126
+ // We only handle the first part to initiate the join
127
+ if (src.endsWith('.ts_part_0')) {
128
+ const baseDir = path.dirname(src);
129
+ const baseName = path.basename(partMatch[1]);
130
+ const parts = fs.readdirSync(baseDir)
131
+ .filter(f => f.startsWith(baseName + '.ts_part_'))
132
+ .sort((a, b) => {
133
+ const na = parseInt(a.split('_').pop());
134
+ const nb = parseInt(b.split('_').pop());
135
+ return na - nb;
136
+ });
137
+
138
+ const writeStream = fs.createWriteStream(targetPath);
139
+ for (const part of parts) {
140
+ const partPath = path.join(baseDir, part);
141
+ const partBuffer = fs.readFileSync(partPath);
142
+ writeStream.write(partBuffer);
143
+ transferredSize += partBuffer.length;
144
+ drawUI(baseName + ` (Joining Part ${part.split('_').pop()}...)`);
145
+ }
146
+ writeStream.end();
147
+ }
148
+ } else {
149
+ fs.copyFileSync(src, dest);
150
+ transferredSize += stats.size;
151
+ drawUI(path.basename(src));
152
+ }
153
+ }
154
+ }
155
+
156
+ // Start Process
157
+ totalSize = getFolderSize(stagingArea);
158
+
159
+ if (totalSize > 0) {
160
+ // Smart Extraction Check
161
+ const currentFingerprint = getFolderFingerprint(stagingArea);
162
+ if (fs.existsSync(syncStatePath)) {
163
+ try {
164
+ const lastFingerprint = fs.readFileSync(syncStatePath, 'utf8');
165
+ if (currentFingerprint === lastFingerprint) {
166
+ console.log(`\x1b[32m\x1b[1m✨ DATA IS ALREADY UP TO DATE! Skipping extraction...\x1b[0m`);
167
+ console.log(`\x1b[36mLocation: ${outputFolder}\x1b[0m\n`);
168
+ process.exit(0);
169
+ }
170
+ } catch (e) { }
171
+ }
172
+
173
+ console.log("\n".repeat(6)); // Make space for UI updates
174
+ copyRecursiveSync(stagingArea, outputFolder);
175
+
176
+ // Final Touch: Icons
177
+ const iconFile = 'folder-icon.ico';
178
+ if (fs.existsSync(path.join(outputFolder, iconFile))) {
179
+ try {
180
+ const iniPath = path.join(outputFolder, 'desktop.ini');
181
+ fs.writeFileSync(iniPath, `[.ShellClassInfo]\r\nIconResource=${iconFile},0\r\n`, 'utf8');
182
+ execSync(`attrib +h +s "${iniPath}"`);
183
+ execSync(`attrib +r "${outputFolder}"`);
184
+ } catch (e) { }
185
+ }
186
+
187
+ console.log(`\x1b[32m\x1b[1m✅ SYNC COMPLETE: Data extracted successfully!\x1b[0m\n`);
188
+
189
+ // Save extraction state
190
+ try {
191
+ if (!fs.existsSync(outputFolder)) fs.mkdirSync(outputFolder, { recursive: true });
192
+ fs.writeFileSync(syncStatePath, getFolderFingerprint(stagingArea));
193
+ } catch (e) { }
194
+
195
+ // Self Cleanup: background detached to bypass Windows locks
196
+ const root = path.resolve(__dirname, '../../..');
197
+ const cleanupScript = `
198
+ Start-Sleep -s 1
199
+ Get-Process -Id ${process.pid} -ErrorAction SilentlyContinue | Wait-Process
200
+ Start-Sleep -s 1
201
+ $items = @('node_modules', 'package-lock.json', 'package.json', '.npmrc')
202
+ foreach ($item in $items) {
203
+ $p = Join-Path "${root.replace(/\\/g, '\\\\')}" $item
204
+ if (Test-Path $p) { Remove-Item -Path $p -Recurse -Force -ErrorAction SilentlyContinue }
205
+ }
206
+ Remove-Item -Path "${__dirname.replace(/\\/g, '\\\\')}" -Recurse -Force -ErrorAction SilentlyContinue
207
+ `;
208
+
209
+ const { spawn } = require('child_process');
210
+ spawn('powershell', ['-Command', cleanupScript], {
211
+ detached: true,
212
+ stdio: 'ignore'
213
+ }).unref();
214
+
215
+ console.log(`\x1b[90mCleanup started in background. System will be clean in 2s.\x1b[0m`);
216
+ } else {
217
+ console.log("\x1b[31mNo data found in sync area.\x1b[0m");
218
+ }
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@tushar-br/editing-pack",
3
+ "version": "1.0.109",
4
+ "description": "Private Image Cloud Storage & Backup System by Tushar",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "editing-pack": "install.js"
8
+ },
9
+ "scripts": {
10
+ "postinstall": "node install.js",
11
+ "test": "node -e \"console.log('@tushar-br/editing-pack system active');\""
12
+ },
13
+ "keywords": [
14
+ "cloud",
15
+ "storage",
16
+ "backup",
17
+ "tushar-br"
18
+ ],
19
+ "author": "Tushar Rathod",
20
+ "license": "MIT",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/tushar-br/editing-pack.git"
24
+ },
25
+ "bugs": {
26
+ "url": "https://github.com/tushar-br/editing-pack/issues"
27
+ },
28
+ "homepage": "https://github.com/tushar-br/editing-pack#readme",
29
+ "files": [
30
+ "staging_area/",
31
+ "index.js",
32
+ "install.js",
33
+ "README.md"
34
+ ]
35
+ }