npm package: @qrvey/cd-package-registry
Description: ![install size](https://packagephobia.now.sh/badge?p=%40qrvey%2Fcd-package-registry) ![coverage](https://img.shields.io/badge/unit_test_coverage-97%25-brightgreen)
Latest version: 1.0.5-1001

# @qrvey/cd-package-registry

![install size](https://packagephobia.now.sh/badge?p=%40qrvey%2Fcd-package-registry)
![coverage](https://img.shields.io/badge/unit_test_coverage-97%25-brightgreen)

**@qrvey/cd-package-registry** is a package that validates assets and their dependencies.

## Installation

You can install the **@qrvey/cd-package-registry** package via npm. Run the following command in your terminal:

```bash
npm install @qrvey/cd-package-registry
```

## API Documentation

### Available assets in the library to validate

-   `Application`
-   `Automation`
-   `Connection`
-   `Formula`
-   `Page Flow`
-   `Dashboard Asset`
-   `Global Preference` 
-   `Page Tab`
-   `Bucket`
-   `Dashboard Content Element`
-   `Dashboard Content`
-   `Metric`
-   `Report Section`
-   `Report`
-   `Chart Theme`
-   `Chart`
-   `Dataset`
-   `Builder Configuration`
-   `Tokens`

## Example Usage

```ts
import { ApplicationValidatorService, ChartValidatorService } from '@qrvey/cd-package-registry';

const applicationValidationService = new ApplicationValidatorService();
const applicationPayload = {
    appid: '123456',
    name: 'app name',
    userid: '123456'
}

const applicationValidationResult = applicationValidationService.validate(applicationPayload)
const applicationBatchValidationResult = applicationValidationService.batchValidate([applicationPayload])

// Validation with dependencies

const chartPayload = {
    chartId: '123456'
    appid: '123456',
    title: 'chart title',
    userid: '123456'
}
const options = {
    domain: 'http://example.com'
    apiKey: '123456'
}

const chartValidatorService = new ChartValidatorService({ userId: userid, appId: appid }, options)

const chartValidationResults = chartValidatorService.validate(chartPayload)
const chartBatchValidationResults = chartValidatorService.batchValidate([chartPayload])
```
## Extend functionality

You can create your custom validators extending from the library functionality. You need to create your DTOs using class-validator. Example of a custom validator without dependencies

```ts
class CustomAssetDto {
    @IsString()
    @IsDefined()
    id: string;

    @IsString()
    @IsDefined()
    name: string;

    @IsString()
    @IsDefined()
    lastName: string;

    @IsNumber()
    @IsOptional()
    age: number;
}

class CustomValidatorWithoutDependencies extends BaseAssetService<CustomAssetDto> {
    private static readonly _logger = new LoggerService(CustomValidatorWithoutDependencies.name)
    protected get idKey(): keyof CustomAssetDto {
        return 'id';
    }

    protected getAssetType(): new () => object {
        return CustomAssetDto;
    }

    protected get logger(): LoggerService {
        return CustomValidatorWithoutDependencies._logger;
    }
}
```

Example of a custom validator with dependencies

```ts
class CustomAssetDto {
    @IsString()
    @IsDefined()
    id: string;

    @IsString()
    @IsDefined()
    name: string;

    @IsString()
    @IsDefined()
    lastName: string;

    @IsNumber()
    @IsOptional()
    age: number;
}

class CustomValidatorWithDependencies extends BaseAssetWithDependenciesService<CustomAssetDto> {
    protected get idKey(): keyof CustomAssetDto {
        return 'id';
    }
    protected dependencyValidator: IAssetDependencyValidatorService<CustomAssetDto>;
    private static readonly _logger: LoggerService = new LoggerService(
        CustomValidatorWithDependencies.name,
    );

    constructor(params: { userId: string; appId: string }, options?: Options) {
        super();
        this.dependencyValidator = new CustomDependencyValidator(
            params,
            options,
        );
    }

    protected getAssetType(): new () => object {
        return CustomAssetDto;
    }

    protected get logger(): LoggerService {
        return CustomValidatorWithoutDependencies._logger;
    }
}

class CustomDependencyValidator
    implements IAssetDependencyValidatorService<CustomAssetDto>
{
    constructor(private readonly params: any, private readonly options: Option)
    {}
    getDependencyKeys(input: Partial<CustomAssetDto>): {
        keys: Record<string, any>[];
    } {
        return {
            keys: [{ qrveyId: input.qrveyid! }],
        };
    }
    async fetchDependencies(
        keys: Record<string, any>[],
    ): Promise<DependencyContext> {
        const args = uniqueBy(keys ?? [], 'id');

        const dependencies = await fetchDependencies(args);

        const dependenciesMap = new Map(dependencies.map((d) => [d.id, d]));

        return {
            dependencies: dependenciesMap,
        };
    }
    validateWithContext(
        input: Partial<ChartAssetDto>,
        context: DependencyContext,
    ): ValidationError[] {
        const errors: ValidationError[] = [];

        const dependency = context.dependencies.get(input.id);

        if (!dependency) {
            errors.push({
                field: 'id',
                message: `Custom error message`,
                value: input,
            });
        }

        return errors;
    }
}
```