Просмотр исходного кода

refactor(elasticsearch-plugin): Refactor to new Plugin architecture

Relates to #123
Michael Bromley 6 лет назад
Родитель
Сommit
9f35e978f6
1 измененных файлов с 43 добавлено и 71 удалено
  1. 43 71
      packages/elasticsearch-plugin/src/plugin.ts

+ 43 - 71
packages/elasticsearch-plugin/src/plugin.ts

@@ -1,20 +1,19 @@
 import { Client } from '@elastic/elasticsearch';
-import { Provider } from '@nestjs/common';
 import {
-    APIExtensionDefinition,
     CatalogModificationEvent,
     CollectionModificationEvent,
     EventBus,
     idsAreEqual,
     Logger,
+    OnVendureBootstrap,
+    OnVendureClose,
+    PluginCommonModule,
     Product,
     ProductVariant,
     SearchService,
     TaxRateModificationEvent,
-    Type,
     VendurePlugin,
 } from '@vendure/core';
-import { gql } from 'apollo-server-core';
 
 import { ELASTIC_SEARCH_CLIENT, ELASTIC_SEARCH_OPTIONS, loggerCtx } from './constants';
 import { ElasticsearchIndexService } from './elasticsearch-index.service';
@@ -77,7 +76,7 @@ export interface ElasticsearchOptions {
  * const config: VendureConfig = {
  *   // Add an instance of the plugin to the plugins array
  *   plugins: [
- *     new ElasticsearchPlugin({
+ *     ElasticsearchPlugin.init({
  *       host: 'http://localhost',
  *       port: 9200,
  *     }),
@@ -87,25 +86,43 @@ export interface ElasticsearchOptions {
  *
  * @docsCategory ElasticsearchPlugin
  */
-export class ElasticsearchPlugin implements VendurePlugin {
-    private readonly options: Required<ElasticsearchOptions>;
-    private readonly client: Client;
+@VendurePlugin({
+    imports: [PluginCommonModule],
+    providers: [
+        ElasticsearchIndexService,
+        ElasticsearchService,
+        { provide: SearchService, useClass: ElasticsearchService },
+        { provide: ELASTIC_SEARCH_OPTIONS, useFactory: () => ElasticsearchPlugin.options },
+        { provide: ELASTIC_SEARCH_CLIENT, useFactory: () => ElasticsearchPlugin.client },
+    ],
+    adminApiExtensions: { resolvers: [AdminElasticSearchResolver] },
+    shopApiExtensions: { resolvers: [ShopElasticSearchResolver] },
+    workers: [ElasticsearchIndexerController],
+})
+export class ElasticsearchPlugin implements OnVendureBootstrap, OnVendureClose {
+    private static options: Required<ElasticsearchOptions>;
+    private static client: Client;
 
-    constructor(options: ElasticsearchOptions) {
-        this.options = { indexPrefix: 'vendure-', batchSize: 2000, ...options };
+    constructor(
+        private eventBus: EventBus,
+        private elasticsearchService: ElasticsearchService,
+        private elasticsearchIndexService: ElasticsearchIndexService,
+    ) {}
+
+    static init(options: ElasticsearchOptions) {
         const { host, port } = options;
+        this.options = { indexPrefix: 'vendure-', batchSize: 2000, ...options };
         this.client = new Client({
             node: `${host}:${port}`,
         });
+        return ElasticsearchPlugin;
     }
 
     /** @internal */
-    async onBootstrap(inject: <T>(type: Type<T>) => T): Promise<void> {
-        const elasticsearchService = inject(ElasticsearchService);
-        const elasticsearchIndexService = inject(ElasticsearchIndexService);
-        const { host, port } = this.options;
+    async onVendureBootstrap(): Promise<void> {
+        const { host, port } = ElasticsearchPlugin.options;
         try {
-            const pingResult = await elasticsearchService.checkConnection();
+            const pingResult = await this.elasticsearchService.checkConnection();
         } catch (e) {
             Logger.error(`Could not connect to Elasticsearch instance at "${host}:${port}"`, loggerCtx);
             Logger.error(JSON.stringify(e), loggerCtx);
@@ -113,73 +130,28 @@ export class ElasticsearchPlugin implements VendurePlugin {
         }
         Logger.info(`Sucessfully connected to Elasticsearch instance at "${host}:${port}"`, loggerCtx);
 
-        await elasticsearchService.createIndicesIfNotExists();
+        await this.elasticsearchService.createIndicesIfNotExists();
 
-        const eventBus = inject(EventBus);
-        eventBus.subscribe(CatalogModificationEvent, event => {
+        this.eventBus.subscribe(CatalogModificationEvent, event => {
             if (event.entity instanceof Product || event.entity instanceof ProductVariant) {
-                return elasticsearchIndexService.updateProductOrVariant(event.ctx, event.entity).start();
+                return this.elasticsearchIndexService.updateProductOrVariant(event.ctx, event.entity).start();
             }
         });
-        eventBus.subscribe(CollectionModificationEvent, event => {
-            return elasticsearchIndexService.updateVariantsById(event.ctx, event.productVariantIds).start();
+        this.eventBus.subscribe(CollectionModificationEvent, event => {
+            return this.elasticsearchIndexService
+                .updateVariantsById(event.ctx, event.productVariantIds)
+                .start();
         });
-        eventBus.subscribe(TaxRateModificationEvent, event => {
+        this.eventBus.subscribe(TaxRateModificationEvent, event => {
             const defaultTaxZone = event.ctx.channel.defaultTaxZone;
             if (defaultTaxZone && idsAreEqual(defaultTaxZone.id, event.taxRate.zone.id)) {
-                return elasticsearchService.reindex(event.ctx);
+                return this.elasticsearchService.reindex(event.ctx);
             }
         });
     }
 
     /** @internal */
-    onClose() {
-        return this.client.close();
-    }
-
-    /** @internal */
-    extendAdminAPI(): APIExtensionDefinition {
-        return {
-            resolvers: [AdminElasticSearchResolver],
-            schema: gql`
-                extend type SearchReindexResponse {
-                    timeTaken: Int!
-                    indexedItemCount: Int!
-                }
-            `,
-        };
-    }
-
-    /** @internal */
-    extendShopAPI(): APIExtensionDefinition {
-        return {
-            resolvers: [ShopElasticSearchResolver],
-            schema: gql`
-                extend type SearchReindexResponse {
-                    timeTaken: Int!
-                    indexedItemCount: Int!
-                }
-            `,
-        };
-    }
-
-    /** @internal */
-    defineProviders(): Provider[] {
-        return [
-            { provide: ElasticsearchIndexService, useClass: ElasticsearchIndexService },
-            AdminElasticSearchResolver,
-            ShopElasticSearchResolver,
-            ElasticsearchService,
-            { provide: SearchService, useClass: ElasticsearchService },
-            { provide: ELASTIC_SEARCH_OPTIONS, useFactory: () => this.options },
-            { provide: ELASTIC_SEARCH_CLIENT, useFactory: () => this.client },
-        ];
-    }
-
-    /** @internal */
-    defineWorkers(): Array<Type<any>> {
-        return [
-            ElasticsearchIndexerController,
-        ];
+    onVendureClose() {
+        return ElasticsearchPlugin.client.close();
     }
 }