ihub-cli 1.1.6 → 1.1.7
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/index.js +185 -0
- package/package.json +2 -2
- package/readbuilddirs.js +0 -0
package/index.js
CHANGED
|
@@ -12,6 +12,8 @@ import { provideClient } from "./dbconnection.js"
|
|
|
12
12
|
|
|
13
13
|
import pLimit from "p-limit";
|
|
14
14
|
|
|
15
|
+
import {createRepo,uploadFiles,commit} from "@huggingface/hub"
|
|
16
|
+
|
|
15
17
|
|
|
16
18
|
const IHUB_DIR = path.join(os.homedir(), ".ihub");
|
|
17
19
|
const FILE_TO_STORE_LOGIN = path.join(IHUB_DIR, "login.txt");
|
|
@@ -33,10 +35,26 @@ async function getcreds() {
|
|
|
33
35
|
|
|
34
36
|
}
|
|
35
37
|
|
|
38
|
+
|
|
39
|
+
async function getToken(){
|
|
40
|
+
|
|
41
|
+
let request=await fetch("https://immutablehub-creds.hf.space/hft",{
|
|
42
|
+
mode:"cors",
|
|
43
|
+
method:"get",
|
|
44
|
+
headers:{
|
|
45
|
+
"content-type":"application/json"
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
let response=await request.json()
|
|
49
|
+
return {"hft":response.hft}
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
36
53
|
async function getRuntime() {
|
|
37
54
|
|
|
38
55
|
const { jwt, gateway } = await getcreds();
|
|
39
56
|
const pinata = new PinataSDK({ pinataJwt: jwt, pinataGateway: gateway });
|
|
57
|
+
|
|
40
58
|
|
|
41
59
|
|
|
42
60
|
const client = provideClient();
|
|
@@ -590,6 +608,144 @@ async function Pull(folder,pinata,client,mcp,prompt){
|
|
|
590
608
|
|
|
591
609
|
|
|
592
610
|
|
|
611
|
+
|
|
612
|
+
async function ensureSpaceExists(name,Token) {
|
|
613
|
+
try {
|
|
614
|
+
await createRepo({
|
|
615
|
+
repo: { type: "space", name: name },
|
|
616
|
+
accessToken: Token,
|
|
617
|
+
sdk: "docker", // Required for Spaces
|
|
618
|
+
});
|
|
619
|
+
return true
|
|
620
|
+
|
|
621
|
+
} catch (error) {
|
|
622
|
+
// Check if the error is specifically because it already exists
|
|
623
|
+
if (error.status !== 409) {
|
|
624
|
+
return true
|
|
625
|
+
}
|
|
626
|
+
else{
|
|
627
|
+
return false
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
async function Host(folder,client){
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
let token=await getToken()
|
|
642
|
+
const TT = Buffer.from(token.hft, 'base64').toString('utf-8');
|
|
643
|
+
const targetManifestId= fs.readFileSync(FILE_TO_STORE_LOGIN,'utf8');
|
|
644
|
+
const absolutePath = path.resolve(folder);
|
|
645
|
+
const lastName = path.basename(absolutePath);
|
|
646
|
+
console.log(lastName);
|
|
647
|
+
const spaceName = `immutablehub/${lastName}_${targetManifestId}`;
|
|
648
|
+
const files = [
|
|
649
|
+
{
|
|
650
|
+
path: "Dockerfile",
|
|
651
|
+
content: `
|
|
652
|
+
#Use a slim Node.js image for faster builds
|
|
653
|
+
FROM node:18-slim
|
|
654
|
+
|
|
655
|
+
#Create and define the working directory
|
|
656
|
+
WORKDIR /app
|
|
657
|
+
|
|
658
|
+
#Copy package.json and package-lock.json first for better caching
|
|
659
|
+
COPY package*.json ./
|
|
660
|
+
|
|
661
|
+
#Install dependencies
|
|
662
|
+
RUN npm install
|
|
663
|
+
|
|
664
|
+
#Copy the rest of your application code
|
|
665
|
+
COPY . .
|
|
666
|
+
|
|
667
|
+
#Hugging Face Spaces require port 7860
|
|
668
|
+
EXPOSE 7860
|
|
669
|
+
|
|
670
|
+
#Start the application
|
|
671
|
+
CMD ["node", "index.js"]
|
|
672
|
+
|
|
673
|
+
`.trim(),
|
|
674
|
+
},
|
|
675
|
+
{
|
|
676
|
+
path: "README.md",
|
|
677
|
+
content: [
|
|
678
|
+
'---',
|
|
679
|
+
'title: Docker Space',
|
|
680
|
+
'emoji: 🐳',
|
|
681
|
+
'colorFrom: blue',
|
|
682
|
+
'colorTo: blue',
|
|
683
|
+
'sdk: docker',
|
|
684
|
+
'app_port: 7860', // Highly recommended since you EXPOSE 7860
|
|
685
|
+
'pinned: false',
|
|
686
|
+
'---'
|
|
687
|
+
].join('\n')
|
|
688
|
+
},
|
|
689
|
+
];
|
|
690
|
+
|
|
691
|
+
console.log("checking space")
|
|
692
|
+
let exists=await ensureSpaceExists(spaceName,TT)
|
|
693
|
+
if(exists) {
|
|
694
|
+
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
let rawFiles=dirtoFileArray(absolutePath)
|
|
698
|
+
console.log(rawFiles)
|
|
699
|
+
|
|
700
|
+
const filesToUpload = rawFiles
|
|
701
|
+
.filter(file => {
|
|
702
|
+
// Replicating your "cleanedFiles" logic
|
|
703
|
+
const isIgnored = file.name === "package-lock.json" || file.name.includes(".history.bundle");
|
|
704
|
+
return !isIgnored;
|
|
705
|
+
})
|
|
706
|
+
.map(file => {
|
|
707
|
+
|
|
708
|
+
return {
|
|
709
|
+
path: file.name,
|
|
710
|
+
content: file
|
|
711
|
+
};
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
//let allFiles=[...files,...filesToUpload]
|
|
715
|
+
const finalFiles = [...files, ...filesToUpload].map(f => ({
|
|
716
|
+
path: f.path,
|
|
717
|
+
//We wrap in a new Blob to strip the 'File' prototype that is causing the error
|
|
718
|
+
content: new Blob([f.content])
|
|
719
|
+
}));
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
console.log("now uploading")
|
|
724
|
+
await uploadFiles({
|
|
725
|
+
repo: { type: "space", name: spaceName },
|
|
726
|
+
accessToken: TT,
|
|
727
|
+
files: finalFiles
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
let db=client.db("ihub_db")
|
|
733
|
+
let coll=db.collection("hosted")
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
await coll.insertOne({"id":targetManifestId,"app":folder,"space":`https://huggingface.co/spaces/${spaceName}`})
|
|
737
|
+
console.log(`https://huggingface.co/spaces/${spaceName}`)
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
}
|
|
741
|
+
else{
|
|
742
|
+
console.log("error in hosting")
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
|
|
593
749
|
yargs(hideBin(process.argv))
|
|
594
750
|
.command(
|
|
595
751
|
'op',
|
|
@@ -751,6 +907,34 @@ yargs(hideBin(process.argv))
|
|
|
751
907
|
|
|
752
908
|
}
|
|
753
909
|
)
|
|
910
|
+
.command(
|
|
911
|
+
'host <foldername>',
|
|
912
|
+
'hosts a provided nodejs backend repo',
|
|
913
|
+
(yargs) => {
|
|
914
|
+
return yargs.positional('foldername', {
|
|
915
|
+
describe: 'The repo to host',
|
|
916
|
+
type: 'string'
|
|
917
|
+
});
|
|
918
|
+
},
|
|
919
|
+
async (argv) => {
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
const { pinata, client } = await getRuntime();
|
|
923
|
+
|
|
924
|
+
try {
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
await Host(argv.foldername,client);
|
|
928
|
+
|
|
929
|
+
}catch(e){
|
|
930
|
+
console.log(e);
|
|
931
|
+
}
|
|
932
|
+
finally{
|
|
933
|
+
await client.close();
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
}
|
|
937
|
+
)
|
|
754
938
|
.demandCommand(1, 'You must provide a subcommand for "ihub" (login, push, or clone).')
|
|
755
939
|
.help()
|
|
756
940
|
}
|
|
@@ -762,6 +946,7 @@ yargs(hideBin(process.argv))
|
|
|
762
946
|
.example('ihub op clone <reponame> --new true', 'Clone a new repository | name will be the reponame in UI')
|
|
763
947
|
.example('ihub op clone <reponame>', 'Clone an existing repository | name will be the reponame in UI')
|
|
764
948
|
.example('ihub op pull <reponame>', 'Pull updates in an existing repository | name will be the reponame in UI')
|
|
949
|
+
.example('ihub op host <reponame>', 'Hosts a provided nodejs backend repo')
|
|
765
950
|
.epilog('ImmutableHub CLI • Built with ❤️')
|
|
766
951
|
.help()
|
|
767
952
|
.argv;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ihub-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.7",
|
|
4
4
|
"description": "immutablehub cli to push and clone repos",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@huggingface/hub": "^2.7.1",
|
|
17
17
|
"jest": "^30.2.0",
|
|
18
18
|
"mongodb": "^7.0.0",
|
|
19
|
-
"p-limit": "^7.
|
|
19
|
+
"p-limit": "^7.3.0",
|
|
20
20
|
"pinata": "^2.5.1",
|
|
21
21
|
"yargs": "^18.0.0"
|
|
22
22
|
}
|
package/readbuilddirs.js
ADDED
|
File without changes
|