webgme-engine
Version:
WebGME server and Client API without a GUI
343 lines (288 loc) • 15.4 kB
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: common/blob/Artifact.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: common/blob/Artifact.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/*globals define*/
/*eslint-env node, browser*/
/**
* @author lattmann / https://github.com/lattmann
*/
define([
'blob/BlobMetadata',
'blob/BlobConfig',
'common/core/tasync',
'q'
], function (BlobMetadata, BlobConfig, tasync, Q) {
'use strict';
/**
* Creates a new instance of artifact, i.e. complex object, in memory. This object can be saved in the blob-storage
* on the server and later retrieved with its metadata hash.
* @param {string} name Artifact's name without extension
* @param {BlobClient} blobClient
* @param {BlobMetadata} descriptor
* @constructor
* @alias Artifact
*/
var Artifact = function (name, blobClient, descriptor) {
this.name = name;
this.blobClient = blobClient;
this.blobClientPutFile = tasync.unwrap(tasync.throttle(tasync.wrap(blobClient.putFile), 5));
this.blobClientGetMetadata = tasync.unwrap(tasync.throttle(tasync.wrap(blobClient.getMetadata), 5));
// TODO: use BlobMetadata class here
this.descriptor = descriptor || {
name: name + '.zip',
size: 0,
mime: 'application/zip',
content: {},
contentType: 'complex'
}; // name and hash pairs
};
/**
* Adds content to the artifact as a file.
* @param {string} name - filename
* @param {Blob} content - File object or Blob.
* @param {function} [callback] - if provided no promise will be returned.
*
* @return {external:Promise} On success the promise will be resolved with {string} <b>metadataHash</b>.<br>
* On error the promise will be rejected with {@link Error} <b>error</b>.
*/
Artifact.prototype.addFile = function (name, content, callback) {
var self = this,
filename = name.substring(name.lastIndexOf('/') + 1),
deferred = Q.defer();
self.blobClientPutFile.call(self.blobClient, filename, content, function (err, metadataHash) {
if (err) {
deferred.reject(err);
return;
}
self.addObjectHash(name, metadataHash, function (err, metadataHash) {
if (err) {
deferred.reject(err);
return;
}
deferred.resolve(metadataHash);
});
});
return deferred.promise.nodeify(callback);
};
/**
* Adds files as soft-link.
* @param {string} name - filename.
* @param {Blob} content - File object or Blob.
* @param {function} [callback] - if provided no promise will be returned.
*
* @return {external:Promise} On success the promise will be resolved with {string} <b>metadataHash</b>.<br>
* On error the promise will be rejected with {@link Error} <b>error</b>.
*/
Artifact.prototype.addFileAsSoftLink = function (name, content, callback) {
var deferred = Q.defer(),
self = this,
filename = name.substring(name.lastIndexOf('/') + 1);
self.blobClientPutFile.call(self.blobClient, filename, content,
function (err, metadataHash) {
if (err) {
deferred.reject(err);
return;
}
var size;
if (content.size !== undefined) {
size = content.size;
}
if (content.length !== undefined) {
size = content.length;
}
self.addMetadataHash(name, metadataHash, size)
.then(deferred.resolve)
.catch(deferred.reject);
});
return deferred.promise.nodeify(callback);
};
/**
* Adds a hash to the artifact using the given file path.
* @param {string} name - Path to the file in the artifact. Note: 'a/b/c.txt'
* @param {string} metadataHash - Metadata hash that has to be added.
* @param {function} [callback] - if provided no promise will be returned.
*
* @return {external:Promise} On success the promise will be resolved with {string} <b>hash</b>.<br>
* On error the promise will be rejected with {@link Error} <b>error</b>.
*/
Artifact.prototype.addObjectHash = function (name, metadataHash, callback) {
var self = this,
deferred = Q.defer();
if (BlobConfig.hashRegex.test(metadataHash) === false) {
deferred.reject('Blob hash is invalid');
} else {
self.blobClientGetMetadata.call(self.blobClient, metadataHash, function (err, metadata) {
if (err) {
deferred.reject(err);
return;
}
if (Object.hasOwn(self.descriptor.content, name)) {
deferred.reject(new Error('Another content with the same name was already added. ' +
JSON.stringify(self.descriptor.content[name])));
} else {
self.descriptor.size += metadata.size;
self.descriptor.content[name] = {
content: metadata.content,
contentType: BlobMetadata.CONTENT_TYPES.OBJECT
};
deferred.resolve(metadataHash);
}
});
}
return deferred.promise.nodeify(callback);
};
/**
* Adds a hash to the artifact using the given file path.
* @param {string} name - Path to the file in the artifact. Note: 'a/b/c.txt'
* @param {string} metadataHash - Metadata hash that has to be added.
* @param {number} [size] - Size of the referenced blob.
* @param {function} [callback] - if provided no promise will be returned.
*
* @return {external:Promise} On success the promise will be resolved with {string} <b>hash</b>.<br>
* On error the promise will be rejected with {@link Error} <b>error</b>.
*/
Artifact.prototype.addMetadataHash = function (name, metadataHash, size, callback) {
var self = this,
deferred = Q.defer(),
addMetadata = function (size) {
if (Object.hasOwn(self.descriptor.content, name)) {
deferred.reject(new Error('Another content with the same name was already added. ' +
JSON.stringify(self.descriptor.content[name])));
} else {
self.descriptor.size += size;
self.descriptor.content[name] = {
content: metadataHash,
contentType: BlobMetadata.CONTENT_TYPES.SOFT_LINK
};
deferred.resolve(metadataHash);
}
};
if (typeof size === 'function') {
callback = size;
size = undefined;
}
if (BlobConfig.hashRegex.test(metadataHash) === false) {
deferred.reject(new Error('Blob hash is invalid'));
} else if (size === undefined) {
self.blobClientGetMetadata.call(self.blobClient, metadataHash, function (err, metadata) {
if (err) {
deferred.reject(err);
return;
}
addMetadata(metadata.size);
});
} else {
addMetadata(size);
}
return deferred.promise.nodeify(callback);
};
/**
* Adds multiple files.
* @param {Object.<string, Blob>} files files to add
* @param {function} [callback] - if provided no promise will be returned.
*
* @return {external:Promise} On success the promise will be resolved with {string[]} <b>metadataHashes</b>.<br>
* On error the promise will be rejected with {@link Error|string} <b>error</b>.
*/
Artifact.prototype.addFiles = function (files, callback) {
var self = this,
fileNames = Object.keys(files);
return Q.all(fileNames.map(function (fileName) {
return self.addFile(fileName, files[fileName]);
})).nodeify(callback);
};
/**
* Adds multiple files as soft-links.
* @param {Object.<string, Blob>} files files to add
* @param {function} [callback] - if provided no promise will be returned.
*
* @return {external:Promise} On success the promise will be resolved with {string[]} <b>metadataHashes</b>.<br>
* On error the promise will be rejected with {@link Error} <b>error</b>.
*/
Artifact.prototype.addFilesAsSoftLinks = function (files, callback) {
var self = this,
fileNames = Object.keys(files);
return Q.all(fileNames.map(function (fileName) {
return self.addFileAsSoftLink(fileName, files[fileName]);
})).nodeify(callback);
};
/**
* Adds hashes to the artifact using the given file paths.
* @param {object.<string, string>} metadataHashes - Keys are file paths and values metadata hashes.
* @param {function} [callback] - if provided no promise will be returned.
*
* @return {external:Promise} On success the promise will be resolved with {string[]} <b>hashes</b>.<br>
* On error the promise will be rejected with {@link Error} <b>error</b>.
*/
Artifact.prototype.addObjectHashes = function (metadataHashes, callback) {
var self = this,
fileNames = Object.keys(metadataHashes);
return Q.all(fileNames.map(function (fileName) {
return self.addObjectHash(fileName, metadataHashes[fileName]);
})).nodeify(callback);
};
/**
* Adds hashes to the artifact using the given file paths.
* @param {object.<string, string>} metadataHashes - Keys are file paths and values metadata hashes.
* @param {function} [callback] - if provided no promise will be returned.
*
* @return {external:Promise} On success the promise will be resolved with {string[]} <b>hashes</b>.<br>
* On error the promise will be rejected with {@link Error} <b>error</b>.
*/
Artifact.prototype.addMetadataHashes = function (metadataHashes, callback) {
var self = this,
fileNames = Object.keys(metadataHashes);
return Q.all(fileNames.map(function (fileName) {
return self.addMetadataHash(fileName, metadataHashes[fileName]);
})).nodeify(callback);
};
/**
* Saves this artifact and uploads the metadata to the server's storage.
* @param {function} [callback] - if provided no promise will be returned.
*
* @return {external:Promise} On success the promise will be resolved with {string} <b>metadataHash</b>.<br>
* On error the promise will be rejected with {@link Error} <b>error</b>.
*/
Artifact.prototype.save = function (callback) {
var deferred = Q.defer();
this.blobClient.putMetadata(this.descriptor, function (err, hash) {
if (err) {
deferred.reject(err);
} else {
deferred.resolve(hash);
}
});
return deferred.promise.nodeify(callback);
};
return Artifact;
});
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="Server_GMEAuth.html">Server:GMEAuth</a></li><li><a href="Server_SafeStorage.html">Server:SafeStorage</a></li><li><a href="Server_UserProject.html">Server:UserProject</a></li><li><a href="module-Core.html">Core</a></li><li><a href="module-Storage.html">Storage</a></li><li><a href="module-crosscuts.html">crosscuts</a></li><li><a href="module-serialization.html">serialization</a></li></ul><h3>Externals</h3><ul><li><a href="external-Promise.html">Promise</a></li></ul><h3>Classes</h3><ul><li><a href="AddOnBase.html">AddOnBase</a></li><li><a href="AddOnUpdateResult.html">AddOnUpdateResult</a></li><li><a href="Artifact.html">Artifact</a></li><li><a href="BlobClient.html">BlobClient</a></li><li><a href="BlobMetadata.html">BlobMetadata</a></li><li><a href="BlobRunPluginClient.html">BlobRunPluginClient</a></li><li><a href="Client.html">Client</a></li><li><a href="Core.html">Core</a></li><li><a href="ExecutorClient.html">ExecutorClient</a></li><li><a href="GMENode.html">GMENode</a></li><li><a href="GmeLogger.html">GmeLogger</a></li><li><a href="InterPluginResult.html">InterPluginResult</a></li><li><a href="JobInfo.html">JobInfo</a></li><li><a href="OutputInfo.html">OutputInfo</a></li><li><a href="PluginBase.html">PluginBase</a></li><li><a href="PluginConfig.html">PluginConfig</a></li><li><a href="PluginMessage.html">PluginMessage</a></li><li><a href="PluginNodeDescription.html">PluginNodeDescription</a></li><li><a href="PluginResult.html">PluginResult</a></li><li><a href="Project.html">Project</a></li><li><a href="ProjectInterface.html">ProjectInterface</a></li><li><a href="Server_GMEAuth-GMEAuth.html">GMEAuth</a></li><li><a href="Server_SafeStorage-SafeStorage.html">SafeStorage</a></li><li><a href="Server_UserProject-UserProject.html">UserProject</a></li><li><a href="WebsocketRouter.html">WebsocketRouter</a></li><li><a href="WebsocketRouterUser.html">WebsocketRouterUser</a></li></ul><h3>Events</h3><ul><li><a href="Client.html#event:BRANCH_CHANGED">BRANCH_CHANGED</a></li><li><a href="Client.html#event:BRANCH_CLOSED">BRANCH_CLOSED</a></li><li><a href="Client.html#event:BRANCH_OPENED">BRANCH_OPENED</a></li><li><a href="Client.html#event:BRANCH_STATUS_CHANGED">BRANCH_STATUS_CHANGED</a></li><li><a href="Client.html#event:CONNECTED_USERS_CHANGED">CONNECTED_USERS_CHANGED</a></li><li><a href="Client.html#event:NETWORK_STATUS_CHANGED">NETWORK_STATUS_CHANGED</a></li><li><a href="Client.html#event:NOTIFICATION">NOTIFICATION</a></li><li><a href="Client.html#event:PLUGIN_FINISHED">PLUGIN_FINISHED</a></li><li><a href="Client.html#event:PLUGIN_INITIATED">PLUGIN_INITIATED</a></li><li><a href="Client.html#event:PLUGIN_NOTIFICATION">PLUGIN_NOTIFICATION</a></li><li><a href="Client.html#event:PROJECT_CLOSED">PROJECT_CLOSED</a></li><li><a href="Client.html#event:PROJECT_OPENED">PROJECT_OPENED</a></li></ul><h3><a href="global.html">Global</a></h3>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> on Fri Jun 21 2024 09:43:40 GMT-0400 (Eastern Daylight Time)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>