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 d8b794cb97
commit 8ae24a4b30
13 changed files with 137 additions and 178 deletions

View File

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

View File

@ -136,25 +136,21 @@ exports.uploadAppAssets = async function({ appId, bucket, accountId }) {
const appAssetsPath = join(budibaseAppsDir(), appId, "public")
const appPages = fs.readdirSync(appAssetsPath)
let uploads = []
for (let page of appPages) {
// Upload HTML, CSS and JS for each page of the web app
walkDir(join(appAssetsPath, page), function(filePath) {
const appAssetUpload = prepareUploadForS3({
file: {
path: filePath,
name: [...filePath.split("/")].pop(),
},
s3Key: filePath.replace(appAssetsPath, `assets/${appId}`),
s3,
metadata: { accountId },
})
uploads.push(appAssetUpload)
// Upload HTML, CSS and JS of the web app
walkDir(appAssetsPath, function(filePath) {
const appAssetUpload = prepareUploadForS3({
file: {
path: filePath,
name: [...filePath.split("/")].pop(),
},
s3Key: filePath.replace(appAssetsPath, `assets/${appId}`),
s3,
metadata: { accountId },
})
}
uploads.push(appAssetUpload)
})
// Upload file attachments
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) {
const App = require("./templates/BudibaseApp.svelte").default
const db = new CouchDB(ctx.params.appId)
const appInfo = await db.get(ctx.params.appId)
const { head, html, css } = App.render({
title: appInfo.name,
pageName:
ctx.auth.authenticated === AuthTypes.APP ? "main" : "unauthenticated",
production: env.CLOUD,
appId: ctx.params.appId,
})

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
const PageTypes = {
const LayoutTypes = {
MAIN: "main",
UNAUTHENTICATED: "unauthenticated",
}
@ -8,7 +8,7 @@ const MAIN = {
title: "{{ name }}",
favicon: "./_shared/favicon.png",
stylesheets: [],
name: PageTypes.MAIN,
name: LayoutTypes.MAIN,
props: {
_id: "private-master-root",
_component: "@budibase/standard-components/container",
@ -153,7 +153,7 @@ const UNAUTHENTICATED = {
title: "{{ name }}",
favicon: "./_shared/favicon.png",
stylesheets: [],
name: PageTypes.UNAUTHENTICATED,
name: LayoutTypes.UNAUTHENTICATED,
props: {
_id: "public-master-root",
_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",
WEBHOOK: "wh",
INSTANCE: "inst",
PAGE: "page",
LAYOUT: "layout",
SCREEN: "screen",
}
@ -180,18 +180,18 @@ exports.getAccessLevelParams = (accessLevelId = null, otherProps = {}) => {
}
/**
* Generates a new page ID.
* @returns {string} The new page ID which the page doc can be stored under.
* Generates a new layout ID.
* @returns {string} The new layout ID which the layout doc can be stored under.
*/
exports.generatePageID = () => {
return `${DocumentTypes.PAGE}${SEPARATOR}${newid()}`
exports.generateLayoutID = () => {
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 = {}) => {
return getDocParams(DocumentTypes.PAGE, pageId, otherProps)
exports.getLayoutParams = (layoutId = null, 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};
`
)
}