x-fidelity 1.6.0 → 1.6.1

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/.eslintrc.js ADDED
@@ -0,0 +1,19 @@
1
+ module.exports = {
2
+ parser: '@typescript-eslint/parser',
3
+ extends: [
4
+ 'eslint:recommended',
5
+ 'plugin:@typescript-eslint/recommended',
6
+ ],
7
+ parserOptions: {
8
+ ecmaVersion: 2020,
9
+ sourceType: 'module',
10
+ },
11
+ env: {
12
+ node: true,
13
+ es6: true,
14
+ },
15
+ rules: {
16
+ // Add any custom rules here
17
+ '@typescript-eslint/no-explicit-any': 'off', // Disable no-explicit-any rule
18
+ },
19
+ };
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [1.6.1](https://github.com/zotoio/x-fidelity/compare/v1.6.0...v1.6.1) (2024-07-27)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **lint:** setup ([f559331](https://github.com/zotoio/x-fidelity/commit/f5593314bc591cb2d6e8cb809c828455fa294b62))
7
+
1
8
  # [1.6.0](https://github.com/zotoio/x-fidelity/compare/v1.5.1...v1.6.0) (2024-07-27)
2
9
 
3
10
 
package/README.md CHANGED
@@ -45,8 +45,9 @@ x-fidelity is an advanced CLI tool designed to enforce opinionated framework adh
45
45
  7. [OpenAI Integration](#openai-integration)
46
46
  8. [Hosting Config Servers](#hosting-config-servers)
47
47
  9. [Best Practices](#best-practices)
48
- 10. [Contributing](#contributing)
49
- 11. [License](#license)
48
+ 10. [Linting](#linting)
49
+ 11. [Contributing](#contributing)
50
+ 12. [License](#license)
50
51
 
51
52
  ## Intent and Purpose
52
53
 
@@ -316,6 +317,22 @@ app.listen(8888, () => {
316
317
 
317
318
  Contributions to x-fidelity are welcome! Please refer to the `CONTRIBUTING.md` file for guidelines on how to contribute to this project.
318
319
 
320
+ ## Linting
321
+
322
+ This project uses ESLint for static code analysis. To run the linter:
323
+
324
+ ```sh
325
+ yarn lint
326
+ ```
327
+
328
+ To automatically fix linting issues:
329
+
330
+ ```sh
331
+ yarn lint:fix
332
+ ```
333
+
334
+ ESLint is also integrated into the CI pipeline and runs alongside unit tests in GitHub Actions.
335
+
319
336
  ## License
320
337
 
321
338
  This project is licensed under the MIT License. See the `LICENSE` file for details.
@@ -107,7 +107,7 @@ function analyzeCodebase(repoPath_1) {
107
107
  logger_1.logger.error(e.message);
108
108
  }
109
109
  });
110
- engine.on('success', (_a, almanac_1) => __awaiter(this, [_a, almanac_1], void 0, function* ({ type, params }, almanac) {
110
+ engine.on('success', (_a) => __awaiter(this, [_a], void 0, function* ({ type, params }) {
111
111
  if (type === 'violation') {
112
112
  logger_1.logger.warn(`violation detected: ${JSON.stringify(params)}}`);
113
113
  yield (0, telemetry_1.sendTelemetry)({
@@ -146,14 +146,14 @@ function analyzeCodebase(repoPath_1) {
146
146
  engine.addFact('repoDependencyAnalysis', repoDependencyFacts_1.repoDependencyAnalysis);
147
147
  // Run the engine for each file's data
148
148
  logger_1.logger.info(`### Executing rules..`);
149
- let failures = [];
149
+ const failures = [];
150
150
  for (const file of fileData) {
151
151
  if (file.fileName === config_1.REPO_GLOBAL_CHECK) {
152
- let msg = `\n==========================\nSTARTING GLOBAL REPO CHECKS..\n==========================`;
152
+ const msg = `\n==========================\nSTARTING GLOBAL REPO CHECKS..\n==========================`;
153
153
  logger_1.logger.info(msg);
154
154
  }
155
155
  else {
156
- let msg = `running engine for ${file.filePath}`;
156
+ const msg = `running engine for ${file.filePath}`;
157
157
  logger_1.logger.info(msg);
158
158
  }
159
159
  const facts = {
@@ -164,7 +164,7 @@ function analyzeCodebase(repoPath_1) {
164
164
  },
165
165
  standardStructure
166
166
  };
167
- let fileFailures = [];
167
+ const fileFailures = [];
168
168
  yield engine.run(facts)
169
169
  .then(({ results }) => {
170
170
  results.map((result) => {
@@ -206,11 +206,11 @@ function analyzeCodebase(repoPath_1) {
206
206
  });
207
207
  }
208
208
  const findKeyValuePair = (data, targetKey, targetValue) => {
209
- let results = [];
209
+ const results = [];
210
210
  const recursiveSearch = (obj) => {
211
211
  if (typeof obj === 'object' && obj !== null) {
212
- for (let key in obj) {
213
- if (obj.hasOwnProperty(key)) {
212
+ for (const key in obj) {
213
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
214
214
  if (key === targetKey && obj[key] === targetValue) {
215
215
  results.push(obj);
216
216
  return; // Stop searching this branch as we've found the target in this object
@@ -67,8 +67,8 @@ describe('analyzeCodebase', () => {
67
67
  getConfig: jest.fn().mockReturnValue(archetypes_1.archetypes['node-fullstack']),
68
68
  configServer: ''
69
69
  });
70
- jest.spyOn(console, 'log').mockImplementation(() => { });
71
- jest.spyOn(console, 'error').mockImplementation(() => { });
70
+ jest.spyOn(console, 'log').mockImplementation(() => { console.log('z'); });
71
+ jest.spyOn(console, 'error').mockImplementation(() => { console.log('z'); });
72
72
  });
73
73
  it('should analyze the codebase and return results', () => __awaiter(void 0, void 0, void 0, function* () {
74
74
  const mockFileData = [
@@ -13,11 +13,13 @@ exports.loadFacts = loadFacts;
13
13
  const repoFilesystemFacts_1 = require("./repoFilesystemFacts");
14
14
  const repoDependencyFacts_1 = require("./repoDependencyFacts");
15
15
  const openaiAnalysisFacts_1 = require("./openaiAnalysisFacts");
16
+ // eslint-disable-next-line @typescript-eslint/ban-types
16
17
  const allFacts = {
17
18
  repoFilesystemFacts: { name: 'fileData', fn: repoFilesystemFacts_1.collectRepoFileData },
18
19
  repoDependencyFacts: { name: 'dependencyData', fn: repoDependencyFacts_1.getDependencyVersionFacts },
19
20
  openaiAnalysisFacts: { name: 'openaiAnalysis', fn: openaiAnalysisFacts_1.openaiAnalysis }
20
21
  };
22
+ // eslint-disable-next-line @typescript-eslint/ban-types
21
23
  function loadFacts(factNames) {
22
24
  return __awaiter(this, void 0, void 0, function* () {
23
25
  return factNames
@@ -50,7 +50,7 @@ const semver = __importStar(require("semver"));
50
50
  function collectLocalDependencies() {
51
51
  let result = {};
52
52
  try {
53
- let stdout = (0, child_process_1.execSync)('npm ls -a --json');
53
+ const stdout = (0, child_process_1.execSync)('npm ls -a --json');
54
54
  result = JSON.parse(stdout.toString());
55
55
  }
56
56
  catch (e) {
@@ -80,11 +80,11 @@ function getDependencyVersionFacts(archetypeConfig) {
80
80
  * @returns An array of results.
81
81
  */
82
82
  function findPropertiesInTree(depGraph, minVersions) {
83
- let results = [];
83
+ const results = [];
84
84
  logger_1.logger.debug(`depGraph: ${depGraph}`);
85
85
  function walk(depGraph) {
86
86
  if (lodash_1.default.isObject(depGraph) && !lodash_1.default.isArray(depGraph)) {
87
- for (let depName in depGraph) {
87
+ for (const depName in depGraph) {
88
88
  if (Object.keys(minVersions).includes(depName)) {
89
89
  results.push({ dep: depName, ver: depGraph[depName].version, min: minVersions[depName] });
90
90
  }
@@ -94,7 +94,7 @@ function findPropertiesInTree(depGraph, minVersions) {
94
94
  }
95
95
  }
96
96
  else if (lodash_1.default.isArray(depGraph)) {
97
- for (let item of depGraph) {
97
+ for (const item of depGraph) {
98
98
  walk(item);
99
99
  }
100
100
  }
@@ -104,18 +104,18 @@ function findPropertiesInTree(depGraph, minVersions) {
104
104
  }
105
105
  function repoDependencyAnalysis(params, almanac) {
106
106
  return __awaiter(this, void 0, void 0, function* () {
107
- let result = { 'result': [] };
107
+ const result = { 'result': [] };
108
108
  const fileData = yield almanac.factValue('fileData');
109
109
  if (fileData.fileName !== 'REPO_GLOBAL_CHECK') {
110
110
  return result;
111
111
  }
112
- let analysis = [];
112
+ const analysis = [];
113
113
  const dependencyData = yield almanac.factValue('dependencyData');
114
114
  dependencyData.installedDependencyVersions.map((versionData) => {
115
115
  logger_1.logger.debug(`outdatedFramework: checking ${versionData.dep}`);
116
116
  const requiredRange = new semver.Range(versionData.min);
117
117
  if (!semver.gtr(versionData.ver, requiredRange)) {
118
- let dependencyFailure = {
118
+ const dependencyFailure = {
119
119
  'dependency': versionData.dep,
120
120
  'currentVersion': versionData.ver,
121
121
  'requiredVersion': versionData.min
@@ -129,4 +129,3 @@ function repoDependencyAnalysis(params, almanac) {
129
129
  return result;
130
130
  });
131
131
  }
132
- ;
package/dist/index.js CHANGED
@@ -25,7 +25,7 @@ try {
25
25
  }
26
26
  else {
27
27
  (() => __awaiter(void 0, void 0, void 0, function* () {
28
- let results = yield (0, engine_1.analyzeCodebase)(`${process.env.PWD}/${cli_1.options.dir}`, cli_1.options.archetype, cli_1.options.configServer);
28
+ const results = yield (0, engine_1.analyzeCodebase)(`${process.env.PWD}/${cli_1.options.dir}`, cli_1.options.archetype, cli_1.options.configServer);
29
29
  // if results are found, there were warning level issues found in the codebase
30
30
  if (results.length > 0) {
31
31
  logger_1.logger.warn('WARNING: lo-fi attributes detected in codebase!');
@@ -7,9 +7,9 @@ const fileContains = {
7
7
  'fn': (fileContent, checkString) => {
8
8
  let result = false;
9
9
  const regex = new RegExp(checkString, 'g');
10
- let lines = fileContent.split('\n');
10
+ const lines = fileContent.split('\n');
11
11
  let lineNumber = 0;
12
- for (let line of lines) {
12
+ for (const line of lines) {
13
13
  lineNumber++;
14
14
  if (regex.test(line)) {
15
15
  logger_1.logger.debug(`fileContains '${checkString}' found in line ${lineNumber}: ${line}`);
@@ -4,7 +4,7 @@ exports.outdatedFramework = void 0;
4
4
  const logger_1 = require("../utils/logger");
5
5
  const outdatedFramework = {
6
6
  'name': 'outdatedFramework',
7
- 'fn': (repoDependencyAnalysis, repoDependencyFacts) => {
7
+ 'fn': (repoDependencyAnalysis) => {
8
8
  var _a;
9
9
  let result = false;
10
10
  try {
@@ -67,9 +67,6 @@ function loadRules(archetype, ruleNames, configServer, logPrefix, localConfigPat
67
67
  else if (localConfigPath) {
68
68
  rule = yield loadLocalConfigRule(ruleName, localConfigPath);
69
69
  }
70
- else if (localConfigPath) {
71
- rule = yield loadLocalConfigRule(ruleName, localConfigPath);
72
- }
73
70
  else {
74
71
  rule = yield loadLocalRule(ruleName);
75
72
  }
@@ -25,7 +25,7 @@ app.use(express_1.default.json());
25
25
  app.use(expressLogger_1.expressLogger);
26
26
  const validInput = (value) => {
27
27
  // Ensure input contains only alphanumeric characters, hyphens, and underscores
28
- const validName = /^[a-zA-Z0-9-_\-]{1,50}$/;
28
+ const validName = /^[a-zA-Z0-9-_-]{1,50}$/;
29
29
  return validName.test(value);
30
30
  };
31
31
  app.get('/archetypes/:archetype', (req, res) => {
@@ -46,7 +46,7 @@ app.get('/archetypes', (req, res) => {
46
46
  app.get('/archetypes/:archetype/rules', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
47
47
  logger_1.logger.info(`serving rules for archetype: ${req.params.archetype}`);
48
48
  const archetype = req.params.archetype;
49
- if (validInput(archetype) && archetypes_1.archetypes.hasOwnProperty(archetype) && archetypes_1.archetypes[archetype].rules) {
49
+ if (validInput(archetype) && Object.prototype.hasOwnProperty.call(archetypes_1.archetypes, archetype) && archetypes_1.archetypes[archetype].rules) {
50
50
  const rules = yield (0, rules_1.loadRules)(archetype, archetypes_1.archetypes[archetype].rules);
51
51
  res.json(rules);
52
52
  }
@@ -58,7 +58,7 @@ app.get('/archetypes/:archetype/rules/:rule', (req, res) => __awaiter(void 0, vo
58
58
  logger_1.logger.info(`serving rule ${req.params.rule} for archetype ${req.params.archetype}..`);
59
59
  const archetype = req.params.archetype;
60
60
  const rule = req.params.rule;
61
- if (validInput(archetype) && validInput(rule) && archetypes_1.archetypes.hasOwnProperty(archetype) && archetypes_1.archetypes[archetype].rules.includes(rule)) {
61
+ if (validInput(archetype) && validInput(rule) && Object.prototype.hasOwnProperty.call(archetypes_1.archetypes, archetype) && archetypes_1.archetypes[archetype].rules.includes(rule)) {
62
62
  const rules = yield (0, rules_1.loadRules)(archetype, archetypes_1.archetypes[archetype].rules);
63
63
  const ruleJson = rules.find((r) => r.name === rule);
64
64
  res.json(ruleJson);
package/dist/xfidelity CHANGED
@@ -25,7 +25,7 @@ try {
25
25
  }
26
26
  else {
27
27
  (() => __awaiter(void 0, void 0, void 0, function* () {
28
- let results = yield (0, engine_1.analyzeCodebase)(`${process.env.PWD}/${cli_1.options.dir}`, cli_1.options.archetype, cli_1.options.configServer);
28
+ const results = yield (0, engine_1.analyzeCodebase)(`${process.env.PWD}/${cli_1.options.dir}`, cli_1.options.archetype, cli_1.options.configServer);
29
29
  // if results are found, there were warning level issues found in the codebase
30
30
  if (results.length > 0) {
31
31
  logger_1.logger.warn('WARNING: lo-fi attributes detected in codebase!');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x-fidelity",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "cli for opinionated framework adherence checks",
5
5
  "main": "dist/xfidelity",
6
6
  "bin": {
@@ -10,13 +10,15 @@
10
10
  "build": "rimraf dist/ && tsc && yarn copy-files",
11
11
  "copy-files": "cp src/rules/*.json dist/rules/ && cp dist/index.js dist/xfidelity",
12
12
  "start": "OPENAI_API_KEY= jest --watch",
13
- "test": "OPENAI_API_KEY= jest",
13
+ "test": "yarn lint && OPENAI_API_KEY= jest",
14
14
  "test:coverage": "OPENAI_API_KEY= jest --coverage",
15
- "commit": "git-cz",
15
+ "commit": "yarn test && git-cz",
16
16
  "release": "semantic-release",
17
17
  "test-bin-install": "yarn build && yarn global bin && yarn global add file:$PWD",
18
18
  "build-run": "yarn build && node . --dir . | jq -R -r '. as $line | try fromjson catch $line'",
19
- "start-server": "ts-node src/index.ts --mode server"
19
+ "start-server": "ts-node src/index.ts --mode server",
20
+ "lint": "eslint . --ext .ts",
21
+ "lint:fix": "eslint . --ext .ts --fix"
20
22
  },
21
23
  "repository": "git@github.com:zotoio/x-fidelity.git",
22
24
  "author": "wyvern8 <io@zoto.io>",
@@ -28,6 +30,9 @@
28
30
  "devDependencies": {
29
31
  "@jest/globals": "^29.7.0",
30
32
  "@semantic-release/changelog": "^6.0.3",
33
+ "@typescript-eslint/eslint-plugin": "^5.59.0",
34
+ "@typescript-eslint/parser": "^5.59.0",
35
+ "eslint": "^8.38.0",
31
36
  "@semantic-release/commit-analyzer": "^13.0.0",
32
37
  "@semantic-release/git": "^10.0.1",
33
38
  "@semantic-release/github": "^10.0.6",
@@ -59,8 +59,8 @@ describe('analyzeCodebase', () => {
59
59
  getConfig: jest.fn().mockReturnValue(archetypes['node-fullstack']),
60
60
  configServer: ''
61
61
  });
62
- jest.spyOn(console, 'log').mockImplementation(() => {});
63
- jest.spyOn(console, 'error').mockImplementation(() => {});
62
+ jest.spyOn(console, 'log').mockImplementation(() => {console.log('z')});
63
+ jest.spyOn(console, 'error').mockImplementation(() => {console.log('z')});
64
64
  });
65
65
 
66
66
  it('should analyze the codebase and return results', async () => {
@@ -1,7 +1,7 @@
1
1
  import { logger, logPrefix } from '../utils/logger';
2
- import { Almanac, Engine, EngineResult, Event, RuleProperties, RuleResult } from 'json-rules-engine';
2
+ import { Engine, EngineResult, Event, RuleProperties, RuleResult } from 'json-rules-engine';
3
3
  import { FileData, collectRepoFileData } from '../facts/repoFilesystemFacts';
4
- import { ScanResult, RuleFailure, ArchetypeConfig, OpenAIAnalysisParams } from '../types/typeDefs';
4
+ import { ScanResult, RuleFailure} from '../types/typeDefs';
5
5
  import { getDependencyVersionFacts, repoDependencyAnalysis } from '../facts/repoDependencyFacts';
6
6
  import { collectOpenaiAnalysisFacts, openaiAnalysis } from '../facts/openaiAnalysisFacts';
7
7
  import { loadOperators } from '../operators';
@@ -13,7 +13,7 @@ import { sendTelemetry } from '../utils/telemetry';
13
13
  import { execSync } from 'child_process';
14
14
  import os from 'os';
15
15
 
16
- async function analyzeCodebase(repoPath: string, archetype: string = 'node-fullstack', configServer: string = '', localConfigPath: string = ''): Promise<any[]> {
16
+ async function analyzeCodebase(repoPath: string, archetype = 'node-fullstack', configServer = '', localConfigPath = ''): Promise<any[]> {
17
17
  const configManager = ConfigManager.getInstance();
18
18
  await configManager.initialize(archetype, configServer, localConfigPath);
19
19
  const archetypeConfig = configManager.getConfig();
@@ -104,7 +104,7 @@ async function analyzeCodebase(repoPath: string, archetype: string = 'node-fulls
104
104
  }
105
105
  });
106
106
 
107
- engine.on('success', async ({ type, params }: Event, almanac: Almanac) => {
107
+ engine.on('success', async ({ type, params }: Event) => {
108
108
  if (type === 'violation') {
109
109
  logger.warn(`violation detected: ${JSON.stringify(params)}}`);
110
110
  await sendTelemetry({
@@ -152,14 +152,14 @@ async function analyzeCodebase(repoPath: string, archetype: string = 'node-fulls
152
152
 
153
153
  // Run the engine for each file's data
154
154
  logger.info(`### Executing rules..`);
155
- let failures: ScanResult[] = [];
155
+ const failures: ScanResult[] = [];
156
156
  for (const file of fileData) {
157
157
  if (file.fileName === REPO_GLOBAL_CHECK) {
158
- let msg = `\n==========================\nSTARTING GLOBAL REPO CHECKS..\n==========================`
158
+ const msg = `\n==========================\nSTARTING GLOBAL REPO CHECKS..\n==========================`
159
159
  logger.info(msg);
160
160
 
161
161
  } else {
162
- let msg = `running engine for ${file.filePath}`
162
+ const msg = `running engine for ${file.filePath}`
163
163
  logger.info(msg);
164
164
  }
165
165
  const facts = {
@@ -171,7 +171,7 @@ async function analyzeCodebase(repoPath: string, archetype: string = 'node-fulls
171
171
  standardStructure
172
172
 
173
173
  };
174
- let fileFailures: RuleFailure[] = [];
174
+ const fileFailures: RuleFailure[] = [];
175
175
 
176
176
  await engine.run(facts)
177
177
  .then(({ results }: EngineResult) => {
@@ -222,12 +222,12 @@ const findKeyValuePair = (
222
222
  targetKey: string,
223
223
  targetValue: any
224
224
  ): any[] => {
225
- let results: any[] = [];
225
+ const results: any[] = [];
226
226
 
227
227
  const recursiveSearch = (obj: any): void => {
228
228
  if (typeof obj === 'object' && obj !== null) {
229
- for (let key in obj) {
230
- if (obj.hasOwnProperty(key)) {
229
+ for (const key in obj) {
230
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
231
231
  if (key === targetKey && obj[key] === targetValue) {
232
232
  results.push(obj);
233
233
  return; // Stop searching this branch as we've found the target in this object
@@ -2,12 +2,14 @@ import { collectRepoFileData } from './repoFilesystemFacts';
2
2
  import { getDependencyVersionFacts } from './repoDependencyFacts';
3
3
  import { openaiAnalysis } from './openaiAnalysisFacts';
4
4
 
5
+ // eslint-disable-next-line @typescript-eslint/ban-types
5
6
  const allFacts: Record<string, { name: string, fn: Function }> = {
6
7
  repoFilesystemFacts: { name: 'fileData', fn: collectRepoFileData },
7
8
  repoDependencyFacts: { name: 'dependencyData', fn: getDependencyVersionFacts },
8
9
  openaiAnalysisFacts: { name: 'openaiAnalysis', fn: openaiAnalysis }
9
10
  };
10
11
 
12
+ // eslint-disable-next-line @typescript-eslint/ban-types
11
13
  async function loadFacts(factNames: string[]): Promise<{ name: string, fn: Function }[]> {
12
14
  return factNames
13
15
  .map(name => allFacts[name])
@@ -1,8 +1,6 @@
1
1
  import { execSync } from 'child_process';
2
2
  import { collectLocalDependencies, getDependencyVersionFacts, findPropertiesInTree } from './repoDependencyFacts';
3
3
  import { logger } from '../utils/logger';
4
- import { ConfigManager } from '../utils/config';
5
- import { arch } from 'os';
6
4
  import { archetypes } from '../archetypes';
7
5
 
8
6
  jest.mock('child_process', () => ({
@@ -13,7 +13,7 @@ import { FileData } from './repoFilesystemFacts';
13
13
  export function collectLocalDependencies(): LocalDependencies {
14
14
  let result: LocalDependencies = {};
15
15
  try {
16
- let stdout = execSync('npm ls -a --json');
16
+ const stdout = execSync('npm ls -a --json');
17
17
  result = JSON.parse(stdout.toString());
18
18
  } catch (e) {
19
19
  logger.error(`exec error: ${e}`);
@@ -44,13 +44,13 @@ export async function getDependencyVersionFacts(archetypeConfig: ArchetypeConfig
44
44
  * @returns An array of results.
45
45
  */
46
46
  export function findPropertiesInTree(depGraph: LocalDependencies, minVersions: MinimumDepVersions): VersionData[] {
47
- let results: VersionData[] = [];
47
+ const results: VersionData[] = [];
48
48
 
49
49
  logger.debug(`depGraph: ${depGraph}`);
50
50
 
51
51
  function walk(depGraph: LocalDependencies) {
52
52
  if (_.isObject(depGraph) && !_.isArray(depGraph)) {
53
- for (let depName in depGraph) {
53
+ for (const depName in depGraph) {
54
54
  if (Object.keys(minVersions).includes(depName)) {
55
55
  results.push({ dep: depName, ver: depGraph[depName].version, min: minVersions[depName] });
56
56
  }
@@ -59,7 +59,7 @@ export function findPropertiesInTree(depGraph: LocalDependencies, minVersions: M
59
59
  }
60
60
  }
61
61
  } else if (_.isArray(depGraph)) {
62
- for (let item of depGraph) {
62
+ for (const item of depGraph) {
63
63
  walk(item);
64
64
  }
65
65
  }
@@ -71,14 +71,14 @@ export function findPropertiesInTree(depGraph: LocalDependencies, minVersions: M
71
71
 
72
72
  export async function repoDependencyAnalysis(params: any, almanac: Almanac) {
73
73
 
74
- let result: any = {'result': []};
74
+ const result: any = {'result': []};
75
75
  const fileData: FileData = await almanac.factValue('fileData');
76
76
 
77
77
  if (fileData.fileName !== 'REPO_GLOBAL_CHECK') {
78
78
  return result;
79
79
  }
80
80
 
81
- let analysis: any = [];
81
+ const analysis: any = [];
82
82
  const dependencyData: any = await almanac.factValue('dependencyData');
83
83
 
84
84
  dependencyData.installedDependencyVersions.map((versionData: VersionData) => {
@@ -86,7 +86,7 @@ export async function repoDependencyAnalysis(params: any, almanac: Almanac) {
86
86
 
87
87
  const requiredRange = new semver.Range(versionData.min);
88
88
  if (!semver.gtr(versionData.ver, requiredRange)) {
89
- let dependencyFailure = {
89
+ const dependencyFailure = {
90
90
  'dependency': versionData.dep,
91
91
  'currentVersion': versionData.ver,
92
92
  'requiredVersion': versionData.min
@@ -102,4 +102,4 @@ export async function repoDependencyAnalysis(params: any, almanac: Almanac) {
102
102
  almanac.addRuntimeFact(params.resultFact, result);
103
103
 
104
104
  return result;
105
- };
105
+ }
@@ -1,7 +1,6 @@
1
1
  import { collectRepoFileData, parseFile, isBlacklisted, isWhitelisted } from './repoFilesystemFacts';
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
- import { logger } from '../utils/logger';
5
4
  import { ArchetypeConfig } from '../types/typeDefs';
6
5
 
7
6
  jest.mock('fs', () => ({
package/src/index.ts CHANGED
@@ -12,7 +12,7 @@ try {
12
12
  startServer(options.port);
13
13
  } else {
14
14
  (async () => {
15
- let results = await analyzeCodebase(`${process.env.PWD}/${options.dir}`, options.archetype, options.configServer);
15
+ const results = await analyzeCodebase(`${process.env.PWD}/${options.dir}`, options.archetype, options.configServer);
16
16
 
17
17
  // if results are found, there were warning level issues found in the codebase
18
18
  if (results.length > 0) {
@@ -7,9 +7,9 @@ const fileContains: OperatorDefn = {
7
7
  let result = false;
8
8
 
9
9
  const regex = new RegExp(checkString, 'g');
10
- let lines = fileContent.split('\n');
10
+ const lines = fileContent.split('\n');
11
11
  let lineNumber = 0;
12
- for (let line of lines) {
12
+ for (const line of lines) {
13
13
  lineNumber++;
14
14
  if (regex.test(line)) {
15
15
  logger.debug(`fileContains '${checkString}' found in line ${lineNumber}: ${line}`);
@@ -2,7 +2,6 @@ import { loadOperators } from './index';
2
2
  import { outdatedFramework } from './outdatedFramework';
3
3
  import { fileContains } from './fileContains';
4
4
  import { nonStandardDirectoryStructure } from './nonStandardDirectoryStructure';
5
- import { openaiAnalysisHighSeverity } from './openaiAnalysisHighSeverity';
6
5
 
7
6
  jest.mock('./outdatedFramework');
8
7
  jest.mock('./fileContains');
@@ -1,4 +1,3 @@
1
- import { logger } from '../utils/logger';
2
1
  import { outdatedFramework } from './outdatedFramework';
3
2
 
4
3
  describe('outdatedFramework', () => {
@@ -1,10 +1,9 @@
1
1
  import { logger } from '../utils/logger';
2
- import { OperatorDefn, VersionData } from '../types/typeDefs';
3
- import { REPO_GLOBAL_CHECK } from '../utils/config';
2
+ import { OperatorDefn } from '../types/typeDefs';
4
3
 
5
4
  const outdatedFramework: OperatorDefn = {
6
5
  'name': 'outdatedFramework',
7
- 'fn': (repoDependencyAnalysis: any, repoDependencyFacts: any) => {
6
+ 'fn': (repoDependencyAnalysis: any) => {
8
7
  let result = false;
9
8
 
10
9
  try {
@@ -3,7 +3,6 @@ import { RuleProperties } from 'json-rules-engine';
3
3
  import * as fs from 'fs';
4
4
  import * as path from 'path';
5
5
  import axios from 'axios';
6
- import { options } from "../core/cli";
7
6
  import { isOpenAIEnabled } from '../utils/openaiUtils';
8
7
 
9
8
  async function loadRules(archetype: string, ruleNames: string[], configServer?: string, logPrefix?: string, localConfigPath?: string): Promise<RuleProperties[]> {
@@ -31,8 +30,6 @@ async function loadRules(archetype: string, ruleNames: string[], configServer?:
31
30
  }
32
31
  } else if (localConfigPath) {
33
32
  rule = await loadLocalConfigRule(ruleName, localConfigPath);
34
- } else if (localConfigPath) {
35
- rule = await loadLocalConfigRule(ruleName, localConfigPath);
36
33
  } else {
37
34
  rule = await loadLocalRule(ruleName);
38
35
  }
@@ -13,7 +13,7 @@ app.use(expressLogger);
13
13
 
14
14
  const validInput = (value: string): boolean => {
15
15
  // Ensure input contains only alphanumeric characters, hyphens, and underscores
16
- const validName = /^[a-zA-Z0-9-_\-]{1,50}$/;
16
+ const validName = /^[a-zA-Z0-9-_-]{1,50}$/;
17
17
  return validName.test(value);
18
18
  }
19
19
 
@@ -36,7 +36,7 @@ app.get('/archetypes', (req, res) => {
36
36
  app.get('/archetypes/:archetype/rules', async (req, res) => {
37
37
  logger.info(`serving rules for archetype: ${req.params.archetype}`);
38
38
  const archetype = req.params.archetype;
39
- if (validInput(archetype) && archetypes.hasOwnProperty(archetype) && archetypes[archetype].rules) {
39
+ if (validInput(archetype) && Object.prototype.hasOwnProperty.call(archetypes, archetype) && archetypes[archetype].rules) {
40
40
  const rules = await loadRules(archetype, archetypes[archetype].rules);
41
41
  res.json(rules);
42
42
  } else {
@@ -48,7 +48,7 @@ app.get('/archetypes/:archetype/rules/:rule', async (req, res) => {
48
48
  logger.info(`serving rule ${req.params.rule} for archetype ${req.params.archetype}..`);
49
49
  const archetype = req.params.archetype;
50
50
  const rule = req.params.rule;
51
- if (validInput(archetype) && validInput(rule) && archetypes.hasOwnProperty(archetype) && archetypes[archetype].rules.includes(rule)) {
51
+ if (validInput(archetype) && validInput(rule) && Object.prototype.hasOwnProperty.call(archetypes, archetype) && archetypes[archetype].rules.includes(rule)) {
52
52
  const rules = await loadRules(archetype, archetypes[archetype].rules);
53
53
  const ruleJson = rules.find((r) => r.name === rule);
54
54
  res.json(ruleJson);
@@ -29,7 +29,7 @@ export class ConfigManager {
29
29
  return ConfigManager.instance;
30
30
  }
31
31
 
32
- public async initialize(archetype: string = 'node-fullstack', configServer?: string, localConfigPath?: string): Promise<void> {
32
+ public async initialize(archetype = 'node-fullstack', configServer?: string, localConfigPath?: string): Promise<void> {
33
33
  this.config = archetypes[archetype] || archetypes['node-fullstack'];
34
34
  this.configServer = configServer || '';
35
35
  this.localConfigPath = localConfigPath || '';