Browse Source

chore: Update to NestJS v8, RxJS v7

Michael Bromley 4 years ago
parent
commit
029623deae
25 changed files with 142 additions and 487 deletions
  1. 1 1
      packages/admin-ui/package.json
  2. 4 4
      packages/admin-ui/src/lib/catalog/src/components/assign-products-to-channel-dialog/assign-products-to-channel-dialog.component.ts
  3. 1 1
      packages/admin-ui/src/lib/catalog/src/components/collection-list/collection-list.component.ts
  4. 2 2
      packages/admin-ui/src/lib/catalog/src/components/product-variants-editor/product-variants-editor.component.ts
  5. 1 1
      packages/admin-ui/src/lib/core/src/common/base-list.component.ts
  6. 1 1
      packages/admin-ui/src/lib/core/src/common/version.ts
  7. 9 9
      packages/admin-ui/src/lib/core/src/data/providers/fetch-adapter.ts
  8. 2 2
      packages/admin-ui/src/lib/core/src/data/query-result.ts
  9. 11 11
      packages/admin-ui/src/lib/core/src/data/server-config.ts
  10. 1 1
      packages/admin-ui/src/lib/core/src/providers/health-check/health-check.service.ts
  11. 6 6
      packages/admin-ui/src/lib/core/src/shared/dynamic-form-inputs/dynamic-form-input/dynamic-form-input.component.ts
  12. 1 1
      packages/admin-ui/src/lib/settings/src/components/country-list/country-list.component.ts
  13. 2 2
      packages/core/e2e/lifecycle.e2e-spec.ts
  14. 8 8
      packages/core/package.json
  15. 6 6
      packages/core/src/api/middleware/transaction-interceptor.ts
  16. 2 1
      packages/core/src/api/resolvers/admin/import.resolver.ts
  17. 2 1
      packages/core/src/cli/populate.ts
  18. 2 2
      packages/core/src/common/utils.ts
  19. 1 1
      packages/core/src/event-bus/event-bus.ts
  20. 5 5
      packages/core/src/job-queue/job-queue.service.spec.ts
  21. 2 4
      packages/core/src/job-queue/polling-job-queue-strategy.ts
  22. 1 1
      packages/create/package.json
  23. 4 4
      packages/dev-server/dev-config.ts
  24. 1 1
      packages/ui-devkit/package.json
  25. 66 411
      yarn.lock

+ 1 - 1
packages/admin-ui/package.json

@@ -57,7 +57,7 @@
     "prosemirror-schema-basic": "^1.1.2",
     "prosemirror-schema-list": "^1.1.4",
     "prosemirror-state": "^1.3.4",
-    "rxjs": "^6.6.6",
+    "rxjs": "^7.3.0",
     "tslib": "^2.1.0",
     "zone.js": "~0.11.4"
   },

+ 4 - 4
packages/admin-ui/src/lib/catalog/src/components/assign-products-to-channel-dialog/assign-products-to-channel-dialog.component.ts

@@ -5,7 +5,7 @@ import { GetChannels, ProductVariantFragment } from '@vendure/admin-ui/core';
 import { NotificationService } from '@vendure/admin-ui/core';
 import { DataService } from '@vendure/admin-ui/core';
 import { Dialog } from '@vendure/admin-ui/core';
-import { combineLatest, from, Observable } from 'rxjs';
+import { combineLatest, from, lastValueFrom, Observable } from 'rxjs';
 import { map, startWith, switchMap } from 'rxjs/operators';
 
 @Component({
@@ -110,15 +110,15 @@ export class AssignProductsToChannelDialogComponent implements OnInit, Dialog<an
         const variants: ProductVariantFragment[] = [];
 
         for (let i = 0; i < this.productIds.length && variants.length < take; i++) {
-            const productVariants = await this.dataService.product
+            const productVariants$ = this.dataService.product
                 .getProduct(this.productIds[i])
                 .mapSingle(({ product }) => {
                     const _variants = product ? product.variants : [];
                     return _variants.filter(v =>
                         this.isProductVariantMode ? this.productVariantIds?.includes(v.id) : true,
                     );
-                })
-                .toPromise();
+                });
+            const productVariants = await lastValueFrom(productVariants$);
             variants.push(...(productVariants || []));
         }
         return variants.slice(0, take);

+ 1 - 1
packages/admin-ui/src/lib/catalog/src/components/collection-list/collection-list.component.ts

@@ -64,7 +64,7 @@ export class CollectionListComponent implements OnInit, OnDestroy {
     }
 
     ngOnDestroy() {
-        this.queryResult.completed$.next();
+        this.queryResult.completed$.next(null);
     }
 
     onRearrange(event: RearrangeEvent) {

+ 2 - 2
packages/admin-ui/src/lib/catalog/src/components/product-variants-editor/product-variants-editor.component.ts

@@ -361,9 +361,9 @@ export class ProductVariantsEditorComponent implements OnInit, DeactivateAware {
         const obsoleteVariants = this.getObsoleteVariants();
         if (obsoleteVariants.length) {
             const deleteOperations = obsoleteVariants.map(v =>
-                this.dataService.product.deleteProductVariant(v.id).pipe(map(() => input)),
+                this.dataService.product.deleteProductVariant(v.id),
             );
-            return forkJoin(...deleteOperations);
+            return forkJoin(...deleteOperations).pipe(map(() => input));
         } else {
             return of(input);
         }

+ 1 - 1
packages/admin-ui/src/lib/core/src/common/base-list.component.ts

@@ -87,7 +87,7 @@ export class BaseListComponent<ResultType, ItemType, VariableType = any> impleme
     ngOnDestroy() {
         this.destroy$.next();
         this.destroy$.complete();
-        this.listQuery.completed$.next();
+        this.listQuery.completed$.next(null);
     }
 
     setPageNumber(page: number) {

+ 1 - 1
packages/admin-ui/src/lib/core/src/common/version.ts

@@ -1,2 +1,2 @@
 // Auto-generated by the set-version.js script.
-export const ADMIN_UI_VERSION = '1.1.5';
+export const ADMIN_UI_VERSION = '1.2.0';

+ 9 - 9
packages/admin-ui/src/lib/core/src/data/providers/fetch-adapter.ts

@@ -1,5 +1,6 @@
 import { HttpClient } from '@angular/common/http';
 import { Injectable } from '@angular/core';
+import { lastValueFrom } from 'rxjs';
 
 /**
  * An adapter that allows the Angular HttpClient to be used as a replacement for the global `fetch` function.
@@ -14,20 +15,19 @@ export class FetchAdapter {
         const url = typeof input === 'string' ? input : input.url;
         const method = typeof input === 'string' ? (init.method ? init.method : 'GET') : input.method;
 
-        return this.httpClient
-            .request(method, url, {
+        return lastValueFrom(
+            this.httpClient.request(method, url, {
                 body: init.body,
                 headers: init.headers as any,
                 observe: 'response',
                 responseType: 'json',
                 withCredentials: true,
-            })
-            .toPromise()
-            .then(result => {
-                return new Response(JSON.stringify(result.body), {
-                    status: result.status,
-                    statusText: result.statusText,
-                });
+            }),
+        ).then(result => {
+            return new Response(JSON.stringify(result.body), {
+                status: result.status,
+                statusText: result.statusText,
             });
+        });
     };
 }

+ 2 - 2
packages/admin-ui/src/lib/core/src/data/query-result.ts

@@ -64,7 +64,7 @@ export class QueryResult<T, V = Record<string, any>> {
             take(1),
             map(result => result.data),
             finalize(() => {
-                this.completed$.next();
+                this.completed$.next(null);
                 this.completed$.complete();
             }),
         );
@@ -78,7 +78,7 @@ export class QueryResult<T, V = Record<string, any>> {
             filter(result => result.networkStatus === NetworkStatus.ready),
             map(result => result.data),
             finalize(() => {
-                this.completed$.next();
+                this.completed$.next(null);
                 this.completed$.complete();
             }),
         );

+ 11 - 11
packages/admin-ui/src/lib/core/src/data/server-config.ts

@@ -1,4 +1,5 @@
 import { Injectable, Injector } from '@angular/core';
+import { lastValueFrom } from 'rxjs';
 
 import {
     CustomFieldConfig,
@@ -43,17 +44,16 @@ export class ServerConfigService {
      * Fetch the ServerConfig. Should be run on app init (in case user is already logged in) and on successful login.
      */
     getServerConfig() {
-        return this.baseDataService
-            .query<GetServerConfig.Query>(GET_SERVER_CONFIG)
-            .single$.toPromise()
-            .then(
-                result => {
-                    this._serverConfig = result.globalSettings.serverConfig;
-                },
-                err => {
-                    // Let the error fall through to be caught by the http interceptor.
-                },
-            );
+        return lastValueFrom(
+            this.baseDataService.query<GetServerConfig.Query>(GET_SERVER_CONFIG).single$,
+        ).then(
+            result => {
+                this._serverConfig = result.globalSettings.serverConfig;
+            },
+            err => {
+                // Let the error fall through to be caught by the http interceptor.
+            },
+        );
     }
 
     getAvailableLanguages() {

+ 1 - 1
packages/admin-ui/src/lib/core/src/providers/health-check/health-check.service.ts

@@ -56,7 +56,7 @@ export class HealthCheckService {
     }
 
     refresh() {
-        this._refresh.next();
+        this._refresh.next(null);
     }
 
     private checkHealth() {

+ 6 - 6
packages/admin-ui/src/lib/core/src/shared/dynamic-form-inputs/dynamic-form-input/dynamic-form-input.component.ts

@@ -184,7 +184,7 @@ export class DynamicFormInputComponent
     }
 
     ngOnDestroy() {
-        this.destroy$.next();
+        this.destroy$.next(null);
         this.destroy$.complete();
     }
 
@@ -210,7 +210,7 @@ export class DynamicFormInputComponent
             id: this.listId++,
             control: new FormControl((this.def as ConfigArgDefinition).defaultValue ?? null),
         });
-        this.renderList$.next();
+        this.renderList$.next(null);
     }
 
     moveListItem(event: CdkDragDrop<InputListItem>) {
@@ -218,7 +218,7 @@ export class DynamicFormInputComponent
             moveItemInArray(this.listItems, event.previousIndex, event.currentIndex);
             this.listFormArray.removeAt(event.previousIndex);
             this.listFormArray.insert(event.currentIndex, event.item.data.control);
-            this.renderList$.next();
+            this.renderList$.next(null);
         }
     }
 
@@ -228,7 +228,7 @@ export class DynamicFormInputComponent
             item.componentRef?.destroy();
             this.listFormArray.removeAt(index);
             this.listItems = this.listItems.filter(i => i !== item);
-            this.renderList$.next();
+            this.renderList$.next(null);
         }
     }
 
@@ -269,11 +269,11 @@ export class DynamicFormInputComponent
                             control: new FormControl(getConfigArgValue(value)),
                         } as InputListItem),
                 );
-                this.renderList$.next();
+                this.renderList$.next(null);
             }
         } else {
             this.listItems = [];
-            this.renderList$.next();
+            this.renderList$.next(null);
         }
         this.changeDetectorRef.markForCheck();
     }

+ 1 - 1
packages/admin-ui/src/lib/settings/src/components/country-list/country-list.component.ts

@@ -52,7 +52,7 @@ export class CountryListComponent implements OnInit, OnDestroy {
     }
 
     ngOnDestroy() {
-        this.destroy$.next();
+        this.destroy$.next(null);
         this.destroy$.complete();
     }
 

+ 2 - 2
packages/core/e2e/lifecycle.e2e-spec.ts

@@ -4,13 +4,13 @@ import {
     Injector,
     ProductService,
     ShippingEligibilityChecker,
+    TransactionalConnection,
 } from '@vendure/core';
 import { createTestEnvironment } from '@vendure/testing';
 import path from 'path';
 
 import { initialData } from '../../../e2e-common/e2e-initial-data';
-import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config';
-import { TransactionalConnection } from '../src/service/transaction/transactional-connection';
+import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config';
 
 const strategyInitSpy = jest.fn();
 const strategyDestroySpy = jest.fn();

+ 8 - 8
packages/core/package.json

@@ -39,13 +39,13 @@
   ],
   "dependencies": {
     "@graphql-tools/stitch": "^7.5.3",
-    "@nestjs/common": "7.6.17",
-    "@nestjs/core": "7.6.17",
-    "@nestjs/graphql": "7.10.6",
-    "@nestjs/platform-express": "7.6.17",
-    "@nestjs/terminus": "7.2.0",
-    "@nestjs/testing": "7.6.17",
-    "@nestjs/typeorm": "7.1.5",
+    "@nestjs/common": "8.0.6",
+    "@nestjs/core": "8.0.6",
+    "@nestjs/graphql": "8.0.2",
+    "@nestjs/platform-express": "8.0.6",
+    "@nestjs/terminus": "8.0.0-next.7",
+    "@nestjs/testing": "8.0.6",
+    "@nestjs/typeorm": "8.0.2",
     "@types/fs-extra": "^9.0.1",
     "@vendure/common": "^1.1.5",
     "apollo-server-express": "2.24.1",
@@ -72,7 +72,7 @@
     "nanoid": "^3.1.23",
     "progress": "^2.0.3",
     "reflect-metadata": "^0.1.13",
-    "rxjs": "^6.6.3",
+    "rxjs": "^7.3.0",
     "typeorm": "0.2.31"
   },
   "devDependencies": {

+ 6 - 6
packages/core/src/api/middleware/transaction-interceptor.ts

@@ -1,6 +1,6 @@
 import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
 import { Reflector } from '@nestjs/core';
-import { Observable, of } from 'rxjs';
+import { firstValueFrom, lastValueFrom, Observable, of } from 'rxjs';
 import { retryWhen, take, tap } from 'rxjs/operators';
 import { QueryRunner } from 'typeorm';
 import { TransactionAlreadyStartedError } from 'typeorm/error/TransactionAlreadyStartedError';
@@ -47,7 +47,7 @@ export class TransactionInterceptor implements NestInterceptor {
             // If a QueryRunner already exists on the RequestContext, there must be an existing
             // outer transaction in progress. In that case, we just execute the work function
             // as usual without needing to further wrap in a transaction.
-            return work().toPromise();
+            return firstValueFrom(work());
         }
         const queryRunner = this.connection.rawConnection.createQueryRunner();
         if (mode === 'auto') {
@@ -57,8 +57,8 @@ export class TransactionInterceptor implements NestInterceptor {
 
         try {
             const maxRetries = 5;
-            const result = await work()
-                .pipe(
+            const result = await lastValueFrom(
+                work().pipe(
                     retryWhen(errors =>
                         errors.pipe(
                             tap(err => {
@@ -69,8 +69,8 @@ export class TransactionInterceptor implements NestInterceptor {
                             take(maxRetries),
                         ),
                     ),
-                )
-                .toPromise();
+                ),
+            );
             if (queryRunner.isTransactionActive) {
                 await queryRunner.commitTransaction();
             }

+ 2 - 1
packages/core/src/api/resolvers/admin/import.resolver.ts

@@ -1,5 +1,6 @@
 import { Args, Mutation, Resolver } from '@nestjs/graphql';
 import { ImportInfo, MutationImportProductsArgs, Permission } from '@vendure/common/lib/generated-types';
+import { lastValueFrom } from 'rxjs';
 
 import { Importer } from '../../../data-import/providers/importer/importer';
 import { RequestContext } from '../../common/request-context';
@@ -18,6 +19,6 @@ export class ImportResolver {
     ): Promise<ImportInfo> {
         const { createReadStream, filename, mimetype, encoding } = await args.csvFile;
         const stream = createReadStream();
-        return this.importer.parseAndImport(stream, ctx).toPromise();
+        return lastValueFrom(this.importer.parseAndImport(stream, ctx));
     }
 }

+ 2 - 1
packages/core/src/cli/populate.ts

@@ -1,6 +1,7 @@
 import { INestApplicationContext } from '@nestjs/common';
 import fs from 'fs-extra';
 import path from 'path';
+import { lastValueFrom } from 'rxjs';
 
 import { logColored } from './cli-utils';
 
@@ -92,5 +93,5 @@ export async function importProductsFromCsv(
     const importer = app.get(Importer);
     const productData = await fs.readFile(productsCsvPath, 'utf-8');
 
-    return importer.parseAndImport(productData, languageCode, true).toPromise();
+    return lastValueFrom(importer.parseAndImport(productData, languageCode, true));
 }

+ 2 - 2
packages/core/src/common/utils.ts

@@ -1,6 +1,6 @@
 import { AssetType } from '@vendure/common/lib/generated-types';
 import { ID } from '@vendure/common/lib/shared-types';
-import { Observable, Observer } from 'rxjs';
+import { lastValueFrom, Observable, Observer } from 'rxjs';
 
 /**
  * Takes a predicate function and returns a negated version.
@@ -71,7 +71,7 @@ export function normalizeEmailAddress(input: string): string {
 export async function awaitPromiseOrObservable<T>(value: T | Promise<T> | Observable<T>): Promise<T> {
     let result = await value;
     if (result instanceof Observable) {
-        result = await result.toPromise();
+        result = await lastValueFrom(result);
     }
     return result;
 }

+ 1 - 1
packages/core/src/event-bus/event-bus.ts

@@ -77,7 +77,7 @@ export class EventBus implements OnModuleDestroy {
 
     /** @internal */
     onModuleDestroy(): any {
-        this.destroy$.next();
+        this.destroy$.next(null);
     }
 
     /**

+ 5 - 5
packages/core/src/job-queue/job-queue.service.spec.ts

@@ -154,21 +154,21 @@ describe('JobQueueService', () => {
 
         expect(await getStates()).toEqual([JobState.RUNNING, JobState.PENDING, JobState.PENDING]);
 
-        subject.next();
+        subject.next(undefined);
         await tick();
         expect(await getStates()).toEqual([JobState.COMPLETED, JobState.PENDING, JobState.PENDING]);
 
         await tick(queuePollInterval);
         expect(await getStates()).toEqual([JobState.COMPLETED, JobState.RUNNING, JobState.PENDING]);
 
-        subject.next();
+        subject.next(undefined);
         await tick();
         expect(await getStates()).toEqual([JobState.COMPLETED, JobState.COMPLETED, JobState.PENDING]);
 
         await tick(queuePollInterval);
         expect(await getStates()).toEqual([JobState.COMPLETED, JobState.COMPLETED, JobState.RUNNING]);
 
-        subject.next();
+        subject.next(undefined);
         await tick();
         expect(await getStates()).toEqual([JobState.COMPLETED, JobState.COMPLETED, JobState.COMPLETED]);
 
@@ -203,14 +203,14 @@ describe('JobQueueService', () => {
 
         expect(await getStates()).toEqual([JobState.RUNNING, JobState.RUNNING, JobState.PENDING]);
 
-        subject.next();
+        subject.next(undefined);
         await tick();
         expect(await getStates()).toEqual([JobState.COMPLETED, JobState.COMPLETED, JobState.PENDING]);
 
         await tick(queuePollInterval);
         expect(await getStates()).toEqual([JobState.COMPLETED, JobState.COMPLETED, JobState.RUNNING]);
 
-        subject.next();
+        subject.next(undefined);
         await tick();
         expect(await getStates()).toEqual([JobState.COMPLETED, JobState.COMPLETED, JobState.COMPLETED]);
 

+ 2 - 4
packages/core/src/job-queue/polling-job-queue-strategy.ts

@@ -1,8 +1,7 @@
 import { JobState } from '@vendure/common/lib/generated-types';
 import { ID } from '@vendure/common/lib/shared-types';
 import { isObject } from '@vendure/common/lib/shared-utils';
-import { interval, race, Subject, Subscription } from 'rxjs';
-import { fromPromise } from 'rxjs/internal-compatibility';
+import { from, interval, lastValueFrom, race, Subject, Subscription } from 'rxjs';
 import { filter, switchMap, take, throttleTime } from 'rxjs/operators';
 
 import { Logger } from '../config/logger/vendure-logger';
@@ -76,8 +75,7 @@ class ActiveQueue<Data extends JobData<Data> = {}> {
                         );
                         const stopSignal$ = this.queueStopped$.pipe(take(1));
 
-                        race(fromPromise(this.process(nextJob)), cancellationSignal$, stopSignal$)
-                            .toPromise()
+                        lastValueFrom(race(from(this.process(nextJob)), cancellationSignal$, stopSignal$))
                             .then(
                                 result => {
                                     if (result === STOP_SIGNAL) {

+ 1 - 1
packages/create/package.json

@@ -41,7 +41,7 @@
     "handlebars": "^4.7.6",
     "listr": "^0.14.3",
     "prompts": "^2.3.2",
-    "rxjs": "^6.6.3",
+    "rxjs": "^7.3.0",
     "semver": "^7.3.2",
     "tcp-port-used": "^1.0.1"
   }

+ 4 - 4
packages/dev-server/dev-config.ts

@@ -86,10 +86,10 @@ export const devConfig: VendureConfig = {
                 changeEmailAddressUrl: 'http://localhost:4201/change-email-address',
             },
         }),
-        // AdminUiPlugin.init({
-        //     route: 'admin',
-        //     port: 5001,
-        // }),
+        AdminUiPlugin.init({
+            route: 'admin',
+            port: 5001,
+        }),
     ],
 };
 

+ 1 - 1
packages/ui-devkit/package.json

@@ -45,7 +45,7 @@
     "chokidar": "^3.5.1",
     "fs-extra": "^9.1.0",
     "glob": "^7.1.6",
-    "rxjs": "^6.6.6"
+    "rxjs": "^7.3.0"
   },
   "devDependencies": {
     "@rollup/plugin-node-resolve": "^11.2.0",

File diff suppressed because it is too large
+ 66 - 411
yarn.lock


Some files were not shown because too many files changed in this diff