mirror of
https://github.com/wassname/talk.git
synced 2026-06-29 04:45:23 +08:00
117 lines
2.9 KiB
JavaScript
117 lines
2.9 KiB
JavaScript
const SettingsService = require('../services/settings');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { merge } = require('lodash');
|
|
|
|
const {
|
|
BASE_URL,
|
|
BASE_PATH,
|
|
MOUNT_PATH,
|
|
STATIC_URL,
|
|
STATIC_ORIGIN,
|
|
} = require('../url');
|
|
|
|
const { RECAPTCHA_PUBLIC, WEBSOCKET_LIVE_URI } = require('../config');
|
|
|
|
// Grab TALK_CLIENT_* environment variables.
|
|
const TALK_CLIENT = /^TALK_CLIENT_/i;
|
|
|
|
// TALK_CLIENT_ENV is all the environment keys that are loaded at runtime.
|
|
const TALK_CLIENT_ENV = Object.keys(process.env)
|
|
.filter(key => TALK_CLIENT.test(key))
|
|
.reduce(
|
|
(env, key) => {
|
|
env[key] = process.env[key];
|
|
return env;
|
|
},
|
|
{
|
|
TALK_RECAPTCHA_PUBLIC: RECAPTCHA_PUBLIC,
|
|
LIVE_URI: WEBSOCKET_LIVE_URI,
|
|
STATIC_URL,
|
|
STATIC_ORIGIN,
|
|
}
|
|
);
|
|
|
|
// TEMPLATE_LOCALS stores the static data that is provided as a `text/json` on
|
|
// to the client from the template.
|
|
const TEMPLATE_LOCALS = {
|
|
BASE_URL,
|
|
BASE_PATH,
|
|
MOUNT_PATH,
|
|
STATIC_URL,
|
|
TALK_CLIENT_ENV,
|
|
data: TALK_CLIENT_ENV,
|
|
};
|
|
|
|
// attachStaticLocals will attach the locals to the response only.
|
|
const attachStaticLocals = locals => {
|
|
for (const key in TEMPLATE_LOCALS) {
|
|
const value = TEMPLATE_LOCALS[key];
|
|
|
|
locals[key] = value;
|
|
}
|
|
};
|
|
|
|
// MANIFESTS are all the manifests accessible by Talk.
|
|
const MANIFESTS = ['../dist/manifest.json', '../dist/manifest.embed.json'];
|
|
|
|
// getManifest will retrieve the manifest files and parse the JSON.
|
|
function getManifest() {
|
|
return merge(
|
|
{},
|
|
...MANIFESTS.map(f =>
|
|
fs.readFileSync(path.resolve(__dirname, f), 'utf8')
|
|
).map(JSON.parse)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* resolveFactory is a function that can be used in templates to resolve an
|
|
* asset from the manifest. In production, the manifest is cached.
|
|
*/
|
|
const createResolveFactory = (() => {
|
|
if (process.env.NODE_ENV === 'production') {
|
|
// In production, we should attempt to load the manifest early.
|
|
const manifest = getManifest();
|
|
|
|
return () => key => `${STATIC_URL}static/${manifest[key]}`;
|
|
}
|
|
|
|
// In dev mode, we are more forgiving and we always load the
|
|
// newest version of the manifest.
|
|
return () => {
|
|
let manifest = {};
|
|
try {
|
|
manifest = getManifest();
|
|
} catch (err) {
|
|
console.warn(err);
|
|
}
|
|
|
|
return key =>
|
|
key in manifest ? `${STATIC_URL}static/${manifest[key]}` : '';
|
|
};
|
|
})();
|
|
|
|
module.exports = async (req, res, next) => {
|
|
try {
|
|
// Attach the custom css url.
|
|
const { customCssUrl } = await SettingsService.retrieve('customCssUrl');
|
|
res.locals.customCssUrl = customCssUrl;
|
|
} catch (err) {
|
|
console.warn(err);
|
|
}
|
|
|
|
// Always attach the locals.
|
|
attachStaticLocals(res.locals);
|
|
|
|
// Resolve will help resolving paths to static files
|
|
// using the manifest.
|
|
res.locals.resolve = createResolveFactory();
|
|
|
|
// Forward the request.
|
|
next();
|
|
};
|
|
|
|
module.exports.attachStaticLocals = attachStaticLocals;
|
|
module.exports.TEMPLATE_LOCALS = TEMPLATE_LOCALS;
|