forked from tsai/budibase
13 changed files with 137 additions and 178 deletions
@ -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 |
|||
} |
|||
@ -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 |
|||
} |
|||
@ -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 |
|||
@ -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 |
|||
) |
|||
} |
|||
@ -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}; |
|||
` |
|||
) |
|||
} |
|||
Loading…
Reference in new issue