UNPKG

webgme-engine

Version:

WebGME server and Client API without a GUI

343 lines (288 loc) 15.4 kB
<!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} &lt;b>metadataHash&lt;/b>.&lt;br> * On error the promise will be rejected with {@link Error} &lt;b>error&lt;/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} &lt;b>metadataHash&lt;/b>.&lt;br> * On error the promise will be rejected with {@link Error} &lt;b>error&lt;/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} &lt;b>hash&lt;/b>.&lt;br> * On error the promise will be rejected with {@link Error} &lt;b>error&lt;/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} &lt;b>hash&lt;/b>.&lt;br> * On error the promise will be rejected with {@link Error} &lt;b>error&lt;/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.&lt;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[]} &lt;b>metadataHashes&lt;/b>.&lt;br> * On error the promise will be rejected with {@link Error|string} &lt;b>error&lt;/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.&lt;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[]} &lt;b>metadataHashes&lt;/b>.&lt;br> * On error the promise will be rejected with {@link Error} &lt;b>error&lt;/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.&lt;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[]} &lt;b>hashes&lt;/b>.&lt;br> * On error the promise will be rejected with {@link Error} &lt;b>error&lt;/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.&lt;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[]} &lt;b>hashes&lt;/b>.&lt;br> * On error the promise will be rejected with {@link Error} &lt;b>error&lt;/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} &lt;b>metadataHash&lt;/b>.&lt;br> * On error the promise will be rejected with {@link Error} &lt;b>error&lt;/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>