jvcs 1.1.8 → 1.2.0
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/.jvcs/HEAD +1 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/add.js +122 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/begin.js +201 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/clone.js +138 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/commit.js +83 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/driveUtility.js +56 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/init.js +60 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/log.js +99 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/login.js +33 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/push.js +165 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/revert.js +208 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/signup.js +28 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/status.js +160 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/unstage.js +104 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/utility.js +29 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/controllers/verifyOtp.js +55 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/jvcs_hashcode.json +62 -0
- package/.jvcs/commits/cd2a0ec7-04b8-4ac9-b539-617bb5fea1f3/meta.json +7 -0
- package/.jvcs/config.json +9 -0
- package/.jvcs/staging/controllers/add.js +122 -0
- package/.jvcs/staging/controllers/begin.js +201 -0
- package/.jvcs/staging/controllers/clone.js +138 -0
- package/.jvcs/staging/controllers/commit.js +83 -0
- package/.jvcs/staging/controllers/driveUtility.js +56 -0
- package/.jvcs/staging/controllers/init.js +60 -0
- package/.jvcs/staging/controllers/log.js +99 -0
- package/.jvcs/staging/controllers/login.js +33 -0
- package/.jvcs/staging/controllers/push.js +165 -0
- package/.jvcs/staging/controllers/revert.js +208 -0
- package/.jvcs/staging/controllers/signup.js +28 -0
- package/.jvcs/staging/controllers/status.js +160 -0
- package/.jvcs/staging/controllers/unstage.js +104 -0
- package/.jvcs/staging/controllers/utility.js +29 -0
- package/.jvcs/staging/controllers/verifyOtp.js +55 -0
- package/.jvcs/staging/jvcs_hashcode.json +62 -0
- package/controllers/clone.js +25 -15
- package/package.json +1 -1
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
const { checkGlobalConfig, getGlobalConfig } = require("./utility");
|
|
5
|
+
const { getDriveClient } = require("../config/drive-config");
|
|
6
|
+
const drive = getDriveClient()
|
|
7
|
+
|
|
8
|
+
async function findFolderIdByName(name,parentId=null) {
|
|
9
|
+
|
|
10
|
+
const safeName = name.replace(/'/g, "\\'");
|
|
11
|
+
const parts = [`name='${safeName}'`, "trashed=false"];
|
|
12
|
+
if (parentId) parts.push(`'${parentId}' in parents`);
|
|
13
|
+
|
|
14
|
+
const q = parts.join(" and ");
|
|
15
|
+
const res = await drive.files.list({
|
|
16
|
+
q,
|
|
17
|
+
fields: "files(id, name)",
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const files = (res.data && res.data.files) || [];
|
|
21
|
+
if (files.length === 0) return null;
|
|
22
|
+
return files[0].id;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function downloadFolderFromDrive(folderId, destPath) {
|
|
26
|
+
try {
|
|
27
|
+
const res = await drive.files.list({
|
|
28
|
+
q: `'${folderId}' in parents and trashed=false`,
|
|
29
|
+
fields: "files(id, name, mimeType)",
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const files = res.data.files;
|
|
33
|
+
if (!files.length) return;
|
|
34
|
+
|
|
35
|
+
for (const file of files) {
|
|
36
|
+
const filePath = path.join(destPath, file.name);
|
|
37
|
+
|
|
38
|
+
if (file.mimeType === "application/vnd.google-apps.folder") {
|
|
39
|
+
// create folder locally
|
|
40
|
+
if (!fs.existsSync(filePath)) fs.mkdirSync(filePath);
|
|
41
|
+
await downloadFolderFromDrive(file.id, filePath);
|
|
42
|
+
} else {
|
|
43
|
+
const dest = fs.createWriteStream(filePath);
|
|
44
|
+
await drive.files.get(
|
|
45
|
+
{ fileId: file.id, alt: "media" },
|
|
46
|
+
{ responseType: "stream" }
|
|
47
|
+
).then(res => {
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
res.data
|
|
50
|
+
.on("end", resolve)
|
|
51
|
+
.on("error", reject)
|
|
52
|
+
.pipe(dest);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} catch (err) {
|
|
58
|
+
console.log(chalk.red("Error downloading folder: " + err.message));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
async function getVisibilityAndLatestCommit(username,reponame,configData) {
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
|
|
67
|
+
const response = await fetch("http://localhost:3000/cloneRepo", {
|
|
68
|
+
method:"POST",
|
|
69
|
+
headers: {
|
|
70
|
+
'Content-Type':"application/json"
|
|
71
|
+
},
|
|
72
|
+
body: JSON.stringify({username,reponame,token:configData.token})
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const data = await response.json()
|
|
76
|
+
return data
|
|
77
|
+
}
|
|
78
|
+
catch(error) {
|
|
79
|
+
console.log(chalk.red(error || error.message))
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function cloneCmd(username,reponame) {
|
|
84
|
+
|
|
85
|
+
if(!username || !reponame) {
|
|
86
|
+
console.log(chalk.red("Path is not provided properly"))
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if(!checkGlobalConfig()) {
|
|
91
|
+
console.log(chalk.red("No existing session found. Please login or signup."));
|
|
92
|
+
console.log(chalk.green("jvcs --help for help"));
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const configData = getGlobalConfig();
|
|
97
|
+
if(!configData) {
|
|
98
|
+
console.log(chalk.red("No existing session found. Please login or signup."));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
console.log(username,reponame)
|
|
103
|
+
|
|
104
|
+
const response = await getVisibilityAndLatestCommit(username,reponame,configData)
|
|
105
|
+
if(response.status === false) {
|
|
106
|
+
console.log(chalk.red(`${response.message}`))
|
|
107
|
+
return
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const latestCommit = response.commitId
|
|
111
|
+
// find the repo from drive GithubClone/username/reponame/commit_lastestCommit
|
|
112
|
+
|
|
113
|
+
const rootFolder = await findFolderIdByName("GithubClone")
|
|
114
|
+
if(!rootFolder) throw new Error("Root folder not found on cloud.");
|
|
115
|
+
|
|
116
|
+
const userFolder = await findFolderIdByName(username, rootFolder);
|
|
117
|
+
if (!userFolder) throw new Error(`User folder '${username}' not found.`);
|
|
118
|
+
|
|
119
|
+
const repoFolder = await findFolderIdByName(reponame, userFolder);
|
|
120
|
+
if (!repoFolder) throw new Error(`Repository folder '${reponame}' not found.`);
|
|
121
|
+
|
|
122
|
+
const commitFolder = await findFolderIdByName(`commit_${latestCommit}`, repoFolder);
|
|
123
|
+
if (!commitFolder) throw new Error(`Commit folder 'commit_${latestCommit}' not found.`);
|
|
124
|
+
|
|
125
|
+
console.log(chalk.green(`Found repository, downloading...`));
|
|
126
|
+
|
|
127
|
+
const destPath = path.join(process.cwd(), reponame);
|
|
128
|
+
if(fs.existsSync(destPath)) {
|
|
129
|
+
console.log(chalk.red(`Destination '${reponame}' already exists. Remove or rename it and retry.`));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
await downloadFolderFromDrive(commitFolder, destPath);
|
|
134
|
+
|
|
135
|
+
console.log(chalk.green(`Repository cloned successfully into ./${reponame}`));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
module.exports = cloneCmd
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const fs = require("fs").promises;
|
|
3
|
+
const fssync = require("fs");
|
|
4
|
+
const chalk = require("chalk");
|
|
5
|
+
const { v4: uuidv4 } = require("uuid");
|
|
6
|
+
const { checkGlobalConfig, getGlobalConfig, checkforjvcs } = require("./utility");
|
|
7
|
+
|
|
8
|
+
async function commitCmd(message) {
|
|
9
|
+
|
|
10
|
+
if (!message || !message.trim()) {
|
|
11
|
+
console.log(chalk.yellow("Please provide a commit message."));
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if(!checkGlobalConfig()) {
|
|
16
|
+
console.log(chalk.red("No existing session found. Please login or signup."))
|
|
17
|
+
console.log(chalk.green("jvcs --help for help"))
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let configData = getGlobalConfig()
|
|
22
|
+
|
|
23
|
+
if(!configData) {
|
|
24
|
+
console.log(chalk.red("No existing session found. Please login or signup."))
|
|
25
|
+
console.log(chalk.green("jvcs --help for help"))
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if(!checkforjvcs()) {
|
|
30
|
+
console.log(chalk.red("Repository is not initialized or is deleted. Please create it."))
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const repoPath = path.join(process.cwd(),".jvcs")
|
|
35
|
+
const staging = path.join(repoPath,"staging")
|
|
36
|
+
const commits = path.join(repoPath,"commits")
|
|
37
|
+
|
|
38
|
+
if(!fssync.existsSync(staging)) {
|
|
39
|
+
console.log(chalk.yellow("Nothing to commit — staging area is empty."))
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const stagedContent = await fs.readdir(staging)
|
|
44
|
+
if(stagedContent.length === 0) {
|
|
45
|
+
console.log(chalk.yellow("Nothing to commit — staging area is empty."))
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if(!fssync.existsSync(commits)) {
|
|
51
|
+
await fs.mkdir(commits)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// main commit logic
|
|
55
|
+
const commitId = uuidv4()
|
|
56
|
+
const commitFolder = path.join(commits,commitId)
|
|
57
|
+
await fs.mkdir(commitFolder, {recursive: true})
|
|
58
|
+
|
|
59
|
+
// copying the staging area content to commit folder
|
|
60
|
+
await fs.cp(staging,commitFolder, {recursive: true})
|
|
61
|
+
|
|
62
|
+
// saving metadata of commit
|
|
63
|
+
let parentId = null;
|
|
64
|
+
const headPath = path.join(repoPath, "HEAD");
|
|
65
|
+
if (fssync.existsSync(headPath)) {
|
|
66
|
+
parentId = (await fs.readFile(headPath, "utf8")).trim() || null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const meta = {
|
|
70
|
+
author: configData.username || "unknown",
|
|
71
|
+
id: commitId,
|
|
72
|
+
message,
|
|
73
|
+
timeStamp: new Date().toISOString(),
|
|
74
|
+
parentId
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
await fs.writeFile(path.join(commitFolder,"meta.json"),JSON.stringify(meta,null,2))
|
|
78
|
+
|
|
79
|
+
await fs.writeFile(path.join(repoPath, "HEAD"), commitId);
|
|
80
|
+
console.log(chalk.green(`Committed as ${commitId}: "${message}"`));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
module.exports = commitCmd
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const { getDriveClient } = require("../config/drive-config");
|
|
2
|
+
const drive = getDriveClient()
|
|
3
|
+
|
|
4
|
+
async function getDirectoryStructure(username,reponame,commitId) {
|
|
5
|
+
|
|
6
|
+
async function findOrCreateFolder(name,parentId=null) {
|
|
7
|
+
|
|
8
|
+
const query = [
|
|
9
|
+
`name='${name}'`,
|
|
10
|
+
"mimeType='application/vnd.google-apps.folder'",
|
|
11
|
+
"trashed=false"
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
if(parentId) {
|
|
15
|
+
query.push(`'${parentId}' in parents`)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const res = await drive.files.list({
|
|
19
|
+
q: query.join(" and "),
|
|
20
|
+
fields: "files(id,name)"
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
if (res.data.files.length > 0)
|
|
24
|
+
return { id: res.data.files[0].id, alreadyExists: true };
|
|
25
|
+
|
|
26
|
+
const folderMetaData = {
|
|
27
|
+
name,
|
|
28
|
+
mimeType: "application/vnd.google-apps.folder",
|
|
29
|
+
}
|
|
30
|
+
if(parentId) folderMetaData.parents = [parentId];
|
|
31
|
+
|
|
32
|
+
const folder = await drive.files.create({
|
|
33
|
+
resource: folderMetaData,
|
|
34
|
+
fields: "id"
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
return { id: folder.data.id, alreadyExists: false };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Build folder hierarchy in drive
|
|
41
|
+
const githubClone = await findOrCreateFolder("GithubClone");
|
|
42
|
+
const userFolder = await findOrCreateFolder(username,githubClone.id)
|
|
43
|
+
const repoFolder = await findOrCreateFolder(reponame,userFolder.id)
|
|
44
|
+
const commitFolderName = `commit_${commitId}`
|
|
45
|
+
const commitFolder = await findOrCreateFolder(commitFolderName,repoFolder.id)
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
githubCloneId: githubClone.id,
|
|
49
|
+
userFolderId: userFolder.id,
|
|
50
|
+
repoFolderId: repoFolder.id,
|
|
51
|
+
commitFolderId: commitFolder.id,
|
|
52
|
+
commitAlreadyExists: commitFolder.alreadyExists
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = getDirectoryStructure
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const fs = require("fs").promises;
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
const fssync = require("fs")
|
|
5
|
+
const { getGlobalConfig, checkGlobalConfig } = require("./utility")
|
|
6
|
+
|
|
7
|
+
async function initCmd() {
|
|
8
|
+
|
|
9
|
+
if(!checkGlobalConfig()) {
|
|
10
|
+
console.log(chalk.red("No existing session found. Please login or signup."))
|
|
11
|
+
console.log(chalk.green("jvcs --help for help"))
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let configData = null
|
|
16
|
+
configData = getGlobalConfig()
|
|
17
|
+
|
|
18
|
+
if(!configData) {
|
|
19
|
+
console.log(chalk.red("No existing session found. Please login or signup."))
|
|
20
|
+
console.log(chalk.green("jvcs --help for help"))
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// initialize an empty folder with the name of current directory
|
|
25
|
+
const cwd = process.cwd()
|
|
26
|
+
const home = require("os").homedir()
|
|
27
|
+
|
|
28
|
+
if(cwd === home) {
|
|
29
|
+
console.log(chalk.red("Cannot initialize a repository in your home directory."));
|
|
30
|
+
console.log(chalk.yellow("Hint: navigate to a project folder and run 'jvcs init' there."));
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const repoPath = path.join(cwd,".jvcs")
|
|
35
|
+
if(fssync.existsSync(repoPath)) {
|
|
36
|
+
console.log(chalk.yellow("Repository already is initialized."));
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
fssync.mkdirSync(repoPath)
|
|
41
|
+
fssync.mkdirSync(path.join(repoPath,"commits"))
|
|
42
|
+
fssync.mkdirSync(path.join(repoPath,"staging"))
|
|
43
|
+
|
|
44
|
+
const config = {
|
|
45
|
+
repoName: path.basename(cwd),
|
|
46
|
+
createdAt: new Date().toISOString(),
|
|
47
|
+
remote: null,
|
|
48
|
+
owner : {
|
|
49
|
+
username: configData.username,
|
|
50
|
+
email: configData.email
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
fssync.writeFileSync(path.join(repoPath, "config.json"), JSON.stringify(config, null, 2))
|
|
55
|
+
fssync.writeFileSync(path.join(repoPath, "HEAD"), "");
|
|
56
|
+
|
|
57
|
+
console.log(chalk.green(`Initialized empty JVCS repository`));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = initCmd
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
const fssync = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
const { checkGlobalConfig, getGlobalConfig, checkforjvcs } = require("./utility");
|
|
5
|
+
|
|
6
|
+
async function logCmd() {
|
|
7
|
+
|
|
8
|
+
if(!checkGlobalConfig()) {
|
|
9
|
+
console.log(chalk.red("No existing session found. Please login or signup."));
|
|
10
|
+
console.log(chalk.green("jvcs --help for help"));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const configData = getGlobalConfig();
|
|
15
|
+
if(!configData) {
|
|
16
|
+
console.log(chalk.red("No existing session found. Please login or signup."));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if(!checkforjvcs()) {
|
|
21
|
+
console.log(chalk.red("Repository is not initialized or is deleted."));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const repoPath = path.join(process.cwd(),".jvcs")
|
|
26
|
+
const commitPath = path.join(repoPath,"commits")
|
|
27
|
+
const headPath = path.join(repoPath,"HEAD")
|
|
28
|
+
|
|
29
|
+
if(!fssync.existsSync(headPath)) {
|
|
30
|
+
console.log(chalk.yellow("No commits yet."));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if(!fssync.existsSync(commitPath)) {
|
|
35
|
+
console.log(chalk.yellow("No commits found. Try commiting first"))
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const commitDir = fssync.readdirSync(commitPath)
|
|
40
|
+
if(commitDir.length === 0) {
|
|
41
|
+
console.log(chalk.yellow("No commits found. Try commiting first"))
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const currentHead = fssync.readFileSync(headPath,"utf-8").trim()
|
|
46
|
+
if(!currentHead) {
|
|
47
|
+
console.log(chalk.yellow("HEAD is empty. No commits to display."));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.log(chalk.bold.cyan("\n=========================== Commit History ====================\n"));
|
|
52
|
+
|
|
53
|
+
let commitId = currentHead
|
|
54
|
+
const chains = []
|
|
55
|
+
|
|
56
|
+
while(commitId) {
|
|
57
|
+
const commitFolder = path.join(commitPath,commitId)
|
|
58
|
+
const metaPath = path.join(commitFolder,"meta.json")
|
|
59
|
+
|
|
60
|
+
if (!fssync.existsSync(metaPath)) {
|
|
61
|
+
console.log(chalk.red(`Missing metadata for commit: ${commitId}`));
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const metaData = JSON.parse(fssync.readFileSync(metaPath,"utf-8"))
|
|
66
|
+
console.log('\t',chalk.yellow(`commit ${metaData.id}`));
|
|
67
|
+
console.log('\t',chalk.green(`Author:`), metaData.author || "Unknown");
|
|
68
|
+
console.log('\t',chalk.cyan(`Date:`), new Date(metaData.timeStamp).toLocaleString());
|
|
69
|
+
console.log('\t',chalk.white(`\n\t\t${metaData.message}\n`));
|
|
70
|
+
|
|
71
|
+
chains.push(metaData.id)
|
|
72
|
+
commitId = metaData.parentId
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.log(chalk.magenta("\n=================Visual Representation for commits==============\n"))
|
|
76
|
+
|
|
77
|
+
console.log(chalk.cyan.bold("\n HEAD"));
|
|
78
|
+
console.log(chalk.cyan(" ↓\n"));
|
|
79
|
+
|
|
80
|
+
let chainLine = "";
|
|
81
|
+
|
|
82
|
+
for (let i = 0; i < chains.length; i++) {
|
|
83
|
+
const id = chains[i].substring(0, 8); // short commit ID
|
|
84
|
+
chainLine += chalk.green(id);
|
|
85
|
+
|
|
86
|
+
if (i !== chains.length - 1) {
|
|
87
|
+
chainLine += chalk.cyan(" → ");
|
|
88
|
+
} else {
|
|
89
|
+
chainLine += chalk.gray(" → NULL");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.log(chainLine);
|
|
94
|
+
console.log();
|
|
95
|
+
|
|
96
|
+
console.log(chalk.bold.cyan("=================================================================\n"));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
module.exports = logCmd
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const path = require("path")
|
|
2
|
+
const chalk = require("chalk")
|
|
3
|
+
const fs = require("fs")
|
|
4
|
+
async function login(loginData) {
|
|
5
|
+
|
|
6
|
+
const response = await fetch("http://localhost:3000/login", {
|
|
7
|
+
method: "POST",
|
|
8
|
+
headers: {
|
|
9
|
+
'Content-Type': 'application/json'
|
|
10
|
+
},
|
|
11
|
+
credentials: "include",
|
|
12
|
+
body: JSON.stringify({email:loginData.email,username:loginData.username,password:loginData.password,cli:true})
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const data = await response.json()
|
|
16
|
+
|
|
17
|
+
if(data.status === true) {
|
|
18
|
+
console.log(chalk.green(data.message))
|
|
19
|
+
|
|
20
|
+
const dirPath = path.join(require("os").homedir(), ".jvcs");
|
|
21
|
+
if (!fs.existsSync(dirPath)) {
|
|
22
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const configPath = path.join(dirPath, "config.json");
|
|
26
|
+
fs.writeFileSync(configPath,JSON.stringify({email: loginData.email,username: loginData.username,token: data.token, CLIENT_ID:"835069827989-3spob55ioa2ocudi3mo8u2ni2ecqohh7.apps.googleusercontent.com",CLIENT_SECRET:"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",REDIRECT_URI:"https://developers.google.com/oauthplayground",REFRESH_TOKEN:"1//04dWkzGCpoIgACgYIARAAGAQSNwF-L9IrRV-B67zRcIkhs7USx3vLewtE764bZPv7d5d7hAlH7QThZxj2CQUr5flQIG12Ad64dQI"},null,2));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
throw new Error(data.message)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = login
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
const fs = require("fs")
|
|
2
|
+
const path = require("path")
|
|
3
|
+
const chalk = require("chalk")
|
|
4
|
+
const { getDriveClient } = require("../config/drive-config")
|
|
5
|
+
const drive = getDriveClient()
|
|
6
|
+
const { getGlobalConfig, checkGlobalConfig, checkforjvcs } = require("./utility")
|
|
7
|
+
const getDirectoryStructure = require("./driveUtility")
|
|
8
|
+
const handleDbForRepo = require("../apicall/handleDbForRepo")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
async function uploadFile(localFile, parentId,data) {
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
|
|
17
|
+
const fileName = path.basename(localFile)
|
|
18
|
+
const fileMetaData = {
|
|
19
|
+
name: fileName,
|
|
20
|
+
parents: [parentId]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const media = {
|
|
24
|
+
mimeType: "application/octet-stream",
|
|
25
|
+
body: fs.createReadStream(localFile),
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const res = await drive.files.create({
|
|
29
|
+
resource: fileMetaData,
|
|
30
|
+
media,
|
|
31
|
+
fields: "id"
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
console.log(chalk.gray(` ↳ Uploaded: ${fileName}`));
|
|
35
|
+
data.files.push({name:fileName,driveId:res.data.id,parentId:parentId,type:"file"})
|
|
36
|
+
return res.data.id;
|
|
37
|
+
}
|
|
38
|
+
catch(error) {
|
|
39
|
+
console.log(chalk.red(`Failed to upload ${filePath}: ${err.message}`));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function uploadDirectory(localDir, parentId,data) {
|
|
44
|
+
|
|
45
|
+
const entries = fs.readdirSync(localDir, {withFileTypes: true})
|
|
46
|
+
|
|
47
|
+
for(const entry of entries) {
|
|
48
|
+
|
|
49
|
+
const entryPath = path.join(localDir,entry.name)
|
|
50
|
+
|
|
51
|
+
if(entry.isDirectory()) {
|
|
52
|
+
const folderMeta = {
|
|
53
|
+
name: entry.name,
|
|
54
|
+
mimeType: "application/vnd.google-apps.folder",
|
|
55
|
+
parents: [parentId],
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const folder = await drive.files.create({
|
|
59
|
+
resource: folderMeta,
|
|
60
|
+
fields: "id"
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
data.files.push({name:entry.name,driveId:folder.data.id,parentId:parentId,type:"folder"})
|
|
64
|
+
await uploadDirectory(entryPath,folder.data.id,data)
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
await uploadFile(entryPath,parentId,data)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function pushCmd() {
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
|
|
76
|
+
let userFolderId,repoFolderId
|
|
77
|
+
|
|
78
|
+
if(!checkGlobalConfig()) {
|
|
79
|
+
console.log(chalk.red("No existing session found. Please login or signup."))
|
|
80
|
+
console.log(chalk.green("jvcs --help for help"))
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let configData = getGlobalConfig()
|
|
85
|
+
|
|
86
|
+
if(!configData) {
|
|
87
|
+
console.log(chalk.red("No existing session found. Please login or signup."))
|
|
88
|
+
console.log(chalk.green("jvcs --help for help"))
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if(!checkforjvcs()) {
|
|
93
|
+
console.log(chalk.red("Repository is not initialized or is deleted. Please create it."))
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const cwd = process.cwd()
|
|
98
|
+
const jvcsDir = path.join(cwd,".jvcs")
|
|
99
|
+
const commitDir = path.join(jvcsDir,"commits")
|
|
100
|
+
const reponame = path.basename(process.cwd())
|
|
101
|
+
|
|
102
|
+
if(!fs.existsSync(commitDir)) {
|
|
103
|
+
console.log(chalk.yellow("No commits to push"))
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// storing the name of commit folders
|
|
108
|
+
const commitFolders = fs.readdirSync(commitDir, {withFileTypes: true}).filter((e)=> e.isDirectory()).map((e)=> e.name)
|
|
109
|
+
if(commitFolders.length === 0) {
|
|
110
|
+
console.log(chalk.yellow('No commits to push'))
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
console.log(chalk.blue("Pushing commits of ",reponame," to cloud storage..."))
|
|
115
|
+
|
|
116
|
+
const Content = []
|
|
117
|
+
for(const commitId of commitFolders) {
|
|
118
|
+
let data = {}
|
|
119
|
+
data.files = []
|
|
120
|
+
data.uuid = commitId
|
|
121
|
+
const commitFolder = path.join(commitDir,commitId)
|
|
122
|
+
const metaPath = path.join(commitFolder,"meta.json")
|
|
123
|
+
|
|
124
|
+
if(!fs.existsSync(metaPath)) {
|
|
125
|
+
console.log(chalk.yellow(`Skipping ${commitId} (no meta.json found)`));
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const metaData = JSON.parse(fs.readFileSync(metaPath,"utf-8"))
|
|
130
|
+
const { author, message, timeStamp } = metaData;
|
|
131
|
+
|
|
132
|
+
console.log(chalk.green(`\n Uploading commit:`));
|
|
133
|
+
console.log(chalk.gray(` id: ${commitId}`));
|
|
134
|
+
console.log(chalk.gray(` message: ${message}`));
|
|
135
|
+
console.log(chalk.gray(` author: ${author}`));
|
|
136
|
+
console.log(chalk.gray(` time: ${timeStamp}`));
|
|
137
|
+
|
|
138
|
+
const folderStructure = await getDirectoryStructure(configData.username,reponame,commitId)
|
|
139
|
+
const driveCommitId = folderStructure.commitFolderId;
|
|
140
|
+
repoFolderId = folderStructure.repoFolderId;
|
|
141
|
+
userFolderId = folderStructure.userFolderId;
|
|
142
|
+
const commitAlreadyExists = folderStructure.commitAlreadyExists;
|
|
143
|
+
|
|
144
|
+
if (commitAlreadyExists) {
|
|
145
|
+
console.log(chalk.yellow(`Skipping ${commitId} (already uploaded)`));
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
await uploadDirectory(commitFolder,driveCommitId,data)
|
|
150
|
+
console.log(chalk.green(`Commit ${commitId} uploaded successfully!`));
|
|
151
|
+
Content.push(data)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
console.log(chalk.bold.green("\nAll commits pushed successfully!"));
|
|
155
|
+
|
|
156
|
+
// database call for creating/updating an repository
|
|
157
|
+
await handleDbForRepo(reponame,repoFolderId,userFolderId,Content,configData.token)
|
|
158
|
+
}
|
|
159
|
+
catch(error) {
|
|
160
|
+
console.log(chalk.red.bold("\nPush Failed"));
|
|
161
|
+
console.error(chalk.red(error.stack || error.message || error));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
module.exports = pushCmd
|