Copy/paste detector for source code that supports 150+ programming languages and provides both CLI and programmatic APIs
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Core programmatic API for detecting code duplications with extensive configuration options and type safety.
Detects code clones in the specified paths with comprehensive configuration options.
/**
* Detects code clones in the provided paths using the specified options
* @param opts - Configuration options for detection behavior
* @param store - Optional custom store implementation for large codebases
* @returns Promise resolving to array of detected clones
*/
function detectClones(
opts: IOptions,
store?: IStore<IMapFrame>
): Promise<IClone[]>;Usage Examples:
import { detectClones } from "jscpd";
// Basic detection
const clones = await detectClones({
path: ["./src"],
minLines: 5,
minTokens: 50
});
// Advanced detection with custom options
const clones = await detectClones({
path: ["./src", "./lib"],
minLines: 3,
minTokens: 30,
maxLines: 1000,
format: ["javascript", "typescript"],
ignore: ["**/*.test.js", "**/node_modules/**"],
ignorePattern: ["DEBUG", "TODO"],
reporters: ["console", "json"],
output: "./reports",
threshold: 10,
mode: "strict",
gitignore: true,
blame: true
});
console.log(`Found ${clones.length} duplications`);
clones.forEach(clone => {
console.log(`Format: ${clone.format}`);
console.log(`Duplication A: ${clone.duplicationA.sourceId}:${clone.duplicationA.start.line}-${clone.duplicationA.end.line}`);
console.log(`Duplication B: ${clone.duplicationB.sourceId}:${clone.duplicationB.start.line}-${clone.duplicationB.end.line}`);
});Complete configuration interface for clone detection behavior.
interface IOptions {
/** Paths to analyze for duplications */
path?: string[];
/** Minimum lines for duplication detection (default varies by mode) */
minLines?: number;
/** Minimum tokens for duplication detection (default: 50) */
minTokens?: number;
/** Maximum source lines to analyze (default varies) */
maxLines?: number;
/** Maximum source size in bytes (examples: "1kb", "1mb", "120kb") */
maxSize?: string;
/** Duplication threshold for error exit */
threshold?: number;
/** Formats to analyze (default: all supported formats) */
format?: string[];
/** Glob pattern for file search (default: "**/*") */
pattern?: string;
/** Glob patterns for files to exclude */
ignore?: string[];
/** Regexp patterns for code blocks to ignore */
ignorePattern?: string[];
/** Reporter names to use (default: ["time", "console"]) */
reporters?: string[];
/** Output directory path (default: "./report/") */
output?: string;
/** Quality mode: "strict", "mild", or "weak" */
mode?: string;
/** Suppress console output */
silent?: boolean;
/** Show debug information */
debug?: boolean;
/** Show verbose output during detection */
verbose?: boolean;
/** Use absolute paths in reports */
absolute?: boolean;
/** Respect .gitignore file */
gitignore?: boolean;
/** Avoid following symlinks */
noSymlinks?: boolean;
/** Get git blame information for duplications */
blame?: boolean;
/** Skip duplicates in local folders */
skipLocal?: boolean;
/** Case-insensitive matching (experimental) */
ignoreCase?: boolean;
/** Enable caching */
cache?: boolean;
/** Custom store type (e.g., "leveldb") */
store?: string;
/** Execution identifier */
executionId?: string;
/** Custom format extensions mapping */
formatsExts?: Record<string, string[]>;
/** Custom exit code when duplications found */
exitCode?: number;
/** Path to configuration file */
config?: string;
/** Custom hash function for token hashing */
hashFunction?: (value: string) => string;
/** Event listeners array */
listeners?: any[];
/** Configuration options for specific reporters */
reportersOptions?: Record<string, any>;
/** Tokens to skip during analysis */
tokensToSkip?: string[];
}Interface representing detected code clones.
interface IClone {
/** Programming language/format of the clone */
format: string;
/** Whether this is a newly detected clone */
isNew?: boolean;
/** Timestamp when clone was found */
foundDate?: number;
/** First instance of the duplication */
duplicationA: IDuplication;
/** Second instance of the duplication */
duplicationB: IDuplication;
}
interface IDuplication {
/** Source file identifier/path */
sourceId: string;
/** Starting location of the duplication */
start: ITokenLocation;
/** Ending location of the duplication */
end: ITokenLocation;
/** Token range [start, end] */
range: [number, number];
/** Source code fragment (optional) */
fragment?: string;
/** Git blame information (optional) */
blame?: IBlamedLines;
}
interface ITokenLocation {
/** Line number (1-based) */
line: number;
/** Column number (1-based, optional) */
column?: number;
/** Character position in file (optional) */
position?: number;
}Interface for implementing custom storage backends for large codebases.
interface IStore<T> {
/** Set namespace for key isolation */
namespace(name: string): void;
/** Store a value with the given key */
set(key: string, value: T): Promise<T>;
/** Retrieve a value by key */
get(key: string): Promise<T>;
/** Close/cleanup the store */
close(): void;
}
interface IMapFrame {
// Internal type used by the detection algorithm
// Specific structure is implementation detail
}
interface IBlamedLines {
// Git blame information for duplicated lines
// From @jscpd/core package
}The detectClones function may throw errors in the following scenarios:
try {
const clones = await detectClones(options);
} catch (error) {
console.error("Detection failed:", error.message);
}