@rerout/cli 0.1.0 → 0.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/README.md +4 -2
- package/dist/cli.js +38 -0
- package/dist/commands/tags.d.ts +19 -0
- package/dist/commands/tags.js +44 -0
- package/dist/core/format.d.ts +3 -1
- package/dist/core/format.js +15 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -39,6 +39,10 @@ rerout webhooks ls
|
|
|
39
39
|
rerout webhooks create --name "Orders" --url https://example.com/hook \
|
|
40
40
|
--events link.created,link.clicked
|
|
41
41
|
rerout webhooks rm wh_...
|
|
42
|
+
rerout tags ls # tags with link counts
|
|
43
|
+
rerout tags create "Spring 2026" --color teal
|
|
44
|
+
rerout tags update tag_... --name "Spring '26"
|
|
45
|
+
rerout tags rm tag_...
|
|
42
46
|
```
|
|
43
47
|
|
|
44
48
|
Add `--json` to any command for raw, machine-readable output.
|
|
@@ -56,8 +60,6 @@ The reusable pieces (config, client factory, formatting) are exported from
|
|
|
56
60
|
`@rerout/cli/core` so other surfaces — like the planned Raycast extension — can
|
|
57
61
|
share one engine instead of re-implementing auth and rendering.
|
|
58
62
|
|
|
59
|
-
> Note: tag management is not yet exposed here; it lands once `@rerout/sdk` adds
|
|
60
|
-
> a `tags` namespace for the `/v1/projects/me/tags` endpoints.
|
|
61
63
|
|
|
62
64
|
## Publishing
|
|
63
65
|
|
package/dist/cli.js
CHANGED
|
@@ -8,6 +8,7 @@ import { createLink, getLink, listLinks, removeLink, updateLink, } from './comma
|
|
|
8
8
|
import { linkStats, projectStats, whoami } from './commands/project.js';
|
|
9
9
|
import { qr } from './commands/qr.js';
|
|
10
10
|
import { createWebhook, listWebhooks, removeWebhook } from './commands/webhooks.js';
|
|
11
|
+
import { createTag, listTags, removeTag, updateTag } from './commands/tags.js';
|
|
11
12
|
const program = new Command();
|
|
12
13
|
program
|
|
13
14
|
.name('rerout')
|
|
@@ -152,6 +153,43 @@ webhooks
|
|
|
152
153
|
.action(async (endpointId, opts) => {
|
|
153
154
|
await removeWebhook(createClient(), endpointId, opts, consoleIO);
|
|
154
155
|
});
|
|
156
|
+
const tags = program.command('tags').description('Manage project tags.');
|
|
157
|
+
tags
|
|
158
|
+
.command('ls')
|
|
159
|
+
.alias('list')
|
|
160
|
+
.description('List tags with their link counts.')
|
|
161
|
+
.option('--json', 'Output raw JSON')
|
|
162
|
+
.action(async (opts) => {
|
|
163
|
+
await listTags(createClient(), opts, consoleIO);
|
|
164
|
+
});
|
|
165
|
+
tags
|
|
166
|
+
.command('create')
|
|
167
|
+
.description('Create a tag.')
|
|
168
|
+
.argument('<name>', 'Tag name')
|
|
169
|
+
.option('--color <color>', 'Tag color (server validates; defaults to teal)')
|
|
170
|
+
.option('--json', 'Output raw JSON')
|
|
171
|
+
.action(async (name, opts) => {
|
|
172
|
+
await createTag(createClient(), name, opts, consoleIO);
|
|
173
|
+
});
|
|
174
|
+
tags
|
|
175
|
+
.command('update')
|
|
176
|
+
.description('Update a tag.')
|
|
177
|
+
.argument('<tag_id>', 'Tag id')
|
|
178
|
+
.option('--name <name>', 'New tag name')
|
|
179
|
+
.option('--color <color>', 'New tag color')
|
|
180
|
+
.option('--json', 'Output raw JSON')
|
|
181
|
+
.action(async (tagId, opts) => {
|
|
182
|
+
await updateTag(createClient(), tagId, opts, consoleIO);
|
|
183
|
+
});
|
|
184
|
+
tags
|
|
185
|
+
.command('rm')
|
|
186
|
+
.alias('delete')
|
|
187
|
+
.description('Delete a tag.')
|
|
188
|
+
.argument('<tag_id>', 'Tag id')
|
|
189
|
+
.option('--json', 'Output raw JSON')
|
|
190
|
+
.action(async (tagId, opts) => {
|
|
191
|
+
await removeTag(createClient(), tagId, opts, consoleIO);
|
|
192
|
+
});
|
|
155
193
|
async function main() {
|
|
156
194
|
try {
|
|
157
195
|
await program.parseAsync(process.argv);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Rerout } from '@rerout/sdk';
|
|
2
|
+
import { type IO } from '../core/format.js';
|
|
3
|
+
export declare function listTags(client: Rerout, opts: {
|
|
4
|
+
json?: boolean;
|
|
5
|
+
}, io: IO): Promise<void>;
|
|
6
|
+
export interface CreateTagOptions {
|
|
7
|
+
color?: string;
|
|
8
|
+
json?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function createTag(client: Rerout, name: string, opts: CreateTagOptions, io: IO): Promise<void>;
|
|
11
|
+
export interface UpdateTagOptions {
|
|
12
|
+
name?: string;
|
|
13
|
+
color?: string;
|
|
14
|
+
json?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function updateTag(client: Rerout, tagId: string, opts: UpdateTagOptions, io: IO): Promise<void>;
|
|
17
|
+
export declare function removeTag(client: Rerout, tagId: string, opts: {
|
|
18
|
+
json?: boolean;
|
|
19
|
+
}, io: IO): Promise<void>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { formatTagsTable } from '../core/format.js';
|
|
2
|
+
export async function listTags(client, opts, io) {
|
|
3
|
+
const result = await client.tags.list();
|
|
4
|
+
if (opts.json) {
|
|
5
|
+
io.json(result);
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
io.out(formatTagsTable(result.tags));
|
|
9
|
+
}
|
|
10
|
+
export async function createTag(client, name, opts, io) {
|
|
11
|
+
const input = { name };
|
|
12
|
+
if (opts.color !== undefined)
|
|
13
|
+
input.color = opts.color;
|
|
14
|
+
const tag = await client.tags.create(input);
|
|
15
|
+
if (opts.json) {
|
|
16
|
+
io.json(tag);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
io.out(`Created ${tag.name} (${tag.id})`);
|
|
20
|
+
}
|
|
21
|
+
export async function updateTag(client, tagId, opts, io) {
|
|
22
|
+
const input = {};
|
|
23
|
+
if (opts.name !== undefined)
|
|
24
|
+
input.name = opts.name;
|
|
25
|
+
if (opts.color !== undefined)
|
|
26
|
+
input.color = opts.color;
|
|
27
|
+
if (input.name === undefined && input.color === undefined) {
|
|
28
|
+
throw new Error('Nothing to update. Pass at least one of --name or --color.');
|
|
29
|
+
}
|
|
30
|
+
const tag = await client.tags.update(tagId, input);
|
|
31
|
+
if (opts.json) {
|
|
32
|
+
io.json(tag);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
io.out(`Updated ${tag.name} (${tag.id})`);
|
|
36
|
+
}
|
|
37
|
+
export async function removeTag(client, tagId, opts, io) {
|
|
38
|
+
const result = await client.tags.delete(tagId);
|
|
39
|
+
if (opts.json) {
|
|
40
|
+
io.json(result);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
io.out(result.deleted ? `Deleted ${tagId}.` : `Nothing deleted for ${tagId}.`);
|
|
44
|
+
}
|
package/dist/core/format.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Link } from '@rerout/sdk';
|
|
1
|
+
import type { Link, TagSummary } from '@rerout/sdk';
|
|
2
2
|
/** Sink for command output so commands stay testable (no direct console use). */
|
|
3
3
|
export interface IO {
|
|
4
4
|
out(line: string): void;
|
|
@@ -13,3 +13,5 @@ export declare function formatTimestamp(seconds: number | null | undefined): str
|
|
|
13
13
|
export declare function formatLinkLine(link: Link): string;
|
|
14
14
|
/** Compact, aligned table of links for `rerout ls`. */
|
|
15
15
|
export declare function formatLinksTable(links: Link[]): string;
|
|
16
|
+
/** Compact, aligned table of tags for `rerout tags ls`. */
|
|
17
|
+
export declare function formatTagsTable(tags: TagSummary[]): string;
|
package/dist/core/format.js
CHANGED
|
@@ -33,3 +33,18 @@ export function formatLinksTable(links) {
|
|
|
33
33
|
function truncate(value, max) {
|
|
34
34
|
return value.length > max ? `${value.slice(0, max - 1)}…` : value;
|
|
35
35
|
}
|
|
36
|
+
/** Compact, aligned table of tags for `rerout tags ls`. */
|
|
37
|
+
export function formatTagsTable(tags) {
|
|
38
|
+
if (tags.length === 0)
|
|
39
|
+
return 'No tags yet.';
|
|
40
|
+
const rows = tags.map((t) => [
|
|
41
|
+
t.name,
|
|
42
|
+
t.color,
|
|
43
|
+
String(t.link_count),
|
|
44
|
+
t.id,
|
|
45
|
+
]);
|
|
46
|
+
const headers = ['NAME', 'COLOR', 'LINKS', 'ID'];
|
|
47
|
+
const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => r[i].length)));
|
|
48
|
+
const render = (cells) => cells.map((c, i) => c.padEnd(widths[i])).join(' ').trimEnd();
|
|
49
|
+
return [render(headers), ...rows.map(render)].join('\n');
|
|
50
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rerout/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Command-line interface for Rerout — branded short links, QR codes, and analytics from your terminal.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"cli"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@rerout/sdk": "^0.
|
|
41
|
+
"@rerout/sdk": "^0.5.0",
|
|
42
42
|
"commander": "^12.1.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|