UNPKG

@socketsecurity/lib

Version:

Core utilities and infrastructure for Socket.dev security tools

297 lines (296 loc) 9.48 kB
"use strict"; /* Socket Lib - Built with esbuild */ var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var dlx_manifest_exports = {}; __export(dlx_manifest_exports, { DlxManifest: () => DlxManifest, dlxManifest: () => dlxManifest, isBinaryEntry: () => isBinaryEntry, isPackageEntry: () => isPackageEntry }); module.exports = __toCommonJS(dlx_manifest_exports); var import_fs = require("fs"); var import_path = __toESM(require("path")); var import_fs2 = require("./fs"); var import_logger = require("./logger"); var import_paths = require("./paths"); var import_process_lock = require("./process-lock"); const logger = (0, import_logger.getDefaultLogger)(); const MANIFEST_FILE_NAME = ".dlx-manifest.json"; function isPackageEntry(entry) { return entry.type === "package"; } function isBinaryEntry(entry) { return entry.type === "binary"; } class DlxManifest { manifestPath; lockPath; constructor(options = {}) { this.manifestPath = options.manifestPath ?? import_path.default.join((0, import_paths.getSocketDlxDir)(), MANIFEST_FILE_NAME); this.lockPath = `${this.manifestPath}.lock`; } /** * Read the entire manifest file. */ readManifest() { try { if (!(0, import_fs.existsSync)(this.manifestPath)) { return /* @__PURE__ */ Object.create(null); } const rawContent = (0, import_fs2.readFileUtf8Sync)(this.manifestPath); const content = (typeof rawContent === "string" ? rawContent : rawContent.toString("utf8")).trim(); if (!content) { return /* @__PURE__ */ Object.create(null); } return JSON.parse(content); } catch (error) { logger.warn( `Failed to read manifest: ${error instanceof Error ? error.message : String(error)}` ); return /* @__PURE__ */ Object.create(null); } } /** * Get a manifest entry by spec (e.g., "@socketsecurity/cli@^2.0.11"). */ getManifestEntry(spec) { const data = this.readManifest(); const entry = data[spec]; if (entry && "type" in entry) { return entry; } return void 0; } /** * Get cached update information for a package (legacy format). * @deprecated Use getManifestEntry() for new code. */ get(name) { const data = this.readManifest(); const entry = data[name]; if (entry && !("type" in entry)) { return entry; } return void 0; } /** * Set a package manifest entry. */ async setPackageEntry(spec, cacheKey, details) { await import_process_lock.processLock.withLock(this.lockPath, async () => { const data = this.readManifest(); data[spec] = { type: "package", cache_key: cacheKey, timestamp: Date.now(), details }; await this.writeManifest(data); }); } /** * Set a binary manifest entry. */ async setBinaryEntry(spec, cacheKey, details) { await import_process_lock.processLock.withLock(this.lockPath, async () => { const data = this.readManifest(); data[spec] = { type: "binary", cache_key: cacheKey, timestamp: Date.now(), details }; await this.writeManifest(data); }); } /** * Write the manifest file atomically. */ async writeManifest(data) { const manifestDir = import_path.default.dirname(this.manifestPath); try { (0, import_fs2.safeMkdirSync)(manifestDir, { recursive: true }); } catch (error) { logger.warn( `Failed to create manifest directory: ${error instanceof Error ? error.message : String(error)}` ); } const content = JSON.stringify(data, null, 2); const tempPath = `${this.manifestPath}.tmp`; try { (0, import_fs.writeFileSync)(tempPath, content, "utf8"); (0, import_fs.writeFileSync)(this.manifestPath, content, "utf8"); try { if ((0, import_fs.existsSync)(tempPath)) { (0, import_fs.unlinkSync)(tempPath); } } catch { } } catch (error) { try { if ((0, import_fs.existsSync)(tempPath)) { (0, import_fs.unlinkSync)(tempPath); } } catch { } throw error; } } /** * Store update information for a package (legacy format). * @deprecated Use setPackageEntry() for new code. */ async set(name, record) { await import_process_lock.processLock.withLock(this.lockPath, async () => { let data = /* @__PURE__ */ Object.create(null); try { if ((0, import_fs.existsSync)(this.manifestPath)) { const content2 = (0, import_fs.readFileSync)(this.manifestPath, "utf8"); if (content2.trim()) { data = JSON.parse(content2); } } } catch (error) { logger.warn( `Failed to read existing manifest: ${error instanceof Error ? error.message : String(error)}` ); } data[name] = record; const manifestDir = import_path.default.dirname(this.manifestPath); try { (0, import_fs2.safeMkdirSync)(manifestDir, { recursive: true }); } catch (error) { logger.warn( `Failed to create manifest directory: ${error instanceof Error ? error.message : String(error)}` ); } const content = JSON.stringify(data, null, 2); const tempPath = `${this.manifestPath}.tmp`; try { (0, import_fs.writeFileSync)(tempPath, content, "utf8"); (0, import_fs.writeFileSync)(this.manifestPath, content, "utf8"); try { if ((0, import_fs.existsSync)(tempPath)) { (0, import_fs.unlinkSync)(tempPath); } } catch { } } catch (error) { try { if ((0, import_fs.existsSync)(tempPath)) { (0, import_fs.unlinkSync)(tempPath); } } catch { } throw error; } }); } /** * Clear cached data for a specific entry. */ async clear(name) { await import_process_lock.processLock.withLock(this.lockPath, async () => { try { if (!(0, import_fs.existsSync)(this.manifestPath)) { return; } const content = (0, import_fs.readFileSync)(this.manifestPath, "utf8"); if (!content.trim()) { return; } const data = JSON.parse(content); delete data[name]; const updatedContent = JSON.stringify(data, null, 2); (0, import_fs.writeFileSync)(this.manifestPath, updatedContent, "utf8"); } catch (error) { logger.warn( `Failed to clear cache for ${name}: ${error instanceof Error ? error.message : String(error)}` ); } }); } /** * Clear all cached data. */ async clearAll() { await import_process_lock.processLock.withLock(this.lockPath, async () => { try { if ((0, import_fs.existsSync)(this.manifestPath)) { (0, import_fs.unlinkSync)(this.manifestPath); } } catch (error) { logger.warn( `Failed to clear all cache: ${error instanceof Error ? error.message : String(error)}` ); } }); } /** * Check if cached data is fresh based on TTL. */ isFresh(record, ttlMs) { if (!record) { return false; } const age = Date.now() - record.timestampFetch; return age < ttlMs; } /** * Get all cached package names. */ getAllPackages() { try { if (!(0, import_fs.existsSync)(this.manifestPath)) { return []; } const rawContent = (0, import_fs2.readFileUtf8Sync)(this.manifestPath); const content = (typeof rawContent === "string" ? rawContent : rawContent.toString("utf8")).trim(); if (!content) { return []; } const data = JSON.parse(content); return Object.keys(data); } catch (error) { logger.warn( `Failed to get package list: ${error instanceof Error ? error.message : String(error)}` ); return []; } } } const dlxManifest = new DlxManifest(); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { DlxManifest, dlxManifest, isBinaryEntry, isPackageEntry });