@aspect-guard/core 0.5.0 → 0.5.2

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/dist/index.d.ts CHANGED
@@ -160,6 +160,11 @@ declare class ExtensionGuardScanner {
160
160
  private hashDatabase;
161
161
  constructor(options?: Partial<ScanOptions>);
162
162
  scan(options?: Partial<ScanOptions>): Promise<FullScanReport>;
163
+ /**
164
+ * Scan multiple extensions concurrently with a configurable pool size.
165
+ * Uses a simple semaphore pattern to limit concurrent operations.
166
+ */
167
+ private scanExtensionsConcurrently;
163
168
  private scanExtension;
164
169
  private calculateTrustScore;
165
170
  private calculateRiskLevel;
@@ -260,6 +265,77 @@ declare class RuleRegistry {
260
265
  }
261
266
  declare const ruleRegistry: RuleRegistry;
262
267
 
268
+ /**
269
+ * Shared pattern matching utilities for detection rules.
270
+ * Reduces code duplication across rules and improves maintainability.
271
+ */
272
+
273
+ /**
274
+ * Pattern definition for matching in file content
275
+ */
276
+ interface MatchPattern {
277
+ /** Name of the pattern for evidence reporting */
278
+ name: string;
279
+ /** Regex pattern (should have 'g' flag for multiple matches) */
280
+ pattern: RegExp;
281
+ /** If specified, use this capture group for the matched value */
282
+ matchGroup?: number;
283
+ }
284
+ /**
285
+ * Options for file filtering
286
+ */
287
+ interface FileFilterOptions {
288
+ /** File extensions to include (e.g., ['.js', '.ts']) */
289
+ extensions?: string[];
290
+ /** Regex patterns to exclude files */
291
+ excludePatterns?: RegExp[];
292
+ }
293
+ /**
294
+ * Options for pattern matching
295
+ */
296
+ interface MatchOptions {
297
+ /** Maximum length for snippet in evidence */
298
+ maxSnippetLength?: number;
299
+ /** Function to validate matched value (return false to skip) */
300
+ validate?: (value: string, content: string, matchIndex: number) => boolean;
301
+ }
302
+ /** Default code file extensions */
303
+ declare const CODE_EXTENSIONS: string[];
304
+ /** Simple JS/TS extensions */
305
+ declare const JS_TS_EXTENSIONS: string[];
306
+ /**
307
+ * Check if a file should be processed based on extension
308
+ */
309
+ declare function hasExtension(filePath: string, extensions: string[]): boolean;
310
+ /**
311
+ * Check if a file matches any exclusion pattern
312
+ */
313
+ declare function isExcluded(filePath: string, patterns: RegExp[]): boolean;
314
+ /**
315
+ * Get line number from content index (1-based)
316
+ */
317
+ declare function getLineNumber(content: string, index: number): number;
318
+ /**
319
+ * Get line content at a specific line number (1-based)
320
+ */
321
+ declare function getLineContent(lines: string[], lineNumber: number): string;
322
+ /**
323
+ * Check if an index position is inside a comment
324
+ */
325
+ declare function isInComment(content: string, matchIndex: number): boolean;
326
+ /**
327
+ * Match all patterns in a single file and generate evidence
328
+ */
329
+ declare function matchPatternsInFile(filePath: string, content: string, patterns: MatchPattern[], options?: MatchOptions): Evidence[];
330
+ /**
331
+ * Match patterns across all files with filtering
332
+ */
333
+ declare function matchPatternsInFiles(files: Map<string, string>, patterns: MatchPattern[], filterOptions?: FileFilterOptions, matchOptions?: MatchOptions): Evidence[];
334
+ /**
335
+ * Check if content within a context window matches a pattern
336
+ */
337
+ declare function hasPatternInContext(content: string, matchIndex: number, matchLength: number, contextPattern: RegExp, contextWindow?: number): boolean;
338
+
263
339
  declare function registerBuiltInRules(): void;
264
340
 
265
341
  /**
@@ -747,6 +823,6 @@ declare function generateBaseline(_extensionPaths: string[], _outputPath?: strin
747
823
  errors: string[];
748
824
  }>;
749
825
 
750
- declare const VERSION = "0.5.0";
826
+ declare const VERSION = "0.5.2";
751
827
 
752
- export { ALL_POPULAR_EXTENSIONS, type AdjustFindingsOptions, type AuditReport, type BundleDetectionResult, DETECTION_RULES, type DetectedIDE, type DetectionRule, type Evidence, type ExtensionCategory, ExtensionGuardScanner, type ExtensionHash, type ExtensionInfo, type ExtensionManifest, type Finding, type FindingCategory, type FullScanReport, type HashDatabase, IDE_PATHS, type InspectOptions, type IntegrityInfo, type IntegrityResult, type IntegrityStatus, JsonReporter, MEGA_POPULAR_EXTENSIONS, MarkdownReporter, POPULAR_EXTENSIONS, type PolicyAction, type PolicyConfig, PolicyEngine, type PolicyRules, type PolicyViolation, type PopularExtension, type Reporter, type ReporterOptions, type RiskLevel, RuleEngine, type RuleEngineOptions, SEVERITY_ORDER, SarifReporter, type ScanOptions, type ScanResult, type ScanSummary, type Severity, TRUSTED_EXTENSION_IDS, TRUSTED_PUBLISHERS, VERIFIED_PUBLISHERS, VERSION, addHash, adjustFindings, categorizeExtension, clearHashCache, collectFiles, compareSeverity, computeExtensionHashes, createHashRecord, detectBundle, detectIDEPaths, expandPath, generateBaseline, getDefaultDatabasePath, getHash, getIDEExtensionPath, getPopularityTier, getSupportedIDEs, isAtLeastSeverity, isBundleOutputPath, isIDEInstalled, isMegaPopular, isPopular, isTrustedExtension, isTrustedPublisher, isVerifiedPublisher, loadHashDatabase, loadPolicyConfig, readExtension, readExtensionsFromDirectory, registerBuiltInRules, ruleRegistry, saveHashDatabase, sha256, shouldCollectFile, shouldReduceSeverityForBundle, verifyIntegrity };
828
+ export { ALL_POPULAR_EXTENSIONS, type AdjustFindingsOptions, type AuditReport, type BundleDetectionResult, CODE_EXTENSIONS, DETECTION_RULES, type DetectedIDE, type DetectionRule, type Evidence, type ExtensionCategory, ExtensionGuardScanner, type ExtensionHash, type ExtensionInfo, type ExtensionManifest, type FileFilterOptions, type Finding, type FindingCategory, type FullScanReport, type HashDatabase, IDE_PATHS, type InspectOptions, type IntegrityInfo, type IntegrityResult, type IntegrityStatus, JS_TS_EXTENSIONS, JsonReporter, MEGA_POPULAR_EXTENSIONS, MarkdownReporter, type MatchOptions, type MatchPattern, POPULAR_EXTENSIONS, type PolicyAction, type PolicyConfig, PolicyEngine, type PolicyRules, type PolicyViolation, type PopularExtension, type Reporter, type ReporterOptions, type RiskLevel, RuleEngine, type RuleEngineOptions, SEVERITY_ORDER, SarifReporter, type ScanOptions, type ScanResult, type ScanSummary, type Severity, TRUSTED_EXTENSION_IDS, TRUSTED_PUBLISHERS, VERIFIED_PUBLISHERS, VERSION, addHash, adjustFindings, categorizeExtension, clearHashCache, collectFiles, compareSeverity, computeExtensionHashes, createHashRecord, detectBundle, detectIDEPaths, expandPath, generateBaseline, getDefaultDatabasePath, getHash, getIDEExtensionPath, getLineContent, getLineNumber, getPopularityTier, getSupportedIDEs, hasExtension, hasPatternInContext, isAtLeastSeverity, isBundleOutputPath, isExcluded, isIDEInstalled, isInComment, isMegaPopular, isPopular, isTrustedExtension, isTrustedPublisher, isVerifiedPublisher, loadHashDatabase, loadPolicyConfig, matchPatternsInFile, matchPatternsInFiles, readExtension, readExtensionsFromDirectory, registerBuiltInRules, ruleRegistry, saveHashDatabase, sha256, shouldCollectFile, shouldReduceSeverityForBundle, verifyIntegrity };
package/dist/index.js CHANGED
@@ -1110,8 +1110,89 @@ var critDataExfiltration = {
1110
1110
  }
1111
1111
  };
1112
1112
 
1113
+ // src/rules/pattern-matcher.ts
1114
+ var CODE_EXTENSIONS = [".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs"];
1115
+ var JS_TS_EXTENSIONS = [".js", ".ts"];
1116
+ function hasExtension(filePath, extensions) {
1117
+ return extensions.some((ext) => filePath.endsWith(ext));
1118
+ }
1119
+ function isExcluded(filePath, patterns) {
1120
+ return patterns.some((pattern) => pattern.test(filePath));
1121
+ }
1122
+ function getLineNumber(content, index) {
1123
+ return content.slice(0, index).split("\n").length;
1124
+ }
1125
+ function getLineContent(lines, lineNumber) {
1126
+ return lines[lineNumber - 1]?.trim() ?? "";
1127
+ }
1128
+ function isInComment(content, matchIndex) {
1129
+ const lineStart = content.lastIndexOf("\n", matchIndex) + 1;
1130
+ const lineContent = content.slice(lineStart, matchIndex);
1131
+ if (lineContent.includes("//")) {
1132
+ return true;
1133
+ }
1134
+ const beforeMatch = content.slice(0, matchIndex);
1135
+ const lastBlockStart = beforeMatch.lastIndexOf("/*");
1136
+ const lastBlockEnd = beforeMatch.lastIndexOf("*/");
1137
+ return lastBlockStart > lastBlockEnd;
1138
+ }
1139
+ function matchPatternsInFile(filePath, content, patterns, options = {}) {
1140
+ const evidences = [];
1141
+ const lines = content.split("\n");
1142
+ const maxSnippetLength = options.maxSnippetLength ?? 100;
1143
+ for (const { name, pattern, matchGroup } of patterns) {
1144
+ pattern.lastIndex = 0;
1145
+ let match;
1146
+ while ((match = pattern.exec(content)) !== null) {
1147
+ const matchIndex = match.index;
1148
+ const matchedValue = matchGroup !== void 0 ? match[matchGroup] : match[0];
1149
+ if (!matchedValue) {
1150
+ continue;
1151
+ }
1152
+ if (options.validate && !options.validate(matchedValue, content, matchIndex)) {
1153
+ continue;
1154
+ }
1155
+ const lineNumber = getLineNumber(content, matchIndex);
1156
+ const lineContent = getLineContent(lines, lineNumber);
1157
+ evidences.push({
1158
+ filePath,
1159
+ lineNumber,
1160
+ lineContent: lineContent.length > maxSnippetLength ? lineContent.slice(0, maxSnippetLength) + "..." : lineContent,
1161
+ matchedPattern: name,
1162
+ snippet: matchedValue.length > maxSnippetLength ? matchedValue.slice(0, maxSnippetLength) + "..." : matchedValue
1163
+ });
1164
+ }
1165
+ }
1166
+ return evidences;
1167
+ }
1168
+ function matchPatternsInFiles(files, patterns, filterOptions = {}, matchOptions = {}) {
1169
+ const evidences = [];
1170
+ const extensions = filterOptions.extensions ?? JS_TS_EXTENSIONS;
1171
+ const excludePatterns = filterOptions.excludePatterns ?? [];
1172
+ for (const [filePath, content] of files) {
1173
+ if (!hasExtension(filePath, extensions)) {
1174
+ continue;
1175
+ }
1176
+ if (excludePatterns.length > 0 && isExcluded(filePath, excludePatterns)) {
1177
+ continue;
1178
+ }
1179
+ if (!content || content.trim().length === 0) {
1180
+ continue;
1181
+ }
1182
+ const fileEvidences = matchPatternsInFile(filePath, content, patterns, matchOptions);
1183
+ evidences.push(...fileEvidences);
1184
+ }
1185
+ return evidences;
1186
+ }
1187
+ function hasPatternInContext(content, matchIndex, matchLength, contextPattern, contextWindow = 200) {
1188
+ const startIndex = Math.max(0, matchIndex - contextWindow);
1189
+ const endIndex = Math.min(content.length, matchIndex + matchLength + contextWindow);
1190
+ const context = content.slice(startIndex, endIndex);
1191
+ return contextPattern.test(context);
1192
+ }
1193
+
1113
1194
  // src/rules/built-in/crit-remote-execution.ts
1114
- var DANGEROUS_PATTERNS = [
1195
+ var PATTERNS = [
1115
1196
  { name: "eval", pattern: /\beval\s*\(/g },
1116
1197
  { name: "Function-constructor", pattern: /new\s+Function\s*\(/g },
1117
1198
  {
@@ -1124,9 +1205,9 @@ var DANGEROUS_PATTERNS = [
1124
1205
  },
1125
1206
  { name: "child_process-spawn-shell", pattern: /\.spawn\s*\([^)]*\{[^}]*shell\s*:\s*true/g },
1126
1207
  { name: "vm-runInContext", pattern: /vm\.run(?:InContext|InNewContext|InThisContext)\s*\(/g },
1127
- { name: "vm-Script", pattern: /new\s+vm\.Script\s*\(/g }
1208
+ { name: "vm-Script", pattern: /new\s+vm\.Script\s*\(/g },
1209
+ { name: "dynamic-require", pattern: /require\s*\(\s*(?:[^'"`\s)]|`[^`]*\$\{)/g }
1128
1210
  ];
1129
- var DYNAMIC_REQUIRE = /require\s*\(\s*(?:[^'"`\s)]|`[^`]*\$\{)/g;
1130
1211
  var critRemoteExecution = {
1131
1212
  id: "EG-CRIT-002",
1132
1213
  name: "Remote Code Execution",
@@ -1136,40 +1217,7 @@ var critRemoteExecution = {
1136
1217
  mitreAttackId: "T1059",
1137
1218
  enabled: true,
1138
1219
  detect(files, _manifest) {
1139
- const evidences = [];
1140
- for (const [filePath, content] of files) {
1141
- if (!filePath.endsWith(".js") && !filePath.endsWith(".ts")) {
1142
- continue;
1143
- }
1144
- const lines = content.split("\n");
1145
- for (const { name, pattern } of DANGEROUS_PATTERNS) {
1146
- pattern.lastIndex = 0;
1147
- let match2;
1148
- while ((match2 = pattern.exec(content)) !== null) {
1149
- const lineNumber = content.slice(0, match2.index).split("\n").length;
1150
- evidences.push({
1151
- filePath,
1152
- lineNumber,
1153
- lineContent: lines[lineNumber - 1]?.trim(),
1154
- matchedPattern: name,
1155
- snippet: match2[0]
1156
- });
1157
- }
1158
- }
1159
- DYNAMIC_REQUIRE.lastIndex = 0;
1160
- let match;
1161
- while ((match = DYNAMIC_REQUIRE.exec(content)) !== null) {
1162
- const lineNumber = content.slice(0, match.index).split("\n").length;
1163
- evidences.push({
1164
- filePath,
1165
- lineNumber,
1166
- lineContent: lines[lineNumber - 1]?.trim(),
1167
- matchedPattern: "dynamic-require",
1168
- snippet: match[0]
1169
- });
1170
- }
1171
- }
1172
- return evidences;
1220
+ return matchPatternsInFiles(files, PATTERNS);
1173
1221
  }
1174
1222
  };
1175
1223
 
@@ -1199,41 +1247,40 @@ var critCredentialAccess = {
1199
1247
  mitreAttackId: "T1552.004",
1200
1248
  enabled: true,
1201
1249
  detect(files, _manifest) {
1202
- const evidences = [];
1203
- for (const [filePath, content] of files) {
1204
- if (!filePath.endsWith(".js") && !filePath.endsWith(".ts")) {
1205
- continue;
1250
+ return matchPatternsInFiles(
1251
+ files,
1252
+ SENSITIVE_PATHS,
1253
+ {},
1254
+ {
1255
+ validate: (value, content, matchIndex) => hasPatternInContext(content, matchIndex, value.length, FILE_READ_CONTEXT, 200)
1206
1256
  }
1207
- const lines = content.split("\n");
1208
- for (const { name, pattern } of SENSITIVE_PATHS) {
1209
- pattern.lastIndex = 0;
1210
- let match;
1211
- while ((match = pattern.exec(content)) !== null) {
1212
- const startIndex = Math.max(0, match.index - 200);
1213
- const endIndex = Math.min(content.length, match.index + match[0].length + 200);
1214
- const context = content.slice(startIndex, endIndex);
1215
- if (FILE_READ_CONTEXT.test(context)) {
1216
- const lineNumber = content.slice(0, match.index).split("\n").length;
1217
- evidences.push({
1218
- filePath,
1219
- lineNumber,
1220
- lineContent: lines[lineNumber - 1]?.trim(),
1221
- matchedPattern: name,
1222
- snippet: match[0]
1223
- });
1224
- }
1225
- }
1226
- }
1227
- }
1228
- return evidences;
1257
+ );
1229
1258
  }
1230
1259
  };
1231
1260
 
1232
1261
  // src/rules/built-in/high-suspicious-network.ts
1233
- var HTTP_TO_IP = /(?:fetch|axios(?:\.(?:get|post|put|delete|request))?|https?\.(?:get|post|request)|XMLHttpRequest)\s*\([^)]*['"`]https?:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/g;
1234
- var DYNAMIC_URL = /(?:fetch|axios|https?\.request)\s*\(\s*(?:`[^`]*\$\{|['"][^'"]*['"]\s*\+\s*\w)/g;
1235
- var WEBSOCKET_TO_IP = /new\s+WebSocket\s*\(\s*['"`]wss?:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/g;
1236
- var UNUSUAL_PORTS = /['"`]https?:\/\/[^'"`:]+:(?!443|80|8080|3000|8443|5000)[0-9]{2,5}/g;
1262
+ var PATTERNS2 = [
1263
+ // HTTP requests to IP addresses instead of domains
1264
+ {
1265
+ name: "http-to-ip",
1266
+ pattern: /(?:fetch|axios(?:\.(?:get|post|put|delete|request))?|https?\.(?:get|post|request)|XMLHttpRequest)\s*\([^)]*['"`]https?:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/g
1267
+ },
1268
+ // Dynamic URL construction (template literals or concatenation)
1269
+ {
1270
+ name: "dynamic-url",
1271
+ pattern: /(?:fetch|axios|https?\.request)\s*\(\s*(?:`[^`]*\$\{|['"][^'"]*['"]\s*\+\s*\w)/g
1272
+ },
1273
+ // WebSocket connections to IP addresses
1274
+ {
1275
+ name: "websocket-to-ip",
1276
+ pattern: /new\s+WebSocket\s*\(\s*['"`]wss?:\/\/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/g
1277
+ },
1278
+ // Unusual ports
1279
+ {
1280
+ name: "unusual-port",
1281
+ pattern: /['"`]https?:\/\/[^'"`:]+:(?!443|80|8080|3000|8443|5000)[0-9]{2,5}/g
1282
+ }
1283
+ ];
1237
1284
  var highSuspiciousNetwork = {
1238
1285
  id: "EG-HIGH-002",
1239
1286
  name: "Suspicious Network Activity",
@@ -1243,34 +1290,7 @@ var highSuspiciousNetwork = {
1243
1290
  mitreAttackId: "T1071",
1244
1291
  enabled: true,
1245
1292
  detect(files, _manifest) {
1246
- const evidences = [];
1247
- for (const [filePath, content] of files) {
1248
- if (!filePath.endsWith(".js") && !filePath.endsWith(".ts")) {
1249
- continue;
1250
- }
1251
- const lines = content.split("\n");
1252
- const patterns = [
1253
- { pattern: HTTP_TO_IP, name: "http-to-ip" },
1254
- { pattern: DYNAMIC_URL, name: "dynamic-url" },
1255
- { pattern: WEBSOCKET_TO_IP, name: "websocket-to-ip" },
1256
- { pattern: UNUSUAL_PORTS, name: "unusual-port" }
1257
- ];
1258
- for (const { pattern, name } of patterns) {
1259
- pattern.lastIndex = 0;
1260
- let match;
1261
- while ((match = pattern.exec(content)) !== null) {
1262
- const lineNumber = content.slice(0, match.index).split("\n").length;
1263
- evidences.push({
1264
- filePath,
1265
- lineNumber,
1266
- lineContent: lines[lineNumber - 1]?.trim(),
1267
- matchedPattern: name,
1268
- snippet: match[0].slice(0, 100)
1269
- });
1270
- }
1271
- }
1272
- }
1273
- return evidences;
1293
+ return matchPatternsInFiles(files, PATTERNS2);
1274
1294
  }
1275
1295
  };
1276
1296
 
@@ -1496,23 +1516,6 @@ function calculateSecretEntropy(str) {
1496
1516
  }
1497
1517
  return entropy;
1498
1518
  }
1499
- function isInComment(content, matchIndex) {
1500
- const lineStart = content.lastIndexOf("\n", matchIndex) + 1;
1501
- const lineContent = content.slice(lineStart, matchIndex);
1502
- if (lineContent.includes("//")) {
1503
- return true;
1504
- }
1505
- const beforeMatch = content.slice(0, matchIndex);
1506
- const lastBlockStart = beforeMatch.lastIndexOf("/*");
1507
- const lastBlockEnd = beforeMatch.lastIndexOf("*/");
1508
- if (lastBlockStart > lastBlockEnd) {
1509
- return true;
1510
- }
1511
- return false;
1512
- }
1513
- function getLineNumber(content, index) {
1514
- return content.slice(0, index).split("\n").length;
1515
- }
1516
1519
  var highHardcodedSecret = {
1517
1520
  id: "EG-HIGH-006",
1518
1521
  name: "Hardcoded Secrets",
@@ -2178,11 +2181,8 @@ var ExtensionGuardScanner = class {
2178
2181
  }
2179
2182
  ide.extensionCount = allExtensions[i].length;
2180
2183
  }
2181
- const results = [];
2182
- for (const { ext } of extensionMap.values()) {
2183
- const result = await this.scanExtension(ext);
2184
- results.push(result);
2185
- }
2184
+ const extensions = Array.from(extensionMap.values()).map(({ ext }) => ext);
2185
+ const results = await this.scanExtensionsConcurrently(extensions, mergedOptions.concurrency);
2186
2186
  const summary = this.calculateSummary(results);
2187
2187
  return {
2188
2188
  scanId: randomUUID2(),
@@ -2199,6 +2199,29 @@ var ExtensionGuardScanner = class {
2199
2199
  scanDurationMs: Date.now() - startTime
2200
2200
  };
2201
2201
  }
2202
+ /**
2203
+ * Scan multiple extensions concurrently with a configurable pool size.
2204
+ * Uses a simple semaphore pattern to limit concurrent operations.
2205
+ */
2206
+ async scanExtensionsConcurrently(extensions, concurrency) {
2207
+ const results = new Array(extensions.length);
2208
+ let currentIndex = 0;
2209
+ const worker = async () => {
2210
+ while (currentIndex < extensions.length) {
2211
+ const index = currentIndex++;
2212
+ const ext = extensions[index];
2213
+ if (ext) {
2214
+ results[index] = await this.scanExtension(ext);
2215
+ }
2216
+ }
2217
+ };
2218
+ const workers = Array.from(
2219
+ { length: Math.min(concurrency, extensions.length) },
2220
+ () => worker()
2221
+ );
2222
+ await Promise.all(workers);
2223
+ return results.filter((r) => r !== void 0);
2224
+ }
2202
2225
  async scanExtension(ext) {
2203
2226
  const startTime = Date.now();
2204
2227
  const files = await collectFiles(ext.installPath);
@@ -2996,12 +3019,14 @@ var PolicyEngine = class {
2996
3019
  };
2997
3020
 
2998
3021
  // src/index.ts
2999
- var VERSION = "0.5.0";
3022
+ var VERSION = "0.5.2";
3000
3023
  export {
3001
3024
  ALL_POPULAR_EXTENSIONS,
3025
+ CODE_EXTENSIONS,
3002
3026
  DETECTION_RULES,
3003
3027
  ExtensionGuardScanner,
3004
3028
  IDE_PATHS,
3029
+ JS_TS_EXTENSIONS,
3005
3030
  JsonReporter,
3006
3031
  MEGA_POPULAR_EXTENSIONS,
3007
3032
  MarkdownReporter,
@@ -3029,11 +3054,17 @@ export {
3029
3054
  getDefaultDatabasePath,
3030
3055
  getHash,
3031
3056
  getIDEExtensionPath,
3057
+ getLineContent,
3058
+ getLineNumber,
3032
3059
  getPopularityTier,
3033
3060
  getSupportedIDEs,
3061
+ hasExtension,
3062
+ hasPatternInContext,
3034
3063
  isAtLeastSeverity,
3035
3064
  isBundleOutputPath,
3065
+ isExcluded,
3036
3066
  isIDEInstalled,
3067
+ isInComment,
3037
3068
  isMegaPopular,
3038
3069
  isPopular,
3039
3070
  isTrustedExtension,
@@ -3041,6 +3072,8 @@ export {
3041
3072
  isVerifiedPublisher,
3042
3073
  loadHashDatabase,
3043
3074
  loadPolicyConfig,
3075
+ matchPatternsInFile,
3076
+ matchPatternsInFiles,
3044
3077
  readExtension,
3045
3078
  readExtensionsFromDirectory,
3046
3079
  registerBuiltInRules,