jvcs 1.0.1 → 1.0.3
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/.env +4 -4
- package/.jvcs/HEAD +1 -1
- package/.jvcs/commits/3a1169c8-ec67-4ce5-8024-ab4f08d7b609/index.js +146 -0
- package/.jvcs/commits/3a1169c8-ec67-4ce5-8024-ab4f08d7b609/jvcs_hashcode.json +6 -0
- package/.jvcs/commits/3a1169c8-ec67-4ce5-8024-ab4f08d7b609/meta.json +7 -0
- package/.jvcs/commits/c362f97f-997b-499a-bb45-9e67f298f61e/index.js +146 -0
- package/.jvcs/commits/c362f97f-997b-499a-bb45-9e67f298f61e/jvcs_hashcode.json +6 -0
- package/.jvcs/commits/c362f97f-997b-499a-bb45-9e67f298f61e/meta.json +7 -0
- package/.jvcs/config.json +1 -1
- package/.jvcs/staging/index.js +146 -0
- package/.jvcs/staging/jvcs_hashcode.json +6 -1
- package/controllers/driveUtility.js +56 -0
- package/controllers/push.js +121 -111
- package/index.js +17 -2
- package/package.json +1 -1
- package/.jvcs/commits/292abee1-42ea-4ddf-b590-be7c98abaf45/jvcs_hashcode.json +0 -1
- package/.jvcs/commits/292abee1-42ea-4ddf-b590-be7c98abaf45/meta.json +0 -7
- package/.jvcs/commits/302af5ea-5789-4ee9-98fe-eab9308b2e27/jvcs_hashcode.json +0 -1
- package/.jvcs/commits/302af5ea-5789-4ee9-98fe-eab9308b2e27/meta.json +0 -7
- package/.jvcs/commits/376d44d4-c595-429e-b711-ae6ec7c9ef74/jvcs_hashcode.json +0 -1
- package/.jvcs/commits/376d44d4-c595-429e-b711-ae6ec7c9ef74/meta.json +0 -7
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/controllers/add.js +0 -122
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/controllers/begin.js +0 -201
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/controllers/commit.js +0 -82
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/controllers/init.js +0 -60
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/controllers/login.js +0 -33
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/controllers/pull.js +0 -98
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/controllers/push.js +0 -135
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/controllers/revert.js +0 -110
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/controllers/signup.js +0 -28
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/controllers/unstage.js +0 -96
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/controllers/utility.js +0 -28
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/controllers/verifyOtp.js +0 -55
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/jvcs_hashcode.json +0 -50
- package/.jvcs/commits/484ac37d-c1a9-4ddd-8796-6e3facda1e11/meta.json +0 -7
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/controllers/add.js +0 -122
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/controllers/begin.js +0 -201
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/controllers/commit.js +0 -82
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/controllers/init.js +0 -60
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/controllers/login.js +0 -33
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/controllers/pull.js +0 -98
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/controllers/push.js +0 -135
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/controllers/revert.js +0 -110
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/controllers/signup.js +0 -28
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/controllers/unstage.js +0 -96
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/controllers/utility.js +0 -28
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/controllers/verifyOtp.js +0 -55
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/jvcs_hashcode.json +0 -50
- package/.jvcs/commits/c3f6ff7a-13bd-4697-a80e-041f7dae8a09/meta.json +0 -7
- package/.jvcs/commits/c7aa89bd-5016-4f21-8979-02e3c0a2c8ee/jvcs_hashcode.json +0 -1
- package/.jvcs/commits/c7aa89bd-5016-4f21-8979-02e3c0a2c8ee/meta.json +0 -7
- package/controllers/pull.js +0 -98
- package/controllers/revert.js +0 -110
|
@@ -1,82 +0,0 @@
|
|
|
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
|
-
if(!fssync.existsSync(commits)) {
|
|
50
|
-
await fs.mkdir(commits)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// main commit logic
|
|
54
|
-
const commitId = uuidv4()
|
|
55
|
-
const commitFolder = path.join(commits,commitId)
|
|
56
|
-
await fs.mkdir(commitFolder, {recursive: true})
|
|
57
|
-
|
|
58
|
-
// copying the staging area content to commit folder
|
|
59
|
-
await fs.cp(staging,commitFolder, {recursive: true})
|
|
60
|
-
|
|
61
|
-
// saving metadata of commit
|
|
62
|
-
let parentId = null;
|
|
63
|
-
const headPath = path.join(repoPath, "HEAD");
|
|
64
|
-
if (fssync.existsSync(headPath)) {
|
|
65
|
-
parentId = (await fs.readFile(headPath, "utf8")).trim() || null;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const meta = {
|
|
69
|
-
author: configData.username || "unknown",
|
|
70
|
-
id: commitId,
|
|
71
|
-
message,
|
|
72
|
-
timeStamp: new Date().toISOString(),
|
|
73
|
-
parentId
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
await fs.writeFile(path.join(commitFolder,"meta.json"),JSON.stringify(meta,null,2))
|
|
77
|
-
|
|
78
|
-
await fs.writeFile(path.join(repoPath, "HEAD"), commitId);
|
|
79
|
-
console.log(chalk.green(`Committed as ${commitId}: "${message}"`));
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
module.exports = commitCmd
|
|
@@ -1,60 +0,0 @@
|
|
|
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
|
|
@@ -1,33 +0,0 @@
|
|
|
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},null,2));
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
throw new Error(data.message)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
module.exports = login
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const fsPromises = require("fs").promises;
|
|
3
|
-
const path = require("path");
|
|
4
|
-
const chalk = require("chalk");
|
|
5
|
-
const { drive } = require("../config/drive-config");
|
|
6
|
-
const { checkInitialization, checkRepoExists, getCLIConfig } = require("./utils");
|
|
7
|
-
|
|
8
|
-
async function pullCmd(reponame) {
|
|
9
|
-
try {
|
|
10
|
-
if (!checkInitialization()) return;
|
|
11
|
-
if (!checkRepoExists(reponame)) return;
|
|
12
|
-
|
|
13
|
-
const repoPath = path.join(process.cwd(), `.${reponame}`);
|
|
14
|
-
const commitFolder = path.join(repoPath, "commits");
|
|
15
|
-
if (!fs.existsSync(commitFolder)) fs.mkdirSync(commitFolder, { recursive: true });
|
|
16
|
-
|
|
17
|
-
const config = await getCLIConfig();
|
|
18
|
-
if (!config) return console.log(chalk.red("Could not read CLI configuration."));
|
|
19
|
-
|
|
20
|
-
console.log(chalk.blue("Pulling commits for user:"), chalk.green(config.username));
|
|
21
|
-
|
|
22
|
-
// 1️⃣ Find user folder in Drive
|
|
23
|
-
const userFolderRes = await drive.files.list({
|
|
24
|
-
q: `name='${config.username}' and '1ahuoMCN_Ls5kGF2KPUGLbRZb9kGVMe0V' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
25
|
-
fields: "files(id, name)"
|
|
26
|
-
});
|
|
27
|
-
if (!userFolderRes.data.files.length) {
|
|
28
|
-
console.log(chalk.yellow("⚠ No user folder found on Drive."));
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
const userFolderId = userFolderRes.data.files[0].id;
|
|
32
|
-
|
|
33
|
-
// 2️⃣ Find repo folder in Drive
|
|
34
|
-
const repoFolderRes = await drive.files.list({
|
|
35
|
-
q: `name='${reponame}' and '${userFolderId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
36
|
-
fields: "files(id, name)"
|
|
37
|
-
});
|
|
38
|
-
if (!repoFolderRes.data.files.length) {
|
|
39
|
-
console.log(chalk.yellow(`⚠ Repository '${reponame}' not found on Drive.`));
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const repoFolderId = repoFolderRes.data.files[0].id;
|
|
43
|
-
|
|
44
|
-
// 3️⃣ Get commit folders in Drive
|
|
45
|
-
const driveCommitsRes = await drive.files.list({
|
|
46
|
-
q: `'${repoFolderId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
47
|
-
fields: "files(name, id)"
|
|
48
|
-
});
|
|
49
|
-
const driveCommits = driveCommitsRes.data.files;
|
|
50
|
-
if (!driveCommits.length) {
|
|
51
|
-
console.log(chalk.yellow("⚠ No commits found on Drive."));
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// 4️⃣ Get local commit folders
|
|
56
|
-
const localCommits = await fsPromises.readdir(commitFolder);
|
|
57
|
-
|
|
58
|
-
// 5️⃣ Download only missing commits
|
|
59
|
-
for (const commit of driveCommits) {
|
|
60
|
-
if (localCommits.includes(commit.name)) {
|
|
61
|
-
console.log(chalk.gray(`✔ Commit '${commit.name}' already exists locally.`));
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
const localCommitPath = path.join(commitFolder, commit.name);
|
|
65
|
-
await fsPromises.mkdir(localCommitPath, { recursive: true });
|
|
66
|
-
await downloadFolder(commit.id, localCommitPath);
|
|
67
|
-
console.log(chalk.green(`⬇ Pulled new commit '${commit.name}' successfully.`));
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
console.log(chalk.blue("Pull complete! Local repo is now up to date."));
|
|
71
|
-
|
|
72
|
-
} catch (error) {
|
|
73
|
-
console.log(chalk.red("Error in pullCmd:"), error.message);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Recursive folder download helper
|
|
78
|
-
async function downloadFolder(folderId, destPath) {
|
|
79
|
-
const res = await drive.files.list({
|
|
80
|
-
q: `'${folderId}' in parents and trashed=false`,
|
|
81
|
-
fields: "files(id, name, mimeType)"
|
|
82
|
-
});
|
|
83
|
-
for (const file of res.data.files) {
|
|
84
|
-
const localPath = path.join(destPath, file.name);
|
|
85
|
-
if (file.mimeType === "application/vnd.google-apps.folder") {
|
|
86
|
-
await fsPromises.mkdir(localPath, { recursive: true });
|
|
87
|
-
await downloadFolder(file.id, localPath);
|
|
88
|
-
} else {
|
|
89
|
-
const dest = fs.createWriteStream(localPath);
|
|
90
|
-
await drive.files.get({ fileId: file.id, alt: "media" }, { responseType: "stream" })
|
|
91
|
-
.then(res => new Promise((resolve, reject) => {
|
|
92
|
-
res.data.on("end", resolve).on("error", reject).pipe(dest);
|
|
93
|
-
}));
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
module.exports = pullCmd;
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const fsPromises = require("fs").promises;
|
|
3
|
-
const path = require("path");
|
|
4
|
-
const chalk = require("chalk");
|
|
5
|
-
const { drive } = require("../config/drive-config");
|
|
6
|
-
const saveData = require("../controllers/saveData");
|
|
7
|
-
const { checkInitialization, checkRepoExists, getCLIConfig } = require("./utils");
|
|
8
|
-
|
|
9
|
-
async function pushCmd(reponame) {
|
|
10
|
-
try {
|
|
11
|
-
if (!checkInitialization()) return;
|
|
12
|
-
if (!checkRepoExists(reponame)) return;
|
|
13
|
-
|
|
14
|
-
const repoPath = path.join(process.cwd(), `.${reponame}`);
|
|
15
|
-
const commitFolder = path.join(repoPath, "commits");
|
|
16
|
-
|
|
17
|
-
const config = await getCLIConfig();
|
|
18
|
-
if (!config) return console.log(chalk.red("Could not read CLI configuration."));
|
|
19
|
-
|
|
20
|
-
console.log(chalk.blue("Pushing commits for user:"), chalk.green(config.username));
|
|
21
|
-
|
|
22
|
-
// Check commits locally
|
|
23
|
-
const commitDirs = await fsPromises.readdir(commitFolder);
|
|
24
|
-
if (!commitDirs.length) {
|
|
25
|
-
console.log(chalk.yellow("⚠ No commits to push."));
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Ensure user folder exists in Google Drive
|
|
30
|
-
let userFolderId;
|
|
31
|
-
const userFolderRes = await drive.files.list({
|
|
32
|
-
q: `name='${config.username}' and '1ahuoMCN_Ls5kGF2KPUGLbRZb9kGVMe0V' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
33
|
-
fields: "files(id, name)"
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
if (userFolderRes.data.files.length) {
|
|
37
|
-
userFolderId = userFolderRes.data.files[0].id;
|
|
38
|
-
} else {
|
|
39
|
-
const folder = await drive.files.create({
|
|
40
|
-
requestBody: {
|
|
41
|
-
name: config.username,
|
|
42
|
-
mimeType: "application/vnd.google-apps.folder",
|
|
43
|
-
parents: ["1ahuoMCN_Ls5kGF2KPUGLbRZb9kGVMe0V"]
|
|
44
|
-
},
|
|
45
|
-
fields: "id, name"
|
|
46
|
-
});
|
|
47
|
-
userFolderId = folder.data.id;
|
|
48
|
-
console.log(chalk.green(`Created user folder in Drive.`));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Ensure repo folder exists
|
|
52
|
-
let repoFolderId;
|
|
53
|
-
const repoFolderRes = await drive.files.list({
|
|
54
|
-
q: `name='${reponame}' and '${userFolderId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
55
|
-
fields: "files(id, name)"
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
if (repoFolderRes.data.files.length) {
|
|
59
|
-
repoFolderId = repoFolderRes.data.files[0].id;
|
|
60
|
-
} else {
|
|
61
|
-
const folder = await drive.files.create({
|
|
62
|
-
requestBody: {
|
|
63
|
-
name: reponame,
|
|
64
|
-
mimeType: "application/vnd.google-apps.folder",
|
|
65
|
-
parents: [userFolderId]
|
|
66
|
-
},
|
|
67
|
-
fields: "id, name"
|
|
68
|
-
});
|
|
69
|
-
repoFolderId = folder.data.id;
|
|
70
|
-
console.log(chalk.green(`Created repo folder '${reponame}' in Drive.`));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// List existing commits in Drive
|
|
74
|
-
const driveCommitsRes = await drive.files.list({
|
|
75
|
-
q: `'${repoFolderId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
76
|
-
fields: "files(name, id)"
|
|
77
|
-
});
|
|
78
|
-
const driveCommitNames = driveCommitsRes.data.files.map(f => f.name);
|
|
79
|
-
|
|
80
|
-
// Upload commits
|
|
81
|
-
for (const commitDir of commitDirs) {
|
|
82
|
-
if (driveCommitNames.includes(commitDir)) {
|
|
83
|
-
console.log(chalk.yellow(`Commit '${commitDir}' already exists on Drive, skipping.`));
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const folderPath = path.join(commitFolder, commitDir);
|
|
88
|
-
|
|
89
|
-
const commitFolderRes = await drive.files.create({
|
|
90
|
-
requestBody: {
|
|
91
|
-
name: commitDir,
|
|
92
|
-
mimeType: "application/vnd.google-apps.folder",
|
|
93
|
-
parents: [repoFolderId]
|
|
94
|
-
},
|
|
95
|
-
fields: "id, name"
|
|
96
|
-
});
|
|
97
|
-
const commitFolderId = commitFolderRes.data.id;
|
|
98
|
-
|
|
99
|
-
await uploadFolder(folderPath, commitFolderId);
|
|
100
|
-
|
|
101
|
-
console.log(chalk.green(`Commit '${commitDir}' pushed successfully.`));
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
} catch(error) {
|
|
105
|
-
console.log(chalk.red("Error in pushCmd:"), error.message);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Helper to recursively upload folder to Drive
|
|
110
|
-
async function uploadFolder(folderPath, parentId) {
|
|
111
|
-
const items = await fsPromises.readdir(folderPath);
|
|
112
|
-
for (const item of items) {
|
|
113
|
-
const fullPath = path.join(folderPath, item);
|
|
114
|
-
const stats = await fsPromises.stat(fullPath);
|
|
115
|
-
if (stats.isDirectory()) {
|
|
116
|
-
const folder = await drive.files.create({
|
|
117
|
-
requestBody: {
|
|
118
|
-
name: item,
|
|
119
|
-
mimeType: "application/vnd.google-apps.folder",
|
|
120
|
-
parents: [parentId]
|
|
121
|
-
},
|
|
122
|
-
fields: "id, name"
|
|
123
|
-
});
|
|
124
|
-
await uploadFolder(fullPath, folder.data.id);
|
|
125
|
-
} else {
|
|
126
|
-
await drive.files.create({
|
|
127
|
-
requestBody: { name: item, parents: [parentId] },
|
|
128
|
-
media: { body: fs.createReadStream(fullPath) },
|
|
129
|
-
fields: "id, name"
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
module.exports = pushCmd;
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const fsPromises = require("fs").promises;
|
|
3
|
-
const path = require("path");
|
|
4
|
-
const { v4: uuidv4 } = require("uuid");
|
|
5
|
-
const chalk = require("chalk");
|
|
6
|
-
const { drive } = require("../config/drive-config");
|
|
7
|
-
const { checkInitialization, checkRepoExists, getCLIConfig } = require("./utils");
|
|
8
|
-
|
|
9
|
-
async function revertCmd(commitId, reponame) {
|
|
10
|
-
try {
|
|
11
|
-
if (!checkInitialization()) return;
|
|
12
|
-
if (!checkRepoExists(reponame)) return;
|
|
13
|
-
|
|
14
|
-
const repoPath = path.join(process.cwd(), `.${reponame}`);
|
|
15
|
-
const commitFolder = path.join(repoPath, "commits");
|
|
16
|
-
if (!fs.existsSync(commitFolder)) fs.mkdirSync(commitFolder, { recursive: true });
|
|
17
|
-
|
|
18
|
-
const config = await getCLIConfig();
|
|
19
|
-
if (!config) return console.log(chalk.red("Could not read CLI configuration."));
|
|
20
|
-
|
|
21
|
-
// 1️⃣ Get user folder
|
|
22
|
-
const userFolderRes = await drive.files.list({
|
|
23
|
-
q: `name='${config.username}' and '1ahuoMCN_Ls5kGF2KPUGLbRZb9kGVMe0V' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
24
|
-
fields: "files(id, name)"
|
|
25
|
-
});
|
|
26
|
-
if (!userFolderRes.data.files.length) return console.log(chalk.red("User folder not found on Drive."));
|
|
27
|
-
const userFolderId = userFolderRes.data.files[0].id;
|
|
28
|
-
|
|
29
|
-
// 2️⃣ Get repo folder
|
|
30
|
-
const repoFolderRes = await drive.files.list({
|
|
31
|
-
q: `name='${reponame}' and '${userFolderId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
32
|
-
fields: "files(id, name)"
|
|
33
|
-
});
|
|
34
|
-
if (!repoFolderRes.data.files.length) return console.log(chalk.red("Repo folder not found on Drive."));
|
|
35
|
-
const repoFolderId = repoFolderRes.data.files[0].id;
|
|
36
|
-
|
|
37
|
-
// 3️⃣ Get commit folder
|
|
38
|
-
const commitRes = await drive.files.list({
|
|
39
|
-
q: `name='${commitId}' and '${repoFolderId}' in parents and mimeType='application/vnd.google-apps.folder' and trashed=false`,
|
|
40
|
-
fields: "files(id, name)"
|
|
41
|
-
});
|
|
42
|
-
if (!commitRes.data.files.length) return console.log(chalk.red(`Commit '${commitId}' not found on Drive.`));
|
|
43
|
-
const driveCommitId = commitRes.data.files[0].id;
|
|
44
|
-
|
|
45
|
-
// 4️⃣ Create new revert commit folder locally
|
|
46
|
-
const newCommitId = `revert_${commitId}_${uuidv4()}`;
|
|
47
|
-
const newCommitPath = path.join(commitFolder, newCommitId);
|
|
48
|
-
await fsPromises.mkdir(newCommitPath, { recursive: true });
|
|
49
|
-
|
|
50
|
-
// 5️⃣ Recursively download commit files from Drive
|
|
51
|
-
await downloadFolderFromDrive(driveCommitId, newCommitPath);
|
|
52
|
-
|
|
53
|
-
// 6️⃣ Clean working directory (except hidden files)
|
|
54
|
-
const cwd = process.cwd();
|
|
55
|
-
const entries = await fsPromises.readdir(cwd);
|
|
56
|
-
for (const entry of entries) {
|
|
57
|
-
if (entry.startsWith(".")) continue;
|
|
58
|
-
await fsPromises.rm(path.join(cwd, entry), { recursive: true, force: true });
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// 7️⃣ Copy new revert commit into working directory
|
|
62
|
-
await copyFolderRecursive(newCommitPath, cwd);
|
|
63
|
-
|
|
64
|
-
console.log(chalk.green(`Reverted to commit '${commitId}'. New revert commit: '${newCommitId}'`));
|
|
65
|
-
|
|
66
|
-
} catch (err) {
|
|
67
|
-
console.log(chalk.red("Error in revertCmd:"), err.message);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Recursive download helper
|
|
72
|
-
async function downloadFolderFromDrive(folderId, localPath) {
|
|
73
|
-
const res = await drive.files.list({
|
|
74
|
-
q: `'${folderId}' in parents and trashed=false`,
|
|
75
|
-
fields: "files(id, name, mimeType)"
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
for (const file of res.data.files) {
|
|
79
|
-
const filePath = path.join(localPath, file.name);
|
|
80
|
-
if (file.mimeType === "application/vnd.google-apps.folder") {
|
|
81
|
-
await fsPromises.mkdir(filePath, { recursive: true });
|
|
82
|
-
await downloadFolderFromDrive(file.id, filePath);
|
|
83
|
-
} else {
|
|
84
|
-
const destStream = fs.createWriteStream(filePath);
|
|
85
|
-
await new Promise((resolve, reject) => {
|
|
86
|
-
drive.files.get({ fileId: file.id, alt: "media" }, { responseType: "stream" }, (err, response) => {
|
|
87
|
-
if (err) return reject(err);
|
|
88
|
-
response.data.pipe(destStream).on("finish", resolve).on("error", reject);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Recursive copy helper
|
|
96
|
-
async function copyFolderRecursive(src, dest) {
|
|
97
|
-
const entries = await fsPromises.readdir(src, { withFileTypes: true });
|
|
98
|
-
for (const entry of entries) {
|
|
99
|
-
const srcPath = path.join(src, entry.name);
|
|
100
|
-
const destPath = path.join(dest, entry.name);
|
|
101
|
-
if (entry.isDirectory()) {
|
|
102
|
-
await fsPromises.mkdir(destPath, { recursive: true });
|
|
103
|
-
await copyFolderRecursive(srcPath, destPath);
|
|
104
|
-
} else {
|
|
105
|
-
await fsPromises.copyFile(srcPath, destPath);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
module.exports = revertCmd;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
const chalk = require("chalk")
|
|
2
|
-
const verifyOtp = require("./verifyOtp")
|
|
3
|
-
async function signup(signupData) {
|
|
4
|
-
|
|
5
|
-
const response = await fetch("http://localhost:3000/signup", {
|
|
6
|
-
method: "POST",
|
|
7
|
-
headers: {
|
|
8
|
-
'Content-Type': 'application/json'
|
|
9
|
-
},
|
|
10
|
-
credentials: "include",
|
|
11
|
-
body: JSON.stringify(signupData)
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
const data = await response.json()
|
|
15
|
-
|
|
16
|
-
if(data.status === true) {
|
|
17
|
-
console.log(chalk.green(data.message))
|
|
18
|
-
await verifyOtp(signupData)
|
|
19
|
-
}
|
|
20
|
-
else if(data.status == "user") {
|
|
21
|
-
console.log(chalk.yellow(data.message))
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
throw new Error(data.message)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
module.exports = signup
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
const fs = require("fs").promises;
|
|
2
|
-
const fssync = require("fs");
|
|
3
|
-
const path = require("path");
|
|
4
|
-
const chalk = require("chalk");
|
|
5
|
-
const { checkGlobalConfig, getGlobalConfig, checkforjvcs } = require("./utility");
|
|
6
|
-
|
|
7
|
-
function removeHashesForFolder(hashData,folderPath) {
|
|
8
|
-
|
|
9
|
-
for(const key of Object.keys(hashData)) {
|
|
10
|
-
if(key.startsWith(folderPath+path.sep)) {
|
|
11
|
-
delete hashData[key]
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
async function unstageCmd(paths) {
|
|
17
|
-
|
|
18
|
-
if(!paths || paths.length === 0) {
|
|
19
|
-
console.log(chalk.yellow("Please specify files or folders to unstage."));
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if(!checkGlobalConfig()) {
|
|
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
|
-
const configData = getGlobalConfig();
|
|
30
|
-
if(!configData) {
|
|
31
|
-
console.log(chalk.red("No existing session found. Please login or signup."));
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if(!checkforjvcs()) {
|
|
36
|
-
console.log(chalk.red("Repository is not initialized or is deleted."));
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const repoPath = path.join(process.cwd(), ".jvcs");
|
|
41
|
-
const stagingPath = path.join(repoPath, "staging");
|
|
42
|
-
const hashPath = path.join(stagingPath, "jvcs_hashcode.json");
|
|
43
|
-
|
|
44
|
-
if(!fssync.existsSync(stagingPath)) {
|
|
45
|
-
console.log(chalk.yellow("Nothing is staged yet."));
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const stagedItems = fssync.readdirSync(stagingPath).filter((item)=> item !== "jvcs_hashcode.json")
|
|
50
|
-
if(stagedItems.length === 0) {
|
|
51
|
-
console.log(chalk.yellow("Staging area is empty. Nothing to unstage."));
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
let hashData = {};
|
|
56
|
-
if(fssync.existsSync(hashPath)) {
|
|
57
|
-
hashData = JSON.parse(await fs.readFile(hashPath, "utf-8"));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if(paths.length === 1 && paths[0] === ".") {
|
|
61
|
-
await fs.rm(stagingPath, {recursive: true, force: true})
|
|
62
|
-
await fs.mkdir(stagingPath, {recursive: true})
|
|
63
|
-
console.log(chalk.cyan("Unstaged all files and folders."));
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const targets = paths.map((p) => path.resolve(process.cwd(), p));
|
|
68
|
-
|
|
69
|
-
for(const target of targets) {
|
|
70
|
-
|
|
71
|
-
const stagedTarget = path.join(stagingPath, path.relative(process.cwd(),target))
|
|
72
|
-
|
|
73
|
-
if(!fssync.existsSync(stagedTarget)) {
|
|
74
|
-
console.log(chalk.yellow(`Not found in staging: ${path.relative(process.cwd(), target)}`));
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const stats = await fs.stat(stagedTarget);
|
|
79
|
-
|
|
80
|
-
if(stats.isDirectory()) {
|
|
81
|
-
await fs.rm(stagedTarget, {recursive: true, force: true})
|
|
82
|
-
removeHashesForFolder(hashData,path.relative(process.cwd(),target))
|
|
83
|
-
console.log(chalk.cyan(`Unstaged folder: ${path.relative(process.cwd(), target)}`));
|
|
84
|
-
}
|
|
85
|
-
else if(stats.isFile()) {
|
|
86
|
-
await fs.rm(stagedTarget)
|
|
87
|
-
delete hashData[path.relative(process.cwd(),target)]
|
|
88
|
-
console.log(chalk.green(`Unstaged file: ${path.relative(process.cwd(), target)}`));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
await fs.writeFile(hashPath, JSON.stringify(hashData, null, 2));
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
module.exports = unstageCmd
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
const fs = require("fs")
|
|
2
|
-
const path = require("path")
|
|
3
|
-
|
|
4
|
-
const config = path.join(require("os").homedir(),".jvcs","config.json")
|
|
5
|
-
|
|
6
|
-
function checkGlobalConfig() {
|
|
7
|
-
return fs.existsSync(config)
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function getGlobalConfig() {
|
|
11
|
-
if(checkGlobalConfig()) {
|
|
12
|
-
const configData = JSON.parse(fs.readFileSync(config,"utf-8"))
|
|
13
|
-
return configData
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return null
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function checkforjvcs() {
|
|
20
|
-
const jvcsPath = path.join(process.cwd(),".jvcs")
|
|
21
|
-
return fs.existsSync(jvcsPath)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
module.exports = {
|
|
25
|
-
checkGlobalConfig,
|
|
26
|
-
getGlobalConfig,
|
|
27
|
-
checkforjvcs
|
|
28
|
-
}
|