charis-cli 1.0.0 → 1.0.1
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/README.md +0 -0
- package/login.js +146 -14
- package/package.json +8 -5
package/README.md
ADDED
|
File without changes
|
package/login.js
CHANGED
|
@@ -1,19 +1,51 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import fetch from "node-fetch";
|
|
2
3
|
import open from "open";
|
|
3
|
-
import
|
|
4
|
+
import promptSync from "prompt-sync";
|
|
5
|
+
import { exec } from "child_process";
|
|
6
|
+
import chalk from "chalk";
|
|
4
7
|
|
|
5
|
-
const
|
|
6
|
-
const question = (q) => new Promise(resolve => rl.question(q, resolve));
|
|
8
|
+
const prompt = promptSync({ sigint: true });
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
// ===== Banner =====
|
|
11
|
+
function printBanner() {
|
|
12
|
+
console.log(chalk.cyanBright(`
|
|
13
|
+
╔══════════════════════════════════════════╗
|
|
14
|
+
║ ║
|
|
15
|
+
║ 🎵 CHARIS SPOTIFY CLI 🎵 ║
|
|
16
|
+
║ ║
|
|
17
|
+
║ Manage your Spotify account ║
|
|
18
|
+
║ directly from the CLI ║
|
|
19
|
+
║ ║
|
|
20
|
+
╚══════════════════════════════════════════╝
|
|
21
|
+
`));
|
|
22
|
+
console.log(chalk.yellowBright("🚀 Welcome! Let's get you logged in.\n"));
|
|
23
|
+
}
|
|
13
24
|
|
|
14
|
-
|
|
15
|
-
|
|
25
|
+
// ===== Input wajib =====
|
|
26
|
+
async function askNonEmpty(promptText, hidden = false) {
|
|
27
|
+
let answer = "";
|
|
28
|
+
do {
|
|
29
|
+
if (hidden) {
|
|
30
|
+
answer = prompt.hide ? prompt.hide(promptText) : prompt(promptText);
|
|
31
|
+
} else {
|
|
32
|
+
answer = prompt(promptText);
|
|
33
|
+
}
|
|
34
|
+
answer = answer.trim();
|
|
35
|
+
if (!answer) console.log(chalk.red("❌ Input cannot be empty. Please try again."));
|
|
36
|
+
} while (!answer);
|
|
37
|
+
return answer;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ===== Login flow =====
|
|
41
|
+
async function loginFlow() {
|
|
42
|
+
printBanner();
|
|
16
43
|
|
|
44
|
+
const userId = await askNonEmpty("Enter your Spotify User ID: ");
|
|
45
|
+
const clientId = await askNonEmpty("Enter your Spotify Client ID: ");
|
|
46
|
+
const clientSecret = await askNonEmpty("Enter your Spotify Client Secret: ", true);
|
|
47
|
+
|
|
48
|
+
const redirectUri = "https://api.charisprod.xyz/v1/spotify/callback";
|
|
17
49
|
const state = Buffer.from(JSON.stringify({ userId, clientId, clientSecret })).toString("base64url");
|
|
18
50
|
|
|
19
51
|
const scope = [
|
|
@@ -31,7 +63,107 @@ const question = (q) => new Promise(resolve => rl.question(q, resolve));
|
|
|
31
63
|
authUrl.searchParams.set("state", state);
|
|
32
64
|
authUrl.searchParams.set("show_dialog", "true");
|
|
33
65
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
console.log("
|
|
37
|
-
|
|
66
|
+
const urlString = authUrl.toString();
|
|
67
|
+
|
|
68
|
+
console.log("\n🔗 Open this URL in your browser if it doesn't open automatically:\n");
|
|
69
|
+
console.log(chalk.green(urlString) + "\n");
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
await open(urlString);
|
|
73
|
+
} catch {
|
|
74
|
+
console.log(chalk.red("⚠️ Could not open browser automatically. Please copy the link above and open manually."));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Prompt uninstall CLI
|
|
78
|
+
const removeChoice = prompt("\nDo you want to remove charis-cli from your system now? [y/N]: ").trim().toLowerCase();
|
|
79
|
+
if (removeChoice === "y" || removeChoice === "yes") {
|
|
80
|
+
console.log("⚠️ Uninstalling charis-cli globally...");
|
|
81
|
+
exec("npm uninstall -g charis-cli", (error, stdout, stderr) => {
|
|
82
|
+
if (error) {
|
|
83
|
+
console.error(`❌ Failed to uninstall: ${error.message}`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (stderr) console.error(stderr);
|
|
87
|
+
console.log("✅ charis-cli has been uninstalled.");
|
|
88
|
+
});
|
|
89
|
+
} else {
|
|
90
|
+
console.log("ℹ️ CLI remains installed. You can run 'charis login' anytime.");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ===== Logout flow =====
|
|
95
|
+
async function logoutFlow() {
|
|
96
|
+
console.log(chalk.cyanBright("\n=== Logout from Spotify (Charis CLI) ===\n"));
|
|
97
|
+
|
|
98
|
+
const userId = prompt("Enter your Spotify User ID to logout: ").trim();
|
|
99
|
+
if (!userId) {
|
|
100
|
+
console.log(chalk.red("❌ User ID cannot be empty."));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const confirm = prompt(
|
|
105
|
+
`⚠️ WARNING: Logging out will delete your Spotify tokens for userId "${userId}"\n` +
|
|
106
|
+
` and you will NO LONGER be able to use our Spotify service.\n` +
|
|
107
|
+
`Are you sure you want to proceed? [y/N]: `
|
|
108
|
+
).trim().toLowerCase();
|
|
109
|
+
if (confirm !== "y" && confirm !== "yes") {
|
|
110
|
+
console.log(chalk.yellow("⚠️ Logout canceled."));
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
const res = await fetch(`https://api.charisprod.xyz/v1/spotify/delete?userId=${userId}`, {
|
|
116
|
+
method: "DELETE",
|
|
117
|
+
headers: { "Content-Type": "application/json" }
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const data = await res.json();
|
|
121
|
+
|
|
122
|
+
if (!res.ok) {
|
|
123
|
+
console.log(chalk.red(`❌ Failed to logout: ${data.error || data.message}`));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
console.log(chalk.green(`✅ ${data.message || "Successfully logged out."}`));
|
|
128
|
+
} catch (err) {
|
|
129
|
+
console.log(chalk.red(`❌ Logout failed: ${err.message}`));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// ===== Remove CLI =====
|
|
134
|
+
async function removeFlow() {
|
|
135
|
+
console.log("⚠️ Uninstalling charis-cli globally...");
|
|
136
|
+
exec("npm uninstall -g charis-cli", (error, stdout, stderr) => {
|
|
137
|
+
if (error) {
|
|
138
|
+
console.error(`❌ Failed to uninstall: ${error.message}`);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (stderr) console.error(stderr);
|
|
142
|
+
console.log("✅ charis-cli has been uninstalled.");
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// ===== Main dispatcher =====
|
|
147
|
+
const subcommand = process.argv[2]?.toLowerCase();
|
|
148
|
+
|
|
149
|
+
switch (subcommand) {
|
|
150
|
+
case "login":
|
|
151
|
+
await loginFlow();
|
|
152
|
+
break;
|
|
153
|
+
case "logout":
|
|
154
|
+
await logoutFlow();
|
|
155
|
+
break;
|
|
156
|
+
case "remove":
|
|
157
|
+
await removeFlow();
|
|
158
|
+
break;
|
|
159
|
+
case undefined:
|
|
160
|
+
console.log(chalk.cyan("\nUsage: charis <command>"));
|
|
161
|
+
console.log(chalk.cyan("Commands:"));
|
|
162
|
+
console.log(chalk.green(" login Login to Spotify"));
|
|
163
|
+
console.log(chalk.green(" logout Logout from Spotify"));
|
|
164
|
+
console.log(chalk.green(" remove Uninstall charis-cli\n"));
|
|
165
|
+
break;
|
|
166
|
+
default:
|
|
167
|
+
console.log(chalk.red(`❌ Unknown command: ${subcommand}`));
|
|
168
|
+
console.log("Use 'charis' to see available commands.");
|
|
169
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "charis-cli",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"main": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"main": "login.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
@@ -10,10 +10,13 @@
|
|
|
10
10
|
"charis": "./login.js"
|
|
11
11
|
},
|
|
12
12
|
"keywords": [],
|
|
13
|
-
"author": "",
|
|
13
|
+
"author": "Charis Production",
|
|
14
14
|
"license": "ISC",
|
|
15
|
-
"description": "",
|
|
15
|
+
"description": "CLI for managing Spotify accounts via Charis API",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"
|
|
17
|
+
"chalk": "^5.6.2",
|
|
18
|
+
"open": "^11.0.0",
|
|
19
|
+
"prompt-sync": "^4.2.0",
|
|
20
|
+
"node-fetch": "^2.7.0"
|
|
18
21
|
}
|
|
19
22
|
}
|