@contentstack/cli-cm-export 1.21.0 → 1.22.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/README.md +3 -3
- package/lib/commands/cm/stacks/export.js +7 -4
- package/lib/config/index.js +7 -0
- package/lib/export/module-exporter.js +4 -3
- package/lib/export/modules/composable-studio.d.ts +15 -0
- package/lib/export/modules/composable-studio.js +87 -0
- package/lib/export/modules/content-types.js +3 -3
- package/lib/export/modules/custom-roles.js +18 -20
- package/lib/export/modules/entries.js +7 -7
- package/lib/export/modules/environments.js +13 -13
- package/lib/export/modules/extensions.js +16 -16
- package/lib/export/modules/global-fields.js +16 -16
- package/lib/export/modules/labels.js +17 -17
- package/lib/export/modules/locales.js +17 -17
- package/lib/export/modules/marketplace-apps.js +32 -32
- package/lib/export/modules/personalize.js +14 -14
- package/lib/export/modules/stack.js +26 -26
- package/lib/export/modules/taxonomies.d.ts +1 -0
- package/lib/export/modules/taxonomies.js +23 -6
- package/lib/export/modules-js/assets.js +3 -3
- package/lib/types/default-config.d.ts +6 -0
- package/lib/types/index.d.ts +27 -1
- package/lib/utils/basic-login.js +1 -1
- package/lib/utils/export-config-handler.js +5 -5
- package/lib/utils/file-helper.js +1 -1
- package/messages/index.json +59 -53
- package/oclif.manifest.json +2 -2
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ $ npm install -g @contentstack/cli-cm-export
|
|
|
48
48
|
$ csdx COMMAND
|
|
49
49
|
running command...
|
|
50
50
|
$ csdx (--version)
|
|
51
|
-
@contentstack/cli-cm-export/1.
|
|
51
|
+
@contentstack/cli-cm-export/1.22.1 linux-x64 node-v22.21.1
|
|
52
52
|
$ csdx --help [COMMAND]
|
|
53
53
|
USAGE
|
|
54
54
|
$ csdx COMMAND
|
|
@@ -83,7 +83,7 @@ FLAGS
|
|
|
83
83
|
-m, --module=<value> [optional] Specific module name. If not specified, the export command will export all
|
|
84
84
|
the modules to the stack. The available modules are assets, content-types, entries,
|
|
85
85
|
environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks,
|
|
86
|
-
workflows, custom-roles, and
|
|
86
|
+
workflows, custom-roles, taxonomies, and studio.
|
|
87
87
|
-t, --content-types=<value>... [optional] The UID of the content type(s) whose content you want to export. In case
|
|
88
88
|
of multiple content types, specify the IDs separated by spaces.
|
|
89
89
|
-y, --yes [optional] Force override all Marketplace prompts.
|
|
@@ -133,7 +133,7 @@ FLAGS
|
|
|
133
133
|
-m, --module=<value> [optional] Specific module name. If not specified, the export command will export all
|
|
134
134
|
the modules to the stack. The available modules are assets, content-types, entries,
|
|
135
135
|
environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks,
|
|
136
|
-
workflows, custom-roles, and
|
|
136
|
+
workflows, custom-roles, taxonomies, and studio.
|
|
137
137
|
-t, --content-types=<value>... [optional] The UID of the content type(s) whose content you want to export. In case
|
|
138
138
|
of multiple content types, specify the IDs separated by spaces.
|
|
139
139
|
-y, --yes [optional] Force override all Marketplace prompts.
|
|
@@ -25,12 +25,12 @@ class ExportCommand extends cli_command_1.Command {
|
|
|
25
25
|
(0, utils_1.writeExportMetaFile)(exportConfig);
|
|
26
26
|
}
|
|
27
27
|
cli_utilities_1.log.success(`The content of the stack ${exportConfig.apiKey} has been exported successfully!`, exportConfig.context);
|
|
28
|
-
cli_utilities_1.log.info(`The exported content has been stored at '${exportDir}'
|
|
29
|
-
cli_utilities_1.log.success(`The log has been stored at '${(0, cli_utilities_1.getLogPath)()}'
|
|
28
|
+
cli_utilities_1.log.info(`The exported content has been stored at '${exportDir}'.`, exportConfig.context);
|
|
29
|
+
cli_utilities_1.log.success(`The log has been stored at '${(0, cli_utilities_1.getLogPath)()}'.`, exportConfig.context);
|
|
30
30
|
}
|
|
31
31
|
catch (error) {
|
|
32
32
|
(0, cli_utilities_1.handleAndLogError)(error);
|
|
33
|
-
cli_utilities_1.log.info(`The log has been stored at '${(0, cli_utilities_1.getLogPath)()}'
|
|
33
|
+
cli_utilities_1.log.info(`The log has been stored at '${(0, cli_utilities_1.getLogPath)()}'.`);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
// Create export context object
|
|
@@ -58,6 +58,9 @@ class ExportCommand extends cli_command_1.Command {
|
|
|
58
58
|
if (this.personalizeUrl) {
|
|
59
59
|
exportConfig.modules.personalize.baseURL[exportConfig.region.name] = this.personalizeUrl;
|
|
60
60
|
}
|
|
61
|
+
if (this.composableStudioUrl) {
|
|
62
|
+
exportConfig.modules['composable-studio'].apiBaseUrl = this.composableStudioUrl;
|
|
63
|
+
}
|
|
61
64
|
}
|
|
62
65
|
}
|
|
63
66
|
exports.default = ExportCommand;
|
|
@@ -113,7 +116,7 @@ ExportCommand.flags = {
|
|
|
113
116
|
}),
|
|
114
117
|
module: cli_utilities_1.flags.string({
|
|
115
118
|
char: 'm',
|
|
116
|
-
description: '[optional] Specific module name. If not specified, the export command will export all the modules to the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, and
|
|
119
|
+
description: '[optional] Specific module name. If not specified, the export command will export all the modules to the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, taxonomies, and studio.',
|
|
117
120
|
parse: (0, cli_utilities_1.printFlagDeprecation)(['-m'], ['--module']),
|
|
118
121
|
}),
|
|
119
122
|
'content-types': cli_utilities_1.flags.string({
|
package/lib/config/index.js
CHANGED
|
@@ -40,6 +40,7 @@ const config = {
|
|
|
40
40
|
'entries',
|
|
41
41
|
'labels',
|
|
42
42
|
'marketplace-apps',
|
|
43
|
+
'composable-studio',
|
|
43
44
|
],
|
|
44
45
|
locales: {
|
|
45
46
|
dirName: 'locales',
|
|
@@ -213,6 +214,12 @@ const config = {
|
|
|
213
214
|
dirName: 'marketplace_apps',
|
|
214
215
|
fileName: 'marketplace_apps.json',
|
|
215
216
|
},
|
|
217
|
+
'composable-studio': {
|
|
218
|
+
dirName: 'composable_studio',
|
|
219
|
+
fileName: 'composable_studio.json',
|
|
220
|
+
apiBaseUrl: 'https://composable-studio-api.contentstack.com',
|
|
221
|
+
apiVersion: 'v1',
|
|
222
|
+
},
|
|
216
223
|
taxonomies: {
|
|
217
224
|
dirName: 'taxonomies',
|
|
218
225
|
fileName: 'taxonomies.json',
|
|
@@ -41,7 +41,7 @@ class ModuleExporter {
|
|
|
41
41
|
this.exportConfig.branchName = branch.uid;
|
|
42
42
|
this.stackAPIClient.stackHeaders.branch = branch.uid;
|
|
43
43
|
this.exportConfig.branchDir = path.join(this.exportConfig.exportDir, branch.uid);
|
|
44
|
-
cli_utilities_1.log.info(`Exporting content from branch ${branch.uid}
|
|
44
|
+
cli_utilities_1.log.info(`Exporting content from branch '${branch.uid}'...`, this.exportConfig.context);
|
|
45
45
|
(0, utils_1.writeExportMetaFile)(this.exportConfig, this.exportConfig.branchDir);
|
|
46
46
|
await this.export();
|
|
47
47
|
cli_utilities_1.log.success(`The content of branch ${branch.uid} has been exported successfully!`, this.exportConfig.context);
|
|
@@ -61,7 +61,7 @@ class ModuleExporter {
|
|
|
61
61
|
return this.exportAllModules();
|
|
62
62
|
}
|
|
63
63
|
async exportByModuleByName(moduleName) {
|
|
64
|
-
cli_utilities_1.log.info(`Exporting module: ${moduleName}
|
|
64
|
+
cli_utilities_1.log.info(`Exporting module: '${moduleName}'...`, this.exportConfig.context);
|
|
65
65
|
// export the modules by name
|
|
66
66
|
// calls the module runner which inturn calls the module itself
|
|
67
67
|
let exportedModuleResponse;
|
|
@@ -94,7 +94,8 @@ class ModuleExporter {
|
|
|
94
94
|
exportModules.push('stack');
|
|
95
95
|
}
|
|
96
96
|
if (!this.exportConfig.skipDependencies) {
|
|
97
|
-
const
|
|
97
|
+
const moduleConfig = this.exportConfig.modules[moduleName];
|
|
98
|
+
const dependencies = (moduleConfig === null || moduleConfig === void 0 ? void 0 : moduleConfig.dependencies) || [];
|
|
98
99
|
if (dependencies.length > 0) {
|
|
99
100
|
exportModules = exportModules.concat(dependencies);
|
|
100
101
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { HttpClient } from '@contentstack/cli-utilities';
|
|
2
|
+
import { ModuleClassParams, ComposableStudioConfig, ExportConfig, ComposableStudioProject } from '../../types';
|
|
3
|
+
export default class ExportComposableStudio {
|
|
4
|
+
protected composableStudioConfig: ComposableStudioConfig;
|
|
5
|
+
protected composableStudioProject: ComposableStudioProject | null;
|
|
6
|
+
protected apiClient: HttpClient;
|
|
7
|
+
composableStudioPath: string;
|
|
8
|
+
exportConfig: ExportConfig;
|
|
9
|
+
constructor({ exportConfig }: Omit<ModuleClassParams, 'stackAPIClient' | 'moduleName'>);
|
|
10
|
+
start(): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Export Studio projects connected to the current stack
|
|
13
|
+
*/
|
|
14
|
+
exportProjects(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const node_path_1 = require("node:path");
|
|
4
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
5
|
+
const utils_1 = require("../../utils");
|
|
6
|
+
class ExportComposableStudio {
|
|
7
|
+
constructor({ exportConfig }) {
|
|
8
|
+
this.composableStudioProject = null;
|
|
9
|
+
this.exportConfig = exportConfig;
|
|
10
|
+
this.composableStudioConfig = exportConfig.modules['composable-studio'];
|
|
11
|
+
this.exportConfig.context.module = 'composable-studio';
|
|
12
|
+
// Initialize HttpClient with Studio API base URL
|
|
13
|
+
this.apiClient = new cli_utilities_1.HttpClient();
|
|
14
|
+
this.apiClient.baseUrl(`${this.composableStudioConfig.apiBaseUrl}/${this.composableStudioConfig.apiVersion}`);
|
|
15
|
+
}
|
|
16
|
+
async start() {
|
|
17
|
+
cli_utilities_1.log.debug('Starting Studio project export process...', this.exportConfig.context);
|
|
18
|
+
if (!(0, cli_utilities_1.isAuthenticated)()) {
|
|
19
|
+
cli_utilities_1.cliux.print('WARNING!!! To export Studio projects, you must be logged in. Please check csdx auth:login --help to log in', { color: 'yellow' });
|
|
20
|
+
return Promise.resolve();
|
|
21
|
+
}
|
|
22
|
+
this.composableStudioPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.composableStudioConfig.dirName);
|
|
23
|
+
cli_utilities_1.log.debug(`Studio folder path: ${this.composableStudioPath}`, this.exportConfig.context);
|
|
24
|
+
await utils_1.fsUtil.makeDirectory(this.composableStudioPath);
|
|
25
|
+
cli_utilities_1.log.debug('Created Studio directory', this.exportConfig.context);
|
|
26
|
+
this.exportConfig.org_uid = this.exportConfig.org_uid || (await (0, utils_1.getOrgUid)(this.exportConfig));
|
|
27
|
+
cli_utilities_1.log.debug(`Organization UID: ${this.exportConfig.org_uid}`, this.exportConfig.context);
|
|
28
|
+
await this.exportProjects();
|
|
29
|
+
cli_utilities_1.log.debug('Studio project export process completed', this.exportConfig.context);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Export Studio projects connected to the current stack
|
|
33
|
+
*/
|
|
34
|
+
async exportProjects() {
|
|
35
|
+
var _a, _b;
|
|
36
|
+
cli_utilities_1.log.debug('Starting Studio project export...', this.exportConfig.context);
|
|
37
|
+
try {
|
|
38
|
+
// Get authentication details - following personalization-api-adapter pattern
|
|
39
|
+
cli_utilities_1.log.debug('Initializing Studio API authentication...', this.exportConfig.context);
|
|
40
|
+
await cli_utilities_1.authenticationHandler.getAuthDetails();
|
|
41
|
+
const token = cli_utilities_1.authenticationHandler.accessToken;
|
|
42
|
+
cli_utilities_1.log.debug(`Authentication type: ${cli_utilities_1.authenticationHandler.isOauthEnabled ? 'OAuth' : 'Token'}`, this.exportConfig.context);
|
|
43
|
+
// Set authentication headers based on auth type
|
|
44
|
+
if (cli_utilities_1.authenticationHandler.isOauthEnabled) {
|
|
45
|
+
cli_utilities_1.log.debug('Setting OAuth authorization header', this.exportConfig.context);
|
|
46
|
+
this.apiClient.headers({ authorization: token });
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
cli_utilities_1.log.debug('Setting authtoken header', this.exportConfig.context);
|
|
50
|
+
this.apiClient.headers({ authtoken: token });
|
|
51
|
+
}
|
|
52
|
+
// Set organization_uid header
|
|
53
|
+
this.apiClient.headers({
|
|
54
|
+
organization_uid: this.exportConfig.org_uid,
|
|
55
|
+
Accept: 'application/json',
|
|
56
|
+
});
|
|
57
|
+
const apiUrl = '/projects';
|
|
58
|
+
cli_utilities_1.log.debug(`Fetching projects from: ${this.composableStudioConfig.apiBaseUrl}${apiUrl}`, this.exportConfig.context);
|
|
59
|
+
// Make API call to fetch projects using HttpClient
|
|
60
|
+
const response = await this.apiClient.get(apiUrl);
|
|
61
|
+
if (response.status < 200 || response.status >= 300) {
|
|
62
|
+
throw new Error(`API call failed with status ${response.status}: ${JSON.stringify(response.data)}`);
|
|
63
|
+
}
|
|
64
|
+
const data = response.data;
|
|
65
|
+
cli_utilities_1.log.debug(`Fetched ${((_a = data.projects) === null || _a === void 0 ? void 0 : _a.length) || 0} total projects`, this.exportConfig.context);
|
|
66
|
+
// Filter projects connected to this stack
|
|
67
|
+
const connectedProject = (_b = data.projects) === null || _b === void 0 ? void 0 : _b.filter((project) => project.connectedStackApiKey === this.exportConfig.apiKey);
|
|
68
|
+
if (!connectedProject || connectedProject.length === 0) {
|
|
69
|
+
cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('COMPOSABLE_STUDIO_NOT_FOUND'), this.exportConfig.context);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// Use the first connected project (stacks should have only one project)
|
|
73
|
+
this.composableStudioProject = connectedProject[0];
|
|
74
|
+
cli_utilities_1.log.debug(`Found Studio project: ${this.composableStudioProject.name}`, this.exportConfig.context);
|
|
75
|
+
// Write the project to file
|
|
76
|
+
const composableStudioFilePath = (0, node_path_1.resolve)(this.composableStudioPath, this.composableStudioConfig.fileName);
|
|
77
|
+
cli_utilities_1.log.debug(`Writing Studio project to: ${composableStudioFilePath}`, this.exportConfig.context);
|
|
78
|
+
utils_1.fsUtil.writeFile(composableStudioFilePath, this.composableStudioProject);
|
|
79
|
+
cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('COMPOSABLE_STUDIO_EXPORT_COMPLETE', this.composableStudioProject.name), this.exportConfig.context);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
cli_utilities_1.log.debug('Error occurred while exporting Studio project', this.exportConfig.context);
|
|
83
|
+
(0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.default = ExportComposableStudio;
|
|
@@ -30,7 +30,7 @@ class ContentTypesExport extends base_class_1.default {
|
|
|
30
30
|
try {
|
|
31
31
|
cli_utilities_1.log.debug('Starting content types export process...', this.exportConfig.context);
|
|
32
32
|
await utils_1.fsUtil.makeDirectory(this.contentTypesDirPath);
|
|
33
|
-
cli_utilities_1.log.debug(`Created directory at
|
|
33
|
+
cli_utilities_1.log.debug(`Created directory at: '${this.contentTypesDirPath}'.`, this.exportConfig.context);
|
|
34
34
|
await this.getContentTypes();
|
|
35
35
|
await this.writeContentTypes(this.contentTypes);
|
|
36
36
|
cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('CONTENT_TYPE_EXPORT_COMPLETE'), this.exportConfig.context);
|
|
@@ -62,7 +62,7 @@ class ContentTypesExport extends base_class_1.default {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
sanitizeAttribs(contentTypes) {
|
|
65
|
-
cli_utilities_1.log.debug(`Sanitizing ${contentTypes === null || contentTypes === void 0 ? void 0 : contentTypes.length} content types
|
|
65
|
+
cli_utilities_1.log.debug(`Sanitizing ${contentTypes === null || contentTypes === void 0 ? void 0 : contentTypes.length} content types...`, this.exportConfig.context);
|
|
66
66
|
const updatedContentTypes = [];
|
|
67
67
|
contentTypes.forEach((contentType) => {
|
|
68
68
|
for (const key in contentType) {
|
|
@@ -75,7 +75,7 @@ class ContentTypesExport extends base_class_1.default {
|
|
|
75
75
|
return updatedContentTypes;
|
|
76
76
|
}
|
|
77
77
|
async writeContentTypes(contentTypes) {
|
|
78
|
-
cli_utilities_1.log.debug(`Writing ${contentTypes === null || contentTypes === void 0 ? void 0 : contentTypes.length} content types to disk
|
|
78
|
+
cli_utilities_1.log.debug(`Writing ${contentTypes === null || contentTypes === void 0 ? void 0 : contentTypes.length} content types to disk...`, this.exportConfig.context);
|
|
79
79
|
function write(contentType) {
|
|
80
80
|
return utils_1.fsUtil.writeFile(path.join((0, cli_utilities_1.sanitizePath)(this.contentTypesDirPath), (0, cli_utilities_1.sanitizePath)(`${contentType.uid === 'schema' ? 'schema|1' : contentType.uid}.json`)), contentType);
|
|
81
81
|
}
|
|
@@ -20,18 +20,17 @@ class ExportCustomRoles extends base_class_1.default {
|
|
|
20
20
|
this.exportConfig.context.module = 'custom-roles';
|
|
21
21
|
}
|
|
22
22
|
async start() {
|
|
23
|
-
|
|
24
|
-
cli_utilities_1.log.debug('Starting custom roles export process...', this.exportConfig.context);
|
|
23
|
+
cli_utilities_1.log.debug('Starting export process for custom roles...', this.exportConfig.context);
|
|
25
24
|
this.rolesFolderPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.customRolesConfig.dirName);
|
|
26
|
-
cli_utilities_1.log.debug(`Custom roles folder path: ${this.rolesFolderPath}`, this.exportConfig.context);
|
|
25
|
+
cli_utilities_1.log.debug(`Custom roles folder path is: ${this.rolesFolderPath}`, this.exportConfig.context);
|
|
27
26
|
await utils_1.fsUtil.makeDirectory(this.rolesFolderPath);
|
|
28
|
-
cli_utilities_1.log.debug('
|
|
27
|
+
cli_utilities_1.log.debug('Custom roles directory created.', this.exportConfig.context);
|
|
29
28
|
this.customRolesLocalesFilepath = (0, node_path_1.resolve)(this.rolesFolderPath, this.customRolesConfig.customRolesLocalesFileName);
|
|
30
|
-
cli_utilities_1.log.debug(`Custom roles locales file path: ${this.customRolesLocalesFilepath}`, this.exportConfig.context);
|
|
29
|
+
cli_utilities_1.log.debug(`Custom roles locales file path is: ${this.customRolesLocalesFilepath}`, this.exportConfig.context);
|
|
31
30
|
await this.getCustomRoles();
|
|
32
31
|
await this.getLocales();
|
|
33
32
|
await this.getCustomRolesLocales();
|
|
34
|
-
cli_utilities_1.log.debug(`Custom roles export completed. Total custom roles: ${
|
|
33
|
+
cli_utilities_1.log.debug(`Custom roles export completed. Total custom roles: ${Object.keys(this.customRoles).length}`, this.exportConfig.context);
|
|
35
34
|
}
|
|
36
35
|
async getCustomRoles() {
|
|
37
36
|
var _a;
|
|
@@ -41,15 +40,15 @@ class ExportCustomRoles extends base_class_1.default {
|
|
|
41
40
|
.fetchAll({ include_rules: true, include_permissions: true })
|
|
42
41
|
.then((data) => {
|
|
43
42
|
var _a;
|
|
44
|
-
cli_utilities_1.log.debug(`Fetched ${((_a = data.items) === null || _a === void 0 ? void 0 : _a.length) || 0}
|
|
43
|
+
cli_utilities_1.log.debug(`Fetched ${((_a = data.items) === null || _a === void 0 ? void 0 : _a.length) || 0} roles from the stack.`, this.exportConfig.context);
|
|
45
44
|
return data;
|
|
46
45
|
})
|
|
47
46
|
.catch((err) => {
|
|
48
|
-
cli_utilities_1.log.debug('
|
|
47
|
+
cli_utilities_1.log.debug('An error occurred while fetching roles.', this.exportConfig.context);
|
|
49
48
|
return (0, cli_utilities_1.handleAndLogError)(err, Object.assign({}, this.exportConfig.context));
|
|
50
49
|
});
|
|
51
50
|
const customRoles = roles.items.filter((role) => !this.existingRoles[role.name]);
|
|
52
|
-
cli_utilities_1.log.debug(`Found ${customRoles.length} custom roles
|
|
51
|
+
cli_utilities_1.log.debug(`Found ${customRoles.length} custom roles from ${((_a = roles.items) === null || _a === void 0 ? void 0 : _a.length) || 0} total roles.`, this.exportConfig.context);
|
|
53
52
|
if (!customRoles.length) {
|
|
54
53
|
cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('ROLES_NO_CUSTOM_ROLES'), this.exportConfig.context);
|
|
55
54
|
return;
|
|
@@ -60,11 +59,10 @@ class ExportCustomRoles extends base_class_1.default {
|
|
|
60
59
|
this.customRoles[role.uid] = role;
|
|
61
60
|
});
|
|
62
61
|
const customRolesFilePath = (0, node_path_1.resolve)(this.rolesFolderPath, this.customRolesConfig.fileName);
|
|
63
|
-
cli_utilities_1.log.debug(`Writing custom roles to: ${customRolesFilePath}
|
|
62
|
+
cli_utilities_1.log.debug(`Writing custom roles to: ${customRolesFilePath}.`, this.exportConfig.context);
|
|
64
63
|
utils_1.fsUtil.writeFile(customRolesFilePath, this.customRoles);
|
|
65
64
|
}
|
|
66
65
|
async getLocales() {
|
|
67
|
-
var _a;
|
|
68
66
|
cli_utilities_1.log.debug('Fetching locales for custom roles mapping...', this.exportConfig.context);
|
|
69
67
|
const locales = await this.stack
|
|
70
68
|
.locale()
|
|
@@ -72,36 +70,36 @@ class ExportCustomRoles extends base_class_1.default {
|
|
|
72
70
|
.find()
|
|
73
71
|
.then((data) => {
|
|
74
72
|
var _a;
|
|
75
|
-
cli_utilities_1.log.debug(`Fetched ${((_a = data === null || data === void 0 ? void 0 : data.items) === null || _a === void 0 ? void 0 : _a.length) || 0} locales
|
|
73
|
+
cli_utilities_1.log.debug(`Fetched ${((_a = data === null || data === void 0 ? void 0 : data.items) === null || _a === void 0 ? void 0 : _a.length) || 0} locales.`, this.exportConfig.context);
|
|
76
74
|
return data;
|
|
77
75
|
})
|
|
78
76
|
.catch((err) => {
|
|
79
|
-
cli_utilities_1.log.debug('
|
|
77
|
+
cli_utilities_1.log.debug('An error occurred while fetching locales.', this.exportConfig.context);
|
|
80
78
|
return (0, cli_utilities_1.handleAndLogError)(err, Object.assign({}, this.exportConfig.context));
|
|
81
79
|
});
|
|
82
80
|
for (const locale of locales.items) {
|
|
83
81
|
cli_utilities_1.log.debug(`Mapping locale: ${locale === null || locale === void 0 ? void 0 : locale.name} (${locale === null || locale === void 0 ? void 0 : locale.uid})`, this.exportConfig.context);
|
|
84
82
|
this.sourceLocalesMap[locale.uid] = locale;
|
|
85
83
|
}
|
|
86
|
-
cli_utilities_1.log.debug(`Mapped ${
|
|
84
|
+
cli_utilities_1.log.debug(`Mapped ${Object.keys(this.sourceLocalesMap).length} source locales.`, this.exportConfig.context);
|
|
87
85
|
}
|
|
88
86
|
async getCustomRolesLocales() {
|
|
89
|
-
var _a, _b
|
|
87
|
+
var _a, _b;
|
|
90
88
|
cli_utilities_1.log.debug('Processing custom roles locales mapping...', this.exportConfig.context);
|
|
91
89
|
for (const role of (0, values_1.default)(this.customRoles)) {
|
|
92
90
|
const customRole = role;
|
|
93
91
|
cli_utilities_1.log.debug(`Processing locales for custom role: ${customRole === null || customRole === void 0 ? void 0 : customRole.name}`, this.exportConfig.context);
|
|
94
92
|
const rulesLocales = (0, find_1.default)(customRole.rules, (rule) => rule.module === 'locale');
|
|
95
93
|
if ((_a = rulesLocales === null || rulesLocales === void 0 ? void 0 : rulesLocales.locales) === null || _a === void 0 ? void 0 : _a.length) {
|
|
96
|
-
cli_utilities_1.log.debug(`Found ${rulesLocales.locales.length} locales for role: ${customRole === null || customRole === void 0 ? void 0 : customRole.name}
|
|
94
|
+
cli_utilities_1.log.debug(`Found ${rulesLocales.locales.length} locales for the role: ${customRole === null || customRole === void 0 ? void 0 : customRole.name}.`, this.exportConfig.context);
|
|
97
95
|
(0, forEach_1.default)(rulesLocales.locales, (locale) => {
|
|
98
|
-
cli_utilities_1.log.debug(`Adding locale ${locale} to custom roles mapping
|
|
96
|
+
cli_utilities_1.log.debug(`Adding locale ${locale} to the custom roles mapping.`, this.exportConfig.context);
|
|
99
97
|
this.localesMap[locale] = 1;
|
|
100
98
|
});
|
|
101
99
|
}
|
|
102
100
|
}
|
|
103
101
|
if ((_b = (0, keys_1.default)(this.localesMap)) === null || _b === void 0 ? void 0 : _b.length) {
|
|
104
|
-
cli_utilities_1.log.debug(`Processing ${
|
|
102
|
+
cli_utilities_1.log.debug(`Processing ${Object.keys(this.localesMap).length} mapped locales.`, this.exportConfig.context);
|
|
105
103
|
for (const locale in this.localesMap) {
|
|
106
104
|
if (this.sourceLocalesMap[locale] !== undefined) {
|
|
107
105
|
const sourceLocale = this.sourceLocalesMap[locale];
|
|
@@ -110,11 +108,11 @@ class ExportCustomRoles extends base_class_1.default {
|
|
|
110
108
|
}
|
|
111
109
|
this.localesMap[locale] = this.sourceLocalesMap[locale];
|
|
112
110
|
}
|
|
113
|
-
cli_utilities_1.log.debug(`Writing custom roles locales to: ${this.customRolesLocalesFilepath}
|
|
111
|
+
cli_utilities_1.log.debug(`Writing custom roles locales to: ${this.customRolesLocalesFilepath}.`, this.exportConfig.context);
|
|
114
112
|
utils_1.fsUtil.writeFile(this.customRolesLocalesFilepath, this.localesMap);
|
|
115
113
|
}
|
|
116
114
|
else {
|
|
117
|
-
cli_utilities_1.log.debug('No custom role locales found to process', this.exportConfig.context);
|
|
115
|
+
cli_utilities_1.log.debug('No custom role locales found to process.', this.exportConfig.context);
|
|
118
116
|
}
|
|
119
117
|
}
|
|
120
118
|
}
|
|
@@ -143,12 +143,12 @@ class EntriesExport extends base_class_1.default {
|
|
|
143
143
|
});
|
|
144
144
|
cli_utilities_1.log.debug('Initialized FsUtility for writing entries', this.exportConfig.context);
|
|
145
145
|
}
|
|
146
|
-
cli_utilities_1.log.debug(`Writing ${entriesSearchResponse.items.length} entries to file
|
|
146
|
+
cli_utilities_1.log.debug(`Writing ${entriesSearchResponse.items.length} entries to file...`, this.exportConfig.context);
|
|
147
147
|
this.entriesFileHelper.writeIntoFile(entriesSearchResponse.items, { mapKeyVal: true });
|
|
148
148
|
if (this.entriesConfig.exportVersions) {
|
|
149
|
-
cli_utilities_1.log.debug('Exporting entry versions is enabled', this.exportConfig.context);
|
|
149
|
+
cli_utilities_1.log.debug('Exporting entry versions is enabled.', this.exportConfig.context);
|
|
150
150
|
let versionedEntryPath = path.join((0, cli_utilities_2.sanitizePath)(this.entriesDirPath), (0, cli_utilities_2.sanitizePath)(options.contentType), (0, cli_utilities_2.sanitizePath)(options.locale), 'versions');
|
|
151
|
-
cli_utilities_1.log.debug(`Creating versioned entries directory at: ${versionedEntryPath}
|
|
151
|
+
cli_utilities_1.log.debug(`Creating versioned entries directory at: ${versionedEntryPath}.`, this.exportConfig.context);
|
|
152
152
|
utils_1.fsUtil.makeDirectory(versionedEntryPath);
|
|
153
153
|
await this.fetchEntriesVersions(entriesSearchResponse.items, {
|
|
154
154
|
locale: options.locale,
|
|
@@ -175,7 +175,7 @@ class EntriesExport extends base_class_1.default {
|
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
async fetchEntriesVersions(entries, options) {
|
|
178
|
-
cli_utilities_1.log.debug(`Fetching versions for ${entries.length} entries
|
|
178
|
+
cli_utilities_1.log.debug(`Fetching versions for ${entries.length} entries...`, this.exportConfig.context);
|
|
179
179
|
const onSuccess = ({ response, apiData: entry }) => {
|
|
180
180
|
const versionFilePath = path.join((0, cli_utilities_2.sanitizePath)(options.versionedEntryPath), (0, cli_utilities_2.sanitizePath)(`${entry.uid}.json`));
|
|
181
181
|
cli_utilities_1.log.debug(`Writing versioned entry to: ${versionFilePath}`, this.exportConfig.context);
|
|
@@ -205,7 +205,7 @@ class EntriesExport extends base_class_1.default {
|
|
|
205
205
|
return new Promise(async (resolve, reject) => {
|
|
206
206
|
return await this.getEntryByVersion(apiParams.queryParam, entry)
|
|
207
207
|
.then((response) => {
|
|
208
|
-
cli_utilities_1.log.debug(`Successfully fetched versions for entry: ${entry.uid}`, this.exportConfig.context);
|
|
208
|
+
cli_utilities_1.log.debug(`Successfully fetched versions for entry UID: ${entry.uid}`, this.exportConfig.context);
|
|
209
209
|
apiParams.resolve({
|
|
210
210
|
response,
|
|
211
211
|
apiData: entry,
|
|
@@ -213,7 +213,7 @@ class EntriesExport extends base_class_1.default {
|
|
|
213
213
|
resolve(true);
|
|
214
214
|
})
|
|
215
215
|
.catch((error) => {
|
|
216
|
-
cli_utilities_1.log.debug(`Failed to fetch versions for entry: ${entry.uid}`, this.exportConfig.context);
|
|
216
|
+
cli_utilities_1.log.debug(`Failed to fetch versions for entry UID: ${entry.uid}`, this.exportConfig.context);
|
|
217
217
|
apiParams.reject({
|
|
218
218
|
error,
|
|
219
219
|
apiData: entry,
|
|
@@ -230,7 +230,7 @@ class EntriesExport extends base_class_1.default {
|
|
|
230
230
|
},
|
|
231
231
|
version: entry._version,
|
|
232
232
|
};
|
|
233
|
-
cli_utilities_1.log.debug(`Fetching entry version ${entry._version} for
|
|
233
|
+
cli_utilities_1.log.debug(`Fetching entry version ${entry._version} for entry UID: '${entry.uid}'.`, this.exportConfig.context);
|
|
234
234
|
const entryResponse = await this.stackAPIClient
|
|
235
235
|
.contentType(options.contentType)
|
|
236
236
|
.entry(entry.uid)
|
|
@@ -18,17 +18,17 @@ class ExportEnvironments extends base_class_1.default {
|
|
|
18
18
|
async start() {
|
|
19
19
|
cli_utilities_1.log.debug('Starting environment export process...', this.exportConfig.context);
|
|
20
20
|
this.environmentsFolderPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.environmentConfig.dirName);
|
|
21
|
-
cli_utilities_1.log.debug(`Environments folder path: ${this.environmentsFolderPath}`, this.exportConfig.context);
|
|
21
|
+
cli_utilities_1.log.debug(`Environments folder path is: ${this.environmentsFolderPath}`, this.exportConfig.context);
|
|
22
22
|
await utils_1.fsUtil.makeDirectory(this.environmentsFolderPath);
|
|
23
|
-
cli_utilities_1.log.debug('
|
|
23
|
+
cli_utilities_1.log.debug('Environments directory created.', this.exportConfig.context);
|
|
24
24
|
await this.getEnvironments();
|
|
25
|
-
cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.environments).length} environments
|
|
25
|
+
cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.environments).length} environments.`, this.exportConfig.context);
|
|
26
26
|
if (this.environments === undefined || (0, isEmpty_1.default)(this.environments)) {
|
|
27
27
|
cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('ENVIRONMENT_NOT_FOUND'), this.exportConfig.context);
|
|
28
28
|
}
|
|
29
29
|
else {
|
|
30
30
|
const environmentsFilePath = (0, node_path_1.resolve)(this.environmentsFolderPath, this.environmentConfig.fileName);
|
|
31
|
-
cli_utilities_1.log.debug(`Writing environments to: ${environmentsFilePath}
|
|
31
|
+
cli_utilities_1.log.debug(`Writing environments to: ${environmentsFilePath}.`, this.exportConfig.context);
|
|
32
32
|
utils_1.fsUtil.writeFile(environmentsFilePath, this.environments);
|
|
33
33
|
cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('ENVIRONMENT_EXPORT_COMPLETE', Object.keys(this.environments).length), this.exportConfig.context);
|
|
34
34
|
}
|
|
@@ -36,10 +36,10 @@ class ExportEnvironments extends base_class_1.default {
|
|
|
36
36
|
async getEnvironments(skip = 0) {
|
|
37
37
|
if (skip) {
|
|
38
38
|
this.qs.skip = skip;
|
|
39
|
-
cli_utilities_1.log.debug(`Fetching environments with skip: ${skip}`, this.exportConfig.context);
|
|
39
|
+
cli_utilities_1.log.debug(`Fetching environments with skip value: ${skip}`, this.exportConfig.context);
|
|
40
40
|
}
|
|
41
41
|
else {
|
|
42
|
-
cli_utilities_1.log.debug('Fetching environments with initial query', this.exportConfig.context);
|
|
42
|
+
cli_utilities_1.log.debug('Fetching environments with initial query...', this.exportConfig.context);
|
|
43
43
|
}
|
|
44
44
|
cli_utilities_1.log.debug(`Query parameters: ${JSON.stringify(this.qs)}`, this.exportConfig.context);
|
|
45
45
|
await this.stack
|
|
@@ -48,30 +48,30 @@ class ExportEnvironments extends base_class_1.default {
|
|
|
48
48
|
.find()
|
|
49
49
|
.then(async (data) => {
|
|
50
50
|
const { items, count } = data;
|
|
51
|
-
cli_utilities_1.log.debug(`Fetched ${(items === null || items === void 0 ? void 0 : items.length) || 0} environments out of
|
|
51
|
+
cli_utilities_1.log.debug(`Fetched ${(items === null || items === void 0 ? void 0 : items.length) || 0} environments out of ${count} total.`, this.exportConfig.context);
|
|
52
52
|
if (items === null || items === void 0 ? void 0 : items.length) {
|
|
53
|
-
cli_utilities_1.log.debug(`Processing ${items.length} environments
|
|
53
|
+
cli_utilities_1.log.debug(`Processing ${items.length} environments.`, this.exportConfig.context);
|
|
54
54
|
this.sanitizeAttribs(items);
|
|
55
55
|
skip += this.environmentConfig.limit || 100;
|
|
56
56
|
if (skip >= count) {
|
|
57
|
-
cli_utilities_1.log.debug('Completed fetching all environments', this.exportConfig.context);
|
|
57
|
+
cli_utilities_1.log.debug('Completed fetching all environments.', this.exportConfig.context);
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
|
-
cli_utilities_1.log.debug(`Continuing
|
|
60
|
+
cli_utilities_1.log.debug(`Continuing environment fetch with skip value: ${skip}`, this.exportConfig.context);
|
|
61
61
|
return await this.getEnvironments(skip);
|
|
62
62
|
}
|
|
63
63
|
else {
|
|
64
|
-
cli_utilities_1.log.debug('No environments found to process', this.exportConfig.context);
|
|
64
|
+
cli_utilities_1.log.debug('No environments found to process.', this.exportConfig.context);
|
|
65
65
|
}
|
|
66
66
|
})
|
|
67
67
|
.catch((error) => {
|
|
68
|
-
cli_utilities_1.log.debug('
|
|
68
|
+
cli_utilities_1.log.debug('An error occurred while fetching environments.', this.exportConfig.context);
|
|
69
69
|
(0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
sanitizeAttribs(environments) {
|
|
73
73
|
var _a;
|
|
74
|
-
cli_utilities_1.log.debug(`Sanitizing ${environments.length} environments
|
|
74
|
+
cli_utilities_1.log.debug(`Sanitizing ${environments.length} environments...`, this.exportConfig.context);
|
|
75
75
|
for (let index = 0; index < (environments === null || environments === void 0 ? void 0 : environments.length); index++) {
|
|
76
76
|
const extUid = environments[index].uid;
|
|
77
77
|
const envName = (_a = environments[index]) === null || _a === void 0 ? void 0 : _a.name;
|
|
@@ -19,17 +19,17 @@ class ExportExtensions extends base_class_1.default {
|
|
|
19
19
|
async start() {
|
|
20
20
|
cli_utilities_1.log.debug('Starting extensions export process...', this.exportConfig.context);
|
|
21
21
|
this.extensionsFolderPath = (0, node_path_1.resolve)(this.exportConfig.data, this.exportConfig.branchName || '', this.extensionConfig.dirName);
|
|
22
|
-
cli_utilities_1.log.debug(`Extensions folder path: ${this.extensionsFolderPath}`, this.exportConfig.context);
|
|
22
|
+
cli_utilities_1.log.debug(`Extensions folder path is: ${this.extensionsFolderPath}`, this.exportConfig.context);
|
|
23
23
|
await utils_1.fsUtil.makeDirectory(this.extensionsFolderPath);
|
|
24
|
-
cli_utilities_1.log.debug('
|
|
24
|
+
cli_utilities_1.log.debug('Extensions directory created.', this.exportConfig.context);
|
|
25
25
|
await this.getExtensions();
|
|
26
|
-
cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.extensions).length} extensions
|
|
26
|
+
cli_utilities_1.log.debug(`Retrieved ${Object.keys(this.extensions).length} extensions.`, this.exportConfig.context);
|
|
27
27
|
if (this.extensions === undefined || (0, isEmpty_1.default)(this.extensions)) {
|
|
28
28
|
cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('EXTENSION_NOT_FOUND'), this.exportConfig.context);
|
|
29
29
|
}
|
|
30
30
|
else {
|
|
31
31
|
const extensionsFilePath = (0, node_path_1.resolve)(this.extensionsFolderPath, this.extensionConfig.fileName);
|
|
32
|
-
cli_utilities_1.log.debug(`Writing extensions to: ${extensionsFilePath}
|
|
32
|
+
cli_utilities_1.log.debug(`Writing extensions to: ${extensionsFilePath}.`, this.exportConfig.context);
|
|
33
33
|
utils_1.fsUtil.writeFile(extensionsFilePath, this.extensions);
|
|
34
34
|
cli_utilities_1.log.success(cli_utilities_1.messageHandler.parse('EXTENSION_EXPORT_COMPLETE', Object.keys(this.extensions).length), this.exportConfig.context);
|
|
35
35
|
}
|
|
@@ -37,50 +37,50 @@ class ExportExtensions extends base_class_1.default {
|
|
|
37
37
|
async getExtensions(skip = 0) {
|
|
38
38
|
if (skip) {
|
|
39
39
|
this.qs.skip = skip;
|
|
40
|
-
cli_utilities_1.log.debug(`Fetching extensions with skip: ${skip}`, this.exportConfig.context);
|
|
40
|
+
cli_utilities_1.log.debug(`Fetching extensions with skip value: ${skip}`, this.exportConfig.context);
|
|
41
41
|
}
|
|
42
42
|
else {
|
|
43
|
-
cli_utilities_1.log.debug('Fetching extensions with initial query', this.exportConfig.context);
|
|
43
|
+
cli_utilities_1.log.debug('Fetching extensions with initial query...', this.exportConfig.context);
|
|
44
44
|
}
|
|
45
|
-
cli_utilities_1.log.debug(`Query parameters: ${JSON.stringify(this.qs)}
|
|
45
|
+
cli_utilities_1.log.debug(`Query parameters: ${JSON.stringify(this.qs)}.`, this.exportConfig.context);
|
|
46
46
|
await this.stack
|
|
47
47
|
.extension()
|
|
48
48
|
.query(this.qs)
|
|
49
49
|
.find()
|
|
50
50
|
.then(async (data) => {
|
|
51
51
|
const { items, count } = data;
|
|
52
|
-
cli_utilities_1.log.debug(`Fetched ${(items === null || items === void 0 ? void 0 : items.length) || 0} extensions out of
|
|
52
|
+
cli_utilities_1.log.debug(`Fetched ${(items === null || items === void 0 ? void 0 : items.length) || 0} extensions out of ${count}.`, this.exportConfig.context);
|
|
53
53
|
if (items === null || items === void 0 ? void 0 : items.length) {
|
|
54
|
-
cli_utilities_1.log.debug(`Processing ${items.length} extensions
|
|
54
|
+
cli_utilities_1.log.debug(`Processing ${items.length} extensions...`, this.exportConfig.context);
|
|
55
55
|
this.sanitizeAttribs(items);
|
|
56
56
|
skip += this.extensionConfig.limit || 100;
|
|
57
57
|
if (skip >= count) {
|
|
58
|
-
cli_utilities_1.log.debug('Completed fetching all extensions', this.exportConfig.context);
|
|
58
|
+
cli_utilities_1.log.debug('Completed fetching all extensions.', this.exportConfig.context);
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
|
-
cli_utilities_1.log.debug(`Continuing to fetch extensions with skip: ${skip}
|
|
61
|
+
cli_utilities_1.log.debug(`Continuing to fetch extensions with skip: ${skip}.`, this.exportConfig.context);
|
|
62
62
|
return await this.getExtensions(skip);
|
|
63
63
|
}
|
|
64
64
|
else {
|
|
65
|
-
cli_utilities_1.log.debug('No extensions found to process', this.exportConfig.context);
|
|
65
|
+
cli_utilities_1.log.debug('No extensions found to process.', this.exportConfig.context);
|
|
66
66
|
}
|
|
67
67
|
})
|
|
68
68
|
.catch((error) => {
|
|
69
|
-
cli_utilities_1.log.debug('
|
|
69
|
+
cli_utilities_1.log.debug('An error occurred while fetching extensions.', this.exportConfig.context);
|
|
70
70
|
(0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.exportConfig.context));
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
73
|
sanitizeAttribs(extensions) {
|
|
74
74
|
var _a;
|
|
75
|
-
cli_utilities_1.log.debug(`Sanitizing ${extensions.length} extensions
|
|
75
|
+
cli_utilities_1.log.debug(`Sanitizing ${extensions.length} extensions...`, this.exportConfig.context);
|
|
76
76
|
for (let index = 0; index < (extensions === null || extensions === void 0 ? void 0 : extensions.length); index++) {
|
|
77
77
|
const extUid = extensions[index].uid;
|
|
78
78
|
const extTitle = (_a = extensions[index]) === null || _a === void 0 ? void 0 : _a.title;
|
|
79
|
-
cli_utilities_1.log.debug(`Processing extension: ${extTitle} (${extUid})
|
|
79
|
+
cli_utilities_1.log.debug(`Processing extension: '${extTitle}' (UID: ${extUid})...`, this.exportConfig.context);
|
|
80
80
|
this.extensions[extUid] = (0, omit_1.default)(extensions[index], ['SYS_ACL']);
|
|
81
81
|
cli_utilities_1.log.info(cli_utilities_1.messageHandler.parse('EXTENSION_EXPORT_SUCCESS', extTitle), this.exportConfig.context);
|
|
82
82
|
}
|
|
83
|
-
cli_utilities_1.log.debug(`Sanitization complete. Total extensions processed: ${Object.keys(this.extensions).length}
|
|
83
|
+
cli_utilities_1.log.debug(`Sanitization complete. Total extensions processed: ${Object.keys(this.extensions).length}.`, this.exportConfig.context);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
exports.default = ExportExtensions;
|