@chillicream/nitro-express-middleware
Version:
Express middleware for Nitro GraphQL IDE
111 lines (107 loc) • 3.49 kB
JavaScript
/*!
* @license ChilliCream License 1.0
*
* Copyright (c) ChilliCream, Inc.
*
* This source code is licensed under the ChilliCream License 1.0 found in the
* LICENSE file in the root directory of this source tree.
*/
import express from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';
import module from 'node:module';
import path from 'node:path';
const Defaults = {
CDN_URL: "https://cdn.chillicream.com/web",
VERSION: "latest",
EMBEDDED_ID: "@chillicream/nitro-embedded",
CONFIG: {
mode: "cdn",
},
OPTIONS: {
useBrowserUrlAsEndpoint: true,
},
};
const Paths = {
ROOT: "/",
INDEX: "/index.html",
CONFIG: "/nitro-config.json",
};
function resolveUrl(target) {
return typeof target === "string"
? target
: `${target?.baseUrl || Defaults.CDN_URL}/${target?.version || Defaults.VERSION}`;
}
function resolvePath(target) {
const require = module.createRequire(import.meta.url);
return path.dirname(require.resolve(target || Defaults.EMBEDDED_ID));
}
function resolveOptions(options) {
return Object.assign({}, Defaults.OPTIONS, options);
}
function combineMiddlewares(...middlewares) {
return middlewares.reduce((a, b) => (req, res, next) => {
a(req, res, (err) => {
if (err) {
next(err);
}
else {
b(req, res, next);
}
});
});
}
function createRootMiddleware() {
return function rootMiddleware(req, res, next) {
if (req.method === "GET" || req.method === "HEAD") {
if (req.path === Paths.ROOT && req.accepts("html")) {
const path = req.originalUrl.replace(/\?.*/, "");
if (!path.endsWith("/")) {
const query = req.originalUrl.slice(path.length);
return res.redirect(301, path + "/" + query);
}
}
}
next();
};
}
function createConfigMiddleware(options) {
return function configMiddleware(req, res, next) {
if (req.method === "GET" || req.method === "HEAD") {
if (req.path === Paths.CONFIG && req.accepts("json")) {
if (req.method === "GET") {
return res.json(resolveOptions(options));
}
else {
return res.json();
}
}
}
next();
};
}
function cdnMiddleware(target, options) {
return combineMiddlewares(createRootMiddleware(), createConfigMiddleware(options), createProxyMiddleware((pathname, req) => {
return (pathname !== req.baseUrl &&
(req.method === "GET" || req.method === "HEAD"));
}, {
target,
pathRewrite(path, req) {
return path.replace(req.baseUrl, "");
},
followRedirects: true,
changeOrigin: true,
logLevel: "silent",
}));
}
function selfMiddleware(target, options) {
return combineMiddlewares(createRootMiddleware(), createConfigMiddleware(options), express.static(target, {
redirect: true,
fallthrough: true,
}));
}
function nitroMiddleware({ mode, target, options, }) {
return mode === "cdn"
? cdnMiddleware(resolveUrl(target), options)
: selfMiddleware(resolvePath(target), options);
}
export { cdnMiddleware, combineMiddlewares, createConfigMiddleware, createRootMiddleware, nitroMiddleware as default, selfMiddleware };