circle-ir 3.2.0 → 3.3.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.
@@ -1,198 +1,125 @@
1
1
  /**
2
- * Centralized logging module using pino.
2
+ * Centralized logging module with dependency injection.
3
+ *
4
+ * By default uses a simple console-based logger (zero dependencies).
5
+ * Consumers can inject a custom logger (e.g. pino) via setLogger().
3
6
  *
4
7
  * Usage:
5
8
  * import { logger } from './utils/logger.js';
6
9
  * logger.info('Processing file', { file: 'test.java' });
7
10
  * logger.error('Failed to parse', { error: err.message });
8
11
  *
12
+ * Injecting a custom logger (e.g. from circle-pack):
13
+ * import pino from 'pino';
14
+ * import { setLogger } from 'circle-ir';
15
+ * setLogger(pino({ level: 'debug' }));
16
+ *
9
17
  * Log Levels (in order of severity):
10
18
  * - trace: Very detailed debugging
11
19
  * - debug: Debugging information
12
- * - info: General information (default for CLI)
20
+ * - info: General information (default)
13
21
  * - warn: Warnings
14
22
  * - error: Errors
15
23
  * - fatal: Fatal errors
16
24
  * - silent: No logging
17
- *
18
- * Configuration:
19
- * - Set LOG_LEVEL env var to change level
20
- * - Set LOG_FORMAT=json for JSON output (default in non-TTY)
21
- * - Set LOG_FORMAT=pretty for human-readable output
22
25
  */
23
- import pino from 'pino';
24
- // Default configuration
25
- const DEFAULT_CONFIG = {
26
- level: process.env.LOG_LEVEL || 'info',
27
- pretty: process.env.LOG_FORMAT === 'pretty' || (process.stdout.isTTY && process.env.LOG_FORMAT !== 'json'),
28
- name: 'circle-ir',
26
+ const LOG_LEVELS = {
27
+ trace: 0,
28
+ debug: 1,
29
+ info: 2,
30
+ warn: 3,
31
+ error: 4,
32
+ fatal: 5,
33
+ silent: 6,
29
34
  };
30
- let currentConfig = { ...DEFAULT_CONFIG };
31
- let loggerInstance = null;
32
- /**
33
- * Create pino logger options from config
34
- */
35
- function createLoggerOptions(config) {
36
- const options = {
37
- name: config.name,
38
- level: config.level || 'info',
39
- };
40
- // Add pretty printing for TTY or when explicitly requested
41
- if (config.pretty) {
42
- options.transport = {
43
- target: 'pino-pretty',
44
- options: {
45
- colorize: true,
46
- translateTime: 'SYS:standard',
47
- ignore: 'pid,hostname',
48
- messageFormat: '{msg}',
49
- singleLine: true,
50
- },
51
- };
52
- }
53
- return options;
35
+ let currentLevel = 'info';
36
+ let customLogger = null;
37
+ function shouldLog(level) {
38
+ return LOG_LEVELS[level] >= LOG_LEVELS[currentLevel];
54
39
  }
55
40
  /**
56
- * Get the singleton logger instance
41
+ * Configure the logger. Should be called early in application startup.
57
42
  */
58
- function getLogger() {
59
- if (!loggerInstance) {
60
- const options = createLoggerOptions(currentConfig);
61
- // Write to stderr to avoid polluting stdout for CLI tools
62
- if (options.transport) {
63
- // When using transport (pino-pretty), specify destination in options
64
- options.transport.options = {
65
- ...options.transport.options,
66
- destination: 2, // stderr file descriptor
67
- };
68
- loggerInstance = pino(options);
69
- }
70
- else {
71
- loggerInstance = pino(options, process.stderr);
72
- }
43
+ export function configureLogger(config) {
44
+ if (config.level) {
45
+ currentLevel = config.level;
73
46
  }
74
- return loggerInstance;
75
47
  }
76
48
  /**
77
- * Configure the logger. Should be called early in application startup.
78
- * Subsequent calls will reconfigure the logger.
49
+ * Inject a custom logger implementation (e.g. pino).
50
+ * The custom logger receives all log calls regardless of level filtering —
51
+ * it is expected to handle its own level filtering.
79
52
  */
80
- export function configureLogger(config) {
81
- currentConfig = { ...currentConfig, ...config };
82
- const options = createLoggerOptions(currentConfig);
83
- // Write to stderr to avoid polluting stdout for CLI tools
84
- if (options.transport) {
85
- options.transport.options = {
86
- ...options.transport.options,
87
- destination: 2, // stderr file descriptor
88
- };
89
- loggerInstance = pino(options);
90
- }
91
- else {
92
- loggerInstance = pino(options, process.stderr);
93
- }
53
+ export function setLogger(instance) {
54
+ customLogger = instance;
94
55
  }
95
56
  /**
96
57
  * Set the log level dynamically
97
58
  */
98
59
  export function setLogLevel(level) {
99
- currentConfig.level = level;
100
- if (loggerInstance) {
101
- loggerInstance.level = level;
102
- }
60
+ currentLevel = level;
103
61
  }
104
62
  /**
105
63
  * Get the current log level
106
64
  */
107
65
  export function getLogLevel() {
108
- return currentConfig.level || 'info';
109
- }
110
- /**
111
- * Create a child logger with additional context
112
- */
113
- export function createChildLogger(bindings) {
114
- return getLogger().child(bindings);
66
+ return currentLevel;
115
67
  }
116
68
  /**
117
69
  * The main logger instance.
118
70
  * Use this for all logging throughout the application.
119
71
  */
120
72
  export const logger = {
121
- /**
122
- * Log at trace level (most verbose)
123
- */
124
73
  trace: (msg, obj) => {
125
- if (obj) {
126
- getLogger().trace(obj, msg);
127
- }
128
- else {
129
- getLogger().trace(msg);
74
+ if (customLogger) {
75
+ customLogger.trace(msg, obj);
76
+ return;
130
77
  }
78
+ if (shouldLog('trace'))
79
+ console.debug(obj ? `[TRACE] ${msg} ${JSON.stringify(obj)}` : `[TRACE] ${msg}`);
131
80
  },
132
- /**
133
- * Log at debug level
134
- */
135
81
  debug: (msg, obj) => {
136
- if (obj) {
137
- getLogger().debug(obj, msg);
138
- }
139
- else {
140
- getLogger().debug(msg);
82
+ if (customLogger) {
83
+ customLogger.debug(msg, obj);
84
+ return;
141
85
  }
86
+ if (shouldLog('debug'))
87
+ console.debug(obj ? `[DEBUG] ${msg} ${JSON.stringify(obj)}` : `[DEBUG] ${msg}`);
142
88
  },
143
- /**
144
- * Log at info level (default)
145
- */
146
89
  info: (msg, obj) => {
147
- if (obj) {
148
- getLogger().info(obj, msg);
149
- }
150
- else {
151
- getLogger().info(msg);
90
+ if (customLogger) {
91
+ customLogger.info(msg, obj);
92
+ return;
152
93
  }
94
+ if (shouldLog('info'))
95
+ console.log(obj ? `[INFO] ${msg} ${JSON.stringify(obj)}` : `[INFO] ${msg}`);
153
96
  },
154
- /**
155
- * Log at warn level
156
- */
157
97
  warn: (msg, obj) => {
158
- if (obj) {
159
- getLogger().warn(obj, msg);
160
- }
161
- else {
162
- getLogger().warn(msg);
98
+ if (customLogger) {
99
+ customLogger.warn(msg, obj);
100
+ return;
163
101
  }
102
+ if (shouldLog('warn'))
103
+ console.warn(obj ? `[WARN] ${msg} ${JSON.stringify(obj)}` : `[WARN] ${msg}`);
164
104
  },
165
- /**
166
- * Log at error level
167
- */
168
105
  error: (msg, obj) => {
169
- if (obj) {
170
- getLogger().error(obj, msg);
171
- }
172
- else {
173
- getLogger().error(msg);
106
+ if (customLogger) {
107
+ customLogger.error(msg, obj);
108
+ return;
174
109
  }
110
+ if (shouldLog('error'))
111
+ console.error(obj ? `[ERROR] ${msg} ${JSON.stringify(obj)}` : `[ERROR] ${msg}`);
175
112
  },
176
- /**
177
- * Log at fatal level (most severe)
178
- */
179
113
  fatal: (msg, obj) => {
180
- if (obj) {
181
- getLogger().fatal(obj, msg);
182
- }
183
- else {
184
- getLogger().fatal(msg);
114
+ if (customLogger) {
115
+ customLogger.fatal(msg, obj);
116
+ return;
185
117
  }
118
+ if (shouldLog('fatal'))
119
+ console.error(obj ? `[FATAL] ${msg} ${JSON.stringify(obj)}` : `[FATAL] ${msg}`);
186
120
  },
187
- /**
188
- * Create a child logger with additional context
189
- */
190
- child: (bindings) => createChildLogger(bindings),
191
- /**
192
- * Check if a level is enabled
193
- */
194
121
  isLevelEnabled: (level) => {
195
- return getLogger().isLevelEnabled(level);
122
+ return shouldLog(level);
196
123
  },
197
124
  };
198
125
  //# sourceMappingURL=logger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "circle-ir",
3
- "version": "3.2.0",
3
+ "version": "3.3.1",
4
4
  "description": "High-performance Static Application Security Testing (SAST) library for detecting security vulnerabilities through taint analysis",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -34,8 +34,8 @@
34
34
  "test:watch": "vitest",
35
35
  "test:coverage": "vitest run --coverage",
36
36
  "build": "tsc",
37
- "build:browser": "esbuild src/browser.ts --bundle --format=esm --platform=browser --external:fs --external:fs/promises --external:path --external:module --external:crypto --external:pino --outfile=dist/browser/circle-ir.js && mkdir -p dist/wasm && cp node_modules/web-tree-sitter/web-tree-sitter.wasm dist/wasm/ && cp wasm/*.wasm dist/wasm/",
38
- "build:core": "esbuild src/core-lib.ts --bundle --format=esm --platform=neutral --external:fs --external:fs/promises --external:path --external:module --external:pino --external:crypto --outfile=dist/core/circle-ir-core.js && esbuild src/core-lib.ts --bundle --format=cjs --platform=neutral --external:fs --external:fs/promises --external:path --external:module --external:pino --external:crypto --outfile=dist/core/circle-ir-core.cjs && cp dist/core-lib.d.ts dist/core/circle-ir-core.d.ts",
37
+ "build:browser": "esbuild src/browser.ts --bundle --format=esm --platform=browser --external:fs --external:fs/promises --external:path --external:module --external:crypto --outfile=dist/browser/circle-ir.js && mkdir -p dist/wasm && cp node_modules/web-tree-sitter/web-tree-sitter.wasm dist/wasm/ && cp wasm/*.wasm dist/wasm/",
38
+ "build:core": "esbuild src/core-lib.ts --bundle --format=esm --platform=neutral --external:fs --external:fs/promises --external:path --external:module --external:crypto --outfile=dist/core/circle-ir-core.js && esbuild src/core-lib.ts --bundle --format=cjs --platform=neutral --external:fs --external:fs/promises --external:path --external:module --external:crypto --outfile=dist/core/circle-ir-core.cjs && cp dist/core-lib.d.ts dist/core/circle-ir-core.d.ts",
39
39
  "build:all": "npm run build && npm run build:browser && npm run build:core",
40
40
  "clean": "rm -rf dist coverage *.tsbuildinfo *.tgz",
41
41
  "typecheck": "tsc --noEmit",
@@ -87,7 +87,6 @@
87
87
  "registry": "https://registry.npmjs.org/"
88
88
  },
89
89
  "dependencies": {
90
- "pino": "^10.3.0",
91
90
  "web-tree-sitter": "^0.26.3",
92
91
  "yaml": "^2.8.2"
93
92
  },
@@ -96,7 +95,6 @@
96
95
  "@types/unzipper": "^0.10.11",
97
96
  "@vitest/coverage-v8": "^3.0.0",
98
97
  "esbuild": "^0.27.2",
99
- "pino-pretty": "^13.1.3",
100
98
  "tree-sitter-java": "^0.23.5",
101
99
  "tree-sitter-python": "^0.25.0",
102
100
  "tree-sitter-rust": "^0.24.0",
@@ -1,86 +0,0 @@
1
- /**
2
- * RustSec Advisory Database Integration
3
- *
4
- * Provides vulnerability data from the RustSec advisory database.
5
- * Advisory data is bundled at build time for offline/deterministic usage.
6
- */
7
- import type { Severity } from '../types/index.js';
8
- export interface AdvisoryVulnerability {
9
- /** Unique advisory ID (RUSTSEC-YYYY-NNNN) */
10
- id: string;
11
- /** Crate name */
12
- package: string;
13
- /** Advisory date (RFC 3339) */
14
- date: string;
15
- /** Advisory URL */
16
- url: string;
17
- /** CVSS score string */
18
- cvss?: string;
19
- /** Vulnerability categories */
20
- categories: string[];
21
- /** Search keywords */
22
- keywords: string[];
23
- /** Related identifiers (CVE, etc.) */
24
- aliases: string[];
25
- /** Affected functions with version constraints */
26
- affectedFunctions?: {
27
- name: string;
28
- versions: string[];
29
- }[];
30
- /** Version constraints */
31
- versions: {
32
- patched?: string[];
33
- unaffected?: string[];
34
- };
35
- /** Affected architectures */
36
- affectedArch?: string[];
37
- /** Affected operating systems */
38
- affectedOs?: string[];
39
- /** Human-readable description */
40
- description: string;
41
- /** Title/summary of the vulnerability */
42
- title?: string;
43
- }
44
- export interface AdvisoryDatabase {
45
- /** Map of crate name to list of advisories */
46
- advisories: Map<string, AdvisoryVulnerability[]>;
47
- /** When the database was last updated */
48
- lastUpdated: string;
49
- /** Source of the database */
50
- source: 'bundled' | 'fetched';
51
- /** Database format version */
52
- version: string;
53
- /** Statistics */
54
- stats?: {
55
- totalAdvisories: number;
56
- uniqueCrates: number;
57
- };
58
- }
59
- /**
60
- * Load the bundled advisory database
61
- */
62
- export declare function loadBundledAdvisories(): AdvisoryDatabase;
63
- /**
64
- * Parse advisory JSON into database structure
65
- */
66
- export declare function parseAdvisoryJson(json: {
67
- version: string;
68
- lastUpdated: string;
69
- advisories: AdvisoryVulnerability[];
70
- }): AdvisoryDatabase;
71
- /**
72
- * Map RustSec categories to severity levels
73
- */
74
- export declare function categoryToSeverity(categories: string[]): Severity;
75
- /**
76
- * Get advisories for a specific crate
77
- */
78
- export declare function getAdvisoriesForCrate(db: AdvisoryDatabase, crateName: string): AdvisoryVulnerability[];
79
- /**
80
- * Search advisories by CVE ID
81
- */
82
- export declare function findAdvisoryByCve(db: AdvisoryDatabase, cveId: string): AdvisoryVulnerability | undefined;
83
- /**
84
- * Get all unique crate names with advisories
85
- */
86
- export declare function getVulnerableCrates(db: AdvisoryDatabase): string[];
@@ -1,104 +0,0 @@
1
- /**
2
- * RustSec Advisory Database Integration
3
- *
4
- * Provides vulnerability data from the RustSec advisory database.
5
- * Advisory data is bundled at build time for offline/deterministic usage.
6
- */
7
- /**
8
- * Bundled advisory database (loaded lazily)
9
- */
10
- let bundledDb = null;
11
- /**
12
- * Load the bundled advisory database
13
- */
14
- export function loadBundledAdvisories() {
15
- if (bundledDb) {
16
- return bundledDb;
17
- }
18
- // Try to load bundled advisories
19
- try {
20
- // eslint-disable-next-line @typescript-eslint/no-require-imports
21
- const json = require('../../advisory-db.json');
22
- bundledDb = parseAdvisoryJson(json);
23
- return bundledDb;
24
- }
25
- catch {
26
- // Return empty database if bundled data not available
27
- return {
28
- advisories: new Map(),
29
- lastUpdated: new Date().toISOString(),
30
- source: 'bundled',
31
- version: '1.0',
32
- stats: { totalAdvisories: 0, uniqueCrates: 0 },
33
- };
34
- }
35
- }
36
- /**
37
- * Parse advisory JSON into database structure
38
- */
39
- export function parseAdvisoryJson(json) {
40
- const advisories = new Map();
41
- for (const advisory of json.advisories) {
42
- const existing = advisories.get(advisory.package) || [];
43
- existing.push(advisory);
44
- advisories.set(advisory.package, existing);
45
- }
46
- return {
47
- advisories,
48
- lastUpdated: json.lastUpdated,
49
- source: 'bundled',
50
- version: json.version,
51
- stats: {
52
- totalAdvisories: json.advisories.length,
53
- uniqueCrates: advisories.size,
54
- },
55
- };
56
- }
57
- /**
58
- * Map RustSec categories to severity levels
59
- */
60
- export function categoryToSeverity(categories) {
61
- const categorySet = new Set(categories);
62
- // Critical: code execution, privilege escalation
63
- if (categorySet.has('code-execution') ||
64
- categorySet.has('privilege-escalation')) {
65
- return 'critical';
66
- }
67
- // High: memory safety, denial of service
68
- if (categorySet.has('memory-safety') || categorySet.has('denial-of-service')) {
69
- return 'high';
70
- }
71
- // Medium: crypto issues, information disclosure
72
- if (categorySet.has('crypto-failure') ||
73
- categorySet.has('information-disclosure')) {
74
- return 'medium';
75
- }
76
- // Default to medium for unknown categories
77
- return 'medium';
78
- }
79
- /**
80
- * Get advisories for a specific crate
81
- */
82
- export function getAdvisoriesForCrate(db, crateName) {
83
- return db.advisories.get(crateName) || [];
84
- }
85
- /**
86
- * Search advisories by CVE ID
87
- */
88
- export function findAdvisoryByCve(db, cveId) {
89
- for (const advisories of db.advisories.values()) {
90
- for (const advisory of advisories) {
91
- if (advisory.aliases.includes(cveId)) {
92
- return advisory;
93
- }
94
- }
95
- }
96
- return undefined;
97
- }
98
- /**
99
- * Get all unique crate names with advisories
100
- */
101
- export function getVulnerableCrates(db) {
102
- return Array.from(db.advisories.keys());
103
- }
104
- //# sourceMappingURL=advisory-db.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"advisory-db.js","sourceRoot":"","sources":["../../src/analysis/advisory-db.ts"],"names":[],"mappings":"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"}
@@ -1,42 +0,0 @@
1
- /**
2
- * Cargo.lock parser for extracting crate dependencies and versions
3
- */
4
- export interface CargoLockDependency {
5
- name: string;
6
- version: string;
7
- source?: string;
8
- checksum?: string;
9
- }
10
- export interface CargoLock {
11
- version: number;
12
- dependencies: CargoLockDependency[];
13
- }
14
- /**
15
- * Parse Cargo.lock TOML file content
16
- */
17
- export declare function parseCargoLock(content: string): CargoLock;
18
- /**
19
- * Parse Cargo.toml to extract direct dependencies
20
- */
21
- export interface CargoTomlDependency {
22
- name: string;
23
- version?: string;
24
- path?: string;
25
- git?: string;
26
- features?: string[];
27
- }
28
- export interface CargoToml {
29
- name?: string;
30
- version?: string;
31
- dependencies: CargoTomlDependency[];
32
- devDependencies: CargoTomlDependency[];
33
- }
34
- /**
35
- * Parse Cargo.toml file content
36
- */
37
- export declare function parseCargoToml(content: string): CargoToml;
38
- /**
39
- * Filter dependencies to only include registry-sourced crates
40
- * (excludes path and git dependencies which can't be vulnerability-checked)
41
- */
42
- export declare function filterRegistryDeps(deps: CargoLockDependency[]): CargoLockDependency[];
@@ -1,102 +0,0 @@
1
- /**
2
- * Cargo.lock parser for extracting crate dependencies and versions
3
- */
4
- /**
5
- * Parse Cargo.lock TOML file content
6
- */
7
- export function parseCargoLock(content) {
8
- const dependencies = [];
9
- // Extract version from the file
10
- const versionMatch = content.match(/^version\s*=\s*(\d+)/m);
11
- const version = versionMatch ? parseInt(versionMatch[1], 10) : 3;
12
- // Parse [[package]] sections
13
- // Format:
14
- // [[package]]
15
- // name = "crate-name"
16
- // version = "1.0.0"
17
- // source = "registry+..."
18
- // checksum = "abc123..."
19
- const packagePattern = /\[\[package\]\]\s*\n((?:(?!^\[\[|\[package\]).*\n?)*)/gm;
20
- let match;
21
- while ((match = packagePattern.exec(content)) !== null) {
22
- const block = match[1];
23
- const nameMatch = block.match(/^name\s*=\s*"([^"]+)"/m);
24
- const versionMatch = block.match(/^version\s*=\s*"([^"]+)"/m);
25
- const sourceMatch = block.match(/^source\s*=\s*"([^"]+)"/m);
26
- const checksumMatch = block.match(/^checksum\s*=\s*"([^"]+)"/m);
27
- if (nameMatch && versionMatch) {
28
- dependencies.push({
29
- name: nameMatch[1],
30
- version: versionMatch[1],
31
- source: sourceMatch?.[1],
32
- checksum: checksumMatch?.[1],
33
- });
34
- }
35
- }
36
- return { version, dependencies };
37
- }
38
- /**
39
- * Parse Cargo.toml file content
40
- */
41
- export function parseCargoToml(content) {
42
- const dependencies = [];
43
- const devDependencies = [];
44
- // Extract package name and version
45
- const nameMatch = content.match(/^\[package\][^[]*name\s*=\s*"([^"]+)"/ms);
46
- const versionMatch = content.match(/^\[package\][^[]*version\s*=\s*"([^"]+)"/ms);
47
- // Parse [dependencies] section
48
- const depsMatch = content.match(/\[dependencies\]\s*\n((?:(?!\[(?!dependencies\.))[^\n]*\n?)*)/m);
49
- if (depsMatch) {
50
- parseDependencySection(depsMatch[1], dependencies);
51
- }
52
- // Parse [dev-dependencies] section
53
- const devDepsMatch = content.match(/\[dev-dependencies\]\s*\n((?:(?!\[(?!dev-dependencies\.))[^\n]*\n?)*)/m);
54
- if (devDepsMatch) {
55
- parseDependencySection(devDepsMatch[1], devDependencies);
56
- }
57
- return {
58
- name: nameMatch?.[1],
59
- version: versionMatch?.[1],
60
- dependencies,
61
- devDependencies,
62
- };
63
- }
64
- function parseDependencySection(section, deps) {
65
- // Simple dependency: crate = "1.0"
66
- const simplePattern = /^(\w[\w-]*)\s*=\s*"([^"]+)"/gm;
67
- let match;
68
- while ((match = simplePattern.exec(section)) !== null) {
69
- deps.push({
70
- name: match[1],
71
- version: match[2],
72
- });
73
- }
74
- // Complex dependency: crate = { version = "1.0", features = [...] }
75
- const complexPattern = /^(\w[\w-]*)\s*=\s*\{([^}]+)\}/gm;
76
- while ((match = complexPattern.exec(section)) !== null) {
77
- const name = match[1];
78
- const attrs = match[2];
79
- const versionMatch = attrs.match(/version\s*=\s*"([^"]+)"/);
80
- const pathMatch = attrs.match(/path\s*=\s*"([^"]+)"/);
81
- const gitMatch = attrs.match(/git\s*=\s*"([^"]+)"/);
82
- deps.push({
83
- name,
84
- version: versionMatch?.[1],
85
- path: pathMatch?.[1],
86
- git: gitMatch?.[1],
87
- });
88
- }
89
- }
90
- /**
91
- * Filter dependencies to only include registry-sourced crates
92
- * (excludes path and git dependencies which can't be vulnerability-checked)
93
- */
94
- export function filterRegistryDeps(deps) {
95
- return deps.filter((dep) => {
96
- // Include if no source (defaults to registry) or explicitly from registry
97
- if (!dep.source)
98
- return true;
99
- return dep.source.startsWith('registry+');
100
- });
101
- }
102
- //# sourceMappingURL=cargo-parser.js.map