Socket
Socket
Sign inDemoInstall

@microsoft/node-core-library

Package Overview
Dependencies
Maintainers
2
Versions
116
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@microsoft/node-core-library - npm Package Compare versions

Comparing version 1.4.1 to 1.5.0

lib/FileSystem.d.ts

12

CHANGELOG.json

@@ -5,2 +5,14 @@ {

{
"version": "1.5.0",
"tag": "@microsoft/node-core-library_v1.5.0",
"date": "Tue, 03 Jul 2018 21:03:31 GMT",
"comments": {
"minor": [
{
"comment": "Add a FileSystem API that wraps and replaces fs and fs-extra"
}
]
}
},
{
"version": "1.4.1",

@@ -7,0 +19,0 @@ "tag": "@microsoft/node-core-library_v1.4.1",

9

CHANGELOG.md
# Change Log - @microsoft/node-core-library
This log was last generated on Thu, 21 Jun 2018 08:27:29 GMT and should not be manually modified.
This log was last generated on Tue, 03 Jul 2018 21:03:31 GMT and should not be manually modified.
## 1.5.0
Tue, 03 Jul 2018 21:03:31 GMT
### Minor changes
- Add a FileSystem API that wraps and replaces fs and fs-extra
## 1.4.1

@@ -6,0 +13,0 @@ Thu, 21 Jun 2018 08:27:29 GMT

@@ -7,4 +7,14 @@ /**

/// <reference types="node" />
import * as fs from 'fs';
/**
* The allowed types of encodings, as supported by Node.js
* @public
*/
declare const enum Encoding {
Utf8 = "utf8",
}
/**
* String constants for common filenames and parts of filenames.

@@ -57,2 +67,213 @@ *

/**
* The FileSystem API provides a complete set of recommended operations for interacting with the file system.
*
* @remarks
* We recommend to use this instead of the native `fs` API, because `fs` is a minimal set of low-level
* primitives that must be mapped for each supported operating system. The FileSystem API takes a
* philosophical approach of providing "one obvious way" to do each operation. We also prefer synchronous
* operations except in cases where there would be a clear performance benefit for using async, since synchronous
* code is much easier to read and debug. Also, indiscriminate parallelism has been seen to actually worsen
* performance, versus improving it.
*
* Note that in the documentation, we refer to "filesystem objects", this can be a
* file, folder, synbolic link, hard link, directory junction, etc.
*
* @public
*/
export declare class FileSystem {
/**
* Returns true if the path exists on disk.
* Behind the scenes it uses `fs.existsSync()`.
* @remarks
* There is a debate about the fact that after `fs.existsSync()` returns true,
* the file might be deleted before fs.readSync() is called, which would imply that everybody
* should catch a `readSync()` exception, and nobody should ever use `fs.existsSync()`.
* We find this to be unpersuasive, since "unexceptional exceptions" really hinder the
* break-on-exception debugging experience. Also, throwing/catching is generally slow.
* @param path - The absolute or relative path to the filesystem object.
*/
static exists(path: string): boolean;
/**
* Gets the statistics for a particular filesystem object.
* If the path is a link, this function follows the link and returns statistics about the link target.
* Behind the scenes it uses `fs.statSync()`.
* @param path - The absolute or relative path to the filesystem object.
*/
static getStatistics(path: string): fs.Stats;
/**
* Updates the accessed and modified timestamps of the filesystem object referenced by path.
* Behind the scenes it uses `fs.utimesSync()`.
* The caller should specify both times in the `times` parameter.
* @param path - The path of the file that should be modified.
* @param times - The times that the object should be updated to reflect.
*/
static updateTimes(path: string, times: IUpdateTimeParameters): void;
/**
* Changes the permissions (i.e. file mode bits) for a filesystem object.
* Behind the scenes it uses `fs.chmodSync()`.
* @param path - The absolute or relative path to the object that should be updated.
* @param mode - UNIX-style file mode bits (e.g. 777 or 666 etc)
*/
static changePermissionBits(path: string, mode: IFileModeBits): void;
/**
* Moves a file. The folder must exist, unless the `ensureFolderExists` option is provided.
* Behind the scenes it uses `fsx.moveSync()`
* @param sourcePath - The absolute or relative path to the source file.
* @param targetPath - The absolute or relative path where the file should be moved to.
* @param options - Optional settings that can change the behavior. Type: `IFileSystemMoveOptions`
*/
static move(sourcePath: string, targetPath: string, options?: IFileSystemMoveOptions): void;
/**
* Recursively creates a folder at a given path.
* Behind the scenes is uses `fsx.ensureDirSync()`.
* @remarks
* Throws an exception if anything in the folderPath is not a folder.
* @param folderPath - The absolute or relative path of the folder which should be created.
*/
static ensureFolder(folderPath: string): void;
/**
* Reads the contents of the folder, not including "." or "..".
* Behind the scenes it uses `fs.readdirSync()`.
* @param folderPath - The absolute or relative path to the folder which should be read.
* @param options - Optional settings that can change the behavior. Type: `IReadFolderOptions`
*/
static readFolder(folderPath: string, options?: IReadFolderOptions): Array<string>;
/**
* Deletes a folder, including all of its contents.
* Behind the scenes is uses `fsx.removeSync()`.
* @remarks
* Does not throw if the folderPath does not exist.
* @param folderPath - The absolute or relative path to the folder which should be deleted.
*/
static deleteFolder(folderPath: string): void;
/**
* Deletes the content of a folder, but not the folder itself. Also ensures the folder exists.
* Behind the scenes it uses `fsx.emptyDirSync()`.
* @remarks
* This is a workaround for a common race condition, where the virus scanner holds a lock on the folder
* for a brief period after it was deleted, causing EBUSY errors for any code that tries to recreate the folder.
* @param folderPath - The absolute or relative path to the folder which should have its contents deleted.
*/
static ensureEmptyFolder(folderPath: string): void;
/**
* Writes a text string to a file on disk, overwriting the file if it already exists.
* Behind the scenes it uses `fs.writeFileSync()`.
* @remarks
* Throws an error if the folder doesn't exist, unless ensureFolder=true.
* @param filePath - The absolute or relative path of the file.
* @param contents - The text that should be written to the file.
* @param options - Optional settings that can change the behavior. Type: `IWriteFileOptions`
*/
static writeFile(filePath: string, contents: string | Buffer, options?: IWriteFileOptions): void;
/**
* Reads the contents of a file into a string.
* Behind the scenes it uses `fs.readFileSync()`.
* @param filePath - The relative or absolute path to the file whose contents should be read.
* @param options - Optional settings that can change the behavior. Type: `IReadFileOptions`
*/
static readFile(filePath: string, options?: IReadFileOptions): string;
/**
* Reads the contents of a file into a buffer.
* Behind the scenes is uses `fs.readFileSync()`.
* @param filePath - The relative or absolute path to the file whose contents should be read.
*/
static readFileToBuffer(filePath: string): Buffer;
/**
* Copies a file from one location to another.
* By default, destinationPath is overwritten if it already exists.
* Behind the scenes it uses `fs.copyFileSync()`.
* @param sourcePath - The absolute or relative path to the source file to be copied.
* @param destinationPath - The absolute or relative path to the new copy that will be created.
*/
static copyFile(sourcePath: string, destinationPath: string): void;
/**
* Deletes a file. Can optionally throw if the file doesn't exist.
* Behind the scenes it uses `fs.unlinkSync()`.
* @param filePath - The absolute or relative path to the file that should be deleted.
* @param options - Optional settings that can change the behavior. Type: `IDeleteFileOptions`
*/
static deleteFile(filePath: string, options?: IDeleteFileOptions): void;
/**
* Gets the statistics of a filesystem object. Does NOT follow the link to its target.
* Behind the scenes it uses `fs.lstatSync()`.
* @param path - The absolute or relative path to the filesystem object.
*/
static getLinkStatistics(path: string): fs.Stats;
/**
* Creates a Windows "directory junction". Behaves like `createSymbolicLinkToFile()` on other platforms.
* Behind the scenes it uses `fs.symlinkSync()`.
* @param linkSource - The absolute or relative path to the destination where the link should be created.
* @param linkTarget - The absolute or relative path to the target of the link.
*/
static createSymbolicLinkJunction(linkTarget: string, linkSource: string): void;
/**
* Creates a symbolic link to a file (on Windows this requires elevated permissionsBits).
* Behind the scenes it uses `fs.symlinkSync()`.
* @param linkSource - The absolute or relative path to the destination where the link should be created.
* @param linkTarget - The absolute or relative path to the target of the link.
*/
static createSymbolicLinkFile(linkTarget: string, linkSource: string): void;
/**
* Creates a symbolic link to a folder (on Windows this requires elevated permissionsBits).
* Behind the scenes it uses `fs.symlinkSync()`.
* @param linkSource - The absolute or relative path to the destination where the link should be created.
* @param linkTarget - The absolute or relative path to the target of the link.
*/
static createSymbolicLinkFolder(linkTarget: string, linkSource: string): void;
/**
* Creates a hard link.
* Behind the scenes it uses `fs.linkSync()`.
* @param linkSource - The absolute or relative path to the destination where the link should be created.
* @param linkTarget - The absolute or relative path to the target of the link.
*/
static createHardLink(linkTarget: string, linkSource: string): void;
/**
* Follows a link to its destination and returns the absolute path to the final target of the link.
* Behind the scenes it uses `fs.realpathSync()`.
* @param linkPath - The path to the link.
*/
static getRealPath(linkPath: string): string;
/**
* A helper function that converts line endings on a string.
* @param text - The text to be normalized.
* @param lineEndings - The style of line endings to use.
*/
private static _convertLineEndings(text, lineEndings);
}
/**
* API for interacting with file handles.
* @public
*/
export declare class FileWriter {
private _fileDescriptor;
/**
* Opens a new file handle to the file at the specified path and given mode.
* Behind the scenes it uses `fs.openSync()`.
* The behaviour of this function is platform specific.
* See: https://nodejs.org/docs/latest-v8.x/api/fs.html#fs_fs_open_path_flags_mode_callback
* @param path - The absolute or relative path to the file handle that should be opened.
* @param flags - The flags for opening the handle
*/
static open(path: string, flags?: IFileWriterFlags): FileWriter;
/**
* Helper function to convert the file writer array to a Node.js style string (e.g. "wx" or "a").
* @param flags - The flags that should be converted.
*/
private static _convertFlagsForNode(flags);
/**
* Writes some text to the given file handle. Throws if the file handle has been closed.
* Behind the scenes it uses `fs.writeSync()`.
* @param text - The text to write to the file.
*/
write(text: string): void;
/**
* Closes the file handle permanently. No operations can be made on this file handle after calling this.
* Behind the scenes it uses `fs.closeSync()` and releases the file descriptor to be re-used.
*/
close(): void;
private constructor();
}
/**
* String constants for common folder names.

@@ -74,2 +295,58 @@ *

/**
* The options for FileSystem.deleteFile()
* @public
*/
export declare interface IDeleteFileOptions {
/**
* If true, will throw an exception if the file did not exist before `deleteFile()` was called.
* Defaults to `false`.
*/
throwIfNotExists?: boolean;
}
/**
* Interface representing Unix-style file permission mode bits.
* All values should be set.
* @public
*/
export declare interface IFileModeBits {
Owner: PermissionsBits;
Group: PermissionsBits;
Other: PermissionsBits;
}
/**
* The options for FileSystem.move()
* @public
*/
export declare interface IFileSystemMoveOptions {
/**
* If true, will overwrite the file if it already exists. Defaults to true.
*/
overwrite?: boolean;
/**
* If true, will ensure the folder is created before writing the file.
* Defaults to `false`.
*/
ensureFolderExists?: boolean;
}
/**
* Interface which represents the flags about which mode the file should be opened in.
* @public
*/
export declare interface IFileWriterFlags {
/**
* Open file for appending.
*/
append?: boolean;
/**
* Fails if path exists. The exclusive flag ensures that path is newly created.
* On POSIX systems, path is considered to exist even if it is a symlink to a non-existent file.
* The exclusive flag may or may not work with network file systems.
*/
exclusive?: boolean;
}
/**
* Options for JsonFile.saveJsonFile()

@@ -85,2 +362,7 @@ *

onlyIfChanged?: boolean;
/**
* Creates the folder recursively using FileSystem.ensureFolder()
* Defaults to false.
*/
ensureFolderExists?: boolean;
}

@@ -342,2 +624,69 @@

/**
* The options for FileSystem.readFile()
* @public
*/
export declare interface IReadFileOptions {
/**
* If specified, will change the encoding of the file that will be written.
* Defaults to `"utf8"`.
*/
encoding?: Encoding;
/**
* If specified, will normalize line endings to the specified style of newline.
* Defaults to `NewlineKind.None`.
*/
convertLineEndings?: NewlineKind;
}
/**
* The options for FileSystem.readFolder()
* @public
*/
export declare interface IReadFolderOptions {
/**
* If true, returns the absolute paths of the files in the folder.
* Defaults to `false`.
*/
absolutePaths?: boolean;
}
/**
* The parameters for `updateTimes()`.
* Both times must be specified.
* @public
*/
export declare interface IUpdateTimeParameters {
/**
* The UNIX epoch time or Date when this was last accessed.
*/
accessedTime: number | Date;
/**
* The UNIX epoch time or Date when this was last modified
*/
modifiedTime: number | Date;
}
/**
* The options for FileSystem.writeFile()
* @public
*/
export declare interface IWriteFileOptions {
/**
* If true, will ensure the folder is created before writing the file.
* Defaults to `false`.
*/
ensureFolderExists?: boolean;
/**
* If specified, will normalize line endings to the specified style of newline.
* Defaults to `NewlineKind.None`.
*/
convertLineEndings?: NewlineKind;
/**
* If specified, will change the encoding of the file that will be written.
* Defaults to `"utf8"`.
*/
encoding?: Encoding;
}
/**
* Utilities for reading/writing JSON files.

@@ -460,3 +809,3 @@ * @public

export declare class LockFile {
private _fileDescriptor;
private _fileWriter;
private _filePath;

@@ -532,2 +881,17 @@ private _dirtyWhenAcquired;

/**
* Enumeration controlling conversion of newline characters.
* @public
*/
export declare const enum NewlineKind {
/**
* Windows-style newlines
*/
CrLf = "\r\n",
/**
* Unix-style newlines
*/
Lf = "\n",
}
/**
* This class provides methods for finding the nearest "package.json" for a folder

@@ -672,2 +1036,17 @@ * and retrieving the name of the package. The results are cached.

/**
* Available PermissionsBits bits. These can be added together using the pipe operator, e.g.:
*
* PermissionsBits.Read === 1 (or "001" in decimal)
* PermissionsBits.Read | PermissionsBits.Write === 3 (or "011" in decimal)
* PermissionsBits.Read | PermissionsBits.Write | PermissionsBits.Execute === 7 (or "111" in decimal)
* @public
*/
declare const enum PermissionsBits {
None = 0,
Execute = 1,
Write = 2,
Read = 4,
}
/**
* The ProtectableMap provides an easy way for an API to expose a Map<K, V> property

@@ -674,0 +1053,0 @@ * while intercepting and validating any write operations that are performed by

21

lib/FileDiffTest.js

@@ -6,5 +6,5 @@ "use strict";

const path = require("path");
const fsx = require("fs-extra");
const PackageJsonLookup_1 = require("./PackageJsonLookup");
const Text_1 = require("./Text");
const FileSystem_1 = require("./FileSystem");
/**

@@ -43,4 +43,4 @@ * Implements a unit testing strategy that generates output files, and then

const diffTestPath = path.join(packageJsonFolderPath, 'temp', 'diff-tests', testModule);
fsx.mkdirsSync(diffTestPath);
fsx.emptyDirSync(diffTestPath);
FileSystem_1.FileSystem.ensureFolder(diffTestPath);
FileSystem_1.FileSystem.ensureEmptyFolder(diffTestPath);
return diffTestPath;

@@ -56,4 +56,4 @@ }

static assertEqual(actualFilePath, expectedFilePath) {
const actualContent = fsx.readFileSync(actualFilePath).toString('utf8');
const expectedContent = fsx.readFileSync(expectedFilePath).toString('utf8');
const actualContent = FileSystem_1.FileSystem.readFile(actualFilePath);
const expectedContent = FileSystem_1.FileSystem.readFile(expectedFilePath);
// NOTE: "\s" also matches "\r" and "\n"

@@ -65,8 +65,13 @@ const normalizedActual = FileDiffTest._getNormalizedContent(actualContent);

const expectedCopyFilename = path.join(path.dirname(actualFilePath), path.basename(expectedFilePath));
if (fsx.existsSync(expectedCopyFilename)) {
if (FileSystem_1.FileSystem.exists(expectedCopyFilename)) {
throw new Error('The FileDiffTest failed, but the expected output cannot be copied because'
+ ' the file already exists:\n' + expectedCopyFilename);
}
fsx.copySync(expectedFilePath, expectedCopyFilename);
fsx.chmodSync(expectedCopyFilename, 292); // 292 = 444 octal = "rrr"
FileSystem_1.FileSystem.copyFile(expectedFilePath, expectedCopyFilename);
// Set to read-only so that developer doesn't accidentally modify the wrong file
FileSystem_1.FileSystem.changePermissionBits(expectedCopyFilename, {
Owner: 4 /* Read */,
Group: 4 /* Read */,
Other: 4 /* Read */
});
throw new Error('The test output file does not match the expected input:\n'

@@ -73,0 +78,0 @@ + actualFilePath);

@@ -18,1 +18,3 @@ /**

export { Text } from './Text';
export { FileSystem, IReadFolderOptions, IWriteFileOptions, IReadFileOptions, IFileSystemMoveOptions, IDeleteFileOptions, NewlineKind, IFileModeBits, IUpdateTimeParameters } from './FileSystem';
export { FileWriter, IFileWriterFlags } from './FileWriter';

@@ -25,3 +25,7 @@ "use strict";

exports.Text = Text_1.Text;
var FileSystem_1 = require("./FileSystem");
exports.FileSystem = FileSystem_1.FileSystem;
var FileWriter_1 = require("./FileWriter");
exports.FileWriter = FileWriter_1.FileWriter;
//# sourceMappingURL=index.js.map

@@ -24,2 +24,7 @@ import { JsonSchema, IJsonSchemaErrorInfo, IJsonSchemaValidateOptions } from './JsonSchema';

onlyIfChanged?: boolean;
/**
* Creates the folder recursively using FileSystem.ensureFolder()
* Defaults to false.
*/
ensureFolderExists?: boolean;
}

@@ -26,0 +31,0 @@ /**

@@ -5,6 +5,6 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const fsx = require("fs-extra");
const os = require("os");
const jju = require("jju");
const Text_1 = require("./Text");
const FileSystem_1 = require("./FileSystem");
/**

@@ -19,8 +19,8 @@ * Utilities for reading/writing JSON files.

static load(jsonFilename) {
if (!fsx.existsSync(jsonFilename)) {
if (!FileSystem_1.FileSystem.exists(jsonFilename)) {
throw new Error(`Input file not found: ${jsonFilename}`);
}
const buffer = fsx.readFileSync(jsonFilename);
const contents = FileSystem_1.FileSystem.readFile(jsonFilename);
try {
return jju.parse(buffer.toString());
return jju.parse(contents);
}

@@ -77,5 +77,5 @@ catch (error) {

// Has the file changed?
if (fsx.existsSync(jsonFilename)) {
if (FileSystem_1.FileSystem.exists(jsonFilename)) {
try {
const oldBuffer = fsx.readFileSync(jsonFilename);
const oldBuffer = FileSystem_1.FileSystem.readFileToBuffer(jsonFilename);
if (Buffer.compare(buffer, oldBuffer) === 0) {

@@ -92,6 +92,8 @@ // Nothing has changed, so don't touch the file

}
fsx.writeFileSync(jsonFilename, buffer);
FileSystem_1.FileSystem.writeFile(jsonFilename, buffer.toString(), {
ensureFolderExists: options.ensureFolderExists
});
// TEST CODE: Used to verify that onlyIfChanged isn't broken by a hidden transformation during saving.
/*
const oldBuffer2: Buffer = fsx.readFileSync(jsonFilename);
const oldBuffer2: Buffer = FileSystem.readFileToBuffer(jsonFilename);
if (Buffer.compare(buffer, oldBuffer2) !== 0) {

@@ -98,0 +100,0 @@ console.log('new:' + buffer.toString('hex'));

@@ -5,3 +5,2 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const fsx = require("fs-extra");
const os = require("os");

@@ -11,2 +10,3 @@ const path = require("path");

const JsonFile_1 = require("./JsonFile");
const FileSystem_1 = require("./FileSystem");
/**

@@ -37,3 +37,3 @@ * Represents a JSON schema that can be used to validate JSON data files loaded by the JsonFile class.

// Full validation will happen later in JsonSchema.compile().
if (!fsx.existsSync(filename)) {
if (!FileSystem_1.FileSystem.exists(filename)) {
throw new Error('Schema file not found: ' + filename);

@@ -40,0 +40,0 @@ }

@@ -19,3 +19,3 @@ /**

export declare class LockFile {
private _fileDescriptor;
private _fileWriter;
private _filePath;

@@ -22,0 +22,0 @@ private _dirtyWhenAcquired;

@@ -5,6 +5,7 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const fsx = require("fs-extra");
const path = require("path");
const child_process = require("child_process");
const timers_1 = require("timers");
const FileSystem_1 = require("./FileSystem");
const FileWriter_1 = require("./FileWriter");
/**

@@ -92,3 +93,3 @@ * http://man7.org/linux/man-pages/man5/proc.5.html

try {
stat = fsx.readFileSync(`/proc/${pidString}/stat`, 'utf8');
stat = FileSystem_1.FileSystem.readFile(`/proc/${pidString}/stat`);
}

@@ -137,4 +138,4 @@ catch (error) {

class LockFile {
constructor(_fileDescriptor, _filePath, _dirtyWhenAcquired) {
this._fileDescriptor = _fileDescriptor;
constructor(_fileWriter, _filePath, _dirtyWhenAcquired) {
this._fileWriter = _fileWriter;
this._filePath = _filePath;

@@ -166,3 +167,3 @@ this._dirtyWhenAcquired = _dirtyWhenAcquired;

static tryAcquire(resourceDir, resourceName) {
fsx.mkdirsSync(resourceDir);
FileSystem_1.FileSystem.ensureFolder(resourceDir);
if (process.platform === 'win32') {

@@ -219,3 +220,3 @@ return LockFile._tryAcquireWindows(resourceDir, resourceName);

const pidLockFilePath = LockFile.getLockFilePath(resourceDir, resourceName);
let lockFileDescriptor;
let lockFileHandle;
let lockFile;

@@ -226,9 +227,9 @@ try {

// We should ideally maintain a dictionary of normalized acquired filenames
lockFileDescriptor = fsx.openSync(pidLockFilePath, 'w');
fsx.writeSync(lockFileDescriptor, startTime);
const currentBirthTimeMs = fsx.statSync(pidLockFilePath).birthtime.getTime();
lockFileHandle = FileWriter_1.FileWriter.open(pidLockFilePath);
lockFileHandle.write(startTime);
const currentBirthTimeMs = FileSystem_1.FileSystem.getStatistics(pidLockFilePath).birthtime.getTime();
let smallestBirthTimeMs = currentBirthTimeMs;
let smallestBirthTimePid = pid.toString();
// now, scan the directory for all lockfiles
const files = fsx.readdirSync(resourceDir);
const files = FileSystem_1.FileSystem.readFolder(resourceDir);
// look for anything ending with # then numbers and ".lock"

@@ -250,5 +251,5 @@ const lockFileRegExp = /^(.+)#([0-9]+)\.lock$/;

try {
otherPidOldStartTime = fsx.readFileSync(fileInFolderPath, 'utf8');
otherPidOldStartTime = FileSystem_1.FileSystem.readFile(fileInFolderPath);
// check the timestamp of the file
otherBirthtimeMs = fsx.statSync(fileInFolderPath).birthtime.getTime();
otherBirthtimeMs = FileSystem_1.FileSystem.getStatistics(fileInFolderPath).birthtime.getTime();
}

@@ -281,3 +282,3 @@ catch (err) {

// console.log(`Other pid ${otherPid} is no longer executing!`);
fsx.removeSync(fileInFolderPath);
FileSystem_1.FileSystem.deleteFile(fileInFolderPath);
continue;

@@ -299,10 +300,10 @@ }

// we have the lock!
lockFile = new LockFile(lockFileDescriptor, pidLockFilePath, dirtyWhenAcquired);
lockFileDescriptor = undefined; // we have handed the descriptor off to the instance
lockFile = new LockFile(lockFileHandle, pidLockFilePath, dirtyWhenAcquired);
lockFileHandle = undefined; // we have handed the descriptor off to the instance
}
finally {
if (lockFileDescriptor) {
if (lockFileHandle) {
// ensure our lock is closed
fsx.closeSync(lockFileDescriptor);
fsx.removeSync(pidLockFilePath);
lockFileHandle.close();
FileSystem_1.FileSystem.deleteFile(pidLockFilePath);
}

@@ -319,6 +320,6 @@ }

let dirtyWhenAcquired = false;
let fileDescriptor;
let fileHandle;
let lockFile;
try {
if (fsx.existsSync(lockFilePath)) {
if (FileSystem_1.FileSystem.exists(lockFilePath)) {
dirtyWhenAcquired = true;

@@ -329,7 +330,7 @@ // If the lockfile is held by an process with an exclusive lock, then removing it will

// the last process to hold it died.
fsx.unlinkSync(lockFilePath);
FileSystem_1.FileSystem.deleteFile(lockFilePath);
}
try {
// Attempt to open an exclusive lockfile
fileDescriptor = fsx.openSync(lockFilePath, 'wx');
fileHandle = FileWriter_1.FileWriter.open(lockFilePath, { exclusive: true });
}

@@ -342,8 +343,8 @@ catch (error) {

// Ensure we can hand off the file descriptor to the lockfile
lockFile = new LockFile(fileDescriptor, lockFilePath, dirtyWhenAcquired);
fileDescriptor = undefined;
lockFile = new LockFile(fileHandle, lockFilePath, dirtyWhenAcquired);
fileHandle = undefined;
}
finally {
if (fileDescriptor) {
fsx.closeSync(fileDescriptor);
if (fileHandle) {
fileHandle.close();
}

@@ -361,5 +362,5 @@ }

}
fsx.closeSync(this._fileDescriptor);
fsx.removeSync(this._filePath);
this._fileDescriptor = undefined;
this._fileWriter.close();
FileSystem_1.FileSystem.deleteFile(this._filePath);
this._fileWriter = undefined;
}

@@ -383,3 +384,3 @@ /**

get isReleased() {
return this._fileDescriptor === undefined;
return this._fileWriter === undefined;
}

@@ -386,0 +387,0 @@ }

@@ -6,5 +6,5 @@ "use strict";

/* tslint:disable:no-constant-condition */
const fsx = require("fs-extra");
const path = require("path");
const JsonFile_1 = require("./JsonFile");
const FileSystem_1 = require("./FileSystem");
/**

@@ -115,3 +115,3 @@ * This class provides methods for finding the nearest "package.json" for a folder

loadPackageJson(jsonFilename) {
if (!fsx.existsSync(jsonFilename)) {
if (!FileSystem_1.FileSystem.exists(jsonFilename)) {
throw new Error(`Input file not found: ${jsonFilename}`);

@@ -121,3 +121,3 @@ }

// to minimize duplication. (Note that duplication can still occur due to e.g. character case.)
const normalizedFilePath = fsx.realpathSync(jsonFilename);
const normalizedFilePath = FileSystem_1.FileSystem.getRealPath(jsonFilename);
let packageJson = this._packageJsonCache.get(normalizedFilePath);

@@ -171,3 +171,3 @@ if (!packageJson) {

// Is resolvedFileOrFolderPath itself a folder with a package.json file? If so, return it.
if (fsx.existsSync(path.join(resolvedFileOrFolderPath, "package.json" /* PackageJson */))) {
if (FileSystem_1.FileSystem.exists(path.join(resolvedFileOrFolderPath, "package.json" /* PackageJson */))) {
this._packageFolderCache.set(resolvedFileOrFolderPath, resolvedFileOrFolderPath);

@@ -174,0 +174,0 @@ return resolvedFileOrFolderPath;

@@ -6,6 +6,7 @@ "use strict";

/// <reference types='mocha' />
const fsx = require("fs-extra");
const chai_1 = require("chai");
const path = require("path");
const LockFile_1 = require("../LockFile");
const FileSystem_1 = require("../FileSystem");
const FileWriter_1 = require("../FileWriter");
function setLockFileGetProcessStartTime(fn) {

@@ -104,3 +105,3 @@ // tslint:disable-next-line:no-any

const testFolder = path.join(__dirname, '1');
fsx.emptyDirSync(testFolder);
FileSystem_1.FileSystem.ensureEmptyFolder(testFolder);
const resourceName = 'test';

@@ -113,6 +114,6 @@ const pidLockFileName = LockFile_1.LockFile.getLockFilePath(testFolder, resourceName);

chai_1.assert.isFalse(lock.isReleased);
chai_1.assert.isTrue(fsx.existsSync(pidLockFileName));
chai_1.assert.isTrue(FileSystem_1.FileSystem.exists(pidLockFileName));
// Ensure that we can release the "clean" lockfile
lock.release();
chai_1.assert.isFalse(fsx.existsSync(pidLockFileName));
chai_1.assert.isFalse(FileSystem_1.FileSystem.exists(pidLockFileName));
chai_1.assert.isTrue(lock.isReleased);

@@ -127,3 +128,3 @@ // Ensure we cannot release the lockfile twice

const testFolder = path.join(__dirname, '2');
fsx.emptyDirSync(testFolder);
FileSystem_1.FileSystem.ensureEmptyFolder(testFolder);
const otherPid = 999999999;

@@ -137,6 +138,9 @@ const otherPidStartTime = '2012-01-02 12:53:12';

// create an open lockfile
const lockFileDescriptor = fsx.openSync(otherPidLockFileName, 'w');
fsx.writeSync(lockFileDescriptor, otherPidStartTime);
fsx.closeSync(lockFileDescriptor);
fsx.utimesSync(otherPidLockFileName, 10000, 10000);
const lockFileHandle = FileWriter_1.FileWriter.open(otherPidLockFileName);
lockFileHandle.write(otherPidStartTime);
lockFileHandle.close();
FileSystem_1.FileSystem.updateTimes(otherPidLockFileName, {
accessedTime: 10000,
modifiedTime: 10000
});
const lock = LockFile_1.LockFile.tryAcquire(testFolder, resourceName);

@@ -160,12 +164,12 @@ // this lock should be undefined since there is an existing lock

const testFolder = path.join(__dirname, '1');
fsx.removeSync(testFolder);
fsx.mkdirsSync(testFolder);
FileSystem_1.FileSystem.deleteFolder(testFolder);
FileSystem_1.FileSystem.ensureFolder(testFolder);
// create an open lockfile
const resourceName = 'test';
const lockFileName = LockFile_1.LockFile.getLockFilePath(testFolder, resourceName);
const lockFileDescriptor = fsx.openSync(lockFileName, 'wx');
const lockFileHandle = FileWriter_1.FileWriter.open(lockFileName, { exclusive: true });
const lock = LockFile_1.LockFile.tryAcquire(testFolder, resourceName);
// this lock should be undefined since there is an existing lock
chai_1.assert.isUndefined(lock);
fsx.closeSync(lockFileDescriptor);
lockFileHandle.close();
});

@@ -175,8 +179,8 @@ it('can acquire and close a dirty lockfile', () => {

const testFolder = path.join(__dirname, '1');
fsx.removeSync(testFolder);
fsx.mkdirsSync(testFolder);
FileSystem_1.FileSystem.deleteFolder(testFolder);
FileSystem_1.FileSystem.ensureFolder(testFolder);
// Create a lockfile that is still hanging around on disk,
const resourceName = 'test';
const lockFileName = LockFile_1.LockFile.getLockFilePath(testFolder, resourceName);
fsx.closeSync(fsx.openSync(lockFileName, 'wx'));
FileWriter_1.FileWriter.open(lockFileName, { exclusive: true }).close();
const lock = LockFile_1.LockFile.tryAcquire(testFolder, resourceName);

@@ -186,6 +190,6 @@ chai_1.assert.isDefined(lock);

chai_1.assert.isFalse(lock.isReleased);
chai_1.assert.isTrue(fsx.existsSync(lockFileName));
chai_1.assert.isTrue(FileSystem_1.FileSystem.exists(lockFileName));
// Ensure that we can release the "dirty" lockfile
lock.release();
chai_1.assert.isFalse(fsx.existsSync(lockFileName));
chai_1.assert.isFalse(FileSystem_1.FileSystem.exists(lockFileName));
chai_1.assert.isTrue(lock.isReleased);

@@ -196,4 +200,4 @@ });

const testFolder = path.join(__dirname, '1');
fsx.removeSync(testFolder);
fsx.mkdirsSync(testFolder);
FileSystem_1.FileSystem.deleteFolder(testFolder);
FileSystem_1.FileSystem.ensureFolder(testFolder);
const resourceName = 'test';

@@ -206,6 +210,6 @@ const lockFileName = LockFile_1.LockFile.getLockFilePath(testFolder, resourceName);

chai_1.assert.isFalse(lock.isReleased);
chai_1.assert.isTrue(fsx.existsSync(lockFileName));
chai_1.assert.isTrue(FileSystem_1.FileSystem.exists(lockFileName));
// Ensure that we can release the "clean" lockfile
lock.release();
chai_1.assert.isFalse(fsx.existsSync(lockFileName));
chai_1.assert.isFalse(FileSystem_1.FileSystem.exists(lockFileName));
chai_1.assert.isTrue(lock.isReleased);

@@ -212,0 +216,0 @@ // Ensure we cannot release the lockfile twice

{
"name": "@microsoft/node-core-library",
"version": "1.4.1",
"version": "1.5.0",
"description": "Core libraries that every NodeJS toolchain project should use",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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