|
|
@ -19,7 +19,19 @@ import open from "open"; |
|
|
import {sanitizeUrl} from "@braintree/sanitize-url"; |
|
|
import {sanitizeUrl} from "@braintree/sanitize-url"; |
|
|
import sanitizeHtml from 'sanitize-html'; |
|
|
import sanitizeHtml from 'sanitize-html'; |
|
|
import {escape} from "lodash-es"; |
|
|
import {escape} from "lodash-es"; |
|
|
import {getBlockData, getBlockConfigs, getConfigs, readJSONFile, zipProject} from "./helpers.js"; |
|
|
import { |
|
|
|
|
|
getBlockConfigs, |
|
|
|
|
|
getBlockData, |
|
|
|
|
|
getBlockName, |
|
|
|
|
|
getConfigs, |
|
|
|
|
|
getImagesList, |
|
|
|
|
|
isFileEmpty, |
|
|
|
|
|
readJSONFile, |
|
|
|
|
|
removeCommentsFromCss, |
|
|
|
|
|
removeCommentsFromJs, |
|
|
|
|
|
uploadFile, |
|
|
|
|
|
zipProject |
|
|
|
|
|
} from "./helpers.js"; |
|
|
import PluginError from 'plugin-error'; |
|
|
import PluginError from 'plugin-error'; |
|
|
import {Server} from "socket.io"; |
|
|
import {Server} from "socket.io"; |
|
|
import {createServer} from 'http'; |
|
|
import {createServer} from 'http'; |
|
|
@ -93,7 +105,6 @@ app.get('/', (req, res) => { |
|
|
data.baseView = baseView; |
|
|
data.baseView = baseView; |
|
|
data.port = `/${baseViewUrl}`; |
|
|
data.port = `/${baseViewUrl}`; |
|
|
data.previewFrameUrl = `${previewFrameUrl}/${baseViewUrl}`; |
|
|
data.previewFrameUrl = `${previewFrameUrl}/${baseViewUrl}`; |
|
|
// data.previewFrameUrl = `/${baseViewUrl}`;
|
|
|
|
|
|
data.shareUrl = shareUrl; |
|
|
data.shareUrl = shareUrl; |
|
|
|
|
|
|
|
|
if (req.headers.referer) { |
|
|
if (req.headers.referer) { |
|
|
@ -127,8 +138,24 @@ app.get('/view/:baseView', (req, res) => { |
|
|
|
|
|
|
|
|
app.get('/publish', async (req, res) => { |
|
|
app.get('/publish', async (req, res) => { |
|
|
const data = await readJSONFile(path.join(projectPath, `block.json`)); |
|
|
const data = await readJSONFile(path.join(projectPath, `block.json`)); |
|
|
|
|
|
|
|
|
|
|
|
data.static_files = { |
|
|
|
|
|
css: getBlockName(data.name).name + '.min.css', |
|
|
|
|
|
js: getBlockName(data.name).name + '.min.js', |
|
|
|
|
|
images: await getImagesList(path.join(projectPath, 'src', 'images')), |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (await isFileEmpty(path.join(projectPath, `src/scripts`, data.static_files.js), true)) { |
|
|
|
|
|
delete data.static_files.js; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!data.static_files.images.length) { |
|
|
|
|
|
delete data.static_files.images; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
let responseData = { |
|
|
let responseData = { |
|
|
uploadUrl: undefined |
|
|
uploadBundleUrl: undefined, |
|
|
|
|
|
staticFilesUrls: {} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
@ -149,27 +176,53 @@ app.get('/publish', async (req, res) => { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (responseData.uploadUrl) { |
|
|
// Start files uploading process.
|
|
|
await zipProject(path.join(projectPath, 'src'), path.join(projectPath, 'dist.zip')); |
|
|
try { |
|
|
const body = await fs.readFile(path.join(projectPath, 'dist.zip')); |
|
|
if (responseData.uploadBundleUrl) { |
|
|
const response = await fetch(`${responseData.uploadUrl}`, { |
|
|
await zipProject(path.join(projectPath, 'src'), path.join(projectPath, 'dist.zip')); |
|
|
method: 'PUT', |
|
|
await uploadFile(path.join(projectPath, 'dist.zip'), responseData.uploadBundleUrl); // Bundle
|
|
|
body, |
|
|
} |
|
|
headers: {'Content-Type': 'application/zip'} |
|
|
|
|
|
}); |
|
|
// TODO: Upload CSS/JS/Images files only if the type of the unit is `foundation` or `component`.
|
|
|
|
|
|
if (responseData.staticFilesUrls.css) { |
|
|
|
|
|
await uploadFile( |
|
|
|
|
|
path.join(projectPath, 'src/styles', data.static_files.css), |
|
|
|
|
|
responseData.staticFilesUrls.css.uploadUrl, |
|
|
|
|
|
(data) => removeCommentsFromCss(data)); // CSS
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (response.status !== 200) { |
|
|
if (responseData.staticFilesUrls.js) { |
|
|
res.json({success: false, message: "Can't upload the archive, permissions error."}); |
|
|
await uploadFile( |
|
|
// TODO: Need to update the registry server.
|
|
|
path.join(projectPath, 'src/scripts', data.static_files.js), |
|
|
await fs.unlink(path.join(projectPath, 'dist.zip')); |
|
|
responseData.staticFilesUrls.js.uploadUrl, |
|
|
return; |
|
|
(data) => removeCommentsFromJs(data)); // JS
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (responseData.staticFilesUrls.images) { |
|
|
|
|
|
for (let i = 0; i < data.static_files.images.length; i++) { |
|
|
|
|
|
await uploadFile(path.join(projectPath, 'src/images', data.static_files.images[i]), |
|
|
|
|
|
responseData.staticFilesUrls.images[i].uploadUrl); // Images
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
} catch (err) { |
|
|
|
|
|
// TODO: Need to update the registry server.
|
|
|
|
|
|
await fs.unlink(path.join(projectPath, 'dist.zip')); // Remove local bundle
|
|
|
|
|
|
|
|
|
|
|
|
res.json({success: false, message: err.message}); |
|
|
|
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
await fs.unlink(path.join(projectPath, 'dist.zip')); // Remove local bundle
|
|
|
|
|
|
|
|
|
res.json({success: true}); |
|
|
// TODO: Trigger build on the registry server only if the type of the unit is `foundation` or `component`.
|
|
|
|
|
|
try { |
|
|
|
|
|
await triggerGlobalProjectFilesBuild(getBlockName(data.name).project); |
|
|
|
|
|
} catch (err) { |
|
|
|
|
|
res.json({success: false, message: 'Something wrong with Project Builder.'}); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
await fs.unlink(path.join(projectPath, 'dist.zip')); |
|
|
res.json({success: true}); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
app.get('/data', async (req, res) => { |
|
|
app.get('/data', async (req, res) => { |
|
|
@ -177,7 +230,13 @@ app.get('/data', async (req, res) => { |
|
|
|
|
|
|
|
|
const dataFiles = prepareListOfDataFiles(await fs.readdir(path.join(projectPath, 'data'))); |
|
|
const dataFiles = prepareListOfDataFiles(await fs.readdir(path.join(projectPath, 'data'))); |
|
|
const data = await getBlockData(jsonDataFileName, {projectPath}); |
|
|
const data = await getBlockData(jsonDataFileName, {projectPath}); |
|
|
const designPreviewFiles = getListOfDesignPreviewFiles(jsonDataFileName, await fs.readdir(path.join(projectPath, 'design', 'preview'))); |
|
|
|
|
|
|
|
|
let designPreviewFiles = []; |
|
|
|
|
|
try { |
|
|
|
|
|
designPreviewFiles = getListOfDesignPreviewFiles(jsonDataFileName, await fs.readdir(path.join(projectPath, 'design', 'preview'))); |
|
|
|
|
|
} catch (err) { |
|
|
|
|
|
console.log('Preview Design doesn\'t exist'); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return res.json({ |
|
|
return res.json({ |
|
|
dataOptions: dataFiles, |
|
|
dataOptions: dataFiles, |
|
|
@ -439,3 +498,13 @@ async function getShareableUrl() { |
|
|
|
|
|
|
|
|
return url; |
|
|
return url; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
async function triggerGlobalProjectFilesBuild(project) { |
|
|
|
|
|
const response = await fetch(`${blocksRegistry}/project-files`, { |
|
|
|
|
|
method: 'POST', |
|
|
|
|
|
body: JSON.stringify({project}), |
|
|
|
|
|
headers: {'Content-Type': 'application/json'} |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
return response.json(); |
|
|
|
|
|
} |
|
|
|