stfca 1.0.4 → 1.0.6

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/CHANGELOG.md CHANGED
@@ -3,6 +3,39 @@
3
3
 
4
4
  All notable changes to ST-FCA will be documented in this file.
5
5
 
6
+ ## [1.0.5] - 2025-01-13
7
+
8
+ ### Added
9
+ - 🔄 Comprehensive update system that properly syncs all files
10
+ - 📂 Automatic file tree comparison between local and GitHub
11
+ - ➕ Smart file addition for new files in updates
12
+ - ♻️ Automatic modification detection and update
13
+ - 🗑️ Automatic deletion of removed files from old versions
14
+ - 🎯 No backup folder creation - cleaner updates
15
+
16
+ ### Changed
17
+ - Improved update mechanism to handle version jumps (e.g., 1.0.3 → 1.0.6)
18
+ - Enhanced file synchronization to ensure no missing files
19
+ - Better error handling during updates
20
+ - Auto-restart after successful update
21
+
22
+ ### Fixed
23
+ - Missing files when updating across multiple versions
24
+ - Outdated files not being properly replaced
25
+ - Orphaned files from old versions not being cleaned up
26
+
27
+ ## [1.0.4] - 2025-01-13
28
+
29
+ ### Added
30
+ - 🔄 Automatic update checking on package initialization
31
+ - ⚡ Non-blocking update process - doesn't interrupt user's bot startup
32
+ - 🎯 Update check runs once per session to avoid redundant checks
33
+ - 💡 Silent error handling for update checks
34
+
35
+ ### Changed
36
+ - Update checker now integrated directly into login flow
37
+ - Improved user experience with seamless auto-updates
38
+
6
39
  ## [1.0.3] - 2025-01-13
7
40
 
8
41
  ### Added
package/checkUpdate.js CHANGED
@@ -16,7 +16,7 @@ async function checkForFCAUpdate() {
16
16
  const latestVersion = packageData.version;
17
17
  const currentPackagePath = path.join(__dirname, 'package.json');
18
18
 
19
- // Check if package.json exists in fb-chat-api folder
19
+ // Check if package.json exists
20
20
  let currentVersion = '1.0.3';
21
21
  if (fs.existsSync(currentPackagePath)) {
22
22
  const currentPackage = JSON.parse(fs.readFileSync(currentPackagePath, 'utf-8'));
@@ -27,7 +27,7 @@ async function checkForFCAUpdate() {
27
27
  console.log('\x1b[32m%s\x1b[0m', `✨ New ST-FCA version available: ${latestVersion} (current: ${currentVersion})`);
28
28
  console.log('\x1b[33m%s\x1b[0m', '📦 Updating ST-FCA...');
29
29
 
30
- // Get changes info
30
+ // Show changelog
31
31
  try {
32
32
  const { data: changesData } = await axios.get(
33
33
  'https://raw.githubusercontent.com/sheikhtamimlover/ST-FCA/main/CHANGELOG.md'
@@ -41,10 +41,17 @@ async function checkForFCAUpdate() {
41
41
  // Silently ignore changelog fetch errors
42
42
  }
43
43
 
44
- // Update FCA files
45
- await updateFCAFiles();
44
+ // Perform comprehensive update
45
+ await performComprehensiveUpdate();
46
46
 
47
47
  console.log('\x1b[32m%s\x1b[0m', '✅ ST-FCA updated successfully!');
48
+ console.log('\x1b[33m%s\x1b[0m', '🔄 Restarting to apply changes...');
49
+
50
+ // Restart the process
51
+ setTimeout(() => {
52
+ process.exit(0);
53
+ }, 1000);
54
+
48
55
  return true;
49
56
  } else {
50
57
  console.log('\x1b[32m%s\x1b[0m', `✅ ST-FCA is up to date (v${currentVersion})`);
@@ -56,54 +63,146 @@ async function checkForFCAUpdate() {
56
63
  }
57
64
  }
58
65
 
59
- async function updateFCAFiles() {
60
- const filesToUpdate = [
61
- 'index.js',
62
- 'utils.js',
63
- 'src/listenMqtt.js',
64
- 'package.json',
65
- 'README.md'
66
- ];
67
-
68
- const backupDir = path.join(__dirname, 'backup_' + Date.now());
69
- if (!fs.existsSync(backupDir)) {
70
- fs.mkdirSync(backupDir, { recursive: true });
66
+ async function performComprehensiveUpdate() {
67
+ try {
68
+ // Step 1: Get the complete file tree from GitHub
69
+ console.log('\x1b[36m%s\x1b[0m', '📂 Fetching complete file structure...');
70
+ const fileTree = await getGitHubFileTree();
71
+
72
+ // Step 2: Get local files
73
+ const localFiles = getLocalFiles();
74
+
75
+ // Step 3: Download/Update all files from GitHub
76
+ console.log('\x1b[36m%s\x1b[0m', '⬇️ Downloading files...');
77
+ for (const file of fileTree) {
78
+ await downloadFile(file);
79
+ }
80
+
81
+ // Step 4: Delete files that don't exist in the latest version
82
+ console.log('\x1b[36m%s\x1b[0m', '🗑️ Cleaning up old files...');
83
+ const githubFilePaths = fileTree.map(f => f.path);
84
+ for (const localFile of localFiles) {
85
+ if (!githubFilePaths.includes(localFile) && !shouldKeepFile(localFile)) {
86
+ deleteLocalFile(localFile);
87
+ }
88
+ }
89
+
90
+ console.log('\x1b[32m%s\x1b[0m', '✅ All files synchronized!');
91
+ } catch (error) {
92
+ console.log('\x1b[31m%s\x1b[0m', '❌ Update failed:', error.message);
93
+ throw error;
71
94
  }
95
+ }
96
+
97
+ async function getGitHubFileTree() {
98
+ try {
99
+ const { data } = await axios.get(
100
+ 'https://api.github.com/repos/sheikhtamimlover/ST-FCA/git/trees/main?recursive=1'
101
+ );
102
+
103
+ // Filter only files (not directories)
104
+ return data.tree
105
+ .filter(item => item.type === 'blob')
106
+ .filter(item => !item.path.startsWith('.git'))
107
+ .filter(item => !shouldIgnoreFile(item.path));
108
+ } catch (error) {
109
+ console.log('\x1b[31m%s\x1b[0m', '❌ Failed to fetch file tree:', error.message);
110
+ throw error;
111
+ }
112
+ }
113
+
114
+ function getLocalFiles() {
115
+ const files = [];
72
116
 
73
- for (const file of filesToUpdate) {
74
- try {
75
- const targetPath = path.join(__dirname, file);
117
+ function walkDir(dir, baseDir = '') {
118
+ const items = fs.readdirSync(dir);
119
+
120
+ for (const item of items) {
121
+ const fullPath = path.join(dir, item);
122
+ const relativePath = baseDir ? path.join(baseDir, item) : item;
76
123
 
77
- // Backup existing file
78
- if (fs.existsSync(targetPath)) {
79
- const backupPath = path.join(backupDir, file);
80
- const backupFileDir = path.dirname(backupPath);
81
- if (!fs.existsSync(backupFileDir)) {
82
- fs.mkdirSync(backupFileDir, { recursive: true });
83
- }
84
- fs.copyFileSync(targetPath, backupPath);
85
- }
124
+ if (shouldIgnoreFile(relativePath)) continue;
86
125
 
87
- // Download new file
88
- const { data } = await axios.get(
89
- `https://raw.githubusercontent.com/sheikhtamimlover/ST-FCA/main/${file}`,
90
- { responseType: 'arraybuffer' }
91
- );
126
+ const stat = fs.statSync(fullPath);
92
127
 
93
- // Ensure directory exists
94
- const fileDir = path.dirname(targetPath);
95
- if (!fs.existsSync(fileDir)) {
96
- fs.mkdirSync(fileDir, { recursive: true });
128
+ if (stat.isDirectory()) {
129
+ walkDir(fullPath, relativePath);
130
+ } else {
131
+ files.push(relativePath.replace(/\\/g, '/'));
97
132
  }
98
-
99
- fs.writeFileSync(targetPath, Buffer.from(data));
100
- console.log('\x1b[32m%s\x1b[0m', ` ✓ Updated: ${file}`);
101
- } catch (error) {
102
- console.log('\x1b[31m%s\x1b[0m', ` ✗ Failed to update: ${file}`, error.message);
103
133
  }
104
134
  }
105
135
 
106
- console.log('\x1b[33m%s\x1b[0m', `💾 Backup saved to: ${backupDir}`);
136
+ walkDir(__dirname);
137
+ return files;
138
+ }
139
+
140
+ function shouldIgnoreFile(filePath) {
141
+ const ignorePatterns = [
142
+ 'node_modules',
143
+ '.git',
144
+ '.env',
145
+ 'appstate.json',
146
+ 'fbstate.json',
147
+ 'package-lock.json',
148
+ '.replit',
149
+ 'replit.nix',
150
+ '.config',
151
+ 'generated-icon.png'
152
+ ];
153
+
154
+ return ignorePatterns.some(pattern => filePath.includes(pattern));
155
+ }
156
+
157
+ function shouldKeepFile(filePath) {
158
+ const keepPatterns = [
159
+ 'node_modules',
160
+ '.env',
161
+ 'appstate.json',
162
+ 'fbstate.json',
163
+ 'package-lock.json',
164
+ '.replit',
165
+ 'replit.nix',
166
+ '.config'
167
+ ];
168
+
169
+ return keepPatterns.some(pattern => filePath.includes(pattern));
170
+ }
171
+
172
+ async function downloadFile(fileInfo) {
173
+ try {
174
+ const targetPath = path.join(__dirname, fileInfo.path);
175
+
176
+ // Download file content
177
+ const { data } = await axios.get(
178
+ `https://raw.githubusercontent.com/sheikhtamimlover/ST-FCA/main/${fileInfo.path}`,
179
+ { responseType: 'arraybuffer' }
180
+ );
181
+
182
+ // Ensure directory exists
183
+ const fileDir = path.dirname(targetPath);
184
+ if (!fs.existsSync(fileDir)) {
185
+ fs.mkdirSync(fileDir, { recursive: true });
186
+ }
187
+
188
+ // Write file
189
+ fs.writeFileSync(targetPath, Buffer.from(data));
190
+ console.log('\x1b[32m%s\x1b[0m', ` ✓ ${fileInfo.path}`);
191
+ } catch (error) {
192
+ console.log('\x1b[31m%s\x1b[0m', ` ✗ Failed: ${fileInfo.path}`, error.message);
193
+ }
194
+ }
195
+
196
+ function deleteLocalFile(filePath) {
197
+ try {
198
+ const fullPath = path.join(__dirname, filePath);
199
+ if (fs.existsSync(fullPath)) {
200
+ fs.unlinkSync(fullPath);
201
+ console.log('\x1b[33m%s\x1b[0m', ` 🗑️ Deleted: ${filePath}`);
202
+ }
203
+ } catch (error) {
204
+ console.log('\x1b[31m%s\x1b[0m', ` ✗ Failed to delete: ${filePath}`, error.message);
205
+ }
107
206
  }
108
207
 
109
- module.exports = { checkForFCAUpdate, updateFCAFiles };
208
+ module.exports = { checkForFCAUpdate, performComprehensiveUpdate };
package/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
  var utils = require("./utils");
4
4
  var cheerio = require("cheerio");
5
5
  var log = require("npmlog");
6
+ var { checkForFCAUpdate } = require("./checkUpdate");
6
7
  /*var { getThemeColors } = require("../../func/utils/log.js");
7
8
  var logger = require("../../func/utils/log.js");
8
9
  var { cra, cv, cb, co } = getThemeColors();*/
@@ -10,6 +11,7 @@ log.maxRecordSize = 100;
10
11
  var checkVerified = null;
11
12
  const Boolean_Option = ['online', 'selfListen', 'listenEvents', 'updatePresence', 'forceLogin', 'autoMarkDelivery', 'autoMarkRead', 'listenTyping', 'autoReconnect', 'emitReady'];
12
13
  global.ditconmemay = false;
14
+ global.stfcaUpdateChecked = false;
13
15
 
14
16
  function setOptions(globalOptions, options) {
15
17
  Object.keys(options).map(function (key) {
@@ -407,6 +409,14 @@ function loginHelper(appState, email, password, globalOptions, callback, prCallb
407
409
 
408
410
 
409
411
  function login(loginData, options, callback) {
412
+ // Check for updates (non-blocking, only once per session)
413
+ if (!global.stfcaUpdateChecked) {
414
+ global.stfcaUpdateChecked = true;
415
+ checkForFCAUpdate().catch(err => {
416
+ // Silently ignore update check errors to not block login
417
+ });
418
+ }
419
+
410
420
  if (utils.getType(options) === 'Function' || utils.getType(options) === 'AsyncFunction') {
411
421
  callback = options;
412
422
  options = {};
package/package.json CHANGED
@@ -1,9 +1,16 @@
1
-
2
1
  {
3
2
  "name": "stfca",
4
- "version": "1.0.4",
3
+ "version": "1.0.6",
5
4
  "description": "Unofficial Facebook Chat API for Node.js - Enhanced by ST | Sheikh Tamim",
6
5
  "main": "index.js",
6
+ "files": [
7
+ "src/",
8
+ "index.js",
9
+ "utils.js",
10
+ "checkUpdate.js",
11
+ "README.md",
12
+ "CHANGELOG.md"
13
+ ],
7
14
  "scripts": {
8
15
  "test": "echo \"Error: no test specified\" && exit 1",
9
16
  "start": "node index.js"
@@ -33,11 +40,13 @@
33
40
  "axios": "^1.4.0",
34
41
  "bluebird": "^3.7.2",
35
42
  "cheerio": "^1.0.0-rc.12",
43
+ "duplexify": "^4.1.3",
36
44
  "https-proxy-agent": "^5.0.1",
37
45
  "mqtt": "^4.3.7",
38
46
  "npmlog": "^7.0.1",
39
47
  "request": "^2.88.2",
40
- "websocket-stream": "^5.5.2"
48
+ "websocket-stream": "^5.5.2",
49
+ "ws": "^8.18.3"
41
50
  },
42
51
  "engines": {
43
52
  "node": ">=14.0.0"