sb-mig 5.5.4-beta.1 → 5.6.0-beta.1

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.
@@ -7,11 +7,15 @@ interface MigrateItems {
7
7
  migrateFrom: MigrateFrom;
8
8
  migrationConfig: string;
9
9
  componentsToMigrate: string[];
10
+ filters?: {
11
+ withSlug?: string[];
12
+ startsWith?: string;
13
+ };
10
14
  }
11
15
  export type MapperDefinition = (data: any) => any;
12
16
  export declare const prepareStoriesFromLocalFile: ({ from }: any) => any;
13
17
  export declare const prepareMigrationConfig: ({ migrationConfig }: any) => any;
14
- export declare const migrateAllComponentsDataInStories: ({ itemType, migrationConfig, migrateFrom, from, to, }: Omit<MigrateItems, "componentsToMigrate">, config: RequestBaseConfig) => Promise<void>;
18
+ export declare const migrateAllComponentsDataInStories: ({ itemType, migrationConfig, migrateFrom, from, to, filters, }: Omit<MigrateItems, "componentsToMigrate">, config: RequestBaseConfig) => Promise<void>;
15
19
  export declare const doTheMigration: ({ itemType, from, itemsToMigrate, componentsToMigrate, migrationConfigFileContent, migrationConfig, to, }: any, config: RequestBaseConfig) => Promise<void>;
16
- export declare const migrateProvidedComponentsDataInStories: ({ itemType, migrationConfig, migrateFrom, from, to, componentsToMigrate, }: MigrateItems, config: RequestBaseConfig) => Promise<void>;
20
+ export declare const migrateProvidedComponentsDataInStories: ({ itemType, migrationConfig, migrateFrom, from, to, componentsToMigrate, filters, }: MigrateItems, config: RequestBaseConfig) => Promise<void>;
17
21
  export {};
@@ -101,7 +101,7 @@ export const prepareMigrationConfig = ({ migrationConfig }) => {
101
101
  Logger.success(`Migration config loaded.`);
102
102
  return migrationConfigFileContent;
103
103
  };
104
- export const migrateAllComponentsDataInStories = async ({ itemType, migrationConfig, migrateFrom, from, to, }, config) => {
104
+ export const migrateAllComponentsDataInStories = async ({ itemType, migrationConfig, migrateFrom, from, to, filters, }, config) => {
105
105
  Logger.warning(`Trying to migrate all ${itemType} from ${migrateFrom}, ${from} to ${to}...`);
106
106
  const migrationConfigFileContent = prepareMigrationConfig({
107
107
  migrationConfig,
@@ -119,6 +119,7 @@ export const migrateAllComponentsDataInStories = async ({ itemType, migrationCon
119
119
  from,
120
120
  to,
121
121
  componentsToMigrate,
122
+ filters,
122
123
  }, config);
123
124
  };
124
125
  export const doTheMigration = async ({ itemType = "story", from, itemsToMigrate, componentsToMigrate, migrationConfigFileContent, migrationConfig, to, }, config) => {
@@ -128,9 +129,10 @@ export const doTheMigration = async ({ itemType = "story", from, itemsToMigrate,
128
129
  if (storyblokConfig.debug) {
129
130
  Logger.success(`# ${index} #`);
130
131
  }
131
- const json = itemType === "story" ? item[itemType].content : item[itemType];
132
+ let json = itemType === "story" ? item[itemType].content : item[itemType];
133
+ const rootWrapper = { root: json };
132
134
  const maxDepth = replaceComponentData({
133
- parent: { root: json },
135
+ parent: rootWrapper,
134
136
  key: "root",
135
137
  components: componentsToMigrate,
136
138
  mapper: migrationConfigFileContent,
@@ -138,6 +140,8 @@ export const doTheMigration = async ({ itemType = "story", from, itemsToMigrate,
138
140
  maxDepth: 0,
139
141
  sumOfReplacing,
140
142
  });
143
+ // After replacement, take potentially new root (root may be reassigned inside)
144
+ json = rootWrapper.root;
141
145
  arrayOfMaxDepths.push(maxDepth);
142
146
  if (Object.keys(sumOfReplacing).length > 0) {
143
147
  console.log(" ");
@@ -220,14 +224,17 @@ const saveBackupToFile = async ({ itemType, res, folder, filename }, config) =>
220
224
  res: res,
221
225
  }, config);
222
226
  };
223
- export const migrateProvidedComponentsDataInStories = async ({ itemType, migrationConfig, migrateFrom, from, to, componentsToMigrate, }, config) => {
227
+ export const migrateProvidedComponentsDataInStories = async ({ itemType, migrationConfig, migrateFrom, from, to, componentsToMigrate, filters, }, config) => {
224
228
  const migrationConfigFileContent = prepareMigrationConfig({
225
229
  migrationConfig,
226
230
  });
227
231
  if (migrateFrom === "file") {
228
232
  Logger.log("Migrating using file....");
229
233
  // Get all stories to be migrated from file
230
- const itemsToMigrate = prepareStoriesFromLocalFile({ from });
234
+ const itemsFromFile = prepareStoriesFromLocalFile({ from });
235
+ const itemsToMigrate = Array.isArray(itemsFromFile)
236
+ ? itemsFromFile.filter((it) => !(it?.story?.is_folder === true))
237
+ : itemsFromFile;
231
238
  await doTheMigration({
232
239
  itemsToMigrate,
233
240
  componentsToMigrate,
@@ -239,10 +246,27 @@ export const migrateProvidedComponentsDataInStories = async ({ itemType, migrati
239
246
  // Get all stories to be migrated from storyblok space
240
247
  let itemsToMigrate = [];
241
248
  if (itemType === "story") {
242
- itemsToMigrate = await managementApi.stories.getAllStories({}, {
243
- ...config,
244
- spaceId: from,
245
- });
249
+ if (filters?.withSlug && filters.withSlug.length > 0) {
250
+ const results = await Promise.all(filters.withSlug.map((slug) => managementApi.stories.getStoryBySlug(slug, {
251
+ ...config,
252
+ spaceId: from,
253
+ })));
254
+ itemsToMigrate = results.filter(Boolean).filter((it) => !(it?.story?.is_folder === true));
255
+ }
256
+ else if (filters?.startsWith) {
257
+ itemsToMigrate = await managementApi.stories.getAllStories({ options: { starts_with: filters.startsWith } }, {
258
+ ...config,
259
+ spaceId: from,
260
+ });
261
+ itemsToMigrate = itemsToMigrate.filter((it) => !(it?.story?.is_folder === true));
262
+ }
263
+ else {
264
+ itemsToMigrate = await managementApi.stories.getAllStories({}, {
265
+ ...config,
266
+ spaceId: from,
267
+ });
268
+ itemsToMigrate = itemsToMigrate.filter((it) => !(it?.story?.is_folder === true));
269
+ }
246
270
  }
247
271
  else if (itemType === "preset") {
248
272
  itemsToMigrate = await managementApi.presets.getAllPresets({
@@ -116,8 +116,8 @@ export const updateStory = (content, storyId, options, config) => {
116
116
  const { spaceId, sbApi } = config;
117
117
  Logger.warning("Trying to update Story...");
118
118
  Logger.log(`Updating story with name: ${content.name} in space: ${spaceId}`);
119
- console.log("THis is content to update: ");
120
- console.log(JSON.stringify(content, null, 2));
119
+ // console.log("THis is content to update: ");
120
+ // console.log(JSON.stringify(content, null, 2));
121
121
  return sbApi
122
122
  .put(`spaces/${spaceId}/stories/${storyId}`, {
123
123
  story: content,
@@ -1,7 +1,7 @@
1
1
  export declare const mainDescription = "\n USAGE\n $ sb-mig [command]\n \n COMMANDS\n sync Synchronize components, datasources, roles, stories, assets with Storyblok space.\n discover Discover components and write to file or stdout.\n backup Command for backing up anything related to Storyblok\n migrate Migrate content from space to space, or from file to space.\n debug Output extra debugging information\n help This screen\n \n Examples\n $ sb-mig sync components --all\n $ sb-mig debug \n";
2
2
  export declare const syncDescription = "\n Usage\n $ sb-mig sync [components|roles|datasources|plugins|content] [space separated file names] or --all\n \n Description\n Synchronize components, roles, datasources, plugins, content with Storyblok space.\n \n COMMANDS\n components - sync components\n roles - sync roles\n datasources - sync datasources\n plugins - sync plugins\n content - sync content (stories, assets) - ! right now destructive, it will move content from 1 space to another, completelly overwriting it\n \n FLAGS\n --all - Sync all components, roles, datasources [components, roles, datasources]\n --presets - Pass it, if u want to sync also with presets (will take longer) [components only]\n \n --yes - Skip ask for confirmation (dangerous, but useful in CI/CD) [content only]\n --from - Space ID from which you want to sync content [content only]\n --to - Space ID to which you want to sync content [content only]\n --syncDirection [fromSpaceToFile|fromFileToSpace|fromSpaceToSpace|fromAWStoSpace] \n - Sync direction (from, to) [content only]\n \n EXAMPLES\n $ sb-mig sync components --all\n $ sb-mig sync components --all --presets\n $ sb-mig sync components accordion accordion-item\n $ sb-mig sync components accordion accordion-item --presets\n \n $ sb-mig sync roles --all\n \n $ sb-mig sync datasources --all\n \n $ sb-mig sync plugins my-awesome-plugin - (you have to be in catalog which has ./dist/export.js file with compiled plugin)\n \n $ sb-mig sync content --all --from 12345 --to 12345\n $ sb-mig sync content --stories --from 12345 --to 12345\n $ sb-mig sync content --assets --from 12345 --to 12345\n";
3
3
  export declare const copyDescription = "\n Usage\n $ sb-mig copy\n \n Description\n Copy stuff\n \n COMMANDS\n ?\n \n FLAGS\n ?\n \n EXAMPLES\n $ sb-mig copy ?\n";
4
- export declare const migrateDescription = "\n Usage\n $ sb-mig migrate [content] [space separated file names] or --all --from [spaceId] --to [spaceId] --migration [migration-config-filename]\n \n Description\n Migrate content from space to space, or from file to space. It's potentially dangerous command, so it will ask for confirmation.\n Use with care.\n \n COMMANDS\n content - migrate content \n \n FLAGS\n --from - Space ID from which you want to migrate / or file name if passed '--migrate-from file'\n --to - Space ID to which you want to migrate\n --migrate-from - Migrate from (space, file) default: space\n --migration - File name of migration file (without extension)\n --yes - Skip ask for confirmation (dangerous, but useful in CI/CD) \n \n EXAMPLES\n $ sb-mig migrate content --all --from 12345 --to 12345 --migration file-with-migration\n $ sb-mig migrate content --all --migrate-from file --from file-with-stories --to 12345 --migration file-with-migration\n $ sb-mig migrate content my-component-1 my-component-2 --from 12345 --to 12345 --migration file-with-migration\n $ sb-mig migrate content my-component-1 my-component-2 --migrate-from file --from file-with-stories --to 12345 --migration file-with-migration \n";
4
+ export declare const migrateDescription = "\n Usage\n $ sb-mig migrate [content] [space separated file names] or --all --from [spaceId] --to [spaceId] --migration [migration-config-filename]\n \n Description\n Migrate content from space to space, or from file to space. It's potentially dangerous command, so it will ask for confirmation.\n Use with care.\n \n COMMANDS\n content - migrate content \n \n FLAGS\n --from - Space ID from which you want to migrate / or file name if passed '--migrate-from file'\n --to - Space ID to which you want to migrate\n --migrate-from - Migrate from (space, file) default: space\n --migration - File name of migration file (without extension)\n --withSlug - Filter stories by full slug (can be repeated)\n --startsWith - Filter stories by starts_with prefix\n --yes - Skip ask for confirmation (dangerous, but useful in CI/CD) \n \n EXAMPLES\n $ sb-mig migrate content --all --from 12345 --to 12345 --migration file-with-migration\n $ sb-mig migrate content --all --from 12345 --to 12345 --migration file-with-migration --withSlug blog/home --withSlug docs/getting-started\n $ sb-mig migrate content --all --from 12345 --to 12345 --migration file-with-migration --startsWith blog/\n $ sb-mig migrate content --all --migrate-from file --from file-with-stories --to 12345 --migration file-with-migration\n $ sb-mig migrate content my-component-1 my-component-2 --from 12345 --to 12345 --migration file-with-migration\n $ sb-mig migrate content my-component-1 my-component-2 --migrate-from file --from file-with-stories --to 12345 --migration file-with-migration \n";
5
5
  export declare const revertDescription = "\n Usage\n $ sb-mig revert [content] --migration\n \n Description\n Revert content migration\n \n COMMANDS\n content - revert content migration \n \n FLAGS\n --migration - ???\n --yes - Skip ask for confirmation (dangerous, but useful in CI/CD) \n \n EXAMPLES\n $ sb-mig revert content --migration \n";
6
6
  export declare const discoverDescription = "\n Usage\n $ sb-mig discover [components] --all --write\n \n Description\n Discover all component and write to file or stdout\n \n COMMANDS\n components - discover components\n \n FLAGS\n --all - Discover all components\n --write - Write to file \n \n EXAMPLES\n $ sb-mig discover components --all\n $ sb-mig discover components --all -- write\n";
7
7
  export declare const migrationsDescription = "\n Usage\n $ sb-mig migrations recognize\n \n Description\n Recognize migrations you need to apply\n \n COMMANDS\n recognize - recognize migrations\n \n FLAGS \n \n EXAMPLES\n $ sb-mig migrations recognize\n\n";
@@ -86,10 +86,14 @@ export const migrateDescription = `
86
86
  --to - Space ID to which you want to migrate
87
87
  --migrate-from - Migrate from (space, file) default: space
88
88
  --migration - File name of migration file (without extension)
89
+ --withSlug - Filter stories by full slug (can be repeated)
90
+ --startsWith - Filter stories by starts_with prefix
89
91
  --yes - Skip ask for confirmation (dangerous, but useful in CI/CD)
90
92
 
91
93
  EXAMPLES
92
94
  $ sb-mig migrate content --all --from 12345 --to 12345 --migration file-with-migration
95
+ $ sb-mig migrate content --all --from 12345 --to 12345 --migration file-with-migration --withSlug blog/home --withSlug docs/getting-started
96
+ $ sb-mig migrate content --all --from 12345 --to 12345 --migration file-with-migration --startsWith blog/
93
97
  $ sb-mig migrate content --all --migrate-from file --from file-with-stories --to 12345 --migration file-with-migration
94
98
  $ sb-mig migrate content my-component-1 my-component-2 --from 12345 --to 12345 --migration file-with-migration
95
99
  $ sb-mig migrate content my-component-1 my-component-2 --migrate-from file --from file-with-stories --to 12345 --migration file-with-migration
@@ -24,6 +24,9 @@ export const migrate = async (props) => {
24
24
  "pageId",
25
25
  "migration",
26
26
  "yes",
27
+ "withSlug",
28
+ "startsWith",
29
+ "dryRun",
27
30
  ]);
28
31
  Logger.warning(`This feature is in BETA. Use it at your own risk. The API might change in the future. (Probably in a standard Prisma like migration way)`);
29
32
  switch (command) {
@@ -32,6 +35,13 @@ export const migrate = async (props) => {
32
35
  const from = getFrom(flags, apiConfig);
33
36
  const to = getTo(flags, apiConfig);
34
37
  const migrationConfig = flags["migration"];
38
+ const withSlugFlag = flags["withSlug"];
39
+ const withSlug = Array.isArray(withSlugFlag)
40
+ ? withSlugFlag
41
+ : withSlugFlag
42
+ ? [withSlugFlag]
43
+ : undefined;
44
+ const startsWith = flags["startsWith"] || undefined;
35
45
  if (isIt("empty")) {
36
46
  const componentsToMigrate = unpackElements(input) || [""];
37
47
  const migrateFrom = "space";
@@ -50,6 +60,7 @@ export const migrate = async (props) => {
50
60
  migrateFrom,
51
61
  componentsToMigrate,
52
62
  migrationConfig,
63
+ filters: { withSlug, startsWith },
53
64
  }, apiConfig);
54
65
  }, () => {
55
66
  Logger.warning("Migration not started, exiting the program...");
@@ -66,6 +77,7 @@ export const migrate = async (props) => {
66
77
  to,
67
78
  migrateFrom,
68
79
  migrationConfig,
80
+ filters: { withSlug, startsWith },
69
81
  }, apiConfig);
70
82
  }, () => {
71
83
  Logger.warning("Migration not started, exiting the program...");
package/dist/cli/index.js CHANGED
@@ -54,6 +54,13 @@ app.migrate = () => ({
54
54
  default: "space",
55
55
  isRequired: true,
56
56
  },
57
+ withSlug: {
58
+ type: "string",
59
+ isMultiple: true,
60
+ },
61
+ startsWith: {
62
+ type: "string",
63
+ },
57
64
  },
58
65
  }),
59
66
  action: (cli) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sb-mig",
3
- "version": "5.5.4-beta.1",
3
+ "version": "5.6.0-beta.1",
4
4
  "description": "CLI to rule the world. (and handle stuff related to Storyblok CMS)",
5
5
  "author": "Marcin Krawczyk <marckraw@icloud.com>",
6
6
  "license": "MIT",