@jungvonmatt/contentful-migrations 6.2.6 → 7.0.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/lib/diff.js CHANGED
@@ -1,7 +1,9 @@
1
- const Diff = require('diff');
2
- const { documentToPlainTextString } = require('@contentful/rich-text-plain-text-renderer');
3
- const pc = require('picocolors');
4
- const { diff: deepDiff } = require('deep-diff');
1
+ const Diff = require("diff");
2
+ const {
3
+ documentToPlainTextString,
4
+ } = require("@contentful/rich-text-plain-text-renderer");
5
+ const pc = require("picocolors");
6
+ const microdiff = require("microdiff").default;
5
7
  const {
6
8
  getContentId,
7
9
  getContentTypeId,
@@ -16,13 +18,19 @@ const {
16
18
  TYPE_ARRAY,
17
19
  TYPE_BOOLEAN,
18
20
  TYPE_LINK,
19
- } = require('./contentful');
21
+ } = require("./contentful");
20
22
 
21
23
  const getNodeDate = (node) => {
22
24
  const { sys } = node || {};
23
25
  const { updatedAt } = sys || {};
24
26
  const date = new Date(updatedAt);
25
- const options = { hour: '2-digit', minute: '2-digit', year: 'numeric', month: '2-digit', day: 'numeric' };
27
+ const options = {
28
+ hour: "2-digit",
29
+ minute: "2-digit",
30
+ year: "numeric",
31
+ month: "2-digit",
32
+ day: "numeric",
33
+ };
26
34
  const { locale } = Intl.DateTimeFormat().resolvedOptions();
27
35
 
28
36
  return date.toLocaleDateString(locale, options);
@@ -51,7 +59,7 @@ const diffString = (source, dest) => {
51
59
  return unchangedColor(part.value);
52
60
  });
53
61
 
54
- return parts.join('');
62
+ return parts.join("");
55
63
  };
56
64
 
57
65
  const getField = (fieldId, contentType) => {
@@ -69,7 +77,7 @@ const getFieldValue = (fieldId, node) => {
69
77
 
70
78
  const normalizeArray = (array) =>
71
79
  (array || []).map((val) => {
72
- if (typeof val === 'string') {
80
+ if (typeof val === "string") {
73
81
  return val;
74
82
  }
75
83
 
@@ -80,13 +88,15 @@ const normalizeArray = (array) =>
80
88
 
81
89
  const diff = (source, dest, contentTypes) => {
82
90
  const id = getContentId(dest);
83
- const contentType = (contentTypes || []).find((ct) => getContentId(ct) === getContentTypeId(dest));
91
+ const contentType = (contentTypes || []).find(
92
+ (ct) => getContentId(ct) === getContentTypeId(dest),
93
+ );
84
94
  const { fields: contentTypeFields } = contentType || {};
85
95
  const { fields: sourceFields } = source || {};
86
96
  const { fields: destFields } = dest || {};
87
- const diffResult = deepDiff(destFields, sourceFields);
97
+ const diffResult = microdiff(destFields || {}, sourceFields || {});
88
98
 
89
- if (!diffResult) {
99
+ if (diffResult.length === 0) {
90
100
  return;
91
101
  }
92
102
 
@@ -100,23 +110,27 @@ const diff = (source, dest, contentTypes) => {
100
110
  const [fieldId] = path || [];
101
111
  return fieldId;
102
112
  })
103
- .filter((v) => v)
113
+ .filter((v) => v),
104
114
  ),
105
115
  ];
106
116
 
107
117
  // console.log(contentType);
108
118
  const fieldData = changedFields.map((fieldId) => {
109
- const { name = fieldId } = (contentTypeFields || []).find(({ id }) => id === fieldId) || {};
119
+ const { name = fieldId } =
120
+ (contentTypeFields || []).find(({ id }) => id === fieldId) || {};
110
121
  const field = getField(fieldId, contentType);
111
122
  const { type, linkType } = field || {};
112
123
  const sourceValue = getFieldValue(fieldId, source);
113
124
  const destValue = getFieldValue(fieldId, dest);
114
125
  if (type === TYPE_SYMBOL) {
115
- return `${pc.bold(name)}: ${pc.reset(diffString(`${destValue || ''}`, `${sourceValue || ''}`))}`;
126
+ return `${pc.bold(name)}: ${pc.reset(diffString(`${destValue || ""}`, `${sourceValue || ""}`))}`;
116
127
  }
117
128
  if (type === TYPE_RICHTEXT) {
118
129
  return `${pc.bold(name)}: ${pc.reset(
119
- diffString(documentToPlainTextString(destValue || {}), documentToPlainTextString(sourceValue || {}))
130
+ diffString(
131
+ documentToPlainTextString(destValue || {}),
132
+ documentToPlainTextString(sourceValue || {}),
133
+ ),
120
134
  )}`;
121
135
  }
122
136
  if (type === TYPE_NUMBER) {
@@ -124,26 +138,26 @@ const diff = (source, dest, contentTypes) => {
124
138
  return `${pc.bold(name)}: ${oldValueColor(`${destValue}`)} ${newValueColor(`${sourceValue}`)}`;
125
139
  }
126
140
  if (type === TYPE_TEXT) {
127
- return `${pc.bold(name)}: ${pc.reset(diffString(`${destValue || ''}`, `${sourceValue || ''}`))}`;
141
+ return `${pc.bold(name)}: ${pc.reset(diffString(`${destValue || ""}`, `${sourceValue || ""}`))}`;
128
142
  }
129
143
  if (type === TYPE_DATE) {
130
- return `${pc.bold(name)}: ${oldValueColor(`${destValue || ''}`)} ${newValueColor(`${sourceValue || ''}`)}`;
144
+ return `${pc.bold(name)}: ${oldValueColor(`${destValue || ""}`)} ${newValueColor(`${sourceValue || ""}`)}`;
131
145
  }
132
146
  if (type === TYPE_LOCATION) {
133
- return `${pc.bold(name)}: ${oldValueColor(`${JSON.stringify(destValue || '')}`)} ${newValueColor(
134
- `${JSON.stringify(sourceValue || '')}`
147
+ return `${pc.bold(name)}: ${oldValueColor(`${JSON.stringify(destValue || "")}`)} ${newValueColor(
148
+ `${JSON.stringify(sourceValue || "")}`,
135
149
  )}`;
136
150
  }
137
151
  if (type === TYPE_BOOLEAN) {
138
152
  return `${pc.bold(name)}: ${oldValueColor(`${JSON.stringify(destValue)}`)} ${newValueColor(
139
- `${JSON.stringify(sourceValue)}`
153
+ `${JSON.stringify(sourceValue)}`,
140
154
  )}`;
141
155
  }
142
156
  if (type === TYPE_LINK) {
143
157
  const sourceValueId = getContentId(sourceValue || {});
144
158
  const destValueId = getContentId(destValue || {});
145
- return `${pc.bold(name)} (${linkType}): ${oldValueColor(destValueId || 'deleted')} ${newValueColor(
146
- sourceValueId || 'empty'
159
+ return `${pc.bold(name)} (${linkType}): ${oldValueColor(destValueId || "deleted")} ${newValueColor(
160
+ sourceValueId || "empty",
147
161
  )}`;
148
162
  }
149
163
 
@@ -158,24 +172,24 @@ const diff = (source, dest, contentTypes) => {
158
172
  const destArray = normalizeArray(destValue);
159
173
 
160
174
  const array = Array(Math.max(sourceArray.length, destArray.length))
161
- .fill('')
175
+ .fill("")
162
176
  .map((_, index) => {
163
177
  if (sourceArray[index] === destArray[index]) {
164
178
  return unchangedColor(sourceArray[index]);
165
179
  }
166
180
 
167
181
  if (sourceArray[index] && destArray[index]) {
168
- return `${oldValueColor(destArray[index] || '')} ${newValueColor(sourceArray[index])}`;
182
+ return `${oldValueColor(destArray[index] || "")} ${newValueColor(sourceArray[index])}`;
169
183
  }
170
184
 
171
185
  if (destArray[index]) {
172
186
  return `${newValueColor(sourceArray[index])}`;
173
187
  }
174
188
 
175
- return `${oldValueColor(destArray[index] || '')}`;
189
+ return `${oldValueColor(destArray[index] || "")}`;
176
190
  });
177
191
 
178
- return `${pc.bold(name)}: [\n ${array.join('\n ')}\n ]`;
192
+ return `${pc.bold(name)}: [\n ${array.join("\n ")}\n ]`;
179
193
  }
180
194
 
181
195
  return name;
@@ -185,20 +199,20 @@ const diff = (source, dest, contentTypes) => {
185
199
  const sourceEnv = getEnvironmentId(source);
186
200
 
187
201
  return {
188
- type: 'list',
189
- message: `${pc.reset('Conflict on')} ${pc.cyan(name)}\n ${pc.reset(`${fieldData.join('\n ')}`)}\n`,
202
+ type: "list",
203
+ message: `${pc.reset("Conflict on")} ${pc.cyan(name)}\n ${pc.reset(`${fieldData.join("\n ")}`)}\n`,
190
204
 
191
205
  name: id,
192
206
  choices: [
193
207
  {
194
- name: `Use ${oldValueColor(destEnv)} - updated on ${getNodeDate(dest)} ${pc.bold('(skip)')}`,
208
+ name: `Use ${oldValueColor(destEnv)} - updated on ${getNodeDate(dest)} ${pc.bold("(skip)")}`,
195
209
  value: false,
196
- short: 'skip',
210
+ short: "skip",
197
211
  },
198
212
  {
199
- name: `Use ${newValueColor(sourceEnv)} - updated on ${getNodeDate(source)} ${pc.bold('(overwrite)')}`,
213
+ name: `Use ${newValueColor(sourceEnv)} - updated on ${getNodeDate(source)} ${pc.bold("(overwrite)")}`,
200
214
  value: true,
201
- short: 'overwrite',
215
+ short: "overwrite",
202
216
  },
203
217
  ],
204
218
  };
@@ -1,6 +1,6 @@
1
- import type { Locale } from "contentful-management/dist/typings/export-types";
2
- import type Migration from "contentful-migration";
3
- import type { MigrationContext } from "contentful-migration";
1
+ import type { Locale } from 'contentful-management/dist/typings/export-types';
2
+ import type Migration from 'contentful-migration';
3
+ import type { MigrationContext } from 'contentful-migration';
4
4
 
5
5
  export interface LocaleHelpers {
6
6
  getLocales(): Promise<Locale[]>;
@@ -1,5 +1,5 @@
1
- import type Migration from "contentful-migration";
2
- import type { MigrationContext } from "contentful-migration";
1
+ import type Migration from 'contentful-migration';
2
+ import type { MigrationContext } from 'contentful-migration';
3
3
 
4
4
  export type ValueMappingFunction<T extends string = string> = (values: T[]) => T[];
5
5
 
@@ -11,31 +11,110 @@ export interface AddValuesOptions {
11
11
  }
12
12
 
13
13
  // define some known mark and node values here to support code completion, but allow any string as well
14
- export type RichTextMarks = 'bold' | 'italic' | 'underline' | 'code' | 'superscript' | 'subscript' | 'strikethrough' | string & {};
15
- export type RichTextNodeType = 'document' | 'paragraph' | 'heading-1' | 'heading-2' | 'heading-3' | 'heading-4' | 'heading-5' | 'heading-6' | 'ordered-list' | 'unordered-list' | 'list-item' | 'hr' | 'blockquote' | 'embedded-entry-block' | 'embedded-asset-block' | 'embedded-resource-block' | 'table' | 'table-row' | 'table-cell' | 'table-header-cell' | 'asset-hyperlink' | 'embedded-entry-inline' | 'embedded-resource-inline' | 'entry-hyperlink' | 'hyperlink' | 'resource-hyperlink' | string & {};
14
+ export type RichTextMarks =
15
+ | 'bold'
16
+ | 'italic'
17
+ | 'underline'
18
+ | 'code'
19
+ | 'superscript'
20
+ | 'subscript'
21
+ | 'strikethrough'
22
+ | (string & {});
23
+ export type RichTextNodeType =
24
+ | 'document'
25
+ | 'paragraph'
26
+ | 'heading-1'
27
+ | 'heading-2'
28
+ | 'heading-3'
29
+ | 'heading-4'
30
+ | 'heading-5'
31
+ | 'heading-6'
32
+ | 'ordered-list'
33
+ | 'unordered-list'
34
+ | 'list-item'
35
+ | 'hr'
36
+ | 'blockquote'
37
+ | 'embedded-entry-block'
38
+ | 'embedded-asset-block'
39
+ | 'embedded-resource-block'
40
+ | 'table'
41
+ | 'table-row'
42
+ | 'table-cell'
43
+ | 'table-header-cell'
44
+ | 'asset-hyperlink'
45
+ | 'embedded-entry-inline'
46
+ | 'embedded-resource-inline'
47
+ | 'entry-hyperlink'
48
+ | 'hyperlink'
49
+ | 'resource-hyperlink'
50
+ | (string & {});
16
51
 
17
- export type RichTextLinkedNodeType = 'entry-hyperlink' | 'embedded-entry-block' | 'embedded-entry-inline'
52
+ export type RichTextLinkedNodeType = 'entry-hyperlink' | 'embedded-entry-block' | 'embedded-entry-inline';
18
53
 
19
54
  export interface RichTextValidationHelpers {
20
55
  addEnabledMarksValues(contentTypeId: string, fieldId: string, values: RichTextMarks | RichTextMarks[]): Promise<void>;
21
- removeEnabledMarksValues(contentTypeId: string, fieldId: string, values: RichTextMarks | RichTextMarks[]): Promise<void>;
22
- modifyEnabledMarksValues(contentTypeId: string, fieldId: string, valueMappingFunction: ValueMappingFunction<RichTextMarks>): Promise<void>;
56
+ removeEnabledMarksValues(
57
+ contentTypeId: string,
58
+ fieldId: string,
59
+ values: RichTextMarks | RichTextMarks[],
60
+ ): Promise<void>;
61
+ modifyEnabledMarksValues(
62
+ contentTypeId: string,
63
+ fieldId: string,
64
+ valueMappingFunction: ValueMappingFunction<RichTextMarks>,
65
+ ): Promise<void>;
23
66
 
24
- addEnabledNodeTypeValues(contentTypeId: string, fieldId: string, values: RichTextNodeType | RichTextNodeType[]): Promise<void>;
25
- removeEnabledNodeTypeValues(contentTypeId: string, fieldId: string, values: RichTextNodeType | RichTextNodeType[]): Promise<void>;
26
- modifyEnabledNodeTypeValues(contentTypeId: string, fieldId: string, valueMappingFunction: ValueMappingFunction<RichTextNodeType>): Promise<void>;
67
+ addEnabledNodeTypeValues(
68
+ contentTypeId: string,
69
+ fieldId: string,
70
+ values: RichTextNodeType | RichTextNodeType[],
71
+ ): Promise<void>;
72
+ removeEnabledNodeTypeValues(
73
+ contentTypeId: string,
74
+ fieldId: string,
75
+ values: RichTextNodeType | RichTextNodeType[],
76
+ ): Promise<void>;
77
+ modifyEnabledNodeTypeValues(
78
+ contentTypeId: string,
79
+ fieldId: string,
80
+ valueMappingFunction: ValueMappingFunction<RichTextNodeType>,
81
+ ): Promise<void>;
27
82
 
28
- addNodeContentTypeValues(contentTypeId: string, fieldId: string, nodeType: RichTextLinkedNodeType, values: string | string[]): Promise<void>;
29
- removeNodeContentTypeValues(contentTypeId: string, fieldId: string, nodeType: RichTextLinkedNodeType, values: string | string[]): Promise<void>;
30
- modifyNodeContentTypeValues(contentTypeId: string, fieldId: string, nodeType: RichTextLinkedNodeType, valueMappingFunction: ValueMappingFunction): Promise<void>;
83
+ addNodeContentTypeValues(
84
+ contentTypeId: string,
85
+ fieldId: string,
86
+ nodeType: RichTextLinkedNodeType,
87
+ values: string | string[],
88
+ ): Promise<void>;
89
+ removeNodeContentTypeValues(
90
+ contentTypeId: string,
91
+ fieldId: string,
92
+ nodeType: RichTextLinkedNodeType,
93
+ values: string | string[],
94
+ ): Promise<void>;
95
+ modifyNodeContentTypeValues(
96
+ contentTypeId: string,
97
+ fieldId: string,
98
+ nodeType: RichTextLinkedNodeType,
99
+ valueMappingFunction: ValueMappingFunction,
100
+ ): Promise<void>;
31
101
  }
32
102
 
33
103
  export interface ValidationHelpers {
34
104
  addLinkContentTypeValues(contentTypeId: string, fieldId: string, values: string | string[]): Promise<void>;
35
105
  removeLinkContentTypeValues(contentTypeId: string, fieldId: string, values: string | string[]): Promise<void>;
36
- modifyLinkContentTypeValues(contentTypeId: string, fieldId: string, valueMappingFunction: ValueMappingFunction): Promise<void>;
106
+ modifyLinkContentTypeValues(
107
+ contentTypeId: string,
108
+ fieldId: string,
109
+ valueMappingFunction: ValueMappingFunction,
110
+ ): Promise<void>;
37
111
 
38
- addInValues(contentTypeId: string, fieldId: string, values: string | string[], options?: AddValuesOptions): Promise<void>;
112
+ addInValues(
113
+ contentTypeId: string,
114
+ fieldId: string,
115
+ values: string | string[],
116
+ options?: AddValuesOptions,
117
+ ): Promise<void>;
39
118
  removeInValues(contentTypeId: string, fieldId: string, values: string | string[]): Promise<void>;
40
119
  modifyInValues(contentTypeId: string, fieldId: string, valueMappingFunction: ValueMappingFunction): Promise<void>;
41
120
 
@@ -172,7 +172,7 @@ const getValidationHelpers = (migration, context) => {
172
172
  removeValidationValues,
173
173
  contentTypeId,
174
174
  fieldId,
175
- values
175
+ values,
176
176
  );
177
177
  },
178
178
  async modifyEnabledNodeTypeValues(contentTypeId, fieldId, valueMappingFunction) {
@@ -186,7 +186,7 @@ const getValidationHelpers = (migration, context) => {
186
186
  addValidationValues,
187
187
  contentTypeId,
188
188
  fieldId,
189
- values
189
+ values,
190
190
  );
191
191
  },
192
192
  async removeNodeContentTypeValues(contentTypeId, fieldId, nodeType, values) {
@@ -195,7 +195,7 @@ const getValidationHelpers = (migration, context) => {
195
195
  removeValidationValues,
196
196
  contentTypeId,
197
197
  fieldId,
198
- values
198
+ values,
199
199
  );
200
200
  },
201
201
  async modifyNodeContentTypeValues(contentTypeId, fieldId, nodeType, valueMappingFunction) {
@@ -205,7 +205,7 @@ const getValidationHelpers = (migration, context) => {
205
205
  uniqueMappingFunction,
206
206
  contentTypeId,
207
207
  fieldId,
208
- []
208
+ [],
209
209
  );
210
210
  },
211
211
  },
package/lib/migration.js CHANGED
@@ -1,18 +1,22 @@
1
- const fs = require('fs-extra');
2
- const prettier = require('prettier');
3
- const path = require('path');
4
- const { stripIndent } = require('common-tags');
5
- const runMigration = require('contentful-migration/built/bin/cli').runMigration;
1
+ const fs = require("fs-extra");
2
+ const { format: oxfmt } = require("oxfmt");
3
+ const path = require("path");
4
+ const { stripIndent } = require("common-tags");
5
+ const { runMigration } = require("contentful-migration");
6
6
  const {
7
7
  getContentTypes,
8
8
  generateMigrationScript,
9
- } = require('contentful-cli/dist/lib/cmds/space_cmds/generate_cmds/migration');
10
- const pc = require('picocolors');
11
- const { getEnvironment, getOrganizationId } = require('./contentful');
9
+ } = require("contentful-cli/dist/lib/cmds/space_cmds/generate_cmds/migration");
10
+ const pc = require("picocolors");
11
+ const { getEnvironment, getOrganizationId } = require("./contentful");
12
12
 
13
- const { confirm, STATE_SUCCESS, STATE_FAILURE } = require('./config');
13
+ const { confirm, STATE_SUCCESS, STATE_FAILURE } = require("./config");
14
14
 
15
- const { storeMigration, getNewMigrations, getVersionFromFile } = require('./backend');
15
+ const {
16
+ storeMigration,
17
+ getNewMigrations,
18
+ getVersionFromFile,
19
+ } = require("./backend");
16
20
 
17
21
  const migrationHeader = stripIndent`/* eslint-env node */
18
22
  const { withHelpers } = require('@jungvonmatt/contentful-migrations');
@@ -33,42 +37,30 @@ const migrationHeader = stripIndent`/* eslint-env node */
33
37
  const createMigration = async (config) => {
34
38
  let module = false;
35
39
  try {
36
- const { readPackageUp } = await import('read-pkg-up');
40
+ const { readPackageUp } = await import("read-package-up");
37
41
  const data = await readPackageUp();
38
- module = data?.packageJson?.type === 'module';
42
+ module = data?.packageJson?.type === "module";
39
43
  } catch (err) {
40
44
  console.log(err);
41
45
  }
42
46
 
43
47
  const { directory } = config || {};
44
48
  const timestamp = Date.now();
45
- const filename = path.join(directory, `${timestamp}-migration.${module ? 'cjs' : 'js'}`);
49
+ const filename = path.join(
50
+ directory,
51
+ `${timestamp}-migration.${module ? "cjs" : "js"}`,
52
+ );
46
53
  const content = stripIndent`${migrationHeader}
47
54
  // Add your migration code here
48
55
  })`;
49
56
 
50
- await fs.outputFile(filename, await format(filename, content, config));
57
+ await fs.outputFile(filename, await format(filename, content));
51
58
  console.log(`Generated new migration file to ${pc.green(filename)}`);
52
59
  };
53
60
 
54
- const format = async (file, content, config) => {
55
- try {
56
- const prettierOptions = await prettier.resolveConfig(file, { editorconfig: true });
57
- return prettier.format(content, {
58
- parser: 'babel',
59
- ...prettierOptions,
60
- });
61
- } catch (error) {
62
- if (config?.verbose) {
63
- console.log(pc.red('Error resolving prettier config. Using default settings.'));
64
- console.log();
65
- console.log(error);
66
- console.log();
67
- }
68
- return prettier.format(content, {
69
- parser: 'babel',
70
- });
71
- }
61
+ const format = async (file, content) => {
62
+ const { code } = await oxfmt(file, content, { singleQuote: true });
63
+ return code;
72
64
  };
73
65
 
74
66
  /**
@@ -80,51 +72,56 @@ const fetchMigration = async (config) => {
80
72
  const client = await getEnvironment(config);
81
73
  let module = false;
82
74
  try {
83
- const { readPackageUp } = await import('read-pkg-up');
75
+ const { readPackageUp } = await import("read-package-up");
84
76
  const data = await readPackageUp();
85
- module = data?.packageJson?.type === 'module';
77
+ module = data?.packageJson?.type === "module";
86
78
  } catch (err) {
87
79
  console.log(err);
88
80
  }
89
81
 
90
82
  let timestamp = Date.now();
91
83
  const contentTypes = contentType
92
- ? (await Promise.all(contentType.map((ct) => getContentTypes(client, ct)))).flat()
84
+ ? (
85
+ await Promise.all(contentType.map((ct) => getContentTypes(client, ct)))
86
+ ).flat()
93
87
  : await getContentTypes(client);
94
88
 
95
89
  const promises = contentTypes.map(async (entry) => {
96
- const filename = path.join(directory, `${timestamp++}-create-${entry.sys.id}-migration.${module ? 'cjs' : 'js'}`);
90
+ const filename = path.join(
91
+ directory,
92
+ `${timestamp++}-create-${entry.sys.id}-migration.${module ? "cjs" : "js"}`,
93
+ );
97
94
 
98
95
  const content = await generateMigrationScript(client, [entry]);
99
96
  // Fetch migration script generated by contentful
100
97
  let modifiedContent = content.toString();
101
98
  // Modify migration script to use our helpers
102
- const testDefaultValueRegex = /(defaultValue\({\s*)[^\:]+([^\)]+)/g;
99
+ const testDefaultValueRegex = /(defaultValue\({\s*)[^:]+([^)]+)/g;
103
100
  if (testDefaultValueRegex.test(modifiedContent)) {
104
101
  modifiedContent = content
105
102
  .toString()
106
103
  // Add call to utils.getDefaultLocale() to the top
107
104
  .replace(
108
- 'module.exports = function (migration) {',
105
+ "module.exports = function (migration) {",
109
106
  `
110
107
  ${migrationHeader}
111
108
  const defaultLocale = await helpers.locale.getDefaultLocale();
112
- `
109
+ `,
113
110
  )
114
111
  // Replace the default locale with defaultLocale.code so that the migration
115
112
  // still works as expected when the locale is changed in contentful
116
- .replace(testDefaultValueRegex, '$1[defaultLocale.code]$2')
113
+ .replace(testDefaultValueRegex, "$1[defaultLocale.code]$2")
117
114
  // Add a closing parentheses as we wrap the migration function.
118
- .replace(/};\s*$/g, '});');
115
+ .replace(/};\s*$/g, "});");
119
116
  } else {
120
117
  // If we don't have a default value we just wrap the migration function with our withHelpers wrapper
121
118
  modifiedContent = content
122
119
  .toString()
123
- .replace('module.exports = function (migration) {', migrationHeader)
124
- .replace(/};\s*$/g, '});');
120
+ .replace("module.exports = function (migration) {", migrationHeader)
121
+ .replace(/};\s*$/g, "});");
125
122
  }
126
123
 
127
- await fs.outputFile(filename, await format(filename, modifiedContent, config));
124
+ await fs.outputFile(filename, await format(filename, modifiedContent));
128
125
  console.log(`Generated new migration file to ${pc.green(filename)}`);
129
126
  });
130
127
 
@@ -145,7 +142,9 @@ const executeMigration = async (file, config) => {
145
142
  const name = path.basename(file);
146
143
  const version = getVersionFromFile(file);
147
144
  if (!version) {
148
- console.error(`Invalid migration file name "${name}". Must start with a timestamp.`);
145
+ console.error(
146
+ `Invalid migration file name "${name}". Must start with a timestamp.`,
147
+ );
149
148
  process.exit(1);
150
149
  }
151
150
 
@@ -163,7 +162,9 @@ const executeMigration = async (file, config) => {
163
162
  options.host = config.host;
164
163
  }
165
164
 
166
- console.log(`\nRun migration ${pc.green(version)} in environment ${pc.green(environmentId)}`);
165
+ console.log(
166
+ `\nRun migration ${pc.green(version)} in environment ${pc.green(environmentId)}`,
167
+ );
167
168
  const proceed = await confirm(config);
168
169
  if (!proceed) {
169
170
  return;
@@ -172,8 +173,13 @@ const executeMigration = async (file, config) => {
172
173
  await runMigration(options);
173
174
  await storeMigration({ version, name, state: STATE_SUCCESS }, config);
174
175
  } catch (error) {
175
- const message = (error.errors || [error]).map((error) => error.message).join('\n');
176
- await storeMigration({ version, name, state: STATE_FAILURE, message }, config);
176
+ const message = (error.errors || [error])
177
+ .map((error) => error.message)
178
+ .join("\n");
179
+ await storeMigration(
180
+ { version, name, state: STATE_FAILURE, message },
181
+ config,
182
+ );
177
183
 
178
184
  throw error;
179
185
  }
@@ -197,8 +203,15 @@ const runMigrations = async (config) => {
197
203
  console.log(error.message);
198
204
  throw error;
199
205
  }
200
- console.log(`Found ${pc.green(migrations.length)} unexecuted migrations in environment ${pc.green(environmentId)}`);
201
-
206
+ console.log(
207
+ `Found ${pc.green(migrations.length)} unexecuted migrations in environment ${pc.green(environmentId)}`,
208
+ );
209
+ if (config?.verbose) {
210
+ for (const migration of migrations) {
211
+ console.log(` ${pc.green(migration)}`);
212
+ }
213
+ console.log();
214
+ }
202
215
  const proceed = migrations.length === 0 || (await confirm(config));
203
216
  if (!proceed) {
204
217
  return;
@@ -214,7 +227,7 @@ const runMigrations = async (config) => {
214
227
  }
215
228
  }
216
229
 
217
- console.log(pc.green('\nAll done'), '🚀');
230
+ console.log(pc.green("\nAll done"), "🚀");
218
231
  };
219
232
 
220
233
  module.exports.fetchMigration = fetchMigration;