1 | const path = require('path');
|
2 | const fs = require('fs-extra');
|
3 | const prettier = require('prettier');
|
4 | const { fetchBuiltinMapping } = require('./api/designManager');
|
5 | const { fetchModule } = require('./api/fileMapper');
|
6 | const { logger } = require('./logger');
|
7 |
|
8 | const META_KEYS_WHITELIST = new Set([
|
9 | 'content_tags',
|
10 | 'css_assets',
|
11 | 'default',
|
12 | 'editable_contexts',
|
13 | 'external_js',
|
14 | 'extra_classes',
|
15 | 'global',
|
16 | 'help_text',
|
17 | 'host_template_types',
|
18 | 'icon',
|
19 | 'is_available_for_new_content',
|
20 | 'js_assets',
|
21 | 'label',
|
22 | 'master_language',
|
23 | 'other_assets',
|
24 | 'smart_type',
|
25 | 'tags',
|
26 | ]);
|
27 |
|
28 | function cleanMetaJson(source) {
|
29 | const meta = JSON.parse(source);
|
30 | const out = {};
|
31 | META_KEYS_WHITELIST.forEach(key => {
|
32 | if (meta[key]) {
|
33 | out[key] = meta[key];
|
34 | }
|
35 | });
|
36 |
|
37 | return JSON.stringify(out);
|
38 | }
|
39 |
|
40 | function writeFiles(dest, tree) {
|
41 | if (tree.source) {
|
42 | let source = tree.source;
|
43 | if (path.basename(tree.path) === 'meta.json') {
|
44 | source = cleanMetaJson(source);
|
45 | }
|
46 | if (path.extname(tree.path) === '.json') {
|
47 | source = prettier.format(source, {
|
48 | parser: 'json',
|
49 | });
|
50 | }
|
51 | fs.outputFileSync(path.join(dest, tree.path), source);
|
52 | logger.debug('Wrote file %s', tree.path);
|
53 | }
|
54 | tree.children.forEach(subtree => writeFiles(dest, subtree));
|
55 | }
|
56 |
|
57 | async function downloadModule(portalId, moduleId, dest) {
|
58 | let response;
|
59 | try {
|
60 | response = await fetchModule(portalId, moduleId);
|
61 | } catch (error) {
|
62 | logger.error('Failed to download %s', moduleId);
|
63 | if (error.response && error.response.body) {
|
64 | logger.error(error.response.body);
|
65 | } else {
|
66 | logger.error(error.message);
|
67 | }
|
68 | return;
|
69 | }
|
70 | writeFiles(dest, response);
|
71 | logger.log('Downloaded %s', response.path);
|
72 | }
|
73 |
|
74 | async function downloadBuiltinModules(portalId, dest) {
|
75 | const builtinMappings = await fetchBuiltinMapping(portalId);
|
76 | const downloaded = new Set();
|
77 | Object.values(builtinMappings).forEach(moduleId => {
|
78 | if (downloaded.has(moduleId)) {
|
79 | return;
|
80 | }
|
81 | logger.log('Downloading module %s', moduleId);
|
82 | downloaded.add(moduleId);
|
83 | downloadModule(portalId, moduleId, dest);
|
84 | logger.error('Failed to download %s', moduleId);
|
85 | });
|
86 | }
|
87 |
|
88 | module.exports = {
|
89 | downloadModule,
|
90 | downloadBuiltinModules,
|
91 | };
|