diff --git a/types/ssri/index.d.ts b/types/ssri/index.d.ts new file mode 100644 index 0000000000..8cecbfe28d --- /dev/null +++ b/types/ssri/index.d.ts @@ -0,0 +1,126 @@ +// Type definitions for ssri 6.0 +// Project: https://github.com/zkat/ssri +// Definitions by: Jeow Li Huan +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +import { Utf8AsciiLatin1Encoding, Hash as CryptoHash } from "crypto"; +import { Readable, Transform } from "stream"; + +export interface HashLike { + algorithm: string; + digest: string; + options?: string[]; +} + +export interface IntegrityLike { + [algorithm: string]: HashLike[]; +} + +export type IntegrityMap = Integrity & IntegrityLike; + +export class Hash implements HashLike { + constructor(hash: string, opts?: { strict?: boolean }); + + source: string; + algorithm: string; + digest: string; + options?: string[]; + isHash: boolean; + + hexDigest(): string; + + toJSON(): string; + + toString(opts?: { strict?: boolean }): string; +} + +export class Integrity { + isIntegrity: boolean; + + toJSON(): string; + + toString(opts?: { strict?: boolean, sep?: string }): string; + + concat( + integrity: string | IntegrityLike | HashLike, + opts?: { strict?: boolean } + ): IntegrityMap; + + hexDigest(): string; + + match( + integrity: string | IntegrityLike | HashLike, + opts?: { strict?: boolean, pickAlgorithm?: (algo1: string, algo2: string) => string } + ): Hash | false; + + pickAlgorithm(opts?: { pickAlgorithm?: (algo1: string, algo2: string) => string }): string; +} + +export function parse( + sri: string | IntegrityLike | HashLike, + opts?: { strict?: boolean } +): IntegrityMap; + +export function parse( + sri: string | IntegrityLike | HashLike, + opts?: { single: true, strict?: boolean } +): Hash; + +export function stringify( + obj: string | IntegrityLike | HashLike, + opts?: { strict?: boolean, sep?: string } +): string; + +export function fromHex( + hexDigest: string, + algorithm: string, + opts?: { strict?: boolean, options?: ReadonlyArray } +): IntegrityMap; + +export function fromHex( + hexDigest: string, + algorithm: string, + opts?: { single: true, strict?: boolean, options?: ReadonlyArray } +): Hash; + +export function fromData( + data: string | Buffer | NodeJS.TypedArray | DataView, + opts?: { strict?: boolean, options?: ReadonlyArray, algorithms?: ReadonlyArray } +): IntegrityMap; + +export function fromStream( + stream: Readable, + opts?: { strict?: boolean, options?: ReadonlyArray, algorithms?: ReadonlyArray, Promise?: PromiseConstructorLike } +): PromiseLike; + +export function checkData( + data: string | Buffer | NodeJS.TypedArray, + sri: string | IntegrityLike | HashLike, + opts?: { strict?: boolean, error?: boolean, size?: number, pickAlgorithm?: (algo1: string, algo2: string) => string } +): Hash | false; + +export function checkStream( + stream: Readable, + sri: string | IntegrityLike | HashLike, + opts?: { + strict?: boolean, + options?: ReadonlyArray, + size?: number, + pickAlgorithm?: (algo1: string, algo2: string) => string, + Promise?: PromiseConstructorLike + } +): PromiseLike; + +export function integrityStream( + opts?: { + single?: boolean, + strict?: boolean, + options?: ReadonlyArray, + algorithms?: ReadonlyArray, + integrity?: string | IntegrityLike | HashLike, + size?: number, + pickAlgorithm?: (algo1: string, algo2: string) => string, + } +): Transform; + +export function create(opts?: { strict?: boolean, options?: ReadonlyArray, algorithms?: ReadonlyArray }): CryptoHash; diff --git a/types/ssri/ssri-tests.ts b/types/ssri/ssri-tests.ts new file mode 100644 index 0000000000..03190cec2b --- /dev/null +++ b/types/ssri/ssri-tests.ts @@ -0,0 +1,135 @@ +/// + +import ssri = require('ssri'); +import { Hash as CryptoHash } from "crypto"; +import { createReadStream } from 'fs'; +import { Transform } from 'stream'; + +const integrityString = 'sha512-9KhgCRIx/AmzC8xqYJTZRrnO8OW2Pxyl2DIMZSBOr0oDvtEFyht3xpp71j/r/pAe1DM+JI/A+line3jUBgzQ7A==?foo'; +const hash = { algorithm: 'sha512', digest: 'c0ffee', options: [] }; + +const integrity = { + sha1: [{ algorithm: 'sha1', digest: 'deadbeef', options: [] }], + sha512: [ + { algorithm: 'sha512', digest: 'c0ffee', options: [] }, + { algorithm: 'sha512', digest: 'bad1dea', options: ['foo'] } + ], +}; + +const parseString1: ssri.IntegrityMap = ssri.parse(integrityString); +const parseHash: ssri.IntegrityMap = ssri.parse(hash); +const parseIntegrity: ssri.IntegrityMap = ssri.parse(integrity); +const parseStringSingle: ssri.Hash = ssri.parse(integrityString, { single: true, strict: true }); +const parseStringWithOptions: ssri.IntegrityMap = ssri.parse(integrityString, { strict: true }); + +const stringifyString: string = ssri.stringify('\n\rsha512-foo\n\t\tsha384-bar'); +const stringifyHash: string = ssri.stringify(hash); +const stringifyIntegrity: string = ssri.stringify(integrity); +const stringifyStringWithOptions: string = ssri.stringify( + '\n\rsha512-foo\n\t\tsha384-bar', + { strict: false, sep: ',' } +); + +const integrityConcatString: ssri.IntegrityMap = new ssri.Integrity().concat(integrityString); +const integrityConcatHash: ssri.IntegrityMap = new ssri.Integrity().concat(hash); +const integrityConcatIntegrity: ssri.IntegrityMap = new ssri.Integrity().concat(integrity); +const integrityConcatStringWithOptions: ssri.IntegrityMap = new ssri.Integrity().concat( + integrityString, + { strict: true } +); + +const integrityToString: string = new ssri.Integrity().toString(); +const integrityToStringWithOptions: string = new ssri.Integrity().toString({ strict: false, sep: ',' }); + +const integrityToJson: string = new ssri.Integrity().toJSON(); + +const integrityMatchString: ssri.Hash | false = new ssri.Integrity().match(integrityString); +const integrityMatchHash: ssri.Hash | false = new ssri.Integrity().match(hash); +const integrityMatchIntegrity: ssri.Hash | false = new ssri.Integrity().match(integrity); +const integrityMatchStringWithOptions: ssri.Hash | false = new ssri.Integrity().match( + integrityString, + { strict: true, pickAlgorithm: (a, b) => a } +); + +const integrityPickAlgorithm: string = new ssri.Integrity().pickAlgorithm(); +const integrityPickAlgorithmWithOptions: string = new ssri.Integrity().pickAlgorithm({ pickAlgorithm: (a, b) => a }); + +const integrityHexDigest: string = new ssri.Integrity().hexDigest(); + +const fromHex: ssri.IntegrityMap = ssri.fromHex('75e69d6de79f', 'sha1'); +const fromHexSingle: ssri.Hash = ssri.fromHex( + '75e69d6de79f', + 'sha1', + { single: true, strict: false, options: ['sriOpt'] } +); +const fromHexWithOptions: ssri.IntegrityMap = ssri.fromHex( + '75e69d6de79f', + 'sha1', + { strict: false, options: ['sriOpt'] } +); + +const fromDataString: ssri.IntegrityMap = ssri.fromData('foobarbaz'); +const fromDataBuffer: ssri.IntegrityMap = ssri.fromData(Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72])); +const fromDataStringWithOptions: ssri.IntegrityMap = ssri.fromData( + 'foobarbaz', { + algorithms: ['sha256', 'sha384', 'sha512'], + strict: true, + options: ['sriOpt'] + } +); + +const fromStream: PromiseLike = ssri.fromStream(createReadStream('index.js')); +const fromStreamWithOptions: PromiseLike = ssri.fromStream( + createReadStream('index.js'), { + algorithms: ['sha1', 'sha512'], + strict: true, + options: ['sriOpt'], + Promise + } +); + +const create: CryptoHash = ssri.create(); +const createWithOptions: CryptoHash = ssri.create({ + algorithms: ['sha1', 'sha512'], + strict: true, + options: ['sriOpt'] +}); + +const checkDataString: ssri.Hash | false = ssri.checkData('data', integrityString); +const checkDataBuffer: ssri.Hash | false = ssri.checkData( + Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]), + integrityString +); +const checkDataHash: ssri.Hash | false = ssri.checkData('data', hash); +const checkDataIntegrity: ssri.Hash | false = ssri.checkData('data', integrity); +const checkDataStringWithOptions: ssri.Hash | false = ssri.checkData( + 'data', + integrityString, + { strict: true, pickAlgorithm: (a, b) => a, error: true, size: 1 } +); + +const checkStreamString: PromiseLike = ssri.checkStream(createReadStream('index.js'), integrityString); +const checkStreamHash: PromiseLike = ssri.checkStream(createReadStream('index.js'), hash); +const checkStreamIntegrity: PromiseLike = ssri.checkStream(createReadStream('index.js'), integrity); +const checkStreamWithOptions: PromiseLike = ssri.checkStream( + createReadStream('index.js'), + integrityString, + { + strict: true, + options: ['sriOpt'], + pickAlgorithm: (a, b) => a, + size: 1, + Promise + } +); + +const integrityStream: Transform = ssri.integrityStream(); +const integrityStreamWithOptions: Transform = ssri.integrityStream({ + single: true, + strict: true, + options: ['sriOpt'], + pickAlgorithm: (a, b) => a, + size: 1, + integrity, + algorithms: ['sha1', 'sha256'] +}); diff --git a/types/ssri/tsconfig.json b/types/ssri/tsconfig.json new file mode 100644 index 0000000000..add9a00f51 --- /dev/null +++ b/types/ssri/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "ssri-tests.ts" + ] +} diff --git a/types/ssri/tslint.json b/types/ssri/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/ssri/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }