diff --git a/web/src/beta/features/PluginPlayground/Code/hook.ts b/web/src/beta/features/PluginPlayground/Code/hook.ts index 15b8ccdb6f..1a99949488 100644 --- a/web/src/beta/features/PluginPlayground/Code/hook.ts +++ b/web/src/beta/features/PluginPlayground/Code/hook.ts @@ -51,10 +51,70 @@ const getYmlJson = (file: FileType) => { export default ({ files }: Props) => { const [widgets, setWidgets] = useState(); const [, setNotification] = useNotification(); + const [fileOutputs, setFileOutputs] = useState< + { + title: string; + output: string; + }[] + >(); const executeCode = useCallback(() => { const ymlFile = files.find((file) => file.title.endsWith(".yml")); + const jsFiles = files.filter((file) => file.title.endsWith(".js")); + + const outputs = jsFiles.map((file) => { + try { + const fn = new Function( + `"use strict"; + const reearth = { + ui: { + show: function () {} + }, + popup: { + show: function () {} + }, + modal: { + show: function () {} + } + }; + + let capturedConsole = []; + + console.log = (message) => { + capturedConsole.push(message); + }; + + console.error = (message) => { + capturedConsole.push(message); + }; + + ${file.sourceCode}; + + return capturedConsole.join("\\n"); + ` + ); + + return { + title: file.title, + output: fn() + }; + } catch (error) { + if (error instanceof Error) { + return { + title: file.title, + output: error.message + }; + } + return { + title: file.title, + output: "Failed to execute" + }; + } + }); + + setFileOutputs(outputs); + if (!ymlFile) return; const getYmlResult = getYmlJson(ymlFile); @@ -66,13 +126,7 @@ export default ({ files }: Props) => { const ymlJson = getYmlResult.data; - if (!Array.isArray(ymlJson.extensions) || ymlJson.extensions.length === 0) { - setNotification({ - type: "error", - text: "No extensions found in YAML file." - }); - return; - } + if (!ymlJson.extensions) return; const widgets = ymlJson.extensions.reduce>( (prv, cur) => { @@ -126,6 +180,7 @@ export default ({ files }: Props) => { return { executeCode, - widgets + widgets, + fileOutputs }; }; diff --git a/web/src/beta/features/PluginPlayground/Console/index.tsx b/web/src/beta/features/PluginPlayground/Console/index.tsx index 0310d33665..0196d7e85d 100644 --- a/web/src/beta/features/PluginPlayground/Console/index.tsx +++ b/web/src/beta/features/PluginPlayground/Console/index.tsx @@ -1,7 +1,34 @@ +import { styled } from "@reearth/services/theme"; import { FC } from "react"; -const Console: FC = () => { - return
Console content
; +type Props = { + fileOutputs: + | { + title: string; + output: string; + }[] + | undefined; }; +const Console: FC = ({ fileOutputs }) => { + if (!fileOutputs) return null; + return ( + + {fileOutputs.map(({ title, output }, index) => ( +
+ {`[${title}]`} {output} +
+ ))} +
+ ); +}; + +const Wrapper = styled.div(() => ({ + display: "flex", + flexDirection: "column", + maxHeight: "100%", + height: "100%", + overflow: "auto" +})); + export default Console; diff --git a/web/src/beta/features/PluginPlayground/hooks.tsx b/web/src/beta/features/PluginPlayground/hooks.tsx index d5f7217fe0..ad0b383da6 100644 --- a/web/src/beta/features/PluginPlayground/hooks.tsx +++ b/web/src/beta/features/PluginPlayground/hooks.tsx @@ -24,7 +24,7 @@ export default () => { handlePluginDownload } = usePlugins(); - const { widgets, executeCode } = useCode({ + const { widgets, executeCode, fileOutputs } = useCode({ files: selectedPlugin.files }); @@ -46,10 +46,10 @@ export default () => { { id: "console", name: "Console", - children: + children: } ], - [] + [fileOutputs] ); const SubRightAreaTabs: TabItem[] = useMemo(