Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@vltpkg/rollback-remove

Package Overview
Dependencies
Maintainers
6
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vltpkg/rollback-remove - npm Package Compare versions

Comparing version
1.0.0-rc.23
to
1.0.0-rc.24
+6
dist/index.d.ts
export declare class RollbackRemove {
#private;
rm(path: string): Promise<void>;
confirm(): void;
rollback(): Promise<void>;
}
import { spawn } from 'node:child_process';
import { rename } from 'node:fs/promises';
import { basename, dirname } from 'node:path';
import { rimraf } from 'rimraf';
import { __CODE_SPLIT_SCRIPT_NAME } from "./remove.js";
const isDeno = globalThis.Deno != undefined;
export class RollbackRemove {
#key = String(Math.random()).substring(2);
#paths = new Map();
async rm(path) {
if (this.#paths.has(path))
return;
const target = `${dirname(path)}/.VLT.DELETE.${this.#key}.${basename(path)}`;
this.#paths.set(path, target);
await rename(path, target).catch((e) => {
if (e instanceof Error &&
'code' in e &&
/* c8 ignore start - very spurious weirdness on Windows */
(e.code === 'ENOENT' || e.code === 'EPERM')
/* c8 ignore stop */
) {
this.#paths.delete(path);
return;
}
/* c8 ignore next */
throw e;
});
}
confirm() {
// nothing to confirm!
if (!this.#paths.size)
return;
const env = { ...process.env };
const args = [];
// Deno on Windows does not support detached processes
// https://github.com/denoland/deno/issues/25867
// TODO: figure out something better to do here?
const detached = !(isDeno && process.platform === 'win32');
// If we are running deno from source we need to add the
// unstable flags we need. The '-A' flag does not need
// to be passed in as Deno supplies that automatically.
if (isDeno) {
args.push('--unstable-node-globals', '--unstable-bare-node-builtins');
}
args.push(__CODE_SPLIT_SCRIPT_NAME);
const child = spawn(process.execPath, args, {
stdio: ['pipe', 'ignore', 'ignore'],
detached,
env,
});
for (const path of this.#paths.values()) {
child.stdin.write(`${path}\0`);
}
child.stdin.end();
if (detached) {
child.unref();
}
this.#paths.clear();
}
async rollback() {
const promises = [];
for (const [original, moved] of this.#paths) {
promises.push(rimraf(original)
/* c8 ignore next */
.catch(() => { })
.then(() => rename(moved, original)));
}
await Promise.all(promises);
this.#paths.clear();
}
}
export declare const __CODE_SPLIT_SCRIPT_NAME: string;
import { pathToFileURL } from 'node:url';
import { rimraf } from 'rimraf';
export const __CODE_SPLIT_SCRIPT_NAME = import.meta.filename;
const isMain = (path) => path === __CODE_SPLIT_SCRIPT_NAME ||
path === pathToFileURL(__CODE_SPLIT_SCRIPT_NAME).toString();
// This is run as a background process, and all the paths to
// be removed written into stdin. We can't pass on argv, because
// it'll be a very long list in many cases.
const main = async () => {
const paths = await new Promise(res => {
const chunks = [];
let chunkLen = 0;
process.stdin.on('data', chunk => {
chunks.push(chunk);
chunkLen += chunk.length;
});
process.stdin.on('end', () => {
res(Buffer.concat(chunks, chunkLen)
.toString()
.split('\0')
.filter(i => !!i));
});
});
if (paths.length) {
await rimraf(paths);
}
};
if (isMain(process.argv[1])) {
await main();
}
+1
-1
{
"name": "@vltpkg/rollback-remove",
"description": "Mark paths as removed, then remove them or roll back",
"version": "1.0.0-rc.23",
"version": "1.0.0-rc.24",
"repository": {

@@ -6,0 +6,0 @@ "type": "git",