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
Advanced configuration system supporting multiple sources, validation, and flexible option processing for both CLI and programmatic usage.
Converts Commander.js CLI instance to validated IOptions configuration object.
/**
* Converts CLI arguments to IOptions configuration with validation
* @param cli - Commander.js instance with parsed CLI arguments
* @returns Fully processed and validated options object
*/
function initOptionsFromCli(cli: Command): IOptions;Usage Example:
import { initCli, initOptionsFromCli } from "jscpd";
import { readJSONSync } from "fs-extra";
const packageJson = readJSONSync("./package.json");
const cli = initCli(packageJson, process.argv);
const options = initOptionsFromCli(cli);
console.log("Processed options:", options);
console.log("Supported formats:", options.format);
console.log("Final paths:", options.path);Merges options from multiple sources (CLI, config files, package.json) with proper priority handling.
/**
* Merges CLI, config file, and package.json options with proper precedence
* @param cli - Commander.js instance with CLI arguments
* @returns Final merged options with all sources combined
*/
function prepareOptions(cli: Command): IOptions;Usage Example:
import { initCli, prepareOptions } from "jscpd";
const cli = initCli(packageJson, [
"node", "jscpd", "./src",
"--config", "./custom-config.json",
"--min-lines", "3"
]);
const options = prepareOptions(cli);
// Result combines: default options + package.json config + config file + CLI argsProcesses ignore patterns including .gitignore integration.
/**
* Processes ignore patterns including .gitignore file integration
* @param options - Options object containing ignore and gitignore settings
* @returns Array of processed ignore patterns
*/
function initIgnore(options: IOptions): string[];Usage Example:
import { initIgnore } from "jscpd";
const options = {
ignore: ["**/*.test.js", "**/dist/**"],
gitignore: true
};
const ignorePatterns = initIgnore(options);
console.log("Final ignore patterns:", ignorePatterns);
// Includes both explicit ignore patterns and .gitignore patternsUtility functions for displaying configuration and file information during debugging.
/**
* Prints the complete options configuration to console
* @param options - Options object to display
*/
function printOptions(options: IOptions): void;
/**
* Prints list of files that will be analyzed
* @param files - Array of file entries with content
*/
function printFiles(files: EntryWithContent[]): void;
// External types from @jscpd/finder
interface EntryWithContent {
path: string;
// Additional properties from finder package
}
/**
* Prints supported file formats and exits
*/
function printSupportedFormat(): void;Usage Examples:
import { printOptions, printFiles, printSupportedFormat } from "jscpd";
import { getFilesToDetect } from "@jscpd/finder";
// Debug current configuration
printOptions(options);
// Show files that will be analyzed
const files = getFilesToDetect(options);
printFiles(files);
// List all supported formats
printSupportedFormat();Configuration options are merged from multiple sources with the following priority (highest to lowest):
Direct command-line arguments override all other sources:
jscpd ./src --min-lines 5 --reporters console,htmlSpecified via --config option or default .jscpd.json:
{
"minLines": 3,
"minTokens": 40,
"threshold": 8,
"reporters": ["console", "json"],
"ignore": ["**/*.test.js"],
"output": "./reports",
"gitignore": true
}Configuration in the jscpd property of package.json:
{
"name": "my-project",
"jscpd": {
"minLines": 4,
"reporters": ["html"],
"threshold": 10
}
}Built-in defaults from @jscpd/core:
// Example default values
{
minLines: 5,
minTokens: 50,
maxLines: 1000,
mode: "mild",
reporters: ["time", "console"],
output: "./report/",
pattern: "**/*"
}{
"minLines": 5,
"minTokens": 50,
"maxLines": 1000,
"maxSize": "1mb",
"threshold": 10,
"mode": "strict",
"format": [
"javascript",
"typescript",
"python"
],
"ignore": [
"**/*.test.js",
"**/*.spec.ts",
"**/node_modules/**",
"**/dist/**"
],
"ignorePattern": [
"DEBUG",
"TODO",
"FIXME"
],
"reporters": [
"console",
"html",
"json"
],
"output": "./reports/jscpd",
"absolute": true,
"gitignore": true,
"blame": true,
"verbose": false,
"silent": false,
"noSymlinks": true,
"skipLocal": false,
"ignoreCase": false,
"cache": true,
"store": "memory",
"formatsExts": {
"javascript": ["js", "jsx", "es6"],
"typescript": ["ts", "tsx"]
}
}{
"name": "my-project",
"version": "1.0.0",
"scripts": {
"jscpd": "jscpd",
"jscpd:check": "jscpd --threshold 5"
},
"jscpd": {
"minLines": 3,
"threshold": 5,
"reporters": ["console", "badge"],
"ignore": [
"**/*.test.js"
],
"path": [
"./src",
"./lib"
]
}
}Paths in configuration files are resolved relative to the config file location:
{
"path": ["./src", "../shared"],
"ignore": ["./tests/**"]
}Comma-separated CLI values are automatically split into arrays:
# CLI input
jscpd --format "javascript,typescript,python" --ignore "**/*.test.js,**/dist/**"
# Processed as
{
"format": ["javascript", "typescript", "python"],
"ignore": ["**/*.test.js", "**/dist/**"]
}Numeric and boolean options are automatically converted:
# CLI input
jscpd --min-lines "5" --threshold "10" --gitignore
# Processed as
{
"minLines": 5,
"threshold": 10,
"gitignore": true
}Reporters are automatically configured based on options:
// Silent mode filters out console reporters
{
"silent": true,
"reporters": ["console", "html"] // Becomes ["silent", "html"]
}
// Threshold automatically adds threshold reporter
{
"threshold": 10,
"reporters": ["console"] // Becomes ["console", "threshold"]
}{
"minLines": 3,
"verbose": true,
"reporters": ["console"],
"format": ["javascript", "typescript"]
}{
"threshold": 5,
"silent": true,
"reporters": ["json", "threshold"],
"output": "./reports",
"exitCode": 1
}{
"minLines": 5,
"threshold": 0,
"reporters": ["console"],
"gitignore": true,
"skipLocal": true
}Use the debug option to inspect final configuration:
jscpd --debug ./srcThis will output:
// Programmatic debugging
import { printOptions, printFiles } from "jscpd";
import { getFilesToDetect } from "@jscpd/finder";
const options = prepareOptions(cli);
printOptions(options);
const files = getFilesToDetect(options);
printFiles(files);