@jungvonmatt/contentful-migrations 5.0.0 → 5.1.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.
- package/index.js +3 -2
- package/lib/backend.js +30 -9
- package/lib/config.js +2 -2
- package/lib/doc.js +7 -6
- package/lib/migration.js +33 -4
- package/package.json +12 -12
package/index.js
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
/* eslint-env node */
|
|
5
5
|
const fs = require('fs-extra');
|
|
6
6
|
const path = require('path');
|
|
7
|
-
const pkgUp = require('pkg-up');
|
|
8
7
|
const chalk = require('chalk');
|
|
9
8
|
const { Command } = require('commander');
|
|
10
9
|
|
|
@@ -79,6 +78,8 @@ program
|
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
// try to store in package.json
|
|
81
|
+
|
|
82
|
+
const {pkgUp} = await import('pkg-up');
|
|
82
83
|
const localPkg = await pkgUp();
|
|
83
84
|
if (localPkg) {
|
|
84
85
|
const packageJson = await fs.readJson(localPkg);
|
|
@@ -224,7 +225,7 @@ program
|
|
|
224
225
|
actionRunner(async (environmentId, options) => {
|
|
225
226
|
const { remove, create, reset } = options;
|
|
226
227
|
const config = await getConfig(parseArgs({ ...(options || {}), environmentId }));
|
|
227
|
-
const verified = await
|
|
228
|
+
const verified = await askMissing(config, ['accessToken', 'spaceId', 'environmentId']);
|
|
228
229
|
|
|
229
230
|
if (create) {
|
|
230
231
|
return createEnvironment(environmentId, verified);
|
package/lib/backend.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
const globby = require('globby');
|
|
3
2
|
const chalk = require('chalk');
|
|
4
3
|
const cliProgress = require('cli-progress');
|
|
5
4
|
const { getEnvironment, getDefaultLocale } = require('./contentful');
|
|
@@ -192,7 +191,9 @@ const migrateToContentStorage = async (config) => {
|
|
|
192
191
|
|
|
193
192
|
const client = await getEnvironment(config);
|
|
194
193
|
const version = await getMigrationVersionFromTag(config);
|
|
195
|
-
|
|
194
|
+
|
|
195
|
+
const {globby} = await import('globby');
|
|
196
|
+
const migrations = await globby([`${directory}/*.js`,`${directory}/*.cjs`]);
|
|
196
197
|
const environmentId = client.sys.id;
|
|
197
198
|
const filtered = migrations.filter((file) => {
|
|
198
199
|
const name = path.basename(file);
|
|
@@ -351,25 +352,45 @@ const getLatestVersion = async (config) => {
|
|
|
351
352
|
return getMigrationVersionFromTag(config);
|
|
352
353
|
};
|
|
353
354
|
|
|
355
|
+
const getVersionFromFile = file => {
|
|
356
|
+
const name = path.basename(file);
|
|
357
|
+
const [, num] = /^(\d+)-/.exec(name);
|
|
358
|
+
return parseInt(num,10);
|
|
359
|
+
}
|
|
360
|
+
|
|
354
361
|
/**
|
|
355
362
|
* Get all unexecuted migration files
|
|
356
363
|
* @param {Object} config The config object including all required data
|
|
357
364
|
*/
|
|
358
365
|
const getNewMigrations = async (config) => {
|
|
359
|
-
const { directory, storage } = config || {};
|
|
360
|
-
const
|
|
366
|
+
const { directory, storage, migrationContentTypeId } = config || {};
|
|
367
|
+
const {globby} = await import('globby');
|
|
368
|
+
const migrations = (await globby([`${directory}/*.js`,`${directory}/*.cjs`])).sort((a,b) => {
|
|
369
|
+
const numA = getVersionFromFile(a);
|
|
370
|
+
const numB = getVersionFromFile(b);
|
|
371
|
+
return numA-numB;
|
|
372
|
+
});
|
|
361
373
|
|
|
362
374
|
if (storage === STORAGE_CONTENT) {
|
|
363
375
|
try {
|
|
364
376
|
const versions = await getMigrationVersions(config);
|
|
365
377
|
|
|
366
|
-
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
return !(versions || []).includes(parseInt(num, 10));
|
|
378
|
+
const result = migrations.filter((file) => {
|
|
379
|
+
const num = getVersionFromFile(file);
|
|
380
|
+
return !(versions || []).includes(num);
|
|
371
381
|
});
|
|
382
|
+
|
|
383
|
+
return result;
|
|
372
384
|
} catch (error) {
|
|
385
|
+
// check if we have a migration scheduled which adds the initial content-type
|
|
386
|
+
const regexp = new RegExp(`createContentType\\(['"]${migrationContentTypeId}['"]\\)`,'mg');
|
|
387
|
+
const initial = (await Promise.all(migrations.map(async file => {
|
|
388
|
+
return fs.readFile(file, 'utf8');
|
|
389
|
+
}))).some(content => regexp.test(content));
|
|
390
|
+
|
|
391
|
+
if (initial) {
|
|
392
|
+
return migrations;
|
|
393
|
+
}
|
|
373
394
|
console.error(chalk.red('\nError:'), `Missing migration content type. Run ${chalk.cyan('npx migrations init')}`);
|
|
374
395
|
process.exit(1);
|
|
375
396
|
}
|
package/lib/config.js
CHANGED
|
@@ -188,7 +188,7 @@ const confirm = async (config = {}) => {
|
|
|
188
188
|
if (config.yes) {
|
|
189
189
|
return true;
|
|
190
190
|
}
|
|
191
|
-
const {
|
|
191
|
+
const { check } = await inquirer.prompt([
|
|
192
192
|
{
|
|
193
193
|
type: 'confirm',
|
|
194
194
|
name: 'check',
|
|
@@ -197,7 +197,7 @@ const confirm = async (config = {}) => {
|
|
|
197
197
|
},
|
|
198
198
|
]);
|
|
199
199
|
|
|
200
|
-
return
|
|
200
|
+
return check;
|
|
201
201
|
};
|
|
202
202
|
|
|
203
203
|
module.exports.getConfig = getConfig;
|
package/lib/doc.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
const table = require('markdown-table');
|
|
3
2
|
const chalk = require('chalk');
|
|
4
3
|
const fs = require('fs-extra');
|
|
5
4
|
const Mustache = require('mustache');
|
|
6
5
|
const { getEditorInterfaces, getContentTypes, getContentTypeId, getContentId } = require('./contentful');
|
|
7
6
|
|
|
8
|
-
const getFieldTable = (fields, editorInterfaces) => {
|
|
7
|
+
const getFieldTable = async (fields, editorInterfaces) => {
|
|
8
|
+
const { markdownTable: table } = await import('markdown-table');
|
|
9
9
|
const { controls = [] } = editorInterfaces;
|
|
10
10
|
return table([
|
|
11
11
|
['Id', 'Name', 'Type', 'Required', 'Localized', 'HelpText', 'Remarks'],
|
|
@@ -27,7 +27,8 @@ const getFieldTable = (fields, editorInterfaces) => {
|
|
|
27
27
|
]);
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
const createDoc = (contentType, editorInterfaces) => {
|
|
30
|
+
const createDoc = async (contentType, editorInterfaces) => {
|
|
31
|
+
const { markdownTable: table } = await import('markdown-table');
|
|
31
32
|
const { name, displayField, description, sys, fields } = contentType || {};
|
|
32
33
|
const { id } = sys || {};
|
|
33
34
|
|
|
@@ -50,7 +51,7 @@ ${description}
|
|
|
50
51
|
|
|
51
52
|
## Fields
|
|
52
53
|
|
|
53
|
-
${getFieldTable(fields, editorInterfaces)}
|
|
54
|
+
${await getFieldTable(fields, editorInterfaces)}
|
|
54
55
|
`;
|
|
55
56
|
};
|
|
56
57
|
|
|
@@ -68,7 +69,7 @@ const prepareData = (contentType, editorInterfaces) => {
|
|
|
68
69
|
};
|
|
69
70
|
|
|
70
71
|
const getCustomRenderer = async (template) => {
|
|
71
|
-
if (template && template.endsWith('.js')) {
|
|
72
|
+
if (template && (template.endsWith('.js') || template.endsWith('.cjs'))) {
|
|
72
73
|
const module = await import(path.resolve(template));
|
|
73
74
|
return (data) => module.default(data);
|
|
74
75
|
} else if (template && template.endsWith('.mustache')) {
|
|
@@ -98,7 +99,7 @@ const createOfflineDocs = async (config) => {
|
|
|
98
99
|
const data = prepareData(contentType, interfaces);
|
|
99
100
|
content = await customRender(data);
|
|
100
101
|
} else {
|
|
101
|
-
content = createDoc(contentType, interfaces);
|
|
102
|
+
content = await createDoc(contentType, interfaces);
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
const filename = `${getContentId(contentType)}.${extension}`;
|
package/lib/migration.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const fs = require('fs-extra');
|
|
2
|
+
const prettier = require('prettier');
|
|
2
3
|
const path = require('path');
|
|
3
4
|
const { stripIndent } = require('common-tags');
|
|
4
5
|
const runMigration = require('contentful-migration/built/bin/cli').runMigration;
|
|
@@ -19,9 +20,18 @@ const { storeMigration, getNewMigrations } = require('./backend');
|
|
|
19
20
|
* @param {Object} config The config object including all required data
|
|
20
21
|
*/
|
|
21
22
|
const createMigration = async (config) => {
|
|
23
|
+
let module = false;
|
|
24
|
+
try {
|
|
25
|
+
const { readPackageUp } = await import('read-pkg-up');
|
|
26
|
+
const data = await readPackageUp();
|
|
27
|
+
module = data?.packageJson?.type === 'module';
|
|
28
|
+
} catch (err) {
|
|
29
|
+
console.log(err);
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
const { directory } = config || {};
|
|
23
33
|
const timestamp = Date.now();
|
|
24
|
-
const filename = path.join(directory, `${timestamp}-migration
|
|
34
|
+
const filename = path.join(directory, `${timestamp}-migration.${module ? 'cjs' : 'js'}`);
|
|
25
35
|
const content = stripIndent`
|
|
26
36
|
/* eslint-env node */
|
|
27
37
|
|
|
@@ -33,10 +43,18 @@ const createMigration = async (config) => {
|
|
|
33
43
|
// See: https://github.com/contentful/contentful-migration
|
|
34
44
|
}`;
|
|
35
45
|
|
|
36
|
-
await fs.outputFile(filename, content);
|
|
46
|
+
await fs.outputFile(filename, await format(filename, content));
|
|
37
47
|
console.log(`Generated new migration file to ${chalk.green(filename)}`);
|
|
38
48
|
};
|
|
39
49
|
|
|
50
|
+
const format = async (file, content) => {
|
|
51
|
+
const prettierOptions = await prettier.resolveConfig(file, { editorconfig: true });
|
|
52
|
+
return prettier.format(content, {
|
|
53
|
+
parser: 'babel',
|
|
54
|
+
...prettierOptions,
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
40
58
|
/**
|
|
41
59
|
* Fetch migration from contentful
|
|
42
60
|
* @param {Object} config The config object including all required data
|
|
@@ -44,15 +62,26 @@ const createMigration = async (config) => {
|
|
|
44
62
|
const fetchMigration = async (config) => {
|
|
45
63
|
const { contentType, directory } = config || {};
|
|
46
64
|
const client = await getEnvironment(config);
|
|
65
|
+
let module = false;
|
|
66
|
+
try {
|
|
67
|
+
const { readPackageUp } = await import('read-pkg-up');
|
|
68
|
+
const data = await readPackageUp();
|
|
69
|
+
module = data?.packageJson?.type === 'module';
|
|
70
|
+
} catch (err) {
|
|
71
|
+
console.log(err);
|
|
72
|
+
}
|
|
73
|
+
|
|
47
74
|
let timestamp = Date.now();
|
|
48
75
|
const contentTypes = contentType
|
|
49
76
|
? (await Promise.all(contentType.map((ct) => getContentTypes(client, ct)))).flat()
|
|
50
77
|
: await getContentTypes(client);
|
|
51
78
|
|
|
52
79
|
const promises = contentTypes.map(async (entry) => {
|
|
53
|
-
const filename = path.join(directory, `${timestamp++}-create-${entry.sys.id}-migration
|
|
80
|
+
const filename = path.join(directory, `${timestamp++}-create-${entry.sys.id}-migration.${module ? 'cjs' : 'js'}`);
|
|
81
|
+
|
|
54
82
|
const content = await generateMigrationScript(client, [entry]);
|
|
55
|
-
|
|
83
|
+
|
|
84
|
+
await fs.outputFile(filename, await format(filename, content));
|
|
56
85
|
console.log(`Generated new migration file to ${chalk.green(filename)}`);
|
|
57
86
|
});
|
|
58
87
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jungvonmatt/contentful-migrations",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.1",
|
|
4
4
|
"description": "Helper to handle migrations in contentful",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -30,39 +30,40 @@
|
|
|
30
30
|
"content-type"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@contentful/rich-text-plain-text-renderer": "^15.
|
|
33
|
+
"@contentful/rich-text-plain-text-renderer": "^15.6.2",
|
|
34
34
|
"array.prototype.flatmap": "^1.2.5",
|
|
35
35
|
"ascii-tree": "^0.3.0",
|
|
36
36
|
"chalk": "^4.1.2",
|
|
37
37
|
"cli-progress": "^3.9.1",
|
|
38
38
|
"commander": "^8.3.0",
|
|
39
|
-
"common-tags": "^1.8.
|
|
39
|
+
"common-tags": "^1.8.2",
|
|
40
40
|
"contentful-cli": "^1.8.23",
|
|
41
41
|
"contentful-import": "^8.2.22",
|
|
42
|
-
"contentful-management": "^7.
|
|
42
|
+
"contentful-management": "^7.45.2",
|
|
43
43
|
"contentful-migration": "^4.3.0",
|
|
44
44
|
"cosmiconfig": "^7.0.1",
|
|
45
45
|
"deep-diff": "^1.0.2",
|
|
46
46
|
"diff": "^5.0.0",
|
|
47
47
|
"dotenv": "^10.0.0",
|
|
48
48
|
"fs-extra": "^10.0.0",
|
|
49
|
-
"globby": "^
|
|
49
|
+
"globby": "^12.0.2",
|
|
50
50
|
"inquirer": "^8.2.0",
|
|
51
|
-
"markdown-table": "^
|
|
51
|
+
"markdown-table": "^3.0.1",
|
|
52
52
|
"merge-options": "^3.0.4",
|
|
53
53
|
"mustache": "^4.2.0",
|
|
54
|
-
"node-fetch": "^3.
|
|
54
|
+
"node-fetch": "^3.1.0",
|
|
55
55
|
"node-object-hash": "^2.3.10",
|
|
56
|
-
"pkg-up": "^
|
|
56
|
+
"pkg-up": "^4.0.0",
|
|
57
|
+
"prettier": "^2.4.1",
|
|
58
|
+
"read-pkg-up": "^9.0.0"
|
|
57
59
|
},
|
|
58
60
|
"devDependencies": {
|
|
59
61
|
"babel-eslint": "^10.1.0",
|
|
60
|
-
"eslint": "^8.
|
|
62
|
+
"eslint": "^8.3.0",
|
|
61
63
|
"eslint-config-prettier": "^8.3.0",
|
|
62
64
|
"eslint-plugin-prettier": "^4.0.0",
|
|
63
65
|
"husky": "^7.0.4",
|
|
64
|
-
"lint-staged": "^
|
|
65
|
-
"prettier": "^2.4.1"
|
|
66
|
+
"lint-staged": "^12.1.2"
|
|
66
67
|
},
|
|
67
68
|
"publishConfig": {
|
|
68
69
|
"access": "public"
|
|
@@ -108,7 +109,6 @@
|
|
|
108
109
|
}
|
|
109
110
|
},
|
|
110
111
|
"migrations": {
|
|
111
|
-
"spaceId": "89na9aswdzfj",
|
|
112
112
|
"storage": "content",
|
|
113
113
|
"migrationContentTypeId": "contentful-migrations",
|
|
114
114
|
"directory": "migrations"
|