diff --git a/packages/builder/rollup.config.js b/packages/builder/rollup.config.js index aaca6e3c8f..5a607720d8 100644 --- a/packages/builder/rollup.config.js +++ b/packages/builder/rollup.config.js @@ -18,7 +18,12 @@ const _builderProxy = proxy("/_builder", { }) const apiProxy = proxy( - ["/_builder/assets/**", "/_builder/api/**", "/_builder/**/componentlibrary"], + [ + "/_builder/assets/**", + "/_builder/api/**", + "/_builder/**/componentlibrary", + "/_builder/instance/**", + ], { target, logLevel: "debug", diff --git a/packages/builder/src/builderStore/loadComponentLibraries.js b/packages/builder/src/builderStore/loadComponentLibraries.js index e844ba77de..5a142f2798 100644 --- a/packages/builder/src/builderStore/loadComponentLibraries.js +++ b/packages/builder/src/builderStore/loadComponentLibraries.js @@ -32,3 +32,24 @@ export const makeLibraryUrl = (appName, lib) => export const libsFromPages = pages => pipe(pages, [values, map(p => p.componentLibraries), flatten, uniq]) + +export const libUrlsForPreview = (appPackage, pageName) => { + const resolve = path => { + let file = appPackage.components.libraryPaths[path] + if (file.startsWith("./")) file = file.substring(2) + if (file.startsWith("/")) file = file.substring(1) + + let newPath = path + + if (!newPath.startsWith("./") && !newPath.startsWith("/")) { + newPath = `/node_modules/${path}` + } + + return { + importPath: `/lib${newPath}/${file}`, + libName: path, + } + } + + return pipe([appPackage.pages[pageName]], [libsFromPages, map(resolve)]) +} diff --git a/packages/builder/src/builderStore/store.js b/packages/builder/src/builderStore/store.js index 1653cdb6dd..7753fa255d 100644 --- a/packages/builder/src/builderStore/store.js +++ b/packages/builder/src/builderStore/store.js @@ -29,7 +29,7 @@ import { getBuiltin, } from "../userInterface/pagesParsing/createProps" import { expandComponentDefinition } from "../userInterface/pagesParsing/types" -import { loadLibs, loadLibUrls } from "./loadComponentLibraries" +import { loadLibs, libUrlsForPreview } from "./loadComponentLibraries" import { buildCodeForScreens } from "./buildCodeForScreens" import { generate_screen_css } from "./generate_css" import { insertCodeMetadata } from "./insertCodeMetadata" @@ -153,9 +153,16 @@ const initialise = (store, initial) => async () => { } initial.libraries = await loadLibs(appname, pkg) - initial.loadLibraryUrls = () => loadLibUrls(appname, pkg) + initial.loadLibraryUrls = pageName => { + const libs = libUrlsForPreview(pkg, pageName) + return libs + } initial.appname = appname initial.pages = pkg.pages + initial.currentInstanceId = + pkg.application.instances && pkg.application.instances.length > 0 + ? pkg.application.instances[0].id + : "" initial.hasAppPackage = true initial.hierarchy = pkg.appDefinition.hierarchy initial.accessLevels = pkg.accessLevels diff --git a/packages/builder/src/userInterface/CurrentItemPreview.svelte b/packages/builder/src/userInterface/CurrentItemPreview.svelte index 7b27a6cb75..429534ceb4 100644 --- a/packages/builder/src/userInterface/CurrentItemPreview.svelte +++ b/packages/builder/src/userInterface/CurrentItemPreview.svelte @@ -30,7 +30,7 @@ ) $: frontendDefinition = { - componentLibraries: $store.loadLibraryUrls(), + componentLibraries: $store.loadLibraryUrls($store.currentPageName), page: $store.currentPreviewItem, screens: [{ name: "Screen Placeholder", @@ -63,7 +63,7 @@ ] } }], - appRootPath: "", + appRootPath: `/_builder/instance/${$store.appname}/${$store.currentInstanceId}/`, } $: backendDefinition = { diff --git a/packages/server/middleware/routeHandlers/appDefault.js b/packages/server/middleware/routeHandlers/appDefault.js index 61dd9520de..6bbb352abf 100644 --- a/packages/server/middleware/routeHandlers/appDefault.js +++ b/packages/server/middleware/routeHandlers/appDefault.js @@ -1,7 +1,9 @@ +const { getAppRelativePath } = require("./helpers") + const send = require("koa-send") module.exports = async (ctx, next) => { - const path = ctx.path.replace(`/${ctx.params.appname}`, "") + const path = getAppRelativePath(ctx.params.appname, ctx.path) if (path.startsWith("/api/")) { await next() diff --git a/packages/server/middleware/routeHandlers/helpers.js b/packages/server/middleware/routeHandlers/helpers.js index 22a29d3d84..92995fb7e6 100644 --- a/packages/server/middleware/routeHandlers/helpers.js +++ b/packages/server/middleware/routeHandlers/helpers.js @@ -1,7 +1,15 @@ exports.getRecordKey = (appname, wholePath) => - wholePath - .replace(`/${appname}/api/files/`, "") - .replace(`/${appname}/api/lookup_field/`, "") - .replace(`/${appname}/api/record/`, "") - .replace(`/${appname}/api/listRecords/`, "") - .replace(`/${appname}/api/aggregates/`, "") + this.getAppRelativePath(appname, wholePath) + .replace(`/api/files/`, "/") + .replace(`/api/lookup_field/`, "/") + .replace(`/api/record/`, "/") + .replace(`/api/listRecords/`, "/") + .replace(`/api/aggregates/`, "/") + +exports.getAppRelativePath = (appname, wholePath) => { + const builderInstanceRegex = new RegExp( + `\\/_builder\\/instance\\/[^\\/]*\\/[^\\/]*\\/` + ) + + return wholePath.replace(builderInstanceRegex, "/").replace(`/${appname}`, "") +} diff --git a/packages/server/middleware/routers.js b/packages/server/middleware/routers.js index 2933ca0a55..dd77706f5f 100644 --- a/packages/server/middleware/routers.js +++ b/packages/server/middleware/routers.js @@ -46,15 +46,29 @@ module.exports = (config, app) => { } if (ctx.path.startsWith("/_builder/instance/_master")) { - ctx.instance = ctx.master.getFullAccessApiForMaster() + const { + instance, + publicPath, + sharedPath, + } = await ctx.master.getFullAccessApiForMaster() + ctx.instance = instance + ctx.publicPath = publicPath + ctx.sharedPath = sharedPath ctx.isAuthenticated = !!ctx.instance } else if (ctx.path.startsWith("/_builder/instance")) { const builderAppName = pathParts[3] const instanceId = pathParts[4] - ctx.instance = ctx.master.getFullAccessApiForInstanceId( + const { + bbInstance, + publicPath, + sharedPath, + } = await ctx.master.getFullAccessApiForInstanceId( builderAppName, instanceId - ).bbInstance + ) + ctx.instance = bbInstance + ctx.publicPath = publicPath + ctx.sharedPath = sharedPath ctx.isAuthenticated = !!ctx.instance } @@ -87,7 +101,7 @@ module.exports = (config, app) => { .get("/_builder/*", async (ctx, next) => { const path = ctx.path.replace("/_builder", "") - if (path.startsWith("/api/")) { + if (path.startsWith("/api/") || path.startsWith("/instance/")) { await next() } else { await send(ctx, path, { root: builderPath }) diff --git a/packages/server/utilities/builder/index.js b/packages/server/utilities/builder/index.js index 4dcdefa32b..26daf8aa87 100644 --- a/packages/server/utilities/builder/index.js +++ b/packages/server/utilities/builder/index.js @@ -147,17 +147,19 @@ const getComponentDefinitions = async (appPath, pages, componentLibrary) => { const components = {} const templates = {} + const libraryPaths = {} for (let library of componentLibraries) { const info = await componentLibraryInfo(appPath, library) merge(components, info.components) merge(templates, info.templates) + libraryPaths[library] = components._lib } if (components._lib) delete components._lib if (templates._lib) delete templates._lib - return { components, templates } + return { components, templates, libraryPaths } } module.exports.getComponentDefinitions = getComponentDefinitions diff --git a/packages/server/utilities/masterAppInternal.js b/packages/server/utilities/masterAppInternal.js index 462e628d59..88a7bdfb75 100644 --- a/packages/server/utilities/masterAppInternal.js +++ b/packages/server/utilities/masterAppInternal.js @@ -156,7 +156,8 @@ module.exports = async context => { const getFullAccessApiForInstanceId = async (appname, instanceId, appId) => { if (!appId) { - appId = (await getApplication(appname)).id + const app = await getApplication(appname) + appId = app.id } const instanceKey = `/applications/${appId}/instances/${instanceId}` const instance = await bb.recordApi.load(instanceKey) @@ -172,15 +173,25 @@ module.exports = async context => { ) return { bbInstance: await getApisWithFullAccess( - datastoreModule.getDatastore(dsConfig), + getInstanceDatastore(dsConfig), appPackage ), instance, + publicPath: appPackage.mainUiPath, + sharedPath: appPackage.sharedPath, } } - const getFullAccessApiForMaster = async () => - await getApisWithFullAccess(masterDatastore, masterAppPackage(context)) + const getFullAccessApiForMaster = async () => { + const masterPkg = masterAppPackage(context) + const instance = await getApisWithFullAccess(masterDatastore, masterPkg) + + return { + instance, + publicPath: masterPkg.unauthenticatedUiPath, + sharedPath: masterPkg.sharedPath, + } + } const getInstanceApiForSession = async (appname, sessionId) => { if (isMaster(appname)) {