@verbatims/cli 0.1.16 → 0.1.17
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 +6 -0
- package/package.json +1 -1
- package/src/commands/quotes.ts +135 -5
package/README.md
CHANGED
|
@@ -23,6 +23,12 @@ verbatims quotes list --language fr --limit 10
|
|
|
23
23
|
verbatims quotes list --reference 42
|
|
24
24
|
verbatims quotes get 123 --format json
|
|
25
25
|
|
|
26
|
+
# Manage provenance (moderator/admin API key)
|
|
27
|
+
verbatims quotes attributions list 123
|
|
28
|
+
verbatims quotes attributions create 123 --author-id 1 --reference-id 2 --status manually_verified --primary
|
|
29
|
+
verbatims quotes sources list 123
|
|
30
|
+
verbatims quotes sources create 123 --source-type book --source-url https://example.com/edition --status externally_verified
|
|
31
|
+
|
|
26
32
|
# Create a quote with a source
|
|
27
33
|
verbatims quotes create --source-type book --source-url https://example.com/edition
|
|
28
34
|
|
package/package.json
CHANGED
package/src/commands/quotes.ts
CHANGED
|
@@ -84,7 +84,16 @@ export function registerQuotesCommand(program: Command) {
|
|
|
84
84
|
const referenceId = options.referenceId ? Number(options.referenceId) : undefined
|
|
85
85
|
|
|
86
86
|
const { data } = await withSpinner('Creating quote', () =>
|
|
87
|
-
client.quotes.create({
|
|
87
|
+
client.quotes.create({
|
|
88
|
+
content: name as string,
|
|
89
|
+
name: name as string,
|
|
90
|
+
language: language as string,
|
|
91
|
+
provenance: {
|
|
92
|
+
author_id: authorId,
|
|
93
|
+
reference_id: referenceId,
|
|
94
|
+
source: options.sourceType ? { source_type: options.sourceType, source_url: options.sourceUrl } : undefined,
|
|
95
|
+
},
|
|
96
|
+
}),
|
|
88
97
|
format,
|
|
89
98
|
)
|
|
90
99
|
console.log(chalk.green(' Quote created'))
|
|
@@ -107,10 +116,14 @@ export function registerQuotesCommand(program: Command) {
|
|
|
107
116
|
const data_: Record<string, unknown> = {}
|
|
108
117
|
if (options.name) { data_.name = options.name; data_.content = options.name }
|
|
109
118
|
if (options.language) data_.language = options.language
|
|
110
|
-
if (options.authorId !== undefined) data_.
|
|
111
|
-
if (options.referenceId !== undefined) data_.
|
|
112
|
-
if (options.sourceType !== undefined
|
|
113
|
-
|
|
119
|
+
if (options.authorId !== undefined) data_.provenance = { ...(data_.provenance as object), author_id: options.authorId === 'null' ? null : Number(options.authorId) }
|
|
120
|
+
if (options.referenceId !== undefined) data_.provenance = { ...(data_.provenance as object), reference_id: options.referenceId === 'null' ? null : Number(options.referenceId) }
|
|
121
|
+
if (options.sourceType !== undefined || options.sourceUrl !== undefined) {
|
|
122
|
+
data_.provenance = {
|
|
123
|
+
...(data_.provenance as object),
|
|
124
|
+
source: { source_type: options.sourceType ?? 'manual', source_url: options.sourceUrl },
|
|
125
|
+
}
|
|
126
|
+
}
|
|
114
127
|
|
|
115
128
|
const { data } = await withSpinner('Updating quote', () => client.quotes.update(Number(id), data_ as any), format)
|
|
116
129
|
console.log(chalk.green(' Quote updated'))
|
|
@@ -206,6 +219,123 @@ export function registerQuotesCommand(program: Command) {
|
|
|
206
219
|
)
|
|
207
220
|
})
|
|
208
221
|
|
|
222
|
+
quotes
|
|
223
|
+
.command('attributions <action> <quoteId> [attributionId]')
|
|
224
|
+
.description('Manage quote attributions (moderator/admin API key required)')
|
|
225
|
+
.option('--author-id <id>', 'Author ID')
|
|
226
|
+
.option('--reference-id <id>', 'Reference ID')
|
|
227
|
+
.option('--status <status>', 'Verification status')
|
|
228
|
+
.option('--notes <text>', 'Internal notes')
|
|
229
|
+
.option('--primary', 'Set as primary attribution')
|
|
230
|
+
.option('--yes', 'Skip confirmation')
|
|
231
|
+
.action(async (action: string, quoteId: string, attributionId: string | undefined, options: Record<string, any>) => {
|
|
232
|
+
const client = await getClient()
|
|
233
|
+
const format = getFormat(program)
|
|
234
|
+
const id = Number(quoteId)
|
|
235
|
+
|
|
236
|
+
if (action === 'list') {
|
|
237
|
+
const { data } = await withSpinner('Fetching attributions', () => client.quotes.listAttributions(id), format)
|
|
238
|
+
output(data, format)
|
|
239
|
+
return
|
|
240
|
+
}
|
|
241
|
+
if (action === 'create') {
|
|
242
|
+
const { data } = await withSpinner('Creating attribution', () => client.quotes.createAttribution(id, {
|
|
243
|
+
author_id: options.authorId ? Number(options.authorId) : null,
|
|
244
|
+
reference_id: options.referenceId ? Number(options.referenceId) : null,
|
|
245
|
+
status: options.status,
|
|
246
|
+
notes: options.notes,
|
|
247
|
+
is_primary: options.primary,
|
|
248
|
+
}), format)
|
|
249
|
+
output(data, format)
|
|
250
|
+
return
|
|
251
|
+
}
|
|
252
|
+
if (!attributionId) throw new Error('Attribution ID is required')
|
|
253
|
+
const attribution = Number(attributionId)
|
|
254
|
+
if (action === 'update') {
|
|
255
|
+
const data_: Record<string, unknown> = {}
|
|
256
|
+
if (options.authorId !== undefined) data_.author_id = Number(options.authorId)
|
|
257
|
+
if (options.referenceId !== undefined) data_.reference_id = Number(options.referenceId)
|
|
258
|
+
if (options.status !== undefined) data_.status = options.status
|
|
259
|
+
if (options.notes !== undefined) data_.notes = options.notes
|
|
260
|
+
if (options.primary !== undefined) data_.is_primary = options.primary
|
|
261
|
+
const { data } = await withSpinner('Updating attribution', () => client.quotes.updateAttribution(id, attribution, data_), format)
|
|
262
|
+
output(data, format)
|
|
263
|
+
return
|
|
264
|
+
}
|
|
265
|
+
if (action === 'delete') {
|
|
266
|
+
if (!options.yes) {
|
|
267
|
+
const confirmed = await confirm({ message: `Delete attribution #${attribution} from quote #${id}?` })
|
|
268
|
+
if (isCancel(confirmed) || !confirmed) cancel('Cancelled')
|
|
269
|
+
}
|
|
270
|
+
await withSpinner('Deleting attribution', () => client.quotes.deleteAttribution(id, attribution), format)
|
|
271
|
+
console.log(chalk.green(' Attribution deleted'))
|
|
272
|
+
return
|
|
273
|
+
}
|
|
274
|
+
throw new Error('Action must be list, create, update, or delete')
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
quotes
|
|
278
|
+
.command('sources <action> <quoteId> [sourceId]')
|
|
279
|
+
.description('Manage quote sources (moderator/admin API key required)')
|
|
280
|
+
.option('--attribution-id <id>', 'Attribution ID')
|
|
281
|
+
.option('--source-type <type>', 'Source type')
|
|
282
|
+
.option('--source-url <url>', 'Source URL')
|
|
283
|
+
.option('--label <label>', 'Source label')
|
|
284
|
+
.option('--status <status>', 'Verification status')
|
|
285
|
+
.option('--notes <text>', 'Internal notes')
|
|
286
|
+
.option('--primary', 'Set as primary source')
|
|
287
|
+
.option('--yes', 'Skip confirmation')
|
|
288
|
+
.action(async (action: string, quoteId: string, sourceId: string | undefined, options: Record<string, any>) => {
|
|
289
|
+
const client = await getClient()
|
|
290
|
+
const format = getFormat(program)
|
|
291
|
+
const id = Number(quoteId)
|
|
292
|
+
|
|
293
|
+
if (action === 'list') {
|
|
294
|
+
const { data } = await withSpinner('Fetching sources', () => client.quotes.listSources(id), format)
|
|
295
|
+
output(data, format)
|
|
296
|
+
return
|
|
297
|
+
}
|
|
298
|
+
if (action === 'create') {
|
|
299
|
+
if (!options.sourceType) throw new Error('--source-type is required')
|
|
300
|
+
const { data } = await withSpinner('Creating source', () => client.quotes.createSource(id, {
|
|
301
|
+
attribution_id: options.attributionId ? Number(options.attributionId) : null,
|
|
302
|
+
source_type: options.sourceType,
|
|
303
|
+
source_url: options.sourceUrl,
|
|
304
|
+
label: options.label,
|
|
305
|
+
verification_status: options.status,
|
|
306
|
+
notes: options.notes,
|
|
307
|
+
is_primary: options.primary,
|
|
308
|
+
}), format)
|
|
309
|
+
output(data, format)
|
|
310
|
+
return
|
|
311
|
+
}
|
|
312
|
+
if (!sourceId) throw new Error('Source ID is required')
|
|
313
|
+
const source = Number(sourceId)
|
|
314
|
+
if (action === 'update') {
|
|
315
|
+
const data_: Record<string, unknown> = {}
|
|
316
|
+
if (options.attributionId !== undefined) data_.attribution_id = Number(options.attributionId)
|
|
317
|
+
if (options.sourceType !== undefined) data_.source_type = options.sourceType
|
|
318
|
+
if (options.sourceUrl !== undefined) data_.source_url = options.sourceUrl
|
|
319
|
+
if (options.label !== undefined) data_.label = options.label
|
|
320
|
+
if (options.status !== undefined) data_.verification_status = options.status
|
|
321
|
+
if (options.notes !== undefined) data_.notes = options.notes
|
|
322
|
+
if (options.primary !== undefined) data_.is_primary = options.primary
|
|
323
|
+
const { data } = await withSpinner('Updating source', () => client.quotes.updateSource(id, source, data_), format)
|
|
324
|
+
output(data, format)
|
|
325
|
+
return
|
|
326
|
+
}
|
|
327
|
+
if (action === 'delete') {
|
|
328
|
+
if (!options.yes) {
|
|
329
|
+
const confirmed = await confirm({ message: `Delete source #${source} from quote #${id}?` })
|
|
330
|
+
if (isCancel(confirmed) || !confirmed) cancel('Cancelled')
|
|
331
|
+
}
|
|
332
|
+
await withSpinner('Deleting source', () => client.quotes.deleteSource(id, source), format)
|
|
333
|
+
console.log(chalk.green(' Source deleted'))
|
|
334
|
+
return
|
|
335
|
+
}
|
|
336
|
+
throw new Error('Action must be list, create, update, or delete')
|
|
337
|
+
})
|
|
338
|
+
|
|
209
339
|
const tags = quotes.command('tags').description('Manage quote tags')
|
|
210
340
|
|
|
211
341
|
tags
|