UNPKG

gulp-gcloud-publish

Version:
131 lines (106 loc) 3.54 kB
'use strict'; var gcloudStorage = require('@google-cloud/storage'); var gutil = require('gulp-util'); var mime = require('mime'); var through = require('through2'); var { Readable } = require('stream'); var PLUGIN_NAME = 'gulp-gcloud-publish'; var PluginError = gutil.PluginError; /** * Get the file metadata * * @private * @param {File} file */ function getMetadata(file, metadata) { var meta = { contentType: mime.lookup(file.path) } // Check if it's gziped if (file.contentEncoding && file.contentEncoding.indexOf('gzip') > -1) { meta.contentEncoding = 'gzip'; } if (metadata && metadata.cacheControl) { meta.cacheControl = metadata.cacheControl; } return meta; } /** * Normalize the path to save the file on GCS * * @param base - Base path * @param file - File to save * @return {string} - new relative path for GCS */ function normalizePath(base, file) { var _relative = file.path.replace(file.base, ''); // ensure there is a trailing slash in the base path if (base && !/\/$/.test(base)) { base += '/'; } // ensure the is no starting slash if (base && /^\//.test(base)) { base = base.replace(/^\//, ''); } base = base || ''; var newPath = base + _relative; return newPath.replace(/\\/g, "/"); } /** * Log the file succesfully uploaded */ function logSuccess(gPath) { gutil.log('Uploaded', gutil.colors.cyan(gPath)); } /** * Upload a file stream to Google Cloud Storage * * @param {Object} options * @param {String} options.bucket - Name of the bucket we want to upload the file into * @param {String} options.keyFilename - Full path to the KeyFile JSON * @param {String} options.projectId - Project id * @param {String} [options.base='/'] - Base path for saving the file * @param {Boolean} [options.public] - Set the file as public * @param {Object} [options.metadata] - Set the file metadata */ function gPublish(options) { // A configuration object is required if (!options || !options.bucket) { throw new PluginError(PLUGIN_NAME, 'Missing required configuration: bucket'); } return through.obj(/** @param {import('vinyl')} file*/ function (file, enc, done) { /* istanbul ignore next */ if (file.isNull()) { return done(null, file); } file.path = file.path.replace(/\.gz$/, ''); // Authenticate on Google Cloud Storage var storage = gcloudStorage({ keyFilename: options.keyFilename, projectId: options.projectId }); var bucket = storage.bucket(options.bucket); var gcPath = normalizePath(options.base, file); var metadata = getMetadata(file, options.metadata); var uploadOptions = { destination: options.transformDestination ? options.transformDestination(gcPath) : gcPath, metadata: metadata, gzip: !!options.gzip, public: !!options.public, resumable: !!options.resumable }; //file is Vinyl instance, and since v2 it does not have pipe, see: https://gulpjs.com/docs/en/api/vinyl#instance-methods var fileStream = file.isBuffer() ? Readable.from(file.contents) : file.contents; fileStream.pipe( bucket.file(uploadOptions.destination).createWriteStream(uploadOptions) ) .on('error', function (e) { throw new PluginError(PLUGIN_NAME, "Error in gcloud connection.\nError message:\n" + JSON.stringify(e)); }) .on('finish', function () { logSuccess(uploadOptions.destination); return done(null, file); }); }); } module.exports = gPublish;