diff --git a/packages/backend-core/src/objectStore/index.ts b/packages/backend-core/src/objectStore/index.ts index fe9be90659..774018b6df 100644 --- a/packages/backend-core/src/objectStore/index.ts +++ b/packages/backend-core/src/objectStore/index.ts @@ -178,6 +178,14 @@ export const streamUpload = async ( const objectStore = ObjectStore(bucketName) await makeSureBucketExists(objectStore, bucketName) + // Set content type for certain known extensions + if (filename?.endsWith(".js")) { + extra = { + ...extra, + ContentType: "application/javascript", + } + } + const params = { Bucket: sanitizeBucket(bucketName), Key: sanitizeKey(filename), diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js index 7903210f53..16d16de8a2 100644 --- a/packages/builder/src/builderStore/store/frontend.js +++ b/packages/builder/src/builderStore/store/frontend.js @@ -90,36 +90,14 @@ export const getFrontendStore = () => { // Fetch component definitions. // Allow errors to propagate. - let components = await API.fetchComponentLibDefinitions(application.appId) - - // Extend definitions with custom components - components["test"] = { - component: "test", - name: "Super cool component", - icon: "Text", - description: "A custom component", - showSettingsBar: false, - hasChildren: true, - settings: [ - { - type: "text", - key: "text", - label: "Text", - }, - ], - context: { - type: "static", - values: [ - { - label: "Text prop", - key: "text", - }, - ], - }, - } + const components = await API.fetchComponentLibDefinitions( + application.appId + ) // Filter out custom component keys so we can flag them - let customComponents = ["test"] + const customComponents = Object.keys(components).filter(name => + name.startsWith("plugin/") + ) // Reset store state store.update(state => ({ @@ -146,6 +124,7 @@ export const getFrontendStore = () => { version: application.version, revertableVersion: application.revertableVersion, navigation: application.navigation || {}, + usedPlugins: application.usedPlugins || [], })) // Initialise backend stores diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte index 3c99c90d49..cd86d2e87c 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/AppPreview.svelte @@ -41,10 +41,23 @@ } // Construct iframe template - $: template = iframeTemplate.replace( - /\{\{ CLIENT_LIB_PATH }}/, - $store.clientLibPath - ) + $: pluginLinks = generatePluginLinks($store.usedPlugins) + $: template = iframeTemplate + .replace(/\{\{ CLIENT_LIB_PATH }}/, $store.clientLibPath) + .replace(/\{\{ PLUGINS }}/, pluginLinks) + + const generatePluginLinks = plugins => { + if (!plugins?.length) { + return "" + } + return plugins + .map(plugin => { + // Split up like this as otherwise parsing fails because the script + // tags confuse svelte + return `<` + `script src="/plugins/${plugin.jsUrl}">` + }) + .join("") + } const placeholderScreen = new Screen() .name("Screen Placeholder") @@ -92,6 +105,7 @@ ? [$store.componentToPaste?._id] : [], isBudibaseEvent: true, + usedPlugins: $store.usedPlugins, } // Refresh the preview when required diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/iframeTemplate.js b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/iframeTemplate.js index 64a05c7246..2b24ee4fa0 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/iframeTemplate.js +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/iframeTemplate.js @@ -37,9 +37,7 @@ export default ` } - + {{ PLUGINS }} @@ -85,9 +86,13 @@ - + {#if usedPlugins?.length} + {#each usedPlugins as plugin} + + {/each} + {/if}