json-function-engine 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +509 -0
- package/dist/constants.d.ts +13 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +18 -0
- package/dist/constants.js.map +1 -0
- package/dist/engine/Executor.d.ts +92 -0
- package/dist/engine/Executor.d.ts.map +1 -0
- package/dist/engine/Executor.js +260 -0
- package/dist/engine/Executor.js.map +1 -0
- package/dist/engine/FileLoader.d.ts +51 -0
- package/dist/engine/FileLoader.d.ts.map +1 -0
- package/dist/engine/FileLoader.js +195 -0
- package/dist/engine/FileLoader.js.map +1 -0
- package/dist/engine/Pipeline.d.ts +54 -0
- package/dist/engine/Pipeline.d.ts.map +1 -0
- package/dist/engine/Pipeline.js +91 -0
- package/dist/engine/Pipeline.js.map +1 -0
- package/dist/engine/actions/BlockAction.d.ts +3 -0
- package/dist/engine/actions/BlockAction.d.ts.map +1 -0
- package/dist/engine/actions/BlockAction.js +13 -0
- package/dist/engine/actions/BlockAction.js.map +1 -0
- package/dist/engine/actions/FlagAction.d.ts +3 -0
- package/dist/engine/actions/FlagAction.d.ts.map +1 -0
- package/dist/engine/actions/FlagAction.js +29 -0
- package/dist/engine/actions/FlagAction.js.map +1 -0
- package/dist/engine/actions/NotifyAction.d.ts +3 -0
- package/dist/engine/actions/NotifyAction.d.ts.map +1 -0
- package/dist/engine/actions/NotifyAction.js +13 -0
- package/dist/engine/actions/NotifyAction.js.map +1 -0
- package/dist/engine/actions/TransformAction.d.ts +3 -0
- package/dist/engine/actions/TransformAction.d.ts.map +1 -0
- package/dist/engine/actions/TransformAction.js +13 -0
- package/dist/engine/actions/TransformAction.js.map +1 -0
- package/dist/engine/actions/index.d.ts +5 -0
- package/dist/engine/actions/index.d.ts.map +1 -0
- package/dist/engine/actions/index.js +5 -0
- package/dist/engine/actions/index.js.map +1 -0
- package/dist/engine/conditions/ArrayCondition.d.ts +3 -0
- package/dist/engine/conditions/ArrayCondition.d.ts.map +1 -0
- package/dist/engine/conditions/ArrayCondition.js +47 -0
- package/dist/engine/conditions/ArrayCondition.js.map +1 -0
- package/dist/engine/conditions/ComparisonCondition.d.ts +3 -0
- package/dist/engine/conditions/ComparisonCondition.d.ts.map +1 -0
- package/dist/engine/conditions/ComparisonCondition.js +42 -0
- package/dist/engine/conditions/ComparisonCondition.js.map +1 -0
- package/dist/engine/conditions/CompositeCondition.d.ts +3 -0
- package/dist/engine/conditions/CompositeCondition.d.ts.map +1 -0
- package/dist/engine/conditions/CompositeCondition.js +50 -0
- package/dist/engine/conditions/CompositeCondition.js.map +1 -0
- package/dist/engine/conditions/ExistsCondition.d.ts +3 -0
- package/dist/engine/conditions/ExistsCondition.d.ts.map +1 -0
- package/dist/engine/conditions/ExistsCondition.js +14 -0
- package/dist/engine/conditions/ExistsCondition.js.map +1 -0
- package/dist/engine/conditions/MathCondition.d.ts +3 -0
- package/dist/engine/conditions/MathCondition.d.ts.map +1 -0
- package/dist/engine/conditions/MathCondition.js +30 -0
- package/dist/engine/conditions/MathCondition.js.map +1 -0
- package/dist/engine/conditions/RegexCondition.d.ts +3 -0
- package/dist/engine/conditions/RegexCondition.d.ts.map +1 -0
- package/dist/engine/conditions/RegexCondition.js +10 -0
- package/dist/engine/conditions/RegexCondition.js.map +1 -0
- package/dist/engine/conditions/helpers.d.ts +3 -0
- package/dist/engine/conditions/helpers.d.ts.map +1 -0
- package/dist/engine/conditions/helpers.js +14 -0
- package/dist/engine/conditions/helpers.js.map +1 -0
- package/dist/engine/conditions/index.d.ts +7 -0
- package/dist/engine/conditions/index.d.ts.map +1 -0
- package/dist/engine/conditions/index.js +7 -0
- package/dist/engine/conditions/index.js.map +1 -0
- package/dist/engine/engine.d.ts +151 -0
- package/dist/engine/engine.d.ts.map +1 -0
- package/dist/engine/engine.js +246 -0
- package/dist/engine/engine.js.map +1 -0
- package/dist/engine/guards.d.ts +22 -0
- package/dist/engine/guards.d.ts.map +1 -0
- package/dist/engine/guards.js +84 -0
- package/dist/engine/guards.js.map +1 -0
- package/dist/engine/registry.d.ts +23 -0
- package/dist/engine/registry.d.ts.map +1 -0
- package/dist/engine/registry.js +93 -0
- package/dist/engine/registry.js.map +1 -0
- package/dist/engine/reporters/index.d.ts +12 -0
- package/dist/engine/reporters/index.d.ts.map +1 -0
- package/dist/engine/reporters/index.js +146 -0
- package/dist/engine/reporters/index.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +204 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +27 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/cache.d.ts +17 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +52 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/errors.d.ts +45 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +84 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/factories.d.ts +23 -0
- package/dist/utils/factories.d.ts.map +1 -0
- package/dist/utils/factories.js +63 -0
- package/dist/utils/factories.js.map +1 -0
- package/dist/utils/metrics.d.ts +75 -0
- package/dist/utils/metrics.d.ts.map +1 -0
- package/dist/utils/metrics.js +99 -0
- package/dist/utils/metrics.js.map +1 -0
- package/dist/utils/regex.d.ts +33 -0
- package/dist/utils/regex.d.ts.map +1 -0
- package/dist/utils/regex.js +226 -0
- package/dist/utils/regex.js.map +1 -0
- package/dist/utils/schema.d.ts +7 -0
- package/dist/utils/schema.d.ts.map +1 -0
- package/dist/utils/schema.js +226 -0
- package/dist/utils/schema.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { FunctionDefinition, FileInput, ExecutionContext, EngineOptions, Finding, LoadResult, FileSystem, Logger } from '../types/index.js';
|
|
2
|
+
import { Registry } from './registry.js';
|
|
3
|
+
import { FileLoader } from './FileLoader.js';
|
|
4
|
+
import { Executor } from './Executor.js';
|
|
5
|
+
import { type MetricsCollector } from '../utils/metrics.js';
|
|
6
|
+
/**
|
|
7
|
+
* Error policy for execution behavior
|
|
8
|
+
*/
|
|
9
|
+
export type ErrorPolicy = 'best-effort' | 'fail-fast';
|
|
10
|
+
/**
|
|
11
|
+
* Execution result with detailed error information
|
|
12
|
+
*/
|
|
13
|
+
export interface ExecutionResult {
|
|
14
|
+
findings: Finding[];
|
|
15
|
+
errors: Array<{
|
|
16
|
+
functionId: string;
|
|
17
|
+
file: string;
|
|
18
|
+
error: string;
|
|
19
|
+
phase: 'condition' | 'action';
|
|
20
|
+
}>;
|
|
21
|
+
success: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Dependencies for Engine constructor (for dependency injection)
|
|
25
|
+
*/
|
|
26
|
+
export interface EngineDependencies {
|
|
27
|
+
/** Custom registry instance */
|
|
28
|
+
registry?: Registry;
|
|
29
|
+
/** Custom file system implementation */
|
|
30
|
+
fileSystem?: FileSystem;
|
|
31
|
+
/** Custom logger implementation */
|
|
32
|
+
logger?: Logger;
|
|
33
|
+
/** Custom file loader implementation */
|
|
34
|
+
fileLoader?: FileLoader;
|
|
35
|
+
/** Custom executor implementation */
|
|
36
|
+
executor?: Executor;
|
|
37
|
+
/** Custom metrics collector implementation */
|
|
38
|
+
metrics?: MetricsCollector;
|
|
39
|
+
/** Error policy: 'best-effort' continues on errors, 'fail-fast' throws immediately */
|
|
40
|
+
errorPolicy?: ErrorPolicy;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Main entry point for the JSON Function Engine.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const engine = new Engine({ timeout: 5000, parallel: true });
|
|
48
|
+
* await engine.loadFunctions('./functions.json');
|
|
49
|
+
* const findings = await engine.execute(files, { cwd: '.' });
|
|
50
|
+
* const output = engine.format(findings, 'json', { pretty: true });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare class Engine {
|
|
54
|
+
private functions;
|
|
55
|
+
private registry;
|
|
56
|
+
private fileSystem;
|
|
57
|
+
private logger;
|
|
58
|
+
private fileLoader;
|
|
59
|
+
private executor;
|
|
60
|
+
private options;
|
|
61
|
+
private errorPolicy;
|
|
62
|
+
constructor(options?: EngineOptions, dependencies?: EngineDependencies);
|
|
63
|
+
/**
|
|
64
|
+
* Get the file loader instance for custom configuration
|
|
65
|
+
* @returns FileLoader instance
|
|
66
|
+
*/
|
|
67
|
+
getFileLoader(): FileLoader;
|
|
68
|
+
/**
|
|
69
|
+
* Get the executor instance for pipeline hooks and advanced control
|
|
70
|
+
* @returns Executor instance
|
|
71
|
+
*/
|
|
72
|
+
getExecutor(): Executor;
|
|
73
|
+
/**
|
|
74
|
+
* Get execution metrics from the last run
|
|
75
|
+
* @returns MetricsCollector with execution statistics
|
|
76
|
+
*/
|
|
77
|
+
getMetrics(): MetricsCollector;
|
|
78
|
+
/**
|
|
79
|
+
* Get execution errors from the last run
|
|
80
|
+
* @returns Array of classified errors with functionId, file, error, phase, and type
|
|
81
|
+
*/
|
|
82
|
+
getErrors(): Array<{
|
|
83
|
+
functionId: string;
|
|
84
|
+
file: string;
|
|
85
|
+
error: string;
|
|
86
|
+
phase: 'condition' | 'action';
|
|
87
|
+
type: string;
|
|
88
|
+
}>;
|
|
89
|
+
/**
|
|
90
|
+
* Get the registry for registering custom conditions, actions, or reporters
|
|
91
|
+
* @returns Registry instance
|
|
92
|
+
*/
|
|
93
|
+
getRegistry(): Registry;
|
|
94
|
+
/**
|
|
95
|
+
* Get all loaded functions from the engine
|
|
96
|
+
* @returns Array of FunctionDefinition objects
|
|
97
|
+
*/
|
|
98
|
+
getFunctions(): FunctionDefinition[];
|
|
99
|
+
/**
|
|
100
|
+
* Get the count of loaded functions
|
|
101
|
+
* @returns Number of functions currently loaded
|
|
102
|
+
*/
|
|
103
|
+
getFunctionCount(): number;
|
|
104
|
+
/**
|
|
105
|
+
* Add functions directly to the engine (useful for testing and programmatic use)
|
|
106
|
+
* @param functions Array of function definitions to add
|
|
107
|
+
*/
|
|
108
|
+
addFunctions(functions: FunctionDefinition[]): void;
|
|
109
|
+
/**
|
|
110
|
+
* Clear all functions from the engine
|
|
111
|
+
*/
|
|
112
|
+
clear(): void;
|
|
113
|
+
/**
|
|
114
|
+
* Set the error policy for execution
|
|
115
|
+
* @param policy 'best-effort' continues on errors, 'fail-fast' throws immediately
|
|
116
|
+
*/
|
|
117
|
+
setErrorPolicy(policy: ErrorPolicy): void;
|
|
118
|
+
/**
|
|
119
|
+
* Get the current error policy
|
|
120
|
+
*/
|
|
121
|
+
getErrorPolicy(): ErrorPolicy;
|
|
122
|
+
/**
|
|
123
|
+
* Load functions from JSON files
|
|
124
|
+
*/
|
|
125
|
+
loadFunctions(paths: string | string[], options?: EngineOptions): Promise<LoadResult>;
|
|
126
|
+
execute(files: FileInput[], context?: ExecutionContext): Promise<Finding[]>;
|
|
127
|
+
/**
|
|
128
|
+
* Execute with best-effort policy - collects errors and continues
|
|
129
|
+
*/
|
|
130
|
+
private executeBestEffort;
|
|
131
|
+
/**
|
|
132
|
+
* Validate all loaded function definitions
|
|
133
|
+
* @throws ValidationError if any function definition is invalid
|
|
134
|
+
*/
|
|
135
|
+
private validateFunctions;
|
|
136
|
+
/**
|
|
137
|
+
* Deduplicate findings based on functionId, file, line, and column
|
|
138
|
+
*/
|
|
139
|
+
private deduplicateFindings;
|
|
140
|
+
format(findings: Finding[], format: 'json' | 'text' | 'html' | 'sarif', options?: {
|
|
141
|
+
pretty?: boolean;
|
|
142
|
+
theme?: 'light' | 'dark';
|
|
143
|
+
version?: string;
|
|
144
|
+
}): string | Promise<string>;
|
|
145
|
+
scan(files: FileInput[], format?: 'json' | 'text' | 'html' | 'sarif', context?: ExecutionContext, formatOptions?: {
|
|
146
|
+
pretty?: boolean;
|
|
147
|
+
theme?: 'light' | 'dark';
|
|
148
|
+
version?: string;
|
|
149
|
+
}): Promise<string>;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { Registry } from './registry.js';
|
|
2
|
+
import { FileLoader } from './FileLoader.js';
|
|
3
|
+
import { Executor } from './Executor.js';
|
|
4
|
+
import { getSeverityWeight } from '../utils/regex.js';
|
|
5
|
+
import { DEFAULT_TIMEOUT_MS } from '../constants.js';
|
|
6
|
+
import { createDefaultFileSystem, createDefaultLogger } from '../utils/factories.js';
|
|
7
|
+
import { ValidationError, ConfigurationError } from '../utils/errors.js';
|
|
8
|
+
/**
|
|
9
|
+
* Main entry point for the JSON Function Engine.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const engine = new Engine({ timeout: 5000, parallel: true });
|
|
14
|
+
* await engine.loadFunctions('./functions.json');
|
|
15
|
+
* const findings = await engine.execute(files, { cwd: '.' });
|
|
16
|
+
* const output = engine.format(findings, 'json', { pretty: true });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export class Engine {
|
|
20
|
+
functions = [];
|
|
21
|
+
registry;
|
|
22
|
+
fileSystem;
|
|
23
|
+
logger;
|
|
24
|
+
fileLoader;
|
|
25
|
+
executor;
|
|
26
|
+
options;
|
|
27
|
+
errorPolicy;
|
|
28
|
+
constructor(options = {}, dependencies = {}) {
|
|
29
|
+
// Validate options
|
|
30
|
+
if (options.timeout !== undefined && options.timeout <= 0) {
|
|
31
|
+
throw new ConfigurationError('timeout must be a positive number');
|
|
32
|
+
}
|
|
33
|
+
if (options.parallel !== undefined && typeof options.parallel !== 'boolean') {
|
|
34
|
+
throw new ConfigurationError('parallel must be a boolean');
|
|
35
|
+
}
|
|
36
|
+
if (options.include !== undefined && !Array.isArray(options.include)) {
|
|
37
|
+
throw new ConfigurationError('include must be an array');
|
|
38
|
+
}
|
|
39
|
+
if (options.exclude !== undefined && !Array.isArray(options.exclude)) {
|
|
40
|
+
throw new ConfigurationError('exclude must be an array');
|
|
41
|
+
}
|
|
42
|
+
this.registry = dependencies.registry ?? new Registry();
|
|
43
|
+
this.fileSystem = dependencies.fileSystem ?? createDefaultFileSystem();
|
|
44
|
+
this.logger = dependencies.logger ?? createDefaultLogger();
|
|
45
|
+
this.fileLoader = dependencies.fileLoader ?? new FileLoader({
|
|
46
|
+
fileSystem: this.fileSystem,
|
|
47
|
+
logger: this.logger
|
|
48
|
+
});
|
|
49
|
+
this.executor = dependencies.executor ?? new Executor({ registry: this.registry, logger: this.logger }, { timeout: options.timeout, parallel: options.parallel });
|
|
50
|
+
this.options = {
|
|
51
|
+
include: options.include || [],
|
|
52
|
+
exclude: options.exclude || [],
|
|
53
|
+
timeout: options.timeout || DEFAULT_TIMEOUT_MS,
|
|
54
|
+
parallel: options.parallel ?? true
|
|
55
|
+
};
|
|
56
|
+
this.errorPolicy = dependencies.errorPolicy ?? 'best-effort';
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get the file loader instance for custom configuration
|
|
60
|
+
* @returns FileLoader instance
|
|
61
|
+
*/
|
|
62
|
+
getFileLoader() {
|
|
63
|
+
return this.fileLoader;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get the executor instance for pipeline hooks and advanced control
|
|
67
|
+
* @returns Executor instance
|
|
68
|
+
*/
|
|
69
|
+
getExecutor() {
|
|
70
|
+
return this.executor;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get execution metrics from the last run
|
|
74
|
+
* @returns MetricsCollector with execution statistics
|
|
75
|
+
*/
|
|
76
|
+
getMetrics() {
|
|
77
|
+
return this.executor.getMetrics();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get execution errors from the last run
|
|
81
|
+
* @returns Array of classified errors with functionId, file, error, phase, and type
|
|
82
|
+
*/
|
|
83
|
+
getErrors() {
|
|
84
|
+
return this.executor.getErrors();
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get the registry for registering custom conditions, actions, or reporters
|
|
88
|
+
* @returns Registry instance
|
|
89
|
+
*/
|
|
90
|
+
getRegistry() {
|
|
91
|
+
return this.registry;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get all loaded functions from the engine
|
|
95
|
+
* @returns Array of FunctionDefinition objects
|
|
96
|
+
*/
|
|
97
|
+
getFunctions() {
|
|
98
|
+
return this.functions;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get the count of loaded functions
|
|
102
|
+
* @returns Number of functions currently loaded
|
|
103
|
+
*/
|
|
104
|
+
getFunctionCount() {
|
|
105
|
+
return this.functions.length;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Add functions directly to the engine (useful for testing and programmatic use)
|
|
109
|
+
* @param functions Array of function definitions to add
|
|
110
|
+
*/
|
|
111
|
+
addFunctions(functions) {
|
|
112
|
+
this.functions = [...this.functions, ...functions];
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Clear all functions from the engine
|
|
116
|
+
*/
|
|
117
|
+
clear() {
|
|
118
|
+
this.functions = [];
|
|
119
|
+
this.fileLoader.clearCache();
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Set the error policy for execution
|
|
123
|
+
* @param policy 'best-effort' continues on errors, 'fail-fast' throws immediately
|
|
124
|
+
*/
|
|
125
|
+
setErrorPolicy(policy) {
|
|
126
|
+
this.errorPolicy = policy;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get the current error policy
|
|
130
|
+
*/
|
|
131
|
+
getErrorPolicy() {
|
|
132
|
+
return this.errorPolicy;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Load functions from JSON files
|
|
136
|
+
*/
|
|
137
|
+
async loadFunctions(paths, options) {
|
|
138
|
+
const mergedOptions = { ...this.options, ...options };
|
|
139
|
+
// Use FileLoader to load and parse files
|
|
140
|
+
const result = await this.fileLoader.load(paths, {
|
|
141
|
+
include: mergedOptions.include,
|
|
142
|
+
exclude: mergedOptions.exclude
|
|
143
|
+
});
|
|
144
|
+
// Best-effort: collect errors but continue (strict mode removed)
|
|
145
|
+
this.functions = result.functions;
|
|
146
|
+
return { loaded: result.loaded, errors: result.errors };
|
|
147
|
+
}
|
|
148
|
+
async execute(files, context = { cwd: process.cwd() }) {
|
|
149
|
+
// Validate function definitions before execution
|
|
150
|
+
this.validateFunctions();
|
|
151
|
+
// Check for cancellation before starting
|
|
152
|
+
if (context.signal?.aborted) {
|
|
153
|
+
const error = new Error('The operation was cancelled');
|
|
154
|
+
error.name = 'AbortError';
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
// Best-effort: continue on errors
|
|
158
|
+
return this.executeBestEffort(files, context);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Execute with best-effort policy - collects errors and continues
|
|
162
|
+
*/
|
|
163
|
+
async executeBestEffort(files, context) {
|
|
164
|
+
// Set up abort listener if signal provided
|
|
165
|
+
let abortHandler = null;
|
|
166
|
+
if (context.signal) {
|
|
167
|
+
abortHandler = () => {
|
|
168
|
+
this.executor.cancel();
|
|
169
|
+
};
|
|
170
|
+
context.signal.addEventListener('abort', abortHandler);
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
// Filter to enabled functions and apply framework filtering
|
|
174
|
+
let enabledFunctions = this.functions.filter(f => f.enabled !== false);
|
|
175
|
+
// Apply framework filtering if context has a framework specified
|
|
176
|
+
if (context.framework) {
|
|
177
|
+
enabledFunctions = enabledFunctions.filter(f => {
|
|
178
|
+
if (f.frameworks && f.frameworks.length > 0) {
|
|
179
|
+
return f.frameworks.includes(context.framework);
|
|
180
|
+
}
|
|
181
|
+
return true;
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
// Sort by priority
|
|
185
|
+
enabledFunctions = [...enabledFunctions].sort((a, b) => (a.priority ?? 999) - (b.priority ?? 999));
|
|
186
|
+
// Use Executor to run the functions - best-effort is default in Executor
|
|
187
|
+
const findings = await this.executor.execute(enabledFunctions, files, context);
|
|
188
|
+
// Deduplicate findings
|
|
189
|
+
const uniqueFindings = this.deduplicateFindings(findings);
|
|
190
|
+
// Sort by severity
|
|
191
|
+
return uniqueFindings.sort((a, b) => getSeverityWeight(b.severity) - getSeverityWeight(a.severity));
|
|
192
|
+
}
|
|
193
|
+
finally {
|
|
194
|
+
// Clean up the listener after execution completes
|
|
195
|
+
if (abortHandler && context.signal) {
|
|
196
|
+
context.signal.removeEventListener('abort', abortHandler);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Validate all loaded function definitions
|
|
202
|
+
* @throws ValidationError if any function definition is invalid
|
|
203
|
+
*/
|
|
204
|
+
validateFunctions() {
|
|
205
|
+
for (const fn of this.functions) {
|
|
206
|
+
if (!fn.id) {
|
|
207
|
+
throw new ValidationError('Function definition is missing required field: id', 'id');
|
|
208
|
+
}
|
|
209
|
+
if (!fn.condition) {
|
|
210
|
+
throw new ValidationError(`Function definition '${fn.id}' is missing required field: condition`, `functions.${fn.id}.condition`);
|
|
211
|
+
}
|
|
212
|
+
if (!fn.action) {
|
|
213
|
+
throw new ValidationError(`Function definition '${fn.id}' is missing required field: action`, `functions.${fn.id}.action`);
|
|
214
|
+
}
|
|
215
|
+
if (fn.condition && !fn.condition.type) {
|
|
216
|
+
throw new ValidationError(`Function definition '${fn.id}' condition is missing required field: type`, `functions.${fn.id}.condition.type`);
|
|
217
|
+
}
|
|
218
|
+
if (fn.action && !fn.action.type) {
|
|
219
|
+
throw new ValidationError(`Function definition '${fn.id}' action is missing required field: type`, `functions.${fn.id}.action.type`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Deduplicate findings based on functionId, file, line, and column
|
|
225
|
+
*/
|
|
226
|
+
deduplicateFindings(findings) {
|
|
227
|
+
const seen = new Set();
|
|
228
|
+
const unique = [];
|
|
229
|
+
for (const finding of findings) {
|
|
230
|
+
const key = `${finding.functionId}:${finding.location.file}:${finding.location.line}:${finding.location.column ?? 0}`;
|
|
231
|
+
if (!seen.has(key)) {
|
|
232
|
+
seen.add(key);
|
|
233
|
+
unique.push(finding);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return unique;
|
|
237
|
+
}
|
|
238
|
+
format(findings, format, options) {
|
|
239
|
+
return this.registry.format(findings, format, options);
|
|
240
|
+
}
|
|
241
|
+
async scan(files, format = 'json', context, formatOptions) {
|
|
242
|
+
const findings = await this.execute(files, context);
|
|
243
|
+
return this.format(findings, format, formatOptions);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/engine/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ConditionConfig, RegexConditionConfig, ComparisonConditionConfig, ExistsConditionConfig, CompositeConditionConfig, MathConditionConfig, ArrayConditionConfig, ActionConfig, FlagActionConfig, BlockActionConfig, TransformActionConfig, NotifyActionConfig } from '../types/index.js';
|
|
2
|
+
export declare function isRegexCondition(config: ConditionConfig): config is RegexConditionConfig;
|
|
3
|
+
export declare function isComparisonCondition(config: ConditionConfig): config is ComparisonConditionConfig;
|
|
4
|
+
export declare function isExistsCondition(config: ConditionConfig): config is ExistsConditionConfig;
|
|
5
|
+
export declare function isCompositeCondition(config: ConditionConfig): config is CompositeConditionConfig;
|
|
6
|
+
export declare function isMathCondition(config: ConditionConfig): config is MathConditionConfig;
|
|
7
|
+
export declare function isArrayCondition(config: ConditionConfig): config is ArrayConditionConfig;
|
|
8
|
+
export declare function isFlagAction(config: ActionConfig): config is FlagActionConfig;
|
|
9
|
+
export declare function isBlockAction(config: ActionConfig): config is BlockActionConfig;
|
|
10
|
+
export declare function isTransformAction(config: ActionConfig): config is TransformActionConfig;
|
|
11
|
+
export declare function isNotifyAction(config: ActionConfig): config is NotifyActionConfig;
|
|
12
|
+
export declare function assertRegexCondition(config: ConditionConfig): asserts config is RegexConditionConfig;
|
|
13
|
+
export declare function assertComparisonCondition(config: ConditionConfig): asserts config is ComparisonConditionConfig;
|
|
14
|
+
export declare function assertExistsCondition(config: ConditionConfig): asserts config is ExistsConditionConfig;
|
|
15
|
+
export declare function assertCompositeCondition(config: ConditionConfig): asserts config is CompositeConditionConfig;
|
|
16
|
+
export declare function assertMathCondition(config: ConditionConfig): asserts config is MathConditionConfig;
|
|
17
|
+
export declare function assertArrayCondition(config: ConditionConfig): asserts config is ArrayConditionConfig;
|
|
18
|
+
export declare function assertFlagAction(config: ActionConfig): asserts config is FlagActionConfig;
|
|
19
|
+
export declare function assertBlockAction(config: ActionConfig): asserts config is BlockActionConfig;
|
|
20
|
+
export declare function assertTransformAction(config: ActionConfig): asserts config is TransformActionConfig;
|
|
21
|
+
export declare function assertNotifyAction(config: ActionConfig): asserts config is NotifyActionConfig;
|
|
22
|
+
//# sourceMappingURL=guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../src/engine/guards.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;AAG3B,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,IAAI,oBAAoB,CAExF;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,IAAI,yBAAyB,CAElG;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,IAAI,qBAAqB,CAE1F;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,IAAI,wBAAwB,CAEhG;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,IAAI,mBAAmB,CAEtF;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,IAAI,oBAAoB,CAExF;AAGD,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,IAAI,gBAAgB,CAE7E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,IAAI,iBAAiB,CAE/E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,IAAI,qBAAqB,CAEvF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,IAAI,kBAAkB,CAEjF;AAGD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,IAAI,oBAAoB,CAIpG;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,IAAI,yBAAyB,CAI9G;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,IAAI,qBAAqB,CAItG;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,IAAI,wBAAwB,CAI5G;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,IAAI,mBAAmB,CAIlG;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,IAAI,oBAAoB,CAIpG;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,IAAI,gBAAgB,CAIzF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,IAAI,iBAAiB,CAI3F;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,IAAI,qBAAqB,CAInG;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,IAAI,kBAAkB,CAI7F"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Condition type guards
|
|
2
|
+
export function isRegexCondition(config) {
|
|
3
|
+
return config.type === 'regex';
|
|
4
|
+
}
|
|
5
|
+
export function isComparisonCondition(config) {
|
|
6
|
+
return config.type === 'comparison';
|
|
7
|
+
}
|
|
8
|
+
export function isExistsCondition(config) {
|
|
9
|
+
return config.type === 'exists';
|
|
10
|
+
}
|
|
11
|
+
export function isCompositeCondition(config) {
|
|
12
|
+
return config.type === 'composite';
|
|
13
|
+
}
|
|
14
|
+
export function isMathCondition(config) {
|
|
15
|
+
return config.type === 'math';
|
|
16
|
+
}
|
|
17
|
+
export function isArrayCondition(config) {
|
|
18
|
+
return config.type === 'array';
|
|
19
|
+
}
|
|
20
|
+
// Action type guards
|
|
21
|
+
export function isFlagAction(config) {
|
|
22
|
+
return config.type === 'flag';
|
|
23
|
+
}
|
|
24
|
+
export function isBlockAction(config) {
|
|
25
|
+
return config.type === 'block';
|
|
26
|
+
}
|
|
27
|
+
export function isTransformAction(config) {
|
|
28
|
+
return config.type === 'transform';
|
|
29
|
+
}
|
|
30
|
+
export function isNotifyAction(config) {
|
|
31
|
+
return config.type === 'notify';
|
|
32
|
+
}
|
|
33
|
+
// Assert functions for type narrowing with throw
|
|
34
|
+
export function assertRegexCondition(config) {
|
|
35
|
+
if (!isRegexCondition(config)) {
|
|
36
|
+
throw new Error(`Expected regex condition, got ${config.type}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function assertComparisonCondition(config) {
|
|
40
|
+
if (!isComparisonCondition(config)) {
|
|
41
|
+
throw new Error(`Expected comparison condition, got ${config.type}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export function assertExistsCondition(config) {
|
|
45
|
+
if (!isExistsCondition(config)) {
|
|
46
|
+
throw new Error(`Expected exists condition, got ${config.type}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function assertCompositeCondition(config) {
|
|
50
|
+
if (!isCompositeCondition(config)) {
|
|
51
|
+
throw new Error(`Expected composite condition, got ${config.type}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export function assertMathCondition(config) {
|
|
55
|
+
if (!isMathCondition(config)) {
|
|
56
|
+
throw new Error(`Expected math condition, got ${config.type}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function assertArrayCondition(config) {
|
|
60
|
+
if (!isArrayCondition(config)) {
|
|
61
|
+
throw new Error(`Expected array condition, got ${config.type}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export function assertFlagAction(config) {
|
|
65
|
+
if (!isFlagAction(config)) {
|
|
66
|
+
throw new Error(`Expected flag action, got ${config.type}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function assertBlockAction(config) {
|
|
70
|
+
if (!isBlockAction(config)) {
|
|
71
|
+
throw new Error(`Expected block action, got ${config.type}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export function assertTransformAction(config) {
|
|
75
|
+
if (!isTransformAction(config)) {
|
|
76
|
+
throw new Error(`Expected transform action, got ${config.type}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export function assertNotifyAction(config) {
|
|
80
|
+
if (!isNotifyAction(config)) {
|
|
81
|
+
throw new Error(`Expected notify action, got ${config.type}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=guards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.js","sourceRoot":"","sources":["../../src/engine/guards.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ConditionDefinition, ActionDefinition, ReporterDefinition, ConditionConfig, ActionConfig, ReporterFormat, ExecutionContext, FileInput, ConditionResult, ActionResult, Finding, FormatOptions } from '../types/index.js';
|
|
2
|
+
export declare class Registry {
|
|
3
|
+
private conditions;
|
|
4
|
+
private actions;
|
|
5
|
+
private reporters;
|
|
6
|
+
constructor();
|
|
7
|
+
private registerBuiltInConditions;
|
|
8
|
+
private registerBuiltInActions;
|
|
9
|
+
private registerBuiltInReporters;
|
|
10
|
+
registerCondition(name: string, definition: ConditionDefinition): void;
|
|
11
|
+
registerAction(name: string, definition: ActionDefinition): void;
|
|
12
|
+
registerReporter(name: string, definition: ReporterDefinition): void;
|
|
13
|
+
hasCondition(type: string): boolean;
|
|
14
|
+
hasAction(type: string): boolean;
|
|
15
|
+
hasReporter(type: string): boolean;
|
|
16
|
+
evaluateCondition(config: ConditionConfig, context: ExecutionContext, file: FileInput): Promise<ConditionResult>;
|
|
17
|
+
executeAction(config: ActionConfig, context: ExecutionContext, conditionResult: ConditionResult, file: FileInput): Promise<ActionResult>;
|
|
18
|
+
format(findings: Finding[], format: ReporterFormat, options?: FormatOptions): string | Promise<string>;
|
|
19
|
+
getConditionNames(): string[];
|
|
20
|
+
getActionNames(): string[];
|
|
21
|
+
getReporterNames(): string[];
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/engine/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,YAAY,EACZ,OAAO,EACP,aAAa,EACd,MAAM,mBAAmB,CAAC;AAmB3B,qBAAa,QAAQ;IACnB,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,SAAS,CAA8C;;IAQ/D,OAAO,CAAC,yBAAyB;IASjC,OAAO,CAAC,sBAAsB;IAO9B,OAAO,CAAC,wBAAwB;IAQhC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,mBAAmB,GAAG,IAAI;IAItE,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,GAAG,IAAI;IAIhE,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB,GAAG,IAAI;IAIpE,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAInC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIhC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI5B,iBAAiB,CACrB,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,eAAe,CAAC;IAoBrB,aAAa,CACjB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,gBAAgB,EACzB,eAAe,EAAE,eAAe,EAChC,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,YAAY,CAAC;IAcxB,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IActG,iBAAiB,IAAI,MAAM,EAAE;IAI7B,cAAc,IAAI,MAAM,EAAE;IAI1B,gBAAgB,IAAI,MAAM,EAAE;CAG7B"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { matchFileExtension } from '../utils/regex.js';
|
|
2
|
+
import { RegistryError } from '../utils/errors.js';
|
|
3
|
+
import { regexCondition, comparisonCondition, existsCondition, compositeCondition, mathCondition, arrayCondition } from './conditions/index.js';
|
|
4
|
+
import { flagAction, blockAction, transformAction, notifyAction } from './actions/index.js';
|
|
5
|
+
import { builtInReporters } from './reporters/index.js';
|
|
6
|
+
export class Registry {
|
|
7
|
+
conditions = new Map();
|
|
8
|
+
actions = new Map();
|
|
9
|
+
reporters = new Map();
|
|
10
|
+
constructor() {
|
|
11
|
+
this.registerBuiltInConditions();
|
|
12
|
+
this.registerBuiltInActions();
|
|
13
|
+
this.registerBuiltInReporters();
|
|
14
|
+
}
|
|
15
|
+
registerBuiltInConditions() {
|
|
16
|
+
this.registerCondition('regex', regexCondition);
|
|
17
|
+
this.registerCondition('comparison', comparisonCondition);
|
|
18
|
+
this.registerCondition('exists', existsCondition);
|
|
19
|
+
this.registerCondition('composite', compositeCondition);
|
|
20
|
+
this.registerCondition('math', mathCondition);
|
|
21
|
+
this.registerCondition('array', arrayCondition);
|
|
22
|
+
}
|
|
23
|
+
registerBuiltInActions() {
|
|
24
|
+
this.registerAction('flag', flagAction);
|
|
25
|
+
this.registerAction('block', blockAction);
|
|
26
|
+
this.registerAction('transform', transformAction);
|
|
27
|
+
this.registerAction('notify', notifyAction);
|
|
28
|
+
}
|
|
29
|
+
registerBuiltInReporters() {
|
|
30
|
+
// Register all built-in reporters from separate module
|
|
31
|
+
for (const [name, reporter] of Object.entries(builtInReporters)) {
|
|
32
|
+
this.registerReporter(name, reporter);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Public methods for custom registration
|
|
36
|
+
registerCondition(name, definition) {
|
|
37
|
+
this.conditions.set(name, definition);
|
|
38
|
+
}
|
|
39
|
+
registerAction(name, definition) {
|
|
40
|
+
this.actions.set(name, definition);
|
|
41
|
+
}
|
|
42
|
+
registerReporter(name, definition) {
|
|
43
|
+
this.reporters.set(name, definition);
|
|
44
|
+
}
|
|
45
|
+
hasCondition(type) {
|
|
46
|
+
return this.conditions.has(type);
|
|
47
|
+
}
|
|
48
|
+
hasAction(type) {
|
|
49
|
+
return this.actions.has(type);
|
|
50
|
+
}
|
|
51
|
+
hasReporter(type) {
|
|
52
|
+
return this.reporters.has(type);
|
|
53
|
+
}
|
|
54
|
+
async evaluateCondition(config, context, file) {
|
|
55
|
+
// Check file extension filter
|
|
56
|
+
if (!matchFileExtension(file.path, config.fileExtensions)) {
|
|
57
|
+
return { matched: false };
|
|
58
|
+
}
|
|
59
|
+
const definition = this.conditions.get(config.type);
|
|
60
|
+
if (!definition) {
|
|
61
|
+
throw new RegistryError(`Unknown condition type: '${config.type}' for file '${file.path}'. ` +
|
|
62
|
+
`Available types: ${Array.from(this.conditions.keys()).join(', ')}`, config.type, Array.from(this.conditions.keys()));
|
|
63
|
+
}
|
|
64
|
+
// Pass registry reference to conditions that need it (like composite)
|
|
65
|
+
return definition.evaluate(config, context, file, this);
|
|
66
|
+
}
|
|
67
|
+
async executeAction(config, context, conditionResult, file) {
|
|
68
|
+
const definition = this.actions.get(config.type);
|
|
69
|
+
if (!definition) {
|
|
70
|
+
throw new RegistryError(`Unknown action type: '${config.type}' for file '${file.path}'. ` +
|
|
71
|
+
`Available types: ${Array.from(this.actions.keys()).join(', ')}`, config.type, Array.from(this.actions.keys()));
|
|
72
|
+
}
|
|
73
|
+
return definition.execute(config, context, conditionResult, file);
|
|
74
|
+
}
|
|
75
|
+
format(findings, format, options) {
|
|
76
|
+
const definition = this.reporters.get(format);
|
|
77
|
+
if (!definition) {
|
|
78
|
+
throw new RegistryError(`Unknown reporter format: '${format}'. ` +
|
|
79
|
+
`Available formats: ${Array.from(this.reporters.keys()).join(', ')}`, format, Array.from(this.reporters.keys()));
|
|
80
|
+
}
|
|
81
|
+
return definition.format(findings, options);
|
|
82
|
+
}
|
|
83
|
+
getConditionNames() {
|
|
84
|
+
return Array.from(this.conditions.keys());
|
|
85
|
+
}
|
|
86
|
+
getActionNames() {
|
|
87
|
+
return Array.from(this.actions.keys());
|
|
88
|
+
}
|
|
89
|
+
getReporterNames() {
|
|
90
|
+
return Array.from(this.reporters.keys());
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=registry.js.map
|