@verbatims/cli 0.1.8 → 0.1.10
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/package.json +1 -1
- package/src/commands/quotes.ts +49 -0
- package/src/commands/themes.ts +3 -3
- package/src/index.ts +2 -0
- package/src/utils/client.ts +9 -0
package/package.json
CHANGED
package/src/commands/quotes.ts
CHANGED
|
@@ -195,4 +195,53 @@ export function registerQuotesCommand(program: Command) {
|
|
|
195
195
|
format,
|
|
196
196
|
)
|
|
197
197
|
})
|
|
198
|
+
|
|
199
|
+
const tags = quotes.command('tags').description('Manage quote tags')
|
|
200
|
+
|
|
201
|
+
tags
|
|
202
|
+
.command('list <id>')
|
|
203
|
+
.description('List tags for a quote')
|
|
204
|
+
.action(async (id: string) => {
|
|
205
|
+
const client = await getClient()
|
|
206
|
+
const format = getFormat(program)
|
|
207
|
+
const { data } = await withSpinner('Fetching tags', () => client.quotes.listTags(Number(id)), format)
|
|
208
|
+
output(data, format)
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
tags
|
|
212
|
+
.command('add <id>')
|
|
213
|
+
.description('Add a tag to a quote (by tag ID or name)')
|
|
214
|
+
.option('--tag-id <n>', 'Existing tag ID')
|
|
215
|
+
.option('--name <name>', 'Tag name (creates new tag if admin)')
|
|
216
|
+
.action(async (id: string, options: Record<string, string>) => {
|
|
217
|
+
const client = await getClient()
|
|
218
|
+
const format = getFormat(program)
|
|
219
|
+
|
|
220
|
+
const tagId = options.tagId ? Number(options.tagId) : undefined
|
|
221
|
+
const name = options.name || undefined
|
|
222
|
+
|
|
223
|
+
if (!tagId && !name) {
|
|
224
|
+
console.log(chalk.red(' Provide --tag-id or --name'))
|
|
225
|
+
process.exit(1)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const { data } = await withSpinner('Adding tag', () =>
|
|
229
|
+
client.quotes.addTag(Number(id), { tagId, name }),
|
|
230
|
+
format,
|
|
231
|
+
)
|
|
232
|
+
console.log(chalk.green(' Tag added'))
|
|
233
|
+
output(data, format)
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
tags
|
|
237
|
+
.command('remove <id> <tagId>')
|
|
238
|
+
.description('Remove a tag from a quote')
|
|
239
|
+
.action(async (id: string, tagId: string) => {
|
|
240
|
+
const confirmed = await confirm({ message: `Remove tag #${tagId} from quote #${id}?` })
|
|
241
|
+
if (isCancel(confirmed) || !confirmed) cancel('Cancelled')
|
|
242
|
+
|
|
243
|
+
const client = await getClient()
|
|
244
|
+
await withSpinner('Removing tag', () => client.quotes.removeTag(Number(id), Number(tagId)))
|
|
245
|
+
console.log(chalk.green(` Tag #${tagId} removed`))
|
|
246
|
+
})
|
|
198
247
|
}
|
package/src/commands/themes.ts
CHANGED
|
@@ -213,14 +213,14 @@ export function registerThemesCommand(program: Command) {
|
|
|
213
213
|
})
|
|
214
214
|
|
|
215
215
|
themes
|
|
216
|
-
.command('feed <
|
|
216
|
+
.command('feed <id>')
|
|
217
217
|
.description('Get the curated feed for a theme')
|
|
218
218
|
.option('--language <lang>', 'Language')
|
|
219
|
-
.action(async (
|
|
219
|
+
.action(async (id: string, options: Record<string, string>) => {
|
|
220
220
|
const client = await getClient()
|
|
221
221
|
const format = getFormat(program)
|
|
222
222
|
const { data } = await withSpinner('Fetching theme feed', () =>
|
|
223
|
-
client.themes.getFeed(
|
|
223
|
+
client.themes.getFeed(Number(id), { language: options.language }),
|
|
224
224
|
format,
|
|
225
225
|
)
|
|
226
226
|
if (!data) {
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { Command } from 'commander'
|
|
4
4
|
import { registerCommands } from './commands/index.js'
|
|
5
5
|
import { setSilent } from './utils/spinner.js'
|
|
6
|
+
import pkg from '../package.json' with { type: 'json' }
|
|
6
7
|
|
|
7
8
|
process.on('unhandledRejection', (err) => {
|
|
8
9
|
console.error(err instanceof Error ? err.message : String(err))
|
|
@@ -14,6 +15,7 @@ const program = new Command()
|
|
|
14
15
|
program
|
|
15
16
|
.name('verbatims')
|
|
16
17
|
.description('CLI for the Verbatims quotes API')
|
|
18
|
+
.version(pkg.version)
|
|
17
19
|
.option('--api-key <key>', 'API key (overrides config and env)')
|
|
18
20
|
.option('--format <type>', 'Output format: table|json|plain', 'table')
|
|
19
21
|
.showHelpAfterError()
|
package/src/utils/client.ts
CHANGED
|
@@ -3,6 +3,14 @@ import { loadConfig } from './config.js'
|
|
|
3
3
|
|
|
4
4
|
const DEFAULT_BASE_URL = 'https://verbatims.cc/api/v1'
|
|
5
5
|
|
|
6
|
+
function withCliSource(fetchFn: typeof globalThis.fetch): typeof globalThis.fetch {
|
|
7
|
+
return (input, init) => {
|
|
8
|
+
const headers = new Headers(init?.headers)
|
|
9
|
+
headers.set('x-client-source', 'cli')
|
|
10
|
+
return fetchFn(input, { ...init, headers })
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
6
14
|
export async function getClient(): Promise<VerbatimsClient> {
|
|
7
15
|
const config = await loadConfig()
|
|
8
16
|
const apiKey = process.env.VERBATIMS_API_KEY ?? config.apiKey
|
|
@@ -14,5 +22,6 @@ export async function getClient(): Promise<VerbatimsClient> {
|
|
|
14
22
|
|
|
15
23
|
return new VerbatimsClient(apiKey, {
|
|
16
24
|
baseUrl: process.env.VERBATIMS_BASE_URL ?? config.baseUrl ?? DEFAULT_BASE_URL,
|
|
25
|
+
fetch: withCliSource(globalThis.fetch),
|
|
17
26
|
})
|
|
18
27
|
}
|