@contentstack/cli-audit 1.14.1 → 1.15.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 +9 -9
- 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 +456 -61
- 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, ContentTypeStruct, CtConstructorParam, ModuleConstructorParam, Extension } from '../types';
|
|
2
2
|
import auditConfig from '../config';
|
|
3
3
|
export default class Extensions {
|
|
4
|
-
log: LogFn;
|
|
5
4
|
protected fix: boolean;
|
|
6
5
|
fileName: any;
|
|
7
6
|
config: ConfigType;
|
|
@@ -13,7 +12,7 @@ export default class Extensions {
|
|
|
13
12
|
missingCtInExtensions: Extension[];
|
|
14
13
|
missingCts: Set<string>;
|
|
15
14
|
extensionsPath: string;
|
|
16
|
-
constructor({
|
|
15
|
+
constructor({ fix, config, moduleName, ctSchema, }: ModuleConstructorParam & Pick<CtConstructorParam, 'ctSchema'>);
|
|
17
16
|
validateModules(moduleName: keyof typeof auditConfig.moduleConfig, moduleConfig: Record<string, unknown>): keyof typeof auditConfig.moduleConfig;
|
|
18
17
|
run(): Promise<{}>;
|
|
19
18
|
fixExtensionsScope(missingCtInExtensions: Extension[]): Promise<void>;
|
|
@@ -8,88 +8,152 @@ const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
|
8
8
|
const messages_1 = require("../messages");
|
|
9
9
|
const lodash_2 = require("lodash");
|
|
10
10
|
class Extensions {
|
|
11
|
-
constructor({
|
|
12
|
-
this.log = log;
|
|
11
|
+
constructor({ fix, config, moduleName, ctSchema, }) {
|
|
13
12
|
this.config = config;
|
|
14
13
|
this.fix = fix !== null && fix !== void 0 ? fix : false;
|
|
15
14
|
this.ctSchema = ctSchema;
|
|
16
15
|
this.extensionsSchema = [];
|
|
16
|
+
cli_utilities_1.log.debug(`Initializing Extensions module`, this.config.auditContext);
|
|
17
|
+
cli_utilities_1.log.debug(`Fix mode: ${this.fix}`, this.config.auditContext);
|
|
18
|
+
cli_utilities_1.log.debug(`Content types count: ${ctSchema.length}`, this.config.auditContext);
|
|
19
|
+
cli_utilities_1.log.debug(`Module name: ${moduleName}`, this.config.auditContext);
|
|
17
20
|
this.moduleName = this.validateModules(moduleName, this.config.moduleConfig);
|
|
18
21
|
this.fileName = config.moduleConfig[this.moduleName].fileName;
|
|
22
|
+
cli_utilities_1.log.debug(`File name: ${this.fileName}`, this.config.auditContext);
|
|
19
23
|
this.folderPath = (0, path_1.resolve)((0, cli_utilities_1.sanitizePath)(config.basePath), (0, cli_utilities_1.sanitizePath)(config.moduleConfig[this.moduleName].dirName));
|
|
24
|
+
cli_utilities_1.log.debug(`Folder path: ${this.folderPath}`, this.config.auditContext);
|
|
20
25
|
this.ctUidSet = new Set(['$all']);
|
|
21
26
|
this.missingCtInExtensions = [];
|
|
22
27
|
this.missingCts = new Set();
|
|
23
28
|
this.extensionsPath = '';
|
|
29
|
+
cli_utilities_1.log.debug(`Extensions module initialization completed`, this.config.auditContext);
|
|
24
30
|
}
|
|
25
31
|
validateModules(moduleName, moduleConfig) {
|
|
32
|
+
cli_utilities_1.log.debug(`Validating module: ${moduleName}`, this.config.auditContext);
|
|
33
|
+
cli_utilities_1.log.debug(`Available modules: ${Object.keys(moduleConfig).join(', ')}`, this.config.auditContext);
|
|
26
34
|
if (Object.keys(moduleConfig).includes(moduleName)) {
|
|
35
|
+
cli_utilities_1.log.debug(`Module ${moduleName} is valid`, this.config.auditContext);
|
|
27
36
|
return moduleName;
|
|
28
37
|
}
|
|
38
|
+
cli_utilities_1.log.debug(`Module ${moduleName} not found, defaulting to 'extensions'`, this.config.auditContext);
|
|
29
39
|
return 'extensions';
|
|
30
40
|
}
|
|
31
41
|
async run() {
|
|
32
|
-
var _a;
|
|
42
|
+
var _a, _b;
|
|
43
|
+
cli_utilities_1.log.debug(`Starting ${this.moduleName} audit process`, this.config.auditContext);
|
|
44
|
+
cli_utilities_1.log.debug(`Extensions folder path: ${this.folderPath}`, this.config.auditContext);
|
|
45
|
+
cli_utilities_1.log.debug(`Fix mode: ${this.fix}`, this.config.auditContext);
|
|
33
46
|
if (!(0, fs_1.existsSync)(this.folderPath)) {
|
|
34
|
-
|
|
35
|
-
|
|
47
|
+
cli_utilities_1.log.debug(`Skipping ${this.moduleName} audit - path does not exist`, this.config.auditContext);
|
|
48
|
+
cli_utilities_1.log.warn(`Skipping ${this.moduleName} audit`, this.config.auditContext);
|
|
49
|
+
cli_utilities_1.cliux.print((0, messages_1.$t)(messages_1.auditMsg.NOT_VALID_PATH, { path: this.folderPath }), { color: 'yellow' });
|
|
36
50
|
return {};
|
|
37
51
|
}
|
|
38
52
|
this.extensionsPath = path_1.default.join(this.folderPath, this.fileName);
|
|
53
|
+
cli_utilities_1.log.debug(`Extensions file path: ${this.extensionsPath}`, this.config.auditContext);
|
|
54
|
+
cli_utilities_1.log.debug(`Loading extensions schema from file`, this.config.auditContext);
|
|
39
55
|
this.extensionsSchema = (0, fs_1.existsSync)(this.extensionsPath)
|
|
40
56
|
? (0, lodash_2.values)(JSON.parse((0, fs_1.readFileSync)(this.extensionsPath, 'utf-8')))
|
|
41
57
|
: [];
|
|
58
|
+
cli_utilities_1.log.debug(`Loaded ${this.extensionsSchema.length} extensions`, this.config.auditContext);
|
|
59
|
+
cli_utilities_1.log.debug(`Building content type UID set from ${this.ctSchema.length} content types`, this.config.auditContext);
|
|
42
60
|
this.ctSchema.map((ct) => this.ctUidSet.add(ct.uid));
|
|
61
|
+
cli_utilities_1.log.debug(`Content type UID set contains: ${Array.from(this.ctUidSet).join(', ')}`, this.config.auditContext);
|
|
62
|
+
cli_utilities_1.log.debug(`Processing ${this.extensionsSchema.length} extensions`, this.config.auditContext);
|
|
43
63
|
for (const ext of this.extensionsSchema) {
|
|
44
64
|
const { title, uid, scope } = ext;
|
|
65
|
+
cli_utilities_1.log.debug(`Processing extension: ${title} (${uid})`, this.config.auditContext);
|
|
66
|
+
cli_utilities_1.log.debug(`Extension scope content types: ${((_a = scope === null || scope === void 0 ? void 0 : scope.content_types) === null || _a === void 0 ? void 0 : _a.join(', ')) || 'none'}`, this.config.auditContext);
|
|
45
67
|
const ctNotPresent = scope === null || scope === void 0 ? void 0 : scope.content_types.filter((ct) => !this.ctUidSet.has(ct));
|
|
68
|
+
cli_utilities_1.log.debug(`Missing content types in extension: ${(ctNotPresent === null || ctNotPresent === void 0 ? void 0 : ctNotPresent.join(', ')) || 'none'}`, this.config.auditContext);
|
|
46
69
|
if ((ctNotPresent === null || ctNotPresent === void 0 ? void 0 : ctNotPresent.length) && ext.scope) {
|
|
70
|
+
cli_utilities_1.log.debug(`Extension ${title} has ${ctNotPresent.length} missing content types`, this.config.auditContext);
|
|
47
71
|
ext.content_types = ctNotPresent;
|
|
48
|
-
ctNotPresent.forEach((ct) => {
|
|
49
|
-
|
|
72
|
+
ctNotPresent.forEach((ct) => {
|
|
73
|
+
var _a;
|
|
74
|
+
cli_utilities_1.log.debug(`Adding missing content type: ${ct} to the Audit report.`, this.config.auditContext);
|
|
75
|
+
(_a = this.missingCts) === null || _a === void 0 ? void 0 : _a.add(ct);
|
|
76
|
+
});
|
|
77
|
+
(_b = this.missingCtInExtensions) === null || _b === void 0 ? void 0 : _b.push((0, lodash_1.cloneDeep)(ext));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
cli_utilities_1.log.debug(`Extension ${title} has no missing content types`, this.config.auditContext);
|
|
50
81
|
}
|
|
51
|
-
|
|
82
|
+
cli_utilities_1.log.info((0, messages_1.$t)(messages_1.auditMsg.SCAN_EXT_SUCCESS_MSG, {
|
|
52
83
|
title,
|
|
53
84
|
module: this.config.moduleConfig[this.moduleName].name,
|
|
54
85
|
uid,
|
|
55
|
-
}),
|
|
86
|
+
}), this.config.auditContext);
|
|
56
87
|
}
|
|
88
|
+
cli_utilities_1.log.debug(`Extensions audit completed. Found ${this.missingCtInExtensions.length} extensions with missing content types`, this.config.auditContext);
|
|
89
|
+
cli_utilities_1.log.debug(`Total missing content types: ${this.missingCts.size}`, this.config.auditContext);
|
|
57
90
|
if (this.fix && this.missingCtInExtensions.length) {
|
|
91
|
+
cli_utilities_1.log.debug(`Fix mode enabled, fixing ${this.missingCtInExtensions.length} extensions`, this.config.auditContext);
|
|
58
92
|
await this.fixExtensionsScope((0, lodash_1.cloneDeep)(this.missingCtInExtensions));
|
|
59
|
-
this.missingCtInExtensions.forEach((ext) =>
|
|
93
|
+
this.missingCtInExtensions.forEach((ext) => {
|
|
94
|
+
cli_utilities_1.log.debug(`Marking extension ${ext.title} as fixed`, this.config.auditContext);
|
|
95
|
+
ext.fixStatus = 'Fixed';
|
|
96
|
+
});
|
|
97
|
+
cli_utilities_1.log.debug(`Extensions fix completed`, this.config.auditContext);
|
|
60
98
|
return this.missingCtInExtensions;
|
|
61
99
|
}
|
|
100
|
+
cli_utilities_1.log.debug(`Extensions audit completed without fixes`, this.config.auditContext);
|
|
62
101
|
return this.missingCtInExtensions;
|
|
63
102
|
}
|
|
64
103
|
async fixExtensionsScope(missingCtInExtensions) {
|
|
65
|
-
var _a, _b;
|
|
104
|
+
var _a, _b, _c, _d;
|
|
105
|
+
cli_utilities_1.log.debug(`Starting extensions scope fix for ${missingCtInExtensions.length} extensions`, this.config.auditContext);
|
|
106
|
+
cli_utilities_1.log.debug(`Loading current extensions schema from: ${this.extensionsPath}`, this.config.auditContext);
|
|
66
107
|
let newExtensionSchema = (0, fs_1.existsSync)(this.extensionsPath)
|
|
67
108
|
? JSON.parse((0, fs_1.readFileSync)(this.extensionsPath, 'utf8'))
|
|
68
109
|
: {};
|
|
110
|
+
cli_utilities_1.log.debug(`Loaded ${Object.keys(newExtensionSchema).length} existing extensions`, this.config.auditContext);
|
|
69
111
|
for (const ext of missingCtInExtensions) {
|
|
70
112
|
const { uid, title } = ext;
|
|
71
|
-
|
|
72
|
-
|
|
113
|
+
cli_utilities_1.log.debug(`Fixing extension: ${title} (${uid})`, this.config.auditContext);
|
|
114
|
+
cli_utilities_1.log.debug(`Extension scope content types: ${((_b = (_a = ext === null || ext === void 0 ? void 0 : ext.scope) === null || _a === void 0 ? void 0 : _a.content_types) === null || _b === void 0 ? void 0 : _b.join(', ')) || 'none'}`, this.config.auditContext);
|
|
115
|
+
const fixedCts = (_c = ext === null || ext === void 0 ? void 0 : ext.scope) === null || _c === void 0 ? void 0 : _c.content_types.filter((ct) => !this.missingCts.has(ct));
|
|
116
|
+
cli_utilities_1.log.debug(`Valid content types after filtering: ${(fixedCts === null || fixedCts === void 0 ? void 0 : fixedCts.join(', ')) || 'none'}`, this.config.auditContext);
|
|
117
|
+
if ((fixedCts === null || fixedCts === void 0 ? void 0 : fixedCts.length) && ((_d = newExtensionSchema[uid]) === null || _d === void 0 ? void 0 : _d.scope)) {
|
|
118
|
+
cli_utilities_1.log.debug(`Updating extension ${title} scope with ${fixedCts.length} valid content types`, this.config.auditContext);
|
|
73
119
|
newExtensionSchema[uid].scope.content_types = fixedCts;
|
|
74
120
|
}
|
|
75
121
|
else {
|
|
76
|
-
|
|
122
|
+
cli_utilities_1.log.debug(`Extension ${title} has no valid content types or scope not found`, this.config.auditContext);
|
|
123
|
+
cli_utilities_1.cliux.print((0, messages_1.$t)(messages_1.commonMsg.EXTENSION_FIX_WARN, { title: title, uid }), { color: 'yellow' });
|
|
77
124
|
const shouldDelete = this.config.flags.yes || (await cli_utilities_1.cliux.confirm(messages_1.commonMsg.EXTENSION_FIX_CONFIRMATION));
|
|
78
125
|
if (shouldDelete) {
|
|
126
|
+
cli_utilities_1.log.debug(`Deleting extension: ${title} (${uid})`, this.config.auditContext);
|
|
79
127
|
delete newExtensionSchema[uid];
|
|
80
128
|
}
|
|
129
|
+
else {
|
|
130
|
+
cli_utilities_1.log.debug(`Keeping extension: ${title} (${uid})`, this.config.auditContext);
|
|
131
|
+
}
|
|
81
132
|
}
|
|
82
133
|
}
|
|
134
|
+
cli_utilities_1.log.debug(`Extensions scope fix completed, writing updated schema`, this.config.auditContext);
|
|
83
135
|
await this.writeFixContent(newExtensionSchema);
|
|
84
136
|
}
|
|
85
137
|
async writeFixContent(fixedExtensions) {
|
|
86
|
-
var _a;
|
|
138
|
+
var _a, _b;
|
|
139
|
+
cli_utilities_1.log.debug(`Writing fix content for ${Object.keys(fixedExtensions).length} extensions`, this.config.auditContext);
|
|
140
|
+
cli_utilities_1.log.debug(`Fix mode: ${this.fix}`, this.config.auditContext);
|
|
141
|
+
cli_utilities_1.log.debug(`Copy directory flag: ${this.config.flags['copy-dir']}`, this.config.auditContext);
|
|
142
|
+
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);
|
|
143
|
+
cli_utilities_1.log.debug(`Yes flag: ${this.config.flags.yes}`, this.config.auditContext);
|
|
87
144
|
if (this.fix &&
|
|
88
145
|
(this.config.flags['copy-dir'] ||
|
|
89
|
-
((
|
|
146
|
+
((_b = this.config.flags['external-config']) === null || _b === void 0 ? void 0 : _b.skipConfirm) ||
|
|
90
147
|
this.config.flags.yes ||
|
|
91
148
|
(await cli_utilities_1.cliux.confirm(messages_1.commonMsg.FIX_CONFIRMATION)))) {
|
|
92
|
-
|
|
149
|
+
const outputPath = (0, path_1.join)(this.folderPath, this.config.moduleConfig[this.moduleName].fileName);
|
|
150
|
+
cli_utilities_1.log.debug(`Writing fixed extensions to: ${outputPath}`, this.config.auditContext);
|
|
151
|
+
cli_utilities_1.log.debug(`Extensions to write: ${Object.keys(fixedExtensions).join(', ')}`, this.config.auditContext);
|
|
152
|
+
(0, fs_1.writeFileSync)(outputPath, JSON.stringify(fixedExtensions));
|
|
153
|
+
cli_utilities_1.log.debug(`Successfully wrote fixed extensions to file`, this.config.auditContext);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
cli_utilities_1.log.debug(`Skipping file write - fix mode disabled or user declined confirmation`, this.config.auditContext);
|
|
93
157
|
}
|
|
94
158
|
}
|
|
95
159
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Locale } from '@contentstack/cli-utilities';
|
|
2
|
-
import {
|
|
2
|
+
import { ConfigType, ModularBlockType, ContentTypeStruct, GroupFieldDataType, CtConstructorParam, GlobalFieldDataType, ModularBlocksDataType, ModuleConstructorParam, EntryStruct } from '../types';
|
|
3
3
|
import auditConfig from '../config';
|
|
4
4
|
export default class FieldRule {
|
|
5
|
-
log: LogFn;
|
|
6
5
|
protected fix: boolean;
|
|
7
6
|
fileName: string;
|
|
8
7
|
config: ConfigType;
|
|
@@ -24,7 +23,7 @@ export default class FieldRule {
|
|
|
24
23
|
protected missingEnvLocale: Record<string, any>;
|
|
25
24
|
entryMetaData: Record<string, any>[];
|
|
26
25
|
action: string[];
|
|
27
|
-
constructor({
|
|
26
|
+
constructor({ fix, config, moduleName, ctSchema, gfSchema }: ModuleConstructorParam & CtConstructorParam);
|
|
28
27
|
validateModules(moduleName: keyof typeof auditConfig.moduleConfig, moduleConfig: Record<string, unknown>): keyof typeof auditConfig.moduleConfig;
|
|
29
28
|
/**
|
|
30
29
|
* The `run` function checks if a folder path exists, sets the schema based on the module name,
|