UNPKG

2.52 kBJavaScriptView Raw
1const Endpoint = require('cubic-api/endpoint')
2const util = require('util')
3const fs = require('fs')
4const readFile = util.promisify(fs.readFile)
5const path = require('path')
6const publicPath = `${cubic.config.ui.api.publicPath}/bundles`
7const createBundleRenderer = require('vue-server-renderer').createBundleRenderer
8const { promisify } = require('util')
9const fileExists = promisify(fs.lstat)
10const Client = require('cubic-client')
11const user = cubic.nodes.auth ? cubic.nodes.auth.api.systemUser : {}
12
13// Server-sided cubic-api client for initial response.
14let api
15if (!cubic.config.ui.client.disableSsr) {
16 api = new Client({
17 api_url: cubic.config.ui.server.apiUrl,
18 auth_url: cubic.config.ui.server.authUrl,
19 user_key: user.user_key || cubic.config.ui.server.user_key,
20 user_secret: user.user_secret || cubic.config.ui.server.user_secret
21 })
22}
23
24/**
25 * One-time check, so we wouldn't read from disk on every request
26 */
27let bundlesReady = false
28async function awaitBundles () {
29 return new Promise(async resolve => {
30 try {
31 await fileExists(`${publicPath}/vue-ssr-client-manifest.json`)
32 await fileExists(`${publicPath}/vue-ssr-server-bundle.json`)
33 bundlesReady = true
34 resolve()
35 } catch (err) {
36 setTimeout(async () => {
37 resolve(await awaitBundles())
38 }, 500)
39 }
40 })
41}
42
43/**
44 * Overrides original endpoint. This one only adds the view key to the schema
45 * and renders it in the main function by default, since that's what all normal
46 * pages do.
47 */
48class View extends Endpoint {
49 /**
50 * Just render the given view if no other instructions are given.
51 */
52 async main (req, res) {
53 res.setHeader('content-type', 'text/html')
54 return res.send(await this.render(req))
55 }
56
57 /**
58 * Render page with Vue.js
59 */
60 async render (req) {
61 if (!bundlesReady) await awaitBundles()
62 const serverBundle = require(path.join(publicPath, 'vue-ssr-server-bundle.json'))
63 const clientManifest = require(path.join(publicPath, 'vue-ssr-client-manifest.json'))
64 const template = await readFile(path.join(__dirname, './vue/index.template.html'), 'utf-8')
65 const renderer = createBundleRenderer(serverBundle, {
66 template,
67 clientManifest,
68 runInNewContext: false
69 })
70 const render = util.promisify(renderer.renderToString)
71 const context = { req, api }
72 const html = await render(context)
73 this.cache(html, cubic.config.ui.api.cacheExp, { 'content-type': 'text/html' })
74 return html
75 }
76}
77
78module.exports = View