From 4c1cdcabcb53d81ed92f510d998b94b68f2e19bb Mon Sep 17 00:00:00 2001
From: Benoit Lavenier <benoit.lavenier@e-is.pro>
Date: Mon, 19 Sep 2022 22:59:03 +0200
Subject: [PATCH] [enh] Wallet: allow to add account

---
 package.json                                  |  1 +
 src/app/auth/auth.controller.ts               | 18 ++--
 src/app/home/home.page.html                   |  2 +-
 src/app/home/home.page.ts                     |  8 +-
 src/app/shared/pages/base.page.ts             |  4 +-
 .../services/storage/storage.service.ts       |  2 +-
 src/app/transfer/transfer.controller.ts       | 31 ++++---
 src/app/transfer/transfer.page.ts             | 19 ++--
 src/app/wallet/wallet.page.html               | 13 +--
 src/assets/i18n/fr.json                       |  1 +
 src/environments/environment.class.ts         |  2 +-
 yarn.lock                                     | 90 +++++++++++++++++++
 12 files changed, 153 insertions(+), 38 deletions(-)

diff --git a/package.json b/package.json
index af6c3d8..c67d543 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,7 @@
     "@polkadot/ui-settings": "^2.9.7",
     "@polkadot/util": "^10.1.6",
     "@polkadot/util-crypto": "^10.1.6",
+    "@rx-angular/state": "^1.7.0",
     "angular2-qrcode": "^2.0.3",
     "crypto-browserify": "^3.12.0",
     "jdenticon": "^3.1.1",
diff --git a/src/app/auth/auth.controller.ts b/src/app/auth/auth.controller.ts
index 5bcd6e7..bfd71bb 100644
--- a/src/app/auth/auth.controller.ts
+++ b/src/app/auth/auth.controller.ts
@@ -14,6 +14,7 @@ import {TranslateService} from "@ngx-translate/core";
 import {AuthModal, AuthModalOptions} from "@app/auth/auth.modal";
 import {Router} from "@angular/router";
 import {RegisterModal, RegisterModalOptions} from "@app/register/register.modal";
+import { Account } from "@app/wallet/account.model";
 
 export declare type LoginMethodType = 'v1' | 'v2' | 'keyfile-v1';
 export const LoginMethods: ListItem[] = [
@@ -120,7 +121,7 @@ export class AuthController {
     return data;
   }
 
-  async register(opts?: { redirectToWalletPage?: boolean; }) {
+  async register(opts?: { redirectToWalletPage?: boolean; }): Promise<Account> {
     const modal = await this.modalCtrl.create({
       component: RegisterModal,
       componentProps: <RegisterModalOptions>{
@@ -132,10 +133,17 @@ export class AuthController {
 
     const {data} = await modal.onWillDismiss();
 
-    if (data?.address && opts.redirectToWalletPage === true) {
-      setTimeout(() => this.router.navigate(['/wallet', data.address]));
-    }
+    try {
+      if (!data?.address) return null; // Skip
 
-    return data;
+      if (opts?.redirectToWalletPage) {
+        setTimeout(() => this.router.navigate(['/wallet', data.address]));
+      }
+
+      return data as Account;
+    }
+    finally {
+      await modal.onDidDismiss();
+    }
   }
 }
diff --git a/src/app/home/home.page.html b/src/app/home/home.page.html
index 7d658f0..30cbe6a 100644
--- a/src/app/home/home.page.html
+++ b/src/app/home/home.page.html
@@ -54,7 +54,7 @@
           </ion-button>
 
           <!-- transfer -->
-          <ion-button expand="block" [routerLink]="'/transfer'">
+          <ion-button expand="block" (click)="transfer()">
             <ion-icon name="paper-plane" slot="start"></ion-icon>
             <ion-label translate>COMMON.BTN_SEND_MONEY</ion-label>
           </ion-button>
diff --git a/src/app/home/home.page.ts b/src/app/home/home.page.ts
index 6cf6c3b..539a6a0 100644
--- a/src/app/home/home.page.ts
+++ b/src/app/home/home.page.ts
@@ -7,6 +7,7 @@ import {Account} from "@app/wallet/account.model";
 import {fadeInAnimation} from "@app/shared/animations";
 import {Router} from "@angular/router";
 import {AuthController} from "@app/auth/auth.controller";
+import { TransferController } from '@app/transfer/transfer.controller';
 
 @Component({
   selector: 'app-home',
@@ -28,6 +29,7 @@ export class HomePage extends BasePage<Settings> implements OnInit {
     public networkService: NetworkService,
     public accountService: AccountService,
     public authController: AuthController,
+    public transferController: TransferController,
     public router: Router,
     @Inject(APP_LOCALES) public locales: LocaleConfig[]
   ) {
@@ -78,9 +80,13 @@ export class HomePage extends BasePage<Settings> implements OnInit {
     }
   }
 
-  logout(event) {
+  logout(even?: UIEvent) {
     event?.preventDefault();
     this.accountService.forgetAll();
     this.defaultAccount = null;
   }
+
+  transfer(event?: UIEvent) {
+    return this.transferController.transfer(event);
+  }
 }
diff --git a/src/app/shared/pages/base.page.ts b/src/app/shared/pages/base.page.ts
index cdf4715..5212c75 100644
--- a/src/app/shared/pages/base.page.ts
+++ b/src/app/shared/pages/base.page.ts
@@ -21,8 +21,8 @@ export abstract class BasePage<
   >
   implements OnInit, OnDestroy {
 
-  private _cd: ChangeDetectorRef;
-  private _subscription: Subscription;
+  protected _cd: ChangeDetectorRef;
+  protected _subscription: Subscription;
 
   protected translate: TranslateService;
   protected settings: SettingsService;
diff --git a/src/app/shared/services/storage/storage.service.ts b/src/app/shared/services/storage/storage.service.ts
index ef2608b..64b28c1 100644
--- a/src/app/shared/services/storage/storage.service.ts
+++ b/src/app/shared/services/storage/storage.service.ts
@@ -4,7 +4,7 @@ import {StartableService} from "@app/shared/services/startable-service.class";
 import {IStorage} from "@app/shared/services/storage/storage.utils";
 import {Platform} from '@ionic/angular';
 import {environment} from "@environments/environment";
-import cordovaSQLiteDriver from 'localforage-cordovasqlitedriver';
+import * as cordovaSQLiteDriver from 'localforage-cordovasqlitedriver';
 
 @Injectable({providedIn: 'root'})
 export class StorageService extends StartableService<Storage>
diff --git a/src/app/transfer/transfer.controller.ts b/src/app/transfer/transfer.controller.ts
index 1567a1a..91f083b 100644
--- a/src/app/transfer/transfer.controller.ts
+++ b/src/app/transfer/transfer.controller.ts
@@ -25,24 +25,31 @@ export class TransferController {
   constructor(
     private platform: PlatformService,
     private translate: TranslateService,
-    private modalCtrl: ModalController
+    private modalCtrl: ModalController,
+    private router: Router
   ) {
   }
 
   async transfer(event: UIEvent, opts?: TransferPageOptions): Promise<string|undefined> {
 
-    console.info('[transfer] Opening transfer modal');
+    if (this._mobile) {
+      console.info('[transfer] Opening transfer page');
+      this.router.navigateByUrl('/transfer');
+    }
+    else {
+      console.info('[transfer] Opening transfer modal');
 
-    const modal = await this.modalCtrl.create({
-          component: TransferPage,
-          componentProps: <TransferPageOptions>{
-            ...opts,
-            dismissOnSubmit: true
-          }
-        });
-    await modal.present();
-    const {data} = await modal.onWillDismiss();
+      const modal = await this.modalCtrl.create({
+            component: TransferPage,
+            componentProps: <TransferPageOptions>{
+              ...opts,
+              dismissOnSubmit: true
+            }
+          });
+      await modal.present();
+      const {data} = await modal.onWillDismiss();
 
-    return data;
+      return data;
+    }
   }
 }
diff --git a/src/app/transfer/transfer.page.ts b/src/app/transfer/transfer.page.ts
index fbb8960..ed74baa 100644
--- a/src/app/transfer/transfer.page.ts
+++ b/src/app/transfer/transfer.page.ts
@@ -19,7 +19,7 @@ import {Currency} from "@app/network/currency.model";
 import {Router} from "@angular/router";
 import {BarcodeScanner} from "@capacitor-community/barcode-scanner";
 import {Capacitor} from "@capacitor/core";
-import {CapacitorPlugins} from "@app/shared/services/plugins";
+import {CapacitorPlugins} from "@app/shared/capacitor/plugins";
 
 export interface TransferPageOptions {
   issuer?: Account;
@@ -187,10 +187,10 @@ export class TransferPage extends BasePage<Observable<Account[]>> implements OnD
     }
   }
 
-  protected hideWotModal(event?: UIEvent) {
+  protected async hideWotModal(event?: UIEvent) {
     if (this.wotModal && this.wotModal.isCmpOpen) {
-      this.wotModal.dismiss();
       this._autoOpenWotModal = false;
+      await this.wotModal.dismiss();
     }
   }
 
@@ -234,7 +234,9 @@ export class TransferPage extends BasePage<Observable<Account[]>> implements OnD
   }
 
   async close(data?: any) {
+    // As a page
     if (this.routerOutlet) {
+      console.debug('[transfer] Closing page with result: ', data);
       if (this.routerOutlet?.canGoBack()) {
         this.routerOutlet.pop();
       }
@@ -242,10 +244,15 @@ export class TransferPage extends BasePage<Observable<Account[]>> implements OnD
         await this.router.navigateByUrl('/wallet');
       }
     }
+    // As a modal
     else {
-      const hasTop = !!(await this.modalCtrl.getTop())
-      if (hasTop) {
-        await this.modalCtrl.dismiss(data);
+      // First close wot modal (if opened)
+      await this.hideWotModal();
+
+      const modal = await this.modalCtrl.getTop();
+      const hasModal = !!modal;
+      if (hasModal) {
+        this.modalCtrl.dismiss(data);
       }
     }
 
diff --git a/src/app/wallet/wallet.page.html b/src/app/wallet/wallet.page.html
index 2b75279..06c81ec 100644
--- a/src/app/wallet/wallet.page.html
+++ b/src/app/wallet/wallet.page.html
@@ -5,25 +5,20 @@
     </ion-buttons>
     <ion-title translate>ACCOUNT.TITLE</ion-title>
     <ion-buttons slot="end">
-      <ion-select *ngIf="$account|async; let accounts"
+      <ion-select *ngIf="$accounts|async; let accounts"
                   [class.cdk-visually-hidden]="accounts|isEmptyArray"
                   [(ngModel)]="data"
+                  (ionChange)="onAccountChange($event)"
                   [interface]="mobile ? 'action-sheet' : 'popover'"
                   [interfaceOptions]="mobile ? actionSheetOptions : popoverOptions"
                   [okText]="'COMMON.BTN_OK'|translate"
                   [cancelText]="'COMMON.BTN_CANCEL'|translate">
         <ion-select-option *ngFor="let account of accounts"
                            [value]="account">
-
-          <ion-avatar *ngIf="loaded">
-            <svg width="40" width="40" [data-jdenticon-value]="data.data?.randomId||data.address"></svg>
-          </ion-avatar>
           {{account|accountName}}
         </ion-select-option>
-
-        <ion-select-option (click)="addNewWallet($event)"
-                           [value]="null"
-                           translate>ACCOUNT.WALLET_LIST.BTN_NEW</ion-select-option>
+        <ion-select-option [value]="new"
+                           translate>ACCOUNT.WALLET_LIST.BTN_NEW_DOTS</ion-select-option>
       </ion-select>
     </ion-buttons>
 
diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json
index 1e7c46c..00eb6b0 100644
--- a/src/assets/i18n/fr.json
+++ b/src/assets/i18n/fr.json
@@ -575,6 +575,7 @@
     "WALLET_LIST": {
       "TITLE": "Mes portefeuilles",
       "BTN_NEW": "Ajouter un portefeuille",
+      "BTN_NEW_DOTS": "Ajouter un portefeuille...",
       "BTN_DOWNLOAD": "Télécharger la liste",
       "BTN_IMPORT_FILE_DOTS": "Importer depuis un fichier...",
       "NO_WALLET": "Aucun portefeuille secondaire",
diff --git a/src/environments/environment.class.ts b/src/environments/environment.class.ts
index fd7b959..fd9ab0d 100644
--- a/src/environments/environment.class.ts
+++ b/src/environments/environment.class.ts
@@ -1,5 +1,5 @@
 import {AuthData} from "@app/auth/auth.model";
-import {StorageConfig} from '@ionic/storage-angular';
+import {StorageConfig} from '@ionic/storage';
 
 export interface Environment {
   name: string;
diff --git a/yarn.lock b/yarn.lock
index 78bbb45..554f6a0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2388,6 +2388,14 @@
     "@types/websocket" "^1.0.5"
     websocket "^1.0.34"
 
+"@rx-angular/state@^1.7.0":
+  version "1.7.0"
+  resolved "https://registry.yarnpkg.com/@rx-angular/state/-/state-1.7.0.tgz#54a1dbe34145c49b5101f13f89775f3e17aec34c"
+  integrity sha512-rrM5qlI6lDsSbTVo+uBoGpOuZ//msi2q72WYvw1MESPDrb9TnOLtVceDaYL0FBMDBhcqtmUsdOs6OoICaroSew==
+  dependencies:
+    ng-morph "^2.0.0"
+    tslib "^2.0.0"
+
 "@schematics/angular@14.2.2":
   version "14.2.2"
   resolved "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.2.tgz#3a9be8912e4f5a2d59c50e866b2853097fd656ff"
@@ -2458,6 +2466,16 @@
   resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz"
   integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
 
+"@ts-morph/common@~0.9.0":
+  version "0.9.2"
+  resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.9.2.tgz#fc63ed4f8d3a45e4ed6849fe20a57f4f2baecc5d"
+  integrity sha512-IPyg+c3Am0EBoa63W0f/AKeLrJhvzMzQ4BIvD1baxLopmiHOj1HFTXYxC6e8iTZ+UYtN+/WFM9UyGRnoA20b8g==
+  dependencies:
+    fast-glob "^3.2.5"
+    minimatch "^3.0.4"
+    mkdirp "^1.0.4"
+    path-browserify "^1.0.1"
+
 "@types/bn.js@^5.1.0":
   version "5.1.0"
   resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz"
@@ -2606,6 +2624,11 @@
   resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz"
   integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==
 
+"@types/minimatch@^3.0.3":
+  version "3.0.5"
+  resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
+  integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==
+
 "@types/node-fetch@^2.6.2":
   version "2.6.2"
   resolved "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz"
@@ -3212,6 +3235,11 @@ aria-query@^4.2.2:
     "@babel/runtime" "^7.10.2"
     "@babel/runtime-corejs3" "^7.10.2"
 
+array-differ@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b"
+  integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==
+
 array-flatten@1.1.1:
   version "1.1.1"
   resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz"
@@ -3265,6 +3293,11 @@ arrify@^1.0.0:
   resolved "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz"
   integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=
 
+arrify@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa"
+  integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==
+
 asn1.js@^5.2.0:
   version "5.4.1"
   resolved "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz"
@@ -3928,6 +3961,11 @@ clone@^1.0.2:
   resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz"
   integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
 
+code-block-writer@^10.1.1:
+  version "10.1.1"
+  resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-10.1.1.tgz#ad5684ed4bfb2b0783c8b131281ae84ee640a42f"
+  integrity sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==
+
 color-convert@^1.9.0:
   version "1.9.3"
   resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
@@ -5831,6 +5869,17 @@ fast-glob@^3.2.11, fast-glob@^3.2.9:
     merge2 "^1.3.0"
     micromatch "^4.0.4"
 
+fast-glob@^3.2.5:
+  version "3.2.12"
+  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80"
+  integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==
+  dependencies:
+    "@nodelib/fs.stat" "^2.0.2"
+    "@nodelib/fs.walk" "^1.2.3"
+    glob-parent "^5.1.2"
+    merge2 "^1.3.0"
+    micromatch "^4.0.4"
+
 fast-json-stable-stringify@2.1.0, fast-json-stable-stringify@^2.0.0:
   version "2.1.0"
   resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
@@ -7830,6 +7879,13 @@ minimalistic-crypto-utils@^1.0.1:
   resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz"
   integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==
 
+minimatch@3.0.4:
+  version "3.0.4"
+  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
+  integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
+  dependencies:
+    brace-expansion "^1.1.7"
+
 minimatch@3.0.5, minimatch@^3.0.4:
   version "3.0.5"
   resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz"
@@ -7975,6 +8031,17 @@ multicast-dns@^7.2.5:
     dns-packet "^5.2.2"
     thunky "^1.0.2"
 
+multimatch@5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6"
+  integrity sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==
+  dependencies:
+    "@types/minimatch" "^3.0.3"
+    array-differ "^3.0.0"
+    array-union "^2.1.0"
+    arrify "^2.0.1"
+    minimatch "^3.0.4"
+
 mute-stream@0.0.8:
   version "0.0.8"
   resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz"
@@ -8036,6 +8103,16 @@ next-tick@^1.1.0:
   resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz"
   integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
 
+ng-morph@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/ng-morph/-/ng-morph-2.1.0.tgz#3f5735962b112981de531c375b42311f18fa74d5"
+  integrity sha512-jn34Ter6HlY7E3yOoMhfk3cnUwjLlvcGTsAJ7jS0pZ3SAGi3hzqlf3oyUQO6fNfbFnydc33yNqQtUIrbHKCtNA==
+  dependencies:
+    jsonc-parser "3.0.0"
+    minimatch "3.0.4"
+    multimatch "5.0.0"
+    ts-morph "10.0.2"
+
 ngx-color-picker@^12.0.1:
   version "12.0.1"
   resolved "https://registry.npmjs.org/ngx-color-picker/-/ngx-color-picker-12.0.1.tgz#bb3159fd685dfd23505e5a27300fa32bb42ebce8"
@@ -8644,6 +8721,11 @@ parseurl@~1.3.2, parseurl@~1.3.3:
   resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz"
   integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
 
+path-browserify@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
+  integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==
+
 path-exists@^3.0.0:
   version "3.0.0"
   resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz"
@@ -10497,6 +10579,14 @@ tree-kill@1.2.2, tree-kill@^1.2.2:
   resolved "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz"
   integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
 
+ts-morph@10.0.2:
+  version "10.0.2"
+  resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-10.0.2.tgz#292418207db467326231b2be92828b5e295e7946"
+  integrity sha512-TVuIfEqtr9dW25K3Jajqpqx7t/zLRFxKu2rXQZSDjTm4MO4lfmuj1hn8WEryjeDDBFcNOCi+yOmYUYR4HucrAg==
+  dependencies:
+    "@ts-morph/common" "~0.9.0"
+    code-block-writer "^10.1.1"
+
 ts-node@^8.10.2:
   version "8.10.2"
   resolved "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d"
-- 
GitLab