-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcli.ts
More file actions
executable file
·104 lines (95 loc) · 3.13 KB
/
cli.ts
File metadata and controls
executable file
·104 lines (95 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { cancel, intro, isCancel, outro, select, text } from '@clack/prompts'
import 'zx/globals'
import dotenv from 'dotenv'
dotenv.config({ quiet: true })
import backupSpace from './commands/backup-space.js'
import restoreSpace from './commands/restore-space.js'
type Task = 'backup' | 'restore'
const getTask = async () => {
const givenTask: Task | undefined = argv['backup'] ? 'backup' : argv['restore'] ? 'restore' : undefined
if (givenTask) {
return givenTask
}
return select({
message: 'Backup or restore?',
options: [
{ value: 'backup', label: 'Backup' },
{ value: 'restore', label: 'Restore' },
],
})
}
const getToken = async () => {
const givenToken: string | undefined = argv['token'] || process.env['STORYBLOK_TOKEN']
if (givenToken) {
return givenToken
}
return text({
message: 'Storyblok token:',
validate: (value) => (value ? undefined : 'Token must be defined.'),
})
}
const getSpaces = async () => {
const givenSpaces: string | undefined = argv['spaces'] || process.env['STORYBLOK_SPACES']
if (givenSpaces) {
return givenSpaces
}
return text({
message: 'Spaces (comma-separated, format: label:id):',
placeholder: 'my-space:12345,another:67890',
validate: (value) => (value ? undefined : 'Spaces must be defined.'),
})
}
const getSpacesMap = (spaces: string): Map<string, string> =>
new Map(
spaces
.split(',')
.map(getSpaceEntry)
.filter((spaceEntry) => spaceEntry[0] && spaceEntry[1]),
)
const getSpaceEntry = (value: string): [string, string] => {
const space = value.split(':')
if (space.length >= 2 && space[0] && space[1]) {
return [space[0], space[1]]
}
if (space.length >= 2 && !space[0] && space[1]) {
return [space[1], space[1]]
}
if (space.length === 1 && space[0]) {
return [space[0], space[0]]
}
return ['', '']
}
const getAdditionalArgs = async () => {
const givenArgs: string | undefined = argv['args'] || process.env['STORYBLOK_ARGS']
if (givenArgs) {
return givenArgs
}
const args = await text({
message: 'Additional arguments (optional):',
defaultValue: '',
})
return args.toString()
}
const parseArgs = (args: string): string[] => args.split(/\s+/).filter(Boolean)
const checkCancel = (possiblyCancelled: string | symbol) => {
if (isCancel(possiblyCancelled)) {
cancel('Canceled')
process.exit(0)
}
return possiblyCancelled
}
intro('storyblok-backup-cli')
const task = checkCancel(await getTask())
const token = checkCancel(await getToken())
const spaces = checkCancel(await getSpaces())
const spacesMap = getSpacesMap(spaces)
const additionalArgsRaw = await getAdditionalArgs()
const passthroughArgs = parseArgs(additionalArgsRaw)
for (const [spaceName, spaceId] of spacesMap) {
if (task === 'backup') {
await backupSpace(token as string, spaceName, spaceId, passthroughArgs)
} else {
await restoreSpace(token as string, spaceName, spaceId, passthroughArgs)
}
}
outro('Finished!')