@verbatims/cli 1.0.3 → 1.0.4
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 +9 -0
- package/package.json +5 -2
- package/src/commands/collections.ts +79 -1
package/README.md
CHANGED
|
@@ -42,6 +42,15 @@ verbatims quotes browse
|
|
|
42
42
|
# Search
|
|
43
43
|
verbatims search "love" --type quotes
|
|
44
44
|
|
|
45
|
+
# Manage collections
|
|
46
|
+
verbatims collections list --limit 20
|
|
47
|
+
verbatims collections get 12 --page 1 --limit 20
|
|
48
|
+
verbatims collections create --name "Favorite quotes" --public
|
|
49
|
+
verbatims collections update 12 --name "Reading notes" --private
|
|
50
|
+
verbatims collections add 12 123
|
|
51
|
+
verbatims collections remove 12 123
|
|
52
|
+
verbatims collections delete 12 --yes
|
|
53
|
+
|
|
45
54
|
# Apply a reproducible theme manifest (safe to preview first)
|
|
46
55
|
verbatims themes apply ./theme.json --dry-run
|
|
47
56
|
verbatims themes apply ./theme.json
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@verbatims/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "CLI for the Verbatims quotes API",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": "^22 || ^24"
|
|
8
|
+
},
|
|
6
9
|
"bin": {
|
|
7
10
|
"verbatims": "./bin/verbatims.js"
|
|
8
11
|
},
|
|
@@ -16,7 +19,7 @@
|
|
|
16
19
|
"typecheck": "tsc --noEmit"
|
|
17
20
|
},
|
|
18
21
|
"dependencies": {
|
|
19
|
-
"@verbatims/sdk": "^2.0.
|
|
22
|
+
"@verbatims/sdk": "^2.0.3",
|
|
20
23
|
"@clack/prompts": "^0.10.1",
|
|
21
24
|
"chalk": "^5.4.1",
|
|
22
25
|
"commander": "^13.1.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Command } from 'commander'
|
|
2
|
-
import { text, isCancel, cancel } from '@clack/prompts'
|
|
2
|
+
import { text, isCancel, cancel, confirm } from '@clack/prompts'
|
|
3
3
|
import chalk from 'chalk'
|
|
4
4
|
import { getClient } from '../utils/client.js'
|
|
5
5
|
import { output, type Format } from '../utils/format.js'
|
|
@@ -12,6 +12,39 @@ function getFormat(program: Command): Format {
|
|
|
12
12
|
export function registerCollectionsCommand(program: Command) {
|
|
13
13
|
const collections = program.command('collections').description('Manage collections')
|
|
14
14
|
|
|
15
|
+
collections
|
|
16
|
+
.command('list')
|
|
17
|
+
.description('List collections')
|
|
18
|
+
.option('--page <n>', 'Page number', '1')
|
|
19
|
+
.option('--limit <n>', 'Number of results', '20')
|
|
20
|
+
.action(async (options: Record<string, string>) => {
|
|
21
|
+
const client = await getClient()
|
|
22
|
+
const format = getFormat(program)
|
|
23
|
+
const { data, pagination } = await withSpinner('Fetching collections', () =>
|
|
24
|
+
client.collections.list({ page: Number(options.page), limit: Number(options.limit) }),
|
|
25
|
+
format,
|
|
26
|
+
)
|
|
27
|
+
output(data, format)
|
|
28
|
+
if (pagination && format !== 'json') {
|
|
29
|
+
console.log(chalk.dim(`\nPage ${pagination.page}/${pagination.totalPages} — ${pagination.total} total`))
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
collections
|
|
34
|
+
.command('get <id>')
|
|
35
|
+
.description('Get a collection and its quotes')
|
|
36
|
+
.option('--page <n>', 'Quote page number', '1')
|
|
37
|
+
.option('--limit <n>', 'Quotes per page', '20')
|
|
38
|
+
.action(async (id: string, options: Record<string, string>) => {
|
|
39
|
+
const client = await getClient()
|
|
40
|
+
const format = getFormat(program)
|
|
41
|
+
const { data } = await withSpinner('Fetching collection', () =>
|
|
42
|
+
client.collections.get(Number(id), { page: Number(options.page), limit: Number(options.limit) }),
|
|
43
|
+
format,
|
|
44
|
+
)
|
|
45
|
+
output(data, format)
|
|
46
|
+
})
|
|
47
|
+
|
|
15
48
|
collections
|
|
16
49
|
.command('create')
|
|
17
50
|
.description('Create a collection')
|
|
@@ -33,6 +66,51 @@ export function registerCollectionsCommand(program: Command) {
|
|
|
33
66
|
output(data, format)
|
|
34
67
|
})
|
|
35
68
|
|
|
69
|
+
collections
|
|
70
|
+
.command('update <id>')
|
|
71
|
+
.description('Update a collection')
|
|
72
|
+
.option('--name <name>', 'Collection name')
|
|
73
|
+
.option('--description <text>', 'Description (use an empty value to clear)')
|
|
74
|
+
.option('--public', 'Make collection public')
|
|
75
|
+
.option('--private', 'Make collection private')
|
|
76
|
+
.action(async (id: string, options: Record<string, string | boolean>) => {
|
|
77
|
+
if (options.public && options.private) {
|
|
78
|
+
throw new Error('Choose either --public or --private')
|
|
79
|
+
}
|
|
80
|
+
const data: { name?: string; description?: string | null; is_public?: boolean } = {}
|
|
81
|
+
if (options.name) data.name = options.name as string
|
|
82
|
+
if (options.description !== undefined) data.description = options.description ? options.description as string : null
|
|
83
|
+
if (options.public) data.is_public = true
|
|
84
|
+
if (options.private) data.is_public = false
|
|
85
|
+
if (Object.keys(data).length === 0) {
|
|
86
|
+
throw new Error('Provide at least one field to update')
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const client = await getClient()
|
|
90
|
+
const format = getFormat(program)
|
|
91
|
+
const { data: updated } = await withSpinner('Updating collection', () =>
|
|
92
|
+
client.collections.update(Number(id), data),
|
|
93
|
+
format,
|
|
94
|
+
)
|
|
95
|
+
console.log(chalk.green(' Collection updated'))
|
|
96
|
+
output(updated, format)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
collections
|
|
100
|
+
.command('delete <id>')
|
|
101
|
+
.description('Delete a collection')
|
|
102
|
+
.option('--yes', 'Skip confirmation')
|
|
103
|
+
.action(async (id: string, options: { yes?: boolean }) => {
|
|
104
|
+
if (!options.yes) {
|
|
105
|
+
const confirmed = await confirm({ message: `Delete collection #${id}?` })
|
|
106
|
+
if (isCancel(confirmed) || !confirmed) cancel('Cancelled')
|
|
107
|
+
}
|
|
108
|
+
const client = await getClient()
|
|
109
|
+
const format = getFormat(program)
|
|
110
|
+
await withSpinner('Deleting collection', () => client.collections.delete(Number(id)), format)
|
|
111
|
+
console.log(chalk.green(` Collection #${id} deleted`))
|
|
112
|
+
})
|
|
113
|
+
|
|
36
114
|
collections
|
|
37
115
|
.command('add <collection-id> <quote-id>')
|
|
38
116
|
.description('Add a quote to a collection')
|