thinkncollab-cli 0.0.21 → 0.0.22

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.
Files changed (2) hide show
  1. package/bin/index.js +38 -20
  2. package/package.json +1 -1
package/bin/index.js CHANGED
@@ -198,28 +198,45 @@ async function uploadFileSigned(filePath, folder, roomId, token, email) {
198
198
  return cloudRes.data.secure_url;
199
199
  }
200
200
 
201
- async function uploadTree(fileTree, folderHex, roomId, token, email, parentPath = "") {
201
+ async function uploadTree(fileTree, folderHex, roomId, token, email, previousVersions, parentPath = "") {
202
202
  const uploaded = [];
203
203
 
204
204
  for (const node of fileTree) {
205
205
  const relativePath = path.join(parentPath, node.name).replace(/\\/g, "/");
206
206
 
207
207
  if (node.type === "folder") {
208
- const children = await uploadTree(node.children, folderHex, roomId, token, email, relativePath);
208
+ const children = await uploadTree(node.children, folderHex, roomId, token, email, previousVersions, relativePath);
209
209
  const folderHash = crypto.createHash("sha256").update(relativePath + children.map(c => c.hash || "").join("")).digest("hex");
210
210
  uploaded.push({ ...node, children, hash: folderHash });
211
211
  } else if (node.changed && node.path) {
212
- const url = await uploadFileSigned(node.path, `tnc_uploads/${folderHex}`, roomId, token, email);
213
- console.log(`📦 Uploaded: ${relativePath} ${url}`);
214
- uploaded.push({ ...node, url });
212
+ try {
213
+ const url = await uploadFileSigned(node.path, `tnc_uploads/${folderHex}`, roomId, token, email);
214
+ console.log(`📦 Uploaded: ${relativePath} ${url}`);
215
+ uploaded.push({
216
+ ...node,
217
+ url,
218
+ hash: node.hash
219
+ });
220
+ } catch (err) {
221
+ console.error(`❌ Failed to upload ${relativePath}:`, err.message);
222
+ uploaded.push({ ...node, hash: node.hash });
223
+ }
215
224
  } else {
216
- uploaded.push(node); // unchanged, no upload
225
+ // Unchanged file - use previous URL
226
+ const prevFile = previousVersions[node.path];
227
+ uploaded.push({
228
+ ...node,
229
+ url: prevFile?.url, // ✅ Use stored URL
230
+ hash: node.hash,
231
+ version: prevFile?.version || 1
232
+ });
217
233
  }
218
234
  }
219
235
 
220
236
  return uploaded;
221
237
  }
222
238
 
239
+
223
240
  /** ------------------ PUSH FUNCTION ------------------ **/
224
241
  async function push(roomId, targetPath) {
225
242
  const { token, email } = readToken();
@@ -230,10 +247,6 @@ async function push(roomId, targetPath) {
230
247
  }
231
248
  const meta = JSON.parse(fs.readFileSync(tncMetaPath, "utf-8"));
232
249
  const projectId = meta.projectId;
233
- if (!projectId) {
234
- console.error("❌ Project ID missing in metadata. Run 'tnc init' again.");
235
- process.exit(1);
236
- }
237
250
 
238
251
  const stats = fs.statSync(targetPath);
239
252
  const rootFolder = stats.isDirectory() ? targetPath : path.dirname(targetPath);
@@ -267,10 +280,9 @@ async function push(roomId, targetPath) {
267
280
  const folderHex = crypto.createHash("md5").update(path.basename(targetPath) + Date.now()).digest("hex");
268
281
 
269
282
  console.log("🚀 Uploading to Cloudinary...");
270
- const uploadedTree = await uploadTree(contentWithChanges, folderHex, roomId, token, email);
271
-
272
- console.log("🗂️ Sending metadata:", { folderId: folderHex, content: uploadedTree, uploadedBy: email, projectId });
283
+ const uploadedTree = await uploadTree(contentWithChanges, folderHex, roomId, token, email, previousVersions);
273
284
 
285
+ console.log("🗂️ Sending metadata...");
274
286
  await axios.post(
275
287
  `${BASE_URL}/${roomId}/upload`,
276
288
  { folderId: folderHex, content: uploadedTree, uploadedBy: email, projectId },
@@ -279,16 +291,22 @@ async function push(roomId, targetPath) {
279
291
 
280
292
  console.log("✅ Upload complete! Metadata stored successfully.");
281
293
 
282
- // Save version hashes
283
- const flattenVersionMap = {};
284
- const flatten = items => {
294
+ // Save version hashes WITH URLs
295
+ const newVersionMap = {};
296
+ const flattenAndStore = (items) => {
285
297
  for (const item of items) {
286
- flattenVersionMap[item.path || item.name] = item.hash;
287
- if (item.children) flatten(item.children);
298
+ if (item.type === "file") {
299
+ newVersionMap[item.path] = {
300
+ hash: item.hash,
301
+ url: item.url, // ✅ Store URL locally
302
+ version: item.version || 1
303
+ };
304
+ }
305
+ if (item.children) flattenAndStore(item.children);
288
306
  }
289
307
  };
290
- flatten(contentWithChanges);
291
- saveVersions(flattenVersionMap);
308
+ flattenAndStore(uploadedTree);
309
+ saveVersions(newVersionMap);
292
310
 
293
311
  } catch (err) {
294
312
  console.error("❌ Upload failed:", err.response?.data || err.message);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "thinkncollab-cli",
3
3
  "author": "Raman Singh",
4
- "version": "0.0.21",
4
+ "version": "0.0.22",
5
5
  "description": "CLI tool for ThinkNCollab",
6
6
  "main": "index.js",
7
7
  "bin": {