trifid-plugin-spex
Version:
Trifid SPEX plugin
89 lines (88 loc) • 2.9 kB
JavaScript
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { resolve } from 'import-meta-resolve';
import fastifyStatic from '@fastify/static';
const __dirname = dirname(fileURLToPath(import.meta.url));
const defaults = {
template: join(__dirname, 'views/index.hbs'),
};
const defaultOptions = {
url: null,
user: null,
password: null,
graph: null,
prefixes: [],
forceIntrospection: false,
};
/**
* Create Plugin.
*
* @param server Fastify server instance.
* @param config Plugin configuration.
* @param render Trifid render function.
*/
const createPlugin = async (server, config, render) => {
const options = { ...defaultOptions, ...config };
const spexOptions = {
sparqlEndpoint: options.url,
username: options.user,
password: options.password,
forceIntrospection: options.forceIntrospection,
namedGraph: options.graph,
prefixes: options.prefixes,
};
const template = typeof config.template === 'string' ? config.template : defaults.template;
// Serve static files from SPEX dist folder
const distPath = dirname(resolve('@zazuko/spex', import.meta.url));
server.register(fastifyStatic, {
root: distPath.replace(/^file:\/\//, ''),
prefix: '/spex/static/',
decorateReply: false,
});
/**
* Route handler.
*
* @param request Request.
* @param reply Reply.
*/
const handler = async (request, reply) => {
let requestPort = '';
const portValue = request.port;
if (portValue) {
requestPort = `:${portValue}`;
}
const fullUrl = `${request.protocol}://${request.hostname}${requestPort}${request.url}`;
const fullUrlObject = new URL(fullUrl);
const fullUrlPathname = fullUrlObject.pathname;
// Enforce trailing slash
if (fullUrlPathname.slice(-1) !== '/') {
reply.redirect(`${fullUrlPathname}/`);
return reply;
}
// Create an absolute URL if a relative URL is provided
spexOptions.sparqlEndpoint = new URL(spexOptions.sparqlEndpoint || '/query', fullUrl).toString();
const content = await render(request, template, {
options: JSON.stringify(spexOptions),
}, { title: 'SPEX' });
reply.type('text/html').send(content);
return reply;
};
return handler;
};
const trifidFactory = async (trifid) => {
const { server, config, render } = trifid;
return {
defaultConfiguration: async () => {
return {
methods: ['GET'],
paths: [
'/spex',
'/spex/',
],
};
},
routeHandler: async () => createPlugin(server, config, render),
};
};
export default trifidFactory;
export { createPlugin };