Comparing version 3.0.0-rc.2 to 3.0.0-rc.3
@@ -5,6 +5,12 @@ # Changelog | ||
A list of unreleased changes can be found [here](https://github.com/SAP/ui5-fs/compare/v3.0.0-rc.2...HEAD). | ||
A list of unreleased changes can be found [here](https://github.com/SAP/ui5-fs/compare/v3.0.0-rc.3...HEAD). | ||
<a name="v3.0.0-rc.3"></a> | ||
## [v3.0.0-rc.3] - 2023-01-20 | ||
### Features | ||
- **Resource:** Add isModified method [`f6a590a`](https://github.com/SAP/ui5-fs/commit/f6a590a284a5ef2879d4d755b5b37be164cf3a45) | ||
<a name="v3.0.0-rc.2"></a> | ||
## [v3.0.0-rc.2] - 2023-01-15 | ||
## [v3.0.0-rc.2] - 2023-01-19 | ||
### Dependency Updates | ||
@@ -226,2 +232,3 @@ - Bump minimatch from 5.1.4 to 6.1.5 [`e6b8d14`](https://github.com/SAP/ui5-fs/commit/e6b8d142517a19b138dab5fc19390ed98db425e1) | ||
[v3.0.0-rc.3]: https://github.com/SAP/ui5-fs/compare/v3.0.0-rc.2...v3.0.0-rc.3 | ||
[v3.0.0-rc.2]: https://github.com/SAP/ui5-fs/compare/v3.0.0-rc.1...v3.0.0-rc.2 | ||
@@ -228,0 +235,0 @@ [v3.0.0-rc.1]: https://github.com/SAP/ui5-fs/compare/v3.0.0-rc.0...v3.0.0-rc.1 |
@@ -188,3 +188,7 @@ import logger from "@ui5/logger"; | ||
async _migrateResource(resource) { | ||
_migrateResource(resource) { | ||
// This function only returns a promise if a migration is necessary. | ||
// Since this is rarely the case, we therefore reduce the amount of | ||
// created Promises by making this differentiation | ||
// Check if its a fs/Resource v3, function 'hasProject' was | ||
@@ -195,3 +199,6 @@ // introduced with v3 therefore take it as the indicator | ||
} | ||
return this._createFromLegacyResource(resource); | ||
} | ||
async _createFromLegacyResource(resource) { | ||
const options = { | ||
@@ -198,0 +205,0 @@ path: resource._path, |
@@ -15,3 +15,3 @@ import logger from "@ui5/logger"; | ||
const READ_ONLY_MODE = 0o444; | ||
const ADAPTER_NAME = "FileSystem"; | ||
/** | ||
@@ -74,4 +74,4 @@ * File system resource adapter | ||
path: this._virBaseDir, | ||
source: { | ||
adapter: "FileSystem", | ||
sourceMetadata: { | ||
adapter: ADAPTER_NAME, | ||
fsPath: this._fsBasePath | ||
@@ -111,4 +111,4 @@ }, | ||
path: virPath, | ||
source: { | ||
adapter: "FileSystem", | ||
sourceMetadata: { | ||
adapter: ADAPTER_NAME, | ||
fsPath: fsPath | ||
@@ -188,4 +188,4 @@ }, | ||
path: virPath, | ||
source: { | ||
adapter: "FileSystem", | ||
sourceMetadata: { | ||
adapter: ADAPTER_NAME, | ||
fsPath | ||
@@ -231,3 +231,8 @@ } | ||
async _write(resource, {drain, readOnly}) { | ||
resource = await this._migrateResource(resource); | ||
resource = this._migrateResource(resource); | ||
if (resource instanceof Promise) { | ||
// Only await if the migrate function returned a promise | ||
// Otherwise await would automatically create a Promise, causing unwanted overhead | ||
resource = await resource; | ||
} | ||
super._write(resource); | ||
@@ -245,16 +250,33 @@ if (drain && readOnly) { | ||
const resourceSource = resource.getSource(); | ||
if (!resourceSource.modified && resourceSource.adapter === "FileSystem" && resourceSource.fsPath) { | ||
// fs.copyFile can be used when the resource is from FS and hasn't been modified | ||
// In addition, nothing needs to be done when src === dest | ||
if (resourceSource.fsPath === fsPath) { | ||
log.silly(`Skip writing to ${fsPath} (Resource hasn't been modified)`); | ||
} else { | ||
log.silly(`Copying resource from ${resourceSource.fsPath} to ${fsPath}`); | ||
await copyFile(resourceSource.fsPath, fsPath); | ||
const sourceMetadata = resource.getSourceMetadata(); | ||
if (sourceMetadata && sourceMetadata.adapter === ADAPTER_NAME && sourceMetadata.fsPath) { | ||
// Resource has been created by FileSystem adapter. This means it might require special handling | ||
/* The following code covers these four conditions: | ||
1. FS-paths not equal + Resource not modified => Shortcut: Use fs.copyFile | ||
2. FS-paths equal + Resource not modified => Shortcut: Skip write altogether | ||
3. FS-paths equal + Resource modified => Drain stream into buffer. Later write from buffer as usual | ||
4. FS-paths not equal + Resource modified => No special handling. Write from stream or buffer | ||
*/ | ||
if (sourceMetadata.fsPath !== fsPath && !sourceMetadata.contentModified) { | ||
// Shortcut: fs.copyFile can be used when the resource hasn't been modified | ||
log.silly(`Resource hasn't been modified. Copying resource from ${sourceMetadata.fsPath} to ${fsPath}`); | ||
await copyFile(sourceMetadata.fsPath, fsPath); | ||
if (readOnly) { | ||
await chmod(fsPath, READ_ONLY_MODE); | ||
} | ||
} | ||
return; | ||
return; | ||
} else if (sourceMetadata.fsPath === fsPath && !sourceMetadata.contentModified) { | ||
log.silly( | ||
`Resource hasn't been modified, target path equals source path. Skipping write to ${fsPath}`); | ||
if (readOnly) { | ||
await chmod(fsPath, READ_ONLY_MODE); | ||
} | ||
return; | ||
} else if (sourceMetadata.fsPath === fsPath && sourceMetadata.contentModified) { | ||
// Resource has been modified. Make sure all streams are drained to prevent | ||
// issues caused by piping the original read-stream into a write-stream for the same path | ||
await resource.getBuffer(); | ||
} else {/* Different paths + modifications require no special handling */} | ||
} | ||
@@ -264,6 +286,6 @@ | ||
return new Promise((resolve, reject) => { | ||
await new Promise((resolve, reject) => { | ||
let contentStream; | ||
if ((drain || readOnly) && resourceSource.fsPath !== fsPath) { | ||
if (drain || readOnly) { | ||
// Stream will be drained | ||
@@ -302,8 +324,2 @@ contentStream = resource.getStream(); | ||
write.on("close", (ex) => { | ||
if (readOnly) { | ||
// Create new stream from written file | ||
resource.setStream(function() { | ||
return fs.createReadStream(fsPath); | ||
}); | ||
} | ||
resolve(); | ||
@@ -313,2 +329,18 @@ }); | ||
}); | ||
if (readOnly) { | ||
if (sourceMetadata?.fsPath === fsPath) { | ||
// When streaming into the same file, permissions need to be changed explicitly | ||
await chmod(fsPath, READ_ONLY_MODE); | ||
} | ||
// In case of readOnly, we drained the stream and can now set a new callback | ||
// for creating a stream from written file | ||
// This should be identical to buffering the resource content in memory, since the written file | ||
// can not be modified. | ||
// We chose this approach to be more memory efficient in scenarios where readOnly is used | ||
resource.setStream(function() { | ||
return fs.createReadStream(fsPath); | ||
}); | ||
} | ||
} | ||
@@ -315,0 +347,0 @@ } |
@@ -6,2 +6,4 @@ import logger from "@ui5/logger"; | ||
const ADAPTER_NAME = "Memory"; | ||
/** | ||
@@ -80,4 +82,4 @@ * Virtual resource Adapter | ||
}, | ||
source: { | ||
adapter: "Memory" | ||
sourceMetadata: { | ||
adapter: ADAPTER_NAME | ||
}, | ||
@@ -137,3 +139,8 @@ path: this._virBasePath.slice(0, -1) | ||
async _write(resource) { | ||
resource = await this._migrateResource(resource); | ||
resource = this._migrateResource(resource); | ||
if (resource instanceof Promise) { | ||
// Only await if the migrate function returned a promise | ||
// Otherwise await would automatically create a Promise, causing unwanted overhead | ||
resource = await resource; | ||
} | ||
super._write(resource); | ||
@@ -161,4 +168,4 @@ const relPath = resource.getPath().substr(this._virBasePath.length); | ||
project: this._project, | ||
source: { | ||
adapter: "Memory" | ||
sourceMetadata: { | ||
adapter: ADAPTER_NAME | ||
}, | ||
@@ -165,0 +172,0 @@ statInfo: { // TODO: make closer to fs stat info |
@@ -9,3 +9,3 @@ import stream from "node:stream"; | ||
/** | ||
* Resource | ||
* Resource. UI5 Tooling specific representation of a file's content and metadata | ||
* | ||
@@ -17,2 +17,16 @@ * @public | ||
class Resource { | ||
#project; | ||
#buffer; | ||
#buffering; | ||
#collections; | ||
#contentDrained; | ||
#createStream; | ||
#name; | ||
#path; | ||
#sourceMetadata; | ||
#statInfo; | ||
#stream; | ||
#streamDrained; | ||
#isModified; | ||
/** | ||
@@ -27,3 +41,2 @@ * Function for dynamic creation of content streams | ||
/** | ||
* The constructor. | ||
* | ||
@@ -46,5 +59,6 @@ * @public | ||
* @param {@ui5/project/specifications/Project} [parameters.project] Project this resource is associated with | ||
* @param {object} [parameters.source] Experimental, internal parameter. Do not use | ||
* @param {object} [parameters.sourceMetadata] Source metadata for UI5 Tooling internal use. | ||
* Typically set by an adapter to store information for later retrieval. | ||
*/ | ||
constructor({path, statInfo, buffer, string, createStream, stream, project, source}) { | ||
constructor({path, statInfo, buffer, string, createStream, stream, project, sourceMetadata}) { | ||
if (!path) { | ||
@@ -59,13 +73,18 @@ throw new Error("Cannot create Resource: path parameter missing"); | ||
this._path = path; | ||
this._name = Resource._getNameFromPath(path); | ||
this.#path = path; | ||
this.#name = Resource._getNameFromPath(path); | ||
this._source = source; // Experimental, internal parameter | ||
if (this._source) { | ||
// Indicator for adapters like FileSystem to detect whether a resource has been changed | ||
this._source.modified = this._source.modified || false; | ||
this.#sourceMetadata = sourceMetadata; | ||
if (this.#sourceMetadata) { | ||
// This flag indicates whether a resource has changed from its original source. | ||
// resource.isModified() is not sufficient, since it only reflects the modification state of the | ||
// current instance. | ||
// Since the sourceMetadata object is inherited to clones, it is the only correct indicator | ||
this.#sourceMetadata.contentModified = this.#sourceMetadata.contentModified || false; | ||
} | ||
this.__project = project; // Two underscores since "_project" was widely used in UI5 Tooling 2.0 | ||
this.#isModified = false; | ||
this._statInfo = statInfo || { // TODO | ||
this.#project = project; | ||
this.#statInfo = statInfo || { // TODO | ||
isFile: fnTrue, | ||
@@ -89,13 +108,15 @@ isDirectory: fnFalse, | ||
if (createStream) { | ||
this._createStream = createStream; | ||
this.#createStream = createStream; | ||
} else if (stream) { | ||
this._stream = stream; | ||
this.#stream = stream; | ||
} else if (buffer) { | ||
this.setBuffer(buffer); | ||
// Use private setter, not to accidentally set any modified flags | ||
this.#setBuffer(buffer); | ||
} else if (typeof string === "string" || string instanceof String) { | ||
this.setString(string); | ||
// Use private setter, not to accidentally set any modified flags | ||
this.#setBuffer(Buffer.from(string, "utf8")); | ||
} | ||
// Tracing: | ||
this._collections = []; | ||
this.#collections = []; | ||
} | ||
@@ -114,13 +135,13 @@ | ||
async getBuffer() { | ||
if (this._contentDrained) { | ||
throw new Error(`Content of Resource ${this._path} has been drained. ` + | ||
if (this.#contentDrained) { | ||
throw new Error(`Content of Resource ${this.#path} has been drained. ` + | ||
"This might be caused by requesting resource content after a content stream has been " + | ||
"requested and no new content (e.g. a new stream) has been set."); | ||
} | ||
if (this._buffer) { | ||
return this._buffer; | ||
} else if (this._createStream || this._stream) { | ||
return this._getBufferFromStream(); | ||
if (this.#buffer) { | ||
return this.#buffer; | ||
} else if (this.#createStream || this.#stream) { | ||
return this.#getBufferFromStream(); | ||
} else { | ||
throw new Error(`Resource ${this._path} has no content`); | ||
throw new Error(`Resource ${this.#path} has no content`); | ||
} | ||
@@ -136,13 +157,18 @@ } | ||
setBuffer(buffer) { | ||
if (this._source && !this._source.modified) { | ||
this._source.modified = true; | ||
if (this.#sourceMetadata) { | ||
this.#sourceMetadata.contentModified = true; | ||
} | ||
this._createStream = null; | ||
// if (this._stream) { // TODO this may cause strange issues | ||
// this._stream.destroy(); | ||
this.#isModified = true; | ||
this.#setBuffer(buffer); | ||
} | ||
#setBuffer(buffer) { | ||
this.#createStream = null; | ||
// if (this.#stream) { // TODO this may cause strange issues | ||
// this.#stream.destroy(); | ||
// } | ||
this._stream = null; | ||
this._buffer = buffer; | ||
this._contentDrained = false; | ||
this._streamDrained = false; | ||
this.#stream = null; | ||
this.#buffer = buffer; | ||
this.#contentDrained = false; | ||
this.#streamDrained = false; | ||
} | ||
@@ -157,4 +183,4 @@ | ||
getString() { | ||
if (this._contentDrained) { | ||
return Promise.reject(new Error(`Content of Resource ${this._path} has been drained. ` + | ||
if (this.#contentDrained) { | ||
return Promise.reject(new Error(`Content of Resource ${this.#path} has been drained. ` + | ||
"This might be caused by requesting resource content after a content stream has been " + | ||
@@ -188,4 +214,4 @@ "requested and no new content (e.g. a new stream) has been set.")); | ||
getStream() { | ||
if (this._contentDrained) { | ||
throw new Error(`Content of Resource ${this._path} has been drained. ` + | ||
if (this.#contentDrained) { | ||
throw new Error(`Content of Resource ${this.#path} has been drained. ` + | ||
"This might be caused by requesting resource content after a content stream has been " + | ||
@@ -195,11 +221,11 @@ "requested and no new content (e.g. a new stream) has been set."); | ||
let contentStream; | ||
if (this._buffer) { | ||
if (this.#buffer) { | ||
const bufferStream = new stream.PassThrough(); | ||
bufferStream.end(this._buffer); | ||
bufferStream.end(this.#buffer); | ||
contentStream = bufferStream; | ||
} else if (this._createStream || this._stream) { | ||
contentStream = this._getStream(); | ||
} else if (this.#createStream || this.#stream) { | ||
contentStream = this.#getStream(); | ||
} | ||
if (!contentStream) { | ||
throw new Error(`Resource ${this._path} has no content`); | ||
throw new Error(`Resource ${this.#path} has no content`); | ||
} | ||
@@ -214,3 +240,3 @@ // If a stream instance is being returned, it will typically get drained be the consumer. | ||
// createStream callback is being used. | ||
this._contentDrained = true; | ||
this.#contentDrained = true; | ||
return contentStream; | ||
@@ -227,18 +253,20 @@ } | ||
setStream(stream) { | ||
if (this._source && !this._source.modified) { | ||
this._source.modified = true; | ||
this.#isModified = true; | ||
if (this.#sourceMetadata) { | ||
this.#sourceMetadata.contentModified = true; | ||
} | ||
this._buffer = null; | ||
// if (this._stream) { // TODO this may cause strange issues | ||
// this._stream.destroy(); | ||
this.#buffer = null; | ||
// if (this.#stream) { // TODO this may cause strange issues | ||
// this.#stream.destroy(); | ||
// } | ||
if (typeof stream === "function") { | ||
this._createStream = stream; | ||
this._stream = null; | ||
this.#createStream = stream; | ||
this.#stream = null; | ||
} else { | ||
this._stream = stream; | ||
this._createStream = null; | ||
this.#stream = stream; | ||
this.#createStream = null; | ||
} | ||
this._contentDrained = false; | ||
this._streamDrained = false; | ||
this.#contentDrained = false; | ||
this.#streamDrained = false; | ||
} | ||
@@ -253,3 +281,3 @@ | ||
getPath() { | ||
return this._path; | ||
return this.#path; | ||
} | ||
@@ -264,4 +292,4 @@ | ||
setPath(path) { | ||
this._path = path; | ||
this._name = Resource._getNameFromPath(path); | ||
this.#path = path; | ||
this.#name = Resource._getNameFromPath(path); | ||
} | ||
@@ -276,3 +304,3 @@ | ||
getName() { | ||
return this._name; | ||
return this.#name; | ||
} | ||
@@ -291,3 +319,3 @@ | ||
getStatInfo() { | ||
return this._statInfo; | ||
return this.#statInfo; | ||
} | ||
@@ -303,3 +331,3 @@ | ||
// if resource does not have any content it should have 0 bytes | ||
if (!this._buffer && !this._createStream && !this._stream) { | ||
if (!this.#buffer && !this.#createStream && !this.#stream) { | ||
return 0; | ||
@@ -317,3 +345,3 @@ } | ||
pushCollection(name) { | ||
this._collections.push(name); | ||
this.#collections.push(name); | ||
} | ||
@@ -328,19 +356,19 @@ | ||
async clone() { | ||
const options = await this._getCloneOptions(); | ||
const options = await this.#getCloneOptions(); | ||
return new Resource(options); | ||
} | ||
async _getCloneOptions() { | ||
async #getCloneOptions() { | ||
const options = { | ||
path: this._path, | ||
statInfo: clone(this._statInfo), | ||
source: clone(this._source) | ||
path: this.#path, | ||
statInfo: clone(this.#statInfo), | ||
sourceMetadata: clone(this.#sourceMetadata) | ||
}; | ||
if (this._stream) { | ||
options.buffer = await this._getBufferFromStream(); | ||
} else if (this._createStream) { | ||
options.createStream = this._createStream; | ||
} else if (this._buffer) { | ||
options.buffer = this._buffer; | ||
if (this.#stream) { | ||
options.buffer = await this.#getBufferFromStream(); | ||
} else if (this.#createStream) { | ||
options.createStream = this.#createStream; | ||
} else if (this.#buffer) { | ||
options.buffer = this.#buffer; | ||
} | ||
@@ -365,3 +393,3 @@ | ||
getProject() { | ||
return this.__project; | ||
return this.#project; | ||
} | ||
@@ -376,7 +404,7 @@ | ||
setProject(project) { | ||
if (this.__project) { | ||
throw new Error(`Unable to assign project ${project.getName()} to resource ${this._path}: ` + | ||
`Resource is already associated to project ${this.__project}`); | ||
if (this.#project) { | ||
throw new Error(`Unable to assign project ${project.getName()} to resource ${this.#path}: ` + | ||
`Resource is already associated to project ${this.#project}`); | ||
} | ||
this.__project = project; | ||
this.#project = project; | ||
} | ||
@@ -391,6 +419,16 @@ | ||
hasProject() { | ||
return !!this.__project; | ||
return !!this.#project; | ||
} | ||
/** | ||
* Check whether the content of this resource has been changed during its life cycle | ||
* | ||
* @public | ||
* @returns {boolean} True if the resource's content has been changed | ||
*/ | ||
isModified() { | ||
return this.#isModified; | ||
} | ||
/** | ||
* Tracing: Get tree for printing out trace | ||
@@ -403,6 +441,6 @@ * | ||
let pointer = tree[this._path] = Object.create(null); | ||
let pointer = tree[this.#path] = Object.create(null); | ||
for (let i = this._collections.length - 1; i >= 0; i--) { | ||
pointer = pointer[this._collections[i]] = Object.create(null); | ||
for (let i = this.#collections.length - 1; i >= 0; i--) { | ||
pointer = pointer[this.#collections[i]] = Object.create(null); | ||
} | ||
@@ -413,4 +451,10 @@ | ||
getSource() { | ||
return this._source || {}; | ||
/** | ||
* Returns source metadata if any where provided during the creation of this resource. | ||
* Typically set by an adapter to store information for later retrieval. | ||
* | ||
* @returns {object|null} | ||
*/ | ||
getSourceMetadata() { | ||
return this.#sourceMetadata || null; | ||
} | ||
@@ -424,11 +468,11 @@ | ||
*/ | ||
_getStream() { | ||
if (this._streamDrained) { | ||
throw new Error(`Content stream of Resource ${this._path} is flagged as drained.`); | ||
#getStream() { | ||
if (this.#streamDrained) { | ||
throw new Error(`Content stream of Resource ${this.#path} is flagged as drained.`); | ||
} | ||
if (this._createStream) { | ||
return this._createStream(); | ||
if (this.#createStream) { | ||
return this.#createStream(); | ||
} | ||
this._streamDrained = true; | ||
return this._stream; | ||
this.#streamDrained = true; | ||
return this.#stream; | ||
} | ||
@@ -442,8 +486,8 @@ | ||
*/ | ||
_getBufferFromStream() { | ||
if (this._buffering) { // Prevent simultaneous buffering, causing unexpected access to drained stream | ||
return this._buffering; | ||
#getBufferFromStream() { | ||
if (this.#buffering) { // Prevent simultaneous buffering, causing unexpected access to drained stream | ||
return this.#buffering; | ||
} | ||
return this._buffering = new Promise((resolve, reject) => { | ||
const contentStream = this._getStream(); | ||
return this.#buffering = new Promise((resolve, reject) => { | ||
const contentStream = this.#getStream(); | ||
const buffers = []; | ||
@@ -458,12 +502,4 @@ contentStream.on("data", (data) => { | ||
const buffer = Buffer.concat(buffers); | ||
let modified; | ||
if (this._source) { | ||
modified = this._source.modified; | ||
} | ||
this.setBuffer(buffer); | ||
// Modified flag should be reset as the resource hasn't been modified from the outside | ||
if (this._source) { | ||
this._source.modified = modified; | ||
} | ||
this._buffering = null; | ||
this.#setBuffer(buffer); | ||
this.#buffering = null; | ||
resolve(buffer); | ||
@@ -470,0 +506,0 @@ }); |
@@ -11,9 +11,12 @@ import Resource from "./Resource.js"; | ||
class ResourceFacade { | ||
#path; | ||
#name; | ||
#resource; | ||
/** | ||
* The constructor. | ||
* | ||
* @public | ||
* @param {object} parameters Parameters | ||
* @param {string} parameters.path Virtual path | ||
* @param {@ui5/fs/Resource} parameters.resource Resource to cover | ||
* @param {string} parameters.path Virtual path of the facade resource | ||
* @param {@ui5/fs/Resource} parameters.resource Resource to conceal | ||
*/ | ||
@@ -27,5 +30,5 @@ constructor({path, resource}) { | ||
} | ||
this._path = path; | ||
this._name = Resource._getNameFromPath(path); | ||
this._resource = resource; | ||
this.#path = path; | ||
this.#name = Resource._getNameFromPath(path); | ||
this.#resource = resource; | ||
} | ||
@@ -40,3 +43,3 @@ | ||
getPath() { | ||
return this._path; | ||
return this.#path; | ||
} | ||
@@ -51,3 +54,3 @@ | ||
getName() { | ||
return this._name; | ||
return this.#name; | ||
} | ||
@@ -74,3 +77,3 @@ | ||
// Cloning resolves the facade | ||
const resourceClone = await this._resource.clone(); | ||
const resourceClone = await this.#resource.clone(); | ||
resourceClone.setPath(this.getPath()); | ||
@@ -92,3 +95,3 @@ return resourceClone; | ||
async getBuffer() { | ||
return this._resource.getBuffer(); | ||
return this.#resource.getBuffer(); | ||
} | ||
@@ -103,3 +106,3 @@ | ||
setBuffer(buffer) { | ||
return this._resource.setBuffer(buffer); | ||
return this.#resource.setBuffer(buffer); | ||
} | ||
@@ -114,3 +117,3 @@ | ||
getString() { | ||
return this._resource.getString(); | ||
return this.#resource.getString(); | ||
} | ||
@@ -125,3 +128,3 @@ | ||
setString(string) { | ||
return this._resource.setString(string); | ||
return this.#resource.setString(string); | ||
} | ||
@@ -141,3 +144,3 @@ | ||
getStream() { | ||
return this._resource.getStream(); | ||
return this.#resource.getStream(); | ||
} | ||
@@ -153,3 +156,3 @@ | ||
setStream(stream) { | ||
return this._resource.setStream(stream); | ||
return this.#resource.setStream(stream); | ||
} | ||
@@ -168,3 +171,3 @@ | ||
getStatInfo() { | ||
return this._resource.getStatInfo(); | ||
return this.#resource.getStatInfo(); | ||
} | ||
@@ -179,3 +182,3 @@ | ||
async getSize() { | ||
return this._resource.getSize(); | ||
return this.#resource.getSize(); | ||
} | ||
@@ -189,3 +192,3 @@ | ||
pushCollection(name) { | ||
return this._resource.pushCollection(name); | ||
return this.#resource.pushCollection(name); | ||
} | ||
@@ -199,3 +202,3 @@ | ||
getPathTree() { | ||
return this._resource.getPathTree(); | ||
return this.#resource.getPathTree(); | ||
} | ||
@@ -217,3 +220,3 @@ | ||
getProject() { | ||
return this._resource.getProject(); | ||
return this.#resource.getProject(); | ||
} | ||
@@ -228,3 +231,3 @@ | ||
setProject(project) { | ||
return this._resource.setProject(project); | ||
return this.#resource.setProject(project); | ||
} | ||
@@ -239,11 +242,32 @@ | ||
hasProject() { | ||
return this._resource.hasProject(); | ||
return this.#resource.hasProject(); | ||
} | ||
/** | ||
* Check whether the content of this resource has been changed during its life cycle | ||
* | ||
* @public | ||
* @returns {boolean} True if the resource's content has been changed | ||
*/ | ||
isModified() { | ||
return this.#resource.isModified(); | ||
} | ||
getConcealedResource() { | ||
return this._resource; | ||
/** | ||
* Returns source metadata if any where provided during the creation of this resource. | ||
* Typically set by an adapter to store information for later retrieval. | ||
* | ||
* @returns {object|null} | ||
*/ | ||
getSourceMetadata() { | ||
return this.#resource.getSourceMetadata(); | ||
} | ||
getSource() { | ||
return this._resource.getSource(); | ||
/** | ||
* Returns the resource concealed by this facade | ||
* | ||
* @returns {@ui5/fs/Resource} | ||
*/ | ||
getConcealedResource() { | ||
return this.#resource; | ||
} | ||
@@ -250,0 +274,0 @@ } |
{ | ||
"name": "@ui5/fs", | ||
"version": "3.0.0-rc.2", | ||
"version": "3.0.0-rc.3", | ||
"description": "UI5 Tooling - File System Abstraction", | ||
@@ -135,3 +135,3 @@ "author": { | ||
"@istanbuljs/esm-loader-hook": "^0.2.0", | ||
"ava": "^5.1.0", | ||
"ava": "^5.1.1", | ||
"chai": "^4.3.7", | ||
@@ -146,3 +146,3 @@ "chai-fs": "^2.0.0", | ||
"eslint-plugin-ava": "^13.2.0", | ||
"eslint-plugin-jsdoc": "^39.6.4", | ||
"eslint-plugin-jsdoc": "^39.6.7", | ||
"esmock": "^2.1.0", | ||
@@ -149,0 +149,0 @@ "jsdoc": "^3.6.11", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
131821
2821