diff --git a/types/lockfile-lint-api/index.d.ts b/types/lockfile-lint-api/index.d.ts new file mode 100644 index 0000000000..43a9221f47 --- /dev/null +++ b/types/lockfile-lint-api/index.d.ts @@ -0,0 +1,73 @@ +// Type definitions for lockfile-lint-api 5.1 +// Project: https://github.com/lirantal/lockfile-lint/tree/master/packages/lockfile-lint-api +// Definitions by: Markus Lasermann +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 3.9 + +export type Hosts = ReadonlyArray; + +export interface PackageMetadata { + version: string; + resolved?: string; + dependencies?: Record; // e.g. {'balanced-match': '^1.0.0', 'concat-map': '0.0.1'} +} + +export type Packages = Record; + +export interface ValidationOptions { + emptyHostname?: boolean; +} + +export interface Error { + message: string; + package: string; +} + +export interface ValidationError { + type: 'error'; + errors: Error[]; +} + +export interface ValidationSuccess { + type: 'success'; + object: Packages; +} + +export type ValidationResult = ValidationError | ValidationSuccess; + +export class ValidateHost { + constructor(packages: { packages: Packages }); + validate(hosts: Hosts, options?: ValidationOptions): ValidationResult; + validateSingle(packageName: string, hosts: Hosts): boolean; +} + +export class ValidateHttps { + constructor(packages: { packages: Packages }); + validate(): ValidationResult; +} + +export class ValidateScheme { + constructor(packages: { packages: Packages }); + validate(schemes: ReadonlyArray): ValidationResult; +} + +export class ValidateUrl { + constructor(packages: { packages: Packages }); + validate(allowedUrls: ReadonlyArray, options?: ValidationOptions): ValidationResult; + validateSingle(packageName: string, allowedUrls: Hosts): boolean; +} + +export interface ParseLockfileOptions { + lockfilePath: string; + lockfileType: string; +} + +export interface ParseLockfileResult { + type: 'success'; + object: Packages; +} + +export class ParseLockfile { + constructor(options: ParseLockfileOptions); + parseSync(): ParseLockfileResult; +} diff --git a/types/lockfile-lint-api/lockfile-lint-api-tests.ts b/types/lockfile-lint-api/lockfile-lint-api-tests.ts new file mode 100644 index 0000000000..f6b69a00e4 --- /dev/null +++ b/types/lockfile-lint-api/lockfile-lint-api-tests.ts @@ -0,0 +1,85 @@ +import { ValidateHost, ValidateHttps, ValidateScheme, ValidateUrl, ParseLockfile } from 'lockfile-lint-api'; + +const validator = new ValidateHost({ packages: { name: { version: 'v1.0.0' } } }); +let result; +try { + result = validator.validate(['npm', 'meow']); +} catch (error) { + // something bad happened during validation and the validation + // process couldn't take place +} +console.log('✔ ValidateHost', result); + +const yarnLockfilePath = './yarn.test.lock'; +const options = { + lockfilePath: yarnLockfilePath, + lockfileType: 'yarn', +}; + +// instantiate a new parser with options object +const parser = new ParseLockfile(options); + +// read the file synchronously and parse it +// providing an object that is compatible +// with the @yarn/lockfile library which has +// all the packages listed in `lockfile.object` +const lockfile = parser.parseSync(); +console.log('✔ parseSync', lockfile); + +// now instantiate a validator object with those +// list of packages +const hostValidator = new ValidateHost({ packages: lockfile.object }); +let hostResult; +try { + // validation is synchronous and is being called + // with 'npm' as a shortcut for the npm registry + // host to validate all lockfile resources are + // whitelisted to the npm host + hostResult = hostValidator.validate(['npm']); +} catch (error) { + // couldn't process the validation +} + +// in this case we expect the validation to fail because +// we validate a yarnpkg lock file for the npm registry +if (hostResult?.type === 'success') { + console.log('✔ ValidateHost', hostResult); +} else { + console.log('X ValidateHost', hostResult); +} + +const hostValidatorSingle = new ValidateHost({ packages: lockfile.object }); +hostResult = hostValidatorSingle.validateSingle('@types/node@^9.6.5', ['npm']); +console.log('✔ validateSingle', hostResult); + +const httpsValidator = new ValidateHttps({ packages: lockfile.object }); +let httpsResult; +try { + httpsResult = httpsValidator.validate(); +} catch (error) { + // couldn't process the validation +} +console.log('✔ ValidateHttps', httpsResult); + +const schemeValidator = new ValidateScheme({ packages: lockfile.object }); +let schemeResult; +try { + schemeResult = schemeValidator.validate(['git']); +} catch (error) { + // couldn't process the validation +} +console.log('X ValidateScheme', schemeResult); + +const urlValidator = new ValidateUrl({ packages: lockfile.object }); +let urlResult; +let urlSingleResult; +try { + urlResult = urlValidator.validate(['git']); + urlSingleResult = urlValidator.validateSingle('@types/node@^9.6.5', [ + 'https://registry.yarnpkg.com/@types/node/-/node-9.6.5.tgz#ee700810fdf49ac1c399fc5980b7559b3e5a381d', + ]); +} catch (error) { + // couldn't process the validation +} +console.log('X ValidateUrl', urlResult); +console.log('✔ ValidateUrlSingle', urlSingleResult); diff --git a/types/lockfile-lint-api/tsconfig.json b/types/lockfile-lint-api/tsconfig.json new file mode 100644 index 0000000000..b097e2efa6 --- /dev/null +++ b/types/lockfile-lint-api/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "dom", + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "jsx": "react", + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "lockfile-lint-api-tests.ts" + ] +} diff --git a/types/lockfile-lint-api/tslint.json b/types/lockfile-lint-api/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/lockfile-lint-api/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }