Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

filesystem-sandbox

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

filesystem-sandbox - npm Package Compare versions

Comparing version 1.19.0 to 1.19.1

dist/filesystem-sandbox.d.ts

46

dist/index.d.ts

@@ -1,44 +0,2 @@

/// <reference types="node" />
import { StatsBase } from "fs";
export declare type Func<T> = () => T;
export declare type AsyncFunc<T> = () => Promise<T>;
export declare const basePrefix = "__sandboxes__";
export declare class Sandbox {
private readonly _path;
private readonly _base;
private readonly _at;
get path(): string;
constructor(at?: string);
destroy(): Promise<void>;
private tryDestroyAt;
private tryDestroyContainer;
private destroyFolderIfEmpty;
private tryDestroySelf;
writeFile(at: string, contents: string | Buffer | string[]): Promise<string>;
appendFile(at: string, contents: string | Buffer | string[]): Promise<string>;
mkdir(name: string): Promise<string>;
private resolveRelativePath;
readTextFile(at: string): Promise<string>;
readFile(at: string): Promise<Buffer>;
fullPathFor(relativePath: string, ...parts: string[]): string;
stat(at: string): Promise<StatsBase<any> | null>;
folderExists(at: string): Promise<boolean>;
fileExists(at: string): Promise<boolean>;
private runOnStat;
run<T>(fn: Func<T> | AsyncFunc<T>, relativePath?: string): Promise<T>;
private _validatePathInsideSandbox;
/**
* Destroys all sandboxes created in this process up until now
*/
static destroyAll(): Promise<void>;
/**
* Destroys the default base folder for sandboxes -- useful as a once-off
* run before all tests to ensure that there are no lingering sandboxes
* - cannot destroy sandboxes in custom paths
*/
static destroyAny(): Promise<void>;
static create(at?: string): Promise<Sandbox>;
static setBaseTargetToCurrentWorkingDirectory(): Promise<void>;
static setBaseTargetToSystemTempFolder(): Promise<void>;
static setBaseTarget(to: string): Promise<void>;
}
export * from "./filesystem-sandbox";
export * from "./index";

@@ -9,240 +9,8 @@ "use strict";

}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Sandbox = exports.basePrefix = void 0;
const fs_1 = require("fs");
const os = __importStar(require("os"));
if (!fs_1.promises) {
throw new Error("Yer node is olde! filesystem-sandboxes requires a Node with fs.promises");
}
// require for "path" produces the cleanest js output
const path_1 = __importDefault(require("path"));
const uuid_1 = require("uuid");
const mkdirp_1 = require("mkdirp");
const rimraf_1 = require("rimraf");
const { writeFile, readFile, stat, appendFile } = fs_1.promises;
async function isFolder(p) {
try {
const st = await stat(p);
return st && st.isDirectory();
}
catch (e) {
return false;
}
}
async function readdir(p) {
const exists = await isFolder(p);
if (!exists) {
return [];
}
return await fs_1.promises.readdir(p);
}
async function rimraf(p) {
if (!(await isFolder(p))) {
return;
}
return new Promise((resolve, reject) => {
try {
rimraf_1.sync(p, { maxBusyTries: 5 });
resolve();
}
catch (e) {
reject(e);
}
});
}
exports.basePrefix = "__sandboxes__";
let baseTarget = os.tmpdir();
const sandboxes = [];
async function writeData(fullPath, contents, writeFunction) {
const options = contents instanceof Buffer
? undefined
: { encoding: "utf8" };
if (Array.isArray(contents)) {
contents = contents.join("\n");
}
await writeFunction(fullPath, contents, options);
return fullPath;
}
class Sandbox {
constructor(at) {
this._at = at;
this._base = path_1.default.join(at || baseTarget, exports.basePrefix);
this._path = path_1.default.join(this._base, uuid_1.v4());
mkdirp_1.sync(this._path);
sandboxes.push(this);
}
get path() {
return this._path;
}
async destroy() {
await this.tryDestroySelf();
await this.tryDestroyContainer();
await this.tryDestroyAt();
}
async tryDestroyAt() {
if (!this._at) {
return;
}
await this.destroyFolderIfEmpty(this._at);
}
async tryDestroyContainer() {
await this.destroyFolderIfEmpty(this._base);
}
async destroyFolderIfEmpty(p) {
const contents = await readdir(p);
if (!contents.length) {
await rimraf(p);
}
}
async tryDestroySelf() {
const myIndex = sandboxes.indexOf(this);
if (myIndex > -1) {
sandboxes.splice(myIndex, 1);
}
await rimraf(this._path);
}
async writeFile(at, contents) {
try {
await this.mkdir(path_1.default.dirname(at));
return await writeData(this.fullPathFor(at), contents, writeFile);
}
catch (e) {
throw new Error(`Unable to write file at ${at}: ${e.message || e}`);
}
}
async appendFile(at, contents) {
try {
await this.mkdir(path_1.default.dirname(at));
return await writeData(this.fullPathFor(at), contents, appendFile);
}
catch (e) {
throw new Error(`Unable to append to file at ${at}: ${e.message || e}`);
}
}
async mkdir(name) {
name = this.resolveRelativePath(name);
return new Promise(async (resolve, reject) => {
const fullpath = path_1.default.join(this._path, name);
if (await isFolder(fullpath)) {
resolve(fullpath);
}
try {
mkdirp_1.sync(fullpath);
resolve(fullpath);
}
catch (e) {
reject(e);
}
});
}
resolveRelativePath(at) {
if (!path_1.default.isAbsolute(at)) {
return at;
}
const result = path_1.default.relative(this._path, at);
if (result.startsWith("..")) {
throw new Error(`${at} is outside the sandbox at ${this._path}`);
}
return result;
}
async readTextFile(at) {
return readFile(this.fullPathFor(at), { encoding: "utf8" });
}
async readFile(at) {
return readFile(this.fullPathFor(at));
}
fullPathFor(relativePath, ...parts) {
relativePath = this.resolveRelativePath(relativePath);
return path_1.default.join(this._path, relativePath, ...parts);
}
async stat(at) {
at = this.resolveRelativePath(at);
try {
return await fs_1.promises.stat(this.fullPathFor(at));
}
catch (e) {
return null;
}
}
async folderExists(at) {
at = this.resolveRelativePath(at);
return this.runOnStat(at, st => !!st && st.isDirectory());
}
async fileExists(at) {
at = this.resolveRelativePath(at);
return this.runOnStat(at, st => !!st && st.isFile());
}
async runOnStat(relativePath, fn) {
const st = await this.stat(relativePath);
return fn(st);
}
async run(fn, relativePath) {
const start = process.cwd();
try {
const target = relativePath
? path_1.default.resolve(path_1.default.join(this.path, relativePath))
: this.path;
this._validatePathInsideSandbox(target);
process.chdir(target);
return await fn();
}
finally {
process.chdir(start);
}
}
_validatePathInsideSandbox(t) {
if (t.startsWith(this.path)) {
return;
}
throw new Error(`${t} is not inside sandbox at ${this.path}`);
}
/**
* Destroys all sandboxes created in this process up until now
*/
static async destroyAll() {
const toDestroy = sandboxes.splice(0, sandboxes.length);
for (const sandbox of toDestroy) {
await sandbox.destroy();
}
}
/**
* Destroys the default base folder for sandboxes -- useful as a once-off
* run before all tests to ensure that there are no lingering sandboxes
* - cannot destroy sandboxes in custom paths
*/
static async destroyAny() {
const target = path_1.default.join(baseTarget, exports.basePrefix);
await rimraf(target);
}
static async create(at) {
return new Sandbox(at);
}
static async setBaseTargetToCurrentWorkingDirectory() {
await this.setBaseTarget(process.cwd());
}
static async setBaseTargetToSystemTempFolder() {
await this.setBaseTarget(os.tmpdir());
}
static async setBaseTarget(to) {
if (!(await isFolder(to))) {
await mkdirp_1.sync(to);
}
baseTarget = to;
}
}
exports.Sandbox = Sandbox;
// this is a generated file: do not edit
__exportStar(require("./filesystem-sandbox"), exports);
__exportStar(require("./index"), exports);
{
"name": "filesystem-sandbox",
"version": "1.19.0",
"version": "1.19.1",
"description": "JavaScript module to provide filesystem sandboxes for testing",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"main": "index.js",
"types": "index.d.ts",
"files": [
"dist/**/*"
"dist/**/*",
"index.js",
"index.d.ts"
],
"scripts": {
"test": "jest",
"prebuild": "rimraf dist",
"prebuild": "run-p clean-dist generate-index",
"clean-dist": "rimraf dist",
"generate-index": "node generate-index.js",
"build": "run-p tsc lint",

@@ -55,3 +59,3 @@ "autobuild": "nodemon -V -w src -w tests -e ts -x \"run-s -s build autobuild-message\"",

"typescript": "^3.9.3",
"zarro": "^1.68.0"
"zarro": "^1.78.0"
},

@@ -58,0 +62,0 @@ "dependencies": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc