x-fidelity 1.2.0 → 1.4.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.
Files changed (63) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +54 -226
  3. package/dist/archetypes/index.js +13 -16
  4. package/dist/core/cli.js +9 -6
  5. package/dist/core/engine.js +41 -31
  6. package/dist/core/engine.test.js +140 -7
  7. package/dist/facts/openaiAnalysisFacts.js +23 -20
  8. package/dist/facts/openaiAnalysisFacts.test.js +34 -26
  9. package/dist/facts/repoDependencyFacts.js +50 -1
  10. package/dist/facts/repoDependencyFacts.test.js +72 -0
  11. package/dist/facts/repoFilesystemFacts.js +2 -2
  12. package/dist/facts/repoFilesystemFacts.test.js +2 -2
  13. package/dist/index.js +2 -2
  14. package/dist/operators/fileContains.js +1 -0
  15. package/dist/operators/index.test.js +52 -0
  16. package/dist/operators/openaiAnalysisHighSeverity.js +3 -5
  17. package/dist/operators/openaiAnalysisHighSeverity.test.js +6 -6
  18. package/dist/operators/outdatedFramework.js +8 -43
  19. package/dist/operators/outdatedFramework.test.js +12 -33
  20. package/dist/rules/index.js +49 -15
  21. package/dist/rules/index.test.js +113 -0
  22. package/dist/rules/noDatabases-rule.json +5 -1
  23. package/dist/rules/openaiAnalysisA11y-rule.json +1 -1
  24. package/dist/rules/openaiAnalysisTop5-rule.json +1 -1
  25. package/dist/rules/outdatedFramework-rule.json +13 -11
  26. package/dist/rules/sensitiveLogging-rule.json +5 -1
  27. package/dist/server/configServer.js +70 -0
  28. package/dist/utils/config.js +10 -15
  29. package/dist/utils/config.test.js +62 -0
  30. package/dist/xfidelity +2 -2
  31. package/package.json +8 -4
  32. package/src/archetypes/index.ts +13 -16
  33. package/src/core/cli.ts +9 -6
  34. package/src/core/engine.test.ts +160 -7
  35. package/src/core/engine.ts +48 -37
  36. package/src/facts/index.ts +1 -1
  37. package/src/facts/openaiAnalysisFacts.test.ts +40 -31
  38. package/src/facts/openaiAnalysisFacts.ts +26 -22
  39. package/src/facts/repoDependencyFacts.test.ts +85 -0
  40. package/src/facts/repoDependencyFacts.ts +32 -1
  41. package/src/facts/repoFilesystemFacts.test.ts +2 -2
  42. package/src/facts/repoFilesystemFacts.ts +4 -4
  43. package/src/index.ts +2 -2
  44. package/src/operators/fileContains.ts +2 -1
  45. package/src/operators/index.test.ts +51 -0
  46. package/src/operators/openaiAnalysisHighSeverity.test.ts +6 -6
  47. package/src/operators/openaiAnalysisHighSeverity.ts +3 -6
  48. package/src/operators/outdatedFramework.test.ts +12 -32
  49. package/src/operators/outdatedFramework.ts +8 -22
  50. package/src/rules/index.test.ts +94 -0
  51. package/src/rules/index.ts +48 -17
  52. package/src/rules/noDatabases-rule.json +5 -1
  53. package/src/rules/openaiAnalysisA11y-rule.json +1 -1
  54. package/src/rules/openaiAnalysisTop5-rule.json +1 -1
  55. package/src/rules/outdatedFramework-rule.json +13 -11
  56. package/src/rules/sensitiveLogging-rule.json +5 -1
  57. package/src/server/configServer.ts +62 -0
  58. package/src/typeDefs.ts +8 -3
  59. package/src/utils/config.test.ts +64 -0
  60. package/src/utils/config.ts +14 -22
  61. package/webpack.config.js +0 -26
  62. /package/dist/rules/{standardDirectoryStructure-rule.json → nonStandardDirectoryStructure-rule.json} +0 -0
  63. /package/src/rules/{standardDirectoryStructure-rule.json → nonStandardDirectoryStructure-rule.json} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,28 @@
1
+ # [1.4.0](https://github.com/zotoio/x-fidelity/compare/v1.3.0...v1.4.0) (2024-07-14)
2
+
3
+
4
+ ### Features
5
+
6
+ * **rule:** report specific dependency issues ([2ccaf6c](https://github.com/zotoio/x-fidelity/commit/2ccaf6cfe9d6cf8a73de5413fffee40dbb0f236d))
7
+
8
+ # [1.3.0](https://github.com/zotoio/x-fidelity/compare/v1.2.0...v1.3.0) (2024-07-11)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **ai:** fix ([8f94cee](https://github.com/zotoio/x-fidelity/commit/8f94cee6ef990a39db3bc4c61f16b3c56bdb10dd))
14
+ * **ai:** fix ([f5ba9f5](https://github.com/zotoio/x-fidelity/commit/f5ba9f5319e02788f3c6a1f0b70b1fa2638e719d))
15
+ * Initialized OpenAI client before using it to prevent "Cannot read properties of undefined (reading 'chat')" error ([a112b43](https://github.com/zotoio/x-fidelity/commit/a112b4372ff7eef5c00cb4c3fede13eeb932b2a2))
16
+ * **refactor:** logic issues and async issue ([2ad8cdd](https://github.com/zotoio/x-fidelity/commit/2ad8cdd7becbd80217dd0115be266cdf753a8470))
17
+ * **sec:** prevent error reflection ([93eca93](https://github.com/zotoio/x-fidelity/commit/93eca93e4737f01977f27dacf8cabbd5adf1ab2b))
18
+ * **sec:** santize input ([6f78c39](https://github.com/zotoio/x-fidelity/commit/6f78c396a6d83189d3985a0c826f5967e1e6eee4))
19
+ * **server:** fix ai error ([20341fa](https://github.com/zotoio/x-fidelity/commit/20341fa0df7a34791f2a4f34a89ee1cf7e5014ef))
20
+
21
+
22
+ ### Features
23
+
24
+ * **server:** remote config server ([f027ed2](https://github.com/zotoio/x-fidelity/commit/f027ed200d94e0bc16c000a8a677da819a8695cf))
25
+
1
26
  # [1.2.0](https://github.com/zotoio/x-fidelity/compare/v1.1.0...v1.2.0) (2024-07-10)
2
27
 
3
28
 
package/README.md CHANGED
@@ -26,287 +26,115 @@ x-fidelity is a CLI tool designed to enforce adherence to a set of opinionated f
26
26
  - Verifies that dependencies are up-to-date according to a specified minimum version.
27
27
  - Checks for the presence or absence of specific strings in files.
28
28
  - Configurable via a remote JSON configuration file.
29
+ - Integrates with OpenAI for advanced code analysis.
29
30
 
30
31
  ## Installation
31
32
 
32
- Install x-fidelity with node 20+ and yarn:
33
+ Install x-fidelity with Node.js 18+ and Yarn:
33
34
 
34
35
  ```sh
35
- corepack enable
36
36
  yarn global add x-fidelity
37
37
  export PATH="$PATH:$(yarn global bin)"
38
38
  ```
39
39
 
40
- You may want to add that path line to ~/.bashrc
40
+ You may want to add the path line to your `~/.bashrc` or `~/.zshrc` file for persistence of the binary in your path.
41
41
 
42
42
  ## Usage
43
43
 
44
+ ### CLI
45
+
44
46
  To run x-fidelity, use the following command:
45
47
 
46
48
  ```sh
47
- xfidelity --dir <directory> [--configUrl <url>]
48
- ```
49
-
50
- - `--dir <directory>`: The directory of the repository to analyze.
51
- - `--configUrl <url>`: (Optional) The URL to fetch the configuration from.
52
-
53
- Example:
49
+ xfidelity
54
50
 
55
- ```sh
56
- xfidelity --dir ./my-repo --configUrl https://example.com/config.json
51
+ # you can use the following options for more advanced setups such as the remote config server
52
+ xfidelity [-d --dir <directory>] [-c --configUrl <url>] [-a --archtype <archetype>]
57
53
  ```
58
54
 
59
- ## Configuration
55
+ - `-d --dir <directory>`: (Optional) The root directory of the local repo dir to analyze. Default is current dir.
56
+ - `-c --configUrl <url>`: (Optional) The URL to fetch the configuration from.
57
+ - `-a --archetype <archetype>`: (Optional) The archetype to use for analysis. 'node-fullstack' is the default, or 'java-microservice' and these are extensible)
60
58
 
61
- The configuration file should be a JSON file containing the following structure:
59
+ **Example for node-fullstack archetype in current dir with remove config server:**
62
60
 
63
- ```json
64
- {
65
- "minimumDependencyVersions": {
66
- "commander": "^2.0.0",
67
- "nodemon": "^3.9.0"
68
- },
69
- "standardStructure": {
70
- "src": {
71
- "core": null,
72
- "utils": null,
73
- "operators": null,
74
- "rules": null,
75
- "facts": null
76
- }
77
- }
78
- }
61
+ ```sh
62
+ xfidelity --configUrl https://localhost:8888
79
63
  ```
80
64
 
81
- ## OpenAI Integration
82
-
83
- x-fidelity can integrate with OpenAI to provide advanced code analysis. To enable OpenAI features, you need to set the `OPENAI_API_KEY` environment variable with your OpenAI API key.
84
-
85
- ### Getting an OpenAI API Key
86
-
87
- 1. Sign up for an account at [OpenAI](https://www.openai.com/).
88
- 2. Navigate to the API section and generate a new API key.
89
- 3. Set the `OPENAI_API_KEY` environment variable in your terminal or CI/CD pipeline.
65
+ **Example for java-microservice archetype in parent dir with remote config server (in this example running locally on port 8888):**
90
66
 
91
67
  ```sh
92
- export OPENAI_API_KEY=your_openai_api_key
68
+ xfidelity -d .. -a java-microservice --c https://localhost:8888
93
69
  ```
94
70
 
95
- ### Disclaimer
71
+ ### Configuration Server
96
72
 
97
- Using OpenAI's API may incur costs. Please refer to OpenAI's pricing page for more details.
73
+ x-fidelity includes an optional configuration server that can be used to serve configuration per archetype. This includes config for fact provders and custom operators, and also the rule json to use per archetype.
98
74
 
99
- ## Rules
75
+ This is of most use when you need to be able to globally rollout config updates for minor/patch releases without relying cli users run to upgrade x-fidelity.
100
76
 
101
- ### Sensitive Logging
77
+ **To start the server:**
102
78
 
103
- This rule checks for the presence of sensitive data in the logs.
79
+ 1. Navigate to the x-fidelity directory.
80
+ 2. Run the following command:
104
81
 
105
- ```json
106
- {
107
- "name": "sensitiveLogging",
108
- "conditions": {
109
- "any": [
110
- {
111
- "fact": "fileData",
112
- "path": "$.fileContent",
113
- "operator": "fileContains",
114
- "value": "token"
115
- },
116
- {
117
- "fact": "fileData",
118
- "path": "$.fileContent",
119
- "operator": "fileContains",
120
- "value": "secret"
121
- },
122
- {
123
- "fact": "fileData",
124
- "path": "$.fileContent",
125
- "operator": "fileContains",
126
- "value": "todo: expand with regex operator for more sensitive data patterns"
127
- }
128
- ]
129
- },
130
- "event": {
131
- "type": "violation",
132
- "params": {
133
- "message": "Sensitive data must not be logged."
134
- }
135
- }
136
- }
82
+ ```sh
83
+ yarn start-config-server
137
84
  ```
138
85
 
139
- ### Outdated Framework
140
-
141
- This rule checks if any core framework dependencies are outdated.
142
-
143
- ```json
144
- {
145
- "name": "outdatedFramework",
146
- "conditions": {
147
- "all": [
148
- {
149
- "fact": "fileData",
150
- "path": "$.fileName",
151
- "operator": "outdatedFramework",
152
- "value": {
153
- "fact": "dependencyData"
154
- }
155
- }
156
- ]
157
- },
158
- "event": {
159
- "type": "violation",
160
- "params": {
161
- "message": "Some core framework dependencies have expired!",
162
- "filePath": {
163
- "fact": "fileData",
164
- "path": "$.filePath"
165
- },
166
- "minimumDependencyVersions": {
167
- "fact": "dependencyData",
168
- "path": "$.minimumDependencyVersions"
169
- }
170
- }
171
- }
172
- }
86
+ > **By default, the server will start on port 8888**. You can override this using the `XFI_SERVER_PORT` environment variable You can then use the server URL as the `--configUrl` parameter when running the CLI.
87
+ ```sh
88
+ export XFI_SERVER_PORT=8888
173
89
  ```
174
90
 
175
- ### No Databases
176
-
177
- This rule ensures that code does not directly call databases.
178
-
179
- ```json
180
- {
181
- "name": "noDatabases",
182
- "conditions": {
183
- "any": [
184
- {
185
- "fact": "fileData",
186
- "path": "$.fileContent",
187
- "operator": "fileContains",
188
- "value": "oracle"
189
- }
190
- ]
191
- },
192
- "event": {
193
- "type": "violation",
194
- "params": {
195
- "message": "Code must not directly call databases."
196
- }
197
- }
198
- }
199
- ```
91
+ ## OpenAI Integration
200
92
 
201
- ### Non-Standard Directory Structure
93
+ To enable OpenAI features for experimental LLM-based codebase analysis:
202
94
 
203
- This rule checks if the directory structure matches the standard structure.
95
+ 1. Sign up for a developer account at [OpenAI](https://platform.openai.com).
96
+ 2. Navigate to the API section and generate a new API key.
97
+ 3. Set the `OPENAI_API_KEY` environment variable:
204
98
 
205
- ```json
206
- {
207
- "name": "nonStandardDirectoryStructure",
208
- "conditions": {
209
- "all": [
210
- {
211
- "fact": "fileData",
212
- "path": "$.fileName",
213
- "operator": "equal",
214
- "value": "REPO_GLOBAL_CHECK"
215
- },
216
- {
217
- "fact": "fileData",
218
- "path": "$.filePath",
219
- "operator": "nonStandardDirectoryStructure",
220
- "value": {
221
- "fact": "standardStructure"
222
- }
223
- }
224
- ]
225
- },
226
- "event": {
227
- "type": "violation",
228
- "params": {
229
- "message": "Directory structure does not match the standard.",
230
- "details": {
231
- "fact": "fileData",
232
- "path": "$.filePath"
233
- }
234
- }
235
- }
236
- }
99
+ ```sh
100
+ export OPENAI_API_KEY=your_openai_api_key
101
+ ```
102
+ 4. Optionally set the OPENAI_MODEL environment var (default is gpt-4o):
103
+ ```sh
104
+ export OPENAI_MODEL=gpt-4
237
105
  ```
106
+ Note that not all models consistently return parseable JSON results, so some experimentation is required.
238
107
 
239
- ### OpenAI Analysis
108
+ > [!IMPORTANT]
109
+ > Using OpenAI's API may incur costs. Please refer to OpenAI's pricing page for more details.
110
+ >
111
+ >The 'collectOpenaiAnalysisFacts' function will concatenate all files that are not blacklisted but are included in the whitelist and send this to OpenAI. Ensure you consider any sensitive data that may be sent, and the cost based on the token count this will be per rule check that is executed.
240
112
 
241
- This rule uses OpenAI to analyze the codebase for various issues.
113
+ ## Configuration
242
114
 
243
- #### Top 5 Issues
115
+ The configuration file should be a JSON file containing rules, operators, facts, and other settings. You can find example configuration files in the `src/rules` directory of the repository.
244
116
 
245
- ```json
246
- {
247
- "name": "openaiAnalysisTop5Rule",
248
- "conditions": {
249
- "all": [
250
- {
251
- "fact": "fileData",
252
- "path": "$.fileName",
253
- "operator": "equal",
254
- "value": "REPO_GLOBAL_CHECK"
255
- },
256
- {
257
- "fact": "openaiAnalysis",
258
- "params": {
259
- "prompt": "What are the most important 5 things to fix?",
260
- "resultFact": "openaiAnalysisTop5"
261
- },
262
- "operator": "openaiAnalysisHighSeverity",
263
- "value": 8
264
- }
265
- ]
266
- },
267
- "event": {
268
- "type": "violation",
269
- "params": {
270
- "message": "OpenAI analysis failed for the provided prompt.",
271
- "results": {
272
- "fact": "openaiAnalysisTop5"
273
- }
274
- }
275
- }
276
- }
277
- ```
117
+ ### Rule Structure
278
118
 
279
- #### Accessibility Issues
119
+ Each rule is defined in a JSON file with the following structure:
280
120
 
281
121
  ```json
282
122
  {
283
- "name": "openaiAnalysisA11yRule",
123
+ "name": "ruleName",
124
+ "description": "A brief description of the rule",
284
125
  "conditions": {
285
126
  "all": [
286
127
  {
287
- "fact": "fileData",
288
- "path": "$.fileName",
289
- "operator": "equal",
290
- "value": "REPO_GLOBAL_CHECK"
291
- },
292
- {
293
- "fact": "openaiAnalysis",
294
- "params": {
295
- "prompt": "Identify any accessibility (a11y) issues in the codebase.",
296
- "resultFact": "openaiAnalysisA11y"
297
- },
298
- "operator": "openaiAnalysisHighSeverity",
299
- "value": 8
128
+ "fact": "factName",
129
+ "operator": "operatorName",
130
+ "value": "expectedValue"
300
131
  }
301
132
  ]
302
133
  },
303
134
  "event": {
304
- "type": "violation",
135
+ "type": "ruleFailure",
305
136
  "params": {
306
- "message": "OpenAI analysis detected accessibility (a11y) issues in the codebase.",
307
- "results": {
308
- "fact": "openaiAnalysisA11y"
309
- }
137
+ "message": "Error message when the rule fails"
310
138
  }
311
139
  }
312
140
  }
@@ -12,22 +12,19 @@ exports.archetypes = {
12
12
  nodemon: '^3.9.0'
13
13
  },
14
14
  standardStructure: {
15
- src: {
16
- core: null,
17
- utils: null,
18
- operators: null,
19
- rules: null,
20
- facts: null
15
+ app: {
16
+ frontend: null,
17
+ common: null,
18
+ server: null
21
19
  }
22
20
  },
23
21
  blacklistPatterns: [
24
- /.*\/\..*/, // dot files
25
- /.*\.(log|lock)$/, // file extensions blacklisted
26
- /.*\/(dist|coverage|build|node_modules)(\/.*|$)/ // directory names blacklisted
22
+ '.*\\/\\..*', // dot files
23
+ '.*\\.(log|lock)$', // file extensions blacklisted
24
+ '.*\\/(dist|coverage|build|node_modules)(\\/.*|$)' // directory names blacklisted
27
25
  ],
28
26
  whitelistPatterns: [
29
- /.*\.(ts|tsx|js|jsx|md)$/,
30
- /.*\/(package|tsconfig)\.json$/
27
+ '.*\\.(ts|tsx|js|jsx|md)$' // file extensions whitelisted
31
28
  ]
32
29
  }
33
30
  },
@@ -53,13 +50,13 @@ exports.archetypes = {
53
50
  }
54
51
  },
55
52
  blacklistPatterns: [
56
- /.*\/\..*/, // dot files
57
- /.*\.(log|lock)$/, // file extensions blacklisted
58
- /.*\/(target|build|out)(\/.*|$)/ // directory names blacklisted
53
+ '.*\\/\\..*', // dot files
54
+ '.*\\.(log|lock)$', // file extensions blacklisted
55
+ '.*\\/(target|build|out|dist|coverage|build|node_modules)(\\/.*|$)' // directory names blacklisted
59
56
  ],
60
57
  whitelistPatterns: [
61
- /.*\.(java|xml|properties|yml)$/,
62
- /.*\/pom\.xml$/
58
+ '.*\\.(java|xml|properties|yml)$',
59
+ '.*\\/pom\\.xml$'
63
60
  ]
64
61
  }
65
62
  }
package/dist/core/cli.js CHANGED
@@ -19,8 +19,9 @@ ${new Date().toString()}`);
19
19
  console.log(banner);
20
20
  logger_1.logger.info([banner]);
21
21
  commander_1.program
22
- .option("-d, --dir <directory>", "The checkout directory to analyse")
23
- .option("-a, --archetype <archetype>", "The archetype to use for analysis", "node-fullstack");
22
+ .option("-d, --dir <directory>", "The checkout directory to analyse", ".")
23
+ .option("-a, --archetype <archetype>", "The archetype to use for analysis", "node-fullstack")
24
+ .option("-c, --configServer <configServer>", "The config server URL for fetching remote archetype configurations and rules");
24
25
  commander_1.program.parse();
25
26
  const options = commander_1.program.opts();
26
27
  exports.options = options;
@@ -30,7 +31,9 @@ if (commander_1.program.options.length === 0)
30
31
  if (!options.dir) {
31
32
  console.error("Checkout directory not provided. Defaulting to current directory.");
32
33
  }
33
- console.log(`Archetype ${options.archetype}: analysis of: ${process.env.PWD}/${options.dir}`);
34
- logger_1.logger.info(`Archetype ${options.archetype}: analysis of: ${process.env.PWD}/${options.dir}`);
35
- console.log('=====================================');
36
- logger_1.logger.info('=====================================');
34
+ let msg = `Archetype ${options.archetype}: analysis of: ${process.env.PWD}/${options.dir}`;
35
+ logger_1.logger.info(msg) && console.log(msg);
36
+ msg = `configServer: ${options.configServer ? options.configServer : 'local'}`;
37
+ logger_1.logger.info(msg) && console.log(msg);
38
+ msg = '=====================================';
39
+ logger_1.logger.info(msg) && console.log(msg);
@@ -8,9 +8,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
12
  exports.analyzeCodebase = analyzeCodebase;
16
13
  const logger_1 = require("../utils/logger");
@@ -18,29 +15,28 @@ const json_rules_engine_1 = require("json-rules-engine");
18
15
  const repoFilesystemFacts_1 = require("../facts/repoFilesystemFacts");
19
16
  const repoDependencyFacts_1 = require("../facts/repoDependencyFacts");
20
17
  const openaiAnalysisFacts_1 = require("../facts/openaiAnalysisFacts");
21
- const axios_1 = __importDefault(require("axios"));
22
- const archetypes_1 = require("../archetypes");
23
- const rules_1 = require("../rules");
24
18
  const operators_1 = require("../operators");
25
19
  const facts_1 = require("../facts");
20
+ const rules_1 = require("../rules");
21
+ const config_1 = require("../utils/config");
26
22
  function analyzeCodebase(repoPath_1) {
27
- return __awaiter(this, arguments, void 0, function* (repoPath, archetype = 'node-fullstack') {
28
- let archetypeConfig = archetypes_1.archetypes[archetype] || archetypes_1.archetypes['node-fullstack'];
29
- if (archetypeConfig.configUrl) {
30
- try {
31
- const response = yield axios_1.default.get(archetypeConfig.configUrl);
32
- archetypeConfig = Object.assign(Object.assign({}, archetypeConfig), { config: Object.assign(Object.assign({}, archetypeConfig.config), response.data) });
33
- }
34
- catch (error) {
35
- logger_1.logger.error(`Error fetching remote config: ${error}`);
36
- }
37
- }
23
+ return __awaiter(this, arguments, void 0, function* (repoPath, archetype = 'node-fullstack', configServer = '') {
24
+ const configManager = config_1.ConfigManager.getInstance();
25
+ yield configManager.initialize(archetype, configServer);
26
+ const archetypeConfig = configManager.getConfig();
38
27
  const installedDependencyVersions = yield (0, repoDependencyFacts_1.getDependencyVersionFacts)(archetypeConfig);
39
28
  const fileData = yield (0, repoFilesystemFacts_1.collectRepoFileData)(repoPath, archetypeConfig);
29
+ // add REPO_GLOBAL_CHECK to fileData, which is the trigger for global checks
30
+ fileData.push({
31
+ fileName: config_1.REPO_GLOBAL_CHECK,
32
+ filePath: config_1.REPO_GLOBAL_CHECK,
33
+ fileContent: config_1.REPO_GLOBAL_CHECK
34
+ });
40
35
  const { minimumDependencyVersions, standardStructure } = archetypeConfig.config;
41
36
  const openaiSystemPrompt = yield (0, openaiAnalysisFacts_1.collectOpenaiAnalysisFacts)(fileData);
42
37
  const engine = new json_rules_engine_1.Engine([], { replaceFactsInEventParams: true, allowUndefinedFacts: true });
43
38
  // Add operators to engine
39
+ console.log(`### loading custom operators..`);
44
40
  const operators = yield (0, operators_1.loadOperators)(archetypeConfig.operators);
45
41
  operators.forEach((operator) => {
46
42
  var _a, _b;
@@ -50,39 +46,54 @@ function analyzeCodebase(repoPath_1) {
50
46
  }
51
47
  });
52
48
  // Add rules to engine
53
- const rules = yield (0, rules_1.loadRules)(archetypeConfig.rules);
49
+ console.log(`### loading json rules..`);
50
+ const rules = yield (0, rules_1.loadRules)(archetype, archetypeConfig.rules, configManager.configServer);
51
+ logger_1.logger.debug(rules);
54
52
  rules.forEach((rule) => {
55
- var _a, _b;
56
53
  try {
57
- if (!((_a = rule === null || rule === void 0 ? void 0 : rule.name) === null || _a === void 0 ? void 0 : _a.includes('openai')) || (process.env.OPENAI_API_KEY && ((_b = rule === null || rule === void 0 ? void 0 : rule.name) === null || _b === void 0 ? void 0 : _b.includes('openai')))) {
58
- console.log(`adding rule: ${rule === null || rule === void 0 ? void 0 : rule.name}`);
59
- engine.addRule(rule);
60
- }
54
+ console.log(`adding rule: ${rule === null || rule === void 0 ? void 0 : rule.name}`);
55
+ engine.addRule(rule);
61
56
  }
62
57
  catch (e) {
63
58
  console.error(`Error loading rule: ${rule === null || rule === void 0 ? void 0 : rule.name}`);
64
59
  logger_1.logger.error(e.message);
65
60
  }
66
61
  });
67
- engine.on('success', ({ type, params }) => {
62
+ engine.on('success', (_a, almanac_1) => __awaiter(this, [_a, almanac_1], void 0, function* ({ type, params }, almanac) {
68
63
  if (type === 'violation') {
69
- //console.log(params);
64
+ //console.log(await almanac.factValue('dependencyData'));
65
+ console.log(`Rule violation: ${JSON.stringify(params)}}`);
70
66
  }
71
- });
67
+ }));
72
68
  // Add facts to engine
69
+ console.log(`### loading facts..`);
73
70
  const facts = yield (0, facts_1.loadFacts)(archetypeConfig.facts);
74
71
  facts.forEach((fact) => {
75
- engine.addFact(fact.name, fact.fn);
72
+ var _a, _b;
73
+ if (!((_a = fact === null || fact === void 0 ? void 0 : fact.name) === null || _a === void 0 ? void 0 : _a.includes('openai')) || (process.env.OPENAI_API_KEY && ((_b = fact === null || fact === void 0 ? void 0 : fact.name) === null || _b === void 0 ? void 0 : _b.includes('openai')))) {
74
+ console.log(`adding fact: ${fact.name}`);
75
+ engine.addFact(fact.name, fact.fn);
76
+ }
76
77
  });
77
78
  if (process.env.OPENAI_API_KEY && archetypeConfig.facts.includes('openaiAnalysisFacts')) {
78
- console.log(`adding openai facts to engine..`);
79
+ console.log(`adding additional openai facts to engine..`);
79
80
  engine.addFact('openaiAnalysis', openaiAnalysisFacts_1.openaiAnalysis);
80
81
  engine.addFact('openaiSystemPrompt', openaiSystemPrompt);
81
82
  }
82
- // Run the engine for each file's data
83
+ // add output facts
84
+ engine.addFact('repoDependencyAnalysis', repoDependencyFacts_1.repoDependencyAnalysis);
85
+ // Run the engine for each file's data
86
+ console.log(`### Executing rules..`);
83
87
  let failures = [];
84
88
  for (const file of fileData) {
85
- logger_1.logger.info(`running engine for ${file.filePath}`);
89
+ if (file.fileName === 'REPO_GLOBAL_CHECK') {
90
+ let msg = `\n==========================\nSTARTING GLOBAL REPO CHECKS..\n==========================`;
91
+ logger_1.logger.info(msg) && console.log(msg);
92
+ }
93
+ else {
94
+ let msg = `running engine for ${file.filePath}`;
95
+ logger_1.logger.info(msg) && console.log(msg);
96
+ }
86
97
  const facts = {
87
98
  fileData: file,
88
99
  dependencyData: {
@@ -92,7 +103,6 @@ function analyzeCodebase(repoPath_1) {
92
103
  standardStructure
93
104
  };
94
105
  let fileFailures = [];
95
- console.log(`running engine for ${file.filePath} ..`);
96
106
  yield engine.run(facts)
97
107
  .then(({ results }) => {
98
108
  //console.log(events);