Skip to content

Commit 612fecb

Browse files
committed
SRE fixes
1 parent e81effc commit 612fecb

File tree

52 files changed

+417
-362
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+417
-362
lines changed

package-lock.json

Lines changed: 132 additions & 154 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/contentstack-audit/src/audit-base-command.ts

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -416,50 +416,55 @@ export abstract class AuditBaseCommand extends BaseCommand<typeof AuditBaseComma
416416
moduleName: keyof typeof config.moduleConfig | keyof typeof config.ReportTitleForEntries,
417417
listOfMissingRefs: Record<string, any>,
418418
): Promise<void> {
419-
const csvPath = join(this.sharedConfig.reportPath, `${moduleName}.csv`);
420-
421-
return new Promise<void>((resolve, reject) => {
422-
// file deepcode ignore MissingClose: Will auto close once csv stream end
423-
const ws = createWriteStream(csvPath).on('error', reject);
424-
const defaultColumns = Object.keys(OutputColumn);
425-
const userDefinedColumns = this.sharedConfig.flags.columns ? this.sharedConfig.flags.columns.split(',') : null;
426-
let missingRefs: RefErrorReturnType[] | WorkflowExtensionsRefErrorReturnType[] =
427-
Object.values(listOfMissingRefs).flat();
428-
const columns: (keyof typeof OutputColumn)[] = userDefinedColumns
429-
? [...userDefinedColumns, ...defaultColumns.filter((val: string) => !userDefinedColumns.includes(val))]
430-
: defaultColumns;
431-
432-
if (this.sharedConfig.flags.filter) {
433-
const [column, value]: [keyof typeof OutputColumn, string] = this.sharedConfig.flags.filter.split('=');
434-
// Filter the missingRefs array
435-
missingRefs = missingRefs.filter((row) => {
436-
if (OutputColumn[column] in row) {
437-
const rowKey = OutputColumn[column] as keyof (RefErrorReturnType | WorkflowExtensionsRefErrorReturnType);
438-
return row[rowKey] === value;
419+
if(Object.keys(config.moduleConfig).includes(moduleName)){
420+
const csvPath = join(this.sharedConfig.reportPath, `${moduleName}.csv`);
421+
return new Promise<void>((resolve, reject) => {
422+
// file deepcode ignore MissingClose: Will auto close once csv stream end
423+
const ws = createWriteStream(csvPath).on('error', reject);
424+
const defaultColumns = Object.keys(OutputColumn);
425+
const userDefinedColumns = this.sharedConfig.flags.columns ? this.sharedConfig.flags.columns.split(',') : null;
426+
let missingRefs: RefErrorReturnType[] | WorkflowExtensionsRefErrorReturnType[] =
427+
Object.values(listOfMissingRefs).flat();
428+
const columns: (keyof typeof OutputColumn)[] = userDefinedColumns
429+
? [...userDefinedColumns, ...defaultColumns.filter((val: string) => !userDefinedColumns.includes(val))]
430+
: defaultColumns;
431+
432+
if (this.sharedConfig.flags.filter) {
433+
const [column, value]: [keyof typeof OutputColumn, string] = this.sharedConfig.flags.filter.split('=');
434+
// Filter the missingRefs array
435+
missingRefs = missingRefs.filter((row) => {
436+
if (OutputColumn[column] in row) {
437+
const rowKey = OutputColumn[column] as keyof (RefErrorReturnType | WorkflowExtensionsRefErrorReturnType);
438+
return row[rowKey] === value;
439+
}
440+
return false;
441+
});
442+
}
443+
444+
const rowData: Record<string, string | string[]>[] = [];
445+
for (const issue of missingRefs) {
446+
let row: Record<string, string | string[]> = {};
447+
448+
for (const column of columns) {
449+
if (Object.keys(issue).includes(OutputColumn[column])) {
450+
const issueKey = OutputColumn[column] as keyof typeof issue;
451+
row[column] = issue[issueKey] as string;
452+
row[column] = typeof row[column] === 'object' ? JSON.stringify(row[column]) : row[column];
453+
}
439454
}
440-
return false;
441-
});
442-
}
443-
444-
const rowData: Record<string, string | string[]>[] = [];
445-
for (const issue of missingRefs) {
446-
let row: Record<string, string | string[]> = {};
447-
448-
for (const column of columns) {
449-
if (Object.keys(issue).includes(OutputColumn[column])) {
450-
const issueKey = OutputColumn[column] as keyof typeof issue;
451-
row[column] = issue[issueKey] as string;
452-
row[column] = typeof row[column] === 'object' ? JSON.stringify(row[column]) : row[column];
455+
456+
if (this.currentCommand === 'cm:stacks:audit:fix') {
457+
row['Fix status'] = row.fixStatus;
453458
}
459+
460+
rowData.push(row);
454461
}
455-
456-
if (this.currentCommand === 'cm:stacks:audit:fix') {
457-
row['Fix status'] = row.fixStatus;
458-
}
459-
460-
rowData.push(row);
461-
}
462-
csv.write(rowData, { headers: true }).pipe(ws).on('error', reject).on('finish', resolve);
463-
});
462+
csv.write(rowData, { headers: true }).pipe(ws).on('error', reject).on('finish', resolve);
463+
});
464+
} else {
465+
return new Promise<void>((reject)=>{
466+
return reject()
467+
})
468+
}
464469
}
465470
}

packages/contentstack-audit/src/messages/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ function $t(msg: string, args: Record<string, string>): string {
7777

7878
for (const key of Object.keys(args)) {
7979
const escapedKey = escapeRegExp(key);
80-
msg = msg.replace(new RegExp(`{${escapedKey}}`, 'g'), escapeRegExp(args[key]) || escapedKey);
80+
const escapedKeyRegex = new RegExp(`{${escapedKey}}`, 'g');
81+
const sanitizedValue = args[key] ? escapeRegExp(args[key]) : '';
82+
msg = msg.replace(escapedKeyRegex, sanitizedValue || escapedKey);
8183
}
8284

8385
return msg;

packages/contentstack-audit/src/modules/content-types.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import isEmpty from 'lodash/isEmpty';
44
import { join, resolve } from 'path';
55
import { existsSync, readFileSync, writeFileSync } from 'fs';
66

7-
import { ux } from '@contentstack/cli-utilities';
7+
import { sanitizepath, ux } from '@contentstack/cli-utilities';
88

99
import {
1010
LogFn,
@@ -51,11 +51,17 @@ export default class ContentType {
5151
this.fix = fix ?? false;
5252
this.ctSchema = ctSchema;
5353
this.gfSchema = gfSchema;
54-
this.moduleName = moduleName ?? 'content-types';
54+
this.moduleName = this.validateModules(moduleName!,this.config.moduleConfig);
5555
this.fileName = config.moduleConfig[this.moduleName].fileName;
56-
this.folderPath = resolve(config.basePath, config.moduleConfig[this.moduleName].dirName);
56+
this.folderPath = resolve(sanitizepath(config.basePath), sanitizepath(config.moduleConfig[this.moduleName].dirName));
5757
}
5858

59+
validateModules(moduleName:keyof typeof auditConfig.moduleConfig, moduleConfig: Record<string, unknown>):keyof typeof auditConfig.moduleConfig {
60+
if(Object.keys(moduleConfig).includes(moduleName)){
61+
return moduleName;
62+
}
63+
return 'content-types'
64+
}
5965
/**
6066
* The `run` function checks if a folder path exists, sets the schema based on the module name,
6167
* iterates over the schema and looks for references, and returns a list of missing references.

packages/contentstack-audit/src/modules/entries.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import find from 'lodash/find';
33
import values from 'lodash/values';
44
import isEmpty from 'lodash/isEmpty';
55
import { join, resolve } from 'path';
6-
import { ux, FsUtility } from '@contentstack/cli-utilities';
6+
import { ux, FsUtility, sanitizepath } from '@contentstack/cli-utilities';
77
import { existsSync, readFileSync, writeFileSync } from 'fs';
88

99
import auditConfig from '../config';
@@ -67,9 +67,16 @@ export default class Entries {
6767
this.fix = fix ?? false;
6868
this.ctSchema = ctSchema;
6969
this.gfSchema = gfSchema;
70-
this.moduleName = moduleName ?? 'entries';
70+
this.moduleName = this.validateModules(moduleName!,this.config.moduleConfig);
7171
this.fileName = config.moduleConfig[this.moduleName].fileName;
72-
this.folderPath = resolve(config.basePath, config.moduleConfig.entries.dirName);
72+
this.folderPath = resolve(sanitizepath(config.basePath), sanitizepath(config.moduleConfig.entries.dirName));
73+
}
74+
75+
validateModules(moduleName:keyof typeof auditConfig.moduleConfig, moduleConfig: Record<string, unknown>):keyof typeof auditConfig.moduleConfig {
76+
if(Object.keys(moduleConfig).includes(moduleName)){
77+
return moduleName;
78+
}
79+
return 'entries'
7380
}
7481

7582
/**

packages/contentstack-audit/src/modules/extensions.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import path, { join, resolve } from 'path';
22
import { existsSync, readFileSync, writeFileSync } from 'fs';
33
import { cloneDeep } from 'lodash';
44
import { LogFn, ConfigType, ContentTypeStruct, CtConstructorParam, ModuleConstructorParam, Extension } from '../types';
5-
import { ux } from '@contentstack/cli-utilities';
5+
import { ux, sanitizepath } from '@contentstack/cli-utilities';
66

77
import auditConfig from '../config';
88
import { $t, auditMsg, commonMsg } from '../messages';
@@ -34,14 +34,20 @@ export default class Extensions {
3434
this.fix = fix ?? false;
3535
this.ctSchema = ctSchema;
3636
this.extensionsSchema = [];
37-
this.moduleName = moduleName ?? 'extensions';
37+
this.moduleName = this.validateModules(moduleName!,this.config.moduleConfig);
3838
this.fileName = config.moduleConfig[this.moduleName].fileName;
39-
this.folderPath = resolve(config.basePath, config.moduleConfig[this.moduleName].dirName);
39+
this.folderPath = resolve(sanitizepath(config.basePath), sanitizepath(config.moduleConfig[this.moduleName].dirName));
4040
this.ctUidSet = new Set(['$all']);
4141
this.missingCtInExtensions = [];
4242
this.missingCts = new Set();
4343
this.extensionsPath = '';
4444
}
45+
validateModules(moduleName:keyof typeof auditConfig.moduleConfig, moduleConfig: Record<string, unknown>):keyof typeof auditConfig.moduleConfig {
46+
if(Object.keys(moduleConfig).includes(moduleName)){
47+
return moduleName;
48+
}
49+
return 'extensions'
50+
}
4551

4652
async run() {
4753
if (!existsSync(this.folderPath)) {

packages/contentstack-audit/src/modules/workflows.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { join, resolve } from 'path';
22
import { existsSync, readFileSync, writeFileSync } from 'fs';
33
import { cloneDeep } from 'lodash';
44
import { LogFn, ConfigType, ContentTypeStruct, CtConstructorParam, ModuleConstructorParam, Workflow } from '../types';
5-
import { ux } from '@contentstack/cli-utilities';
5+
import { sanitizepath, ux } from '@contentstack/cli-utilities';
66

77
import auditConfig from '../config';
88
import { $t, auditMsg, commonMsg } from '../messages';
@@ -35,15 +35,22 @@ export default class Workflows {
3535
this.fix = fix ?? false;
3636
this.ctSchema = ctSchema;
3737
this.workflowSchema = [];
38-
this.moduleName = moduleName ?? 'workflows';
38+
this.moduleName = this.validateModules(moduleName!,this.config.moduleConfig);
3939
this.fileName = config.moduleConfig[this.moduleName].fileName;
40-
this.folderPath = resolve(config.basePath, config.moduleConfig[this.moduleName].dirName);
40+
this.folderPath = resolve(sanitizepath(config.basePath), sanitizepath(config.moduleConfig[this.moduleName].dirName));
4141
this.ctUidSet = new Set(['$all']);
4242
this.missingCtInWorkflows = [];
4343
this.missingCts = new Set();
4444
this.workflowPath = '';
4545
this.isBranchFixDone = false;
4646
}
47+
validateModules(moduleName:keyof typeof auditConfig.moduleConfig, moduleConfig: Record<string, unknown>):keyof typeof auditConfig.moduleConfig {
48+
if(Object.keys(moduleConfig).includes(moduleName)){
49+
return moduleName;
50+
}
51+
return 'workflows'
52+
}
53+
4754
/**
4855
* Check whether the given path for the workflow exists or not
4956
* If path exist read

packages/contentstack-bootstrap/src/bootstrap/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as path from 'path';
2-
import { cliux } from '@contentstack/cli-utilities';
2+
import { cliux, sanitizepath } from '@contentstack/cli-utilities';
33
import { default as ContentStackSeed } from '@contentstack/cli-cm-seed/lib/commands/cm/stacks/seed';
44

55
import { AppConfig } from '../config';
@@ -58,7 +58,7 @@ export default class Bootstrap {
5858
if (options.appConfig.branch) {
5959
this.repo.branch = options.appConfig.branch;
6060
}
61-
this.cloneDirectory = path.join(options.cloneDirectory, this.repo.name);
61+
this.cloneDirectory = path.join(sanitizepath(options.cloneDirectory), sanitizepath(this.repo.name));
6262
this.ghClient = new GitHubClient(this.repo, options.appConfig.private, options.accessToken);
6363
this.options = options;
6464
}

packages/contentstack-bootstrap/src/bootstrap/utils.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as fs from 'fs';
22
import * as path from 'path';
3-
import { cliux, pathValidator } from '@contentstack/cli-utilities';
3+
import { cliux, pathValidator, sanitizepath } from '@contentstack/cli-utilities';
44
import { continueBootstrapCommand } from '../bootstrap/interactive';
55
import { AppConfig } from '../config';
66
import messageHandler from '../messages';
@@ -154,7 +154,7 @@ const envFileHandler = async (
154154
case 'reactjs':
155155
case 'reactjs-starter':
156156
fileName = `.env.${environmentVariables.environment}.local`;
157-
filePath = pathValidator(path.join(clonedDirectory, fileName));
157+
filePath = pathValidator(path.join(sanitizepath(clonedDirectory), sanitizepath(fileName)));
158158
content = `REACT_APP_CONTENTSTACK_API_KEY=${
159159
environmentVariables.api_key
160160
}\nREACT_APP_CONTENTSTACK_DELIVERY_TOKEN=${environmentVariables.deliveryToken}${
@@ -173,7 +173,7 @@ const envFileHandler = async (
173173
case 'nextjs':
174174
case 'nextjs-starter':
175175
fileName = `.env.${environmentVariables.environment}.local`;
176-
filePath = pathValidator(path.join(clonedDirectory, fileName));
176+
filePath = pathValidator(path.join(sanitizepath(clonedDirectory), sanitizepath(fileName)));
177177
content = `CONTENTSTACK_API_KEY=${environmentVariables.api_key}\nCONTENTSTACK_DELIVERY_TOKEN=${
178178
environmentVariables.deliveryToken
179179
}\n${
@@ -192,7 +192,7 @@ const envFileHandler = async (
192192
case 'gatsby':
193193
case 'gatsby-starter':
194194
fileName = `.env.${environmentVariables.environment}`;
195-
filePath = pathValidator(path.join(clonedDirectory, fileName));
195+
filePath = pathValidator(path.join(sanitizepath(clonedDirectory), sanitizepath(fileName)));
196196
content = `CONTENTSTACK_API_KEY=${environmentVariables.api_key}\nCONTENTSTACK_DELIVERY_TOKEN=${
197197
environmentVariables.deliveryToken
198198
}\n${
@@ -239,15 +239,15 @@ const envFileHandler = async (
239239
!isUSRegion && !customHost ? '\nCONTENTSTACK_REGION=' + region.name : ''
240240
}\nCONTENTSTACK_LIVE_PREVIEW=${livePreviewEnabled}\nCONTENTSTACK_LIVE_EDIT_TAGS=false`;
241241
fileName = `.env${environmentVariables.environment === 'production' ? '.prod' : ''}`;
242-
filePath = pathValidator(path.join(clonedDirectory, fileName));
242+
filePath = pathValidator(path.join(sanitizepath(clonedDirectory), sanitizepath(fileName)));
243243
result = await writeEnvFile(content, filePath);
244244
break;
245245
case 'nuxtjs':
246246
case 'nuxt-starter':
247247
case 'nuxt3-starter':
248248
case 'stencil-starter':
249249
fileName = production ? '.env.production' : '.env';
250-
filePath = pathValidator(path.join(clonedDirectory, fileName));
250+
filePath = pathValidator(path.join(sanitizepath(clonedDirectory), sanitizepath(fileName)));
251251
// Note: Stencil app needs all the env variables, even if they are not having values otherwise the rollup does not work properly and throws process in undefined error.
252252
content = `CONTENTSTACK_API_KEY=${environmentVariables.api_key}\nCONTENTSTACK_DELIVERY_TOKEN=${
253253
environmentVariables.deliveryToken
@@ -266,7 +266,7 @@ const envFileHandler = async (
266266
break;
267267
case 'vue-starter':
268268
fileName = '.env';
269-
filePath = pathValidator(path.join(clonedDirectory, fileName));
269+
filePath = pathValidator(path.join(sanitizepath(clonedDirectory), sanitizepath(fileName)));
270270
content = `VUE_APP_CONTENTSTACK_API_KEY=${environmentVariables.api_key}\nVUE_APP_CONTENTSTACK_DELIVERY_TOKEN=${
271271
environmentVariables.deliveryToken
272272
}\n${

packages/contentstack-branches/src/utils/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import fs from 'fs';
55
import path from 'path';
66
import forEach from 'lodash/forEach'
7-
import { configHandler, cliux, messageHandler } from '@contentstack/cli-utilities';
7+
import { configHandler, cliux, messageHandler, sanitizepath } from '@contentstack/cli-utilities';
88
import { MergeParams } from '../interfaces';
99

1010
export const getbranchesList = (branchResult, baseBranch: string) => {
@@ -40,7 +40,7 @@ export const refreshbranchConfig = async (apiKey, branchUid) => {
4040
export const writeFile = (filePath, data) => {
4141
return new Promise((resolve, reject) => {
4242
data = typeof data === 'object' ? JSON.stringify(data, null, 2) : data || '{}';
43-
fs.writeFile(path.resolve(filePath), data, (error) => {
43+
fs.writeFile(path.resolve(sanitizepath(filePath)), data, (error) => {
4444
if (error) {
4545
return reject(error);
4646
}
@@ -52,7 +52,7 @@ export const writeFile = (filePath, data) => {
5252
// by default file type is json
5353
export const readFile = (filePath, options = { type: 'json' }) => {
5454
return new Promise((resolve, reject) => {
55-
filePath = path.resolve(filePath);
55+
filePath = path.resolve(sanitizepath(filePath));
5656
fs.readFile(filePath, 'utf-8', (error, data) => {
5757
if (error) {
5858
reject(error);

0 commit comments

Comments
 (0)