From 2d215e38ab25e0588d9d59d329ec7562f9869fed Mon Sep 17 00:00:00 2001 From: hexchain Date: Sat, 20 Dec 2025 03:02:40 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Merge=20PR=20#74241=20[cacache]?= =?UTF-8?q?=20fix=20types=20and=20update=20version=20by=20@hexchain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- types/cacache/cacache-tests.ts | 18 +++++++-- types/cacache/index.d.ts | 73 ++++++++++++++++++++++++++++++---- types/cacache/package.json | 5 ++- 3 files changed, 83 insertions(+), 13 deletions(-) diff --git a/types/cacache/cacache-tests.ts b/types/cacache/cacache-tests.ts index 9d0a73a03b0b8c..d4d60c032015f5 100644 --- a/types/cacache/cacache-tests.ts +++ b/types/cacache/cacache-tests.ts @@ -6,7 +6,7 @@ const cachePath = ""; cacache.ls(cachePath).then(() => {}); cacache.ls.stream(cachePath).on("data", data => { - data; // $ExpectType any + data; // $ExpectType Cache }); cacache.get(cachePath, "my-thing", { memoize: true }).then(() => {}); @@ -21,7 +21,10 @@ cacache.get metadata; // $ExpectType any }) .on("integrity", integrity => { - integrity; // $ExpectType any + integrity; // $ExpectType string + }) + .on("size", size => { + size; // $ExpectType number }) .pipe(fs.createWriteStream("./x.tgz")); @@ -29,7 +32,9 @@ cacache.get.stream.byDigest(cachePath, "sha512-SoMeDIGest+64==").pipe(fs.createW cacache.get.info(cachePath, "my-thing").then(() => {}); -cacache.get.hasContent(cachePath, "sha521-NOT+IN/CACHE==").then(() => {}); +cacache.get.hasContent(cachePath, "sha521-NOT+IN/CACHE==").then((res) => { + res; // $ExpectType HasContentObject | false +}); cacache .put(cachePath, "registry.npmjs.org|cacache@1.0.0", Buffer.from([]), { @@ -43,7 +48,12 @@ cacache fs.createReadStream("").pipe( cacache.put .stream(cachePath, "registry.npmjs.org|cacache@1.0.0") - .on("integrity", d => console.log(`integrity digest is ${d}`)), + .on("integrity", integrity => { + integrity; // $ExpectType string + }) + .on("size", size => { + size; // $ExpectType number + }), ); cacache.rm.all(cachePath).then(() => { diff --git a/types/cacache/index.d.ts b/types/cacache/index.d.ts index ef16a1aec301aa..c6a54989049b33 100644 --- a/types/cacache/index.d.ts +++ b/types/cacache/index.d.ts @@ -1,5 +1,9 @@ /// +import { Minipass } from "minipass"; +import * as fs from "node:fs"; +import { EventEmitter } from "node:stream"; + export interface CacheObject { /** Subresource Integrity hash for the content this entry refers to. */ integrity: string; @@ -36,6 +40,7 @@ export namespace get { options: any[]; source: string; }; + stat: fs.Stats; } interface Options { @@ -74,16 +79,29 @@ export namespace get { size?: number | undefined; } + interface GetStreamEvents extends Minipass.Events { + // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type + integrity: [integrity: string]; + + // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type + size: [size: number]; + + // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type + metadata: [metadata: any]; + } + + type CopyResultObject = Pick; + namespace copy { function byDigest(cachePath: string, hash: string, dest: string, opts?: Options): Promise; } namespace stream { - function byDigest(cachePath: string, hash: string, opts?: Options): NodeJS.ReadableStream; + function byDigest(cachePath: string, hash: string, opts?: Options): Minipass; } - function byDigest(cachePath: string, hash: string, opts?: Options): Promise; - function copy(cachePath: string, key: string, dest: string, opts?: Options): Promise; + function byDigest(cachePath: string, hash: string, opts?: Options): Promise; + function copy(cachePath: string, key: string, dest: string, opts?: Options): Promise; /** * Looks up a Subresource Integrity hash in the cache. If content exists @@ -114,7 +132,7 @@ export namespace get { * entirely. This version does not emit the `metadata` and `integrity` * events at all. */ - function stream(cachePath: string, key: string, opts?: Options): NodeJS.ReadableStream; + function stream(cachePath: string, key: string, opts?: Options): Minipass; } export namespace ls { @@ -127,10 +145,21 @@ export namespace ls { * This works just like `ls`, except `get.info` entries are returned as * `'data'` events on the returned stream. */ - function stream(cachePath: string): NodeJS.ReadableStream; + function stream(cachePath: string): Minipass; } export namespace put { + interface IntegrityEmitterEvents { + // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type + integrity: [integrity: string]; + + // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type + size: [size: number]; + + // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type + error: [err: unknown]; + } + interface Options { /** * Default: `['sha512']` @@ -144,7 +173,8 @@ export namespace put { * Currently only supports one algorithm at a time (i.e., an array * length of exactly `1`). Has no effect if `opts.integrity` is present. */ - algorithms?: string[] | undefined; + // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type + algorithms?: [string] | undefined; /** * If present, the pre-calculated digest for the inserted content. If @@ -189,6 +219,31 @@ export namespace put { * Prefix to append on the temporary directory name inside the cache's tmp dir. */ tmpPrefix?: null | string | undefined; + + /** + * Default: `undefined` + * + * (Streaming only) If present, uses the provided event emitter as a + * source of truth for both integrity and size. This allows use cases + * where integrity is already being calculated outside of cacache to + * reuse that data instead of calculating it a second time. + * + * The emitter must emit both the 'integrity' and 'size' events. + * + * NOTE: If this option is provided, you must verify that you receive + * the correct integrity value yourself and emit an 'error' event if + * there is a mismatch. ssri Integrity Streams do this for you when + * given an expected integrity. + */ + integrityEmitter?: EventEmitter | undefined; + } + + interface PutStreamEvents extends Minipass.Events { + // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type + integrity: [integrity: string]; + + // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type + size: [size: number]; } /** @@ -196,7 +251,11 @@ export namespace put { * Emits an `integrity` event with the digest of written contents when it * succeeds. */ - function stream(cachePath: string, key: string, opts?: Options): NodeJS.WritableStream; + function stream( + cachePath: string, + key: string, + opts?: Options, + ): Minipass; } export namespace rm { diff --git a/types/cacache/package.json b/types/cacache/package.json index 5a3c77b554bf1d..897ca5dbe9f88f 100644 --- a/types/cacache/package.json +++ b/types/cacache/package.json @@ -1,12 +1,13 @@ { "private": true, "name": "@types/cacache", - "version": "19.0.9999", + "version": "20.0.9999", "projects": [ "https://github.com/npm/cacache#readme" ], "dependencies": { - "@types/node": "*" + "@types/node": "*", + "minipass": "*" }, "devDependencies": { "@types/cacache": "workspace:."