storyblok 3.19.0 → 3.20.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/README.md CHANGED
@@ -225,6 +225,10 @@ $ storyblok sync --type <COMMAND> --source <SPACE_ID> --target <SPACE_ID>
225
225
  * `type`: describe the command type to execute. Can be: `folders`, `components`, `stories`, `datasources` or `roles`. It's possible pass multiple types separated by comma (`,`).
226
226
  * `source`: the source space to use to sync
227
227
  * `target`: the target space to use to sync
228
+ * `starts-with`: sync only stories that starts with the given string
229
+ * `filter`: sync stories based on the given filter. Required Options: Required options: `--keys`, `--operations`, `--values`
230
+ * `keys`: Multiple keys should be separated by comma. Example: `--keys key1,key2`, `--keys key1`
231
+ * `operations`: Operations to be used for filtering. Can be: `is`, `in`, `not_in`, `like`, `not_like`, `any_in_array`, `all_in_array`, `gt_date`, `lt_date`, `gt_int`, `lt_int`, `gt_float`, `lt_float`. Multiple operations should be separated by comma.
228
232
 
229
233
  #### Examples
230
234
 
@@ -234,6 +238,15 @@ $ storyblok sync --type components --source 00001 --target 00002
234
238
 
235
239
  # Sync components and stories from `00001` space to `00002` space
236
240
  $ storyblok sync --type components,stories --source 00001 --target 00002
241
+
242
+ # Sync only stories that starts with `myStartsWithString` from `00001` space to `00002` space
243
+ $ storyblok sync --type stories --source 00001 --target 00002 --starts-with myStartsWithString
244
+
245
+ # Sync only stories with a category field like `reference` from `00001` space to `00002` space
246
+ $ storyblok sync --type stories --source 00001 --target 00002 --filter --keys category --operations like --values reference
247
+
248
+ # Sync only stories with a category field like `reference` and a name field not like `demo` from `00001` space to `00002` space
249
+ $ storyblok sync --type stories --source 00001 --target 00002 --filter --keys category,name --operations like,not_like --values reference,demo
237
250
  ```
238
251
 
239
252
  ### quickstart
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storyblok",
3
- "version": "3.19.0",
3
+ "version": "3.20.0",
4
4
  "description": "A simple CLI to start Storyblok from your command line.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,7 +25,7 @@
25
25
  "author": "Dominik Angerer <dominikangerer1@gmail.com>, Alexander Feiglstorfer <delooks@gmail.com>",
26
26
  "license": "MIT",
27
27
  "dependencies": {
28
- "axios": "^0.21.1",
28
+ "axios": "^0.27.2",
29
29
  "chalk": "^4.1.0",
30
30
  "clear": "0.1.0",
31
31
  "commander": "^5.1.0",
package/src/cli.js CHANGED
@@ -12,7 +12,7 @@ const updateNotifier = require('update-notifier')
12
12
  const pkg = require('../package.json')
13
13
 
14
14
  const tasks = require('./tasks')
15
- const { getQuestions, lastStep, api, creds } = require('./utils')
15
+ const { getQuestions, lastStep, api, creds, buildFilterQuery } = require('./utils')
16
16
  const { SYNC_TYPES, COMMANDS } = require('./constants')
17
17
 
18
18
  clear()
@@ -268,6 +268,11 @@ program
268
268
  .requiredOption('--type <TYPE>', 'Define what will be sync. Can be components, folders, stories, datasources or roles')
269
269
  .requiredOption('--source <SPACE_ID>', 'Source space id')
270
270
  .requiredOption('--target <SPACE_ID>', 'Target space id')
271
+ .option('--starts-with <STARTS_WITH>', 'Sync only stories that starts with the given string')
272
+ .option('--filter', 'Enable filter options to sync only stories that match the given filter. Required options: --keys; --operations; --values')
273
+ .option('--keys <KEYS>', 'Field names in your story object which should be used for filtering. Multiple keys should separated by comma.')
274
+ .option('--operations <OPERATIONS>', 'Operations to be used for filtering. Can be: is, in, not_in, like, not_like, any_in_array, all_in_array, gt_date, lt_date, gt_int, lt_int, gt_float, lt_float. Multiple operations should be separated by comma.')
275
+ .option('--values <VALUES>', 'Values to be used for filtering. Any string or number. If you want to use multiple values, separate them with a comma. Multiple values should be separated by comma.')
271
276
  .action(async (options) => {
272
277
  console.log(`${chalk.blue('-')} Sync data between spaces\n`)
273
278
 
@@ -279,7 +284,12 @@ program
279
284
  const {
280
285
  type,
281
286
  source,
282
- target
287
+ target,
288
+ startsWith,
289
+ filter,
290
+ keys,
291
+ operations,
292
+ values
283
293
  } = options
284
294
 
285
295
  const _types = type.split(',') || []
@@ -289,13 +299,16 @@ program
289
299
  }
290
300
  })
291
301
 
292
- const token = creds.get().token || null
302
+ const filterQuery = filter ? buildFilterQuery(keys, operations, values) : undefined
293
303
 
304
+ const token = creds.get().token || null
294
305
  await tasks.sync(_types, {
295
306
  api,
296
307
  token,
297
308
  source,
298
- target
309
+ target,
310
+ startsWith,
311
+ filterQuery
299
312
  })
300
313
 
301
314
  console.log('\n' + chalk.green('✓') + ' Sync data between spaces successfully completed')
package/src/tasks/sync.js CHANGED
@@ -3,6 +3,7 @@ const chalk = require('chalk')
3
3
  const SyncComponents = require('./sync-commands/components')
4
4
  const SyncDatasources = require('./sync-commands/datasources')
5
5
  const { capitalize } = require('../utils')
6
+ const { startsWith } = require('lodash/string')
6
7
 
7
8
  const SyncSpaces = {
8
9
  targetComponents: [],
@@ -14,6 +15,8 @@ const SyncSpaces = {
14
15
  this.sourceSpaceId = options.source
15
16
  this.targetSpaceId = options.target
16
17
  this.oauthToken = options.token
18
+ this.startsWith = options.startsWith
19
+ this.filterQuery = options.filterQuery
17
20
  this.client = api.getClient()
18
21
  },
19
22
 
@@ -56,7 +59,9 @@ const SyncSpaces = {
56
59
  }
57
60
 
58
61
  const all = await this.client.getAll(`spaces/${this.sourceSpaceId}/stories`, {
59
- story_only: 1
62
+ story_only: 1,
63
+ ...(this.startsWith ? { starts_with: this.startsWith } : {}),
64
+ ...(this.filterQuery ? { filter_query: this.filterQuery } : {})
60
65
  })
61
66
 
62
67
  for (let i = 0; i < all.length; i++) {
@@ -0,0 +1,23 @@
1
+ const buildFilterQuery = (keys, operations, values) => {
2
+ const operators = ['is', 'in', 'not_in', 'like', 'not_like', 'any_in_array', 'all_in_array', 'gt_date', 'lt_date', 'gt_int', 'lt_int', 'gt_float', 'lt_float']
3
+ if (!keys || !operations || !values) {
4
+ throw new Error('Filter options are required: --keys; --operations; --values')
5
+ }
6
+ const _keys = keys.split(',')
7
+ const _operations = operations.split(',')
8
+ const _values = values.split(',')
9
+ if (_keys.length !== _operations.length || _keys.length !== _values.length) {
10
+ throw new Error('The number of keys, operations and values must be the same')
11
+ }
12
+ const invalidOperators = _operations.filter((o) => !operators.includes(o))
13
+ if (invalidOperators.length) {
14
+ throw new Error('Invalid operator(s) applied for filter: ' + invalidOperators.join(' '))
15
+ }
16
+ const filterQuery = {}
17
+ _keys.forEach((key, index) => {
18
+ filterQuery[key] = { [_operations[index]]: _values[index] }
19
+ })
20
+ return filterQuery
21
+ }
22
+
23
+ module.exports = buildFilterQuery
@@ -6,5 +6,6 @@ module.exports = {
6
6
  capitalize: require('./capitalize'),
7
7
  findByProperty: require('./find-by-property'),
8
8
  parseError: require('./parse-error'),
9
+ buildFilterQuery: require('./build-filter-query'),
9
10
  saveFileFactory: require('./save-file-factory')
10
- }
11
+ }