vvc
Version:
Vivocha Command Line Tools
149 lines • 4.93 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const crypto = require("crypto");
const fs = require("fs");
const _mkdirp = require("mkdirp");
const path = require("path");
const util_1 = require("util");
const config_1 = require("./config");
const walkdir_1 = require("./walkdir");
const ws_1 = require("./ws");
const stat = util_1.promisify(fs.stat);
const access = util_1.promisify(fs.access);
const mkdirp = util_1.promisify(_mkdirp);
async function scanWidgetAssets(basepath) {
const assets = [];
const resolvedPath = path.resolve(basepath);
async function checkAsset(filename) {
let rok = true, info;
try {
await access(filename, fs.constants.R_OK);
info = await stat(filename);
}
catch (err) {
rok = false;
}
let base_filename = filename.replace(resolvedPath + '/', '');
if (rok && info.isFile()) {
return {
path: base_filename
};
}
else {
throw new Error(base_filename);
}
}
const html = checkAsset(`${resolvedPath}/main.html`);
const scss = checkAsset(`${resolvedPath}/main.scss`);
const thumb = checkAsset(`${resolvedPath}/thumbnail.png`);
assets.push(html);
assets.push(scss);
try {
await thumb;
assets.push(thumb);
}
catch (e) { }
const assetsPath = `${basepath}/assets`;
try {
assets.push(...(await walkdir_1.default(assetsPath)).map(f => f.replace(/^\.\//, '')).map(f => checkAsset(f)));
}
catch (e) { }
return Promise.all(assets);
}
exports.scanWidgetAssets = scanWidgetAssets;
function hashWidgetAssets(assets) {
const hashedAssets = [];
assets.forEach(({ path: filename }) => {
hashedAssets.push(new Promise((resolve, reject) => {
let hash = crypto.createHash('sha256');
let stream = fs.createReadStream(filename);
stream.on('error', err => reject(err));
stream.on('data', chunk => hash.update(chunk));
stream.on('end', () => resolve({
path: filename,
hash: hash.digest('hex')
}));
}));
});
return Promise.all(hashedAssets);
}
exports.hashWidgetAssets = hashWidgetAssets;
async function uploadWidgetAssetChanges(widgetId, oldAssets, newAssets, global) {
async function upload(asset) {
try {
let data = await ws_1.ws(`widgets/${widgetId}/upload${global ? '?global=true' : ''}`, {
method: 'POST',
qs: {
id: `${asset.path}/${asset.hash.substr(0, 7)}`
},
formData: {
file: fs.createReadStream(asset.path)
}
});
asset.id = data.id;
asset.type = data.type;
asset.size = data.size;
return asset;
}
catch (err) {
if (err.originalError) {
console.error('upload error', err.originalError);
}
else if (err.response) {
console.error('upload failed', err.response.statusCode);
}
else {
console.error(err);
}
throw err;
}
}
function reduce(o, i) {
o[i.path] = i;
return o;
}
const oldMap = oldAssets.reduce(reduce, {});
const newMap = newAssets.reduce(reduce, {});
for (let k in newMap) {
const o = oldMap[k], n = newMap[k];
if (!o || !o.id || o.hash !== n.hash) {
console.log(`${k} changed, uploading`);
await upload(n);
}
else {
n.id = o.id;
if (o.size)
n.size = o.size;
if (o.type)
n.type = o.type;
}
}
}
exports.uploadWidgetAssetChanges = uploadWidgetAssetChanges;
async function downloadAsset(url, filename) {
const pathInfo = path.parse(filename);
if (pathInfo.dir) {
await access(pathInfo.dir).then(async () => {
const statInfo = await stat(pathInfo.dir).catch(() => {
throw `Cannot access destination path \'${pathInfo.dir}\'`;
});
if (!statInfo.isDirectory()) {
throw `Destination path ${pathInfo.dir} exists and it\'s not a directory`;
}
}, async () => {
await mkdirp(pathInfo.dir).catch(() => {
throw `Cannot create path ${pathInfo.dir}`;
});
});
}
console.log(`Downloading ${filename}`);
await ws_1.download(url, filename);
}
async function downloadAssets(assets) {
const config = await config_1.read();
for (let a of assets) {
await downloadAsset(`${config.info.assets}${a.id}`, a.path);
}
}
exports.downloadAssets = downloadAssets;
//# sourceMappingURL=assets.js.map