123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- import { nanoid } from 'nanoid/non-secure';
- export default function (data) {
- let timeout;
- const instanceId = nanoid();
- const scriptId = `script${data.id}`;
- const propertyName = `automa${data.id}`;
- const isScriptExists = document.querySelector(`#${scriptId}`);
- if (isScriptExists) {
- window.top.postMessage(
- {
- id: data.id,
- type: 'sandbox',
- result: {
- columns: {},
- variables: {},
- },
- },
- '*'
- );
- return;
- }
- const preloadScripts = data.preloadScripts.map((item) => {
- const scriptEl = document.createElement('script');
- scriptEl.textContent = item.script;
- (document.body || document.documentElement).appendChild(scriptEl);
- return scriptEl;
- });
- if (!data.blockData.code.includes('automaNextBlock')) {
- data.blockData.code += `\n automaNextBlock()`;
- }
- const script = document.createElement('script');
- script.id = scriptId;
- script.textContent = `
- (() => {
- function automaRefData(keyword, path = '') {
- if (!keyword) return null;
- if (!path) return ${propertyName}.refData[keyword];
- return window.$getNestedProperties(${propertyName}.refData, keyword + '.' + path);
- }
- function automaSetVariable(name, value) {
- const variables = ${propertyName}.refData.variables;
- if (!variables) ${propertyName}.refData.variables = {}
- ${propertyName}.refData.variables[name] = value;
- }
- function automaNextBlock(data = {}, insert = true) {
- ${propertyName}.nextBlock({ data, insert });
- }
- function automaResetTimeout() {
- ${propertyName}.resetTimeout();
- }
- function automaFetch(type, resource) {
- return ${propertyName}.fetch(type, resource);
- }
- try {
- ${data.blockData.code}
- } catch (error) {
- console.error(error);
- automaNextBlock({ $error: true, message: error.message });
- }
- })();
- `;
- function cleanUp() {
- script.remove();
- preloadScripts.forEach((preloadScript) => {
- preloadScript.remove();
- });
- delete window[propertyName];
- }
- window[propertyName] = {
- refData: data.refData,
- nextBlock: (result) => {
- cleanUp();
- window.top.postMessage(
- {
- id: data.id,
- type: 'sandbox',
- result: {
- variables: data?.refData?.variables,
- columns: {
- data: result?.data,
- insert: result?.insert,
- },
- },
- },
- '*'
- );
- },
- resetTimeout: () => {
- clearTimeout(timeout);
- timeout = setTimeout(cleanUp, data.blockData.timeout);
- },
- fetch: (type, resource) => {
- return new Promise((resolve, reject) => {
- const types = ['json', 'text'];
- if (!type || !types.includes(type)) {
- reject(new Error('The "type" must be "text" or "json"'));
- return;
- }
- window.top.postMessage(
- {
- type: 'automa-fetch',
- data: { id: instanceId, type, resource },
- },
- '*'
- );
- const eventName = `automa-fetch-response-${instanceId}`;
- const eventListener = ({ detail }) => {
- window.removeEventListener(eventName, eventListener);
- if (detail.isError) {
- reject(new Error(detail.result));
- } else {
- resolve(detail.result);
- }
- };
- window.addEventListener(eventName, eventListener);
- });
- },
- };
- timeout = setTimeout(cleanUp, data.blockData.timeout);
- (document.body || document.documentElement).appendChild(script);
- }
|