ihub-cli 1.1.4 → 1.1.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.
Files changed (2) hide show
  1. package/index.js +287 -93
  2. package/package.json +3 -1
package/index.js CHANGED
@@ -10,86 +10,14 @@ import dirtoFileArray from "./recursive_file_extractor.js"
10
10
  import { PinataSDK } from "pinata";
11
11
  import { provideClient } from "./dbconnection.js"
12
12
 
13
+ import pLimit from "p-limit";
14
+
13
15
 
14
16
  const IHUB_DIR = path.join(os.homedir(), ".ihub");
15
17
  const FILE_TO_STORE_LOGIN = path.join(IHUB_DIR, "login.txt");
16
18
 
17
19
 
18
20
 
19
- async function UpdateRepo(folder,cid,pinata) {
20
-
21
-
22
- const result = await pinata.gateways.public.get(cid)
23
- const Data = result.data;
24
- console.log(Data)
25
- const arrayBuffer = await Data.arrayBuffer()
26
- const buffer = Buffer.from(arrayBuffer);
27
- console.log(buffer)
28
- deleteFilesWithExtension(".history.bundle",".")
29
- let dynamicstring=crypto.randomUUID()
30
- let shortID = dynamicstring.substring(0, 5)
31
- let bpath=`${shortID}.history.bundle`
32
-
33
- fs.writeFileSync(`${bpath}`,buffer);
34
-
35
- const absolutePath = path.resolve(folder);
36
-
37
- execSync(`git pull ${bpath} ${absolutePath} main`, {
38
- cwd: ".",
39
- stdio: 'inherit'
40
- });
41
- console.log("pulled successfully")
42
-
43
- }
44
-
45
-
46
-
47
- async function Pull(folder,pinata,client){
48
-
49
-
50
- const db = client.db("ihub_db");
51
- const coll = db.collection("ihub_col");
52
- const targetManifestId= fs.readFileSync(FILE_TO_STORE_LOGIN,'utf8');
53
- const doc = await coll.findOne({
54
- "owner": "system",
55
- "manifests.id": targetManifestId
56
- });
57
- if(doc) {
58
-
59
- let uploads=null
60
- let bundle=null
61
- let manifests=doc.manifests
62
-
63
-
64
- for(let obj of manifests){
65
-
66
- let dbfolder=String(obj.folder)
67
-
68
- if(obj.id==targetManifestId && dbfolder==folder){
69
- console.log(obj.folder)
70
- uploads=obj.uploads
71
- }
72
-
73
-
74
-
75
- }
76
- console.log(uploads)
77
-
78
- for(let obj of uploads){
79
-
80
- let name=obj.name
81
- const isIncluded = name.includes(".history.bundle");
82
- if(isIncluded) {
83
-
84
- bundle=obj.cid
85
-
86
- }}
87
-
88
- await UpdateRepo(folder,bundle,pinata)
89
-
90
- }}
91
-
92
-
93
21
 
94
22
  async function getcreds() {
95
23
 
@@ -106,10 +34,14 @@ async function getcreds() {
106
34
  }
107
35
 
108
36
  async function getRuntime() {
37
+
109
38
  const { jwt, gateway } = await getcreds();
110
39
  const pinata = new PinataSDK({ pinataJwt: jwt, pinataGateway: gateway });
40
+
41
+
111
42
  const client = provideClient();
112
43
  return { pinata, client };
44
+
113
45
  }
114
46
 
115
47
 
@@ -159,11 +91,28 @@ function fileWithExtensionExists(extension,folder) {
159
91
 
160
92
 
161
93
 
162
- async function deleteManifest(targetManifestId, foldername,client) {
163
94
 
164
95
 
165
- const db = client.db("ihub_db");
166
- const coll = db.collection("ihub_col");
96
+ async function deleteManifest(targetManifestId, foldername,client,mpc,prompt) {
97
+
98
+
99
+
100
+
101
+ let db = client.db("ihub_db");
102
+ let coll = db.collection("ihub_col");
103
+
104
+ if (mcp ==true){
105
+
106
+ db = client.db("ihub_db");
107
+ coll = db.collection("mcp_registry");
108
+
109
+ }else if(prompt ==true){
110
+
111
+ db = client.db("ihub_db");
112
+ coll = db.collection("prompt_comp");
113
+ }
114
+
115
+
167
116
  await coll.updateOne(
168
117
  { owner: "system" },
169
118
  {
@@ -180,6 +129,60 @@ function fileWithExtensionExists(extension,folder) {
180
129
 
181
130
 
182
131
 
132
+
133
+ //--------------------------------------------------------------------
134
+
135
+ async function deactivateOlderVersions(targetId, targetFolder,mcp,prompt) {
136
+
137
+ let db = client.db("ihub_db");
138
+ let coll = db.collection("ihub_col");
139
+
140
+ if (mcp ==true){
141
+
142
+ db = client.db("ihub_db");
143
+ coll = db.collection("mcp_registry");
144
+
145
+ }else if(prompt ==true){
146
+ db = client.db("ihub_db");
147
+ coll = db.collection("prompt_comp");
148
+ }
149
+
150
+
151
+ try {
152
+ const filter = {
153
+ "manifests": {
154
+ $elemMatch: { id: targetId, folder: targetFolder }
155
+ }
156
+ };
157
+
158
+ const update = {
159
+ $set: { "manifests.$[elem].is_latest": false }
160
+ };
161
+ const options = {
162
+ arrayFilters: [
163
+ {
164
+ "elem.id": targetId,
165
+ "elem.folder": targetFolder
166
+ }
167
+ ]
168
+ };
169
+
170
+ const result = await coll.updateMany(filter, update, options);
171
+
172
+ console.log(`Matched ${result.matchedCount} docs and updated ${result.modifiedCount} manifests.`);
173
+ return result;
174
+ } catch (error) {
175
+ console.error("Global update failed:", error);
176
+ }
177
+ }
178
+
179
+
180
+
181
+
182
+ //-------------------------------------------------------------------------
183
+
184
+
185
+
183
186
  async function manifestExists(targetManifestId, foldername,client) {
184
187
 
185
188
  const db = client.db("ihub_db");
@@ -246,6 +249,7 @@ async function getFileNew(folder,obj,pinata) {
246
249
  const result = await pinata.gateways.public.get(obj.cid)
247
250
  const Data = result.data;
248
251
 
252
+ //fs.mkdirSync(folder, { recursive: true });
249
253
  const filePath = path.join(folder, obj.name);
250
254
  fs.writeFileSync(`${filePath}`,Data,"utf-8");
251
255
  console.log("successfully")
@@ -298,15 +302,29 @@ function gitBundler(FOLDER_TO_UPLOAD){
298
302
  }
299
303
 
300
304
 
301
- async function Clone(folder,pinata,client){
305
+ async function Clone(folder,pinata,client,mcp,prompt){
302
306
 
303
307
 
304
- const db = client.db("ihub_db");
305
- const coll = db.collection("ihub_col");
308
+
309
+ let db = client.db("ihub_db");
310
+ let coll = db.collection("ihub_col");
311
+
312
+ if (mcp ==true){
313
+
314
+ db = client.db("ihub_db");
315
+ coll = db.collection("mcp_registry");
316
+
317
+ }
318
+ else if(prompt ==true){
319
+ db = client.db("ihub_db");
320
+ coll = db.collection("prompt_comp");
321
+ }
322
+
323
+
324
+
306
325
  const targetManifestId= fs.readFileSync(FILE_TO_STORE_LOGIN,'utf8');
307
326
  const doc = await coll.findOne({
308
327
  "owner": "system",
309
- "manifests.id": targetManifestId
310
328
  });
311
329
  if(doc) {
312
330
 
@@ -389,37 +407,57 @@ async function CloneNew(folder,pinata,client){
389
407
 
390
408
 
391
409
 
410
+ async function Push(FOLDER_TO_UPLOAD,pinata,client,mcp,prompt) {
411
+
412
+ try {
392
413
 
414
+ let db = client.db("ihub_db");
415
+ let coll = db.collection("ihub_col");
393
416
 
394
- async function Push(FOLDER_TO_UPLOAD,pinata,client) {
417
+ if (mcp ==true){
395
418
 
396
- try {
419
+ db = client.db("ihub_db");
420
+ coll = db.collection("mcp_registry");
397
421
 
422
+ }
423
+ else if(prompt ==true){
424
+ db = client.db("ihub_db");
425
+ coll = db.collection("prompt_comp");
426
+ }
398
427
 
399
- const db = client.db("ihub_db");
400
- const coll = db.collection("ihub_col");
428
+
401
429
 
402
- let uploads=[]
430
+ //let uploads=[]
403
431
  const absolutePath = path.resolve(FOLDER_TO_UPLOAD);
404
432
  let files=dirtoFileArray(absolutePath)
405
433
 
434
+ /*
406
435
  for (let file of files) {
407
436
 
408
437
  const upload=await pinata.upload.public.file(file)
409
438
  uploads.push(upload)
410
439
  }
440
+ */
441
+
442
+
411
443
 
444
+ const limit = pLimit(5); // 5 concurrent uploads
445
+ const uploadPromises = files.map(file =>
446
+ limit(() => pinata.upload.public.file(file))
447
+ );
412
448
 
449
+ const uploads = await Promise.all(uploadPromises);
413
450
  console.log(uploads)
414
451
  const data = fs.readFileSync(FILE_TO_STORE_LOGIN, 'utf8');
415
452
  const lastpath = path.basename(absolutePath);
416
-
453
+
417
454
  let meta={"id":data,"folder":lastpath,"uploads":uploads,"is_latest":true}
418
455
 
419
456
 
420
457
  let docalreadyexists=await manifestExists(data,lastpath,client)
421
458
  if (docalreadyexists){
422
- await deleteManifest(data,lastpath,client)
459
+ //await deleteManifest(data,lastpath,client,mcp,prompt)
460
+ await deactivateOlderVersions(data,lastpath,mcp,prompt)
423
461
  }
424
462
 
425
463
  await coll.findOneAndUpdate(
@@ -441,6 +479,116 @@ async function Push(FOLDER_TO_UPLOAD,pinata,client) {
441
479
 
442
480
 
443
481
 
482
+ async function UpdateRepo(cid,pinata) {
483
+
484
+
485
+ const result = await pinata.gateways.public.get(cid)
486
+ const Data = result.data;
487
+ console.log(Data)
488
+ const arrayBuffer = await Data.arrayBuffer()
489
+ const buffer = Buffer.from(arrayBuffer);
490
+ console.log(buffer)
491
+ deleteFilesWithExtension(".history.bundle",".")
492
+ let dynamicstring=crypto.randomUUID()
493
+ let shortID = dynamicstring.substring(0, 5)
494
+ let bpath=`${shortID}.history.bundle`
495
+
496
+ fs.writeFileSync(`${bpath}`,buffer);
497
+
498
+ //const absolutePath = path.resolve(folder);
499
+ const absoluteBundlePath = path.resolve(bpath);
500
+
501
+ execSync(`git fetch ${absoluteBundlePath} refs/heads/*:refs/remotes/bundle/*`, {
502
+ cwd: `.`,
503
+ stdio: 'inherit'
504
+ });
505
+
506
+ const currentBranch = execSync(
507
+ `git branch --show-current`,
508
+ {
509
+ cwd: '.',
510
+ encoding: 'utf8',
511
+ shell: true
512
+ }
513
+ ).trim();
514
+
515
+ const bundleBranch = `bundle/${currentBranch}`;
516
+
517
+ console.log(`🔀 Merging ${bundleBranch} → ${currentBranch}`);
518
+ execSync(
519
+ `git merge ${bundleBranch} --allow-unrelated-histories --no-edit`,
520
+ {
521
+ cwd: '.',
522
+ stdio: 'inherit',
523
+ shell: true
524
+ }
525
+ );
526
+
527
+ console.log("pulled successfully")
528
+
529
+ }
530
+
531
+
532
+
533
+ async function Pull(folder,pinata,client,mcp,prompt){
534
+
535
+
536
+ let db = client.db("ihub_db");
537
+ let coll = db.collection("ihub_col");
538
+
539
+ if (mcp == true){
540
+
541
+ db = client.db("ihub_db");
542
+ coll = db.collection("mcp_registry");
543
+
544
+ }
545
+ else if(prompt == true){
546
+ db = client.db("ihub_db");
547
+ coll = db.collection("prompt_comp");
548
+ }
549
+
550
+
551
+ const targetManifestId= fs.readFileSync(FILE_TO_STORE_LOGIN,'utf8');
552
+ const doc = await coll.findOne({
553
+ "owner": "system",
554
+ });
555
+ if(doc) {
556
+
557
+ let uploads=null
558
+ let bundle=null
559
+ let manifests=doc.manifests
560
+
561
+
562
+ for(let obj of manifests){
563
+
564
+ let dbfolder=String(obj.folder)
565
+
566
+ if(obj.id==targetManifestId && dbfolder==folder){
567
+ console.log(obj.folder)
568
+ uploads=obj.uploads
569
+ }
570
+
571
+
572
+
573
+ }
574
+ console.log(uploads)
575
+
576
+ for(let obj of uploads){
577
+
578
+ let name=obj.name
579
+ const isIncluded = name.includes(".history.bundle");
580
+ if(isIncluded) {
581
+
582
+ bundle=obj.cid
583
+
584
+ }}
585
+
586
+ await UpdateRepo(bundle,pinata)
587
+
588
+ }}
589
+
590
+
591
+
444
592
 
445
593
  yargs(hideBin(process.argv))
446
594
  .command(
@@ -469,7 +617,23 @@ yargs(hideBin(process.argv))
469
617
  return yargs.positional('folderpath', {
470
618
  describe: 'The local folder to push',
471
619
  type: 'string'
620
+ })
621
+ .option('mcp', {
622
+
623
+ alias: 'm',
624
+ type: 'boolean',
625
+ description: 'mcp server repo or not',
626
+ default: false
627
+ })
628
+ .option('prompt', {
629
+
630
+ alias: 'p',
631
+ type: 'boolean',
632
+ description: 'mcp server repo or not',
633
+ default: false
472
634
  });
635
+
636
+
473
637
  },
474
638
  async (argv) => {
475
639
 
@@ -478,11 +642,11 @@ yargs(hideBin(process.argv))
478
642
 
479
643
  console.log(`\n⬆️ Starting PUSH operation on folder: ${argv.folderpath}`);
480
644
  gitBundler(argv.folderpath);
481
- await Push(argv.folderpath,pinata,client);
645
+ await Push(argv.folderpath,pinata,client,argv.mcp,argv.prompt);
482
646
  console.log('Push operation finished.');
483
647
 
484
648
  }catch(e){
485
- console.log(str(e))
649
+ console.log(String(e))
486
650
  }finally{
487
651
  await client.close()
488
652
  }
@@ -497,6 +661,20 @@ yargs(hideBin(process.argv))
497
661
  return yargs.positional('foldername', {
498
662
  describe: 'the repo/folder to pull',
499
663
  type: 'string'
664
+ })
665
+ .option('mcp', {
666
+
667
+ alias: 'm',
668
+ type: 'boolean',
669
+ description: 'mcp server repo or not',
670
+ default: false
671
+ })
672
+ .option('prompt', {
673
+
674
+ alias: 'p',
675
+ type: 'boolean',
676
+ description: 'mcp server repo or not',
677
+ default: false
500
678
  });
501
679
  },
502
680
  async (argv) => {
@@ -509,7 +687,7 @@ yargs(hideBin(process.argv))
509
687
 
510
688
 
511
689
  }catch(e){
512
- console.log(str(e))
690
+ console.log(String(e))
513
691
  }finally{
514
692
  await client.close()
515
693
  }
@@ -526,7 +704,22 @@ yargs(hideBin(process.argv))
526
704
  describe: 'The folder to clone',
527
705
  type: 'string'
528
706
  })
707
+ .option('mcp', {
708
+
709
+ alias: 'm',
710
+ type: 'boolean',
711
+ description: 'mcp server repo or not',
712
+ default: false
713
+ })
714
+ .option('prompt', {
715
+
716
+ alias: 'p',
717
+ type: 'boolean',
718
+ description: 'mcp server repo or not',
719
+ default: false
720
+ })
529
721
  .option('new', {
722
+
530
723
  alias: 'n',
531
724
  type: 'boolean',
532
725
  description: 'new repo or existing repo',
@@ -543,7 +736,8 @@ yargs(hideBin(process.argv))
543
736
 
544
737
  }
545
738
  else {
546
- await Clone(argv.foldername,pinata,client);
739
+
740
+ await Clone(argv.foldername,pinata,client,argv.mcp,argv.prompt);
547
741
  console.log('Clone operation finished.');
548
742
 
549
743
  }
@@ -567,7 +761,7 @@ yargs(hideBin(process.argv))
567
761
  .example('ihub op push ./repo', 'Push a local repository')
568
762
  .example('ihub op clone <reponame> --new true', 'Clone a new repository | name will be the reponame in UI')
569
763
  .example('ihub op clone <reponame>', 'Clone an existing repository | name will be the reponame in UI')
570
- .example('ihub op clone <reponame>', 'Pull updates in an existing repository | name will be the reponame in UI')
764
+ .example('ihub op pull <reponame>', 'Pull updates in an existing repository | name will be the reponame in UI')
571
765
  .epilog('ImmutableHub CLI • Built with ❤️')
572
766
  .help()
573
767
  .argv;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ihub-cli",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "immutablehub cli to push and clone repos",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -13,8 +13,10 @@
13
13
  "author": "immutablehub",
14
14
  "license": "ISC",
15
15
  "dependencies": {
16
+ "@huggingface/hub": "^2.7.1",
16
17
  "jest": "^30.2.0",
17
18
  "mongodb": "^7.0.0",
19
+ "p-limit": "^7.2.0",
18
20
  "pinata": "^2.5.1",
19
21
  "yargs": "^18.0.0"
20
22
  }