@verbatims/cli 1.0.2 → 1.0.3
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 +3 -2
- package/src/commands/themes.ts +40 -0
package/README.md
CHANGED
|
@@ -42,6 +42,10 @@ verbatims quotes browse
|
|
|
42
42
|
# Search
|
|
43
43
|
verbatims search "love" --type quotes
|
|
44
44
|
|
|
45
|
+
# Apply a reproducible theme manifest (safe to preview first)
|
|
46
|
+
verbatims themes apply ./theme.json --dry-run
|
|
47
|
+
verbatims themes apply ./theme.json
|
|
48
|
+
|
|
45
49
|
# List social platforms with queue stats
|
|
46
50
|
verbatims social platforms
|
|
47
51
|
|
|
@@ -58,6 +62,8 @@ verbatims social queue run-now --platform bluesky
|
|
|
58
62
|
verbatims --help
|
|
59
63
|
```
|
|
60
64
|
|
|
65
|
+
Theme manifests use `schema_version: 1`, a stable `slug`, a `name`, and an explicit `filters` array. Optional translations (including homepage copy), language, priority, description, and config are validated before a write. Applying the same manifest reconciles filters by type/value, retaining IDs for unchanged filters; translations reconcile by language, and omitted homepage copy is preserved. Activation and default status are left unchanged. Keep manifests in version control to review theme changes before applying them. See [`examples/themes/quiet-courage.json`](examples/themes/quiet-courage.json).
|
|
66
|
+
|
|
61
67
|
### Social commands
|
|
62
68
|
|
|
63
69
|
```bash
|
package/package.json
CHANGED
package/src/commands/quotes.ts
CHANGED
|
@@ -95,12 +95,13 @@ export function registerQuotesCommand(program: Command) {
|
|
|
95
95
|
}),
|
|
96
96
|
format,
|
|
97
97
|
)
|
|
98
|
-
|
|
98
|
+
const sourceType = options.sourceType
|
|
99
|
+
if (sourceType && data) {
|
|
99
100
|
const primary = data.attributions?.find(attribution => attribution.is_primary)
|
|
100
101
|
if (!primary) throw new Error('The created quote has no primary attribution')
|
|
101
102
|
await withSpinner('Creating source', () => client.quotes.createSource(data.id, {
|
|
102
103
|
attribution_id: primary.id,
|
|
103
|
-
source_type:
|
|
104
|
+
source_type: sourceType,
|
|
104
105
|
source_url: options.sourceUrl,
|
|
105
106
|
is_primary: true,
|
|
106
107
|
}), format)
|
package/src/commands/themes.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { Command } from 'commander'
|
|
2
|
+
import { readFile } from 'node:fs/promises'
|
|
3
|
+
import { resolve } from 'node:path'
|
|
2
4
|
import { text, isCancel, cancel, confirm } from '@clack/prompts'
|
|
3
5
|
import chalk from 'chalk'
|
|
4
6
|
import { getClient } from '../utils/client.js'
|
|
@@ -47,6 +49,44 @@ export function registerThemesCommand(program: Command) {
|
|
|
47
49
|
output(data, format)
|
|
48
50
|
})
|
|
49
51
|
|
|
52
|
+
themes
|
|
53
|
+
.command('apply <file>')
|
|
54
|
+
.description('Create or reconcile a theme from a versioned JSON manifest')
|
|
55
|
+
.option('--dry-run', 'Validate and show the planned operation without changing data')
|
|
56
|
+
.action(async (file: string, options: { dryRun?: boolean }) => {
|
|
57
|
+
const sdk = await import('@verbatims/sdk')
|
|
58
|
+
if (!('parseThemeManifest' in sdk) || typeof sdk.parseThemeManifest !== 'function') {
|
|
59
|
+
throw new Error('Theme manifests require a newer @verbatims/sdk. Update the SDK and try again.')
|
|
60
|
+
}
|
|
61
|
+
const parseThemeManifest = sdk.parseThemeManifest
|
|
62
|
+
const manifest = parseThemeManifest(JSON.parse(await readFile(resolve(file), 'utf8')))
|
|
63
|
+
const client = await getClient()
|
|
64
|
+
if (typeof client.themes.apply !== 'function') {
|
|
65
|
+
throw new Error('Theme manifests require a newer @verbatims/sdk. Update the SDK and try again.')
|
|
66
|
+
}
|
|
67
|
+
const format = getFormat(program)
|
|
68
|
+
|
|
69
|
+
if (options.dryRun) {
|
|
70
|
+
const { data } = await withSpinner('Checking existing themes', () =>
|
|
71
|
+
client.themes.list({ search: manifest.slug, limit: 100 }), format)
|
|
72
|
+
const existing = data?.find(theme => theme.slug === manifest.slug)
|
|
73
|
+
output({
|
|
74
|
+
operation: existing ? 'update' : 'create',
|
|
75
|
+
slug: manifest.slug,
|
|
76
|
+
name: manifest.name,
|
|
77
|
+
filters: manifest.filters?.length ?? 0,
|
|
78
|
+
translations: manifest.translations?.length ?? 'unchanged',
|
|
79
|
+
activation: 'unchanged',
|
|
80
|
+
defaultStatus: 'unchanged',
|
|
81
|
+
}, format)
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const result = await withSpinner('Applying theme manifest', () => client.themes.apply(manifest), format)
|
|
86
|
+
console.log(chalk.green(` Theme ${result.operation}`))
|
|
87
|
+
output(result.data, format)
|
|
88
|
+
})
|
|
89
|
+
|
|
50
90
|
themes
|
|
51
91
|
.command('create')
|
|
52
92
|
.description('Create a theme')
|