plugin-utils.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import { RequestHandler } from 'express';
  2. import { createProxyMiddleware } from 'http-proxy-middleware';
  3. import { Logger } 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}/${options.basePath ?? ''}`,
  41. pathRewrite: {
  42. [`^${route}`]: '/' + (options.basePath || ''),
  43. },
  44. logger: {
  45. log(message: string) {
  46. Logger.debug(message, options.label);
  47. },
  48. debug(message: string) {
  49. Logger.debug(message, options.label);
  50. },
  51. info(message: string) {
  52. Logger.debug(message, options.label);
  53. },
  54. warn(message: string) {
  55. Logger.warn(message, options.label);
  56. },
  57. error(message: string) {
  58. Logger.error(message, options.label);
  59. },
  60. },
  61. });
  62. return middleware;
  63. }
  64. /**
  65. * @description
  66. * Options to configure proxy middleware via {@link createProxyHandler}.
  67. *
  68. * @docsCategory Plugin
  69. * @docsPage Plugin Utilities
  70. */
  71. export interface ProxyOptions {
  72. /**
  73. * @description
  74. * A human-readable label for the service which is being proxied. Used to
  75. * generate more informative logs.
  76. */
  77. label: string;
  78. /**
  79. * @description
  80. * The route of the Vendure server which will act as the proxy url.
  81. */
  82. route: string;
  83. /**
  84. * @description
  85. * The port on which the service being proxied is running.
  86. */
  87. port: number;
  88. /**
  89. * @description
  90. * The hostname of the server on which the service being proxied is running.
  91. *
  92. * @default 'localhost'
  93. */
  94. hostname?: string;
  95. /**
  96. * @description
  97. * An optional base path on the proxied server.
  98. */
  99. basePath?: string;
  100. }
  101. const pluginStartupMessages: Array<{ label: string; path: string }> = [];
  102. /**
  103. * Use this function to add a line to the bootstrap log output listing a service added
  104. * by this plugin.
  105. */
  106. export function registerPluginStartupMessage(serviceName: string, path: string) {
  107. pluginStartupMessages.push({ label: serviceName, path });
  108. }
  109. export function getPluginStartupMessages(): ReadonlyArray<{ label: string; path: string }> {
  110. return pluginStartupMessages;
  111. }