UNPKG

vlt

Version:
308 lines (306 loc) 8.73 kB
var global = globalThis; import {Buffer} from "node:buffer"; import {setTimeout,clearTimeout,setImmediate,clearImmediate,setInterval,clearInterval} from "node:timers"; import {createRequire as _vlt_createRequire} from "node:module"; var require = _vlt_createRequire(import.meta.filename); import { prettyBytes } from "./chunk-QGJUWLFF.js"; import { stderr, stdout } from "./chunk-KNHO4BUR.js"; import "./chunk-BQNTW6JU.js"; import { ViewClass } from "./chunk-YESBS37V.js"; import "./chunk-J25GTXK2.js"; import "./chunk-3VS4XBYN.js"; import { CacheEntry } from "./chunk-OTLTOVZN.js"; import { commandUsage } from "./chunk-L3E552CT.js"; import { Spec2 as Spec } from "./chunk-U5J4TCIV.js"; import "./chunk-KPA4XNCN.js"; import "./chunk-VYJVN3B6.js"; import "./chunk-B4MAUXR2.js"; import "./chunk-W7RMFRDJ.js"; import "./chunk-O57KIW5U.js"; import "./chunk-JBBINXAZ.js"; import "./chunk-OAYCZMD4.js"; import "./chunk-BA67AKYJ.js"; import { error } from "./chunk-KVH5ECIG.js"; import "./chunk-AECDW3EJ.js"; // ../../src/cli-sdk/src/commands/cache.ts import { mkdir, rm } from "node:fs/promises"; var view; var CacheView = class extends ViewClass { constructor(options, conf) { super(options, conf); view = this; } stdout(...args) { stdout(...args); } }; var views = { human: CacheView }; var usageDef = { command: "cache", usage: "<command> [flags]", description: "Work with vlt cache folders", subcommands: { add: { usage: "<package-spec> [<package-spec>...]", description: `Resolve the referenced package identifiers and ensure they are cached.` }, ls: { usage: "[<key>...]", description: `Show cache entries. If no keys are provided, then a list of available keys will be printed. If one or more keys are provided, then details will be shown for the specified items.` }, info: { usage: "<key>", description: `Print metadata details for the specified cache key to stderr, and the response body to stdout.` }, clean: { usage: "[<key>...]", description: `Purge expired cache entries. If one or more keys are provided, then only those cache entries will be considered.` }, delete: { usage: "<key> [<key>...]", description: `Purge items explicitly, whether expired or not. If one or more keys are provided, then only those cache entries will be considered.` }, "delete-before": { usage: "<date>", description: `Purge all cache items from before a given date. Date can be provided in any format that JavaScript can parse.` }, "delete-all": { usage: "", description: `Delete the entire cache folder to make vlt slower.` } }, examples: { "vlt cache ls https://registry.npmjs.org/typescript": { description: `Show cache metadata for a given registry URL` }, "vlt cache add eslint@latest": { description: `Add a given package specifier to the cache by fetching its resolved value.` }, "vlt cache info https://registry.npmjs.org/eslint/-/eslint-9.25.1.tgz > eslint.tgz": { description: `Print the cache metadata to stderr, and write the tarball on stdout, redirecting to a file.` }, "vlt cache delete-before 2025-01-01": { description: "Delete all entries created before Jan 1, 2025" } } }; var usage = () => commandUsage(usageDef); var command = async (conf) => { const [sub, ...args] = conf.positionals; switch (sub) { case "ls": return ls(conf, args, view); case "info": return info(conf, args, view); case "add": return add(conf, args, view); case "clean": return clean(conf, args, view); case "delete": return deleteKeys(conf, args, view); case "delete-before": return deleteBefore(conf, args, view); case "delete-all": return deleteAll(conf, args, view); default: { throw error("Unrecognized cache command", { code: "EUSAGE", found: sub, validOptions: Object.keys(usageDef.subcommands) }); } } }; var ls = async (conf, keys, view2) => keys.length ? await fetchKeys( conf, keys, (entry, key) => { view2?.stdout( key.includes(" ") ? JSON.stringify(key) : key, entry ); return true; }, view2 ) : await fetchAll(conf, (_, key) => { view2?.stdout(key.includes(" ") ? JSON.stringify(key) : key); return true; }); var info = async (conf, keys, view2) => { const [key] = keys; if (keys.length !== 1 || !key) { throw error("Must provide exactly one cache key", { code: "EUSAGE" }); } await fetchKeys( conf, [key], (entry, key2) => { stderr( /* c8 ignore next */ key2.includes(" ") ? JSON.stringify(key2) : key2, entry ); if (entry.isJSON) { stdout(JSON.stringify(entry.body, null, 2)); } else { process.stdout.write(entry.body); } return true; }, view2 ); }; var fetchAll = async (conf, test) => { const rc = conf.options.packageInfo.registryClient; const { cache } = rc; const map = {}; for await (const [key, val] of cache) { const entry = CacheEntry.decode(val); if (!test(entry, key, val)) continue; map[key] = entry.toJSON(); } return map; }; var fetchKeys = async (conf, keys, test, view2) => { const rc = conf.options.packageInfo.registryClient; const { cache } = rc; const map = {}; const results = await Promise.all( keys.map(async (key) => { return [key, await cache.fetch(key)]; }) ); for (const [key, val] of results) { if (!val) { view2?.stdout("Not found:", key); } else { const entry = CacheEntry.decode(val); if (!test(entry, key, val)) continue; map[key] = entry.toJSON(); } } return map; }; var deleteEntries = async (conf, keys, test, view2) => { const rc = conf.options.packageInfo.registryClient; const { cache } = rc; let count = 0; let size = 0; const testAction = (entry, key, val) => { if (!test(entry)) { return false; } count++; const s2 = val.byteLength + key.length; cache.delete(key, true, entry.integrity); const k = key.includes(" ") ? JSON.stringify(key) : key; view2?.stdout("-", k, s2); size += s2; return true; }; const map = await (keys.length ? fetchKeys(conf, keys, testAction, view2) : fetchAll(conf, testAction)); const pb = prettyBytes(size, { binary: true }); const s = count === 1 ? "" : "s"; await cache.promise(); view2?.stdout(`Removed ${count} item${s} totalling ${pb}`); return map; }; var clean = async (conf, keys, view2) => deleteEntries(conf, keys, (entry) => !entry.valid, view2); var deleteBefore = async (conf, args, view2) => { if (!args.length) { throw error("Must provide a date to delete before", { code: "EUSAGE" }); } const now = /* @__PURE__ */ new Date(); const before = new Date(args.join(" ")); if (before >= now) { throw error("Cannot delete cache entries from the future", { code: "EUSAGE", found: before }); } return deleteEntries( conf, [], (entry) => !!entry.date && entry.date < before, view2 ); }; var deleteKeys = async (conf, keys, view2) => { if (!keys.length) { throw error("Must provide cache keys to delete", { code: "EUSAGE" }); } return deleteEntries(conf, keys, () => true, view2); }; var deleteAll = async (conf, _, view2) => { const { cache } = conf.options.packageInfo.registryClient; await rm(cache.path(), { recursive: true, force: true }); await mkdir(cache.path(), { recursive: true }); view2?.stdout("Deleted all cache entries."); }; var add = async (conf, specs, view2) => { if (!specs.length) { throw error("Must provide specs to add to the cache", { code: "EUSAGE" }); } const { packageInfo } = conf.options; const promises = []; for (const spec of specs) { const p = packageInfo.resolve(Spec.parseArgs(spec, conf.options), { staleWhileRevalidate: false }).then(async (r) => { const { resolved, integrity } = r; await packageInfo.registryClient.request(resolved, { ...conf.options, integrity, staleWhileRevalidate: false, query: void 0 }); view2?.stdout("+", spec, r.resolved); }); promises.push(p); } await Promise.all(promises); }; export { CacheView, command, usage, views }; //# sourceMappingURL=cache-WBS2SOZN.js.map