etherpad-lite/src/node/hooks/express/static.ts

95 lines
3.3 KiB
TypeScript
Raw Normal View History

2024-04-17 22:01:04 +02:00
import type { MapArrayType } from "../../types/MapType";
import type { PartType } from "../../types/PartType";
2021-01-21 21:06:52 +00:00
2024-04-17 22:01:04 +02:00
const fs = require("fs").promises;
const minify = require("../../utils/Minify");
const path = require("path");
const plugins = require("../../../static/js/pluginfw/plugin_defs");
const settings = require("../../utils/Settings");
import CachingMiddleware from "../../utils/caching_middleware";
const Yajsml = require("etherpad-yajsml");
// Rewrite tar to include modules with no extensions and proper rooted paths.
2021-02-09 17:26:46 -05:00
const getTar = async () => {
2024-04-17 22:01:04 +02:00
const prefixLocalLibraryPath = (path: string) => {
if (path.charAt(0) === "$") {
return path.slice(1);
} else {
return `ep_etherpad-lite/static/js/${path}`;
}
};
2024-02-22 11:36:43 +01:00
2024-04-17 22:01:04 +02:00
const tarJson = await fs.readFile(
path.join(settings.root, "src/node/utils/tar.json"),
"utf8",
);
const tar: MapArrayType<string[]> = {};
for (const [key, relativeFiles] of Object.entries(JSON.parse(tarJson)) as [
string,
string[],
][]) {
const files = relativeFiles.map(prefixLocalLibraryPath);
tar[prefixLocalLibraryPath(key)] = files
.concat(files.map((p) => p.replace(/\.js$/, "")))
.concat(files.map((p) => `${p.replace(/\.js$/, "")}/index.js`));
}
return tar;
};
2024-04-17 22:01:04 +02:00
exports.expressPreSession = async (hookName: string, { app }: any) => {
// Cache both minified and static.
const assetCache = new CachingMiddleware();
// Cache static assets
app.all(/\/js\/(.*)/, assetCache.handle.bind(assetCache));
app.all(/\/css\/(.*)/, assetCache.handle.bind(assetCache));
2024-04-17 22:01:04 +02:00
// Minify will serve static files compressed (minify enabled). It also has
// file-specific hacks for ace/require-kernel/etc.
app.all("/static/:filename(*)", minify.minify);
2024-04-17 22:01:04 +02:00
// Setup middleware that will package JavaScript files served by minify for
// CommonJS loader on the client-side.
// Hostname "invalid.invalid" is a dummy value to allow parsing as a URI.
const jsServer = new Yajsml.Server({
rootPath: "javascripts/src/",
rootURI: "http://invalid.invalid/static/js/",
libraryPath: "javascripts/lib/",
libraryURI: "http://invalid.invalid/static/plugins/",
requestURIs: minify.requestURIs, // Loop-back is causing problems, this is a workaround.
});
2012-02-25 19:43:00 +01:00
2024-04-17 22:01:04 +02:00
const StaticAssociator = Yajsml.associators.StaticAssociator;
const associations = Yajsml.associators.associationsForSimpleMapping(
await getTar(),
);
const associator = new StaticAssociator(associations);
jsServer.setAssociator(associator);
2015-04-07 07:55:05 -05:00
2024-04-17 22:01:04 +02:00
app.use(jsServer.handle.bind(jsServer));
2024-04-17 22:01:04 +02:00
// serve plugin definitions
// not very static, but served here so that client can do
// require("pluginfw/static/js/plugin-definitions.js");
app.get(
"/pluginfw/plugin-definitions.json",
(req: any, res: any, next: Function) => {
const clientParts = plugins.parts.filter(
(part: PartType) => part.client_hooks != null,
);
const clientPlugins: MapArrayType<string> = {};
for (const name of new Set(
clientParts.map((part: PartType) => part.plugin),
)) {
// @ts-ignore
clientPlugins[name] = { ...plugins.plugins[name] };
// @ts-ignore
delete clientPlugins[name].package;
}
res.setHeader("Content-Type", "application/json; charset=utf-8");
res.setHeader("Cache-Control", `public, max-age=${settings.maxAge}`);
res.write(JSON.stringify({ plugins: clientPlugins, parts: clientParts }));
res.end();
},
);
2020-11-23 13:24:19 -05:00
};