UNPKG

@equinor/fusion-framework-cli

Version:

--- title: Fusion Framework CLI ---

139 lines 6.46 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; /** * Preserve token for executing proxy assets * * @remarks * This assumes the client will execute a api call using bearer token before * acquiring a asset. By default the Framework will execute a rest call to load * application manifest for resolving build assets to import. * * @remarks * This is a quick and dirty method to authorize requests without bearer token * like browser `import`. * The correct way would be to have a auth controller within the dev-server, * but since the token is only exposed to the plugin and the cli is a tool for local * development, this should be sufficient. */ let __APP_API_TOKEN__ = ''; /** * The `appProxyPlugin` function creates a Vite plugin that configures a proxy for API and bundle requests * to the Fusion apps backend. It also serves the app manifest, config, and local bundles if an app is provided. * * @param {AppProxyPluginOptions} options - The options for configuring the app proxy plugin. * * @returns {Plugin} - The configured Vite plugin. * * @example * ```typescript * const plugin = appProxyPlugin({ * proxy: { * path: '/app-proxy', * target: 'https://apps.ci.api.fusion-dev.net', * onProxyReq: (proxyReq, req, res) => { * proxyReq.on('response', (res) => { console.log(res.statusCode) }); * }, * }, * app: { * key: 'my-app', * version: '1.0.0', * generateConfig: async () => ({}), * generateManifest: async () => ({}), * }, * }); * * // api calls * fetch('/app-proxy/apps/my-app/builds/1.0.0/config'); // will generate app config by provided function * fetch('/app-proxy/apps/my-app/builds/0.0.9/config'); // will proxy to the target, since version does not match * fetch('/app-proxy/apps/other-app/builds/1.0.0/config'); // will proxy to the target, since app key does not match * * // asset calls * fetch('/app-proxy/bundles/my-app/builds/1.0.0/index.js'); // will generate bundle by provided function * fetch('/app-proxy/bundles/my-app/builds/0.0.9/index.js'); // will proxy to the target, since version does not match * ``` * */ export const appProxyPlugin = (options) => { const { proxy: { onProxyReq = () => void 0, path: proxyPath, target }, } = options; return { name: 'fusion:app-proxy', apply: 'serve', config(config) { var _a, _b; var _c; (_a = config.server) !== null && _a !== void 0 ? _a : (config.server = {}); (_b = (_c = config.server).proxy) !== null && _b !== void 0 ? _b : (_c.proxy = {}); config.server.proxy[proxyPath] = { target, changeOrigin: true, secure: false, rewrite: (path) => path.replace(proxyPath, ''), configure: (proxy) => { proxy.on('proxyReq', (proxyReq) => { const token = proxyReq.getHeader('authorization'); if (typeof token === 'string') { // preserve token for executing proxy assets __APP_API_TOKEN__ = token; } else if (__APP_API_TOKEN__) { // apply token to proxy request proxyReq.setHeader('authorization', __APP_API_TOKEN__); } }); proxy.on('proxyReq', onProxyReq); }, }; }, configureServer(server) { var _a, _b, _c; const { app } = options; // disable local assets if no app configuration provided if (!app) return; // serve app config if request matches the current app and version const configPath = [ proxyPath, (_a = app.configPath) !== null && _a !== void 0 ? _a : `apps/${app.key}/builds/${app.version}/config`, ].join('/'); server.middlewares.use(configPath, (_req, res) => __awaiter(this, void 0, void 0, function* () { res.setHeader('content-type', 'application/json'); res.end(JSON.stringify(yield app.generateConfig())); })); // serve app manifest if request matches the current app const manifestPath = [proxyPath, (_b = app.manifestPath) !== null && _b !== void 0 ? _b : `apps/${app.key}`].join('/'); server.middlewares.use((req, res, next) => __awaiter(this, void 0, void 0, function* () { var _a; // We only want to match the exact path const [requestPath] = ((_a = req.url) !== null && _a !== void 0 ? _a : '').split('?'); if (requestPath === manifestPath) { res.setHeader('content-type', 'application/json'); res.end(JSON.stringify(yield app.generateManifest())); return; } next(); })); // serve local bundles if request matches the current app and version const bundlePath = [ proxyPath, (_c = app.bundlePath) !== null && _c !== void 0 ? _c : `bundles/apps/${app.key}/${app.version}`, ].join('/'); server.middlewares.use((req, _res, next) => __awaiter(this, void 0, void 0, function* () { var _a; if ((_a = req.url) === null || _a === void 0 ? void 0 : _a.match(bundlePath)) { // remove proxy path from url req.url = req.url.replace(bundlePath, ''); } next(); })); }, }; }; export default appProxyPlugin; //# sourceMappingURL=app-proxy-plugin.js.map