Storing some work in commit, currently broken, further work needed - application needs cleaned up.

This commit is contained in:
mike12345567 2020-11-23 14:07:18 +00:00
parent b63ca545bf
commit 90a8435641
13 changed files with 137 additions and 178 deletions

View File

@ -1,5 +1,5 @@
const CouchDB = require("../../db") const CouchDB = require("../../db")
const compileStaticAssetsForPage = require("../../utilities/builder/compileStaticAssetsForPage") const compileStaticAssets = require("../../utilities/builder/compileStaticAssets")
const env = require("../../environment") const env = require("../../environment")
const { existsSync } = require("fs-extra") const { existsSync } = require("fs-extra")
const { budibaseAppsDir } = require("../../utilities/budibaseDir") const { budibaseAppsDir } = require("../../utilities/budibaseDir")
@ -14,16 +14,16 @@ const {
generateAppID, generateAppID,
DocumentTypes, DocumentTypes,
SEPARATOR, SEPARATOR,
getPageParams, getLayoutParams,
getScreenParams, getScreenParams,
generatePageID, generateLayoutID,
generateScreenID, generateScreenID,
} = require("../../db/utils") } = require("../../db/utils")
const { BUILTIN_LEVEL_IDS } = require("../../utilities/security/accessLevels") const { BUILTIN_LEVEL_IDS } = require("../../utilities/security/accessLevels")
const { const {
downloadExtractComponentLibraries, downloadExtractComponentLibraries,
} = require("../../utilities/createAppPackage") } = require("../../utilities/createAppPackage")
const { MAIN, UNAUTHENTICATED, PageTypes } = require("../../constants/pages") const { MAIN, UNAUTHENTICATED, LayoutTypes } = require("../../constants/layouts")
const { HOME_SCREEN } = require("../../constants/screens") const { HOME_SCREEN } = require("../../constants/screens")
const { cloneDeep } = require("lodash/fp") const { cloneDeep } = require("lodash/fp")
@ -32,14 +32,14 @@ const APP_PREFIX = DocumentTypes.APP + SEPARATOR
// utility function, need to do away with this // utility function, need to do away with this
async function getMainAndUnauthPage(db) { async function getMainAndUnauthPage(db) {
let pages = await db.allDocs( let pages = await db.allDocs(
getPageParams(null, { getLayoutParams(null, {
include_docs: true, include_docs: true,
}) })
) )
pages = pages.rows.map(row => row.doc) pages = pages.rows.map(row => row.doc)
const mainPage = pages.find(page => page.name === PageTypes.MAIN) const mainPage = pages.find(page => page.name === LayoutTypes.MAIN)
const unauthPage = pages.find(page => page.name === PageTypes.UNAUTHENTICATED) const unauthPage = pages.find(page => page.name === LayoutTypes.UNAUTHENTICATED)
return { mainPage, unauthPage } return { mainPage, unauthPage }
} }
@ -194,11 +194,11 @@ const createEmptyAppPackage = async (ctx, app) => {
fs.mkdirpSync(newAppFolder) fs.mkdirpSync(newAppFolder)
const mainPage = cloneDeep(MAIN) const mainPage = cloneDeep(MAIN)
mainPage._id = generatePageID() mainPage._id = generateLayoutID()
mainPage.title = app.name mainPage.title = app.name
const unauthPage = cloneDeep(UNAUTHENTICATED) const unauthPage = cloneDeep(UNAUTHENTICATED)
unauthPage._id = generatePageID() unauthPage._id = generateLayoutID()
unauthPage.title = app.name unauthPage.title = app.name
unauthPage.props._children[0].title = `Log in to ${app.name}` unauthPage.props._children[0].title = `Log in to ${app.name}`
@ -206,14 +206,6 @@ const createEmptyAppPackage = async (ctx, app) => {
homeScreen._id = generateScreenID(mainPage._id) homeScreen._id = generateScreenID(mainPage._id)
await db.bulkDocs([mainPage, unauthPage, homeScreen]) await db.bulkDocs([mainPage, unauthPage, homeScreen])
await compileStaticAssetsForPage(app._id, "main", { await compileStaticAssets(app._id)
page: mainPage,
screens: [homeScreen],
})
await compileStaticAssetsForPage(app._id, "unauthenticated", {
page: unauthPage,
screens: [],
})
return newAppFolder return newAppFolder
} }

View File

@ -136,25 +136,21 @@ exports.uploadAppAssets = async function({ appId, bucket, accountId }) {
const appAssetsPath = join(budibaseAppsDir(), appId, "public") const appAssetsPath = join(budibaseAppsDir(), appId, "public")
const appPages = fs.readdirSync(appAssetsPath)
let uploads = [] let uploads = []
for (let page of appPages) { // Upload HTML, CSS and JS of the web app
// Upload HTML, CSS and JS for each page of the web app walkDir(appAssetsPath, function(filePath) {
walkDir(join(appAssetsPath, page), function(filePath) { const appAssetUpload = prepareUploadForS3({
const appAssetUpload = prepareUploadForS3({ file: {
file: { path: filePath,
path: filePath, name: [...filePath.split("/")].pop(),
name: [...filePath.split("/")].pop(), },
}, s3Key: filePath.replace(appAssetsPath, `assets/${appId}`),
s3Key: filePath.replace(appAssetsPath, `assets/${appId}`), s3,
s3, metadata: { accountId },
metadata: { accountId },
})
uploads.push(appAssetUpload)
}) })
} uploads.push(appAssetUpload)
})
// Upload file attachments // Upload file attachments
const db = new PouchDB(appId) const db = new PouchDB(appId)

View File

@ -0,0 +1,15 @@
const CouchDB = require("../../db/client")
const { generateLayoutID } = require("../../db/utils")
const compileStaticAssets = require("../../utilities/builder/compileStaticAssets")
exports.save = async function(ctx) {
const db = new CouchDB(ctx.user.appId)
const appPackage = ctx.request.body
// remove special doc props which couch will complain about
delete appPackage.layout._css
appPackage.layout._id = appPackage.layout._id || generateLayoutID()
ctx.body = await db.put(appPackage.layout)
await compileStaticAssets(ctx.user.appId)
ctx.status = 200
}

View File

@ -1,19 +0,0 @@
const CouchDB = require("../../db/client")
const { generatePageID } = require("../../db/utils")
const compileStaticAssetsForPage = require("../../utilities/builder/compileStaticAssetsForPage")
exports.save = async function(ctx) {
const db = new CouchDB(ctx.user.appId)
const appPackage = ctx.request.body
const page = await db.get(ctx.params.pageId)
await compileStaticAssetsForPage(ctx.user.appId, page.name, ctx.request.body)
// remove special doc props which couch will complain about
delete appPackage.page._css
delete appPackage.page._screens
appPackage.page._id = appPackage.page._id || generatePageID()
ctx.body = await db.put(appPackage.page)
ctx.status = 200
}

View File

@ -142,15 +142,11 @@ exports.performLocalFileProcessing = async function(ctx) {
exports.serveApp = async function(ctx) { exports.serveApp = async function(ctx) {
const App = require("./templates/BudibaseApp.svelte").default const App = require("./templates/BudibaseApp.svelte").default
const db = new CouchDB(ctx.params.appId) const db = new CouchDB(ctx.params.appId)
const appInfo = await db.get(ctx.params.appId) const appInfo = await db.get(ctx.params.appId)
const { head, html, css } = App.render({ const { head, html, css } = App.render({
title: appInfo.name, title: appInfo.name,
pageName:
ctx.auth.authenticated === AuthTypes.APP ? "main" : "unauthenticated",
production: env.CLOUD, production: env.CLOUD,
appId: ctx.params.appId, appId: ctx.params.appId,
}) })

View File

@ -3,14 +3,13 @@
export let favicon = "" export let favicon = ""
export let appId export let appId
export let pageName = ""
export let production export let production
export const PRODUCTION_ASSETS_URL = `https://${appId}.app.budi.live` export const PRODUCTION_ASSETS_URL = `https://${appId}.app.budi.live`
function publicPath(path) { function publicPath(path) {
if (production) { if (production) {
return `${PRODUCTION_ASSETS_URL}/assets/${appId}/${pageName}/${path}` return `${PRODUCTION_ASSETS_URL}/assets/${appId}/${path}`
} }
return `/assets/${path}` return `/assets/${path}`

View File

@ -1,5 +1,5 @@
const authRoutes = require("./auth") const authRoutes = require("./auth")
const pageRoutes = require("./pages") const layoutRoutes = require("./layout")
const screenRoutes = require("./screen") const screenRoutes = require("./screen")
const userRoutes = require("./user") const userRoutes = require("./user")
const applicationRoutes = require("./application") const applicationRoutes = require("./application")
@ -19,7 +19,7 @@ const routingRoutes = require("./routing")
exports.mainRoutes = [ exports.mainRoutes = [
deployRoutes, deployRoutes,
pageRoutes, layoutRoutes,
screenRoutes, screenRoutes,
userRoutes, userRoutes,
applicationRoutes, applicationRoutes,

View File

@ -1,10 +1,10 @@
const Router = require("@koa/router") const Router = require("@koa/router")
const authorized = require("../../middleware/authorized") const authorized = require("../../middleware/authorized")
const { BUILDER } = require("../../utilities/security/permissions") const { BUILDER } = require("../../utilities/security/permissions")
const controller = require("../controllers/page") const controller = require("../controllers/layout")
const router = Router() const router = Router()
router.post("/api/pages/:pageId", authorized(BUILDER), controller.save) router.post("/api/layouts/:layoutId", authorized(BUILDER), controller.save)
module.exports = router module.exports = router

View File

@ -17,7 +17,6 @@ const AUTOMATION_ID = generateAutomationID()
const TEST_AUTOMATION = { const TEST_AUTOMATION = {
_id: AUTOMATION_ID, _id: AUTOMATION_ID,
name: "My Automation", name: "My Automation",
pageId: "123123123",
screenId: "kasdkfldsafkl", screenId: "kasdkfldsafkl",
live: true, live: true,
uiTree: { uiTree: {

View File

@ -1,4 +1,4 @@
const PageTypes = { const LayoutTypes = {
MAIN: "main", MAIN: "main",
UNAUTHENTICATED: "unauthenticated", UNAUTHENTICATED: "unauthenticated",
} }
@ -8,7 +8,7 @@ const MAIN = {
title: "{{ name }}", title: "{{ name }}",
favicon: "./_shared/favicon.png", favicon: "./_shared/favicon.png",
stylesheets: [], stylesheets: [],
name: PageTypes.MAIN, name: LayoutTypes.MAIN,
props: { props: {
_id: "private-master-root", _id: "private-master-root",
_component: "@budibase/standard-components/container", _component: "@budibase/standard-components/container",
@ -153,7 +153,7 @@ const UNAUTHENTICATED = {
title: "{{ name }}", title: "{{ name }}",
favicon: "./_shared/favicon.png", favicon: "./_shared/favicon.png",
stylesheets: [], stylesheets: [],
name: PageTypes.UNAUTHENTICATED, name: LayoutTypes.UNAUTHENTICATED,
props: { props: {
_id: "public-master-root", _id: "public-master-root",
_component: "@budibase/standard-components/container", _component: "@budibase/standard-components/container",
@ -218,4 +218,4 @@ const UNAUTHENTICATED = {
}, },
} }
module.exports = { MAIN, UNAUTHENTICATED, PageTypes } module.exports = { MAIN, UNAUTHENTICATED, LayoutTypes }

View File

@ -13,7 +13,7 @@ const DocumentTypes = {
ACCESS_LEVEL: "ac", ACCESS_LEVEL: "ac",
WEBHOOK: "wh", WEBHOOK: "wh",
INSTANCE: "inst", INSTANCE: "inst",
PAGE: "page", LAYOUT: "layout",
SCREEN: "screen", SCREEN: "screen",
} }
@ -180,18 +180,18 @@ exports.getAccessLevelParams = (accessLevelId = null, otherProps = {}) => {
} }
/** /**
* Generates a new page ID. * Generates a new layout ID.
* @returns {string} The new page ID which the page doc can be stored under. * @returns {string} The new layout ID which the layout doc can be stored under.
*/ */
exports.generatePageID = () => { exports.generateLayoutID = () => {
return `${DocumentTypes.PAGE}${SEPARATOR}${newid()}` return `${DocumentTypes.LAYOUT}${SEPARATOR}${newid()}`
} }
/** /**
* Gets parameters for retrieving pages, this is a utility function for the getDocParams function. * Gets parameters for retrieving layout, this is a utility function for the getDocParams function.
*/ */
exports.getPageParams = (pageId = null, otherProps = {}) => { exports.getLayoutParams = (layoutId = null, otherProps = {}) => {
return getDocParams(DocumentTypes.PAGE, pageId, otherProps) return getDocParams(DocumentTypes.LAYOUT, layoutId, otherProps)
} }
/** /**

View File

@ -0,0 +1,83 @@
const { ensureDir, constants, copyFile, writeFile } = require("fs-extra")
const { join } = require("../centralPath")
const { budibaseAppsDir } = require("../budibaseDir")
const CouchDB = require("../../db")
const { getScreenParams, getLayoutParams } = require("../../db/utils")
async function getAppPackage(appId) {
const db = new CouchDB(appId)
let params = {
include_docs: true,
}
let [screens, layouts] = await Promise.all([
db.allDocs(getScreenParams(null, params)),
db.allDocs(getLayoutParams(null, params)),
])
screens = screens.rows.map(row => row.doc)
layouts = layouts.rows.map(row => row.doc)
if (!screens) {
screens = []
}
if (!layouts) {
layouts = []
}
return { screens, layouts }
}
/**
* Compile all the non-db static web assets that are required for the running of
* a budibase application. This includes CSS, the JSON structure of the DOM and
* the client library, a script responsible for reading the JSON structure
* and rendering the application.
* @param {string} appId - id of the application we want to compile static assets for
*/
module.exports = async appId => {
const publicPath = join(budibaseAppsDir(), appId, "public")
const pkg = await getAppPackage(appId)
await ensureDir(publicPath)
await buildCssBundle(publicPath, pkg)
await copyClientLib(publicPath)
}
/**
* Reads the _css property of all screens and the screen layouts, and creates a singular CSS
* bundle for the app at <appId>/public/bundle.css
* @param {String} publicPath - path to the public assets directory of the budibase application
* @param {Object} pkg - app package information
*/
const buildCssBundle = async (publicPath, pkg) => {
let cssString = ""
for (let screen of pkg.screens || []) {
if (!screen._css) continue
if (screen._css.trim().length === 0) {
delete screen._css
continue
}
cssString += screen._css
}
if (pkg.layout._css) cssString += pkg.layout._css
writeFile(join(publicPath, "bundle.css"), cssString)
}
/**
* Copy the budibase client library and sourcemap from NPM to <appId>/public/.
* The client library is then served as a static asset when the budibase application
* is running in preview or prod
* @param {String} publicPath - path to write the client library to
*/
const copyClientLib = async publicPath => {
const sourcepath = require.resolve("@budibase/client")
const destPath = join(publicPath, "budibase-client.js")
await copyFile(sourcepath, destPath, constants.COPYFILE_FICLONE)
await copyFile(
sourcepath + ".map",
destPath + ".map",
constants.COPYFILE_FICLONE
)
}

View File

@ -1,102 +0,0 @@
const { ensureDir, constants, copyFile, writeFile } = require("fs-extra")
const { join } = require("../centralPath")
const { budibaseAppsDir } = require("../budibaseDir")
/**
* Compile all the non-db static web assets that are required for the running of
* a budibase application. This includes CSS, the JSON structure of the DOM and
* the client library, a script responsible for reading the JSON structure
* and rendering the application.
* @param {} appId - id of the application we want to compile static assets for
* @param {*} pageName - name of the page that the assets will be served for
* @param {*} pkg - app package information/metadata
*/
module.exports = async (appId, pageName, pkg) => {
const pagePath = join(budibaseAppsDir(), appId, "public", pageName)
pkg.screens = pkg.screens || []
await ensureDir(pagePath)
await buildPageCssBundle(pagePath, pkg)
await buildFrontendAppDefinition(pagePath, pkg)
await copyClientLib(pagePath)
}
/**
* Reads the _css property of a page and its screens, and creates a singular CSS
* bundle for the page at <appId>/public/<pageName>/bundle.css
* @param {String} publicPagePath - path to the public assets directory of the budibase application
* @param {Object} pkg - app package information
* @param {"main" | "unauthenticated"} pageName - the pagename of the page we are compiling CSS for.
*/
const buildPageCssBundle = async (publicPagePath, pkg) => {
let cssString = ""
for (let screen of pkg.screens || []) {
if (!screen._css) continue
if (screen._css.trim().length === 0) {
delete screen._css
continue
}
cssString += screen._css
}
if (pkg.page._css) cssString += pkg.page._css
writeFile(join(publicPagePath, "bundle.css"), cssString)
}
/**
* Copy the budibase client library and sourcemap from NPM to <appId>/public/<pageName>.
* The client library is then served as a static asset when the budibase application
* is running in preview or prod
* @param {String} pagePath - path to write the client library to
*/
const copyClientLib = async pagePath => {
const sourcepath = require.resolve("@budibase/client")
const destPath = join(pagePath, "budibase-client.js")
await copyFile(sourcepath, destPath, constants.COPYFILE_FICLONE)
await copyFile(
sourcepath + ".map",
destPath + ".map",
constants.COPYFILE_FICLONE
)
}
/**
* Build the frontend definition for a budibase application. This includes all page and screen information,
* and is injected into the budibase client library to tell it how to start constructing
* the DOM from components defined in the frontendDefinition.
* @param {String} pagePath - path to the public folder of the page where the definition will be written
* @param {Object} pkg - app package information from which the frontendDefinition will be built.
*/
const buildFrontendAppDefinition = async (pagePath, pkg) => {
const filename = join(pagePath, "clientFrontendDefinition.js")
// Delete CSS code from the page and screens so it's not injected
delete pkg.page._css
for (let screen of pkg.screens) {
if (screen._css) {
delete pkg.page._css
}
}
const clientUiDefinition = JSON.stringify({
page: pkg.page,
screens: pkg.screens,
libraries: ["@budibase/standard-components"],
})
await writeFile(
filename,
`
window['##BUDIBASE_FRONTEND_DEFINITION##'] = ${clientUiDefinition};
`
)
}