### Start the Electron Example Source: https://github.com/ttlabs/evaporatejs/wiki/Support-for-Node.js-FileSystem-(fs)-and-ReadableStreams Starts the Electron example application. ```shell npm start ``` -------------------------------- ### Install Electron and Evaporate Source: https://github.com/ttlabs/evaporatejs/wiki/Support-for-Node.js-FileSystem-(fs)-and-ReadableStreams Installs the development dependencies for the Electron example. ```shell cd examples/electron npm install ``` -------------------------------- ### Evaporate Instance Configuration Source: https://github.com/ttlabs/evaporatejs/wiki/Quick-Start-Guide JavaScript example for creating an Evaporate instance with necessary configurations for browser uploads, including crypto polyfills. ```javascript import Evaporate from 'evaporate'; import sparkMD5 from 'spark-md5'; import sha256 from 'js-sha256'; const uploader = Evaporate.create({ signerUrl: '/auth/signv4_upload', aws_key: 'AWS_PUBLIC_KEY', bucket: 'your-bucket-name', cloudfront: true, computeContentMd5: true, cryptoMd5Method: (d) => btoa(sparkMD5.ArrayBuffer.hash(d, true)), cryptoHexEncodedHash256: sha256, }); ``` -------------------------------- ### Ruby Signing Service Example Source: https://github.com/ttlabs/evaporatejs/wiki/Quick-Start-Guide A Ruby example of a signing service that generates an AWS v4 signature for upload policies. ```ruby def signv4_upload date_stamp = Date.strptime(params[:datetime], "%Y%m%dT%H%M%SZ").strftime("%Y%m%d") secret_key = "AWS_SECRET_KEY" aws_region = "AWS_REGION" date_key = OpenSSL::HMAC.digest("sha256", "AWS4" + secret_key, date_stamp) region_key = OpenSSL::HMAC.digest("sha256", date_key, aws_region) service_key = OpenSSL::HMAC.digest("sha256", region_key, "s3") signing_key = OpenSSL::HMAC.digest("sha256", service_key, "aws4_request") render plain: OpenSSL::HMAC.hexdigest("sha256", signing_key, params[:to_sign]).gsub("\n", "") end ``` -------------------------------- ### EvaporateJS Initialization and Usage Example Source: https://github.com/ttlabs/evaporatejs/blob/master/example/evaporate_example.html This snippet shows how to initialize EvaporateJS, set up a signing function, and use it to sign a string. ```javascript var evaporate = new Evaporate({ signing: function(toSign) { return new Promise(function(resolve) { // Replace with your actual signing logic // For example, using a server-side signing function or a client-side key var signingKey = 'your-secret-signing-key'; // In a real app, get this securely var signed = evaporate.sign(toSign, signingKey, 'hex'); resolve(signed); }); } }); evaporate.sign('some string to sign', 'your-secret-signing-key', 'hex').then(function(signed) { console.log('Signed string:', signed); }); evaporate.sign('another string', 'your-secret-signing-key', 'hex').then(function(signed) { console.log('Signed string:', signed); }); // Example of using the signing function during initialization var evaporateWithSigning = new Evaporate({ signing: function(toSign) { return new Promise(function(resolve) { // Replace with your actual signing logic var signingKey = 'your-secret-signing-key'; // In a real app, get this securely var signed = evaporate.sign(toSign, signingKey, 'hex'); resolve(signed); }); } }); evaporateWithSigning.sign('string for evaporateWithSigning').then(function(signed) { console.log('Signed string (with init signing):', signed); }); // Example of a custom signing function that returns a promise var evaporatePromiseSigning = new Evaporate({ signing: function(toSign) { return new Promise(function(resolve, reject) { // Simulate an async signing operation setTimeout(function() { try { var signingKey = 'your-secret-signing-key'; // In a real app, get this securely var signed = evaporate.sign(toSign, signingKey, 'hex'); resolve(signed); } catch (e) { reject(e); } }, 50); }); } }); evaporatePromiseSigning.sign('string for promise signing').then(function(signed) { console.log('Signed string (with promise signing):', signed); }).catch(function(err) { console.error('Signing failed:', err); }); // Example of a signing function that doesn't return a promise (synchronous) var evaporateSyncSigning = new Evaporate({ signing: function(toSign) { // Replace with your actual signing logic var signingKey = 'your-secret-signing-key'; // In a real app, get this securely return evaporate.sign(toSign, signingKey, 'hex'); } }); evaporateSyncSigning.sign('string for sync signing').then(function(signed) { console.log('Signed string (with sync signing):', signed); }); // Example of signing a string using the RIComponent function (if available/defined elsewhere) // This part seems to be a fragment and might require context from a larger file. // Assuming RIComponent is a function that returns a signing key or similar. // var signingKey = RIComponent(stringToSign); // evaporate.sign(stringToSign, signingKey, 'hex'); // The provided fragment 'RIComponent(stringToSign), 'hex'); resolve(signingKey); }); }' appears to be a partial piece of a Promise-based signing function. // Reconstructing a plausible snippet based on the fragment: new Promise(function(resolve) { var signingKey = RIComponent(stringToSign); resolve(signingKey); }); ``` -------------------------------- ### EvaporateJS Progress Clock and UI Initialization Source: https://github.com/ttlabs/evaporatejs/blob/master/example/evaporate_example.html This snippet initializes the progress clock UI elements and defines functions to update the UI based on the upload status (progress, started, error, cancelled, pausing, paused, resumed, warn, nameChanged, complete). It also handles the initial setup of the EvaporateJS instance. ```javascript sume); var status = $(\'\'); progress_clock.append(status); var speed = $(\'786 Kbs\'); progress_clock.append(speed); clock = new ProgressBar.Circle(progress_clock.find('.circle')[0], { strokeWidth: 3, trailWidth: 1, duration: 350, text: { value: \'\' }, step: function(state, bar) { bar.setText((bar.value() * 100).toFixed(0) + \'%\'); } }); progress_clock.find('svg path').removeAttr('stroke'); progress_clock.find('.progressbar-text').css('color', \'\'); function markComplete(className) { progress_clock.addClass(className); status.text(className); } return { progress: function (progressValue, data) { progress = progressValue; console.log( 'Total Loaded:', data && data.loaded ? data.loaded : \'', 'Speed:', data && data.speed ? data.speed : \'', 'Formatted speed:', data && data.speed ? data.readableSpeed + \'s\' : \'', 'Minutes left:', data && data.secondsLeft ? Math.round(data.secondsLeft / 60) : \'\' ) clock.animate(progressValue); if(data) { var xferRate = data.speed ? \'
\' + data.readableSpeed + \ ``` -------------------------------- ### cryptoMd5Method examples Source: https://github.com/ttlabs/evaporatejs/wiki/Evaporate.create() Examples of cryptoMd5Method implementations for different environments. ```javascript function (data) { return btoa(SparkMD5.ArrayBuffer.hash(data, true)); } ``` ```javascript function (data) { return crypto.createHash('md5').update(Buffer.from(data)).digest('base64'); } ``` ```javascript function (data) { return AWS.util.crypto.md5(data, 'base64'); } ``` -------------------------------- ### EvaporateJS Configuration Source: https://github.com/ttlabs/evaporatejs/wiki/Examples Configuration for the EvaporateJS example application, setting up the signer URL, AWS key, and S3 bucket. ```javascript var promise = Evaporate.create({ signerUrl: '/sign_auth', // Do not change this in the example app aws_key: 'your aws_key here', bucket: 'your s3 bucket name here', }); ``` -------------------------------- ### readableStreamPartMethod example Source: https://github.com/ttlabs/evaporatejs/wiki/Evaporate.create() Example of a readableStreamPartMethod for Node.js environments. ```javascript function (file, start, end) { // Node returns a Stream of Uint8Array return fs.createReadStream(file.path, {start: start, end: end}); } ``` -------------------------------- ### signHeaders Example Source: https://github.com/ttlabs/evaporatejs/wiki/Evaporate.create() An example demonstrating how to configure signHeaders, which are key/value pairs passed as headers to all calls to signerUrl. Values can be functions. ```javascript signHeaders: { xVip: 1, x-user-name: function () { return user.name; } } ``` -------------------------------- ### signParams Example Source: https://github.com/ttlabs/evaporatejs/wiki/Evaporate.create() An example demonstrating how to configure signParams, which are key/value pairs passed to all calls to signerUrl. Values can be functions. ```javascript signParams: { vip: true, username: function () { return user.name; } } ``` -------------------------------- ### Install EvaporateJS Source: https://github.com/ttlabs/evaporatejs/blob/master/README.md Install the EvaporateJS library using npm. ```bash $ npm install evaporate ``` -------------------------------- ### Example usage of resume() Source: https://github.com/ttlabs/evaporatejs/wiki/Evaporate.prototype.resume() Demonstrates creating an Evaporate instance, adding a file, pausing it, and then resuming it. ```javascript Evaporate.create({ bucket: 'mybucket' }) .then(function (evaporate) { evaporate.add({ name: 'myFile', file: new File() }) .then(function (awsKey) { console.log('Completed', awsKey); }); evaporate.pause('mybucket/myFile', {force: true}) // or 'evaporate.pause()' to pause all .then(function () { console.log('Paused!'); }) .catch(function (reason) { console.log('Failed to pause:', reason); }; evaporate.resume('mybucket/myFile') .then(function () { console.log('Resumed!'); }) .catch(function (reason) { console.log('Failed to resume:', reason); }; }) ``` -------------------------------- ### Basic EvaporateJS Configuration and Upload Source: https://github.com/ttlabs/evaporatejs/blob/master/README.md A simple example demonstrating how to configure EvaporateJS and upload a file, including progress and completion callbacks. ```javascript const Evaporate = require('EvaporateJS'); const Crypto = require('crypto'); const config = { signerUrl: SIGNER_URL, aws_key: AWS_KEY, bucket: AWS_BUCKET, cloudfront: true, computeContentMd5: true, cryptoMd5Method: data => Crypto .createHash('md5') .update(data) .digest('base64'); }; const uploadFile = evaporate => { const file = new File([""], "file_object_to_upload"); const addConfig = { name: file.name, file: file, progress: progressValue => console.log('Progress', progressValue), complete: (_xhr, awsKey) => console.log('Complete!'), } /* The bucket and some other properties can be changed per upload */ const overrides = { bucket: AWS_BUCKET_2 }; evaporate.add(addConfig, overrides) .then( awsObjectKey => console.log('File successfully uploaded to:', awsObjectKey), reason => console.log('File did not upload sucessfully:', reason); ) } return Evaporate.create(config).then(uploadFile); ``` -------------------------------- ### Upload File Function Source: https://github.com/ttlabs/evaporatejs/wiki/Quick-Start-Guide This code snippet demonstrates how to upload a file using the Evaporate.add method, including various callback handlers for different upload states. ```javascript function uploadFile(file) { uploader.then((evaporate) => { evaporate.add({ file: file, name: file.name, progress: (percent, stats) => console.log('Progress', percent, stats), complete: (xhr, awsObjectKey) => console.log('Complete!', awsObjectKey), error: (mssg) => console.log('Error', mssg), paused: () => console.log('Paused'), pausing: () => console.log('Pausing'), resumed: () => console.log('Resumed'), cancelled: () => console.log('Cancelled'), started: (fileKey) => console.log('Started', fileKey), uploadInitiated: (s3Id) => console.log('Upload Initiated', s3Id), warn: (mssg) => console.log('Warning', mssg) }).then( (awsObjectKey) => console.log('File successfully uploaded to:', awsObjectKey), (reason) => console.log('File did not upload sucessfully:', reason) ); }); } // Respond to files selected using a file input field: document.querySelector('#file-field').addEventListener('change', (evt) => { Array.from(evt.target.files).forEach(uploadFile); evt.target.value = ''; }); ``` -------------------------------- ### Custom authentication method example Source: https://github.com/ttlabs/evaporatejs/wiki/Evaporate.create() An example of a custom authentication method that returns a Promise for signature calculation. ```javascript function (signParams, signHeaders, stringToSign, signatureDateTime, canonicalRequest) { // pluggable signing return new Promise(function (resolve, reject) { resolve('computed signature'); }) } ``` -------------------------------- ### EvaporateJS Initialization and File Upload Logic Source: https://github.com/ttlabs/evaporatejs/blob/master/example/evaporate_example.html This snippet shows how to initialize EvaporateJS with various configuration options and handle file selection, upload progress, completion, and errors. ```javascript var files, file_id = 0, file_ids = []; var filePromises = [], allCompleted COOKIE = 'evaporate_example', cookie_data = { persist: "off" }, cookie_options = { expires: 1 }; // Change these to reflect your local settings var persist = $("input[name=persist]").val(); if (persist) { try { cookie_data = JSON.parse(Cookies.get(COOKIE) || '{ "persist": "off" }'); $("input[type=radio][name=persist][value=" + cookie_data.persist + "]").attr("checked", true); updateSignerUi(cookie_data.useUnsafeJavaScript); $("#awsKey").val(decodeURIComponent(cookie_data.awsKey || '')); $("#awsRegion").val(decodeURIComponent(cookie_data.awsRegion || '')); $("#s3Bucket").val(decodeURIComponent(cookie_data.s3Bucket || '')); $("#signerUrl").val(decodeURIComponent(cookie_data.signerUrl || '')); } catch (e) { console.log(e); } } var customAuth = $("#signingMethod")[0].checked; Evaporate.create({ signerUrl: customAuth ? undefined : $("#signerUrl").val(), aws_key: $("#awsKey").val(), awsRegion: ($("#awsRegion").val() || '').trim() || "us-east-1", bucket: $("#s3Bucket").val(), cloudfront: true, computeContentMd5: true, cryptoMd5Method: function (data) { return AWS.util.crypto.md5(data, 'base64'); }, cryptoHexEncodedHash256: function (data) { return AWS.util.crypto.sha256(data, 'hex'); }, logging: false, s3FileCacheHoursAgo: 1, allowS3ExistenceOptimization: true, customAuthMethod: customAuth? doNotUseUnsafeJavaScriptV4Signer : undefined, evaporateChanged: function (file, evaporatingCount) { $('#totalParts').text(evaporatingCount); if (evaporatingCount > 0) { $("#pause-all, #pause-all-force, #cancel-all").show(); } else if (evaporatingCount === 0) { $("#pause-all, #pause-all-force, #resume, #cancel-all").hide(); } } }) .then(function (_e_) { $('#files').change(function (evt) { files = evt.target.files; for (var i = 0; i < files.length; i++) { var name = files[i].name + Math.random() * 100; var fileKey = $("#s3Bucket").val() + '/' + name; callback_methods = callbacks(files[i], fileKey, i); var promise = _e_.add({ name: name, file: files[i], started: callback_methods.started, complete: callback_methods.complete, cancelled: callback_methods.cancelled, progress: callback_methods.progress, error: callback_methods.error, warn: callback_methods.warn, paused: callback_methods.paused, pausing: callback_methods.pausing, resumed: callback_methods.resumed, nameChanged: callback_methods.nameChanged }, { bucket: $("#s3Bucket").val(), // Shows that the bucket can be changed per aws_key: $("#awsKey").val() // Shows that aws_key can be changed per } ) .then((function (requestedName) { return function (awsKey) { if (awsKey === requestedName) { console.log(awsKey, 'successfully uploaded!'); } else { console.log('Did not re-upload', requestedName, 'because it exists as', awsKey); } } })(name) ); filePromises.push(promise); callback_methods.progress_clock.attr('file_id', file_id); ["#pause-all", "#pause-all-force", "#cancel-all"].forEach(function (v) { $(v).show(); }); } allCompleted = Promise.all(filePromises) .then(function () { console.log('All files were uploaded successfully.'); }, function (reason) { console.log('All files were not uploaded successfully:', reason); }) $(evt.target).val(''); }); $("#pause-all").hide().click(function () { _e_.pause(); }); $("#cancel-all").hide().click(function () { _e_.cancel(); }); $("#pause-all-force").hide().click(function () { _e_.pause(undefined, {force: true}); }); $("#resume").hide().click(function () { _e_.resume(); $("#resume").hide(); }); function callbacks(file, fileKey, idx) { var progress_clock = $("
"), clock, progress, file_id; $('#progress-container') .append(progress_clock); progress_clock .append('' + file.name + '') .append('
'); var cancel = $("") .click(function () { console.log('canceling', fileKey); _e_.cancel(fileKey); }); progress_clock.append(cancel); var pause = $("") .click(function () { console.log('pausing', fileKey); _e_.pause(fileKey); }); progress_clock.append(pause); var forcePause = $("") .click(function () { console.log('force pausing', fileKey); _e_.pause(fileKey, {force: true}); }); progress_clock.append(forcePause); var resume = $("").hide() .hide() .click(function () { console.log('resuming', fileKey); _e_.resume(fileKey); }); progress_clock.append(re ``` -------------------------------- ### cryptoHexEncodedHash256 examples Source: https://github.com/ttlabs/evaporatejs/wiki/Evaporate.create() Examples of cryptoHexEncodedHash256 implementations for different environments. ```javascript function (data) { return crypto.createHash('sha256').update(Buffer.from(data)).digest('hex'); } ``` ```javascript function (data) { return AWS.util.crypto.sha256(data, 'hex'); } ``` -------------------------------- ### Install v3 for testing Source: https://github.com/ttlabs/evaporatejs/blob/master/README.md Install the latest v3 version of EvaporateJS from a specific pull request for testing purposes. ```bash npm install evaporate@TTLabs/EvaporateJS#pull/448/head ``` -------------------------------- ### AWS Lambda Authentication Function Source: https://github.com/ttlabs/evaporatejs/blob/master/example/evaporate_example_lambda.html This JavaScript function demonstrates how to authenticate with EvaporateJS using AWS Lambda. It takes signing parameters, headers, and the string to sign, then invokes an AWS Lambda function to get the signature. ```javascript var files; function authByAwsLambda (signParams, signHeaders, stringToSign, dateString) { return new Promise(function(resolve, reject) { var awsLambda = new AWS.Lambda({ region: 'lambda region', accessKeyId: 'a key that can invoke the lambda function', secretAccessKey: 'the secret' }) awsLambda.invoke({ FunctionName: 'arn:aws:lambda:...:function:cw-signer', // arn of your lambda function InvocationType: 'RequestResponse', Payload: JSON.stringify({ to_sign: stringToSign, sign_params: signParams, sign_headers: signHeaders }) }, function (err, data) { if (err) { return reject(err); } resolve(JSON.parse(data.Payload)); }); }); }; ``` -------------------------------- ### Sign response handler example Source: https://github.com/ttlabs/evaporatejs/wiki/Evaporate.create() An example of a sign response handler that returns a Promise resolving with the computed signature. ```javascript function (response, stringToSign, signatureDateTime) { return new Promise(function (resolve, reject) { resolve('computed signature'); } } ``` -------------------------------- ### Basic Usage Source: https://github.com/ttlabs/evaporatejs/wiki/Evaporate.prototype.add() Example of adding a file to the upload queue with basic configuration. ```javascript Evaporate.create({ bucket: 'mybucket' }) .then(function (evaporate) { evaporate.add({ name: 'myFile', file: new File() }) .then( function (awsS3ObjectKey) { // "Sucessfully uploaded to: mybucket/myfile" console.log('Successfully uploaded to:', awsS3ObjectKey); }, function (reason) { console.log('Failed to upload because:', reason); } ); }); ``` -------------------------------- ### Electron Renderer Process Example Source: https://github.com/ttlabs/evaporatejs/blob/master/example/electron/index.html This code snippet demonstrates how to use EvaporateJS in the renderer process of an Electron application, including file uploads, progress tracking, and error handling. ```javascript Hello World! Hello World! ============ We are using Node.js document.write(process.versions.node), Chromium document.write(process.versions.chrome), and Electron document.write(process.versions.electron). // You can also require other files to run in this process require('./renderer.js') const crypto = require('crypto') const fs = require('fs') const Evaporate = require('evaporate') var AWS_KEY = '', AWS_BUCKET = '', SIGNER_URL = ''; function expose(f) { var files = document.getElementById("files").files, keys = []; Evaporate.create({ signerUrl: SIGNER_URL, aws_key: AWS_KEY, bucket: AWS_BUCKET, readableStreams: true, readableStreamPartMethod: function (file, start, end) { return fs.createReadStream('~/Desktop/' + file.name, {start: start, end: end}); }, cloudfront: true, awsSignatureVersion: "4", computeContentMd5: true, cryptoMd5Method: function (data) { return crypto.createHash('md5').update(data).digest('base64'); }, cryptoHexEncodedHash256: function (data) { return crypto.createHash('sha256').update(data).digest('hex'); }, logging: false, s3FileCacheHoursAgo: 1 }) .then(function (evaporate) { for (var i = 0; i < files.length; i++) { var name = files[i].name + Math.random() * 100; var fileKey = AWS_BUCKET + '/' + name; keys.push(fileKey); var promise = evaporate.add({ name: name, file: files[i], started: function (f) { console.log('started', f); }, progress: function (p, d) { console.log('progress', p); }, error: function (m) { console.log('error:', m); } }) .then((function (requestedName) { return function (awsKey) { if (awsKey === requestedName) { console.log(awsKey, 'successfully uploaded!'); } else { console.log('Did not re-upload', requestedName, 'because it exists as', awsKey); } } })(name)); } }); } ``` -------------------------------- ### Install specific version for 1.x users Source: https://github.com/ttlabs/evaporatejs/blob/master/CHANGELOG.md Instructions on how to install a specific tagged branch for users on the 1.x version of EvaporateJS. ```shell npm install git://github.com/TTLabs/EvaporateJS.git#1.6.4 ``` -------------------------------- ### Evaporate.create() Configuration Source: https://github.com/ttlabs/evaporatejs/blob/master/example/evaporate_example_awsv4_signature.html Configuration object for creating a new Evaporate instance, including AWS V4 signature settings and S3 bucket details. ```javascript Evaporate.create({ aws_key: '', // REQUIRED -- set this to your AWS_ACCESS_KEY_ID bucket: '', // REQUIRED -- set this to your s3 bucket name awsRegion: 'us-east-1', // OPTIONAL -- change this if your bucket is outside us-east-1 signerUrl: 'http://localhost:3000/signv4_auth', awsSignatureVersion: '4', computeContentMd5: true, cryptoMd5Method: function (data) { return AWS.util.crypto.md5(data, 'base64'); }, cryptoHexEncodedHash256: function (data) { return AWS.util.crypto.sha256(data, 'hex'); } }) ``` -------------------------------- ### S3 Bucket CORS Configuration Example Source: https://github.com/ttlabs/evaporatejs/wiki/Configuring-The-AWS-S3-Bucket An example of CORS configuration for an S3 bucket, crucial for allowing EvaporateJS to upload files. It highlights the importance of the PUT method and the ETag header. ```xml https://*.yourdomain.com http://*.yourdomain.com PUT POST DELETE GET ETag * ``` -------------------------------- ### EvaporateJS Initialization and File Upload Source: https://github.com/ttlabs/evaporatejs/blob/master/example/evaporate_example_lambda.html This code snippet shows how to initialize EvaporateJS with the custom AWS Lambda authentication method and handle file uploads. It includes event listeners for file changes and progress tracking. ```javascript Evaporate.create({ aws_key: 'your aws_key here', bucket: 'your s3 bucket name here', customAuthMethod: authByAwsLambda }) .then(function (_e_) { $('#files').change(function (evt) { files = evt.target.files; for (var i = 0; i < files.length; i++) { var promise = _e_.add({ name: 'test_' + Math.floor(1000000000 * Math.random()), file: files[i], notSignedHeadersAtInitiate: { 'Cache-Control': 'max-age=3600' }, xAmzHeadersAtInitiate: { 'x-amz-acl': 'public-read' }, signParams: { foo: 'bar', fooFunction: function () { return 'bar'; } }, signHeaders: { fooHeaderFunction: function () { return 'bar' }, fooHeader: 'bar' }, beforeSigner: function (xhr) { var requestDate = (new Date()).toISOString(); xhr.setRequestHeader('Request-Header', requestDate); }, complete: function () { console.log('complete................yay!'); }, progress: function (progress) { console.log('making progress: ' + progress); } }) .then(function (awsKey) { console.log(awsKey, 'complete!'); }); filePromises.push(promise); } }); allCompleted = Promise.all(filePromises) .then(function () { console.log('All files were uploaded successfully.'); }, function (reason) { console.log('All files were not uploaded successfully:', reason); }); $(evt.target).val(''); }, function (reason) { console.log('Evaporate failed to initialize: ', reason) }); ``` -------------------------------- ### Stats Object Source: https://github.com/ttlabs/evaporatejs/wiki/Evaporate.prototype.add() An example of the _stats_ object which contains upload statistics. ```javascript { speed: 70343222.003493043, // avgSpeedBytesPerSecond, readableSpeed: "703 Kb", loaded: 7034333, // Bytes loaded since the last call. it's for part upload. totalUploaded: 10024457, // Total bytes uploaded remainingSize: 20000000, secondsLeft: 10, //when -1, it's unknown. fileSize: 30024457 } ``` -------------------------------- ### File Upload Handling Source: https://github.com/ttlabs/evaporatejs/blob/master/example/evaporate_example_awsv4_signature.html Handles new file additions to the file input, adds them to Evaporate for upload, and logs progress and completion status. ```javascript var fileInput = document.getElementById('files'), filePromises = []; // Start a new evaporate upload anytime new files are added in the file input fileInput.onchange = function(evt) { var files = evt.target.files; for (var i = 0; i < files.length; i++) { var promise = _e_.add({ name: 'test_' + Math.floor(1000000000*Math.random()), file: files[i], progress: function (progress) { console.log('making progress: ' + progress); } }) .then(function (awsKey) { console.log(awsKey, 'complete!'); }); filePromises.push(promise); } // Wait until all promises are complete Promise.all(filePromises) .then(function () { console.log('All files were uploaded successfully.'); }, function (reason) { console.log('All files were not uploaded successfully:', reason); }); // Clear out the file picker input evt.target.value = ''; }; ``` -------------------------------- ### S3 Bucket Policy with GetObject for Existence Check Source: https://github.com/ttlabs/evaporatejs/wiki/Configuring-The-AWS-S3-Bucket An extended S3 bucket policy example that includes the 's3:GetObject' action, required when the 'allowS3ExistenceOptimization' configuration option is enabled in EvaporateJS. This allows checking for object existence on S3. ```json { "Version": "2012-10-17", "Id": "Policy145337ddwd", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::6681765859115:user/me" }, "Action": [ "s3:AbortMultipartUpload", "s3:ListMultipartUploadParts", "s3:GetObject", "s3:PutObject" ], "Resource": "arn:aws:s3:::mybucket/*" } ] } ``` -------------------------------- ### S3 Bucket Policy for Multi-part Uploads Source: https://github.com/ttlabs/evaporatejs/wiki/Configuring-The-AWS-S3-Bucket A JSON example of an AWS S3 bucket policy that grants necessary permissions for creating, resuming, and aborting multi-part uploads. Replace placeholder ARNs and bucket names with actual values. ```json { "Version": "2012-10-17", "Id": "Policy145337ddwd", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::6681765859115:user/me" }, "Action": [ "s3:AbortMultipartUpload", "s3:ListMultipartUploadParts", "s3:PutObject" ], "Resource": "arn:aws:s3:::mybucket/*" } ] } ``` -------------------------------- ### S3 CORS Configuration Source: https://github.com/ttlabs/evaporatejs/wiki/Quick-Start-Guide XML configuration for an S3 bucket to allow Evaporate uploads, including essential methods and headers. ```xml https://*.yourdomain.com PUT POST DELETE GET ETag * ``` -------------------------------- ### Evaporate.create() usage with Promises Source: https://github.com/ttlabs/evaporatejs/wiki/Evaporate.create() Demonstrates how to use Evaporate.create() with Promises to add a file and handle success or failure. ```javascript Evaporate.create(config) .then( function (evaporate) { evaporate.add(add_config) .then( function (awsKey) { console.log('Successfully uploaded:', awsKey); }, function (reason) { console.log('Failed to upload:', reason); } ) }, function (reason) { console.log('Evaporate failed to initialize:', reason); }); ``` -------------------------------- ### Cancel a specific file upload Source: https://github.com/ttlabs/evaporatejs/wiki/Evaporate.prototype.cancel() Example of canceling a specific file upload using its file key. ```javascript Evaporate.create({ bucket: 'mybucket' }) .then(function (evaporate) { evaporate.add({ name: 'myFile', file: new File() }) .then(function (awsKey) { console.log('Completed', awsKey); }, function (reason) { console.log('Did not upload', reason); }); evaporate.cancel('mybucket/myFile') .then(function () { console.log('Canceled!'); }); }) ```