diff --git a/helpers.js b/helpers.js index 34d3135..ec2a05d 100644 --- a/helpers.js +++ b/helpers.js @@ -9,6 +9,11 @@ import archiver from "archiver"; import {buildWordPress} from "./platforms/wordpress/wordpress-adapter.js"; import {buildHubspotEmail} from "./platforms/hubspot/hubspot-email-adapter.js"; import {buildHubspotPage} from "./platforms/hubspot/hubspot-page-adapter.js"; +import fs from "fs/promises"; +import {constants} from "fs"; +import fetch from "node-fetch"; +import mime from "mime-types"; +import {exec} from "child_process"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -26,6 +31,7 @@ export async function readJSONFile(jsonFile) { let data = {}; try { + await fs.access(jsonFile, constants.F_OK | constants.R_OK); data = await fsExtra.readJson(jsonFile); } catch (e) { return { @@ -43,29 +49,37 @@ function getErrorHtml(message = '', errorMessage = '') { `; } -export async function getBlockConfigs(jsonFileName = 'default', - {includeConfigs, projectPath, modulesPath, dataFiles} = {}) { - let data = await readJSONFile(path.join(projectPath, 'data', `${jsonFileName}.json`)); +export async function getBlockData(jsonFileName = 'default', {projectPath} = {jsonFileName: 'default'}) { + const filePath = path.join(projectPath, 'data', `${jsonFileName}.json`); + const data = await readJSONFile(filePath); + if (data.error) { - return data; - } - - if (includeConfigs) { - Object.assign(data, { - config: Object.assign(JSON.parse(JSON.stringify(config)), // The entire config object. - { - projectDir: modulesPath, activeDataFile: jsonFileName, dataFiles: dataFiles.map((name) => { - return { - name, active: jsonFileName === name, - }; - }), remToPx: config.has('remToPx') ? config.get('remToPx') : 16, - }) - }); + console.log(filePath, data.errorMessage.replace(/<[^>]*>?/gm, '')); + return {}; } return data; } +export function getBlockConfigs(args = {modulesPath: '', dataFiles: []}) { + const updatedConfig = Object.assign(JSON.parse(JSON.stringify(config)), // The entire config object. + { + projectDir: args.modulesPath, dataFiles: args.dataFiles.map((name) => { + return { + name, + }; + }), remToPx: config.has('remToPx') ? config.get('remToPx') : 16, + }); + + // Avoid cache conflict on Global Project css/js files. + if (updatedConfig.project) { + updatedConfig.project.css = updatedConfig.project.css ? updatedConfig.project.css + '?cache=' + Date.now() : undefined; + updatedConfig.project.js = updatedConfig.project.js ? updatedConfig.project.js + '?cache=' + Date.now() : undefined; + } + + return updatedConfig; +} + export function getBlockName(name = '') { if (name.startsWith('@')) { name = name.substring(1); @@ -163,3 +177,158 @@ export async function buildExportFiles(blockName, platform) { await buildHubspotPage(blockName) } } + +export function removeCommentsFromCss(content) { + return content.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, ''); +} + +export function removeCommentsFromJs(content) { + return content.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, ''); +} + +export async function uploadFile(filePath, uploadUrl, validator) { + const options = {}; + + const contentType = mime.lookup(filePath); + if (['text/css', 'application/javascript'].includes(contentType)) { + options.encoding = 'utf8'; + } + + let body = await fs.readFile(filePath, options); + + if (validator) { + body = validator(body); + } + + try { + const response = await fetch(uploadUrl, { + method: 'PUT', + body: body, + headers: {'Content-Type': contentType} + }); + + return response.status !== 200; + } catch (err) { + console.log(err) + const fileName = filePath.split('/').pop(); + throw new Error(`Can't upload "${fileName}" file. Server permission error.`); + } +} + +export async function getImagesList(rootFolder, subFolder = '') { + const imagesPath = path.join(rootFolder, subFolder); + + try { + await fs.access(imagesPath); + } catch (err) { + // Folder doesn't exist. + return []; + } + + const images = await fs.readdir(imagesPath); + const imagesList = []; + + for (const image of images) { + const stats = await fs.stat(path.join(imagesPath, image)); + + if (stats.isDirectory()) { + const subImages = await getImagesList(rootFolder, image); + imagesList.push(...subImages); + } else { + imagesList.push(path.join(subFolder, image)); + } + } + + return imagesList; +} + +export async function isFileEmpty(filePath, ignoreComments = false) { + const fileContent = await fs.readFile(filePath, 'utf8'); + const lines = fileContent.split('\n'); + + for (const line of lines) { + if (ignoreComments && line.trim().startsWith('//')) { + continue; + } + + if (line.trim().length > 0) { + return false; + } + } + + return true; +} + +export function replaceNames(content, images, uploadedImages) { + images.forEach((image, index) => { + content = content.replace(image, uploadedImages[index].fileName); + }); + + return content; +} + +export async function getBlockFromCloud(blockName, blocksRegistry) { + const queryString = new URLSearchParams(); + queryString.append('blockName', blockName); + queryString.append('includeDevConfig', 'true'); + + const response = await fetch(`${blocksRegistry}?${queryString.toString()}`); + const responseData = await response.json(); + if (!responseData || !responseData.name) { + const message = "⚠️ Block not found, please contact administrator." + throw new Error(message); + } + + if (responseData.statusCode && responseData.statusCode !== 200) { + const message = ["⚠️ [ERROR]", responseData.message || "Server side error."].join(' '); + throw new Error(message); + } + + return responseData; +} + +export async function verifyVersion(projectPath, blocksRegistry) { + const blockJson = await readJSONFile(path.join(projectPath, `block.json`)); + const blockName = getBlockName(blockJson.name); + + if (typeof blockJson.version === 'undefined' || !blockName.name) { + return true; + } + + /* + * This block is managed on cloud. + * Let's detect the latest version. + */ + + const block = await getBlockFromCloud('@' + blockJson.name, blocksRegistry); + return block.version === blockJson.version; +} + +export async function syncFilesWithCloud(jsonBlockPath, bs, sourceFiles = false) { + const blockJson = await readJSONFile(jsonBlockPath); + const blockName = blockJson.name.startsWith('@') ? blockJson.name : `@${blockJson.name}`; + + bs.pause(); + + // Looks like it takes time to pause the browser-sync server, so delay(setTimeout) is necessary. + await new Promise((resolve) => setTimeout(() => resolve(), 1000)); + + await new Promise((resolve) => { + const args = sourceFiles ? '--source' : ''; + const createBlockModulePath = `./node_modules/@axe-web/create-block`; + + // exec(`BLOCK_NAME=${blockName} node ${createBlockModulePath}/create-block.js sync ${args}`, (err, stdout, stderr) => { + exec(`node ${createBlockModulePath}/create-block.js sync ${args}`, (err, stdout, stderr) => { + if (err || stderr) { + const message = err || stderr; + console.error('Error:', message); + throw new Error(message); + } + + console.log(stdout); + resolve(); + }); + }); + + bs.resume(); +} diff --git a/layouts/alignfull.hbs b/layouts/alignfull.hbs index 2a123da..77baa6e 100644 --- a/layouts/alignfull.hbs +++ b/layouts/alignfull.hbs @@ -4,9 +4,7 @@ -
- {{> (include_block_template) }} -
+
{{> (include_partial "layouts/partials/scripts") }} diff --git a/layouts/container.hbs b/layouts/container.hbs index b1f559f..901800a 100644 --- a/layouts/container.hbs +++ b/layouts/container.hbs @@ -4,11 +4,9 @@ -
-
- {{> (include_block_template) }} -
-
+
+
+
{{> (include_partial "layouts/partials/scripts") }} diff --git a/layouts/index.hbs b/layouts/index.hbs index 0199dbb..99ec74d 100644 --- a/layouts/index.hbs +++ b/layouts/index.hbs @@ -14,6 +14,9 @@ diff --git a/layouts/partials/head.hbs b/layouts/partials/head.hbs index d2ebb29..7a1c7bf 100644 --- a/layouts/partials/head.hbs +++ b/layouts/partials/head.hbs @@ -3,6 +3,8 @@ +{{#if config.project.css }} +{{/if}} {{#if config.cssUrl }} {{#each config.cssUrl }} diff --git a/layouts/partials/scripts.hbs b/layouts/partials/scripts.hbs index 0cd3743..eece0f5 100644 --- a/layouts/partials/scripts.hbs +++ b/layouts/partials/scripts.hbs @@ -1,6 +1,11 @@ + + -{{#if config.jsUrl }} + +{{#if config.project.js }} +{{/if}} +{{#if config.jsUrl }} {{#each config.jsUrl }} {{/each}} {{/if}} diff --git a/layouts/partials/toolbar.hbs b/layouts/partials/toolbar.hbs index e12aa92..70b018c 100644 --- a/layouts/partials/toolbar.hbs +++ b/layouts/partials/toolbar.hbs @@ -3,14 +3,17 @@
-
- Sizes: 1rem = {{ config.remToPx }}px +
+ Version: {{ config.version }}
- {{#if config.styleGuideUrl}} - + {{#if shareUrl}} + + {{/if}} + {{#if styleGuideUrl}} + {{/if}}
diff --git a/layouts/scripts/dist/frame-index.min.js b/layouts/scripts/dist/frame-index.min.js index 29014a5..1514557 100644 --- a/layouts/scripts/dist/frame-index.min.js +++ b/layouts/scripts/dist/frame-index.min.js @@ -1 +1 @@ -window.initBlock=function(e="",n="",o){document.querySelectorAll(n).forEach((e=>o(e)))},function(){let e;function n(n){const o=document.querySelector("body > main").scrollHeight;if(e===o)return;e=o,window.parent.postMessage("resize:"+JSON.stringify({height:e}),"*")}n(),new ResizeObserver(n).observe(document.body)}(); +let e;window.initBlock=function(e="",n="",r){t=function(){document.querySelectorAll(n).forEach((e=>r(e)))},t()};let t,n={};function r(r={}){r.template&&(e=r.template),r.data&&(n=r.data),e&&function(e,n,r){const a=Handlebars.compile(e);let o;Handlebars.registerHelper("esc_attr",(function(e){return e})),Handlebars.registerHelper("esc_url",(function(e){return e})),Handlebars.registerHelper("esc_html",(function(e){return e})),Handlebars.registerHelper("base_url",(function(){return"/"}));try{o=a(n)}catch(e){o=`
\n

Syntax Error:

\n
${e.toString()}
\n
`}r.innerHTML=o,t&&t()}(e,n||{},document.getElementById("hbs-container"))}!function(){function e(){const e=new URLSearchParams(window.location.search),t={};for(const[n,r]of e)t[n]=r;return t}!function(){const t=new URLSearchParams({name:e().data||"default"});fetch(`/data?${t}`).then((e=>e.json())).then((e=>{n=e.data,r({data:n})}))}(),window.addEventListener("message",(function(e){const t=e.data,a="dataUpdate:";if("string"==typeof t&&t.startsWith(a))try{n=JSON.parse(t.substring(a.length)),r({data:n})}catch(e){console.log("Error parsing incoming data.",e)}}))}(),function(){const e=window.io.connect();e.on("error",(function(e){console.log(e)})),e.on("templateUpdate",(function(e){r({template:e.template})}))}(); diff --git a/layouts/scripts/dist/frame-index.min.js.map b/layouts/scripts/dist/frame-index.min.js.map new file mode 100644 index 0000000..692808e --- /dev/null +++ b/layouts/scripts/dist/frame-index.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"frame-index.min.js","sources":["../frame/frame.js"],"sourcesContent":["'use strict';\n\nwindow.initBlock = initBlock;\n\nlet template;\nlet data = {};\nlet reload;\n\n// Blocks Initialization.\nfunction initBlock(blockName = '', selector = '', cb) {\n reload = function () {\n document.querySelectorAll(selector).forEach((el) => cb(el));\n }\n\n reload();\n}\n\n// Data Updates Listeners.\n(function () {\n loadDataOptions();\n listenToDataOptionsUpdates();\n\n function listenToDataOptionsUpdates() {\n window.addEventListener('message', function (event) {\n const message = event.data;\n const prefix = 'dataUpdate:';\n\n if (typeof message !== \"string\" || !message.startsWith(prefix)) {\n return;\n }\n\n try {\n data = JSON.parse(message.substring(prefix.length));\n updateBlock({data});\n } catch (e) {\n console.log('Error parsing incoming data.', e);\n }\n });\n }\n\n function getQueryParams() {\n const urlParams = new URLSearchParams(window.location.search);\n const params = {};\n\n for (const [key, value] of urlParams) {\n params[key] = value;\n }\n\n return params;\n }\n\n function loadDataOptions() {\n const queryParameters = new URLSearchParams({name: getQueryParams().data || 'default'});\n fetch(`/data?${queryParameters}`)\n .then((response) => response.json())\n .then((response) => {\n data = response.data; // Update state.\n updateBlock({data});\n })\n }\n})();\n\n// Listen to Template updates.\n(function () {\n initSocket();\n\n function initSocket() {\n const socket = window.io.connect();\n\n socket.on('error', function (err) {\n console.log(err);\n });\n\n // socket.on('connect', function () {\n // console.log('user connected', socket.id)\n // });\n\n socket.on('templateUpdate', function (args) {\n updateBlock({template: args.template});\n });\n }\n})();\n\nfunction updateBlock(args = {}) {\n if (args.template) {\n template = args.template; // Update state.\n }\n\n if (args.data) {\n data = args.data; // Update state.\n }\n\n if (!template) {\n return;\n }\n\n renderBlock(template, data || {}, document.getElementById(\"hbs-container\"));\n}\n\nfunction renderBlock(templateHbs, jsonData, target) {\n const template = Handlebars.compile(templateHbs);\n\n /**\n * Handlebars Helpers\n */\n Handlebars.registerHelper('esc_attr', function (attr) {\n return attr;\n });\n\n Handlebars.registerHelper('esc_url', function (attr) {\n return attr;\n });\n\n Handlebars.registerHelper('esc_html', function (attr) {\n return attr;\n });\n\n Handlebars.registerHelper('base_url', function () {\n return '/';\n });\n\n let html;\n\n try {\n html = template(jsonData);\n } catch (e) {\n html = `
\n

Syntax Error:

\n
${e.toString()}
\n
`;\n }\n\n target.innerHTML = html;\n if (reload) {\n reload();\n }\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/layouts/scripts/dist/index.min.js b/layouts/scripts/dist/index.min.js index 0cc308c..98f64fa 100644 --- a/layouts/scripts/dist/index.min.js +++ b/layouts/scripts/dist/index.min.js @@ -1,4 +1,4 @@ -function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var t={exports:{}},n={},r=Symbol.for("react.element"),a=Symbol.for("react.portal"),l=Symbol.for("react.fragment"),o=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),u=Symbol.for("react.provider"),s=Symbol.for("react.context"),c=Symbol.for("react.forward_ref"),f=Symbol.for("react.suspense"),d=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),m=Symbol.iterator;var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,v={};function y(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||h}function b(){}function k(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||h}y.prototype.isReactComponent={},y.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},y.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},b.prototype=y.prototype;var w=k.prototype=new b;w.constructor=k,g(w,y.prototype),w.isPureReactComponent=!0;var S=Array.isArray,x=Object.prototype.hasOwnProperty,C={current:null},E={key:!0,ref:!0,__self:!0,__source:!0};function _(e,t,n){var a,l={},o=null,i=null;if(null!=t)for(a in void 0!==t.ref&&(i=t.ref),void 0!==t.key&&(o=""+t.key),t)x.call(t,a)&&!E.hasOwnProperty(a)&&(l[a]=t[a]);var u=arguments.length-2;if(1===u)l.children=n;else if(1>>1,l=e[r];if(!(0>>1;ra(u,n))sa(c,u)?(e[r]=c,e[s]=n,r=s):(e[r]=u,e[i]=n,r=i);else{if(!(sa(c,n)))break e;e[r]=c,e[s]=n,r=s}}}return t}function a(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if("object"==typeof performance&&"function"==typeof performance.now){var l=performance;e.unstable_now=function(){return l.now()}}else{var o=Date,i=o.now();e.unstable_now=function(){return o.now()-i}}var u=[],s=[],c=1,f=null,d=3,p=!1,m=!1,h=!1,g="function"==typeof setTimeout?setTimeout:null,v="function"==typeof clearTimeout?clearTimeout:null,y="undefined"!=typeof setImmediate?setImmediate:null;function b(e){for(var a=n(s);null!==a;){if(null===a.callback)r(s);else{if(!(a.startTime<=e))break;r(s),a.sortIndex=a.expirationTime,t(u,a)}a=n(s)}}function k(e){if(h=!1,b(e),!m)if(null!==n(u))m=!0,R(w);else{var t=n(s);null!==t&&O(k,t.startTime-e)}}function w(t,a){m=!1,h&&(h=!1,v(E),E=-1),p=!0;var l=d;try{for(b(a),f=n(u);null!==f&&(!(f.expirationTime>a)||t&&!z());){var o=f.callback;if("function"==typeof o){f.callback=null,d=f.priorityLevel;var i=o(f.expirationTime<=a);a=e.unstable_now(),"function"==typeof i?f.callback=i:f===n(u)&&r(u),b(a)}else r(u);f=n(u)}if(null!==f)var c=!0;else{var g=n(s);null!==g&&O(k,g.startTime-a),c=!1}return c}finally{f=null,d=l,p=!1}}"undefined"!=typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var S,x=!1,C=null,E=-1,_=5,P=-1;function z(){return!(e.unstable_now()-P<_)}function N(){if(null!==C){var t=e.unstable_now();P=t;var n=!0;try{n=C(!0,t)}finally{n?S():(x=!1,C=null)}}else x=!1}if("function"==typeof y)S=function(){y(N)};else if("undefined"!=typeof MessageChannel){var T=new MessageChannel,L=T.port2;T.port1.onmessage=N,S=function(){L.postMessage(null)}}else S=function(){g(N,0)};function R(e){C=e,x||(x=!0,S())}function O(t,n){E=g((function(){t(e.unstable_now())}),n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_continueExecution=function(){m||p||(m=!0,R(w))},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=l,t(s,r),null===n(u)&&r===n(s)&&(h?(v(E),E=-1):h=!0,O(k,l-o))):(r.sortIndex=i,t(u,r),m||p||(m=!0,R(w))),r},e.unstable_shouldYield=z,e.unstable_wrapCallback=function(e){var t=d;return function(){var n=d;d=t;try{return e.apply(this,arguments)}finally{d=n}}}}(j),$.exports=j; +!function(e){function t(e,t){var n=e.length;e.push(t);e:for(;0>>1,l=e[r];if(!(0>>1;ra(u,n))sa(c,u)?(e[r]=c,e[s]=n,r=s):(e[r]=u,e[i]=n,r=i);else{if(!(sa(c,n)))break e;e[r]=c,e[s]=n,r=s}}}return t}function a(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if("object"==typeof performance&&"function"==typeof performance.now){var l=performance;e.unstable_now=function(){return l.now()}}else{var o=Date,i=o.now();e.unstable_now=function(){return o.now()-i}}var u=[],s=[],c=1,f=null,d=3,p=!1,m=!1,h=!1,g="function"==typeof setTimeout?setTimeout:null,v="function"==typeof clearTimeout?clearTimeout:null,y="undefined"!=typeof setImmediate?setImmediate:null;function b(e){for(var a=n(s);null!==a;){if(null===a.callback)r(s);else{if(!(a.startTime<=e))break;r(s),a.sortIndex=a.expirationTime,t(u,a)}a=n(s)}}function k(e){if(h=!1,b(e),!m)if(null!==n(u))m=!0,O(w);else{var t=n(s);null!==t&&R(k,t.startTime-e)}}function w(t,a){m=!1,h&&(h=!1,v(E),E=-1),p=!0;var l=d;try{for(b(a),f=n(u);null!==f&&(!(f.expirationTime>a)||t&&!z());){var o=f.callback;if("function"==typeof o){f.callback=null,d=f.priorityLevel;var i=o(f.expirationTime<=a);a=e.unstable_now(),"function"==typeof i?f.callback=i:f===n(u)&&r(u),b(a)}else r(u);f=n(u)}if(null!==f)var c=!0;else{var g=n(s);null!==g&&R(k,g.startTime-a),c=!1}return c}finally{f=null,d=l,p=!1}}"undefined"!=typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var S,x=!1,C=null,E=-1,_=5,P=-1;function z(){return!(e.unstable_now()-P<_)}function N(){if(null!==C){var t=e.unstable_now();P=t;var n=!0;try{n=C(!0,t)}finally{n?S():(x=!1,C=null)}}else x=!1}if("function"==typeof y)S=function(){y(N)};else if("undefined"!=typeof MessageChannel){var T=new MessageChannel,L=T.port2;T.port1.onmessage=N,S=function(){L.postMessage(null)}}else S=function(){g(N,0)};function O(e){C=e,x||(x=!0,S())}function R(t,n){E=g((function(){t(e.unstable_now())}),n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_continueExecution=function(){m||p||(m=!0,O(w))},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=l,t(s,r),null===n(u)&&r===n(s)&&(h?(v(E),E=-1):h=!0,R(k,l-o))):(r.sortIndex=i,t(u,r),m||p||(m=!0,O(w))),r},e.unstable_shouldYield=z,e.unstable_wrapCallback=function(e){var t=d;return function(){var n=d;d=t;try{return e.apply(this,arguments)}finally{d=n}}}}(j),$.exports=j; /** * @license React * react-dom.production.min.js @@ -18,7 +18,7 @@ function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"de * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -var U=t.exports,B=$.exports;function V(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n