@contentstack/cli-audit 1.17.0 → 2.0.0-beta

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.
Files changed (38) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +19 -23
  3. package/lib/audit-base-command.d.ts +4 -1
  4. package/lib/audit-base-command.js +85 -54
  5. package/lib/config/index.d.ts +0 -5
  6. package/lib/config/index.js +9 -16
  7. package/lib/messages/index.d.ts +0 -1
  8. package/lib/messages/index.js +1 -2
  9. package/lib/modules/assets.d.ts +6 -4
  10. package/lib/modules/assets.js +51 -30
  11. package/lib/modules/base-class.d.ts +24 -0
  12. package/lib/modules/base-class.js +54 -0
  13. package/lib/modules/content-types.d.ts +6 -4
  14. package/lib/modules/content-types.js +62 -40
  15. package/lib/modules/custom-roles.d.ts +4 -4
  16. package/lib/modules/custom-roles.js +82 -61
  17. package/lib/modules/entries.d.ts +5 -4
  18. package/lib/modules/entries.js +190 -168
  19. package/lib/modules/extensions.d.ts +4 -4
  20. package/lib/modules/extensions.js +78 -58
  21. package/lib/modules/field_rules.d.ts +4 -4
  22. package/lib/modules/field_rules.js +69 -52
  23. package/lib/modules/global-fields.d.ts +3 -1
  24. package/lib/modules/global-fields.js +4 -2
  25. package/lib/modules/index.d.ts +2 -2
  26. package/lib/modules/index.js +3 -3
  27. package/lib/modules/modulesData.js +8 -17
  28. package/lib/modules/workflows.d.ts +4 -4
  29. package/lib/modules/workflows.js +85 -68
  30. package/lib/types/content-types.d.ts +1 -2
  31. package/lib/types/content-types.js +0 -1
  32. package/lib/types/context.d.ts +5 -0
  33. package/oclif.manifest.json +3 -5
  34. package/package.json +4 -4
  35. package/lib/modules/composable-studio.d.ts +0 -40
  36. package/lib/modules/composable-studio.js +0 -307
  37. package/lib/types/composable-studio.d.ts +0 -25
  38. package/lib/types/composable-studio.js +0 -2
@@ -10,10 +10,12 @@ const cli_utilities_1 = require("@contentstack/cli-utilities");
10
10
  const fs_1 = require("fs");
11
11
  const content_types_1 = tslib_1.__importDefault(require("./content-types"));
12
12
  const messages_1 = require("../messages");
13
+ const base_class_1 = tslib_1.__importDefault(require("./base-class"));
13
14
  const global_fields_1 = tslib_1.__importDefault(require("./global-fields"));
14
15
  const lodash_1 = require("lodash");
15
- class Entries {
16
+ class Entries extends base_class_1.default {
16
17
  constructor({ fix, config, moduleName, ctSchema, gfSchema }) {
18
+ super({ config });
17
19
  this.extensions = [];
18
20
  this.missingRefs = {};
19
21
  this.missingSelectFeild = {};
@@ -24,7 +26,6 @@ class Entries {
24
26
  this.environments = [];
25
27
  this.entryMetaData = [];
26
28
  this.moduleName = 'entries';
27
- this.config = config;
28
29
  cli_utilities_1.log.debug(`Initializing Entries module`, this.config.auditContext);
29
30
  this.fix = fix !== null && fix !== void 0 ? fix : false;
30
31
  this.ctSchema = ctSchema;
@@ -49,190 +50,211 @@ class Entries {
49
50
  /**
50
51
  * The `run` function checks if a folder path exists, sets the schema based on the module name,
51
52
  * iterates over the schema and looks for references, and returns a list of missing references.
53
+ * @param totalCount - Total number of entries to process (for progress tracking)
52
54
  * @returns the `missingRefs` object.
53
55
  */
54
- async run() {
56
+ async run(totalCount) {
55
57
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
56
- if (!(0, fs_1.existsSync)(this.folderPath)) {
57
- cli_utilities_1.log.debug(`Skipping ${this.moduleName} audit - path does not exist`, this.config.auditContext);
58
- cli_utilities_1.log.warn(`Skipping ${this.moduleName} audit`, this.config.auditContext);
59
- cli_utilities_1.cliux.print((0, messages_1.$t)(messages_1.auditMsg.NOT_VALID_PATH, { path: this.folderPath }), { color: 'yellow' });
60
- return {};
61
- }
62
- cli_utilities_1.log.debug(`Found ${((_a = this.ctSchema) === null || _a === void 0 ? void 0 : _a.length) || 0} content types to audit`, this.config.auditContext);
63
- cli_utilities_1.log.debug(`Found ${((_b = this.locales) === null || _b === void 0 ? void 0 : _b.length) || 0} locales to process`, this.config.auditContext);
64
- cli_utilities_1.log.debug('Preparing entry metadata', this.config.auditContext);
65
- await this.prepareEntryMetaData();
66
- cli_utilities_1.log.debug(`Entry metadata prepared: ${this.entryMetaData.length} entries found`, this.config.auditContext);
67
- cli_utilities_1.log.debug('Fixing prerequisite data', this.config.auditContext);
68
- await this.fixPrerequisiteData();
69
- cli_utilities_1.log.debug('Prerequisite data fix completed', this.config.auditContext);
70
- cli_utilities_1.log.debug(`Processing ${this.locales.length} locales and ${this.ctSchema.length} content types`, this.config.auditContext);
71
- for (const { code } of this.locales) {
72
- cli_utilities_1.log.debug(`Processing locale: ${code}`, this.config.auditContext);
73
- for (const ctSchema of this.ctSchema) {
74
- cli_utilities_1.log.debug(`Processing content type: ${ctSchema.uid} in locale ${code}`, this.config.auditContext);
75
- const basePath = (0, path_1.join)(this.folderPath, ctSchema.uid, code);
76
- cli_utilities_1.log.debug(`Base path for entries: ${basePath}`, this.config.auditContext);
77
- const fsUtility = new cli_utilities_1.FsUtility({ basePath, indexFileName: 'index.json', createDirIfNotExist: false });
78
- const indexer = fsUtility.indexFileContent;
79
- cli_utilities_1.log.debug(`Found ${Object.keys(indexer).length} entry files to process`, this.config.auditContext);
80
- for (const fileIndex in indexer) {
81
- cli_utilities_1.log.debug(`Processing entry file: ${indexer[fileIndex]}`, this.config.auditContext);
82
- const entries = (await fsUtility.readChunkFiles.next());
83
- this.entries = entries;
84
- cli_utilities_1.log.debug(`Loaded ${Object.keys(entries).length} entries from file`, this.config.auditContext);
85
- for (const entryUid in this.entries) {
86
- const entry = this.entries[entryUid];
87
- const { uid, title } = entry;
88
- this.currentUid = uid;
89
- this.currentTitle = title;
90
- if (this.currentTitle) {
91
- this.currentTitle = this.removeEmojiAndImages(this.currentTitle);
92
- }
93
- cli_utilities_1.log.debug(`Processing entry - title:${this.currentTitle} with uid:(${uid})`, this.config.auditContext);
94
- if (!this.missingRefs[this.currentUid]) {
95
- this.missingRefs[this.currentUid] = [];
96
- }
97
- if (!this.missingSelectFeild[this.currentUid]) {
98
- this.missingSelectFeild[this.currentUid] = [];
99
- }
100
- if (!this.missingMandatoryFields[this.currentUid]) {
101
- this.missingMandatoryFields[this.currentUid] = [];
102
- }
103
- if (this.fix) {
104
- cli_utilities_1.log.debug(`Removing missing keys from entry ${uid}`, this.config.auditContext);
105
- this.removeMissingKeysOnEntry(ctSchema.schema, this.entries[entryUid]);
106
- }
107
- cli_utilities_1.log.debug(`Looking for references in entry ${uid}`, this.config.auditContext);
108
- this.lookForReference([{ locale: code, uid, name: this.removeEmojiAndImages(this.currentTitle) }], ctSchema, this.entries[entryUid]);
109
- if ((_c = this.missingRefs[this.currentUid]) === null || _c === void 0 ? void 0 : _c.length) {
110
- cli_utilities_1.log.debug(`Found ${this.missingRefs[this.currentUid].length} missing references for entry ${uid}`, this.config.auditContext);
111
- this.missingRefs[this.currentUid].forEach((entry) => {
112
- entry.ct = ctSchema.uid;
113
- entry.locale = code;
114
- });
115
- }
116
- if ((_d = this.missingSelectFeild[this.currentUid]) === null || _d === void 0 ? void 0 : _d.length) {
117
- cli_utilities_1.log.debug(`Found ${this.missingSelectFeild[this.currentUid].length} missing select fields for entry ${uid}`, this.config.auditContext);
118
- this.missingSelectFeild[this.currentUid].forEach((entry) => {
119
- entry.ct = ctSchema.uid;
120
- entry.locale = code;
121
- });
122
- }
123
- if ((_e = this.missingMandatoryFields[this.currentUid]) === null || _e === void 0 ? void 0 : _e.length) {
124
- cli_utilities_1.log.debug(`Found ${this.missingMandatoryFields[this.currentUid].length} missing mandatory fields for entry ${uid}`, this.config.auditContext);
125
- this.missingMandatoryFields[this.currentUid].forEach((entry) => {
126
- entry.ct = ctSchema.uid;
127
- entry.locale = code;
128
- });
129
- }
130
- const fields = this.missingMandatoryFields[uid];
131
- const isPublished = ((_f = entry.publish_details) === null || _f === void 0 ? void 0 : _f.length) > 0;
132
- cli_utilities_1.log.debug(`Entry ${uid} published status: ${isPublished}, missing mandatory fields: ${(fields === null || fields === void 0 ? void 0 : fields.length) || 0}`, this.config.auditContext);
133
- if ((this.fix && fields.length && isPublished) || (!this.fix && fields)) {
134
- const fixStatus = this.fix ? 'Fixed' : '';
135
- cli_utilities_1.log.debug(`Applying fix status: ${fixStatus} to ${fields.length} fields`, this.config.auditContext);
136
- fields === null || fields === void 0 ? void 0 : fields.forEach((field, index) => {
137
- cli_utilities_1.log.debug(`Processing field ${index + 1}/${fields.length}`, this.config.auditContext);
138
- field.isPublished = isPublished;
58
+ try {
59
+ if (!(0, fs_1.existsSync)(this.folderPath)) {
60
+ cli_utilities_1.log.debug(`Skipping ${this.moduleName} audit - path does not exist`, this.config.auditContext);
61
+ cli_utilities_1.log.warn(`Skipping ${this.moduleName} audit`, this.config.auditContext);
62
+ cli_utilities_1.cliux.print((0, messages_1.$t)(messages_1.auditMsg.NOT_VALID_PATH, { path: this.folderPath }), { color: 'yellow' });
63
+ return {};
64
+ }
65
+ cli_utilities_1.log.debug(`Found ${((_a = this.ctSchema) === null || _a === void 0 ? void 0 : _a.length) || 0} content types to audit`, this.config.auditContext);
66
+ cli_utilities_1.log.debug(`Found ${((_b = this.locales) === null || _b === void 0 ? void 0 : _b.length) || 0} locales to process`, this.config.auditContext);
67
+ // Prepare entry metadata with loading spinner
68
+ await this.withLoadingSpinner('ENTRIES: Preparing entry metadata...', async () => {
69
+ await this.prepareEntryMetaData();
70
+ });
71
+ cli_utilities_1.log.debug(`Entry metadata prepared: ${this.entryMetaData.length} entries found`, this.config.auditContext);
72
+ // Fix prerequisite data with loading spinner
73
+ await this.withLoadingSpinner('ENTRIES: Fixing prerequisite data...', async () => {
74
+ await this.fixPrerequisiteData();
75
+ });
76
+ cli_utilities_1.log.debug('Prerequisite data fix completed', this.config.auditContext);
77
+ // Create progress manager if we have a total count
78
+ if (totalCount && totalCount > 0) {
79
+ const progress = this.createSimpleProgress(this.moduleName, totalCount);
80
+ progress.updateStatus('Validating entries...');
81
+ }
82
+ cli_utilities_1.log.debug(`Processing ${this.locales.length} locales and ${this.ctSchema.length} content types`, this.config.auditContext);
83
+ for (const { code } of this.locales) {
84
+ cli_utilities_1.log.debug(`Processing locale: ${code}`, this.config.auditContext);
85
+ for (const ctSchema of this.ctSchema) {
86
+ cli_utilities_1.log.debug(`Processing content type: ${ctSchema.uid} in locale ${code}`, this.config.auditContext);
87
+ const basePath = (0, path_1.join)(this.folderPath, ctSchema.uid, code);
88
+ cli_utilities_1.log.debug(`Base path for entries: ${basePath}`, this.config.auditContext);
89
+ const fsUtility = new cli_utilities_1.FsUtility({ basePath, indexFileName: 'index.json', createDirIfNotExist: false });
90
+ const indexer = fsUtility.indexFileContent;
91
+ cli_utilities_1.log.debug(`Found ${Object.keys(indexer).length} entry files to process`, this.config.auditContext);
92
+ for (const fileIndex in indexer) {
93
+ cli_utilities_1.log.debug(`Processing entry file: ${indexer[fileIndex]}`, this.config.auditContext);
94
+ const entries = (await fsUtility.readChunkFiles.next());
95
+ this.entries = entries;
96
+ cli_utilities_1.log.debug(`Loaded ${Object.keys(entries).length} entries from file`, this.config.auditContext);
97
+ for (const entryUid in this.entries) {
98
+ const entry = this.entries[entryUid];
99
+ const { uid, title } = entry;
100
+ this.currentUid = uid;
101
+ this.currentTitle = title;
102
+ if (this.currentTitle) {
103
+ this.currentTitle = this.removeEmojiAndImages(this.currentTitle);
104
+ }
105
+ cli_utilities_1.log.debug(`Processing entry - title:${this.currentTitle} with uid:(${uid})`, this.config.auditContext);
106
+ if (!this.missingRefs[this.currentUid]) {
107
+ this.missingRefs[this.currentUid] = [];
108
+ }
109
+ if (!this.missingSelectFeild[this.currentUid]) {
110
+ this.missingSelectFeild[this.currentUid] = [];
111
+ }
112
+ if (!this.missingMandatoryFields[this.currentUid]) {
113
+ this.missingMandatoryFields[this.currentUid] = [];
114
+ }
115
+ if (this.fix) {
116
+ cli_utilities_1.log.debug(`Removing missing keys from entry ${uid}`, this.config.auditContext);
117
+ this.removeMissingKeysOnEntry(ctSchema.schema, this.entries[entryUid]);
118
+ }
119
+ cli_utilities_1.log.debug(`Looking for references in entry ${uid}`, this.config.auditContext);
120
+ this.lookForReference([{ locale: code, uid, name: this.removeEmojiAndImages(this.currentTitle) }], ctSchema, this.entries[entryUid]);
121
+ if ((_c = this.missingRefs[this.currentUid]) === null || _c === void 0 ? void 0 : _c.length) {
122
+ cli_utilities_1.log.debug(`Found ${this.missingRefs[this.currentUid].length} missing references for entry ${uid}`, this.config.auditContext);
123
+ this.missingRefs[this.currentUid].forEach((entry) => {
124
+ entry.ct = ctSchema.uid;
125
+ entry.locale = code;
126
+ });
127
+ }
128
+ if ((_d = this.missingSelectFeild[this.currentUid]) === null || _d === void 0 ? void 0 : _d.length) {
129
+ cli_utilities_1.log.debug(`Found ${this.missingSelectFeild[this.currentUid].length} missing select fields for entry ${uid}`, this.config.auditContext);
130
+ this.missingSelectFeild[this.currentUid].forEach((entry) => {
131
+ entry.ct = ctSchema.uid;
132
+ entry.locale = code;
133
+ });
134
+ }
135
+ if ((_e = this.missingMandatoryFields[this.currentUid]) === null || _e === void 0 ? void 0 : _e.length) {
136
+ cli_utilities_1.log.debug(`Found ${this.missingMandatoryFields[this.currentUid].length} missing mandatory fields for entry ${uid}`, this.config.auditContext);
137
+ this.missingMandatoryFields[this.currentUid].forEach((entry) => {
138
+ entry.ct = ctSchema.uid;
139
+ entry.locale = code;
140
+ });
141
+ }
142
+ const fields = this.missingMandatoryFields[uid];
143
+ const isPublished = ((_f = entry.publish_details) === null || _f === void 0 ? void 0 : _f.length) > 0;
144
+ cli_utilities_1.log.debug(`Entry ${uid} published status: ${isPublished}, missing mandatory fields: ${(fields === null || fields === void 0 ? void 0 : fields.length) || 0}`, this.config.auditContext);
145
+ if ((this.fix && fields.length && isPublished) || (!this.fix && fields)) {
146
+ const fixStatus = this.fix ? 'Fixed' : '';
147
+ cli_utilities_1.log.debug(`Applying fix status: ${fixStatus} to ${fields.length} fields`, this.config.auditContext);
148
+ fields === null || fields === void 0 ? void 0 : fields.forEach((field, index) => {
149
+ cli_utilities_1.log.debug(`Processing field ${index + 1}/${fields.length}`, this.config.auditContext);
150
+ field.isPublished = isPublished;
151
+ if (this.fix && isPublished) {
152
+ field.fixStatus = fixStatus;
153
+ cli_utilities_1.log.debug(`Field ${index + 1} marked as published and fixed`, this.config.auditContext);
154
+ }
155
+ });
139
156
  if (this.fix && isPublished) {
140
- field.fixStatus = fixStatus;
141
- cli_utilities_1.log.debug(`Field ${index + 1} marked as published and fixed`, this.config.auditContext);
157
+ cli_utilities_1.log.debug(`Fixing mandatory field issue for entry ${uid}`, this.config.auditContext);
158
+ cli_utilities_1.log.error((0, messages_1.$t)(messages_1.auditFixMsg.ENTRY_MANDATORY_FIELD_FIX, { uid, locale: code }), this.config.auditContext);
159
+ entry.publish_details = [];
142
160
  }
143
- });
144
- if (this.fix && isPublished) {
145
- cli_utilities_1.log.debug(`Fixing mandatory field issue for entry ${uid}`, this.config.auditContext);
146
- cli_utilities_1.log.error((0, messages_1.$t)(messages_1.auditFixMsg.ENTRY_MANDATORY_FIELD_FIX, { uid, locale: code }), this.config.auditContext);
147
- entry.publish_details = [];
148
- }
149
- }
150
- else {
151
- delete this.missingMandatoryFields[uid];
152
- }
153
- const localKey = this.locales.map((locale) => locale.code);
154
- cli_utilities_1.log.debug(`Available locales: ${localKey.join(', ')}, environments: ${this.environments.join(', ')}`, this.config.auditContext);
155
- if (((_g = this.entries[entryUid]) === null || _g === void 0 ? void 0 : _g.publish_details) && !Array.isArray(this.entries[entryUid].publish_details)) {
156
- cli_utilities_1.log.debug(`Entry ${entryUid} has invalid publish_details format`, this.config.auditContext);
157
- cli_utilities_1.log.debug((0, messages_1.$t)(messages_1.auditMsg.ENTRY_PUBLISH_DETAILS_NOT_EXIST, { uid: entryUid }), this.config.auditContext);
158
- }
159
- const originalPublishDetails = ((_j = (_h = this.entries[entryUid]) === null || _h === void 0 ? void 0 : _h.publish_details) === null || _j === void 0 ? void 0 : _j.length) || 0;
160
- this.entries[entryUid].publish_details = (_k = this.entries[entryUid]) === null || _k === void 0 ? void 0 : _k.publish_details.filter((pd) => {
161
- var _a;
162
- cli_utilities_1.log.debug(`Checking publish detail: locale=${pd.locale}, environment=${pd.environment}`, this.config.auditContext);
163
- if ((localKey === null || localKey === void 0 ? void 0 : localKey.includes(pd.locale)) && ((_a = this.environments) === null || _a === void 0 ? void 0 : _a.includes(pd.environment))) {
164
- cli_utilities_1.log.debug(`Publish detail valid for entry ${entryUid}: locale=${pd.locale}, environment=${pd.environment}`, this.config.auditContext);
165
- return true;
166
161
  }
167
162
  else {
168
- cli_utilities_1.log.debug(`Publish detail invalid for entry ${entryUid}: locale=${pd.locale}, environment=${pd.environment}`, this.config.auditContext);
169
- cli_utilities_1.log.debug((0, messages_1.$t)(messages_1.auditMsg.ENTRY_PUBLISH_DETAILS, {
170
- uid: entryUid,
171
- ctuid: ctSchema.uid,
172
- locale: code,
173
- publocale: pd.locale,
174
- environment: pd.environment,
175
- }), this.config.auditContext);
176
- if (!Object.keys(this.missingEnvLocale).includes(entryUid)) {
177
- cli_utilities_1.log.debug(`Creating new missing environment/locale entry for ${entryUid}`, this.config.auditContext);
178
- this.missingEnvLocale[entryUid] = [
179
- {
163
+ delete this.missingMandatoryFields[uid];
164
+ }
165
+ const localKey = this.locales.map((locale) => locale.code);
166
+ cli_utilities_1.log.debug(`Available locales: ${localKey.join(', ')}, environments: ${this.environments.join(', ')}`, this.config.auditContext);
167
+ if (((_g = this.entries[entryUid]) === null || _g === void 0 ? void 0 : _g.publish_details) && !Array.isArray(this.entries[entryUid].publish_details)) {
168
+ cli_utilities_1.log.debug(`Entry ${entryUid} has invalid publish_details format`, this.config.auditContext);
169
+ cli_utilities_1.log.debug((0, messages_1.$t)(messages_1.auditMsg.ENTRY_PUBLISH_DETAILS_NOT_EXIST, { uid: entryUid }), this.config.auditContext);
170
+ }
171
+ const originalPublishDetails = ((_j = (_h = this.entries[entryUid]) === null || _h === void 0 ? void 0 : _h.publish_details) === null || _j === void 0 ? void 0 : _j.length) || 0;
172
+ this.entries[entryUid].publish_details = (_k = this.entries[entryUid]) === null || _k === void 0 ? void 0 : _k.publish_details.filter((pd) => {
173
+ var _a;
174
+ cli_utilities_1.log.debug(`Checking publish detail: locale=${pd.locale}, environment=${pd.environment}`, this.config.auditContext);
175
+ if ((localKey === null || localKey === void 0 ? void 0 : localKey.includes(pd.locale)) && ((_a = this.environments) === null || _a === void 0 ? void 0 : _a.includes(pd.environment))) {
176
+ cli_utilities_1.log.debug(`Publish detail valid for entry ${entryUid}: locale=${pd.locale}, environment=${pd.environment}`, this.config.auditContext);
177
+ return true;
178
+ }
179
+ else {
180
+ cli_utilities_1.log.debug(`Publish detail invalid for entry ${entryUid}: locale=${pd.locale}, environment=${pd.environment}`, this.config.auditContext);
181
+ cli_utilities_1.log.debug((0, messages_1.$t)(messages_1.auditMsg.ENTRY_PUBLISH_DETAILS, {
182
+ uid: entryUid,
183
+ ctuid: ctSchema.uid,
184
+ locale: code,
185
+ publocale: pd.locale,
186
+ environment: pd.environment,
187
+ }), this.config.auditContext);
188
+ if (!Object.keys(this.missingEnvLocale).includes(entryUid)) {
189
+ cli_utilities_1.log.debug(`Creating new missing environment/locale entry for ${entryUid}`, this.config.auditContext);
190
+ this.missingEnvLocale[entryUid] = [
191
+ {
192
+ entry_uid: entryUid,
193
+ publish_locale: pd.locale,
194
+ publish_environment: pd.environment,
195
+ ctUid: ctSchema.uid,
196
+ ctLocale: code,
197
+ },
198
+ ];
199
+ }
200
+ else {
201
+ cli_utilities_1.log.debug(`Adding to existing missing environment/locale entry for ${entryUid}`, this.config.auditContext);
202
+ this.missingEnvLocale[entryUid].push({
180
203
  entry_uid: entryUid,
181
204
  publish_locale: pd.locale,
182
205
  publish_environment: pd.environment,
183
206
  ctUid: ctSchema.uid,
184
207
  ctLocale: code,
185
- },
186
- ];
208
+ });
209
+ }
210
+ return false;
187
211
  }
188
- else {
189
- cli_utilities_1.log.debug(`Adding to existing missing environment/locale entry for ${entryUid}`, this.config.auditContext);
190
- this.missingEnvLocale[entryUid].push({
191
- entry_uid: entryUid,
192
- publish_locale: pd.locale,
193
- publish_environment: pd.environment,
194
- ctUid: ctSchema.uid,
195
- ctLocale: code,
196
- });
197
- }
198
- return false;
212
+ });
213
+ const remainingPublishDetails = ((_l = this.entries[entryUid].publish_details) === null || _l === void 0 ? void 0 : _l.length) || 0;
214
+ cli_utilities_1.log.debug(`Entry ${entryUid} publish details: ${originalPublishDetails} -> ${remainingPublishDetails}`, this.config.auditContext);
215
+ const message = (0, messages_1.$t)(messages_1.auditMsg.SCAN_ENTRY_SUCCESS_MSG, {
216
+ title,
217
+ local: code,
218
+ module: this.config.moduleConfig.entries.name,
219
+ });
220
+ cli_utilities_1.log.debug(message, this.config.auditContext);
221
+ cli_utilities_1.log.info(message, this.config.auditContext);
222
+ // Track progress for each entry processed
223
+ if (this.progressManager) {
224
+ this.progressManager.tick(true, `entry: ${title || uid}`, null);
199
225
  }
200
- });
201
- const remainingPublishDetails = ((_l = this.entries[entryUid].publish_details) === null || _l === void 0 ? void 0 : _l.length) || 0;
202
- cli_utilities_1.log.debug(`Entry ${entryUid} publish details: ${originalPublishDetails} -> ${remainingPublishDetails}`, this.config.auditContext);
203
- const message = (0, messages_1.$t)(messages_1.auditMsg.SCAN_ENTRY_SUCCESS_MSG, {
204
- title,
205
- local: code,
206
- module: this.config.moduleConfig.entries.name,
207
- });
208
- cli_utilities_1.log.debug(message, this.config.auditContext);
209
- cli_utilities_1.log.info(message, this.config.auditContext);
210
- }
211
- if (this.fix) {
212
- cli_utilities_1.log.debug(`Writing fix content for ${Object.keys(this.entries).length} entries`, this.config.auditContext);
213
- await this.writeFixContent(`${basePath}/${indexer[fileIndex]}`, this.entries);
226
+ }
227
+ if (this.fix) {
228
+ cli_utilities_1.log.debug(`Writing fix content for ${Object.keys(this.entries).length} entries`, this.config.auditContext);
229
+ await this.writeFixContent(`${basePath}/${indexer[fileIndex]}`, this.entries);
230
+ }
214
231
  }
215
232
  }
216
233
  }
234
+ cli_utilities_1.log.debug('Cleaning up empty missing references', this.config.auditContext);
235
+ this.removeEmptyVal();
236
+ const result = {
237
+ missingEntryRefs: this.missingRefs,
238
+ missingSelectFeild: this.missingSelectFeild,
239
+ missingMandatoryFields: this.missingMandatoryFields,
240
+ missingTitleFields: this.missingTitleFields,
241
+ missingEnvLocale: this.missingEnvLocale,
242
+ missingMultipleFields: this.missingMultipleField,
243
+ };
244
+ cli_utilities_1.log.debug(`Entries audit completed. Found issues:`, this.config.auditContext);
245
+ cli_utilities_1.log.debug(`- Missing references: ${Object.keys(this.missingRefs).length}`, this.config.auditContext);
246
+ cli_utilities_1.log.debug(`- Missing select fields: ${Object.keys(this.missingSelectFeild).length}`, this.config.auditContext);
247
+ cli_utilities_1.log.debug(`- Missing mandatory fields: ${Object.keys(this.missingMandatoryFields).length}`, this.config.auditContext);
248
+ cli_utilities_1.log.debug(`- Missing title fields: ${Object.keys(this.missingTitleFields).length}`, this.config.auditContext);
249
+ cli_utilities_1.log.debug(`- Missing environment/locale: ${Object.keys(this.missingEnvLocale).length}`, this.config.auditContext);
250
+ cli_utilities_1.log.debug(`- Missing multiple fields: ${Object.keys(this.missingMultipleField).length}`, this.config.auditContext);
251
+ this.completeProgress(true);
252
+ return result;
253
+ }
254
+ catch (error) {
255
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Entries audit failed');
256
+ throw error;
217
257
  }
218
- cli_utilities_1.log.debug('Cleaning up empty missing references', this.config.auditContext);
219
- this.removeEmptyVal();
220
- const result = {
221
- missingEntryRefs: this.missingRefs,
222
- missingSelectFeild: this.missingSelectFeild,
223
- missingMandatoryFields: this.missingMandatoryFields,
224
- missingTitleFields: this.missingTitleFields,
225
- missingEnvLocale: this.missingEnvLocale,
226
- missingMultipleFields: this.missingMultipleField,
227
- };
228
- cli_utilities_1.log.debug(`Entries audit completed. Found issues:`, this.config.auditContext);
229
- cli_utilities_1.log.debug(`- Missing references: ${Object.keys(this.missingRefs).length}`, this.config.auditContext);
230
- cli_utilities_1.log.debug(`- Missing select fields: ${Object.keys(this.missingSelectFeild).length}`, this.config.auditContext);
231
- cli_utilities_1.log.debug(`- Missing mandatory fields: ${Object.keys(this.missingMandatoryFields).length}`, this.config.auditContext);
232
- cli_utilities_1.log.debug(`- Missing title fields: ${Object.keys(this.missingTitleFields).length}`, this.config.auditContext);
233
- cli_utilities_1.log.debug(`- Missing environment/locale: ${Object.keys(this.missingEnvLocale).length}`, this.config.auditContext);
234
- cli_utilities_1.log.debug(`- Missing multiple fields: ${Object.keys(this.missingMultipleField).length}`, this.config.auditContext);
235
- return result;
236
258
  }
237
259
  /**
238
260
  * The function removes any properties from the `missingRefs` object that have an empty array value.
@@ -1,9 +1,9 @@
1
- import { ConfigType, ContentTypeStruct, CtConstructorParam, ModuleConstructorParam, Extension } from '../types';
1
+ import { ContentTypeStruct, CtConstructorParam, ModuleConstructorParam, Extension } from '../types';
2
2
  import auditConfig from '../config';
3
- export default class Extensions {
3
+ import BaseClass from './base-class';
4
+ export default class Extensions extends BaseClass {
4
5
  protected fix: boolean;
5
6
  fileName: any;
6
- config: ConfigType;
7
7
  folderPath: string;
8
8
  extensionsSchema: Extension[];
9
9
  ctSchema: ContentTypeStruct[];
@@ -14,7 +14,7 @@ export default class Extensions {
14
14
  extensionsPath: string;
15
15
  constructor({ fix, config, moduleName, ctSchema, }: ModuleConstructorParam & Pick<CtConstructorParam, 'ctSchema'>);
16
16
  validateModules(moduleName: keyof typeof auditConfig.moduleConfig, moduleConfig: Record<string, unknown>): keyof typeof auditConfig.moduleConfig;
17
- run(): Promise<{}>;
17
+ run(totalCount?: number): Promise<{}>;
18
18
  fixExtensionsScope(missingCtInExtensions: Extension[]): Promise<void>;
19
19
  writeFixContent(fixedExtensions: Record<string, Extension>): Promise<void>;
20
20
  }
@@ -7,9 +7,10 @@ const lodash_1 = require("lodash");
7
7
  const cli_utilities_1 = require("@contentstack/cli-utilities");
8
8
  const messages_1 = require("../messages");
9
9
  const lodash_2 = require("lodash");
10
- class Extensions {
10
+ const base_class_1 = tslib_1.__importDefault(require("./base-class"));
11
+ class Extensions extends base_class_1.default {
11
12
  constructor({ fix, config, moduleName, ctSchema, }) {
12
- this.config = config;
13
+ super({ config });
13
14
  this.fix = fix !== null && fix !== void 0 ? fix : false;
14
15
  this.ctSchema = ctSchema;
15
16
  this.extensionsSchema = [];
@@ -38,67 +39,86 @@ class Extensions {
38
39
  cli_utilities_1.log.debug(`Module ${moduleName} not found, defaulting to 'extensions'`, this.config.auditContext);
39
40
  return 'extensions';
40
41
  }
41
- async run() {
42
+ async run(totalCount) {
42
43
  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);
46
- if (!(0, fs_1.existsSync)(this.folderPath)) {
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' });
50
- return {};
51
- }
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);
55
- this.extensionsSchema = (0, fs_1.existsSync)(this.extensionsPath)
56
- ? (0, lodash_2.values)(JSON.parse((0, fs_1.readFileSync)(this.extensionsPath, 'utf-8')))
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);
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);
63
- for (const ext of this.extensionsSchema) {
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);
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);
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);
71
- ext.content_types = ctNotPresent;
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);
44
+ try {
45
+ cli_utilities_1.log.debug(`Starting ${this.moduleName} audit process`, this.config.auditContext);
46
+ cli_utilities_1.log.debug(`Extensions folder path: ${this.folderPath}`, this.config.auditContext);
47
+ cli_utilities_1.log.debug(`Fix mode: ${this.fix}`, this.config.auditContext);
48
+ if (!(0, fs_1.existsSync)(this.folderPath)) {
49
+ cli_utilities_1.log.debug(`Skipping ${this.moduleName} audit - path does not exist`, this.config.auditContext);
50
+ cli_utilities_1.log.warn(`Skipping ${this.moduleName} audit`, this.config.auditContext);
51
+ cli_utilities_1.cliux.print((0, messages_1.$t)(messages_1.auditMsg.NOT_VALID_PATH, { path: this.folderPath }), { color: 'yellow' });
52
+ return {};
81
53
  }
82
- cli_utilities_1.log.info((0, messages_1.$t)(messages_1.auditMsg.SCAN_EXT_SUCCESS_MSG, {
83
- title,
84
- module: this.config.moduleConfig[this.moduleName].name,
85
- uid,
86
- }), this.config.auditContext);
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);
90
- if (this.fix && this.missingCtInExtensions.length) {
91
- cli_utilities_1.log.debug(`Fix mode enabled, fixing ${this.missingCtInExtensions.length} extensions`, this.config.auditContext);
92
- await this.fixExtensionsScope((0, lodash_1.cloneDeep)(this.missingCtInExtensions));
93
- this.missingCtInExtensions.forEach((ext) => {
94
- cli_utilities_1.log.debug(`Marking extension ${ext.title} as fixed`, this.config.auditContext);
95
- ext.fixStatus = 'Fixed';
54
+ this.extensionsPath = path_1.default.join(this.folderPath, this.fileName);
55
+ cli_utilities_1.log.debug(`Extensions file path: ${this.extensionsPath}`, this.config.auditContext);
56
+ // Load extensions schema with loading spinner
57
+ await this.withLoadingSpinner('EXTENSIONS: Loading extensions schema...', async () => {
58
+ this.extensionsSchema = (0, fs_1.existsSync)(this.extensionsPath)
59
+ ? (0, lodash_2.values)(JSON.parse((0, fs_1.readFileSync)(this.extensionsPath, 'utf-8')))
60
+ : [];
96
61
  });
97
- cli_utilities_1.log.debug(`Extensions fix completed`, this.config.auditContext);
62
+ cli_utilities_1.log.debug(`Loaded ${this.extensionsSchema.length} extensions`, this.config.auditContext);
63
+ cli_utilities_1.log.debug(`Building content type UID set from ${this.ctSchema.length} content types`, this.config.auditContext);
64
+ this.ctSchema.map((ct) => this.ctUidSet.add(ct.uid));
65
+ cli_utilities_1.log.debug(`Content type UID set contains: ${Array.from(this.ctUidSet).join(', ')}`, this.config.auditContext);
66
+ // Create progress manager if we have a total count
67
+ if (totalCount && totalCount > 0) {
68
+ const progress = this.createSimpleProgress(this.moduleName, totalCount);
69
+ progress.updateStatus('Validating extensions...');
70
+ }
71
+ cli_utilities_1.log.debug(`Processing ${this.extensionsSchema.length} extensions`, this.config.auditContext);
72
+ for (const ext of this.extensionsSchema) {
73
+ const { title, uid, scope } = ext;
74
+ cli_utilities_1.log.debug(`Processing extension: ${title} (${uid})`, this.config.auditContext);
75
+ 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);
76
+ const ctNotPresent = scope === null || scope === void 0 ? void 0 : scope.content_types.filter((ct) => !this.ctUidSet.has(ct));
77
+ cli_utilities_1.log.debug(`Missing content types in extension: ${(ctNotPresent === null || ctNotPresent === void 0 ? void 0 : ctNotPresent.join(', ')) || 'none'}`, this.config.auditContext);
78
+ if ((ctNotPresent === null || ctNotPresent === void 0 ? void 0 : ctNotPresent.length) && ext.scope) {
79
+ cli_utilities_1.log.debug(`Extension ${title} has ${ctNotPresent.length} missing content types`, this.config.auditContext);
80
+ ext.content_types = ctNotPresent;
81
+ ctNotPresent.forEach((ct) => {
82
+ var _a;
83
+ cli_utilities_1.log.debug(`Adding missing content type: ${ct} to the Audit report.`, this.config.auditContext);
84
+ (_a = this.missingCts) === null || _a === void 0 ? void 0 : _a.add(ct);
85
+ });
86
+ (_b = this.missingCtInExtensions) === null || _b === void 0 ? void 0 : _b.push((0, lodash_1.cloneDeep)(ext));
87
+ }
88
+ else {
89
+ cli_utilities_1.log.debug(`Extension ${title} has no missing content types`, this.config.auditContext);
90
+ }
91
+ cli_utilities_1.log.info((0, messages_1.$t)(messages_1.auditMsg.SCAN_EXT_SUCCESS_MSG, {
92
+ title,
93
+ module: this.config.moduleConfig[this.moduleName].name,
94
+ uid,
95
+ }), this.config.auditContext);
96
+ // Track progress for each extension processed
97
+ if (this.progressManager) {
98
+ this.progressManager.tick(true, `extension: ${title}`, null);
99
+ }
100
+ }
101
+ cli_utilities_1.log.debug(`Extensions audit completed. Found ${this.missingCtInExtensions.length} extensions with missing content types`, this.config.auditContext);
102
+ cli_utilities_1.log.debug(`Total missing content types: ${this.missingCts.size}`, this.config.auditContext);
103
+ if (this.fix && this.missingCtInExtensions.length) {
104
+ cli_utilities_1.log.debug(`Fix mode enabled, fixing ${this.missingCtInExtensions.length} extensions`, this.config.auditContext);
105
+ await this.fixExtensionsScope((0, lodash_1.cloneDeep)(this.missingCtInExtensions));
106
+ this.missingCtInExtensions.forEach((ext) => {
107
+ cli_utilities_1.log.debug(`Marking extension ${ext.title} as fixed`, this.config.auditContext);
108
+ ext.fixStatus = 'Fixed';
109
+ });
110
+ cli_utilities_1.log.debug(`Extensions fix completed`, this.config.auditContext);
111
+ this.completeProgress(true);
112
+ return this.missingCtInExtensions;
113
+ }
114
+ cli_utilities_1.log.debug(`Extensions audit completed without fixes`, this.config.auditContext);
115
+ this.completeProgress(true);
98
116
  return this.missingCtInExtensions;
99
117
  }
100
- cli_utilities_1.log.debug(`Extensions audit completed without fixes`, this.config.auditContext);
101
- return this.missingCtInExtensions;
118
+ catch (error) {
119
+ this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Extensions audit failed');
120
+ throw error;
121
+ }
102
122
  }
103
123
  async fixExtensionsScope(missingCtInExtensions) {
104
124
  var _a, _b, _c, _d;