plugin-utils.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { RequestHandler } from 'express';
  2. import { createProxyMiddleware } from 'http-proxy-middleware';
  3. import { Logger, RuntimeVendureConfig, VendureConfig } from '../config';
  4. /**
  5. * @description
  6. * Creates a proxy middleware which proxies the given route to the given port.
  7. * Useful for plugins which start their own servers but should be accessible
  8. * via the main Vendure url.
  9. *
  10. * @example
  11. * ```ts
  12. * // Example usage in the `configuration` method of a VendurePlugin.
  13. * // Imagine that we have started a Node server on port 5678
  14. * // running some service which we want to access via the `/my-plugin/`
  15. * // route of the main Vendure server.
  16. * \@VendurePlugin({
  17. * configuration: (config: Required<VendureConfig>) => {
  18. * config.apiOptions.middleware.push({
  19. * handler: createProxyHandler({
  20. * label: 'Admin UI',
  21. * route: 'my-plugin',
  22. * port: 5678,
  23. * }),
  24. * route: 'my-plugin',
  25. * });
  26. * return config;
  27. * }
  28. * })
  29. * export class MyPlugin {}
  30. * ```
  31. *
  32. * @docsCategory Plugin
  33. * @docsPage Plugin Utilities
  34. */
  35. export function createProxyHandler(options: ProxyOptions): RequestHandler {
  36. const route = options.route.charAt(0) === '/' ? options.route : '/' + options.route;
  37. const proxyHostname = options.hostname || 'localhost';
  38. const middleware = createProxyMiddleware({
  39. // TODO: how do we detect https?
  40. target: `http://${proxyHostname}:${options.port}`,
  41. pathRewrite: {
  42. [`^${route}`]: `/` + (options.basePath || ''),
  43. },
  44. logProvider(provider) {
  45. return {
  46. log(message: string) {
  47. Logger.debug(message, options.label);
  48. },
  49. debug(message: string) {
  50. Logger.debug(message, options.label);
  51. },
  52. info(message: string) {
  53. Logger.debug(message, options.label);
  54. },
  55. warn(message: string) {
  56. Logger.warn(message, options.label);
  57. },
  58. error(message: string) {
  59. Logger.error(message, options.label);
  60. },
  61. };
  62. },
  63. });
  64. return middleware;
  65. }
  66. /**
  67. * @description
  68. * Options to configure proxy middleware via {@link createProxyHandler}.
  69. *
  70. * @docsCategory Plugin
  71. * @docsPage Plugin Utilities
  72. */
  73. export interface ProxyOptions {
  74. /**
  75. * @description
  76. * A human-readable label for the service which is being proxied. Used to
  77. * generate more informative logs.
  78. */
  79. label: string;
  80. /**
  81. * @description
  82. * The route of the Vendure server which will act as the proxy url.
  83. */
  84. route: string;
  85. /**
  86. * @description
  87. * The port on which the service being proxied is running.
  88. */
  89. port: number;
  90. /**
  91. * @description
  92. * The hostname of the server on which the service being proxied is running.
  93. *
  94. * @default 'localhost'
  95. */
  96. hostname?: string;
  97. /**
  98. * @description
  99. * An optional base path on the proxied server.
  100. */
  101. basePath?: string;
  102. }
  103. const pluginStartupMessages: Array<{ label: string; path: string }> = [];
  104. /**
  105. * Use this function to add a line to the bootstrap log output listing a service added
  106. * by this plugin.
  107. */
  108. export function registerPluginStartupMessage(serviceName: string, path: string) {
  109. pluginStartupMessages.push({ label: serviceName, path });
  110. }
  111. export function getPluginStartupMessages(): ReadonlyArray<{ label: string; path: string }> {
  112. return pluginStartupMessages;
  113. }