@contentstack/cli-audit 1.16.1 → 1.17.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/LICENSE +1 -1
- package/README.md +23 -19
- package/lib/audit-base-command.d.ts +1 -4
- package/lib/audit-base-command.js +20 -20
- package/lib/config/index.d.ts +5 -0
- package/lib/config/index.js +16 -9
- package/lib/messages/index.d.ts +1 -0
- package/lib/messages/index.js +2 -1
- package/lib/modules/composable-studio.d.ts +40 -0
- package/lib/modules/composable-studio.js +307 -0
- package/lib/modules/index.d.ts +2 -1
- package/lib/modules/index.js +3 -1
- package/lib/modules/modulesData.js +17 -8
- package/lib/types/composable-studio.d.ts +25 -0
- package/lib/types/composable-studio.js +2 -0
- package/lib/types/content-types.d.ts +2 -1
- package/lib/types/content-types.js +1 -0
- package/lib/types/context.d.ts +0 -5
- package/oclif.manifest.json +5 -3
- package/package.json +3 -3
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ $ npm install -g @contentstack/cli-audit
|
|
|
19
19
|
$ csdx COMMAND
|
|
20
20
|
running command...
|
|
21
21
|
$ csdx (--version|-v)
|
|
22
|
-
@contentstack/cli-audit/1.
|
|
22
|
+
@contentstack/cli-audit/1.17.0 linux-x64 node-v22.21.1
|
|
23
23
|
$ csdx --help [COMMAND]
|
|
24
24
|
USAGE
|
|
25
25
|
$ csdx COMMAND
|
|
@@ -53,13 +53,14 @@ Perform audits and find possible errors in the exported Contentstack data
|
|
|
53
53
|
```
|
|
54
54
|
USAGE
|
|
55
55
|
$ csdx audit [-c <value>] [-d <value>] [--show-console-output] [--report-path <value>] [--modules
|
|
56
|
-
content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-rules...]
|
|
57
|
-
[--sort <value>] [--filter <value>] [--csv] [--no-truncate] [--no-header] [--output
|
|
56
|
+
content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-rules|composable-studio...]
|
|
57
|
+
[--columns <value>] [--sort <value>] [--filter <value>] [--csv] [--no-truncate] [--no-header] [--output
|
|
58
|
+
csv|json|yaml]
|
|
58
59
|
|
|
59
60
|
FLAGS
|
|
60
61
|
--modules=<option>... Provide the list of modules to be audited
|
|
61
|
-
<options:
|
|
62
|
-
|
|
62
|
+
<options: content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-ru
|
|
63
|
+
les|composable-studio>
|
|
63
64
|
--report-path=<value> Path to store the audit reports
|
|
64
65
|
|
|
65
66
|
COMMON FLAGS
|
|
@@ -103,9 +104,10 @@ Perform audits and fix possible errors in the exported Contentstack data.
|
|
|
103
104
|
```
|
|
104
105
|
USAGE
|
|
105
106
|
$ csdx audit:fix [-c <value>] [-d <value>] [--show-console-output] [--report-path <value>] [--modules
|
|
106
|
-
content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-rules...]
|
|
107
|
-
--copy-dir] [--fix-only
|
|
108
|
-
|
|
107
|
+
content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-rules|composable-studio...]
|
|
108
|
+
[--copy-path <value> --copy-dir] [--fix-only
|
|
109
|
+
reference|global_field|json:rte|json:extension|blocks|group|content_types...] [--columns <value>] [--sort <value>]
|
|
110
|
+
[--filter <value>] [--csv] [--no-truncate] [--no-header] [--output csv|json|yaml]
|
|
109
111
|
|
|
110
112
|
FLAGS
|
|
111
113
|
--copy-dir Create backup from the original data.
|
|
@@ -113,8 +115,8 @@ FLAGS
|
|
|
113
115
|
--fix-only=<option>... Provide the list of fix options
|
|
114
116
|
<options: reference|global_field|json:rte|json:extension|blocks|group|content_types>
|
|
115
117
|
--modules=<option>... Provide the list of modules to be audited
|
|
116
|
-
<options:
|
|
117
|
-
|
|
118
|
+
<options: content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-r
|
|
119
|
+
ules|composable-studio>
|
|
118
120
|
--report-path=<value> Path to store the audit reports
|
|
119
121
|
|
|
120
122
|
COMMON FLAGS
|
|
@@ -160,13 +162,14 @@ Perform audits and find possible errors in the exported Contentstack data
|
|
|
160
162
|
```
|
|
161
163
|
USAGE
|
|
162
164
|
$ csdx cm:stacks:audit [-c <value>] [-d <value>] [--show-console-output] [--report-path <value>] [--modules
|
|
163
|
-
content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-rules...]
|
|
164
|
-
[--sort <value>] [--filter <value>] [--csv] [--no-truncate] [--no-header] [--output
|
|
165
|
+
content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-rules|composable-studio...]
|
|
166
|
+
[--columns <value>] [--sort <value>] [--filter <value>] [--csv] [--no-truncate] [--no-header] [--output
|
|
167
|
+
csv|json|yaml]
|
|
165
168
|
|
|
166
169
|
FLAGS
|
|
167
170
|
--modules=<option>... Provide the list of modules to be audited
|
|
168
|
-
<options:
|
|
169
|
-
|
|
171
|
+
<options: content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-ru
|
|
172
|
+
les|composable-studio>
|
|
170
173
|
--report-path=<value> Path to store the audit reports
|
|
171
174
|
|
|
172
175
|
COMMON FLAGS
|
|
@@ -212,9 +215,10 @@ Perform audits and fix possible errors in the exported Contentstack data.
|
|
|
212
215
|
```
|
|
213
216
|
USAGE
|
|
214
217
|
$ csdx cm:stacks:audit:fix [-c <value>] [-d <value>] [--show-console-output] [--report-path <value>] [--modules
|
|
215
|
-
content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-rules...]
|
|
216
|
-
--copy-dir] [--fix-only
|
|
217
|
-
|
|
218
|
+
content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-rules|composable-studio...]
|
|
219
|
+
[--copy-path <value> --copy-dir] [--fix-only
|
|
220
|
+
reference|global_field|json:rte|json:extension|blocks|group|content_types...] [--columns <value>] [--sort <value>]
|
|
221
|
+
[--filter <value>] [--csv] [--no-truncate] [--no-header] [--output csv|json|yaml]
|
|
218
222
|
|
|
219
223
|
FLAGS
|
|
220
224
|
--copy-dir Create backup from the original data.
|
|
@@ -222,8 +226,8 @@ FLAGS
|
|
|
222
226
|
--fix-only=<option>... Provide the list of fix options
|
|
223
227
|
<options: reference|global_field|json:rte|json:extension|blocks|group|content_types>
|
|
224
228
|
--modules=<option>... Provide the list of modules to be audited
|
|
225
|
-
<options:
|
|
226
|
-
|
|
229
|
+
<options: content-types|global-fields|entries|extensions|workflows|custom-roles|assets|field-r
|
|
230
|
+
ules|composable-studio>
|
|
227
231
|
--report-path=<value> Path to store the audit reports
|
|
228
232
|
|
|
229
233
|
COMMON FLAGS
|
|
@@ -12,10 +12,6 @@ export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditB
|
|
|
12
12
|
get: (row: any) => string;
|
|
13
13
|
};
|
|
14
14
|
};
|
|
15
|
-
/**
|
|
16
|
-
* Create audit context object similar to export command
|
|
17
|
-
*/
|
|
18
|
-
private createAuditContext;
|
|
19
15
|
/**
|
|
20
16
|
* The `start` function performs an audit on content types, global fields, entries, and workflows and displays
|
|
21
17
|
* any missing references.
|
|
@@ -43,6 +39,7 @@ export declare abstract class AuditBaseCommand extends BaseCommand<typeof AuditB
|
|
|
43
39
|
missingEnvLocalesInEntries: Record<string, any> | undefined;
|
|
44
40
|
missingFieldRules: Record<string, any> | undefined;
|
|
45
41
|
missingMultipleFields: Record<string, any> | undefined;
|
|
42
|
+
missingRefsInComposableStudio: {} | undefined;
|
|
46
43
|
}>;
|
|
47
44
|
/**
|
|
48
45
|
* The `promptQueue` function prompts the user to enter a data directory path if the `data-dir` flag
|
|
@@ -33,19 +33,6 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
33
33
|
},
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
|
-
/**
|
|
37
|
-
* Create audit context object similar to export command
|
|
38
|
-
*/
|
|
39
|
-
createAuditContext(moduleName) {
|
|
40
|
-
var _a, _b, _c;
|
|
41
|
-
return {
|
|
42
|
-
command: ((_b = (_a = this.context) === null || _a === void 0 ? void 0 : _a.info) === null || _b === void 0 ? void 0 : _b.command) || 'cm:stacks:audit',
|
|
43
|
-
module: moduleName || 'audit',
|
|
44
|
-
email: cli_utilities_1.configHandler.get('email') || '',
|
|
45
|
-
sessionId: ((_c = this.context) === null || _c === void 0 ? void 0 : _c.sessionId) || '',
|
|
46
|
-
authenticationMethod: cli_utilities_1.configHandler.get('authenticationMethod') || '',
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
36
|
/**
|
|
50
37
|
* The `start` function performs an audit on content types, global fields, entries, and workflows and displays
|
|
51
38
|
* any missing references.
|
|
@@ -53,9 +40,11 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
53
40
|
* being executed.
|
|
54
41
|
*/
|
|
55
42
|
async start(command) {
|
|
43
|
+
var _a, _b;
|
|
56
44
|
this.currentCommand = command;
|
|
57
|
-
// Initialize audit context
|
|
58
|
-
|
|
45
|
+
// Initialize audit context (reused, no need to call again in scanAndFix)
|
|
46
|
+
(0, cli_utilities_1.createLogContext)((_b = (_a = this.context) === null || _a === void 0 ? void 0 : _a.info) === null || _b === void 0 ? void 0 : _b.command, '', cli_utilities_1.configHandler.get('authenticationMethod'));
|
|
47
|
+
this.auditContext = { module: 'audit' };
|
|
59
48
|
cli_utilities_1.log.debug(`Starting audit command: ${command}`, this.auditContext);
|
|
60
49
|
cli_utilities_1.log.info(`Starting audit command: ${command}`, this.auditContext);
|
|
61
50
|
await this.promptQueue();
|
|
@@ -63,7 +52,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
63
52
|
this.sharedConfig.reportPath = (0, path_1.resolve)(this.flags['report-path'] || process.cwd(), 'audit-report');
|
|
64
53
|
cli_utilities_1.log.debug(`Data directory: ${this.flags['data-dir']}`, this.auditContext);
|
|
65
54
|
cli_utilities_1.log.debug(`Report path: ${this.flags['report-path'] || process.cwd()}`, this.auditContext);
|
|
66
|
-
const { missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow, missingSelectFeild, missingMandatoryFields, missingTitleFields, missingRefInCustomRoles, missingEnvLocalesInAssets, missingEnvLocalesInEntries, missingFieldRules, missingMultipleFields, } = await this.scanAndFix();
|
|
55
|
+
const { missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow, missingSelectFeild, missingMandatoryFields, missingTitleFields, missingRefInCustomRoles, missingEnvLocalesInAssets, missingEnvLocalesInEntries, missingFieldRules, missingMultipleFields, missingRefsInComposableStudio, } = await this.scanAndFix();
|
|
67
56
|
if (this.flags['show-console-output']) {
|
|
68
57
|
this.showOutputOnScreen([
|
|
69
58
|
{ module: 'Content types', missingRefs: missingCtRefs },
|
|
@@ -90,6 +79,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
90
79
|
this.showOutputOnScreenWorkflowsAndExtension([
|
|
91
80
|
{ module: 'Entries Changed Multiple Fields', missingRefs: missingMultipleFields },
|
|
92
81
|
]);
|
|
82
|
+
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Studio', missingRefs: missingRefsInComposableStudio }]);
|
|
93
83
|
}
|
|
94
84
|
this.showOutputOnScreenWorkflowsAndExtension([{ module: 'Summary', missingRefs: this.summaryDataToPrint }]);
|
|
95
85
|
if (!(0, isEmpty_1.default)(missingCtRefs) ||
|
|
@@ -103,7 +93,8 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
103
93
|
!(0, isEmpty_1.default)(missingEnvLocalesInAssets) ||
|
|
104
94
|
!(0, isEmpty_1.default)(missingEnvLocalesInEntries) ||
|
|
105
95
|
!(0, isEmpty_1.default)(missingFieldRules) ||
|
|
106
|
-
!(0, isEmpty_1.default)(missingMultipleFields)
|
|
96
|
+
!(0, isEmpty_1.default)(missingMultipleFields) ||
|
|
97
|
+
!(0, isEmpty_1.default)(missingRefsInComposableStudio)) {
|
|
107
98
|
if (this.currentCommand === 'cm:stacks:audit') {
|
|
108
99
|
cli_utilities_1.log.warn(this.$t(messages_1.auditMsg.FINAL_REPORT_PATH, { path: this.sharedConfig.reportPath }), this.auditContext);
|
|
109
100
|
}
|
|
@@ -130,7 +121,8 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
130
121
|
!(0, isEmpty_1.default)(missingRefInCustomRoles) ||
|
|
131
122
|
!(0, isEmpty_1.default)(missingEnvLocalesInAssets) ||
|
|
132
123
|
!(0, isEmpty_1.default)(missingEnvLocalesInEntries) ||
|
|
133
|
-
!(0, isEmpty_1.default)(missingFieldRules)
|
|
124
|
+
!(0, isEmpty_1.default)(missingFieldRules) ||
|
|
125
|
+
!(0, isEmpty_1.default)(missingRefsInComposableStudio));
|
|
134
126
|
}
|
|
135
127
|
/**
|
|
136
128
|
* The `scan` function performs an audit on different modules (content-types, global-fields, and
|
|
@@ -143,7 +135,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
143
135
|
cli_utilities_1.log.debug('Starting scan and fix process', this.auditContext);
|
|
144
136
|
let { ctSchema, gfSchema } = this.getCtAndGfSchema();
|
|
145
137
|
cli_utilities_1.log.info(`Retrieved ${(ctSchema === null || ctSchema === void 0 ? void 0 : ctSchema.length) || 0} content types and ${(gfSchema === null || gfSchema === void 0 ? void 0 : gfSchema.length) || 0} global fields`, this.auditContext);
|
|
146
|
-
let missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow, missingSelectFeild, missingEntry = {}, missingMandatoryFields, missingTitleFields, missingRefInCustomRoles, missingEnvLocalesInAssets, missingEnvLocalesInEntries, missingFieldRules, missingMultipleFields;
|
|
138
|
+
let missingCtRefs, missingGfRefs, missingEntryRefs, missingCtRefsInExtensions, missingCtRefsInWorkflow, missingSelectFeild, missingEntry = {}, missingMandatoryFields, missingTitleFields, missingRefInCustomRoles, missingEnvLocalesInAssets, missingEnvLocalesInEntries, missingFieldRules, missingMultipleFields, missingRefsInComposableStudio;
|
|
147
139
|
const constructorParam = {
|
|
148
140
|
ctSchema,
|
|
149
141
|
gfSchema,
|
|
@@ -154,7 +146,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
154
146
|
cli_utilities_1.log.debug(`Data module wise: ${JSON.stringify(dataModuleWise)}`, this.auditContext);
|
|
155
147
|
for (const module of this.sharedConfig.flags.modules || this.sharedConfig.modules) {
|
|
156
148
|
// Update audit context with current module
|
|
157
|
-
this.auditContext =
|
|
149
|
+
this.auditContext = { module: module };
|
|
158
150
|
cli_utilities_1.log.debug(`Starting audit for module: ${module}`, this.auditContext);
|
|
159
151
|
cli_utilities_1.log.info(`Starting audit for module: ${module}`, this.auditContext);
|
|
160
152
|
(0, log_1.print)([
|
|
@@ -242,6 +234,13 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
242
234
|
this.getAffectedData('field-rules', dataModuleWise['content-types'], missingFieldRules);
|
|
243
235
|
cli_utilities_1.log.success(`Field-rules audit completed. Found ${Object.keys(missingFieldRules || {}).length} issues`, this.auditContext);
|
|
244
236
|
break;
|
|
237
|
+
case 'composable-studio':
|
|
238
|
+
cli_utilities_1.log.info('Executing composable-studio audit', this.auditContext);
|
|
239
|
+
missingRefsInComposableStudio = await new modules_1.ComposableStudio((0, cloneDeep_1.default)(constructorParam)).run();
|
|
240
|
+
await this.prepareReport(module, missingRefsInComposableStudio);
|
|
241
|
+
this.getAffectedData('composable-studio', dataModuleWise['composable-studio'] || { Total: Object.keys(missingRefsInComposableStudio || {}).length }, missingRefsInComposableStudio);
|
|
242
|
+
cli_utilities_1.log.success(`Composable-studio audit completed. Found ${Object.keys(missingRefsInComposableStudio || {}).length} issues`, this.auditContext);
|
|
243
|
+
break;
|
|
245
244
|
}
|
|
246
245
|
(0, log_1.print)([
|
|
247
246
|
{
|
|
@@ -273,6 +272,7 @@ class AuditBaseCommand extends base_command_1.BaseCommand {
|
|
|
273
272
|
missingEnvLocalesInEntries,
|
|
274
273
|
missingFieldRules,
|
|
275
274
|
missingMultipleFields,
|
|
275
|
+
missingRefsInComposableStudio,
|
|
276
276
|
};
|
|
277
277
|
}
|
|
278
278
|
/**
|
package/lib/config/index.d.ts
CHANGED
package/lib/config/index.js
CHANGED
|
@@ -13,6 +13,7 @@ const config = {
|
|
|
13
13
|
'custom-roles',
|
|
14
14
|
'assets',
|
|
15
15
|
'field-rules',
|
|
16
|
+
'composable-studio',
|
|
16
17
|
],
|
|
17
18
|
'fix-fields': ['reference', 'global_field', 'json:rte', 'json:extension', 'blocks', 'group', 'content_types'],
|
|
18
19
|
'schema-fields-data-type': ['blocks', 'group', 'global_field'],
|
|
@@ -62,6 +63,11 @@ const config = {
|
|
|
62
63
|
dirName: 'environments',
|
|
63
64
|
fileName: 'environments.json',
|
|
64
65
|
},
|
|
66
|
+
'composable-studio': {
|
|
67
|
+
name: 'composable-studio',
|
|
68
|
+
dirName: 'composable_studio',
|
|
69
|
+
fileName: 'composable_studio.json',
|
|
70
|
+
},
|
|
65
71
|
},
|
|
66
72
|
entries: {
|
|
67
73
|
systemKeys: [
|
|
@@ -109,13 +115,14 @@ const config = {
|
|
|
109
115
|
'selectedValue',
|
|
110
116
|
'ct_uid',
|
|
111
117
|
'action',
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
'Module',
|
|
119
|
+
'Total',
|
|
120
|
+
'Fixable',
|
|
121
|
+
'Non-Fixable',
|
|
122
|
+
'Fixed',
|
|
123
|
+
'Not-Fixed',
|
|
124
|
+
'Passed',
|
|
125
|
+
'issues',
|
|
119
126
|
],
|
|
120
127
|
ReportTitleForEntries: {
|
|
121
128
|
Entries_Select_field: 'Entries_Select_field',
|
|
@@ -123,7 +130,7 @@ const config = {
|
|
|
123
130
|
Entries_Title_field: 'Entries_Title_field',
|
|
124
131
|
Entry_Missing_Locale_and_Env: 'Entry_Missing_Locale_and_Env',
|
|
125
132
|
Entry_Missing_Locale_and_Env_in_Publish_Details: 'Entry_Missing_Locale_and_Env_in_Publish_Details',
|
|
126
|
-
Entry_Multiple_Fields:
|
|
133
|
+
Entry_Multiple_Fields: 'Entry_Multiple_Fields',
|
|
127
134
|
},
|
|
128
135
|
feild_level_modules: [
|
|
129
136
|
'Entries_Title_field',
|
|
@@ -132,7 +139,7 @@ const config = {
|
|
|
132
139
|
'Entry_Missing_Locale_and_Env_in_Publish_Details',
|
|
133
140
|
'field-rules',
|
|
134
141
|
'Entry_Multiple_Fields',
|
|
135
|
-
'Summary'
|
|
142
|
+
'Summary',
|
|
136
143
|
],
|
|
137
144
|
fixSelectField: false,
|
|
138
145
|
};
|
package/lib/messages/index.d.ts
CHANGED
package/lib/messages/index.js
CHANGED
|
@@ -42,6 +42,7 @@ const auditMsg = {
|
|
|
42
42
|
AUDIT_CMD_DESCRIPTION: 'Perform audits and find possible errors in the exported Contentstack data',
|
|
43
43
|
SCAN_WF_SUCCESS_MSG: 'Successfully completed the scanning of workflow with UID {uid} and name {name}.',
|
|
44
44
|
SCAN_CR_SUCCESS_MSG: 'Successfully completed the scanning of custom role with UID {uid} and name {name}.',
|
|
45
|
+
SCAN_CS_SUCCESS_MSG: 'Successfully completed the scanning of studio project with UID {uid} and name {name}.',
|
|
45
46
|
SCAN_ASSET_SUCCESS_MSG: `Successfully completed the scanning of Asset with UID '{uid}'.`,
|
|
46
47
|
SCAN_ASSET_WARN_MSG: `The locale '{locale}' or environment '{environment}' are not present for asset with uid '{uid}'`,
|
|
47
48
|
ENTRY_PUBLISH_DETAILS: `Removing the publish detials for entry '{uid}' of ct '{ctuid}' in locale '{locale}' as locale '{publocale}' or environment '{environment}' does not exist`,
|
|
@@ -51,7 +52,7 @@ const auditMsg = {
|
|
|
51
52
|
FIELD_RULE_CONDITION_ABSENT: `The operand field '{condition_field}' is not present in the schema of the content-type {ctUid}`,
|
|
52
53
|
FIELD_RULE_TARGET_ABSENT: `The target field '{target_field}' is not present in the schema of the content-type {ctUid}`,
|
|
53
54
|
FIELD_RULE_CONDITION_SCAN_MESSAGE: `Completed Scanning of Field Rule '{num}' condition of Content-type '{ctUid}'`,
|
|
54
|
-
FIELD_RULE_TARGET_SCAN_MESSAGE: `Completed Scanning of Field Rule '{num}' target of Content-type '{ctUid}'
|
|
55
|
+
FIELD_RULE_TARGET_SCAN_MESSAGE: `Completed Scanning of Field Rule '{num}' target of Content-type '{ctUid}'`,
|
|
55
56
|
};
|
|
56
57
|
exports.auditMsg = auditMsg;
|
|
57
58
|
const auditFixMsg = {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ConfigType, ContentTypeStruct, CtConstructorParam, ModuleConstructorParam } from '../types';
|
|
2
|
+
import auditConfig from '../config';
|
|
3
|
+
import { ComposableStudioProject } from '../types/composable-studio';
|
|
4
|
+
export default class ComposableStudio {
|
|
5
|
+
protected fix: boolean;
|
|
6
|
+
fileName: string;
|
|
7
|
+
config: ConfigType;
|
|
8
|
+
folderPath: string;
|
|
9
|
+
composableStudioProjects: ComposableStudioProject[];
|
|
10
|
+
ctSchema: ContentTypeStruct[];
|
|
11
|
+
moduleName: keyof typeof auditConfig.moduleConfig;
|
|
12
|
+
ctUidSet: Set<string>;
|
|
13
|
+
environmentUidSet: Set<string>;
|
|
14
|
+
localeCodeSet: Set<string>;
|
|
15
|
+
projectsWithIssues: any[];
|
|
16
|
+
composableStudioPath: string;
|
|
17
|
+
private projectsWithIssuesMap;
|
|
18
|
+
constructor({ fix, config, moduleName, ctSchema }: ModuleConstructorParam & Pick<CtConstructorParam, 'ctSchema'>);
|
|
19
|
+
validateModules(moduleName: keyof typeof auditConfig.moduleConfig, moduleConfig: Record<string, unknown>): keyof typeof auditConfig.moduleConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Load environments from the environments.json file
|
|
22
|
+
*/
|
|
23
|
+
loadEnvironments(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Load locales from the locales.json and master-locale.json files
|
|
26
|
+
*/
|
|
27
|
+
loadLocales(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Main run method to audit composable studio projects
|
|
30
|
+
*/
|
|
31
|
+
run(): Promise<{}>;
|
|
32
|
+
/**
|
|
33
|
+
* Fix composable studio projects by removing invalid references
|
|
34
|
+
*/
|
|
35
|
+
fixComposableStudioProjects(): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Write fixed composable studio projects back to file
|
|
38
|
+
*/
|
|
39
|
+
writeFixContent(fixedProjects: any): Promise<void>;
|
|
40
|
+
}
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const path_1 = require("path");
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
6
|
+
const messages_1 = require("../messages");
|
|
7
|
+
class ComposableStudio {
|
|
8
|
+
constructor({ fix, config, moduleName, ctSchema }) {
|
|
9
|
+
this.config = config;
|
|
10
|
+
this.fix = fix !== null && fix !== void 0 ? fix : false;
|
|
11
|
+
this.ctSchema = ctSchema;
|
|
12
|
+
this.composableStudioProjects = [];
|
|
13
|
+
cli_utilities_1.log.debug(`Initializing ComposableStudio module`, this.config.auditContext);
|
|
14
|
+
cli_utilities_1.log.debug(`Fix mode: ${this.fix}`, this.config.auditContext);
|
|
15
|
+
cli_utilities_1.log.debug(`Content types count: ${ctSchema.length}`, this.config.auditContext);
|
|
16
|
+
cli_utilities_1.log.debug(`Module name: ${moduleName}`, this.config.auditContext);
|
|
17
|
+
this.moduleName = this.validateModules(moduleName, this.config.moduleConfig);
|
|
18
|
+
this.fileName = config.moduleConfig[this.moduleName].fileName;
|
|
19
|
+
cli_utilities_1.log.debug(`File name: ${this.fileName}`, this.config.auditContext);
|
|
20
|
+
this.folderPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(config.basePath), (0, cli_utilities_1.sanitizePath)(config.moduleConfig[this.moduleName].dirName));
|
|
21
|
+
cli_utilities_1.log.debug(`Folder path: ${this.folderPath}`, this.config.auditContext);
|
|
22
|
+
this.ctUidSet = new Set();
|
|
23
|
+
this.environmentUidSet = new Set();
|
|
24
|
+
this.localeCodeSet = new Set();
|
|
25
|
+
this.projectsWithIssues = [];
|
|
26
|
+
this.projectsWithIssuesMap = new Map();
|
|
27
|
+
this.composableStudioPath = '';
|
|
28
|
+
cli_utilities_1.log.debug(`ComposableStudio module initialization completed`, this.config.auditContext);
|
|
29
|
+
}
|
|
30
|
+
validateModules(moduleName, moduleConfig) {
|
|
31
|
+
cli_utilities_1.log.debug(`Validating module: ${moduleName}`, this.config.auditContext);
|
|
32
|
+
cli_utilities_1.log.debug(`Available modules: ${Object.keys(moduleConfig).join(', ')}`, this.config.auditContext);
|
|
33
|
+
if (Object.keys(moduleConfig).includes(moduleName)) {
|
|
34
|
+
cli_utilities_1.log.debug(`Module ${moduleName} is valid`, this.config.auditContext);
|
|
35
|
+
return moduleName;
|
|
36
|
+
}
|
|
37
|
+
cli_utilities_1.log.debug(`Module ${moduleName} not found, defaulting to 'composable-studio'`, this.config.auditContext);
|
|
38
|
+
return 'composable-studio';
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Load environments from the environments.json file
|
|
42
|
+
*/
|
|
43
|
+
async loadEnvironments() {
|
|
44
|
+
cli_utilities_1.log.debug(`Loading environments`, this.config.auditContext);
|
|
45
|
+
const environmentsPath = (0, path_1.resolve)(this.config.basePath, 'environments', 'environments.json');
|
|
46
|
+
if ((0, fs_1.existsSync)(environmentsPath)) {
|
|
47
|
+
cli_utilities_1.log.debug(`Environments file path: ${environmentsPath}`, this.config.auditContext);
|
|
48
|
+
try {
|
|
49
|
+
const environments = JSON.parse((0, fs_1.readFileSync)(environmentsPath, 'utf-8'));
|
|
50
|
+
const envArray = Array.isArray(environments) ? environments : Object.values(environments);
|
|
51
|
+
envArray.forEach((env) => {
|
|
52
|
+
if (env.uid) {
|
|
53
|
+
this.environmentUidSet.add(env.uid);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
cli_utilities_1.log.debug(`Loaded ${this.environmentUidSet.size} environments: ${Array.from(this.environmentUidSet).join(', ')}`, this.config.auditContext);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
(0, cli_utilities_1.handleAndLogError)(error, this.config.auditContext, 'Failed to load environments');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
cli_utilities_1.log.debug(`Environments file not found at: ${environmentsPath}`, this.config.auditContext);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Load locales from the locales.json and master-locale.json files
|
|
68
|
+
*/
|
|
69
|
+
async loadLocales() {
|
|
70
|
+
cli_utilities_1.log.debug(`Loading locales`, this.config.auditContext);
|
|
71
|
+
const localesPath = (0, path_1.resolve)(this.config.basePath, 'locales', 'locales.json');
|
|
72
|
+
const masterLocalePath = (0, path_1.resolve)(this.config.basePath, 'locales', 'master-locale.json');
|
|
73
|
+
// Load master locale
|
|
74
|
+
if ((0, fs_1.existsSync)(masterLocalePath)) {
|
|
75
|
+
cli_utilities_1.log.debug(`Master locale file path: ${masterLocalePath}`, this.config.auditContext);
|
|
76
|
+
try {
|
|
77
|
+
const masterLocales = JSON.parse((0, fs_1.readFileSync)(masterLocalePath, 'utf-8'));
|
|
78
|
+
const localeArray = Array.isArray(masterLocales) ? masterLocales : Object.values(masterLocales);
|
|
79
|
+
localeArray.forEach((locale) => {
|
|
80
|
+
if (locale.code) {
|
|
81
|
+
this.localeCodeSet.add(locale.code);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
cli_utilities_1.log.debug(`Loaded ${this.localeCodeSet.size} master locales`, this.config.auditContext);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
(0, cli_utilities_1.handleAndLogError)(error, this.config.auditContext, 'Failed to load master locales');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
cli_utilities_1.log.debug(`Master locale file not found at: ${masterLocalePath}`, this.config.auditContext);
|
|
92
|
+
}
|
|
93
|
+
// Load additional locales
|
|
94
|
+
if ((0, fs_1.existsSync)(localesPath)) {
|
|
95
|
+
cli_utilities_1.log.debug(`Locales file path: ${localesPath}`, this.config.auditContext);
|
|
96
|
+
try {
|
|
97
|
+
const locales = JSON.parse((0, fs_1.readFileSync)(localesPath, 'utf-8'));
|
|
98
|
+
const localeArray = Array.isArray(locales) ? locales : Object.values(locales);
|
|
99
|
+
localeArray.forEach((locale) => {
|
|
100
|
+
if (locale.code) {
|
|
101
|
+
this.localeCodeSet.add(locale.code);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
cli_utilities_1.log.debug(`Total locales after loading additional locales: ${this.localeCodeSet.size}`, this.config.auditContext);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
(0, cli_utilities_1.handleAndLogError)(error, this.config.auditContext, 'Failed to load additional locales');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
cli_utilities_1.log.debug(`Locales file not found at: ${localesPath}`, this.config.auditContext);
|
|
112
|
+
}
|
|
113
|
+
cli_utilities_1.log.debug(`Locale codes loaded: ${Array.from(this.localeCodeSet).join(', ')}`, this.config.auditContext);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Main run method to audit composable studio projects
|
|
117
|
+
*/
|
|
118
|
+
async run() {
|
|
119
|
+
var _a, _b, _c, _d;
|
|
120
|
+
cli_utilities_1.log.debug(`Starting ${this.moduleName} audit process`, this.config.auditContext);
|
|
121
|
+
cli_utilities_1.log.debug(`Composable Studio folder path: ${this.folderPath}`, this.config.auditContext);
|
|
122
|
+
cli_utilities_1.log.debug(`Fix mode: ${this.fix}`, this.config.auditContext);
|
|
123
|
+
if (!(0, fs_1.existsSync)(this.folderPath)) {
|
|
124
|
+
cli_utilities_1.log.debug(`Skipping ${this.moduleName} audit - path does not exist`, this.config.auditContext);
|
|
125
|
+
cli_utilities_1.log.warn(`Skipping ${this.moduleName} audit`, this.config.auditContext);
|
|
126
|
+
cli_utilities_1.cliux.print((0, messages_1.$t)(messages_1.auditMsg.NOT_VALID_PATH, { path: this.folderPath }), { color: 'yellow' });
|
|
127
|
+
return {};
|
|
128
|
+
}
|
|
129
|
+
this.composableStudioPath = (0, path_1.join)(this.folderPath, this.fileName);
|
|
130
|
+
cli_utilities_1.log.debug(`Composable Studio file path: ${this.composableStudioPath}`, this.config.auditContext);
|
|
131
|
+
// Load composable studio projects
|
|
132
|
+
cli_utilities_1.log.debug(`Loading composable studio projects from file`, this.config.auditContext);
|
|
133
|
+
if ((0, fs_1.existsSync)(this.composableStudioPath)) {
|
|
134
|
+
try {
|
|
135
|
+
const projectsData = JSON.parse((0, fs_1.readFileSync)(this.composableStudioPath, 'utf-8'));
|
|
136
|
+
this.composableStudioProjects = Array.isArray(projectsData) ? projectsData : [projectsData];
|
|
137
|
+
cli_utilities_1.log.debug(`Loaded ${this.composableStudioProjects.length} composable studio projects`, this.config.auditContext);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
(0, cli_utilities_1.handleAndLogError)(error, this.config.auditContext, 'Failed to load composable studio projects');
|
|
141
|
+
return {};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
cli_utilities_1.log.debug(`Composable studio file not found`, this.config.auditContext);
|
|
146
|
+
return {};
|
|
147
|
+
}
|
|
148
|
+
// Build content type UID set
|
|
149
|
+
cli_utilities_1.log.debug(`Building content type UID set from ${this.ctSchema.length} content types`, this.config.auditContext);
|
|
150
|
+
this.ctSchema.forEach((ct) => this.ctUidSet.add(ct.uid));
|
|
151
|
+
cli_utilities_1.log.debug(`Content type UID set contains: ${Array.from(this.ctUidSet).join(', ')}`, this.config.auditContext);
|
|
152
|
+
// Load environments and locales
|
|
153
|
+
await this.loadEnvironments();
|
|
154
|
+
await this.loadLocales();
|
|
155
|
+
// Process each project
|
|
156
|
+
cli_utilities_1.log.debug(`Processing ${this.composableStudioProjects.length} composable studio projects`, this.config.auditContext);
|
|
157
|
+
for (const project of this.composableStudioProjects) {
|
|
158
|
+
const { name, uid, contentTypeUid, settings } = project;
|
|
159
|
+
cli_utilities_1.log.debug(`Processing composable studio project: ${name} (${uid})`, this.config.auditContext);
|
|
160
|
+
cli_utilities_1.log.debug(`Content type UID: ${contentTypeUid}`, this.config.auditContext);
|
|
161
|
+
cli_utilities_1.log.debug(`Environment: ${(_a = settings === null || settings === void 0 ? void 0 : settings.configuration) === null || _a === void 0 ? void 0 : _a.environment}`, this.config.auditContext);
|
|
162
|
+
cli_utilities_1.log.debug(`Locale: ${(_b = settings === null || settings === void 0 ? void 0 : settings.configuration) === null || _b === void 0 ? void 0 : _b.locale}`, this.config.auditContext);
|
|
163
|
+
let hasIssues = false;
|
|
164
|
+
const issuesList = [];
|
|
165
|
+
const invalidContentTypes = [];
|
|
166
|
+
const invalidEnvironments = [];
|
|
167
|
+
const invalidLocales = [];
|
|
168
|
+
// Check content type
|
|
169
|
+
if (contentTypeUid && !this.ctUidSet.has(contentTypeUid)) {
|
|
170
|
+
cli_utilities_1.log.debug(`Content type ${contentTypeUid} not found in project ${name}`, this.config.auditContext);
|
|
171
|
+
invalidContentTypes.push(contentTypeUid);
|
|
172
|
+
issuesList.push(`Invalid contentTypeUid: ${contentTypeUid}`);
|
|
173
|
+
hasIssues = true;
|
|
174
|
+
}
|
|
175
|
+
// Check environment
|
|
176
|
+
if (((_c = settings === null || settings === void 0 ? void 0 : settings.configuration) === null || _c === void 0 ? void 0 : _c.environment) && !this.environmentUidSet.has(settings.configuration.environment)) {
|
|
177
|
+
cli_utilities_1.log.debug(`Environment ${settings.configuration.environment} not found in project ${name}`, this.config.auditContext);
|
|
178
|
+
invalidEnvironments.push(settings.configuration.environment);
|
|
179
|
+
issuesList.push(`Invalid environment: ${settings.configuration.environment}`);
|
|
180
|
+
hasIssues = true;
|
|
181
|
+
}
|
|
182
|
+
// Check locale
|
|
183
|
+
if (((_d = settings === null || settings === void 0 ? void 0 : settings.configuration) === null || _d === void 0 ? void 0 : _d.locale) && !this.localeCodeSet.has(settings.configuration.locale)) {
|
|
184
|
+
cli_utilities_1.log.debug(`Locale ${settings.configuration.locale} not found in project ${name}`, this.config.auditContext);
|
|
185
|
+
invalidLocales.push(settings.configuration.locale);
|
|
186
|
+
issuesList.push(`Invalid locale: ${settings.configuration.locale}`);
|
|
187
|
+
hasIssues = true;
|
|
188
|
+
}
|
|
189
|
+
if (hasIssues) {
|
|
190
|
+
cli_utilities_1.log.debug(`Project ${name} has validation issues`, this.config.auditContext);
|
|
191
|
+
// Store the original project for fixing
|
|
192
|
+
this.projectsWithIssuesMap.set(uid, project);
|
|
193
|
+
// Create a report-friendly object
|
|
194
|
+
const reportEntry = {
|
|
195
|
+
title: name,
|
|
196
|
+
name: name,
|
|
197
|
+
uid: uid,
|
|
198
|
+
content_types: invalidContentTypes.length > 0 ? invalidContentTypes : undefined,
|
|
199
|
+
environment: invalidEnvironments.length > 0 ? invalidEnvironments : undefined,
|
|
200
|
+
locale: invalidLocales.length > 0 ? invalidLocales : undefined,
|
|
201
|
+
issues: issuesList.join(', '),
|
|
202
|
+
};
|
|
203
|
+
this.projectsWithIssues.push(reportEntry);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
cli_utilities_1.log.debug(`Project ${name} has no validation issues`, this.config.auditContext);
|
|
207
|
+
}
|
|
208
|
+
cli_utilities_1.log.info((0, messages_1.$t)(messages_1.auditMsg.SCAN_CS_SUCCESS_MSG, {
|
|
209
|
+
name,
|
|
210
|
+
uid,
|
|
211
|
+
}), this.config.auditContext);
|
|
212
|
+
}
|
|
213
|
+
cli_utilities_1.log.debug(`Composable Studio audit completed. Found ${this.projectsWithIssues.length} projects with issues`, this.config.auditContext);
|
|
214
|
+
if (this.fix && this.projectsWithIssues.length) {
|
|
215
|
+
cli_utilities_1.log.debug(`Fix mode enabled, fixing ${this.projectsWithIssues.length} projects`, this.config.auditContext);
|
|
216
|
+
await this.fixComposableStudioProjects();
|
|
217
|
+
this.projectsWithIssues.forEach((project) => {
|
|
218
|
+
cli_utilities_1.log.debug(`Marking project ${project.name} as fixed`, this.config.auditContext);
|
|
219
|
+
project.fixStatus = 'Fixed';
|
|
220
|
+
});
|
|
221
|
+
cli_utilities_1.log.debug(`Composable Studio fix completed`, this.config.auditContext);
|
|
222
|
+
return this.projectsWithIssues;
|
|
223
|
+
}
|
|
224
|
+
cli_utilities_1.log.debug(`Composable Studio audit completed without fixes`, this.config.auditContext);
|
|
225
|
+
return this.projectsWithIssues;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Fix composable studio projects by removing invalid references
|
|
229
|
+
*/
|
|
230
|
+
async fixComposableStudioProjects() {
|
|
231
|
+
var _a, _b, _c, _d;
|
|
232
|
+
cli_utilities_1.log.debug(`Starting composable studio projects fix`, this.config.auditContext);
|
|
233
|
+
cli_utilities_1.log.debug(`Loading current composable studio projects from: ${this.composableStudioPath}`, this.config.auditContext);
|
|
234
|
+
let projectsData;
|
|
235
|
+
try {
|
|
236
|
+
projectsData = JSON.parse((0, fs_1.readFileSync)(this.composableStudioPath, 'utf-8'));
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
cli_utilities_1.log.debug(`Failed to load composable studio projects for fixing: ${error}`, this.config.auditContext);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
const isArray = Array.isArray(projectsData);
|
|
243
|
+
const projects = isArray ? projectsData : [projectsData];
|
|
244
|
+
cli_utilities_1.log.debug(`Loaded ${projects.length} projects for fixing`, this.config.auditContext);
|
|
245
|
+
for (let i = 0; i < projects.length; i++) {
|
|
246
|
+
const project = projects[i];
|
|
247
|
+
const { uid, name } = project;
|
|
248
|
+
cli_utilities_1.log.debug(`Fixing project: ${name} (${uid})`, this.config.auditContext);
|
|
249
|
+
let needsFix = false;
|
|
250
|
+
// Check and fix content type
|
|
251
|
+
if (project.contentTypeUid && !this.ctUidSet.has(project.contentTypeUid)) {
|
|
252
|
+
cli_utilities_1.log.debug(`Removing invalid content type ${project.contentTypeUid} from project ${name}`, this.config.auditContext);
|
|
253
|
+
cli_utilities_1.cliux.print(`Warning: Project "${name}" has invalid content type "${project.contentTypeUid}". It will be removed.`, { color: 'yellow' });
|
|
254
|
+
project.contentTypeUid = undefined;
|
|
255
|
+
needsFix = true;
|
|
256
|
+
}
|
|
257
|
+
// Check and fix environment
|
|
258
|
+
if (((_b = (_a = project.settings) === null || _a === void 0 ? void 0 : _a.configuration) === null || _b === void 0 ? void 0 : _b.environment) &&
|
|
259
|
+
!this.environmentUidSet.has(project.settings.configuration.environment)) {
|
|
260
|
+
cli_utilities_1.log.debug(`Removing invalid environment ${project.settings.configuration.environment} from project ${name}`, this.config.auditContext);
|
|
261
|
+
cli_utilities_1.cliux.print(`Warning: Project "${name}" has invalid environment "${project.settings.configuration.environment}". It will be removed.`, { color: 'yellow' });
|
|
262
|
+
project.settings.configuration.environment = undefined;
|
|
263
|
+
needsFix = true;
|
|
264
|
+
}
|
|
265
|
+
// Check and fix locale
|
|
266
|
+
if (((_d = (_c = project.settings) === null || _c === void 0 ? void 0 : _c.configuration) === null || _d === void 0 ? void 0 : _d.locale) && !this.localeCodeSet.has(project.settings.configuration.locale)) {
|
|
267
|
+
cli_utilities_1.log.debug(`Removing invalid locale ${project.settings.configuration.locale} from project ${name}`, this.config.auditContext);
|
|
268
|
+
cli_utilities_1.cliux.print(`Warning: Project "${name}" has invalid locale "${project.settings.configuration.locale}". It will be removed.`, { color: 'yellow' });
|
|
269
|
+
project.settings.configuration.locale = undefined;
|
|
270
|
+
needsFix = true;
|
|
271
|
+
}
|
|
272
|
+
if (needsFix) {
|
|
273
|
+
cli_utilities_1.log.debug(`Project ${name} was fixed`, this.config.auditContext);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
cli_utilities_1.log.debug(`Project ${name} did not need fixing`, this.config.auditContext);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
cli_utilities_1.log.debug(`Composable studio projects fix completed, writing updated file`, this.config.auditContext);
|
|
280
|
+
await this.writeFixContent(isArray ? projects : projects[0]);
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Write fixed composable studio projects back to file
|
|
284
|
+
*/
|
|
285
|
+
async writeFixContent(fixedProjects) {
|
|
286
|
+
var _a, _b;
|
|
287
|
+
cli_utilities_1.log.debug(`Writing fix content`, this.config.auditContext);
|
|
288
|
+
cli_utilities_1.log.debug(`Fix mode: ${this.fix}`, this.config.auditContext);
|
|
289
|
+
cli_utilities_1.log.debug(`Copy directory flag: ${this.config.flags['copy-dir']}`, this.config.auditContext);
|
|
290
|
+
cli_utilities_1.log.debug(`External config skip confirm: ${(_a = this.config.flags['external-config']) === null || _a === void 0 ? void 0 : _a.skipConfirm}`, this.config.auditContext);
|
|
291
|
+
cli_utilities_1.log.debug(`Yes flag: ${this.config.flags.yes}`, this.config.auditContext);
|
|
292
|
+
if (this.fix &&
|
|
293
|
+
(this.config.flags['copy-dir'] ||
|
|
294
|
+
((_b = this.config.flags['external-config']) === null || _b === void 0 ? void 0 : _b.skipConfirm) ||
|
|
295
|
+
this.config.flags.yes ||
|
|
296
|
+
(await cli_utilities_1.cliux.confirm(messages_1.commonMsg.FIX_CONFIRMATION)))) {
|
|
297
|
+
const outputPath = (0, path_1.join)(this.folderPath, this.config.moduleConfig[this.moduleName].fileName);
|
|
298
|
+
cli_utilities_1.log.debug(`Writing fixed composable studio projects to: ${outputPath}`, this.config.auditContext);
|
|
299
|
+
(0, fs_1.writeFileSync)(outputPath, JSON.stringify(fixedProjects, null, 2));
|
|
300
|
+
cli_utilities_1.log.debug(`Successfully wrote fixed composable studio projects to file`, this.config.auditContext);
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
cli_utilities_1.log.debug(`Skipping file write - fix mode disabled or user declined confirmation`, this.config.auditContext);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
exports.default = ComposableStudio;
|
package/lib/modules/index.d.ts
CHANGED
|
@@ -7,4 +7,5 @@ import CustomRoles from './custom-roles';
|
|
|
7
7
|
import Assets from './assets';
|
|
8
8
|
import FieldRule from './field_rules';
|
|
9
9
|
import ModuleDataReader from './modulesData';
|
|
10
|
-
|
|
10
|
+
import ComposableStudio from './composable-studio';
|
|
11
|
+
export { Entries, GlobalField, ContentType, Workflows, Extensions, Assets, CustomRoles, FieldRule, ModuleDataReader, ComposableStudio };
|
package/lib/modules/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ModuleDataReader = exports.FieldRule = exports.CustomRoles = exports.Assets = exports.Extensions = exports.Workflows = exports.ContentType = exports.GlobalField = exports.Entries = void 0;
|
|
3
|
+
exports.ComposableStudio = exports.ModuleDataReader = exports.FieldRule = exports.CustomRoles = exports.Assets = exports.Extensions = exports.Workflows = exports.ContentType = exports.GlobalField = exports.Entries = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const entries_1 = tslib_1.__importDefault(require("./entries"));
|
|
6
6
|
exports.Entries = entries_1.default;
|
|
@@ -20,3 +20,5 @@ const field_rules_1 = tslib_1.__importDefault(require("./field_rules"));
|
|
|
20
20
|
exports.FieldRule = field_rules_1.default;
|
|
21
21
|
const modulesData_1 = tslib_1.__importDefault(require("./modulesData"));
|
|
22
22
|
exports.ModuleDataReader = modulesData_1.default;
|
|
23
|
+
const composable_studio_1 = tslib_1.__importDefault(require("./composable-studio"));
|
|
24
|
+
exports.ComposableStudio = composable_studio_1.default;
|
|
@@ -24,7 +24,7 @@ class ModuleDataReader {
|
|
|
24
24
|
cli_utilities_1.log.debug(`Getting item count for module: ${moduleName}`, this.config.auditContext);
|
|
25
25
|
let count = 0;
|
|
26
26
|
switch (moduleName) {
|
|
27
|
-
case
|
|
27
|
+
case 'content-types':
|
|
28
28
|
cli_utilities_1.log.debug(`Counting content types`, this.config.auditContext);
|
|
29
29
|
count = this.ctSchema.length;
|
|
30
30
|
cli_utilities_1.log.debug(`Content types count: ${count}`, this.config.auditContext);
|
|
@@ -38,7 +38,7 @@ class ModuleDataReader {
|
|
|
38
38
|
cli_utilities_1.log.debug(`Counting assets`, this.config.auditContext);
|
|
39
39
|
const assetsPath = (0, path_1.join)(this.folderPath, 'assets');
|
|
40
40
|
cli_utilities_1.log.debug(`Assets path: ${assetsPath}`, this.config.auditContext);
|
|
41
|
-
count = await this.readEntryAssetsModule(assetsPath, 'assets') || 0;
|
|
41
|
+
count = (await this.readEntryAssetsModule(assetsPath, 'assets')) || 0;
|
|
42
42
|
cli_utilities_1.log.debug(`Assets count: ${count}`, this.config.auditContext);
|
|
43
43
|
break;
|
|
44
44
|
}
|
|
@@ -53,11 +53,13 @@ class ModuleDataReader {
|
|
|
53
53
|
cli_utilities_1.log.debug(`Master locales path: ${masterLocalesPath}`, this.config.auditContext);
|
|
54
54
|
cli_utilities_1.log.debug(`Loading master locales`, this.config.auditContext);
|
|
55
55
|
this.locales = (0, lodash_1.values)(await this.readUsingFsModule(masterLocalesPath));
|
|
56
|
-
cli_utilities_1.log.debug(`Loaded ${this.locales.length} master locales: ${this.locales.map(locale => locale.code).join(', ')}`, this.config.auditContext);
|
|
56
|
+
cli_utilities_1.log.debug(`Loaded ${this.locales.length} master locales: ${this.locales.map((locale) => locale.code).join(', ')}`, this.config.auditContext);
|
|
57
57
|
if ((0, fs_1.existsSync)(localesPath)) {
|
|
58
58
|
cli_utilities_1.log.debug(`Loading additional locales from file`, this.config.auditContext);
|
|
59
59
|
this.locales.push(...(0, lodash_1.values)(JSON.parse((0, fs_1.readFileSync)(localesPath, 'utf8'))));
|
|
60
|
-
cli_utilities_1.log.debug(`Total locales after loading: ${this.locales.length} - ${this.locales
|
|
60
|
+
cli_utilities_1.log.debug(`Total locales after loading: ${this.locales.length} - ${this.locales
|
|
61
|
+
.map((locale) => locale.code)
|
|
62
|
+
.join(', ')}`, this.config.auditContext);
|
|
61
63
|
}
|
|
62
64
|
else {
|
|
63
65
|
cli_utilities_1.log.debug(`Additional locales file not found`, this.config.auditContext);
|
|
@@ -69,7 +71,7 @@ class ModuleDataReader {
|
|
|
69
71
|
cli_utilities_1.log.debug(`Processing content type: ${ctSchema.uid}`, this.config.auditContext);
|
|
70
72
|
const basePath = (0, path_1.join)(this.folderPath, 'entries', ctSchema.uid, code);
|
|
71
73
|
cli_utilities_1.log.debug(`Base path: ${basePath}`, this.config.auditContext);
|
|
72
|
-
const entryCount = await this.readEntryAssetsModule(basePath, 'index') || 0;
|
|
74
|
+
const entryCount = (await this.readEntryAssetsModule(basePath, 'index')) || 0;
|
|
73
75
|
cli_utilities_1.log.debug(`Found ${entryCount} entries for ${ctSchema.uid} in ${code}`, this.config.auditContext);
|
|
74
76
|
count = count + entryCount;
|
|
75
77
|
}
|
|
@@ -79,12 +81,19 @@ class ModuleDataReader {
|
|
|
79
81
|
break;
|
|
80
82
|
case 'custom-roles':
|
|
81
83
|
case 'extensions':
|
|
82
|
-
case 'workflows':
|
|
84
|
+
case 'workflows':
|
|
85
|
+
case 'composable-studio': {
|
|
83
86
|
cli_utilities_1.log.debug(`Counting ${moduleName}`, this.config.auditContext);
|
|
84
87
|
const modulePath = (0, path_1.resolve)(this.folderPath, (0, cli_utilities_1.sanitizePath)(this.config.moduleConfig[moduleName].dirName), (0, cli_utilities_1.sanitizePath)(this.config.moduleConfig[moduleName].fileName));
|
|
85
88
|
cli_utilities_1.log.debug(`Reading module: ${moduleName} from file: ${modulePath}`, this.config.auditContext);
|
|
86
89
|
const moduleData = await this.readUsingFsModule(modulePath);
|
|
87
|
-
|
|
90
|
+
// For composable-studio, it could be a single object or an array
|
|
91
|
+
if (moduleName === 'composable-studio') {
|
|
92
|
+
count = Array.isArray(moduleData) ? moduleData.length : Object.keys(moduleData).length > 0 ? 1 : 0;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
count = (0, lodash_1.keys)(moduleData).length;
|
|
96
|
+
}
|
|
88
97
|
cli_utilities_1.log.debug(`module:${moduleName} count: ${count}`, this.config.auditContext);
|
|
89
98
|
break;
|
|
90
99
|
}
|
|
@@ -94,7 +103,7 @@ class ModuleDataReader {
|
|
|
94
103
|
}
|
|
95
104
|
async readUsingFsModule(path) {
|
|
96
105
|
cli_utilities_1.log.debug(`Reading file: ${path}`, this.config.auditContext);
|
|
97
|
-
const data = (0, fs_1.existsSync)(path) ?
|
|
106
|
+
const data = (0, fs_1.existsSync)(path) ? JSON.parse((0, fs_1.readFileSync)(path, 'utf-8')) : [];
|
|
98
107
|
cli_utilities_1.log.debug(`File ${(0, fs_1.existsSync)(path) ? 'exists' : 'not found'}, data type: ${Array.isArray(data) ? 'array' : 'object'}`, this.config.auditContext);
|
|
99
108
|
if ((0, fs_1.existsSync)(path)) {
|
|
100
109
|
const dataSize = Array.isArray(data) ? data.length : Object.keys(data).length;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
interface ComposableStudioProject {
|
|
2
|
+
name: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
canvasUrl?: string;
|
|
5
|
+
connectedStackApiKey?: string;
|
|
6
|
+
contentTypeUid: string;
|
|
7
|
+
organizationUid?: string;
|
|
8
|
+
settings: {
|
|
9
|
+
configuration: {
|
|
10
|
+
environment: string;
|
|
11
|
+
locale: string;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
createdBy?: string;
|
|
15
|
+
updatedBy?: string;
|
|
16
|
+
deletedAt?: boolean;
|
|
17
|
+
createdAt?: string;
|
|
18
|
+
updatedAt?: string;
|
|
19
|
+
uid: string;
|
|
20
|
+
missingContentType?: boolean;
|
|
21
|
+
missingEnvironment?: boolean;
|
|
22
|
+
missingLocale?: boolean;
|
|
23
|
+
fixStatus?: string;
|
|
24
|
+
}
|
|
25
|
+
export { ComposableStudioProject };
|
|
@@ -127,7 +127,8 @@ declare enum OutputColumn {
|
|
|
127
127
|
"Fixable" = "Fixable",
|
|
128
128
|
"Non-Fixable" = "Non-Fixable",
|
|
129
129
|
"Fixed" = "Fixed",
|
|
130
|
-
"Not-Fixed" = "Not-Fixed"
|
|
130
|
+
"Not-Fixed" = "Not-Fixed",
|
|
131
|
+
"Issues" = "issues"
|
|
131
132
|
}
|
|
132
133
|
export { CtConstructorParam, ContentTypeStruct, ModuleConstructorParam, ReferenceFieldDataType, GlobalFieldDataType, ExtensionOrAppFieldDataType, JsonRTEFieldDataType, GroupFieldDataType, ModularBlocksDataType, RefErrorReturnType, ModularBlocksSchemaTypes, ModularBlockType, OutputColumn, ContentTypeSchemaType, GlobalFieldSchemaTypes, WorkflowExtensionsRefErrorReturnType, SelectFeildStruct, FieldRuleStruct, };
|
|
133
134
|
type FieldRuleStruct = {
|
package/lib/types/context.d.ts
CHANGED
package/oclif.manifest.json
CHANGED
|
@@ -68,7 +68,8 @@
|
|
|
68
68
|
"workflows",
|
|
69
69
|
"custom-roles",
|
|
70
70
|
"assets",
|
|
71
|
-
"field-rules"
|
|
71
|
+
"field-rules",
|
|
72
|
+
"composable-studio"
|
|
72
73
|
],
|
|
73
74
|
"type": "option"
|
|
74
75
|
},
|
|
@@ -263,7 +264,8 @@
|
|
|
263
264
|
"workflows",
|
|
264
265
|
"custom-roles",
|
|
265
266
|
"assets",
|
|
266
|
-
"field-rules"
|
|
267
|
+
"field-rules",
|
|
268
|
+
"composable-studio"
|
|
267
269
|
],
|
|
268
270
|
"type": "option"
|
|
269
271
|
},
|
|
@@ -344,5 +346,5 @@
|
|
|
344
346
|
]
|
|
345
347
|
}
|
|
346
348
|
},
|
|
347
|
-
"version": "1.
|
|
349
|
+
"version": "1.17.0"
|
|
348
350
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-audit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "Contentstack audit plugin",
|
|
5
5
|
"author": "Contentstack CLI",
|
|
6
6
|
"homepage": "https://github.com/contentstack/cli",
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"/oclif.manifest.json"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@contentstack/cli-command": "~1.7.
|
|
22
|
-
"@contentstack/cli-utilities": "~1.
|
|
21
|
+
"@contentstack/cli-command": "~1.7.1",
|
|
22
|
+
"@contentstack/cli-utilities": "~1.16.0",
|
|
23
23
|
"@oclif/core": "^4.3.0",
|
|
24
24
|
"@oclif/plugin-help": "^6.2.28",
|
|
25
25
|
"@oclif/plugin-plugins": "^5.4.54",
|