storyblok-backup 0.4.1 → 0.6.0

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/.env.example CHANGED
@@ -1,3 +1,3 @@
1
- STORYBLOK_OAUTH_TOKEN=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6
2
- STORYBLOK_SPACE_ID=123456
1
+ STORYBLOK_OAUTH_TOKEN=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6
2
+ STORYBLOK_SPACE_ID=123456
3
3
  STORYBLOK_REGION=eu
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  A npx CLI tool to create a full backup of a space of the [Storyblok CMS](https://www.storyblok.com).
7
7
 
8
- A restore tool to restore (create or update) resources is also included.
8
+ A limited restore tool to restore (create or update) single resources is also included. A full restore-tool is available in a separate package: [netgen/storyblok-restore](https://github.com/netgen/storyblok-restore)
9
9
 
10
10
  The backup script will fetch the following resources of a Storyblok space using the Management API and archive them in a zip file:
11
11
 
@@ -38,6 +38,8 @@ The restore script is able to individually restore the resources from the backup
38
38
  - Workflow stage changes: No update possible.
39
39
  - Access Tokens: Creating access tokens from backup makes no sense, since it will result in a new token-string.
40
40
 
41
+ For a much more feature-rich full restore-tool see [netgen/storyblok-restore](https://github.com/netgen/storyblok-restore).
42
+
41
43
  ## Table of contents
42
44
 
43
45
  - [Installation](#installation)
@@ -83,51 +85,52 @@ Call `npx storyblok-backup` with the following options:
83
85
  #### Backup options
84
86
 
85
87
  ```text
86
- --token <token> (required) Personal OAuth access token created
87
- in the account settings of a Stoyblok user.
88
- (NOT the Access Token of a Space!)
89
- Alternatively, you can set the STORYBLOK_OAUTH_TOKEN environment variable.
90
- --space <space_id> (required) ID of the space to backup
91
- Alternatively, you can set the STORYBLOK_SPACE_ID environment variable.
92
- --region <region> Region of the space. Possible values are:
93
- - 'eu' (default): EU
94
- - 'us': US
95
- - 'ap': Australia
96
- - 'ca': Canada
97
- - 'cn': China
98
- Alternatively, you can set the STORYBLOK_REGION environment variable.
99
- --types <types> Comma separated list of resource-types to backup. Defaults to all.
100
- Possible values are:
101
- - 'stories'
102
- - 'collaborators'
103
- - 'components'
104
- - 'component-groups'
105
- - 'assets'
106
- - 'asset-folders'
107
- - 'internal-tags'
108
- - 'datasources'
109
- - 'space'
110
- - 'space-roles'
111
- - 'tasks'
112
- - 'activities'
113
- - 'presets'
114
- - 'field-types'
115
- - 'webhooks'
116
- - 'workflow-stages'
117
- - 'workflow-stage-changes'
118
- - 'workflows'
119
- - 'releases'
120
- - 'pipeline-branches'
121
- - 'access-tokens'
122
- --with-asset-files Downloads all files (assets) of the space. Defaults to false.
123
- --output-dir <dir> Directory to write the backup to. Defaults to ./.output
124
- (ATTENTION: Will fail if the directory already exists!)
125
- --force Force deletion and recreation of existing output directory.
126
- --create-zip Create a zip file of the backup. Defaults to false.
127
- --zip-prefix <dir> Prefix for the zip file. Defaults to 'backup'.
128
- (The suffix will automatically be the current date.)
129
- --verbose Will show detailed output for every file written.
130
- --help Show this help
88
+ --token <token> (required) Personal OAuth access token created
89
+ in the account settings of a Stoyblok user.
90
+ (NOT the Access Token of a Space!)
91
+ Alternatively, you can set the STORYBLOK_OAUTH_TOKEN environment variable.
92
+ --space <space_id> (required) ID of the space to backup
93
+ Alternatively, you can set the STORYBLOK_SPACE_ID environment variable.
94
+ --region <region> Region of the space. Possible values are:
95
+ - 'eu' (default): EU
96
+ - 'us': US
97
+ - 'ap': Australia
98
+ - 'ca': Canada
99
+ - 'cn': China
100
+ Alternatively, you can set the STORYBLOK_REGION environment variable.
101
+ --types <types> Comma separated list of resource-types to backup (default=all).
102
+ Possible values are:
103
+ - 'stories'
104
+ - 'collaborators'
105
+ - 'components'
106
+ - 'component-groups'
107
+ - 'assets'
108
+ - 'asset-folders'
109
+ - 'internal-tags'
110
+ - 'datasources'
111
+ - 'space'
112
+ - 'space-roles'
113
+ - 'tasks'
114
+ - 'activities'
115
+ - 'presets'
116
+ - 'field-types'
117
+ - 'webhooks'
118
+ - 'workflow-stages'
119
+ - 'workflow-stage-changes'
120
+ - 'workflows'
121
+ - 'releases'
122
+ - 'pipeline-branches'
123
+ - 'access-tokens'
124
+ --omit-types <types> Comma separated list of resource-types to omit.
125
+ --with-asset-files Downloads all files (assets) of the space (default=false).
126
+ --output-dir <dir> Directory to write the backup to (default=./.output)
127
+ (ATTENTION: Will fail if the directory already exists!)
128
+ --force Force deletion and recreation of existing output directory.
129
+ --create-zip Create a zip file of the backup (default=false).
130
+ --zip-prefix <dir> Prefix for the zip file. (default='backup').
131
+ (The suffix will automatically be the current date.)
132
+ --verbose Will show detailed output for every file written.
133
+ --help Show this help
131
134
  ```
132
135
 
133
136
  OAuth token, space-id and region can be set via environment variables. You can also use a `.env` file in your project root for this (see `.env.example`).
@@ -160,7 +163,7 @@ This will create the folder `./my-dir/backup`, fetch all resources (incl. the or
160
163
 
161
164
  #### Continuous backup integration examples
162
165
 
163
- You can use this script to create periodic backups of Storyblok spaces using GitHub Actions and artifacts, or commit each content change to a git repository usint Storyblok's webhooks.
166
+ You can use this script to create periodic backups of Storyblok spaces using GitHub Actions and artifacts, or commit each content change to a git repository using Storyblok's webhooks.
164
167
 
165
168
  ##### Example for a GitHub workflow for a complete backup as an artifact
166
169
 
@@ -225,7 +228,7 @@ Also keep in mind, that there is a limit on artifact storage and runner minutes
225
228
 
226
229
  ##### Example for a GitHub workflow for an incremental git-commit-based backup
227
230
 
228
- The following workflow should run via webhook on every relevant change (e.g.publish) in Storyblok. It creates a new current backup (excl. asset files) and commits them to the current repository in the `backup` folder. This enables an incremental git-commit-based backup of all Storyblok-content.
231
+ The following workflow should run via webhook on every relevant change (e.g.publish) in Storyblok. It creates a new current backup (excl. asset files and resources of types access-tokens, activities and workflow-stage-changes) and commits them to the current repository in the `backup` folder. This enables an incremental git-commit-based backup of all Storyblok-content.
229
232
 
230
233
  ```yaml
231
234
  name: Incremental Repository Backup
@@ -256,7 +259,7 @@ jobs:
256
259
  env:
257
260
  STORYBLOK_OAUTH_TOKEN: ${{ secrets.STORYBLOK_OAUTH_TOKEN }}
258
261
  STORYBLOK_SPACE_ID: ${{ secrets.STORYBLOK_SPACE_ID }}
259
- run: npx storyblok-backup
262
+ run: npx storyblok-backup --omit-types "access-tokens,activities,workflow-stage-changes"
260
263
 
261
264
  - name: Copy files into repository
262
265
  run: |
@@ -281,9 +284,11 @@ A webhook to the URL `https://api.github.com/repos/{owner}/{repo}/dispatches` mu
281
284
 
282
285
  ### Restore
283
286
 
287
+ (NOTE: The included restore functionality is limited to restoring only single documents, and not full spaces. For a much more feature-rich full restore-tool see [netgen/storyblok-restore](https://github.com/netgen/storyblok-restore).)
288
+
284
289
  Make sure to install the package first (see [Installation](#installation)).
285
290
 
286
- Call `npx storyblok-restore` with the following options:
291
+ Call `npx storyblok-backup-restore` with the following options:
287
292
 
288
293
  #### Restore options
289
294
 
@@ -338,7 +343,7 @@ Call `npx storyblok-restore` with the following options:
338
343
  #### Minimal restore example
339
344
 
340
345
  ```shell
341
- npx storyblok-restore --token 1234567890abcdef --space 12345 --type story --file ./.output/backup/123456789.json
346
+ npx storyblok-backup-restore --token 1234567890abcdef --space 12345 --type story --file ./.output/backup/123456789.json
342
347
  ```
343
348
 
344
349
  This will restore the story from the stated file by updating it.
@@ -346,7 +351,7 @@ This will restore the story from the stated file by updating it.
346
351
  #### Maximal restore example
347
352
 
348
353
  ```shell
349
- npx storyblok-restore \
354
+ npx storyblok-backup-restore \
350
355
  --token 1234567890abcdef \
351
356
  --space 12345 \
352
357
  --region ap \
@@ -8,7 +8,7 @@ import dotenvx from '@dotenvx/dotenvx'
8
8
 
9
9
  const startTime = performance.now()
10
10
 
11
- dotenvx.config({ quiet: true })
11
+ dotenvx.config({ quiet: true, ignore: ['MISSING_ENV_FILE'] })
12
12
 
13
13
  const resourceTypes = [
14
14
  'story',
@@ -37,7 +37,7 @@ const args = minimist(process.argv.slice(2))
37
37
 
38
38
  if ('help' in args) {
39
39
  console.log(`USAGE
40
- $ npx storyblok-restore
40
+ $ npx storyblok-backup-restore
41
41
 
42
42
  OPTIONS
43
43
  --token <token> (required) Personal OAuth access token created
@@ -69,10 +69,10 @@ OPTIONS
69
69
  --help Show this help
70
70
 
71
71
  MINIMAL EXAMPLE
72
- $ npx storyblok-restore --token 1234567890abcdef --space 12345 --type story --file ./.output/backup/123456789.json
72
+ $ npx storyblok-backup-restore --token 1234567890abcdef --space 12345 --type story --file ./.output/backup/123456789.json
73
73
 
74
74
  MAXIMAL EXAMPLE
75
- $ npx storyblok-restore \\
75
+ $ npx storyblok-backup-restore \\
76
76
  --token 1234567890abcdef \\
77
77
  --space 12345 \\
78
78
  --region ap \\
@@ -154,6 +154,19 @@ if (propagate && args.type !== 'story') {
154
154
  process.exit(1)
155
155
  }
156
156
 
157
+ // Output General information
158
+ console.log('')
159
+ console.log(`Restoring backup in space ${spaceId}:`)
160
+ console.log(`- resource type: ${args.type}`)
161
+ console.log(`- file: ${args.file}`)
162
+ if ('id' in args) {
163
+ console.log(`- datasource id: ${args.id}`)
164
+ }
165
+ console.log(`- mode: ${'create' in args ? 'create' : 'update'}`)
166
+ console.log(`- publish: ${'publish' in args ? 'yes' : 'no'}`)
167
+ console.log(`- propagate: ${'propagate' in args ? 'yes' : 'no'}`)
168
+ console.log('')
169
+
157
170
  // Init Management API
158
171
  const StoryblokMAPI = new StoryblokClient({
159
172
  oauthToken: oauthToken,
@@ -11,7 +11,7 @@ import dotenvx from '@dotenvx/dotenvx'
11
11
 
12
12
  const startTime = performance.now()
13
13
 
14
- dotenvx.config({ quiet: true })
14
+ dotenvx.config({ quiet: true, ignore: ['MISSING_ENV_FILE'] })
15
15
 
16
16
  let resourceTypes = [
17
17
  'stories',
@@ -44,31 +44,32 @@ if ('help' in args) {
44
44
  $ npx storyblok-backup
45
45
 
46
46
  OPTIONS
47
- --token <token> (required) Personal OAuth access token created
48
- in the account settings of a Stoyblok user.
49
- (NOT the Access Token of a Space!)
50
- Alternatively, you can set the STORYBLOK_OAUTH_TOKEN environment variable.
51
- --space <space_id> (required) ID of the space to backup
52
- Alternatively, you can set the STORYBLOK_SPACE_ID environment variable.
53
- --region <region> Region of the space. Possible values are:
54
- - 'eu' (default): EU
55
- - 'us': US
56
- - 'ap': Australia
57
- - 'ca': Canada
58
- - 'cn': China
59
- Alternatively, you can set the STORYBLOK_REGION environment variable.
60
- --types <types> Comma separated list of resource-types to backup (default=all).
61
- Possible values are:
62
- - '${resourceTypes.join("'\n - '")}'
63
- --with-asset-files Downloads all files (assets) of the space (default=false).
64
- --output-dir <dir> Directory to write the backup to (default=./.output)
65
- (ATTENTION: Will fail if the directory already exists!)
66
- --force Force deletion and recreation of existing output directory.
67
- --create-zip Create a zip file of the backup (default=false).
68
- --zip-prefix <dir> Prefix for the zip file. (default='backup').
69
- (The suffix will automatically be the current date.)
70
- --verbose Will show detailed output for every file written.
71
- --help Show this help
47
+ --token <token> (required) Personal OAuth access token created
48
+ in the account settings of a Stoyblok user.
49
+ (NOT the Access Token of a Space!)
50
+ Alternatively, you can set the STORYBLOK_OAUTH_TOKEN environment variable.
51
+ --space <space_id> (required) ID of the space to backup
52
+ Alternatively, you can set the STORYBLOK_SPACE_ID environment variable.
53
+ --region <region> Region of the space. Possible values are:
54
+ - 'eu' (default): EU
55
+ - 'us': US
56
+ - 'ap': Australia
57
+ - 'ca': Canada
58
+ - 'cn': China
59
+ Alternatively, you can set the STORYBLOK_REGION environment variable.
60
+ --types <types> Comma separated list of resource-types to backup (default=all).
61
+ Possible values are:
62
+ - '${resourceTypes.join("'\n - '")}'
63
+ --omit-types <types> Comma separated list of resource-types to omit.
64
+ --with-asset-files Downloads all files (assets) of the space (default=false).
65
+ --output-dir <dir> Directory to write the backup to (default=./.output)
66
+ (ATTENTION: Will fail if the directory already exists!)
67
+ --force Force deletion and recreation of existing output directory.
68
+ --create-zip Create a zip file of the backup (default=false).
69
+ --zip-prefix <dir> Prefix for the zip file. (default='backup').
70
+ (The suffix will automatically be the current date.)
71
+ --verbose Will show detailed output for every file written.
72
+ --help Show this help
72
73
 
73
74
  MINIMAL EXAMPLE
74
75
  $ npx storyblok-backup --token 1234567890abcdef --space 12345
@@ -79,6 +80,7 @@ MAXIMAL EXAMPLE
79
80
  --space 12345 \\
80
81
  --region ap \\
81
82
  --types "stories,components" \\
83
+ --omit-types "activities" \\
82
84
  --with-asset-files \\
83
85
  --output-dir ./my-dir \\
84
86
  --force \\
@@ -128,6 +130,11 @@ if ('types' in args) {
128
130
  resourceTypes = typesToBackup
129
131
  }
130
132
 
133
+ if ('omit-types' in args) {
134
+ const typesToOmit = args['omit-types'].split(',')
135
+ resourceTypes = resourceTypes.filter((type) => !typesToOmit.includes(type))
136
+ }
137
+
131
138
  const verbose = 'verbose' in args
132
139
 
133
140
  const outputDir = args['output-dir'] || './.output'
@@ -156,11 +163,17 @@ const fileName =
156
163
 
157
164
  const filePath = `${outputDir}/${fileName}`
158
165
 
166
+ // Output General information
167
+ console.log('')
159
168
  console.log(`Creating backup for space ${spaceId}:`)
160
- console.log(`Output dir: ${outputDir}`)
169
+ console.log(`- output dir: ${outputDir}`)
161
170
  if ('create-zip' in args) {
162
- console.log(`Output zip: ${filePath}`)
171
+ console.log(`- output zip: ${filePath}`)
163
172
  }
173
+ console.log(`- resource types: ${resourceTypes.join(', ')}`)
174
+ console.log(`- with asset files: ${'with-asset-files' in args ? 'yes' : 'no'}`)
175
+ console.log(`- force output folder: ${'force' in args ? 'yes' : 'no'}`)
176
+ console.log('')
164
177
 
165
178
  // Init Management API
166
179
  const StoryblokMAPI = new StoryblokClient({
@@ -179,6 +192,11 @@ resourceTypes.forEach(
179
192
  (resource) => resource === 'space' || fs.mkdirSync(`${backupDir}/${resource}`)
180
193
  )
181
194
 
195
+ // Create separate directory for asset-files
196
+ if (resourceTypes.includes('assets') && 'with-asset-files' in args) {
197
+ fs.mkdirSync(`${backupDir}/asset-files`)
198
+ }
199
+
182
200
  // Function to perform a default fetch
183
201
  const defaultFetch = async (endpoint, type, fileField, fileFieldObject) => {
184
202
  if (resourceTypes.includes(type)) {
@@ -282,7 +300,7 @@ if (resourceTypes.includes('assets')) {
282
300
  if ('with-asset-files' in args) {
283
301
  const fileExtension = asset.filename.split('.').at(-1)
284
302
  const fileName = asset.id + '.' + fileExtension
285
- await downloadFile('assets', fileName, asset.filename)
303
+ await downloadFile('asset-files', fileName, asset.filename)
286
304
  }
287
305
  }
288
306
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storyblok-backup",
3
- "version": "0.4.1",
3
+ "version": "0.6.0",
4
4
  "description": "npx CLI tool to create a full backup of a Storyblok space and restore single resources from it.",
5
5
  "scripts": {
6
6
  "upgrade": "npx npm-check-updates -i -u && pnpm install",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "bin": {
15
15
  "storyblok-backup": "bin/storyblok-backup.mjs",
16
- "storyblok-restore": "bin/storyblok-restore.mjs"
16
+ "storyblok-backup-restore": "bin/storyblok-backup-restore.mjs"
17
17
  },
18
18
  "repository": {
19
19
  "type": "git",