@gulpred/s3-adapter
Version:
Upload/download files to/from S3
176 lines (172 loc) • 14.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.src = src;
exports.dest = dest;
// https://evertpot.com/universal-commonjs-esm-typescript-packages/
// no esModuleInterop, so use 'import * ...'
const through2 = require("through2");
const Vinyl = require("vinyl");
const PluginError = require("plugin-error");
const PLUGIN_NAME = "gulp-s3-adapter";
const loglevel_1 = require("loglevel");
const log = loglevel_1.default.getLogger(PLUGIN_NAME); // get a logger instance based on the project name
log.setLevel((process.env.DEBUG_LEVEL || 'warn'));
function getErrOptions() { return { showStack: log.getLevel() >= log.levels.DEBUG }; }
const path = require("path");
// const from2 = require('from2')
const url_1 = require("url");
// import * as fs from 'fs';
const Minio = require("minio");
const client_s3_1 = require("@aws-sdk/client-s3");
const lead = require("lead");
/* This is a gulp plugin. It is compliant with best practices for Gulp plugins (see
https://github.com/gulpjs/gulp/blob/master/docs/writing-a-plugin/guidelines.md#what-does-a-good-plugin-look-like ) */
function src(url, configObj) {
let result;
if (!configObj)
configObj = {};
let minioClient = new Minio.Client(configObj);
try {
let fileName = (0, url_1.parse)(url).pathname || "apiResult.dat";
fileName = path.basename(fileName);
url = url.split(/[\/\\]+/).join("/"); // ensure posix-style separators
// from2 returns a writable stream; we put the vinyl file into the stream. This is the core of gulp: Vinyl files
// inside streams
// result = from2.obj([vinylFile])
// result = from2.obj()
result = through2.obj(); // passthrough stream
//
// Now we set the contents of our vinyl file. For now we're using streams; we'll add buffer support later
// We want to set our content to the stream produced by the request module:
//
// this doesn't work; request doesn't produce a stream when called this way. It doesn't have a .stream() function either...
// vinylFile.contents = request(url) as any
// this works: set contents to a passthrough stream, and pipe the result of the request file through that passthrough stream
// vinylFile.contents = through2.obj() // passthrough stream
// request(url).pipe(vinylFile.contents as unknown as any)
// this works: same idea as above, but a cleaner
// make a copy of configObj specific to this file, adding url and leaving original unchanged
// let optionsCopy = Object.assign({}, configObj, {"url":url})
if (!configObj.buffer) {
// vinylFile.contents = request(optionsCopy).pipe(through2.obj());
// throw new PluginError(PLUGIN_NAME, "Streaming not available")
log.debug("url:", url);
let pathSections = (url || "").split(/[\/\\]+/); // split directory into sections by slashes/backslashes
let bucket = pathSections.shift() || ""; // remove first path section as bucket
// let subfolders = pathSections.join("/"); // reassemble remaining path sections
// minioClient.putObject(bucket, path.posix.join(subfolders, (file.relative.split(/[\/\\]+/).join("/"))), file.contents as Readable, undefined, (err:any, stats:any) => {
// TODO: add glob support
let vinylFile = new Vinyl({
path: url, // for now: url contains a full file name
base: path.posix.dirname(url) // use entire dir structure up to the filename as the "base", meaning it will only use subfolders BELOW that level inside the eventual target folder
});
minioClient.getObject(bucket, pathSections.join("/"))
.then(readable => {
log.debug("got it!");
vinylFile.contents = readable;
result.push(vinylFile);
})
.catch((err) => {
log.error("promise error: ", JSON.stringify(err));
// cb(err)
// throw(err)
// node.error(err, msg);
// result.emit(new PluginError(PLUGIN_NAME, err))
});
}
else {
throw new PluginError(PLUGIN_NAME, "Buffer mode not available");
/*
let minioClient = new Minio.Client(configObj);
// console.log("uploading...")
// TODO: don't ignore subfolders
dbx.filesDownload({ path: url})
// .filesUpload({ path: path.posix.join(directory,file.basename), contents: file.contents as Buffer, mode:mode as any })
.then((response:any) => {
// console.log(response.result);
let vinylFile = new Vinyl({
// base: response.name,
cwd:'/', // just guessing here; not sure if this is the right approach. But it seams to work as intended...
path:response.result.path_lower,
contents:response.result.fileBinary
});
result.push(vinylFile)
// cb(null, file)
// console.log("worked!")
})
.catch ((err) => {
console.error("promise error: ", JSON.stringify(err));
// cb(err)
// throw(err)
// node.error(err, msg);
// result.emit(new PluginError(PLUGIN_NAME, err))
})
*/
}
}
catch (err) {
// emitting here causes some other error: TypeError: Cannot read property 'pipe' of undefined
// result.emit(new PluginError(PLUGIN_NAME, err))
// For now, bubble error up to calling function
throw new PluginError(PLUGIN_NAME, err);
}
return result;
}
// export function dest(this: any, url:string, options: any) {
function dest(directory, configObj) {
if (!configObj)
configObj = {};
// override configObj defaults here, if needed
// if (configObj.header === undefined) configObj.header = true
let client = new client_s3_1.S3Client(configObj);
// creating a stream through which each file will pass - a new instance will be created and invoked for each file
// see https://stackoverflow.com/a/52432089/5578474 for a note on the "this" param
const strm = through2.obj(function (file, encoding, cb) {
const self = this;
let returnErr = null;
if (file.isNull()) {
// return empty file
return cb(returnErr, file);
}
else if (file.isBuffer()) {
// returnErr = new PluginError(PLUGIN_NAME, "Buffer mode not available");
// return cb(returnErr, file)
try {
let pathSections = (directory || "").split(/[\/\\]+/); // split directory into sections by slashes/backslashes
let bucket = pathSections.shift() || ""; // remove first path section as bucket
let subfolders = pathSections.join("/"); // reassemble remaining path sections
let testo = {
"Body": file.contents,
"Bucket": bucket,
"Key": path.posix.join(subfolders, (file.relative.split(/[\/\\]+/).join("/")))
};
const command = new client_s3_1.PutObjectCommand(testo);
client.send(command)
.then((data) => {
// process data.
log.debug('Success');
return cb(returnErr, file);
})
.catch((err) => {
returnErr = err;
if (err) {
log.error(err); // err should be null
return cb(err, file);
}
});
}
catch (err) {
log.error("caught err", err);
return cb(err);
}
}
else if (file.isStream()) {
returnErr = new PluginError(PLUGIN_NAME, "Streaming not available");
// result.emit(returnErr)
return cb(returnErr, file);
}
});
// Sink the output stream to start flowing
return lead(strm);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3BsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXdCQSxrQkFpSEM7QUFHRCxvQkFrRUM7QUE5TUQsbUVBQW1FO0FBQ25FLDRDQUE0QztBQUM1QyxxQ0FBb0M7QUFDcEMsK0JBQThCO0FBQzlCLDRDQUEyQztBQUUzQyxNQUFNLFdBQVcsR0FBRyxpQkFBaUIsQ0FBQztBQUN0Qyx1Q0FBK0I7QUFDL0IsTUFBTSxHQUFHLEdBQUcsa0JBQVEsQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUEsQ0FBQyxrREFBa0Q7QUFDOUYsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxJQUFJLE1BQU0sQ0FBMEIsQ0FBQyxDQUFBO0FBQzFFLFNBQVMsYUFBYSxLQUFLLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxDQUFDLFFBQVEsRUFBRSxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUEsQ0FBQyxDQUFDO0FBRXJGLDZCQUE0QjtBQUM1QixpQ0FBaUM7QUFDakMsNkJBQXVDO0FBQ3ZDLDRCQUE0QjtBQUU1QiwrQkFBK0I7QUFDL0Isa0RBQWtHO0FBQ2xHLDZCQUE0QjtBQUU1QjtxSEFDcUg7QUFFckgsU0FBZ0IsR0FBRyxDQUFZLEdBQVcsRUFBRSxTQUFjO0lBQ3hELElBQUksTUFBVyxDQUFDO0lBQ2hCLElBQUksQ0FBQyxTQUFTO1FBQUUsU0FBUyxHQUFHLEVBQUUsQ0FBQTtJQUU5QixJQUFJLFdBQVcsR0FBRyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFOUMsSUFBSSxDQUFDO1FBQ0gsSUFBSSxRQUFRLEdBQVcsSUFBQSxXQUFRLEVBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxJQUFJLGVBQWUsQ0FBQTtRQUNoRSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENB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