From 49017346dc36cd91fc22b534a9a2d7cb6aa0d4a9 Mon Sep 17 00:00:00 2001 From: keiya01 Date: Mon, 7 Aug 2023 18:02:14 +0900 Subject: [PATCH 1/2] fix: import builtin plugin from external url --- .../Infobox/Block/builtin/unsafeBlocks.ts | 6 +++--- .../Widgets/Widget/builtin/unsafeWidgets.ts | 6 +++--- .../beta/lib/unsafeBuiltinPlugins/.gitignore | 4 ---- .../beta/lib/unsafeBuiltinPlugins/index.ts | 6 +++--- web/src/beta/lib/unsafeBuiltinPlugins/load.ts | 20 ++++++++++++++++++ .../beta/lib/unsafeBuiltinPlugins/types.ts | 21 +++++++++++++++++++ web/src/services/config/index.ts | 5 +++-- .../services/config/unsafeBuiltinPlugin.ts | 20 ++---------------- 8 files changed, 55 insertions(+), 33 deletions(-) delete mode 100644 web/src/beta/lib/unsafeBuiltinPlugins/.gitignore create mode 100644 web/src/beta/lib/unsafeBuiltinPlugins/load.ts create mode 100644 web/src/beta/lib/unsafeBuiltinPlugins/types.ts diff --git a/web/src/beta/lib/core/Crust/Infobox/Block/builtin/unsafeBlocks.ts b/web/src/beta/lib/core/Crust/Infobox/Block/builtin/unsafeBlocks.ts index f8c225bedb..8f21cc299b 100644 --- a/web/src/beta/lib/core/Crust/Infobox/Block/builtin/unsafeBlocks.ts +++ b/web/src/beta/lib/core/Crust/Infobox/Block/builtin/unsafeBlocks.ts @@ -14,7 +14,7 @@ function processUnsafeBuiltinBlocks(plugin?: UnsafeBuiltinPlugin[]) { const unsafeBlocks: UnsafeBuiltinBlocks | undefined = plugin .map(p => - p.widgets.map(w => { + p.blocks?.map(w => { return { widgetId: `${p.id}/${w.extensionId}`, ...w, @@ -23,11 +23,11 @@ function processUnsafeBuiltinBlocks(plugin?: UnsafeBuiltinPlugin[]) { ) .reduce((a, b) => { const newObject: { [key: string]: Component } = {}; - b.forEach(w => { + b?.forEach(w => { newObject[w.widgetId] = w.component; }); return merge(a, newObject); }, {}); - return unsafeBlocks; + return unsafeBlocks || []; } diff --git a/web/src/beta/lib/core/Crust/Widgets/Widget/builtin/unsafeWidgets.ts b/web/src/beta/lib/core/Crust/Widgets/Widget/builtin/unsafeWidgets.ts index 2a84807537..c7dd40fad3 100644 --- a/web/src/beta/lib/core/Crust/Widgets/Widget/builtin/unsafeWidgets.ts +++ b/web/src/beta/lib/core/Crust/Widgets/Widget/builtin/unsafeWidgets.ts @@ -16,7 +16,7 @@ function processUnsafeBuiltinWidgets(plugin?: UnsafeBuiltinPlugin[]) { const unsafeWidgets: UnsafeBuiltinWidgets | undefined = plugin .map(p => - p.widgets.map(w => { + p.widgets?.map(w => { return { widgetId: `${p.id}/${w.extensionId}`, ...w, @@ -25,11 +25,11 @@ function processUnsafeBuiltinWidgets(plugin?: UnsafeBuiltinPlugin[]) { ) .reduce((a, b) => { const newObject: { [key: string]: Component } = {}; - b.forEach(w => { + b?.forEach(w => { newObject[w.widgetId] = w.component; }); return merge(a, newObject); }, {}); - return unsafeWidgets; + return unsafeWidgets || []; } diff --git a/web/src/beta/lib/unsafeBuiltinPlugins/.gitignore b/web/src/beta/lib/unsafeBuiltinPlugins/.gitignore deleted file mode 100644 index c795b63c43..0000000000 --- a/web/src/beta/lib/unsafeBuiltinPlugins/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!.gitignore -!README.md -!index.ts \ No newline at end of file diff --git a/web/src/beta/lib/unsafeBuiltinPlugins/index.ts b/web/src/beta/lib/unsafeBuiltinPlugins/index.ts index f5a9972005..ee23657566 100644 --- a/web/src/beta/lib/unsafeBuiltinPlugins/index.ts +++ b/web/src/beta/lib/unsafeBuiltinPlugins/index.ts @@ -1,5 +1,5 @@ -// import { default as myExampleUnsafePlugin } from "./myExampleUnsafePlugin/index.jsx"; +import { loadPlugins } from "./load"; -// export default [myExampleUnsafePlugin]; +export * from "./types"; -export default []; +export default await loadPlugins(); diff --git a/web/src/beta/lib/unsafeBuiltinPlugins/load.ts b/web/src/beta/lib/unsafeBuiltinPlugins/load.ts new file mode 100644 index 0000000000..d80d1fe6ca --- /dev/null +++ b/web/src/beta/lib/unsafeBuiltinPlugins/load.ts @@ -0,0 +1,20 @@ +import { UnsafeBuiltinPlugin } from "./types"; + +export const loadPlugins = async () => { + const urls = window.REEARTH_CONFIG?.unsafePluginUrls; + return urls + ? ( + await Promise.all( + urls.map(async url => { + try { + const plugin: UnsafeBuiltinPlugin = (await import(/* @vite-ignore */ url)).default; + console.log("Hello", plugin); + return plugin; + } catch (e) { + throw new Error(`Specified unsafe built-in module could not find: ${url} ${e}`); + } + }), + ) + ).filter(Boolean) + : []; +}; diff --git a/web/src/beta/lib/unsafeBuiltinPlugins/types.ts b/web/src/beta/lib/unsafeBuiltinPlugins/types.ts new file mode 100644 index 0000000000..1d60d0095e --- /dev/null +++ b/web/src/beta/lib/unsafeBuiltinPlugins/types.ts @@ -0,0 +1,21 @@ +import type { FC } from "react"; + +export type UnsafeBuiltinPlugin = { + id: string; + name: string; + widgets?: UnsafeBuiltinWidget[]; + blocks?: UnsafeBuiltinBlock[]; +}; + +type UnsafeBuiltinWidget = UnsafeBuiltinPluginExtension<"widget">; + +type UnsafeBuiltinBlock = UnsafeBuiltinPluginExtension<"block">; + +type UnsafeBuiltinPluginExtension = { + type: T; + extensionId: string; + name: string; + component: FC; +}; + +export type UnsafeBuiltinWidgets = Record; diff --git a/web/src/services/config/index.ts b/web/src/services/config/index.ts index eba755cc9c..d6de88caa8 100644 --- a/web/src/services/config/index.ts +++ b/web/src/services/config/index.ts @@ -44,6 +44,7 @@ export type Config = { documentationUrl?: string; marketplaceUrl?: string; extensionUrls?: string[]; + unsafePluginUrls?: string[]; extensions?: Extensions; unsafeBuiltinPlugins?: UnsafeBuiltinPlugin[]; }; @@ -80,9 +81,9 @@ export default async function loadConfig() { config.extensions = extensions; } - config.unsafeBuiltinPlugins = loadUnsafeBuiltinPlugins(); - window.REEARTH_CONFIG = config; + + config.unsafeBuiltinPlugins = await loadUnsafeBuiltinPlugins(); } export function config(): Config | undefined { diff --git a/web/src/services/config/unsafeBuiltinPlugin.ts b/web/src/services/config/unsafeBuiltinPlugin.ts index 35a6941d10..2e8867abe8 100644 --- a/web/src/services/config/unsafeBuiltinPlugin.ts +++ b/web/src/services/config/unsafeBuiltinPlugin.ts @@ -1,22 +1,6 @@ -export type UnsafeBuiltinPlugin = { - id: string; - name: string; - widgets: UnsafeBuiltinWidget[]; - blocks: UnsafeBuiltinBlock[]; -}; +import type { UnsafeBuiltinPlugin } from "../../beta/lib/unsafeBuiltinPlugins"; -type UnsafeBuiltinWidget = UnsafeBuiltinPluginExtension<"widget">; - -type UnsafeBuiltinBlock = UnsafeBuiltinPluginExtension<"block">; - -type UnsafeBuiltinPluginExtension = { - type: T; - extensionId: string; - name: string; - component: React.FC; -}; - -export type UnsafeBuiltinWidgets = Record; +export type { UnsafeBuiltinPlugin } from "../../beta/lib/unsafeBuiltinPlugins"; export async function loadUnsafeBuiltinPlugins() { try { From f72e6dfd7a69e50dad6d4af24828b42a4f926f16 Mon Sep 17 00:00:00 2001 From: keiya01 Date: Tue, 8 Aug 2023 10:29:42 +0900 Subject: [PATCH 2/2] fix review --- .../beta/lib/unsafeBuiltinPlugins/README.md | 34 ------------- .../beta/lib/unsafeBuiltinPlugins/index.ts | 5 -- web/src/beta/lib/unsafeBuiltinPlugins/load.ts | 20 -------- .../beta/lib/unsafeBuiltinPlugins/types.ts | 21 -------- web/src/services/config/index.ts | 8 +-- .../services/config/unsafeBuiltinPlugin.ts | 51 +++++++++++++------ 6 files changed, 41 insertions(+), 98 deletions(-) delete mode 100644 web/src/beta/lib/unsafeBuiltinPlugins/README.md delete mode 100644 web/src/beta/lib/unsafeBuiltinPlugins/index.ts delete mode 100644 web/src/beta/lib/unsafeBuiltinPlugins/load.ts delete mode 100644 web/src/beta/lib/unsafeBuiltinPlugins/types.ts diff --git a/web/src/beta/lib/unsafeBuiltinPlugins/README.md b/web/src/beta/lib/unsafeBuiltinPlugins/README.md deleted file mode 100644 index cf9550e745..0000000000 --- a/web/src/beta/lib/unsafeBuiltinPlugins/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# *!!!! USE AT OWN RISK !!!!* -#### This folder is for any personal plugins you want to write but be treated as builtin, bypassing the sandboxing that happens to regularly installed plugins. - - -## Basic setup guide -### Server -You must add the URL that is hosting your unsafe builting plugin's YAML file to the server's environment variables `REEARTH_EXT_PLUGIN`. - -For example, you have `REEARTH_EXT_PLUGIN=https://example/com/myPlugin/reearth.yml`, add `REEARTH_EXT_PLUGIN=https://example/com/myPlugin` to your environment variables. - -### Frontend - -unsafeBuiltinPlugins - -Add your plugin code here in their own, plugin separated, directories. Import these in to the unsafeBuiltinPlugins/index.ts file. - -Plugin directory structure -- in the root directory have an index.jsx/tsx file that exports your plugin as default - -``` -type Extension = { - type: T; - extensionId: string; - name: string; - component: -} - -type Plugin = { - id: string; - name: string; - widgets: Extension<"widget">[]; - blocks: Extension<"block">[]; -} -``` \ No newline at end of file diff --git a/web/src/beta/lib/unsafeBuiltinPlugins/index.ts b/web/src/beta/lib/unsafeBuiltinPlugins/index.ts deleted file mode 100644 index ee23657566..0000000000 --- a/web/src/beta/lib/unsafeBuiltinPlugins/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { loadPlugins } from "./load"; - -export * from "./types"; - -export default await loadPlugins(); diff --git a/web/src/beta/lib/unsafeBuiltinPlugins/load.ts b/web/src/beta/lib/unsafeBuiltinPlugins/load.ts deleted file mode 100644 index d80d1fe6ca..0000000000 --- a/web/src/beta/lib/unsafeBuiltinPlugins/load.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { UnsafeBuiltinPlugin } from "./types"; - -export const loadPlugins = async () => { - const urls = window.REEARTH_CONFIG?.unsafePluginUrls; - return urls - ? ( - await Promise.all( - urls.map(async url => { - try { - const plugin: UnsafeBuiltinPlugin = (await import(/* @vite-ignore */ url)).default; - console.log("Hello", plugin); - return plugin; - } catch (e) { - throw new Error(`Specified unsafe built-in module could not find: ${url} ${e}`); - } - }), - ) - ).filter(Boolean) - : []; -}; diff --git a/web/src/beta/lib/unsafeBuiltinPlugins/types.ts b/web/src/beta/lib/unsafeBuiltinPlugins/types.ts deleted file mode 100644 index 1d60d0095e..0000000000 --- a/web/src/beta/lib/unsafeBuiltinPlugins/types.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { FC } from "react"; - -export type UnsafeBuiltinPlugin = { - id: string; - name: string; - widgets?: UnsafeBuiltinWidget[]; - blocks?: UnsafeBuiltinBlock[]; -}; - -type UnsafeBuiltinWidget = UnsafeBuiltinPluginExtension<"widget">; - -type UnsafeBuiltinBlock = UnsafeBuiltinPluginExtension<"block">; - -type UnsafeBuiltinPluginExtension = { - type: T; - extensionId: string; - name: string; - component: FC; -}; - -export type UnsafeBuiltinWidgets = Record; diff --git a/web/src/services/config/index.ts b/web/src/services/config/index.ts index d6de88caa8..60890e9335 100644 --- a/web/src/services/config/index.ts +++ b/web/src/services/config/index.ts @@ -61,7 +61,7 @@ declare global { export default async function loadConfig() { if (window.REEARTH_CONFIG) return; window.REEARTH_CONFIG = defaultConfig; - const config = { + const config: Config = { ...defaultConfig, ...(await (await fetch("/reearth_config.json")).json()), }; @@ -81,9 +81,11 @@ export default async function loadConfig() { config.extensions = extensions; } - window.REEARTH_CONFIG = config; + if (config.unsafePluginUrls) { + config.unsafeBuiltinPlugins = await loadUnsafeBuiltinPlugins(config.unsafePluginUrls); + } - config.unsafeBuiltinPlugins = await loadUnsafeBuiltinPlugins(); + window.REEARTH_CONFIG = config; } export function config(): Config | undefined { diff --git a/web/src/services/config/unsafeBuiltinPlugin.ts b/web/src/services/config/unsafeBuiltinPlugin.ts index 2e8867abe8..ddd6caa012 100644 --- a/web/src/services/config/unsafeBuiltinPlugin.ts +++ b/web/src/services/config/unsafeBuiltinPlugin.ts @@ -1,15 +1,36 @@ -import type { UnsafeBuiltinPlugin } from "../../beta/lib/unsafeBuiltinPlugins"; - -export type { UnsafeBuiltinPlugin } from "../../beta/lib/unsafeBuiltinPlugins"; - -export async function loadUnsafeBuiltinPlugins() { - try { - const unsafeBuiltinPlugins = ( - await import(/* @vite-ignore */ "src/beta/lib/unsafeBuiltinPlugins") - ).default as UnsafeBuiltinPlugin[]; - return unsafeBuiltinPlugins; - } catch (e) { - console.error("unsafe builtin plugin load failed", e); - } - return undefined; -} +import { FC } from "react"; + +export type UnsafeBuiltinPlugin = { + id: string; + name: string; + widgets?: UnsafeBuiltinWidget[]; + blocks?: UnsafeBuiltinBlock[]; +}; + +type UnsafeBuiltinWidget = UnsafeBuiltinPluginExtension<"widget">; + +type UnsafeBuiltinBlock = UnsafeBuiltinPluginExtension<"block">; + +type UnsafeBuiltinPluginExtension = { + type: T; + extensionId: string; + name: string; + component: FC; +}; + +export type UnsafeBuiltinWidgets = Record; + +export const loadUnsafeBuiltinPlugins = async (urls: string[]) => { + return ( + await Promise.all( + urls.map(async url => { + try { + const plugin: UnsafeBuiltinPlugin = (await import(/* @vite-ignore */ url)).default; + return plugin; + } catch (e) { + throw new Error(`Specified unsafe built-in module could not find: ${url} ${e}`); + } + }), + ) + ).filter(Boolean); +};