| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- import { AdminUiConfig } from '@vendure/common/lib/shared-types';
- import { createProxyHandler, InjectorFn, VendureConfig, VendurePlugin } from '@vendure/core';
- import express from 'express';
- import fs from 'fs-extra';
- import { Server } from 'http';
- import path from 'path';
- /**
- * @description
- * Configuration options for the {@link AdminUiPlugin}.
- *
- * @docsCategory AdminUiPlugin
- */
- export interface AdminUiOptions {
- /**
- * @description
- * The hostname of the server serving the static admin ui files.
- *
- * @default 'localhost'
- */
- hostname?: string;
- /**
- * @description
- * The port on which the server will listen.
- */
- port: number;
- /**
- * @description
- * The hostname of the Vendure server which the admin ui will be making API calls
- * to. If set to "auto", the admin ui app will determine the hostname from the
- * current location (i.e. `window.location.hostname`).
- *
- * @default 'auto'
- */
- apiHost?: string | 'auto';
- /**
- * @description
- * The port of the Vendure server which the admin ui will be making API calls
- * to. If set to "auto", the admin ui app will determine the port from the
- * current location (i.e. `window.location.port`).
- *
- * @default 'auto'
- */
- apiPort?: number | 'auto';
- }
- /**
- * @description
- * This plugin starts a static server for the Admin UI app, and proxies it via the `/admin/` path of the main Vendure server.
- *
- * The Admin UI allows you to administer all aspects of your store, from inventory management to order tracking. It is the tool used by
- * store administrators on a day-to-day basis for the management of the store.
- *
- * ## Installation
- *
- * `yarn add @vendure/admin-ui-plugin`
- *
- * or
- *
- * `npm install @vendure/admin-ui-plugin`
- *
- * @example
- * ```ts
- * import { AdminUiPlugin } from '@vendure/admin-ui-plugin';
- *
- * const config: VendureConfig = {
- * // Add an instance of the plugin to the plugins array
- * plugins: [
- * new AdminUiPlugin({ port: 3002 }),
- * ],
- * };
- * ```
- *
- * @docsCategory AdminUiPlugin
- */
- export class AdminUiPlugin implements VendurePlugin {
- private server: Server;
- constructor(private options: AdminUiOptions) {}
- /** @internal */
- async configure(config: Required<VendureConfig>): Promise<Required<VendureConfig>> {
- const route = 'admin';
- config.middleware.push({
- handler: createProxyHandler({ ...this.options, route, label: 'Admin UI' }),
- route,
- });
- const { adminApiPath } = config;
- const { apiHost, apiPort } = this.options;
- await this.overwriteAdminUiConfig(apiHost || 'auto', apiPort || 'auto', adminApiPath);
- return config;
- }
- /** @internal */
- onBootstrap(inject: InjectorFn): void | Promise<void> {
- const adminUiPath = this.getAdminUiPath();
- const assetServer = express();
- assetServer.use(express.static(adminUiPath));
- assetServer.use((req, res) => {
- res.sendFile(path.join(adminUiPath, 'index.html'));
- });
- this.server = assetServer.listen(this.options.port);
- }
- /** @internal */
- onClose(): Promise<void> {
- return new Promise(resolve => this.server.close(() => resolve()));
- }
- /**
- * Overwrites the parts of the admin-ui app's `vendure-ui-config.json` file relating to connecting to
- * the server admin API.
- */
- private async overwriteAdminUiConfig(host: string | 'auto', port: number | 'auto', adminApiPath: string) {
- const adminUiConfigPath = path.join(this.getAdminUiPath(), 'vendure-ui-config.json');
- const adminUiConfig = await fs.readFile(adminUiConfigPath, 'utf-8');
- const config: AdminUiConfig = JSON.parse(adminUiConfig);
- config.apiHost = host || 'http://localhost';
- config.apiPort = port;
- config.adminApiPath = adminApiPath;
- await fs.writeFile(adminUiConfigPath, JSON.stringify(config, null, 2));
- }
- private getAdminUiPath(): string {
- // attempt to read from the path location on a production npm install
- const prodPath = path.join(__dirname, '../admin-ui');
- if (fs.existsSync(path.join(prodPath, 'index.html'))) {
- return prodPath;
- }
- // attempt to read from the path on a development install
- const devPath = path.join(__dirname, '../lib/admin-ui');
- if (fs.existsSync(path.join(devPath, 'index.html'))) {
- return devPath;
- }
- throw new Error(`AdminUiPlugin: admin-ui app not found`);
- }
- }
|