# core/parsers/tool.jscpd.parser.ts

> 29 lines of code and 9 definitions.

Tree: GovLab Quality
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/quality#file-quality-core-parsers-tool-jscpd-parser-ts
Source text: https://banes-lab.com/source/quality/core/parsers/tool.jscpd.parser.ts.txt

Listed in [core/parsers](https://banes-lab.com/api/source/quality/core/parsers.md), after [core/parsers/tool.hadolint.parser.ts](https://banes-lab.com/source/quality/core/parsers/tool.hadolint.parser.ts.md) and before [core/parsers/tool.kics.parser.ts](https://banes-lab.com/source/quality/core/parsers/tool.kics.parser.ts.md).

## Definitions

- `parseJscpdOutput` (lexical_declaration, line 18, exported)
- `TOOL` (lexical_declaration, line 8)
- `RULE_ID` (lexical_declaration, line 9)
- `locationOf` (lexical_declaration, line 11)
- `record` (lexical_declaration, line 12)
- `start` (lexical_declaration, line 13)
- `line` (lexical_declaration, line 14)
- `first` (lexical_declaration, line 20, exported)
- `second` (lexical_declaration, line 21, exported)

## Contained in

- [core/parsers](https://banes-lab.com/anatomy/quality/folder-quality-core-parsers.md)

## Uses

- [configuration/strings/tool.strings.ts](https://banes-lab.com/source/quality/configuration/strings/tool.strings.ts.md)
- [core/factories/finding.factory.ts](https://banes-lab.com/source/quality/core/factories/finding.factory.ts.md)
- [core/parsers/record.parser.ts](https://banes-lab.com/source/quality/core/parsers/record.parser.ts.md)

## Used by

- [core/adapters/tool.jscpd.adapter.ts](https://banes-lab.com/source/quality/core/adapters/tool.jscpd.adapter.ts.md)

## Linked from

- [configuration/strings](https://banes-lab.com/anatomy/quality/folder-quality-configuration-strings.md)
- [core/adapters](https://banes-lab.com/anatomy/quality/folder-quality-core-adapters.md)
- [core/factories](https://banes-lab.com/anatomy/quality/folder-quality-core-factories.md)
- [core/parsers](https://banes-lab.com/anatomy/quality/folder-quality-core-parsers.md)

## Source

```typescript
import { isRecord, recordAt, stringField } from "#core/selectors/record.selector";
import type { Finding } from "#types/finding.types";
import { POSITION } from "#configuration/constants/tool.constants";
import { duplicatedBlock } from "#configuration/strings/tool.strings";
import { jsonRecordsAt } from "#core/parsers/record.parser";
import { toolFinding } from "#core/factories/finding.factory";

const TOOL = "jscpd";
const RULE_ID = "jscpd/duplicate";

const locationOf = function locationOf(side: unknown): { file: string; line: number } {
    const record = isRecord(side) ? side : {};
    const start = recordAt(record, "start");
    const line = typeof start["line"] === "number" ? start["line"] : POSITION;
    return { file: stringField(record, "name"), line };
};

export const parseJscpdOutput = function parseJscpdOutput(stdout: string, ecosystem: string): Finding[] {
    return jsonRecordsAt(stdout, "duplicates").map((clone) => {
        const first = locationOf(clone["firstFile"]);
        const second = locationOf(clone["secondFile"]);
        return toolFinding({
            column: POSITION,
            ecosystem,
            file: second.file,
            line: second.line,
            message: duplicatedBlock(first.file, first.line),
            ruleId: RULE_ID,
            tool: TOOL,
        });
    });
};
```
