@contentstack/cli-audit 1.14.2 → 1.16.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/README.md +13 -13
- package/lib/audit-base-command.d.ts +6 -1
- package/lib/audit-base-command.js +67 -14
- package/lib/base-command.d.ts +1 -4
- package/lib/base-command.js +1 -8
- package/lib/commands/cm/stacks/audit/fix.js +1 -2
- package/lib/commands/cm/stacks/audit/index.js +1 -2
- package/lib/modules/assets.d.ts +2 -3
- package/lib/modules/assets.js +71 -13
- package/lib/modules/content-types.d.ts +3 -4
- package/lib/modules/content-types.js +254 -43
- package/lib/modules/custom-roles.d.ts +2 -3
- package/lib/modules/custom-roles.js +98 -18
- package/lib/modules/entries.d.ts +3 -18
- package/lib/modules/entries.js +478 -63
- package/lib/modules/extensions.d.ts +2 -3
- package/lib/modules/extensions.js +81 -17
- package/lib/modules/field_rules.d.ts +2 -3
- package/lib/modules/field_rules.js +216 -42
- package/lib/modules/global-fields.js +18 -1
- package/lib/modules/modulesData.d.ts +2 -3
- package/lib/modules/modulesData.js +71 -9
- package/lib/modules/workflows.d.ts +2 -3
- package/lib/modules/workflows.js +98 -18
- package/lib/types/content-types.d.ts +1 -2
- package/lib/types/context.d.ts +8 -0
- package/lib/types/context.js +2 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +1 -0
- package/oclif.manifest.json +1 -1
- package/package.json +2 -2
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ConfigType, CtConstructorParam, ModuleConstructorParam, CustomRole } from '../types';
|
|
2
2
|
import auditConfig from '../config';
|
|
3
3
|
export default class CustomRoles {
|
|
4
|
-
log: LogFn;
|
|
5
4
|
protected fix: boolean;
|
|
6
5
|
fileName: any;
|
|
7
6
|
config: ConfigType;
|
|
@@ -11,7 +10,7 @@ export default class CustomRoles {
|
|
|
11
10
|
missingFieldsInCustomRoles: CustomRole[];
|
|
12
11
|
customRolePath: string;
|
|
13
12
|
isBranchFixDone: boolean;
|
|
14
|
-
constructor({
|
|
13
|
+
constructor({ fix, config, moduleName }: ModuleConstructorParam & Pick<CtConstructorParam, 'ctSchema'>);
|
|
15
14
|
validateModules(moduleName: keyof typeof auditConfig.moduleConfig, moduleConfig: Record<string, unknown>): keyof typeof auditConfig.moduleConfig;
|
|
16
15
|
/**
|
|
17
16
|
* Check whether the given path for the custom role exists or not
|
|
@@ -7,9 +7,10 @@ const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
|
7
7
|
const messages_1 = require("../messages");
|
|
8
8
|
const lodash_2 = require("lodash");
|
|
9
9
|
class CustomRoles {
|
|
10
|
-
constructor({
|
|
11
|
-
|
|
10
|
+
constructor({ fix, config, moduleName }) {
|
|
11
|
+
var _a;
|
|
12
12
|
this.config = config;
|
|
13
|
+
cli_utilities_1.log.debug(`Initializing Custom Roles module`, this.config.auditContext);
|
|
13
14
|
this.fix = fix !== null && fix !== void 0 ? fix : false;
|
|
14
15
|
this.customRoleSchema = [];
|
|
15
16
|
this.moduleName = this.validateModules(moduleName, this.config.moduleConfig);
|
|
@@ -18,11 +19,19 @@ class CustomRoles {
|
|
|
18
19
|
this.missingFieldsInCustomRoles = [];
|
|
19
20
|
this.customRolePath = '';
|
|
20
21
|
this.isBranchFixDone = false;
|
|
22
|
+
cli_utilities_1.log.debug(`Starting ${this.moduleName} audit process`, this.config.auditContext);
|
|
23
|
+
cli_utilities_1.log.debug(`Data directory: ${this.folderPath}`, this.config.auditContext);
|
|
24
|
+
cli_utilities_1.log.debug(`Fix mode: ${this.fix}`, this.config.auditContext);
|
|
25
|
+
cli_utilities_1.log.debug(`Branch filter: ${((_a = this.config) === null || _a === void 0 ? void 0 : _a.branch) || 'none'}`, this.config.auditContext);
|
|
21
26
|
}
|
|
22
27
|
validateModules(moduleName, moduleConfig) {
|
|
28
|
+
cli_utilities_1.log.debug(`Validating module: ${moduleName}`, this.config.auditContext);
|
|
29
|
+
cli_utilities_1.log.debug(`Available modules in config: ${Object.keys(moduleConfig).join(', ')}`, this.config.auditContext);
|
|
23
30
|
if (Object.keys(moduleConfig).includes(moduleName)) {
|
|
31
|
+
cli_utilities_1.log.debug(`Module ${moduleName} found in config, returning: ${moduleName}`, this.config.auditContext);
|
|
24
32
|
return moduleName;
|
|
25
33
|
}
|
|
34
|
+
cli_utilities_1.log.debug(`Module ${moduleName} not found in config, defaulting to: custom-roles`, this.config.auditContext);
|
|
26
35
|
return 'custom-roles';
|
|
27
36
|
}
|
|
28
37
|
/**
|
|
@@ -34,91 +43,162 @@ class CustomRoles {
|
|
|
34
43
|
async run() {
|
|
35
44
|
var _a, _b, _c, _d;
|
|
36
45
|
if (!(0, fs_1.existsSync)(this.folderPath)) {
|
|
37
|
-
|
|
38
|
-
|
|
46
|
+
cli_utilities_1.log.debug(`Skipping ${this.moduleName} audit - path does not exist`, this.config.auditContext);
|
|
47
|
+
cli_utilities_1.log.warn(`Skipping ${this.moduleName} audit`, this.config.auditContext);
|
|
48
|
+
cli_utilities_1.cliux.print((0, messages_1.$t)(messages_1.auditMsg.NOT_VALID_PATH, { path: this.folderPath }), { color: 'yellow' });
|
|
39
49
|
return {};
|
|
40
50
|
}
|
|
41
51
|
this.customRolePath = (0, path_1.join)(this.folderPath, this.fileName);
|
|
52
|
+
cli_utilities_1.log.debug(`Custom roles file path: ${this.customRolePath}`, this.config.auditContext);
|
|
42
53
|
this.customRoleSchema = (0, fs_1.existsSync)(this.customRolePath)
|
|
43
54
|
? (0, lodash_2.values)(JSON.parse((0, fs_1.readFileSync)(this.customRolePath, 'utf8')))
|
|
44
55
|
: [];
|
|
56
|
+
cli_utilities_1.log.debug(`Found ${this.customRoleSchema.length} custom roles to audit`, this.config.auditContext);
|
|
45
57
|
for (let index = 0; index < ((_a = this.customRoleSchema) === null || _a === void 0 ? void 0 : _a.length); index++) {
|
|
46
58
|
const customRole = this.customRoleSchema[index];
|
|
59
|
+
cli_utilities_1.log.debug(`Processing custom role: ${customRole.name} (${customRole.uid})`, this.config.auditContext);
|
|
47
60
|
let branchesToBeRemoved = [];
|
|
48
61
|
if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.branch) {
|
|
62
|
+
cli_utilities_1.log.debug(`Config branch : ${this.config.branch}`, this.config.auditContext);
|
|
63
|
+
cli_utilities_1.log.debug(`Checking branch rules for custom role: ${customRole.name}`, this.config.auditContext);
|
|
49
64
|
(_c = customRole === null || customRole === void 0 ? void 0 : customRole.rules) === null || _c === void 0 ? void 0 : _c.filter((rule) => {
|
|
50
|
-
var _a;
|
|
65
|
+
var _a, _b;
|
|
51
66
|
if (rule.module === 'branch') {
|
|
52
|
-
|
|
67
|
+
cli_utilities_1.log.debug(`Found branch rule with branches: ${((_a = rule === null || rule === void 0 ? void 0 : rule.branches) === null || _a === void 0 ? void 0 : _a.join(', ')) || 'none'}`, this.config.auditContext);
|
|
68
|
+
branchesToBeRemoved = ((_b = rule === null || rule === void 0 ? void 0 : rule.branches) === null || _b === void 0 ? void 0 : _b.filter((branch) => { var _a; return branch !== ((_a = this.config) === null || _a === void 0 ? void 0 : _a.branch); })) || [];
|
|
69
|
+
cli_utilities_1.log.debug(`Branches to be removed: ${branchesToBeRemoved.join(', ') || 'none'}`, this.config.auditContext);
|
|
53
70
|
}
|
|
54
71
|
});
|
|
55
72
|
}
|
|
73
|
+
else {
|
|
74
|
+
cli_utilities_1.log.debug(`No branch filter configured, skipping branch validation`, this.config.auditContext);
|
|
75
|
+
}
|
|
56
76
|
if (branchesToBeRemoved === null || branchesToBeRemoved === void 0 ? void 0 : branchesToBeRemoved.length) {
|
|
77
|
+
cli_utilities_1.log.debug(`Custom role ${customRole.name} has branches to be removed: ${branchesToBeRemoved.join(', ')}`, this.config.auditContext);
|
|
57
78
|
this.isBranchFixDone = true;
|
|
58
79
|
const tempCR = (0, lodash_1.cloneDeep)(customRole);
|
|
59
80
|
if ((customRole === null || customRole === void 0 ? void 0 : customRole.rules) && ((_d = this.config) === null || _d === void 0 ? void 0 : _d.branch)) {
|
|
81
|
+
cli_utilities_1.log.debug(`Applying branch fix to custom role: ${customRole.name}`, this.config.auditContext);
|
|
60
82
|
tempCR.rules.forEach((rule) => {
|
|
83
|
+
var _a;
|
|
61
84
|
if (rule.module === 'branch') {
|
|
85
|
+
cli_utilities_1.log.debug(`Updating branch rule branches from ${(_a = rule.branches) === null || _a === void 0 ? void 0 : _a.join(', ')} to ${branchesToBeRemoved.join(', ')}`, this.config.auditContext);
|
|
62
86
|
rule.branches = branchesToBeRemoved;
|
|
63
87
|
}
|
|
64
88
|
});
|
|
65
89
|
}
|
|
66
90
|
this.missingFieldsInCustomRoles.push(tempCR);
|
|
91
|
+
cli_utilities_1.log.debug(`Added custom role ${customRole.name} to missing fields list`, this.config.auditContext);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
cli_utilities_1.log.debug(`Custom role ${customRole.name} has no branch issues`, this.config.auditContext);
|
|
67
95
|
}
|
|
68
|
-
|
|
96
|
+
cli_utilities_1.log.info((0, messages_1.$t)(messages_1.auditMsg.SCAN_CR_SUCCESS_MSG, {
|
|
69
97
|
name: customRole.name,
|
|
70
98
|
uid: customRole.uid,
|
|
71
|
-
}),
|
|
99
|
+
}), this.config.auditContext);
|
|
72
100
|
}
|
|
101
|
+
cli_utilities_1.log.debug(`Found ${this.missingFieldsInCustomRoles.length} custom roles with issues`, this.config.auditContext);
|
|
102
|
+
cli_utilities_1.log.debug(`Branch fix done: ${this.isBranchFixDone}`, this.config.auditContext);
|
|
73
103
|
if (this.fix && (this.missingFieldsInCustomRoles.length || this.isBranchFixDone)) {
|
|
104
|
+
cli_utilities_1.log.debug('Fix mode enabled and issues found, applying fixes', this.config.auditContext);
|
|
74
105
|
await this.fixCustomRoleSchema();
|
|
75
106
|
this.missingFieldsInCustomRoles.forEach((cr) => (cr.fixStatus = 'Fixed'));
|
|
107
|
+
cli_utilities_1.log.debug(`Applied fixes to ${this.missingFieldsInCustomRoles.length} custom roles`, this.config.auditContext);
|
|
76
108
|
}
|
|
109
|
+
else {
|
|
110
|
+
cli_utilities_1.log.debug('No fixes needed or fix mode disabled', this.config.auditContext);
|
|
111
|
+
}
|
|
112
|
+
cli_utilities_1.log.debug(`${this.moduleName} audit completed. Found ${this.missingFieldsInCustomRoles.length} custom roles with issues`, this.config.auditContext);
|
|
77
113
|
return this.missingFieldsInCustomRoles;
|
|
78
114
|
}
|
|
79
115
|
async fixCustomRoleSchema() {
|
|
80
116
|
var _a;
|
|
117
|
+
cli_utilities_1.log.debug('Starting custom role schema fix process', this.config.auditContext);
|
|
81
118
|
const newCustomRoleSchema = (0, fs_1.existsSync)(this.customRolePath)
|
|
82
119
|
? JSON.parse((0, fs_1.readFileSync)(this.customRolePath, 'utf8'))
|
|
83
120
|
: {};
|
|
121
|
+
cli_utilities_1.log.debug(`Loaded ${Object.keys(newCustomRoleSchema).length} custom roles from file`, this.config.auditContext);
|
|
84
122
|
if (Object.keys(newCustomRoleSchema).length === 0 || !((_a = this.customRoleSchema) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
123
|
+
cli_utilities_1.log.debug('No custom roles to fix or empty schema, skipping fix process', this.config.auditContext);
|
|
85
124
|
return;
|
|
86
125
|
}
|
|
126
|
+
cli_utilities_1.log.debug(`Processing ${this.customRoleSchema.length} custom roles for branch fixes`, this.config.auditContext);
|
|
87
127
|
this.customRoleSchema.forEach((customRole) => {
|
|
88
128
|
var _a, _b, _c, _d;
|
|
89
|
-
|
|
129
|
+
cli_utilities_1.log.debug(`Fixing custom role: ${customRole.name} (${customRole.uid})`, this.config.auditContext);
|
|
130
|
+
if (!this.config.branch) {
|
|
131
|
+
cli_utilities_1.log.debug(`No branch configured, skipping fix for ${customRole.name}`, this.config.auditContext);
|
|
90
132
|
return;
|
|
133
|
+
}
|
|
134
|
+
cli_utilities_1.log.debug(`Looking for branch rules in custom role: ${customRole.name}`, this.config.auditContext);
|
|
91
135
|
const fixedBranches = (_b = (_a = customRole.rules) === null || _a === void 0 ? void 0 : _a.filter((rule) => { var _a; return rule.module === 'branch' && ((_a = rule.branches) === null || _a === void 0 ? void 0 : _a.length); })) === null || _b === void 0 ? void 0 : _b.reduce((acc, rule) => {
|
|
92
|
-
var _a;
|
|
93
|
-
|
|
136
|
+
var _a, _b;
|
|
137
|
+
cli_utilities_1.log.debug(`Processing branch rule with branches: ${(_a = rule.branches) === null || _a === void 0 ? void 0 : _a.join(', ')}`, this.config.auditContext);
|
|
138
|
+
const relevantBranches = ((_b = rule.branches) === null || _b === void 0 ? void 0 : _b.filter((branch) => {
|
|
94
139
|
if (branch !== this.config.branch) {
|
|
95
|
-
|
|
140
|
+
cli_utilities_1.log.debug(`Removing branch ${branch} from custom role ${customRole.name}`, this.config.auditContext);
|
|
141
|
+
cli_utilities_1.log.debug((0, messages_1.$t)(messages_1.commonMsg.CR_BRANCH_REMOVAL, {
|
|
96
142
|
uid: customRole.uid,
|
|
97
143
|
name: customRole.name,
|
|
98
144
|
branch,
|
|
99
|
-
}),
|
|
145
|
+
}), this.config.auditContext);
|
|
100
146
|
return false;
|
|
101
147
|
}
|
|
148
|
+
else {
|
|
149
|
+
cli_utilities_1.log.debug(`Keeping branch ${branch} for custom role ${customRole.name}`, this.config.auditContext);
|
|
150
|
+
}
|
|
102
151
|
return true;
|
|
103
152
|
})) || [];
|
|
153
|
+
cli_utilities_1.log.debug(`Relevant branches after filtering: ${relevantBranches.join(', ')}`, this.config.auditContext);
|
|
104
154
|
return [...acc, ...relevantBranches];
|
|
105
155
|
}, []);
|
|
156
|
+
cli_utilities_1.log.debug(`Fixed branches for ${customRole.name}: ${(fixedBranches === null || fixedBranches === void 0 ? void 0 : fixedBranches.join(', ')) || 'none'}`, this.config.auditContext);
|
|
106
157
|
if (fixedBranches === null || fixedBranches === void 0 ? void 0 : fixedBranches.length) {
|
|
158
|
+
cli_utilities_1.log.debug(`Applying branch fix to custom role ${customRole.name}`, this.config.auditContext);
|
|
107
159
|
(_d = (_c = newCustomRoleSchema[customRole.uid].rules) === null || _c === void 0 ? void 0 : _c.filter((rule) => rule.module === 'branch')) === null || _d === void 0 ? void 0 : _d.forEach((rule) => {
|
|
160
|
+
var _a;
|
|
161
|
+
cli_utilities_1.log.debug(`Updating branch rule from ${(_a = rule.branches) === null || _a === void 0 ? void 0 : _a.join(', ')} to ${fixedBranches.join(', ')}`, this.config.auditContext);
|
|
108
162
|
rule.branches = fixedBranches;
|
|
109
163
|
});
|
|
110
164
|
}
|
|
165
|
+
else {
|
|
166
|
+
cli_utilities_1.log.debug(`No branch fixes needed for custom role ${customRole.name}`, this.config.auditContext);
|
|
167
|
+
}
|
|
111
168
|
});
|
|
169
|
+
cli_utilities_1.log.debug('Writing fixed custom role schema to file', this.config.auditContext);
|
|
112
170
|
await this.writeFixContent(newCustomRoleSchema);
|
|
171
|
+
cli_utilities_1.log.debug('Custom role schema fix process completed', this.config.auditContext);
|
|
113
172
|
}
|
|
114
173
|
async writeFixContent(newCustomRoleSchema) {
|
|
115
174
|
var _a;
|
|
116
|
-
|
|
117
|
-
|
|
175
|
+
cli_utilities_1.log.debug('Starting writeFixContent process for custom roles', this.config.auditContext);
|
|
176
|
+
const filePath = (0, path_1.join)(this.folderPath, this.config.moduleConfig[this.moduleName].fileName);
|
|
177
|
+
cli_utilities_1.log.debug(`Target file path: ${filePath}`, this.config.auditContext);
|
|
178
|
+
cli_utilities_1.log.debug(`Custom roles to write: ${Object.keys(newCustomRoleSchema).length}`, this.config.auditContext);
|
|
179
|
+
if (this.fix) {
|
|
180
|
+
cli_utilities_1.log.debug('Fix mode enabled, checking write permissions', this.config.auditContext);
|
|
181
|
+
const skipConfirm = this.config.flags['copy-dir'] ||
|
|
118
182
|
((_a = this.config.flags['external-config']) === null || _a === void 0 ? void 0 : _a.skipConfirm) ||
|
|
119
|
-
this.config.flags.yes
|
|
120
|
-
|
|
121
|
-
|
|
183
|
+
this.config.flags.yes;
|
|
184
|
+
if (skipConfirm) {
|
|
185
|
+
cli_utilities_1.log.debug('Skipping confirmation due to copy-dir, external-config, or yes flags', this.config.auditContext);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
cli_utilities_1.log.debug('Asking user for confirmation to write fix content', this.config.auditContext);
|
|
189
|
+
}
|
|
190
|
+
const canWrite = skipConfirm || (await cli_utilities_1.cliux.confirm(messages_1.commonMsg.FIX_CONFIRMATION));
|
|
191
|
+
if (canWrite) {
|
|
192
|
+
cli_utilities_1.log.debug(`Writing fixed custom roles to: ${filePath}`, this.config.auditContext);
|
|
193
|
+
(0, fs_1.writeFileSync)(filePath, JSON.stringify(newCustomRoleSchema));
|
|
194
|
+
cli_utilities_1.log.debug(`Successfully wrote ${Object.keys(newCustomRoleSchema).length} custom roles to file`, this.config.auditContext);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
cli_utilities_1.log.debug('User declined to write fix content', this.config.auditContext);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
cli_utilities_1.log.debug('Skipping writeFixContent - not in fix mode', this.config.auditContext);
|
|
122
202
|
}
|
|
123
203
|
}
|
|
124
204
|
}
|
package/lib/modules/entries.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import auditConfig from '../config';
|
|
2
|
-
import {
|
|
2
|
+
import { Locale, ConfigType, EntryStruct, EntryFieldType, ModularBlockType, ContentTypeStruct, CtConstructorParam, GroupFieldDataType, GlobalFieldDataType, JsonRTEFieldDataType, ContentTypeSchemaType, ModularBlocksDataType, ModuleConstructorParam, ReferenceFieldDataType, EntryRefErrorReturnType, EntryGroupFieldDataType, EntryGlobalFieldDataType, EntryJsonRTEFieldDataType, EntryModularBlocksDataType, EntryReferenceFieldDataType, ExtensionOrAppFieldDataType, EntryExtensionOrAppFieldDataType, SelectFeildStruct } from '../types';
|
|
3
3
|
export default class Entries {
|
|
4
|
-
log: LogFn;
|
|
5
4
|
protected fix: boolean;
|
|
6
5
|
fileName: string;
|
|
7
6
|
locales: Locale[];
|
|
@@ -22,28 +21,14 @@ export default class Entries {
|
|
|
22
21
|
environments: string[];
|
|
23
22
|
entryMetaData: Record<string, any>[];
|
|
24
23
|
moduleName: keyof typeof auditConfig.moduleConfig;
|
|
25
|
-
constructor({
|
|
24
|
+
constructor({ fix, config, moduleName, ctSchema, gfSchema }: ModuleConstructorParam & CtConstructorParam);
|
|
26
25
|
validateModules(moduleName: keyof typeof auditConfig.moduleConfig, moduleConfig: Record<string, unknown>): keyof typeof auditConfig.moduleConfig;
|
|
27
26
|
/**
|
|
28
27
|
* The `run` function checks if a folder path exists, sets the schema based on the module name,
|
|
29
28
|
* iterates over the schema and looks for references, and returns a list of missing references.
|
|
30
29
|
* @returns the `missingRefs` object.
|
|
31
30
|
*/
|
|
32
|
-
run(): Promise<{
|
|
33
|
-
missingEntryRefs?: undefined;
|
|
34
|
-
missingSelectFeild?: undefined;
|
|
35
|
-
missingMandatoryFields?: undefined;
|
|
36
|
-
missingTitleFields?: undefined;
|
|
37
|
-
missingEnvLocale?: undefined;
|
|
38
|
-
missingMultipleFields?: undefined;
|
|
39
|
-
} | {
|
|
40
|
-
missingEntryRefs: Record<string, any>;
|
|
41
|
-
missingSelectFeild: Record<string, any>;
|
|
42
|
-
missingMandatoryFields: Record<string, any>;
|
|
43
|
-
missingTitleFields: Record<string, any>;
|
|
44
|
-
missingEnvLocale: Record<string, any>;
|
|
45
|
-
missingMultipleFields: Record<string, any>;
|
|
46
|
-
}>;
|
|
31
|
+
run(): Promise<{}>;
|
|
47
32
|
/**
|
|
48
33
|
* The function removes any properties from the `missingRefs` object that have an empty array value.
|
|
49
34
|
*/
|