Socket
Socket
Sign inDemoInstall

@ui5/fs

Package Overview
Dependencies
Maintainers
3
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ui5/fs - npm Package Compare versions

Comparing version 3.0.0-rc.4 to 3.0.0-rc.5

6

CHANGELOG.md

@@ -5,4 +5,7 @@ # Changelog

A list of unreleased changes can be found [here](https://github.com/SAP/ui5-fs/compare/v3.0.0-rc.4...HEAD).
A list of unreleased changes can be found [here](https://github.com/SAP/ui5-fs/compare/v3.0.0-rc.5...HEAD).
<a name="v3.0.0-rc.5"></a>
## [v3.0.0-rc.5] - 2023-02-03
<a name="v3.0.0-rc.4"></a>

@@ -235,2 +238,3 @@ ## [v3.0.0-rc.4] - 2023-01-24

[v3.0.0-rc.5]: https://github.com/SAP/ui5-fs/compare/v3.0.0-rc.4...v3.0.0-rc.5
[v3.0.0-rc.4]: https://github.com/SAP/ui5-fs/compare/v3.0.0-rc.3...v3.0.0-rc.4

@@ -237,0 +241,0 @@ [v3.0.0-rc.3]: https://github.com/SAP/ui5-fs/compare/v3.0.0-rc.2...v3.0.0-rc.3

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

import path from "node:path/posix";
import {getLogger} from "@ui5/logger";

@@ -23,3 +24,4 @@ const log = getLogger("resources:adapters:AbstractAdapter");

* @param {object} parameters Parameters
* @param {string} parameters.virBasePath Virtual base path
* @param {string} parameters.virBasePath
* Virtual base path. Must be absolute, POSIX-style, and must end with a slash
* @param {string[]} [parameters.excludes] List of glob patterns to exclude

@@ -33,4 +35,12 @@ * @param {object} [parameters.project] Experimental, internal parameter. Do not use

super();
if (!virBasePath) {
throw new Error(`Unable to create adapter: Missing parameter 'virBasePath'`);
}
if (!path.isAbsolute(virBasePath)) {
throw new Error(`Unable to create adapter: Virtual base path must be absolute but is '${virBasePath}'`);
}
if (!virBasePath.endsWith("/")) {
throw new Error(`Virtual base path must end with a slash: ${virBasePath}`);
throw new Error(
`Unable to create adapter: Virtual base path must end with a slash but is '${virBasePath}'`);
}

@@ -102,3 +112,3 @@ this._virBasePath = virBasePath;

*/
isPathExcluded(virPath) {
_isPathExcluded(virPath) {
return micromatch(virPath, this._excludes).length > 0;

@@ -108,2 +118,15 @@ }

/**
* Validate if virtual path should be handled by the adapter.
* This means that it either starts with the virtual base path of the adapter
* or equals the base directory (base path without a trailing slash)
*
* @param {string} virPath Virtual Path
* @returns {boolean} True if path should be handled
*/
_isPathHandled(virPath) {
// Check whether path starts with base path, or equals base directory
return virPath.startsWith(this._virBasePath) || virPath === this._virBaseDir;
}
/**
* Normalizes virtual glob patterns.

@@ -222,8 +245,3 @@ *

_write(resource) {
if (!resource.getPath().startsWith(this._virBasePath)) {
throw new Error(`The path of the resource '${resource.getPath()}' does not start with ` +
`the configured virtual base path of the adapter '${this._virBasePath}'`);
}
_assignProjectToResource(resource) {
if (this._project) {

@@ -244,4 +262,43 @@ // Assign project to resource if necessary

}
_resolveVirtualPathToBase(inputVirPath, writeMode = false) {
if (!path.isAbsolute(inputVirPath)) {
throw new Error(`Failed to resolve virtual path '${inputVirPath}': Path must be absolute`);
}
// Resolve any ".." segments to make sure we compare the effective start of the path
// with the virBasePath
const virPath = path.normalize(inputVirPath);
if (!writeMode) {
// When reading resources, validate against path excludes and return null if the given path
// does not match this adapters base path
if (!this._isPathHandled(virPath)) {
if (log.isLevelEnabled("silly")) {
log.silly(`Failed to resolve virtual path '${inputVirPath}': ` +
`Resolved path does not start with adapter base path '${this._virBasePath}' or equals ` +
`base dir: ${this._virBaseDir}`);
}
return null;
}
if (this._isPathExcluded(virPath)) {
if (log.isLevelEnabled("silly")) {
log.silly(`Failed to resolve virtual path '${inputVirPath}': ` +
`Resolved path is excluded by configuration of adapter with base path '${this._virBasePath}'`);
}
return null;
}
} else if (!this._isPathHandled(virPath)) {
// Resolved path is not within the configured base path and does
// not equal the virtual base directory.
// Since we don't want to write resources to foreign locations, we throw an error
throw new Error(
`Failed to write resource with virtual path '${inputVirPath}': Path must start with ` +
`the configured virtual base path of the adapter. Base path: '${this._virBasePath}'`);
}
const relPath = virPath.substr(this._virBasePath.length);
return relPath;
}
}
export default AbstractAdapter;

59

lib/adapters/FileSystem.js

@@ -29,4 +29,6 @@ import {getLogger} from "@ui5/logger";

* @param {object} parameters Parameters
* @param {string} parameters.virBasePath Virtual base path
* @param {string} parameters.fsBasePath (Physical) File system path
* @param {string} parameters.virBasePath
* Virtual base path. Must be absolute, POSIX-style, and must end with a slash
* @param {string} parameters.fsBasePath
* File System base path. Must be absolute and must use platform-specific path segment separators
* @param {string[]} [parameters.excludes] List of glob patterns to exclude

@@ -39,3 +41,10 @@ * @param {object} [parameters.useGitignore=false]

super({virBasePath, project, excludes});
this._fsBasePath = path.resolve(fsBasePath);
if (!fsBasePath) {
throw new Error(`Unable to create adapter: Missing parameter 'fsBasePath'`);
}
// Ensure path is resolved to an absolute path, ending with a slash (or backslash on Windows)
// path.resolve will always remove any trailing segment separator
this._fsBasePath = path.join(path.resolve(fsBasePath), path.sep);
this._useGitignore = !!useGitignore;

@@ -99,4 +108,12 @@ }

promises.push(new Promise((resolve, reject) => {
const fsPath = path.join(this._fsBasePath, matches[i]);
const virPath = (this._virBasePath + matches[i]);
const relPath = this._resolveVirtualPathToBase(virPath);
if (!relPath) {
// Match is likely outside adapter base path
log.verbose(
`Failed to resolve virtual path of glob match '${virPath}': Path must start with ` +
`the configured virtual base path of the adapter. Base path: '${this._virBasePath}'`);
resolve(null);
}
const fsPath = this._resolveToFileSystem(relPath);

@@ -128,3 +145,3 @@ // Workaround for not getting the stat from the glob

// Flatten results
return Array.prototype.concat.apply([], results);
return Array.prototype.concat.apply([], results).filter(($) => $);
}

@@ -136,3 +153,3 @@

* @private
* @param {string} virPath Virtual path
* @param {string} virPath Absolute virtual path
* @param {object} options Options

@@ -143,7 +160,5 @@ * @param {@ui5/fs/tracing.Trace} trace Trace instance

async _byPath(virPath, options, trace) {
if (this.isPathExcluded(virPath)) {
return null;
}
const relPath = this._resolveVirtualPathToBase(virPath);
if (!virPath.startsWith(this._virBasePath) && virPath !== this._virBaseDir) {
if (!relPath) {
// Neither starts with basePath, nor equals baseDirectory

@@ -164,5 +179,5 @@ if (!options.nodir && this._virBasePath.startsWith(virPath)) {

}
const relPath = virPath.substr(this._virBasePath.length);
const fsPath = path.join(this._fsBasePath, relPath);
const fsPath = this._resolveToFileSystem(relPath);
trace.pathCall();

@@ -240,3 +255,3 @@

}
super._write(resource);
this._assignProjectToResource(resource);
if (drain && readOnly) {

@@ -247,4 +262,4 @@ throw new Error(`Error while writing resource ${resource.getPath()}: ` +

const relPath = resource.getPath().substr(this._virBasePath.length);
const fsPath = path.join(this._fsBasePath, relPath);
const relPath = this._resolveVirtualPathToBase(resource.getPath(), true);
const fsPath = this._resolveToFileSystem(relPath);
const dirPath = path.dirname(fsPath);

@@ -347,4 +362,18 @@

}
_resolveToFileSystem(relPath) {
const fsPath = path.join(this._fsBasePath, relPath);
if (!fsPath.startsWith(this._fsBasePath)) {
log.verbose(`Failed to resolve virtual path internally: ${relPath}`);
log.verbose(` Adapter base path: ${this._fsBasePath}`);
log.verbose(` Resulting path: ${fsPath}`);
throw new Error(
`Error while resolving internal virtual path: '${relPath}' resolves ` +
`to a directory not accessible by this File System adapter instance`);
}
return fsPath;
}
}
export default FileSystem;

@@ -22,3 +22,4 @@ import {getLogger} from "@ui5/logger";

* @param {object} parameters Parameters
* @param {string} parameters.virBasePath Virtual base path
* @param {string} parameters.virBasePath
* Virtual base path. Must be absolute, POSIX-style, and must end with a slash
* @param {string[]} [parameters.excludes] List of glob patterns to exclude

@@ -110,11 +111,7 @@ * @param {@ui5/project/specifications/Project} [parameters.project] Project this adapter belongs to (if any)

async _byPath(virPath, options, trace) {
if (this.isPathExcluded(virPath)) {
const relPath = this._resolveVirtualPathToBase(virPath);
if (!relPath) {
return null;
}
if (!virPath.startsWith(this._virBasePath) && virPath !== this._virBaseDir) {
// Neither starts with basePath, nor equals baseDirectory
return null;
}
const relPath = virPath.substr(this._virBasePath.length);
trace.pathCall();

@@ -145,4 +142,4 @@

}
super._write(resource);
const relPath = resource.getPath().substr(this._virBasePath.length);
this._assignProjectToResource(resource);
const relPath = this._resolveVirtualPathToBase(resource.getPath(), true);
log.silly(`Writing to virtual path ${resource.getPath()}`);

@@ -149,0 +146,0 @@ this._virFiles[relPath] = await resource.clone();

import stream from "node:stream";
import clone from "clone";
import path from "node:path";
import posixPath from "node:path/posix";

@@ -42,3 +42,3 @@ const fnTrue = () => true;

* @param {object} parameters Parameters
* @param {string} parameters.path Virtual path
* @param {string} parameters.path Absolute virtual path of the resource
* @param {fs.Stats|object} [parameters.statInfo] File information. Instance of

@@ -62,12 +62,11 @@ * [fs.Stats]{@link https://nodejs.org/api/fs.html#fs_class_fs_stats} or similar object

if (!path) {
throw new Error("Cannot create Resource: path parameter missing");
throw new Error("Unable to create Resource: Missing parameter 'path'");
}
if (buffer && createStream || buffer && string || string && createStream || buffer && stream ||
string && stream || createStream && stream) {
throw new Error("Cannot create Resource: Please set only one content parameter. " +
"Buffer, string, stream or createStream");
throw new Error("Unable to create Resource: Please set only one content parameter. " +
"'buffer', 'string', 'stream' or 'createStream'");
}
this.#path = path;
this.#name = Resource._getNameFromPath(path);
this.setPath(path);

@@ -120,6 +119,2 @@ this.#sourceMetadata = sourceMetadata;

static _getNameFromPath(virPath) {
return path.posix.basename(virPath);
}
/**

@@ -265,6 +260,6 @@ * Gets a buffer with the resource content.

/**
* Gets the resources path
* Gets the virtual resources path
*
* @public
* @returns {string} (Virtual) path of the resource
* @returns {string} Virtual path of the resource
*/

@@ -276,10 +271,14 @@ getPath() {

/**
* Sets the resources path
* Sets the virtual resources path
*
* @public
* @param {string} path (Virtual) path of the resource
* @param {string} path Absolute virtual path of the resource
*/
setPath(path) {
path = posixPath.normalize(path);
if (!posixPath.isAbsolute(path)) {
throw new Error(`Unable to set resource path: Path must be absolute: ${path}`);
}
this.#path = path;
this.#name = Resource._getNameFromPath(path);
this.#name = posixPath.basename(path);
}

@@ -286,0 +285,0 @@

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

import Resource from "./Resource.js";
import posixPath from "node:path/posix";

@@ -24,9 +24,13 @@ /**

if (!path) {
throw new Error("Cannot create ResourceFacade: path parameter missing");
throw new Error("Unable to create ResourceFacade: Missing parameter 'path'");
}
if (!resource) {
throw new Error("Cannot create ResourceFacade: resource parameter missing");
throw new Error("Unable to create ResourceFacade: Missing parameter 'resource'");
}
path = posixPath.normalize(path);
if (!posixPath.isAbsolute(path)) {
throw new Error(`Unable to create ResourceFacade: Parameter 'path' must be absolute: ${path}`);
}
this.#path = path;
this.#name = Resource._getNameFromPath(path);
this.#name = posixPath.basename(path);
this.#resource = resource;

@@ -33,0 +37,0 @@ }

import path from "node:path";
import minimatch from "minimatch";
import DuplexCollection from "./DuplexCollection.js";
import FileSystem from "./adapters/FileSystem.js";
import FsAdapter from "./adapters/FileSystem.js";
import MemAdapter from "./adapters/Memory.js";

@@ -27,4 +27,7 @@ import ReaderCollection from "./ReaderCollection.js";

* @param {object} parameters Parameters
* @param {string} parameters.virBasePath Virtual base path
* @param {string} [parameters.fsBasePath] File system base path
* @param {string} parameters.virBasePath Virtual base path. Must be absolute, POSIX-style, and must end with a slash
* @param {string} [parameters.fsBasePath]
* File System base path.
* If this parameter is supplied, a File System adapter will be created instead of a Memory adapter.
* The provided path must be absolute and must use platform-specific path segment separators.
* @param {string[]} [parameters.excludes] List of glob patterns to exclude

@@ -39,3 +42,2 @@ * @param {object} [parameters.useGitignore=false]

if (fsBasePath) {
const FsAdapter = FileSystem;
return new FsAdapter({fsBasePath, virBasePath, project, excludes, useGitignore});

@@ -48,8 +50,9 @@ } else {

/**
* Creates an adapter and wraps it in a ReaderCollection
* Creates a File System adapter and wraps it in a ReaderCollection
*
* @public
* @param {object} parameters Parameters
* @param {string} parameters.virBasePath Virtual base path
* @param {string} parameters.fsBasePath File system base path
* @param {string} parameters.virBasePath Virtual base path. Must be absolute, POSIX-style, and must end with a slash
* @param {string} parameters.fsBasePath
* File System base path. Must be absolute and must use platform-specific path segment separators
* @param {object} [parameters.project] Experimental, internal parameter. Do not use

@@ -67,3 +70,3 @@ * @param {string[]} [parameters.excludes] List of glob patterns to exclude

// since there would be no way to fill the adapter with resources
throw new Error(`Missing parameter "fsBasePath"`);
throw new Error(`Unable to create reader: Missing parameter "fsBasePath"`);
}

@@ -155,7 +158,7 @@ return new ReaderCollection({

* only used for writing files. If not supplied, a Memory adapter will be created.
* @param {string} [parameters.name="vir & fs source"] Name of the collection
* @param {string} [parameters.name="workspace"] Name of the collection
* @param {string} [parameters.virBasePath="/"] Virtual base path
* @returns {@ui5/fs/DuplexCollection} DuplexCollection which wraps the provided resource locators
*/
export function createWorkspace({reader, writer, virBasePath = "/", name = "vir & fs source"}) {
export function createWorkspace({reader, writer, virBasePath = "/", name = "workspace"}) {
if (!writer) {

@@ -162,0 +165,0 @@ writer = new MemAdapter({

{
"name": "@ui5/fs",
"version": "3.0.0-rc.4",
"version": "3.0.0-rc.5",
"description": "UI5 Tooling - File System Abstraction",

@@ -35,3 +35,3 @@ "author": {

"engines": {
"node": "^16.18.0 || >=18.0.0",
"node": "^16.18.0 || >=18.12.0",
"npm": ">= 8"

@@ -124,3 +124,3 @@ },

"dependencies": {
"@ui5/logger": "^3.0.1-rc.2",
"@ui5/logger": "^3.0.1-rc.3",
"clone": "^2.1.2",

@@ -131,3 +131,3 @@ "escape-string-regexp": "^5.0.0",

"micromatch": "^4.0.5",
"minimatch": "^6.1.5",
"minimatch": "^6.1.6",
"pretty-hrtime": "^1.0.3",

@@ -145,6 +145,6 @@ "random-int": "^3.0.0"

"docdash": "^2.0.1",
"eslint": "^8.32.0",
"eslint": "^8.33.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-ava": "^14.0.0",
"eslint-plugin-jsdoc": "^39.6.7",
"eslint-plugin-jsdoc": "^39.7.4",
"esmock": "^2.1.0",

@@ -154,3 +154,3 @@ "jsdoc": "^3.6.11",

"open-cli": "^7.1.0",
"rimraf": "^4.1.1",
"rimraf": "^4.1.2",
"sinon": "^15.0.1",

@@ -157,0 +157,0 @@ "tap-xunit": "^2.4.1"

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