cby-vtex-cms-sauce
Version:
Tool for handling VTEX CMS requests.
283 lines (243 loc) • 7.89 kB
JavaScript
import '@babel/register'
import '@babel/polyfill'
import rl from 'readline'
import { createReadStream } from 'fs'
import { createHash } from 'crypto'
import FormData from 'form-data'
import cheerio from 'cheerio'
import apisauce from "apisauce";
const ask = question => {
const r = rl.createInterface({
input: process.stdin,
output: process.stdout
});
return new Promise((resolve, reject) => {
r.question(question + "\n", function(answer) {
r.close();
if (answer) resolve(answer);
else {
reject("No answer!");
}
});
});
};
const create = baseURL => {
// Create and configure an apisauce-based api object.
const api = apisauce.create({
baseURL,
headers: {
"Cache-Control": "no-cache",
Accept: "*/*",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
},
timeout: 10000
});
// Transforms JSON request data into x-www-form-urlencoded
api.addRequestTransform(request => {
let str = [];
for (const p in request.data) {
str.push(
encodeURIComponent(p) + "=" + encodeURIComponent(request.data[p])
);
}
request.data = str.join("&");
});
let _getAuthCookie = async () => {
try {
const authCookie = await ask("Insert authentication cookie:");
_getAuthCookie = () => authCookie;
return authCookie;
} catch (err) {
console.error(err);
}
};
const _getTemplateId = templatename =>
createHash("md5")
.update(templatename)
.digest("hex");
const _getRequestToken = async () => {
try {
const authCookie = await _getAuthCookie();
api.setHeader("Cookie", `VtexIdclientAutCookie=${authCookie};`);
const { data } = await api.post(
"/admin/a/PortalManagement/AddFile?fileType=css"
);
const $ = cheerio.load(data);
const requestToken = $("#fileUploadRequestToken").val();
if (!requestToken) throw new Error("Couldn't get request token!");
return requestToken;
} catch (err) {
console.error(`Couldn't get request token: ${err}`);
}
};
const _saveTemplate = async (data = {}, isSub, type, actionForm = "Save") => {
try {
const authCookie = await _getAuthCookie();
const { templateName, templatename, template, templateId } = data;
const endpoint =
type === "shelf" || type === "shelfTemplate"
? "admin/a/PortalManagement/SaveShelfTemplate"
: "admin/a/PortalManagement/SaveTemplate";
if (!authCookie) throw new Error("You must provide a valid auth cookie!");
if (!templatename && !templateName)
throw new Error("You must provide a name when saving a template!");
if (!template)
throw new Error("You must provide content when saving a template!");
api.setHeader("Cookie", `VtexIdclientAutCookie=${authCookie};`);
api.setHeader(
"Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8"
);
return api.post(endpoint, {
...data,
isSub,
actionForm,
textConfirm: "sim"
});
} catch (err) {
console.error(err);
}
};
const _parseErrorMessage = (data, templatename) => {
const x = data.indexOf("<applicationexceptionobject>") + 28;
const y = data.indexOf("</applicationexceptionobject>");
const obj = JSON.parse(data.substr(x, y - x));
return `Couldn't save template (${templatename}): ${obj.message}`;
};
let _getTemplates = async (type, isSub = false) => {
try {
_getTemplates.cache = _getTemplates.cache || {};
const key = `${type}-${isSub}`;
const endpoint = `admin/a/PortalManagement/GetTemplateList?type=${type}&IsSub=${
isSub ? 1 : 0
}`;
const authCookie = await _getAuthCookie();
api.setHeader("Cookie", `VtexIdclientAutCookie=${authCookie};`);
api.setHeader(
"Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8"
);
if (!_getTemplates.cache[key]) {
const { data } = await api.post(endpoint);
_getTemplates.cache[key] = data;
}
return _getTemplates.cache[key];
} catch (err) {
console.error(err);
}
};
const _getLegacyTemplateId = async (reqData, type, isSub = false) => {
try {
const templatesList = await _getTemplates(type, isSub);
const name = reqData.templateName || reqData.templatename;
const regex = new RegExp(
`(${name})([\\s\\S]+?)(templateId=)([\\s\\S]+?(?="))`
);
const matches = templatesList.match(regex);
const templateId = matches[4];
if (!templateId) throw new Error("template not found!");
return templateId;
} catch (err) {
console.error(`Couldn't get legacy template id: ${err}`);
}
};
const _saveLegacyTemplate = async (reqData, type = "viewTemplate", isSub) => {
try {
const action = type === "shelfTemplate" ? "Update" : "Save";
reqData.templateId = await _getLegacyTemplateId(reqData, type, isSub);
return _saveTemplate(reqData, isSub, type, action);
} catch (err) {
console.error(err);
}
};
const saveShelfTemplate = async (templateName, HTML, shelfClass) => {
try {
const reqData = {
templateName,
templateId: _getTemplateId(templateName),
template: HTML,
roundCorners: false,
templateCssClass: shelfClass
};
let term = "saved";
let { status, data } = await _saveTemplate(reqData, true, "shelf");
if (~data.indexOf("already exists")) {
term = "updated";
const res = await _saveLegacyTemplate(reqData, "shelfTemplate", true);
status = res.status;
data = res.data;
}
if (status.toString().substr(0, 1) !== "2")
throw new Error(
`Couldn't save template (${templateName}). Status: ${status}`
);
else if (~data.indexOf("originalMessage"))
throw new Error(_parseErrorMessage(data, templateName));
return `Shelf template (${templateName}) ${term}!`;
} catch (err) {
console.error(err);
}
};
const saveTemplate = async (templatename, HTML, isSub = false) => {
try {
const reqData = {
templatename,
templateId: _getTemplateId(templatename),
template: HTML
};
let { status, data } = await _saveTemplate(reqData, isSub);
if (~data.indexOf("already exists")) {
const res = await _saveLegacyTemplate(reqData, "viewTemplate", isSub);
status = res.status;
data = res.data;
}
if (status.toString().substr(0, 1) !== "2")
throw new Error(
`Couldn't save template (${templatename}). Status: ${status}`
);
else if (~data.indexOf("originalMessage"))
throw new Error(_parseErrorMessage(data, templatename));
return `Template (${templatename}) saved!`;
} catch (err) {
console.error(err);
}
};
const saveFile = async (website, file, filepath, content) => {
try {
const authCookie = await _getAuthCookie();
const data = {
path: filepath,
text: content
};
const url = `/api/portal/pvt/sites/${website}/files/${file}`;
const headers = {
Cookie: `VtexIdclientAutCookie=${authCookie};`,
"Content-Type": "application/json",
Accept: "application/json"
};
try {
const response = (await api({
url,
method: "PUT",
data,
headers
})).data;
console.log(response);
return `File: ${filepath} saved!`;
} catch (error) {
throw error;
}
} catch (err) {
console.error(err);
}
};
// The public API
return {
saveTemplate,
saveShelfTemplate,
saveFile
};
};
module.exports = {
create
};