@tinyurl-ca/cli 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 +139 -0
- package/bin/cli.js +68 -0
- package/dist/commands.d.ts +12 -0
- package/dist/commands.js +162 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# TinyURL.ca CLI
|
|
2
|
+
|
|
3
|
+
Command-line tool for creating and managing short links from your terminal.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @tinyurl-ca/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### 1. Configure your API key
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
tinyurl config --key YOUR_API_KEY
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Get your API key from https://tinyurl.ca/dashboard/settings
|
|
20
|
+
|
|
21
|
+
### 2. Shorten a URL
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
tinyurl shorten https://example.com
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Commands
|
|
28
|
+
|
|
29
|
+
### `config`
|
|
30
|
+
Configure your API key
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
tinyurl config --key YOUR_API_KEY
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### `shorten`
|
|
37
|
+
Create a new short link
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Basic usage
|
|
41
|
+
tinyurl shorten https://example.com
|
|
42
|
+
|
|
43
|
+
# Custom short code
|
|
44
|
+
tinyurl shorten https://example.com --custom my-link
|
|
45
|
+
|
|
46
|
+
# Add title
|
|
47
|
+
tinyurl shorten https://example.com --title "My Website"
|
|
48
|
+
|
|
49
|
+
# Set expiration (30 days)
|
|
50
|
+
tinyurl shorten https://example.com --expires 2592000
|
|
51
|
+
|
|
52
|
+
# Show QR code
|
|
53
|
+
tinyurl shorten https://example.com --qr
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### `list`
|
|
57
|
+
List your short links
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# List 20 most recent links
|
|
61
|
+
tinyurl list
|
|
62
|
+
|
|
63
|
+
# List 50 links
|
|
64
|
+
tinyurl list --limit 50
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### `get`
|
|
68
|
+
Get details of a specific link
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
tinyurl get LINK_ID
|
|
72
|
+
|
|
73
|
+
# Show with QR code
|
|
74
|
+
tinyurl get LINK_ID --qr
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### `delete`
|
|
78
|
+
Delete a short link
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
tinyurl delete LINK_ID
|
|
82
|
+
|
|
83
|
+
# Alias
|
|
84
|
+
tinyurl rm LINK_ID
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### `stats`
|
|
88
|
+
Get analytics for a link
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
tinyurl stats LINK_ID
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Options
|
|
95
|
+
|
|
96
|
+
| Option | Description |
|
|
97
|
+
|--------|-------------|
|
|
98
|
+
| `-k, --key <apiKey>` | Your API key |
|
|
99
|
+
| `-c, --custom <code>` | Custom short code |
|
|
100
|
+
| `-t, --title <title>` | Link title |
|
|
101
|
+
| `-e, --expires <seconds>` | Expiration time in seconds |
|
|
102
|
+
| `-q, --qr` | Show QR code |
|
|
103
|
+
| `-l, --limit <number>` | Number of items to display |
|
|
104
|
+
|
|
105
|
+
## Examples
|
|
106
|
+
|
|
107
|
+
### Create a link with custom code
|
|
108
|
+
```bash
|
|
109
|
+
tinyurl shorten https://mywebsite.com --custom promo2024
|
|
110
|
+
# → https://tinyurl.ca/promo2024
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Create temporary link (expires in 1 hour)
|
|
114
|
+
```bash
|
|
115
|
+
tinyurl shorten https://example.com --expires 3600
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### List last 100 links
|
|
119
|
+
```bash
|
|
120
|
+
tinyurl list --limit 100
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Environment Variables
|
|
124
|
+
|
|
125
|
+
You can also set your API key via environment variable:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
export TINYURL_API_KEY=your_api_key_here
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## License
|
|
132
|
+
|
|
133
|
+
MIT
|
|
134
|
+
|
|
135
|
+
## Support
|
|
136
|
+
|
|
137
|
+
- Documentation: https://tinyurl.ca/docs
|
|
138
|
+
- Issues: https://github.com/raj-iwt/tinyurl-cli/issues
|
|
139
|
+
- Email: support@tinyurl.ca
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { readFileSync } from 'fs';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { dirname, join } from 'path';
|
|
6
|
+
import * as commands from '../dist/commands.js';
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
|
|
11
|
+
const { version } = packageJson;
|
|
12
|
+
|
|
13
|
+
const program = new Command();
|
|
14
|
+
|
|
15
|
+
program
|
|
16
|
+
.name('tinyurl')
|
|
17
|
+
.description('TinyURL.ca CLI - Create and manage short links from your terminal')
|
|
18
|
+
.version(version);
|
|
19
|
+
|
|
20
|
+
// Configure API key
|
|
21
|
+
program
|
|
22
|
+
.command('config')
|
|
23
|
+
.description('Configure your API key')
|
|
24
|
+
.option('-k, --key <apiKey>', 'Your TinyURL.ca API key')
|
|
25
|
+
.action(commands.config);
|
|
26
|
+
|
|
27
|
+
// Create a short link
|
|
28
|
+
program
|
|
29
|
+
.command('shorten')
|
|
30
|
+
.description('Create a new short link')
|
|
31
|
+
.argument('<url>', 'URL to shorten')
|
|
32
|
+
.option('-c, --custom <code>', 'Custom short code')
|
|
33
|
+
.option('-t, --title <title>', 'Link title')
|
|
34
|
+
.option('-e, --expires <seconds>', 'Expiration time in seconds')
|
|
35
|
+
.option('-q, --qr', 'Show QR code')
|
|
36
|
+
.action(commands.shorten);
|
|
37
|
+
|
|
38
|
+
// List all links
|
|
39
|
+
program
|
|
40
|
+
.command('list')
|
|
41
|
+
.description('List your short links')
|
|
42
|
+
.option('-l, --limit <number>', 'Number of links to display', '20')
|
|
43
|
+
.action(commands.list);
|
|
44
|
+
|
|
45
|
+
// Get link details
|
|
46
|
+
program
|
|
47
|
+
.command('get')
|
|
48
|
+
.description('Get details of a specific link')
|
|
49
|
+
.argument('<id>', 'Link ID or short code')
|
|
50
|
+
.option('-q, --qr', 'Show QR code')
|
|
51
|
+
.action(commands.get);
|
|
52
|
+
|
|
53
|
+
// Delete a link
|
|
54
|
+
program
|
|
55
|
+
.command('delete')
|
|
56
|
+
.alias('rm')
|
|
57
|
+
.description('Delete a short link')
|
|
58
|
+
.argument('<id>', 'Link ID to delete')
|
|
59
|
+
.action(commands.deleteLink);
|
|
60
|
+
|
|
61
|
+
// Get link analytics
|
|
62
|
+
program
|
|
63
|
+
.command('stats')
|
|
64
|
+
.description('Get analytics for a link')
|
|
65
|
+
.argument('<id>', 'Link ID or short code')
|
|
66
|
+
.action(commands.stats);
|
|
67
|
+
|
|
68
|
+
program.parse();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function config(options: {
|
|
2
|
+
key?: string;
|
|
3
|
+
}): Promise<void>;
|
|
4
|
+
export declare function shorten(url: string, options: any): Promise<void>;
|
|
5
|
+
export declare function list(options: {
|
|
6
|
+
limit: string;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
export declare function get(id: string, options: {
|
|
9
|
+
qr?: boolean;
|
|
10
|
+
}): Promise<void>;
|
|
11
|
+
export declare function deleteLink(id: string): Promise<void>;
|
|
12
|
+
export declare function stats(id: string): Promise<void>;
|
package/dist/commands.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import Conf from 'conf';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import Table from 'cli-table3';
|
|
6
|
+
import qrcode from 'qrcode-terminal';
|
|
7
|
+
const store = new Conf({ projectName: 'tinyurl-cli' });
|
|
8
|
+
const API_BASE = 'https://tinyurl.ca/api/v1';
|
|
9
|
+
// Helper to get API client
|
|
10
|
+
function getApiClient() {
|
|
11
|
+
const apiKey = store.get('apiKey');
|
|
12
|
+
if (!apiKey) {
|
|
13
|
+
console.log(chalk.red('❌ API key not configured'));
|
|
14
|
+
console.log(chalk.yellow('Run: tinyurl config --key YOUR_API_KEY'));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
return axios.create({
|
|
18
|
+
baseURL: API_BASE,
|
|
19
|
+
headers: {
|
|
20
|
+
'X-API-Key': apiKey,
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// Configure API key
|
|
26
|
+
export async function config(options) {
|
|
27
|
+
if (options.key) {
|
|
28
|
+
store.set('apiKey', options.key);
|
|
29
|
+
console.log(chalk.green('✓ API key configured successfully'));
|
|
30
|
+
console.log(chalk.gray('You can now use the CLI to create short links'));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const currentKey = store.get('apiKey');
|
|
34
|
+
if (currentKey) {
|
|
35
|
+
console.log(chalk.blue('Current API key:'), chalk.gray(currentKey.substring(0, 20) + '...'));
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
console.log(chalk.yellow('No API key configured'));
|
|
39
|
+
console.log(chalk.gray('Run: tinyurl config --key YOUR_API_KEY'));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Shorten a URL
|
|
44
|
+
export async function shorten(url, options) {
|
|
45
|
+
const spinner = ora('Creating short link...').start();
|
|
46
|
+
try {
|
|
47
|
+
const api = getApiClient();
|
|
48
|
+
const response = await api.post('/links', {
|
|
49
|
+
url,
|
|
50
|
+
customCode: options.custom,
|
|
51
|
+
title: options.title,
|
|
52
|
+
expiresIn: options.expires ? parseInt(options.expires) : null,
|
|
53
|
+
});
|
|
54
|
+
spinner.succeed('Short link created!');
|
|
55
|
+
const { data } = response.data;
|
|
56
|
+
console.log('');
|
|
57
|
+
console.log(chalk.green.bold('✓ Success!'));
|
|
58
|
+
console.log('');
|
|
59
|
+
console.log(chalk.cyan('Short URL:'), chalk.bold.underline(data.shortUrl));
|
|
60
|
+
console.log(chalk.gray('Original:'), data.originalUrl);
|
|
61
|
+
if (data.title) {
|
|
62
|
+
console.log(chalk.gray('Title:'), data.title);
|
|
63
|
+
}
|
|
64
|
+
console.log(chalk.gray('Created:'), new Date(data.createdAt).toLocaleString());
|
|
65
|
+
if (options.qr) {
|
|
66
|
+
console.log('');
|
|
67
|
+
qrcode.generate(data.shortUrl, { small: true });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
spinner.fail('Failed to create short link');
|
|
72
|
+
console.log(chalk.red('Error:'), error.response?.data?.error || error.message);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// List links
|
|
77
|
+
export async function list(options) {
|
|
78
|
+
const spinner = ora('Fetching your links...').start();
|
|
79
|
+
try {
|
|
80
|
+
const api = getApiClient();
|
|
81
|
+
const response = await api.get('/links', {
|
|
82
|
+
params: { limit: options.limit }
|
|
83
|
+
});
|
|
84
|
+
spinner.stop();
|
|
85
|
+
const { data } = response.data;
|
|
86
|
+
if (data.length === 0) {
|
|
87
|
+
console.log(chalk.yellow('No links found'));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const table = new Table({
|
|
91
|
+
head: ['Short Code', 'Original URL', 'Clicks', 'Created'].map(h => chalk.cyan(h)),
|
|
92
|
+
colWidths: [15, 50, 10, 20],
|
|
93
|
+
});
|
|
94
|
+
data.forEach((link) => {
|
|
95
|
+
table.push([
|
|
96
|
+
chalk.bold(link.shortCode),
|
|
97
|
+
link.originalUrl.substring(0, 47) + '...',
|
|
98
|
+
link.clicks.toString(),
|
|
99
|
+
new Date(link.createdAt).toLocaleDateString(),
|
|
100
|
+
]);
|
|
101
|
+
});
|
|
102
|
+
console.log('');
|
|
103
|
+
console.log(table.toString());
|
|
104
|
+
console.log('');
|
|
105
|
+
console.log(chalk.gray(`Showing ${data.length} links`));
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
spinner.fail('Failed to fetch links');
|
|
109
|
+
console.log(chalk.red('Error:'), error.response?.data?.error || error.message);
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Get link details
|
|
114
|
+
export async function get(id, options) {
|
|
115
|
+
const spinner = ora('Fetching link details...').start();
|
|
116
|
+
try {
|
|
117
|
+
const api = getApiClient();
|
|
118
|
+
const response = await api.get(`/links/${id}`);
|
|
119
|
+
spinner.succeed('Link found!');
|
|
120
|
+
const { data } = response.data;
|
|
121
|
+
console.log('');
|
|
122
|
+
console.log(chalk.cyan.bold('Link Details'));
|
|
123
|
+
console.log('');
|
|
124
|
+
console.log(chalk.gray('ID:'), data.id);
|
|
125
|
+
console.log(chalk.gray('Short Code:'), chalk.bold(data.shortCode));
|
|
126
|
+
console.log(chalk.gray('Short URL:'), chalk.bold.underline(data.shortUrl));
|
|
127
|
+
console.log(chalk.gray('Original URL:'), data.originalUrl);
|
|
128
|
+
if (data.title) {
|
|
129
|
+
console.log(chalk.gray('Title:'), data.title);
|
|
130
|
+
}
|
|
131
|
+
console.log(chalk.gray('Clicks:'), chalk.bold(data.clicks));
|
|
132
|
+
console.log(chalk.gray('Created:'), new Date(data.createdAt).toLocaleString());
|
|
133
|
+
if (options.qr) {
|
|
134
|
+
console.log('');
|
|
135
|
+
qrcode.generate(data.shortUrl, { small: true });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
spinner.fail('Failed to fetch link');
|
|
140
|
+
console.log(chalk.red('Error:'), error.response?.data?.error || error.message);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Delete link
|
|
145
|
+
export async function deleteLink(id) {
|
|
146
|
+
const spinner = ora('Deleting link...').start();
|
|
147
|
+
try {
|
|
148
|
+
const api = getApiClient();
|
|
149
|
+
await api.delete(`/links/${id}`);
|
|
150
|
+
spinner.succeed('Link deleted successfully!');
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
spinner.fail('Failed to delete link');
|
|
154
|
+
console.log(chalk.red('Error:'), error.response?.data?.error || error.message);
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Get stats (placeholder)
|
|
159
|
+
export async function stats(id) {
|
|
160
|
+
console.log(chalk.yellow('Analytics feature coming soon!'));
|
|
161
|
+
console.log(chalk.gray('Use the web dashboard at https://tinyurl.ca/dashboard for detailed analytics'));
|
|
162
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tinyurl-ca/cli",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Command-line tool for TinyURL.ca - create and manage short links from your terminal",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"tinyurl": "./bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "dist/index.js",
|
|
10
|
+
"types": "dist/index.d.ts",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"url-shortener",
|
|
17
|
+
"tinyurl",
|
|
18
|
+
"cli",
|
|
19
|
+
"short-links",
|
|
20
|
+
"tiny url canada"
|
|
21
|
+
],
|
|
22
|
+
"author": "TinyURL.ca",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"commander": "^11.1.0",
|
|
26
|
+
"axios": "^1.6.0",
|
|
27
|
+
"chalk": "^5.3.0",
|
|
28
|
+
"ora": "^8.0.1",
|
|
29
|
+
"conf": "^12.0.0",
|
|
30
|
+
"cli-table3": "^0.6.3",
|
|
31
|
+
"qrcode-terminal": "^0.12.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^20.10.0",
|
|
35
|
+
"typescript": "^5.3.0"
|
|
36
|
+
},
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/raj-iwt/linksnap.git",
|
|
40
|
+
"directory": "cli"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://tinyurl.ca/docs"
|
|
43
|
+
}
|