qubitlink_cli 1.0.0-dev.1 → 1.0.0-dev.2
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/dist/index.js +70 -16
- package/dist/services/auth.js +16 -3
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -5,11 +5,30 @@ import inquirer from 'inquirer';
|
|
|
5
5
|
import { AuthService } from './services/auth.js';
|
|
6
6
|
import { LinkService } from './services/link.js';
|
|
7
7
|
import { OrgService } from './services/org.js';
|
|
8
|
+
import boxen from 'boxen';
|
|
9
|
+
import ora from 'ora';
|
|
10
|
+
import Table from 'cli-table3';
|
|
8
11
|
const program = new Command();
|
|
12
|
+
const displayHeader = () => {
|
|
13
|
+
const banner = chalk.bold.magenta(`
|
|
14
|
+
____ _ _ _ _ _ _
|
|
15
|
+
/ __ \\ _ _| |__ (_) |_| | (_)_ __ | | __
|
|
16
|
+
| | | || | | | '_ \\ | | __| | | | '_ \\| |/ /
|
|
17
|
+
| |_| || |_| | |_) || | |_| |___| | | | | <
|
|
18
|
+
\\___\\_\\\\ \\__,_|_.__/ |_|\\__|_____|_|_| |_|_|\\_\\
|
|
19
|
+
`);
|
|
20
|
+
console.log(banner);
|
|
21
|
+
console.log(chalk.dim(' Manage your short links from the terminal\n'));
|
|
22
|
+
};
|
|
9
23
|
program
|
|
10
24
|
.name('qubit')
|
|
11
25
|
.description('QubitLink CLI - Manage your short links from the terminal')
|
|
12
|
-
.version('1.0.0');
|
|
26
|
+
.version('1.0.0-dev.1');
|
|
27
|
+
program.hook('preAction', (thisCommand, actionCommand) => {
|
|
28
|
+
if (actionCommand.name() !== 'logout') {
|
|
29
|
+
displayHeader();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
13
32
|
// --- Auth Commands ---
|
|
14
33
|
program
|
|
15
34
|
.command('login')
|
|
@@ -17,9 +36,8 @@ program
|
|
|
17
36
|
.action(async () => {
|
|
18
37
|
try {
|
|
19
38
|
await AuthService.loginFlow();
|
|
20
|
-
console.log(chalk.green('\nLogin successful!'));
|
|
21
39
|
const user = AuthService.getUser();
|
|
22
|
-
console.log(
|
|
40
|
+
console.log(`\nWelcome back, ${chalk.bold.magenta(user.fullname)}! ✨`);
|
|
23
41
|
process.exit(0);
|
|
24
42
|
}
|
|
25
43
|
catch (error) {
|
|
@@ -42,8 +60,19 @@ program
|
|
|
42
60
|
return;
|
|
43
61
|
}
|
|
44
62
|
const activeOrg = AuthService.getActiveOrgId();
|
|
45
|
-
|
|
46
|
-
|
|
63
|
+
const content = [
|
|
64
|
+
`${chalk.cyan('👤 User :')} ${chalk.bold(user.fullname)}`,
|
|
65
|
+
`${chalk.cyan('📧 Email :')} ${user.email}`,
|
|
66
|
+
`${chalk.cyan('🎯 Scope :')} ${activeOrg ? chalk.green(`Organization (${activeOrg})`) : chalk.yellow('Personal')}`
|
|
67
|
+
].join('\n');
|
|
68
|
+
console.log(boxen(content, {
|
|
69
|
+
padding: 1,
|
|
70
|
+
margin: { top: 1, bottom: 1 },
|
|
71
|
+
borderStyle: 'round',
|
|
72
|
+
borderColor: 'magenta',
|
|
73
|
+
title: 'Active Session',
|
|
74
|
+
titleAlignment: 'center'
|
|
75
|
+
}));
|
|
47
76
|
});
|
|
48
77
|
// --- Link Commands ---
|
|
49
78
|
const link = program.command('link').description('Manage short links');
|
|
@@ -56,34 +85,57 @@ link
|
|
|
56
85
|
.option('--sensitive', 'Mark as sensitive content')
|
|
57
86
|
.option('--org <orgId>', 'Create in specific organization')
|
|
58
87
|
.action(async (url, options) => {
|
|
88
|
+
const spinner = ora('Creating link...').start();
|
|
59
89
|
try {
|
|
60
|
-
console.log(chalk.blue('Creating link...'));
|
|
61
90
|
const result = await LinkService.create(url, options);
|
|
62
|
-
|
|
63
|
-
|
|
91
|
+
spinner.succeed(chalk.green('Link created successfully! ✨'));
|
|
92
|
+
const content = [
|
|
93
|
+
`${chalk.cyan('🔗 Short URL :')} ${chalk.bold.magenta(result.data.shortUrl)}`,
|
|
94
|
+
`${chalk.cyan('🌍 Original :')} ${url}`,
|
|
95
|
+
`${chalk.cyan('🆔 Short Code:')} ${result.data.urlKey}`
|
|
96
|
+
].join('\n');
|
|
97
|
+
console.log(boxen(content, {
|
|
98
|
+
padding: 1,
|
|
99
|
+
borderStyle: 'round',
|
|
100
|
+
borderColor: 'cyan',
|
|
101
|
+
title: 'Link Details',
|
|
102
|
+
titleAlignment: 'center'
|
|
103
|
+
}));
|
|
64
104
|
}
|
|
65
105
|
catch (error) {
|
|
66
|
-
|
|
106
|
+
spinner.fail(chalk.red('Failed to create link: ') + (error.response?.data?.message || error.message));
|
|
67
107
|
}
|
|
68
108
|
});
|
|
69
109
|
link
|
|
70
110
|
.command('list')
|
|
71
111
|
.description('List your links')
|
|
72
112
|
.action(async () => {
|
|
113
|
+
const spinner = ora('Fetching links...').start();
|
|
73
114
|
try {
|
|
74
115
|
const result = await LinkService.list();
|
|
75
116
|
const links = result.data || [];
|
|
76
|
-
|
|
117
|
+
spinner.stop();
|
|
77
118
|
if (links.length === 0) {
|
|
78
|
-
console.log('
|
|
119
|
+
console.log(chalk.yellow('\nNo links found in this scope.'));
|
|
79
120
|
return;
|
|
80
121
|
}
|
|
122
|
+
const table = new Table({
|
|
123
|
+
head: [chalk.magenta('Code'), chalk.magenta('Original URL'), chalk.magenta('Clicks')],
|
|
124
|
+
colWidths: [12, 40, 10],
|
|
125
|
+
wordWrap: true,
|
|
126
|
+
style: { head: [], border: [] }
|
|
127
|
+
});
|
|
81
128
|
links.forEach((l) => {
|
|
82
|
-
|
|
129
|
+
table.push([
|
|
130
|
+
chalk.bold(l.urlKey),
|
|
131
|
+
l.originalURL || chalk.dim('[Page]'),
|
|
132
|
+
l.clicks || 0
|
|
133
|
+
]);
|
|
83
134
|
});
|
|
135
|
+
console.log('\n' + table.toString() + '\n');
|
|
84
136
|
}
|
|
85
137
|
catch (error) {
|
|
86
|
-
|
|
138
|
+
spinner.fail(chalk.red('Failed to list links: ') + (error.response?.data?.message || error.message));
|
|
87
139
|
}
|
|
88
140
|
});
|
|
89
141
|
// --- Scope Commands ---
|
|
@@ -91,10 +143,12 @@ const scope = program.command('scope').description('Manage organization or perso
|
|
|
91
143
|
scope
|
|
92
144
|
.action(async () => {
|
|
93
145
|
try {
|
|
146
|
+
const spinner = ora('Fetching available scopes...').start();
|
|
94
147
|
const orgs = await OrgService.list();
|
|
148
|
+
spinner.stop();
|
|
95
149
|
const choices = [
|
|
96
|
-
{ name: 'Personal Mode
|
|
97
|
-
...orgs.map((o) => ({ name: `${o.name} (Organization)`, value: o._id }))
|
|
150
|
+
{ name: `${chalk.yellow('●')} Personal Mode`, value: null },
|
|
151
|
+
...orgs.map((o) => ({ name: `${chalk.cyan('●')} ${o.name} (Organization)`, value: o._id }))
|
|
98
152
|
];
|
|
99
153
|
const { scopeId } = await inquirer.prompt([
|
|
100
154
|
{
|
|
@@ -106,7 +160,7 @@ scope
|
|
|
106
160
|
}
|
|
107
161
|
]);
|
|
108
162
|
AuthService.setActiveOrg(scopeId);
|
|
109
|
-
console.log(chalk.green(`\nActive scope set to: ${chalk.bold(scopeId ? 'Organization' : 'Personal')}
|
|
163
|
+
console.log(chalk.green(`\nActive scope set to: ${chalk.bold(scopeId ? 'Organization' : 'Personal')}! ✨`));
|
|
110
164
|
}
|
|
111
165
|
catch (error) {
|
|
112
166
|
console.error(chalk.red('Failed to manage scope:'), error.response?.data?.message || error.message);
|
package/dist/services/auth.js
CHANGED
|
@@ -4,6 +4,7 @@ import open from 'open';
|
|
|
4
4
|
import http from 'http';
|
|
5
5
|
import { URL } from 'url';
|
|
6
6
|
import { getConfig } from '../config.js';
|
|
7
|
+
import ora from 'ora';
|
|
7
8
|
import { generateAuthResponseHtml } from '../utils/html.js';
|
|
8
9
|
const PORT = 4005;
|
|
9
10
|
const REDIRECT_URI = `http://localhost:${PORT}/callback`;
|
|
@@ -54,17 +55,29 @@ export class AuthService {
|
|
|
54
55
|
finish('An unexpected error occurred during the authentication process. Please try again later.', false, err, 'Unexpected Error');
|
|
55
56
|
}
|
|
56
57
|
});
|
|
58
|
+
const spinner = ora('Opening browser for authentication...').start();
|
|
57
59
|
server.listen(PORT, async () => {
|
|
58
|
-
|
|
60
|
+
spinner.text = chalk.blue('Opening browser for authentication...');
|
|
59
61
|
console.log(chalk.gray(`URL: ${authUrl}\n`));
|
|
60
62
|
try {
|
|
61
63
|
await open(authUrl);
|
|
64
|
+
spinner.text = chalk.yellow('Waiting for authentication in browser...');
|
|
62
65
|
}
|
|
63
66
|
catch (e) {
|
|
64
|
-
|
|
67
|
+
spinner.warn(chalk.yellow('Could not open browser automatically. Please open the link above manually.'));
|
|
68
|
+
spinner.start(chalk.yellow('Waiting for authentication in browser...'));
|
|
65
69
|
}
|
|
66
|
-
console.log(chalk.yellow('Waiting for authentication in browser...'));
|
|
67
70
|
});
|
|
71
|
+
const originalResolve = resolve;
|
|
72
|
+
const originalReject = reject;
|
|
73
|
+
resolve = () => {
|
|
74
|
+
spinner.succeed(chalk.green('Authentication successful!'));
|
|
75
|
+
originalResolve();
|
|
76
|
+
};
|
|
77
|
+
reject = (err) => {
|
|
78
|
+
spinner.fail(chalk.red('Authentication failed: ') + err.message);
|
|
79
|
+
originalReject(err);
|
|
80
|
+
};
|
|
68
81
|
});
|
|
69
82
|
}
|
|
70
83
|
static async exchangeCode(code) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qubitlink_cli",
|
|
3
|
-
"version": "1.0.0-dev.
|
|
3
|
+
"version": "1.0.0-dev.2",
|
|
4
4
|
"description": "CLI tool for QubitLink",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -32,11 +32,14 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@types/open": "^6.1.0",
|
|
34
34
|
"axios": "^1.7.9",
|
|
35
|
+
"boxen": "^8.0.1",
|
|
35
36
|
"chalk": "^5.4.1",
|
|
37
|
+
"cli-table3": "^0.6.5",
|
|
36
38
|
"commander": "^13.1.0",
|
|
37
39
|
"conf": "^13.1.0",
|
|
38
40
|
"inquirer": "^12.3.2",
|
|
39
|
-
"open": "^11.0.0"
|
|
41
|
+
"open": "^11.0.0",
|
|
42
|
+
"ora": "^9.1.0"
|
|
40
43
|
},
|
|
41
44
|
"devDependencies": {
|
|
42
45
|
"@types/chalk": "^2.2.4",
|