mirror of
https://github.com/denoland/deno.git
synced 2024-11-29 16:30:56 -05:00
1 line
26 KiB
JSON
1 line
26 KiB
JSON
{"name":"cacache","description":"Fast, fault-tolerant, cross-platform, disk-based, data-agnostic, content-addressable cache.","dist-tags":{"latest":"18.0.3"},"versions":{"18.0.3":{"name":"cacache","version":"18.0.3","author":{"name":"GitHub Inc."},"license":"ISC","_id":"cacache@18.0.3","bugs":{"url":"https://github.com/npm/cacache/issues"},"tap":{"nyc-arg":["--exclude","tap-snapshots/**"]},"dist":{"shasum":"864e2c18414e1e141ae8763f31e46c2cb96d1b21","tarball":"http://localhost:4260/cacache/cacache-18.0.3.tgz","fileCount":17,"integrity":"sha512-qXCd4rh6I07cnDqh8V48/94Tc/WSfj+o3Gn6NZ0aZovS255bUx8O13uKxRFd2eWG0xgsco7+YItQNPaa5E85hg==","signatures":[{"sig":"MEUCIQCC/lkDf8YH7ovTQqLbvK15fnzGfIJD1adj7kQqKK+peAIgWnG8F6vXojVvrsufossNxTJRwkt3kB21imzmvzAlRxI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"attestations":{"url":"http://localhost:4260/attestations/cacache@18.0.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":63516},"main":"lib/index.js","engines":{"node":"^16.14.0 || >=18.0.0"},"gitHead":"f9ebcea7e36403d37cd46da1567f40302b950ea7","scripts":{"lint":"eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"","snap":"tap","test":"tap","lintfix":"npm run lint -- --fix","coverage":"tap","postlint":"template-oss-check","postsnap":"npm run lintfix --","posttest":"npm run lint","npmclilint":"npmcli-lint","test-docker":"docker run -it --rm --name pacotest -v \"$PWD\":/tmp -w /tmp node:latest npm test","template-oss-apply":"template-oss-apply --force"},"repository":{"url":"git+https://github.com/npm/cacache.git","type":"git"},"_npmVersion":"10.7.0","description":"Fast, fault-tolerant, cross-platform, disk-based, data-agnostic, content-addressable cache.","directories":{},"templateOSS":{"publish":"true","version":"4.22.0","windowsCI":false,"//@npmcli/template-oss":"This file is partially managed by @npmcli/template-oss. Edits may be overwritten."},"_nodeVersion":"22.1.0","dependencies":{"tar":"^6.1.11","glob":"^10.2.2","ssri":"^10.0.0","p-map":"^4.0.0","minipass":"^7.0.3","lru-cache":"^10.0.1","@npmcli/fs":"^3.1.0","fs-minipass":"^3.0.0","minipass-flush":"^1.0.5","unique-filename":"^3.0.0","minipass-collect":"^2.0.1","minipass-pipeline":"^1.2.4"},"cache-version":{"index":"5","content":"2"},"_hasShrinkwrap":false,"devDependencies":{"tap":"^16.0.0","@npmcli/template-oss":"4.22.0","@npmcli/eslint-config":"^4.0.0"}}},"author":{"name":"GitHub Inc."},"repository":{"url":"git+https://github.com/npm/cacache.git","type":"git"},"license":"ISC","homepage":"https://github.com/npm/cacache#readme","bugs":{"url":"https://github.com/npm/cacache/issues"},"readme":"# cacache [![npm version](https://img.shields.io/npm/v/cacache.svg)](https://npm.im/cacache) [![license](https://img.shields.io/npm/l/cacache.svg)](https://npm.im/cacache) [![Travis](https://img.shields.io/travis/npm/cacache.svg)](https://travis-ci.org/npm/cacache) [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/npm/cacache?svg=true)](https://ci.appveyor.com/project/npm/cacache) [![Coverage Status](https://coveralls.io/repos/github/npm/cacache/badge.svg?branch=latest)](https://coveralls.io/github/npm/cacache?branch=latest)\n\n[`cacache`](https://github.com/npm/cacache) is a Node.js library for managing\nlocal key and content address caches. It's really fast, really good at\nconcurrency, and it will never give you corrupted data, even if cache files\nget corrupted or manipulated.\n\nOn systems that support user and group settings on files, cacache will\nmatch the `uid` and `gid` values to the folder where the cache lives, even\nwhen running as `root`.\n\nIt was written to be used as [npm](https://npm.im)'s local cache, but can\njust as easily be used on its own.\n\n## Install\n\n`$ npm install --save cacache`\n\n## Table of Contents\n\n* [Example](#example)\n* [Features](#features)\n* [Contributing](#contributing)\n* [API](#api)\n * [Using localized APIs](#localized-api)\n * Reading\n * [`ls`](#ls)\n * [`ls.stream`](#ls-stream)\n * [`get`](#get-data)\n * [`get.stream`](#get-stream)\n * [`get.info`](#get-info)\n * [`get.hasContent`](#get-hasContent)\n * Writing\n * [`put`](#put-data)\n * [`put.stream`](#put-stream)\n * [`rm.all`](#rm-all)\n * [`rm.entry`](#rm-entry)\n * [`rm.content`](#rm-content)\n * [`index.compact`](#index-compact)\n * [`index.insert`](#index-insert)\n * Utilities\n * [`clearMemoized`](#clear-memoized)\n * [`tmp.mkdir`](#tmp-mkdir)\n * [`tmp.withTmp`](#with-tmp)\n * Integrity\n * [Subresource Integrity](#integrity)\n * [`verify`](#verify)\n * [`verify.lastRun`](#verify-last-run)\n\n### Example\n\n```javascript\nconst cacache = require('cacache')\nconst fs = require('fs')\n\nconst cachePath = '/tmp/my-toy-cache'\nconst key = 'my-unique-key-1234'\n\n// Cache it! Use `cachePath` as the root of the content cache\ncacache.put(cachePath, key, '10293801983029384').then(integrity => {\n console.log(`Saved content to ${cachePath}.`)\n})\n\nconst destination = '/tmp/mytar.tgz'\n\n// Copy the contents out of the cache and into their destination!\n// But this time, use stream instead!\ncacache.get.stream(\n cachePath, key\n).pipe(\n fs.createWriteStream(destination)\n).on('finish', () => {\n console.log('done extracting!')\n})\n\n// The same thing, but skip the key index.\ncacache.get.byDigest(cachePath, integrityHash).then(data => {\n fs.writeFile(destination, data, err => {\n console.log('tarball data fetched based on its sha512sum and written out!')\n })\n})\n```\n\n### Features\n\n* Extraction by key or by content address (shasum, etc)\n* [Subresource Integrity](#integrity) web standard support\n* Multi-hash support - safely host sha1, sha512, etc, in a single cache\n* Automatic content deduplication\n* Fault tolerance (immune to corruption, partial writes, process races, etc)\n* Consistency guarantees on read and write (full data verification)\n* Lockless, high-concurrency cache access\n* Streaming support\n* Promise support\n* Fast -- sub-millisecond reads and writes including verification\n* Arbitrary metadata storage\n* Garbage collection and additional offline verification\n* Thorough test coverage\n* There's probably a bloom filter in there somewhere. Those are cool, right? 🤔\n\n### Contributing\n\nThe cacache team enthusiastically welcomes contributions and project participation! There's a bunch of things you can do if you want to contribute! Please don't hesitate to jump in if you'd like to, or even ask us questions if something isn't clear.\n\nAll participants and maintainers in this project are expected to follow [Code of Conduct](CODE_OF_CONDUCT.md), and just generally be excellent to each other.\n\nPlease refer to the [Changelog](CHANGELOG.md) for project history details, too.\n\nHappy hacking!\n\n### API\n\n#### <a name=\"ls\"></a> `> cacache.ls(cache) -> Promise<Object>`\n\nLists info for all entries currently in the cache as a single large object. Each\nentry in the object will be keyed by the unique index key, with corresponding\n[`get.info`](#get-info) objects as the values.\n\n##### Example\n\n```javascript\ncacache.ls(cachePath).then(console.log)\n// Output\n{\n 'my-thing': {\n key: 'my-thing',\n integrity: 'sha512-BaSe64/EnCoDED+HAsh=='\n path: '.testcache/content/deadbeef', // joined with `cachePath`\n time: 12345698490,\n size: 4023948,\n metadata: {\n name: 'blah',\n version: '1.2.3',\n description: 'this was once a package but now it is my-thing'\n }\n },\n 'other-thing': {\n key: 'other-thing',\n integrity: 'sha1-ANothER+hasH=',\n path: '.testcache/content/bada55',\n time: 11992309289,\n size: 111112\n }\n}\n```\n\n#### <a name=\"ls-stream\"></a> `> cacache.ls.stream(cache) -> Readable`\n\nLists info for all entries currently in the cache as a single large object.\n\nThis works just like [`ls`](#ls), except [`get.info`](#get-info) entries are\nreturned as `'data'` events on the returned stream.\n\n##### Example\n\n```javascript\ncacache.ls.stream(cachePath).on('data', console.log)\n// Output\n{\n key: 'my-thing',\n integrity: 'sha512-BaSe64HaSh',\n path: '.testcache/content/deadbeef', // joined with `cachePath`\n time: 12345698490,\n size: 13423,\n metadata: {\n name: 'blah',\n version: '1.2.3',\n description: 'this was once a package but now it is my-thing'\n }\n}\n\n{\n key: 'other-thing',\n integrity: 'whirlpool-WoWSoMuchSupport',\n path: '.testcache/content/bada55',\n time: 11992309289,\n size: 498023984029\n}\n\n{\n ...\n}\n```\n\n#### <a name=\"get-data\"></a> `> cacache.get(cache, key, [opts]) -> Promise({data, metadata, integrity})`\n\nReturns an object with the cached data, digest, and metadata identified by\n`key`. The `data` property of this object will be a `Buffer` instance that\npresumably holds some data that means something to you. I'm sure you know what\nto do with it! cacache just won't care.\n\n`integrity` is a [Subresource\nIntegrity](#integrity)\nstring. That is, a string that can be used to verify `data`, which looks like\n`<hash-algorithm>-<base64-integrity-hash>`.\n\nIf there is no content identified by `key`, or if the locally-stored data does\nnot pass the validity checksum, the promise will be rejected.\n\nA sub-function, `get.byDigest` may be used for identical behavior, except lookup\nwill happen by integrity hash, bypassing the index entirely. This version of the\nfunction *only* returns `data` itself, without any wrapper.\n\nSee: [options](#get-options)\n\n##### Note\n\nThis function loads the entire cache entry into memory before returning it. If\nyou're dealing with Very Large data, consider using [`get.stream`](#get-stream)\ninstead.\n\n##### Example\n\n```javascript\n// Look up by key\ncache.get(cachePath, 'my-thing').then(console.log)\n// Output:\n{\n metadata: {\n thingName: 'my'\n },\n integrity: 'sha512-BaSe64HaSh',\n data: Buffer#<deadbeef>,\n size: 9320\n}\n\n// Look up by digest\ncache.get.byDigest(cachePath, 'sha512-BaSe64HaSh').then(console.log)\n// Output:\nBuffer#<deadbeef>\n```\n\n#### <a name=\"get-stream\"></a> `> cacache.get.stream(cache, key, [opts]) -> Readable`\n\nReturns a [Readable Stream](https://nodejs.org/api/stream.html#stream_readable_streams) of the cached data identified by `key`.\n\nIf there is no content identified by `key`, or if the locally-stored data does\nnot pass the validity checksum, an error will be emitted.\n\n`metadata` and `integrity` events will be emitted before the stream closes, if\nyou need to collect that extra data about the cached entry.\n\nA sub-function, `get.stream.byDigest` may be used for identical behavior,\nexcept lookup will happen by integrity hash, bypassing the index entirely. This\nversion does not emit the `metadata` and `integrity` events at all.\n\nSee: [options](#get-options)\n\n##### Example\n\n```javascript\n// Look up by key\ncache.get.stream(\n cachePath, 'my-thing'\n).on('metadata', metadata => {\n console.log('metadata:', metadata)\n}).on('integrity', integrity => {\n console.log('integrity:', integrity)\n}).pipe(\n fs.createWriteStream('./x.tgz')\n)\n// Outputs:\nmetadata: { ... }\nintegrity: 'sha512-SoMeDIGest+64=='\n\n// Look up by digest\ncache.get.stream.byDigest(\n cachePath, 'sha512-SoMeDIGest+64=='\n).pipe(\n fs.createWriteStream('./x.tgz')\n)\n```\n\n#### <a name=\"get-info\"></a> `> cacache.get.info(cache, key) -> Promise`\n\nLooks up `key` in the cache index, returning information about the entry if\none exists.\n\n##### Fields\n\n* `key` - Key the entry was looked up under. Matches the `key` argument.\n* `integrity` - [Subresource Integrity hash](#integrity) for the content this entry refers to.\n* `path` - Filesystem path where content is stored, joined with `cache` argument.\n* `time` - Timestamp the entry was first added on.\n* `metadata` - User-assigned metadata associated with the entry/content.\n\n##### Example\n\n```javascript\ncacache.get.info(cachePath, 'my-thing').then(console.log)\n\n// Output\n{\n key: 'my-thing',\n integrity: 'sha256-MUSTVERIFY+ALL/THINGS=='\n path: '.testcache/content/deadbeef',\n time: 12345698490,\n size: 849234,\n metadata: {\n name: 'blah',\n version: '1.2.3',\n description: 'this was once a package but now it is my-thing'\n }\n}\n```\n\n#### <a name=\"get-hasContent\"></a> `> cacache.get.hasContent(cache, integrity) -> Promise`\n\nLooks up a [Subresource Integrity hash](#integrity) in the cache. If content\nexists for this `integrity`, it will return an object, with the specific single integrity hash\nthat was found in `sri` key, and the size of the found content as `size`. If no content exists for this integrity, it will return `false`.\n\n##### Example\n\n```javascript\ncacache.get.hasContent(cachePath, 'sha256-MUSTVERIFY+ALL/THINGS==').then(console.log)\n\n// Output\n{\n sri: {\n source: 'sha256-MUSTVERIFY+ALL/THINGS==',\n algorithm: 'sha256',\n digest: 'MUSTVERIFY+ALL/THINGS==',\n options: []\n },\n size: 9001\n}\n\ncacache.get.hasContent(cachePath, 'sha521-NOT+IN/CACHE==').then(console.log)\n\n// Output\nfalse\n```\n\n##### <a name=\"get-options\"></a> Options\n\n##### `opts.integrity`\nIf present, the pre-calculated digest for the inserted content. If this option\nis provided and does not match the post-insertion digest, insertion will fail\nwith an `EINTEGRITY` error.\n\n##### `opts.memoize`\n\nDefault: null\n\nIf explicitly truthy, cacache will read from memory and memoize data on bulk read. If `false`, cacache will read from disk data. Reader functions by default read from in-memory cache.\n\n##### `opts.size`\nIf provided, the data stream will be verified to check that enough data was\npassed through. If there's more or less data than expected, insertion will fail\nwith an `EBADSIZE` error.\n\n\n#### <a name=\"put-data\"></a> `> cacache.put(cache, key, data, [opts]) -> Promise`\n\nInserts data passed to it into the cache. The returned Promise resolves with a\ndigest (generated according to [`opts.algorithms`](#optsalgorithms)) after the\ncache entry has been successfully written.\n\nSee: [options](#put-options)\n\n##### Example\n\n```javascript\nfetch(\n 'http://localhost:4260/cacache/cacache-1.0.0.tgz'\n).then(data => {\n return cacache.put(cachePath, 'registry.npmjs.org|cacache@1.0.0', data)\n}).then(integrity => {\n console.log('integrity hash is', integrity)\n})\n```\n\n#### <a name=\"put-stream\"></a> `> cacache.put.stream(cache, key, [opts]) -> Writable`\n\nReturns a [Writable\nStream](https://nodejs.org/api/stream.html#stream_writable_streams) that inserts\ndata written to it into the cache. Emits an `integrity` event with the digest of\nwritten contents when it succeeds.\n\nSee: [options](#put-options)\n\n##### Example\n\n```javascript\nrequest.get(\n 'http://localhost:4260/cacache/cacache-1.0.0.tgz'\n).pipe(\n cacache.put.stream(\n cachePath, 'registry.npmjs.org|cacache@1.0.0'\n ).on('integrity', d => console.log(`integrity digest is ${d}`))\n)\n```\n\n##### <a name=\"put-options\"></a> Options\n\n##### `opts.metadata`\n\nArbitrary metadata to be attached to the inserted key.\n\n##### `opts.size`\n\nIf provided, the data stream will be verified to check that enough data was\npassed through. If there's more or less data than expected, insertion will fail\nwith an `EBADSIZE` error.\n\n##### `opts.integrity`\n\nIf present, the pre-calculated digest for the inserted content. If this option\nis provided and does not match the post-insertion digest, insertion will fail\nwith an `EINTEGRITY` error.\n\n`algorithms` has no effect if this option is present.\n\n##### `opts.integrityEmitter`\n\n*Streaming only* If present, uses the provided event emitter as a source of\ntruth for both integrity and size. This allows use cases where integrity is\nalready being calculated outside of cacache to reuse that data instead of\ncalculating it a second time.\n\nThe emitter must emit both the `'integrity'` and `'size'` events.\n\nNOTE: If this option is provided, you must verify that you receive the correct\nintegrity value yourself and emit an `'error'` event if there is a mismatch.\n[ssri Integrity Streams](https://github.com/npm/ssri#integrity-stream) do this for you when given an expected integrity.\n\n##### `opts.algorithms`\n\nDefault: ['sha512']\n\nHashing algorithms to use when calculating the [subresource integrity\ndigest](#integrity)\nfor inserted data. Can use any algorithm listed in `crypto.getHashes()` or\n`'omakase'`/`'お任せします'` to pick a random hash algorithm on each insertion. You\nmay also use any anagram of `'modnar'` to use this feature.\n\nCurrently only supports one algorithm at a time (i.e., an array length of\nexactly `1`). Has no effect if `opts.integrity` is present.\n\n##### `opts.memoize`\n\nDefault: null\n\nIf provided, cacache will memoize the given cache insertion in memory, bypassing\nany filesystem checks for that key or digest in future cache fetches. Nothing\nwill be written to the in-memory cache unless this option is explicitly truthy.\n\nIf `opts.memoize` is an object or a `Map`-like (that is, an object with `get`\nand `set` methods), it will be written to instead of the global memoization\ncache.\n\nReading from disk data can be forced by explicitly passing `memoize: false` to\nthe reader functions, but their default will be to read from memory.\n\n##### `opts.tmpPrefix`\nDefault: null\n\nPrefix to append on the temporary directory name inside the cache's tmp dir. \n\n#### <a name=\"rm-all\"></a> `> cacache.rm.all(cache) -> Promise`\n\nClears the entire cache. Mainly by blowing away the cache directory itself.\n\n##### Example\n\n```javascript\ncacache.rm.all(cachePath).then(() => {\n console.log('THE APOCALYPSE IS UPON US 😱')\n})\n```\n\n#### <a name=\"rm-entry\"></a> `> cacache.rm.entry(cache, key, [opts]) -> Promise`\n\nAlias: `cacache.rm`\n\nRemoves the index entry for `key`. Content will still be accessible if\nrequested directly by content address ([`get.stream.byDigest`](#get-stream)).\n\nBy default, this appends a new entry to the index with an integrity of `null`.\nIf `opts.removeFully` is set to `true` then the index file itself will be\nphysically deleted rather than appending a `null`.\n\nTo remove the content itself (which might still be used by other entries), use\n[`rm.content`](#rm-content). Or, to safely vacuum any unused content, use\n[`verify`](#verify).\n\n##### Example\n\n```javascript\ncacache.rm.entry(cachePath, 'my-thing').then(() => {\n console.log('I did not like it anyway')\n})\n```\n\n#### <a name=\"rm-content\"></a> `> cacache.rm.content(cache, integrity) -> Promise`\n\nRemoves the content identified by `integrity`. Any index entries referring to it\nwill not be usable again until the content is re-added to the cache with an\nidentical digest.\n\n##### Example\n\n```javascript\ncacache.rm.content(cachePath, 'sha512-SoMeDIGest/IN+BaSE64==').then(() => {\n console.log('data for my-thing is gone!')\n})\n```\n\n#### <a name=\"index-compact\"></a> `> cacache.index.compact(cache, key, matchFn, [opts]) -> Promise`\n\nUses `matchFn`, which must be a synchronous function that accepts two entries\nand returns a boolean indicating whether or not the two entries match, to\ndeduplicate all entries in the cache for the given `key`.\n\nIf `opts.validateEntry` is provided, it will be called as a function with the\nonly parameter being a single index entry. The function must return a Boolean,\nif it returns `true` the entry is considered valid and will be kept in the index,\nif it returns `false` the entry will be removed from the index.\n\nIf `opts.validateEntry` is not provided, however, every entry in the index will\nbe deduplicated and kept until the first `null` integrity is reached, removing\nall entries that were written before the `null`.\n\nThe deduplicated list of entries is both written to the index, replacing the\nexisting content, and returned in the Promise.\n\n#### <a name=\"index-insert\"></a> `> cacache.index.insert(cache, key, integrity, opts) -> Promise`\n\nWrites an index entry to the cache for the given `key` without writing content.\n\nIt is assumed if you are using this method, you have already stored the content\nsome other way and you only wish to add a new index to that content. The `metadata`\nand `size` properties are read from `opts` and used as part of the index entry.\n\nReturns a Promise resolving to the newly added entry.\n\n#### <a name=\"clear-memoized\"></a> `> cacache.clearMemoized()`\n\nCompletely resets the in-memory entry cache.\n\n#### <a name=\"tmp-mkdir\"></a> `> tmp.mkdir(cache, opts) -> Promise<Path>`\n\nReturns a unique temporary directory inside the cache's `tmp` dir. This\ndirectory will use the same safe user assignment that all the other stuff use.\n\nOnce the directory is made, it's the user's responsibility that all files\nwithin are given the appropriate `gid`/`uid` ownership settings to match\nthe rest of the cache. If not, you can ask cacache to do it for you by\ncalling [`tmp.fix()`](#tmp-fix), which will fix all tmp directory\npermissions.\n\nIf you want automatic cleanup of this directory, use\n[`tmp.withTmp()`](#with-tpm)\n\nSee: [options](#tmp-options)\n\n##### Example\n\n```javascript\ncacache.tmp.mkdir(cache).then(dir => {\n fs.writeFile(path.join(dir, 'blablabla'), Buffer#<1234>, ...)\n})\n```\n\n#### <a name=\"tmp-fix\"></a> `> tmp.fix(cache) -> Promise`\n\nSets the `uid` and `gid` properties on all files and folders within the tmp\nfolder to match the rest of the cache.\n\nUse this after manually writing files into [`tmp.mkdir`](#tmp-mkdir) or\n[`tmp.withTmp`](#with-tmp).\n\n##### Example\n\n```javascript\ncacache.tmp.mkdir(cache).then(dir => {\n writeFile(path.join(dir, 'file'), someData).then(() => {\n // make sure we didn't just put a root-owned file in the cache\n cacache.tmp.fix().then(() => {\n // all uids and gids match now\n })\n })\n})\n```\n\n#### <a name=\"with-tmp\"></a> `> tmp.withTmp(cache, opts, cb) -> Promise`\n\nCreates a temporary directory with [`tmp.mkdir()`](#tmp-mkdir) and calls `cb`\nwith it. The created temporary directory will be removed when the return value\nof `cb()` resolves, the tmp directory will be automatically deleted once that \npromise completes.\n\nThe same caveats apply when it comes to managing permissions for the tmp dir's\ncontents.\n\nSee: [options](#tmp-options)\n\n##### Example\n\n```javascript\ncacache.tmp.withTmp(cache, dir => {\n return fs.writeFile(path.join(dir, 'blablabla'), 'blabla contents', { encoding: 'utf8' })\n}).then(() => {\n // `dir` no longer exists\n})\n```\n\n##### <a name=\"tmp-options\"></a> Options\n\n##### `opts.tmpPrefix`\nDefault: null\n\nPrefix to append on the temporary directory name inside the cache's tmp dir. \n\n#### <a name=\"integrity\"></a> Subresource Integrity Digests\n\nFor content verification and addressing, cacache uses strings following the\n[Subresource\nIntegrity spec](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity).\nThat is, any time cacache expects an `integrity` argument or option, it\nshould be in the format `<hashAlgorithm>-<base64-hash>`.\n\nOne deviation from the current spec is that cacache will support any hash\nalgorithms supported by the underlying Node.js process. You can use\n`crypto.getHashes()` to see which ones you can use.\n\n##### Generating Digests Yourself\n\nIf you have an existing content shasum, they are generally formatted as a\nhexadecimal string (that is, a sha1 would look like:\n`5f5513f8822fdbe5145af33b64d8d970dcf95c6e`). In order to be compatible with\ncacache, you'll need to convert this to an equivalent subresource integrity\nstring. For this example, the corresponding hash would be:\n`sha1-X1UT+IIv2+UUWvM7ZNjZcNz5XG4=`.\n\nIf you want to generate an integrity string yourself for existing data, you can\nuse something like this:\n\n```javascript\nconst crypto = require('crypto')\nconst hashAlgorithm = 'sha512'\nconst data = 'foobarbaz'\n\nconst integrity = (\n hashAlgorithm +\n '-' +\n crypto.createHash(hashAlgorithm).update(data).digest('base64')\n)\n```\n\nYou can also use [`ssri`](https://npm.im/ssri) to have a richer set of functionality\naround SRI strings, including generation, parsing, and translating from existing\nhex-formatted strings.\n\n#### <a name=\"verify\"></a> `> cacache.verify(cache, opts) -> Promise`\n\nChecks out and fixes up your cache:\n\n* Cleans up corrupted or invalid index entries.\n* Custom entry filtering options.\n* Garbage collects any content entries not referenced by the index.\n* Checks integrity for all content entries and removes invalid content.\n* Fixes cache ownership.\n* Removes the `tmp` directory in the cache and all its contents.\n\nWhen it's done, it'll return an object with various stats about the verification\nprocess, including amount of storage reclaimed, number of valid entries, number\nof entries removed, etc.\n\n##### <a name=\"verify-options\"></a> Options\n\n##### `opts.concurrency`\n\nDefault: 20\n\nNumber of concurrently read files in the filesystem while doing clean up.\n\n##### `opts.filter`\nReceives a formatted entry. Return false to remove it.\nNote: might be called more than once on the same entry.\n\n##### `opts.log`\nCustom logger function:\n```\n log: { silly () {} }\n log.silly('verify', 'verifying cache at', cache)\n```\n\n##### Example\n\n```sh\necho somegarbage >> $CACHEPATH/content/deadbeef\n```\n\n```javascript\ncacache.verify(cachePath).then(stats => {\n // deadbeef collected, because of invalid checksum.\n console.log('cache is much nicer now! stats:', stats)\n})\n```\n\n#### <a name=\"verify-last-run\"></a> `> cacache.verify.lastRun(cache) -> Promise`\n\nReturns a `Date` representing the last time `cacache.verify` was run on `cache`.\n\n##### Example\n\n```javascript\ncacache.verify(cachePath).then(() => {\n cacache.verify.lastRun(cachePath).then(lastTime => {\n console.log('cacache.verify was last called on' + lastTime)\n })\n})\n```\n","readmeFilename":"README.md"}
|