Browse Source

storage-node: Fix linter issues.

Shamil Gadelshin 4 năm trước cách đây
mục cha
commit
e4d7cb4569

+ 36 - 30
storage-node/packages/cli/src/cli.ts

@@ -18,16 +18,15 @@
 
 'use strict'
 
-import { RuntimeApi } from "@joystream/storage-runtime-api"
-import meow from "meow"
-import _ from "lodash"
+import { RuntimeApi } from '@joystream/storage-runtime-api'
+import meow from 'meow'
+import _ from 'lodash'
 
 // Commands
-import * as dev from "./commands/dev"
-import {HeadCommand} from "./commands/head";
-import {DownloadCommand} from "./commands/download";
-import {UploadCommand} from "./commands/upload";
-
+import * as dev from './commands/dev'
+import { HeadCommand } from './commands/head'
+import { DownloadCommand } from './commands/download'
+import { UploadCommand } from './commands/upload'
 
 // Parse CLI
 const FLAG_DEFINITIONS = {
@@ -52,42 +51,56 @@ const usage = `
     dev-check         Check the chain is setup with Alice as lead and storage provider.
     
   Type 'storage-cli command' for the exact command usage examples.
-  `;
+  `
+
+const cli = meow(usage, { flags: FLAG_DEFINITIONS })
 
-const cli = meow(usage, { flags: FLAG_DEFINITIONS });
+// Shows a message, CLI general usage and exits.
+function showUsageAndExit(message: string) {
+  console.log(message)
+  console.log(usage)
+  process.exit(1)
+}
 
 const commands = {
   // add Alice well known account as storage provider
-  'dev-init': async api => {
+  'dev-init': async (api) => {
     // dev accounts are automatically loaded, no need to add explicitly to keyring using loadIdentity(api)
     return dev.init(api)
   },
   // Checks that the setup done by dev-init command was successful.
-  'dev-check': async api => {
+  'dev-check': async (api) => {
     // dev accounts are automatically loaded, no need to add explicitly to keyring using loadIdentity(api)
     return dev.check(api)
   },
   // Uploads the file to the system. Registers new data object in the runtime, obtains proper colossus instance URL.
-  upload: async (api: any, filePath: string, dataObjectTypeId: string, keyFile: string, passPhrase: string, memberId: string) => {
-    let uploadCmd = new UploadCommand(api, filePath, dataObjectTypeId, keyFile, passPhrase, memberId);
-
-    await uploadCmd.run();
+  upload: async (
+    api: any,
+    filePath: string,
+    dataObjectTypeId: string,
+    keyFile: string,
+    passPhrase: string,
+    memberId: string
+  ) => {
+    const uploadCmd = new UploadCommand(api, filePath, dataObjectTypeId, keyFile, passPhrase, memberId)
+
+    await uploadCmd.run()
   },
   // needs to be updated to take a content id and resolve it a potential set
   // of providers that has it, and select one (possibly try more than one provider)
   // to fetch it from the get api url of a provider..
   download: async (api: any, url: string, contentId: string, filePath: string) => {
-    let downloadCmd = new DownloadCommand(api, url, contentId, filePath);
+    const downloadCmd = new DownloadCommand(api, url, contentId, filePath)
 
-    await downloadCmd.run();
+    await downloadCmd.run()
   },
   // Shows asset information derived from response headers.
   // Accepts colossus URL and content ID.
   head: async (api: any, storageNodeUrl: string, contentId: string) => {
-    let headCmd = new HeadCommand(api, storageNodeUrl, contentId);
+    const headCmd = new HeadCommand(api, storageNodeUrl, contentId)
 
-    await headCmd.run();
-  }
+    await headCmd.run()
+  },
 }
 
 // Entry point.
@@ -97,7 +110,7 @@ export async function main() {
   // Simple CLI commands
   const command = cli.input[0]
   if (!command) {
-    showUsageAndExit('Enter the command, please.');
+    showUsageAndExit('Enter the command, please.')
   }
 
   if (Object.prototype.hasOwnProperty.call(commands, command)) {
@@ -105,13 +118,6 @@ export async function main() {
     const args = _.clone(cli.input).slice(1)
     await commands[command](api, ...args)
   } else {
-    showUsageAndExit(`Command "${command}" not recognized.`);
+    showUsageAndExit(`Command "${command}" not recognized.`)
   }
 }
-
-// Shows a message, CLI general usage and exits.
-function showUsageAndExit(message: string) {
-  console.log(message);
-  console.log(usage);
-  process.exit(1);
-}

+ 28 - 28
storage-node/packages/cli/src/commands/base.ts

@@ -1,39 +1,39 @@
-import chalk from "chalk";
-import removeEndingForwardSlash from "@joystream/storage-utils/stripEndingSlash";
+import chalk from 'chalk'
+import removeEndingForwardSlash from '@joystream/storage-utils/stripEndingSlash'
 
 // Commands base abstract class. Contains reusable methods.
 export abstract class BaseCommand {
-    // Creates the Colossus asset URL and logs it.
-    protected createAndLogAssetUrl(url: string, contentId: string): string {
-        const normalizedUrl = removeEndingForwardSlash(url);
-        const assetUrl = `${normalizedUrl}/asset/v0/${contentId}`;
-        console.log(chalk.yellow('Generated asset URL:', assetUrl));
+  // Creates the Colossus asset URL and logs it.
+  protected createAndLogAssetUrl(url: string, contentId: string): string {
+    const normalizedUrl = removeEndingForwardSlash(url)
+    const assetUrl = `${normalizedUrl}/asset/v0/${contentId}`
+    console.log(chalk.yellow('Generated asset URL:', assetUrl))
 
-        return assetUrl;
-    }
-
-    // Abstract method to provide parameter validation.
-    protected abstract validateParameters() : boolean;
+    return assetUrl
+  }
 
-    // Abstract method to show command usage.
-    protected abstract showUsage();
+  // Abstract method to provide parameter validation.
+  protected abstract validateParameters(): boolean
 
-    // Checks command parameters and shows the usage if necessary.
-    protected assertParameters() : boolean {
-        // Create, validate and show parameters.
-        if (!this.validateParameters()) {
-            console.log(chalk.yellow(`Invalid parameters for the command:`));
-            this.showUsage();
+  // Abstract method to show command usage.
+  protected abstract showUsage()
 
-            return false;
-        }
+  // Checks command parameters and shows the usage if necessary.
+  protected assertParameters(): boolean {
+    // Create, validate and show parameters.
+    if (!this.validateParameters()) {
+      console.log(chalk.yellow(`Invalid parameters for the command:`))
+      this.showUsage()
 
-        return true;
+      return false
     }
 
-    // Shows the error message and ends the process with error code.
-    protected fail(message: string) {
-        console.log(chalk.red(message));
-        process.exit(1);
-    }
+    return true
+  }
+
+  // Shows the error message and ends the process with error code.
+  protected fail(message: string) {
+    console.log(chalk.red(message))
+    process.exit(1)
+  }
 }

+ 3 - 9
storage-node/packages/cli/src/commands/dev.ts

@@ -19,7 +19,7 @@ function developmentPort() {
   return 3001
 }
 
-const check = async api => {
+const check = async (api) => {
   const roleAccountId = roleKeyPair(api).address
   const providerId = await api.workers.findProviderIdByRoleAccount(roleAccountId)
 
@@ -40,7 +40,7 @@ const check = async api => {
 // Setup Alice account on a developement chain as
 // a member, storage lead, and a storage provider using a deterministic
 // development key for the role account
-const init = async api => {
+const init = async (api) => {
   try {
     await check(api)
     return
@@ -124,10 +124,4 @@ module.exports = {
   developmentPort,
 }
 
-export {
-  init,
-  check,
-  aliceKeyPair,
-  roleKeyPair,
-  developmentPort,
-};
+export { init, check, aliceKeyPair, roleKeyPair, developmentPort }

+ 61 - 55
storage-node/packages/cli/src/commands/download.ts

@@ -1,71 +1,77 @@
-import axios from "axios";
-import chalk from "chalk"
-import fs from "fs";
-import {BaseCommand} from "./base";
+import axios from 'axios'
+import chalk from 'chalk'
+import fs from 'fs'
+import { BaseCommand } from './base'
 
 // Download command class. Validates input parameters and execute the logic for asset downloading.
-export class DownloadCommand extends BaseCommand{
-    private readonly api: any;
-    private readonly storageNodeUrl: string;
-    private readonly contentId: string;
-    private readonly outputFilePath: string;
+export class DownloadCommand extends BaseCommand {
+  private readonly api: any
+  private readonly storageNodeUrl: string
+  private readonly contentId: string
+  private readonly outputFilePath: string
 
-    constructor(api: any, storageNodeUrl: string, contentId: string, outputFilePath: string) {
-        super();
+  constructor(api: any, storageNodeUrl: string, contentId: string, outputFilePath: string) {
+    super()
 
-        this.api = api;
-        this.storageNodeUrl = storageNodeUrl;
-        this.contentId = contentId;
-        this.outputFilePath = outputFilePath;
-    }
+    this.api = api
+    this.storageNodeUrl = storageNodeUrl
+    this.contentId = contentId
+    this.outputFilePath = outputFilePath
+  }
 
-    // Provides parameter validation. Overrides the abstract method from the base class.
-    protected validateParameters(): boolean {
-        return this.storageNodeUrl && this.storageNodeUrl !== ""
-            && this.contentId && this.contentId !== ""
-            && this.outputFilePath && this.outputFilePath !== "";
-    }
+  // Provides parameter validation. Overrides the abstract method from the base class.
+  protected validateParameters(): boolean {
+    return (
+      this.storageNodeUrl &&
+      this.storageNodeUrl !== '' &&
+      this.contentId &&
+      this.contentId !== '' &&
+      this.outputFilePath &&
+      this.outputFilePath !== ''
+    )
+  }
 
-    // Shows command usage. Overrides the abstract method from the base class.
-    protected showUsage() {
-        console.log(chalk.yellow(`
+  // Shows command usage. Overrides the abstract method from the base class.
+  protected showUsage() {
+    console.log(
+      chalk.yellow(`
         Usage:   storage-cli download colossusURL contentID filePath
         Example: storage-cli download http://localhost:3001 0x7a6ba7e9157e5fba190dc146fe1baa8180e29728a5c76779ed99655500cff795 ./movie.mp4
-      `));
-    }
+      `)
+    )
+  }
 
-    // Command executor.
-    async run() {
-        // Checks for input parameters, shows usage if they are invalid.
-        if (!this.assertParameters()) return;
+  // Command executor.
+  async run() {
+    // Checks for input parameters, shows usage if they are invalid.
+    if (!this.assertParameters()) return
 
-        const assetUrl = this.createAndLogAssetUrl(this.storageNodeUrl, this.contentId);
-        console.log(chalk.yellow('File path:', this.outputFilePath));
+    const assetUrl = this.createAndLogAssetUrl(this.storageNodeUrl, this.contentId)
+    console.log(chalk.yellow('File path:', this.outputFilePath))
 
-        // Create file write stream and set error handler.
-        const writer = fs.createWriteStream(this.outputFilePath)
-            .on('error', (err) => {
-                this.fail(`File write failed: ${err}`);
-            });
+    // Create file write stream and set error handler.
+    const writer = fs.createWriteStream(this.outputFilePath).on('error', (err) => {
+      this.fail(`File write failed: ${err}`)
+    })
 
-        // Request file download.
-        try {
-            const response = await axios({
-                url: assetUrl,
-                method: 'GET',
-                responseType: 'stream'
-            });
+    // Request file download.
+    try {
+      const response = await axios({
+        url: assetUrl,
+        method: 'GET',
+        responseType: 'stream',
+      })
 
-            response.data.pipe(writer);
+      response.data.pipe(writer)
 
-            return new Promise((resolve) => {
-                writer.on('finish', () => {
-                    console.log("File downloaded.")
-                    resolve();
-                });
-            });
-        } catch (err) {
-            this.fail(`Colossus request failed: ${err.message}`);
-        }
+      return new Promise((resolve) => {
+        writer.on('finish', () => {
+          console.log('File downloaded.')
+          resolve()
+        })
+      })
+    } catch (err) {
+      this.fail(`Colossus request failed: ${err.message}`)
     }
+  }
 }

+ 40 - 39
storage-node/packages/cli/src/commands/head.ts

@@ -1,49 +1,50 @@
-import axios from "axios";
-import chalk from "chalk"
-import {BaseCommand} from "./base";
+import axios from 'axios'
+import chalk from 'chalk'
+import { BaseCommand } from './base'
 
 // Head command class. Validates input parameters and obtains the asset headers.
-export class HeadCommand extends BaseCommand{
-    private readonly api: any;
-    private readonly storageNodeUrl: string;
-    private readonly contentId: string;
-
-    constructor(api: any, storageNodeUrl: string, contentId: string) {
-        super();
-
-        this.api = api;
-        this.storageNodeUrl = storageNodeUrl;
-        this.contentId = contentId;
-    }
-
-    // Provides parameter validation. Overrides the abstract method from the base class.
-    protected validateParameters(): boolean {
-        return this.storageNodeUrl && this.storageNodeUrl !== "" && this.contentId && this.contentId !== "";
-    }
-
-    // Shows command usage. Overrides the abstract method from the base class.
-    protected showUsage() {
-        console.log(chalk.yellow(`
+export class HeadCommand extends BaseCommand {
+  private readonly api: any
+  private readonly storageNodeUrl: string
+  private readonly contentId: string
+
+  constructor(api: any, storageNodeUrl: string, contentId: string) {
+    super()
+
+    this.api = api
+    this.storageNodeUrl = storageNodeUrl
+    this.contentId = contentId
+  }
+
+  // Provides parameter validation. Overrides the abstract method from the base class.
+  protected validateParameters(): boolean {
+    return this.storageNodeUrl && this.storageNodeUrl !== '' && this.contentId && this.contentId !== ''
+  }
+
+  // Shows command usage. Overrides the abstract method from the base class.
+  protected showUsage() {
+    console.log(
+      chalk.yellow(`
         Usage:   storage-cli head colossusURL contentID
         Example: storage-cli head http://localhost:3001 0x7a6ba7e9157e5fba190dc146fe1baa8180e29728a5c76779ed99655500cff795
-      `));
-    }
-
-    // Command executor.
-    async run() {
-        // Checks for input parameters, shows usage if they are invalid.
-        if (!this.assertParameters()) return;
+      `)
+    )
+  }
 
-        const assetUrl = this.createAndLogAssetUrl(this.storageNodeUrl, this.contentId);
+  // Command executor.
+  async run() {
+    // Checks for input parameters, shows usage if they are invalid.
+    if (!this.assertParameters()) return
 
-        try {
-            const response = await axios.head(assetUrl);
+    const assetUrl = this.createAndLogAssetUrl(this.storageNodeUrl, this.contentId)
 
-            console.log(chalk.green(`Content type: ${response.headers['content-type']}`));
-            console.log(chalk.green(`Content length: ${response.headers['content-length']}`));
+    try {
+      const response = await axios.head(assetUrl)
 
-        } catch (err) {
-            this.fail(`Colossus request failed: ${err.message}`);
-        }
+      console.log(chalk.green(`Content type: ${response.headers['content-type']}`))
+      console.log(chalk.green(`Content length: ${response.headers['content-length']}`))
+    } catch (err) {
+      this.fail(`Colossus request failed: ${err.message}`)
     }
+  }
 }

+ 184 - 177
storage-node/packages/cli/src/commands/upload.ts

@@ -1,207 +1,214 @@
-import axios, {AxiosRequestConfig} from "axios";
-import fs from "fs";
-import ipfsHash from "ipfs-only-hash";
-import { ContentId, DataObject } from '@joystream/types/media';
-import BN from "bn.js";
-import { Option } from '@polkadot/types/codec';
-import {BaseCommand} from "./base";
-import {discover} from "@joystream/service-discovery/discover";
-import Debug from "debug";
-import chalk from "chalk";
-const debug = Debug('joystream:storage-cli:upload');
+import axios, { AxiosRequestConfig } from 'axios'
+import fs from 'fs'
+import ipfsHash from 'ipfs-only-hash'
+import { ContentId, DataObject } from '@joystream/types/media'
+import BN from 'bn.js'
+import { Option } from '@polkadot/types/codec'
+import { BaseCommand } from './base'
+import { discover } from '@joystream/service-discovery/discover'
+import Debug from 'debug'
+import chalk from 'chalk'
+const debug = Debug('joystream:storage-cli:upload')
 
 // Defines maximum content length for the assets (files). Limits the upload.
-const MAX_CONTENT_LENGTH = 500 * 1024 * 1024; // 500Mb
+const MAX_CONTENT_LENGTH = 500 * 1024 * 1024 // 500Mb
 
 // Defines the necessary parameters for the AddContent runtime tx.
 interface AddContentParams {
-    accountId: string,
-    ipfsCid: string,
-    contentId: string,
-    fileSize: BN,
-    dataObjectTypeId: number,
-    memberId: number
+  accountId: string
+  ipfsCid: string
+  contentId: string
+  fileSize: BN
+  dataObjectTypeId: number
+  memberId: number
 }
 
 // Upload command class. Validates input parameters and uploads the asset to the storage node and runtime.
-export class UploadCommand extends BaseCommand{
-    private readonly api: any;
-    private readonly mediaSourceFilePath: string;
-    private readonly dataObjectTypeId: string;
-    private readonly keyFile: string;
-    private readonly passPhrase: string;
-    private readonly memberId: string;
-
-    constructor(api: any,
-                mediaSourceFilePath: string,
-                dataObjectTypeId: string,
-                memberId: string,
-                keyFile: string,
-                passPhrase: string
-    ) {
-        super();
-
-        this.api = api;
-        this.mediaSourceFilePath = mediaSourceFilePath;
-        this.dataObjectTypeId = dataObjectTypeId;
-        this.memberId = memberId;
-        this.keyFile = keyFile;
-        this.passPhrase = passPhrase;
+export class UploadCommand extends BaseCommand {
+  private readonly api: any
+  private readonly mediaSourceFilePath: string
+  private readonly dataObjectTypeId: string
+  private readonly keyFile: string
+  private readonly passPhrase: string
+  private readonly memberId: string
+
+  constructor(
+    api: any,
+    mediaSourceFilePath: string,
+    dataObjectTypeId: string,
+    memberId: string,
+    keyFile: string,
+    passPhrase: string
+  ) {
+    super()
+
+    this.api = api
+    this.mediaSourceFilePath = mediaSourceFilePath
+    this.dataObjectTypeId = dataObjectTypeId
+    this.memberId = memberId
+    this.keyFile = keyFile
+    this.passPhrase = passPhrase
+  }
+
+  // Provides parameter validation. Overrides the abstract method from the base class.
+  protected validateParameters(): boolean {
+    return (
+      this.mediaSourceFilePath &&
+      this.mediaSourceFilePath !== '' &&
+      this.dataObjectTypeId &&
+      this.dataObjectTypeId !== '' &&
+      this.keyFile &&
+      this.keyFile !== '' &&
+      this.passPhrase &&
+      this.passPhrase !== '' &&
+      this.memberId &&
+      this.memberId !== ''
+    )
+  }
+
+  // Reads the file from the filesystem and computes IPFS hash.
+  private async computeIpfsHash(): Promise<string> {
+    const file = fs.createReadStream(this.mediaSourceFilePath).on('error', (err) => {
+      this.fail(`File read failed: ${err}`)
+    })
+
+    return await ipfsHash.of(file)
+  }
+
+  // Read the file size from the file system.
+  private getFileSize(): number {
+    const stats = fs.statSync(this.mediaSourceFilePath)
+    return stats.size
+  }
+
+  // Creates parameters for the AddContent runtime tx.
+  private async getAddContentParams(): Promise<AddContentParams> {
+    const identity = await this.loadIdentity()
+    const accountId = identity.address
+
+    const dataObjectTypeId: number = parseInt(this.dataObjectTypeId)
+    if (isNaN(dataObjectTypeId)) {
+      this.fail(`Cannot parse dataObjectTypeId: ${this.dataObjectTypeId}`)
     }
 
-    // Provides parameter validation. Overrides the abstract method from the base class.
-    protected validateParameters(): boolean {
-        return this.mediaSourceFilePath && this.mediaSourceFilePath !== ""
-            && this.dataObjectTypeId && this.dataObjectTypeId !== ""
-            && this.keyFile && this.keyFile !== ""
-            && this.passPhrase && this.passPhrase !== ""
-            && this.memberId && this.memberId !== ""
-
+    const memberId: number = parseInt(this.memberId)
+    if (isNaN(dataObjectTypeId)) {
+      this.fail(`Cannot parse memberIdString: ${this.memberId}`)
     }
 
-    // Reads the file from the filesystem and computes IPFS hash.
-    private async computeIpfsHash(): Promise<string> {
-        const file = fs.createReadStream(this.mediaSourceFilePath)
-            .on('error', (err) => {
-                this.fail(`File read failed: ${err}`);
-            });
-
-        return await ipfsHash.of(file);
+    return {
+      accountId,
+      ipfsCid: await this.computeIpfsHash(),
+      contentId: ContentId.generate().encode(),
+      fileSize: new BN(this.getFileSize()),
+      dataObjectTypeId,
+      memberId,
     }
-
-    // Read the file size from the file system.
-    private getFileSize(): number {
-        const stats = fs.statSync(this.mediaSourceFilePath);
-        return stats.size;
+  }
+
+  // Creates the DataObject in the runtime.
+  private async createContent(p: AddContentParams): Promise<DataObject> {
+    try {
+      const dataObject: Option<DataObject> = await this.api.assets.createDataObject(
+        p.accountId,
+        p.memberId,
+        p.contentId,
+        p.dataObjectTypeId,
+        p.fileSize,
+        p.ipfsCid
+      )
+
+      if (dataObject.isNone) {
+        this.fail('Cannot create data object: got None object')
+      }
+
+      return dataObject.unwrap()
+    } catch (err) {
+      this.fail(`Cannot create data object: ${err}`)
     }
-
-    // Creates parameters for the AddContent runtime tx.
-    private async getAddContentParams(): Promise<AddContentParams> {
-        const identity = await this.loadIdentity();
-        const accountId = identity.address;
-
-        let dataObjectTypeId: number = parseInt(this.dataObjectTypeId);
-        if (isNaN(dataObjectTypeId)) {
-            this.fail(`Cannot parse dataObjectTypeId: ${this.dataObjectTypeId}`);
-        }
-
-        let memberId: number = parseInt(this.memberId);
-        if (isNaN(dataObjectTypeId)) {
-            this.fail(`Cannot parse memberIdString: ${this.memberId}`);
-        }
-
-        return {
-            accountId,
-            ipfsCid: await this.computeIpfsHash(),
-            contentId: ContentId.generate().encode(),
-            fileSize: new BN(this.getFileSize()),
-            dataObjectTypeId,
-            memberId
-        };
+  }
+
+  // Uploads file to given asset URL.
+  private async uploadFile(assetUrl: string) {
+    // Create file read stream and set error handler.
+    const file = fs.createReadStream(this.mediaSourceFilePath).on('error', (err) => {
+      this.fail(`File read failed: ${err}`)
+    })
+
+    // Upload file from the stream.
+    try {
+      const fileSize = this.getFileSize()
+      const config: AxiosRequestConfig = {
+        headers: {
+          'Content-Type': '', // https://github.com/Joystream/storage-node-joystream/issues/16
+          'Content-Length': fileSize.toString(),
+        },
+        maxContentLength: MAX_CONTENT_LENGTH,
+      }
+      await axios.put(assetUrl, file, config)
+
+      console.log('File uploaded.')
+    } catch (err) {
+      this.fail(err.toString())
     }
+  }
 
-    // Creates the DataObject in the runtime.
-    private async createContent(p: AddContentParams): Promise<DataObject> {
-        try {
-            const dataObject: Option<DataObject> = await this.api.assets.createDataObject(
-                p.accountId,
-                p.memberId,
-                p.contentId,
-                p.dataObjectTypeId,
-                p.fileSize,
-                p.ipfsCid
-            );
-
-            if (dataObject.isNone) {
-                this.fail("Cannot create data object: got None object");
-            }
-
-            return dataObject.unwrap();
-        } catch (err) {
-            this.fail(`Cannot create data object: ${err}`);
-        }
-    }
-
-    // Uploads file to given asset URL.
-    private async uploadFile(assetUrl: string) {
-        // Create file read stream and set error handler.
-        const file = fs.createReadStream(this.mediaSourceFilePath)
-            .on('error', (err) => {
-                this.fail(`File read failed: ${err}`);
-            });
-
-        // Upload file from the stream.
-        try {
-            const fileSize = this.getFileSize();
-            const config: AxiosRequestConfig = {
-                headers: {
-                    'Content-Type': '', // https://github.com/Joystream/storage-node-joystream/issues/16
-                    'Content-Length': fileSize.toString()
-                },
-                'maxContentLength': MAX_CONTENT_LENGTH,
-            };
-            await axios.put(assetUrl, file, config);
-
-            console.log("File uploaded.");
-        } catch (err) {
-            this.fail(err.toString());
-        }
-    }
+  // Requests the runtime and obtains the storage node endpoint URL.
+  private async discoverStorageProviderEndpoint(storageProviderId: string): Promise<string> {
+    try {
+      const serviceInfo = await discover(storageProviderId, this.api)
 
-    // Requests the runtime and obtains the storage node endpoint URL.
-    private async discoverStorageProviderEndpoint(storageProviderId: string): Promise<string> {
-        try {
-            const serviceInfo = await discover(storageProviderId, this.api);
+      if (serviceInfo === null) {
+        this.fail('Storage node discovery failed.')
+      }
+      debug(`Discovered service info object: ${serviceInfo}`)
 
-            if (serviceInfo === null) {
-                this.fail("Storage node discovery failed.");
-            }
-            debug(`Discovered service info object: ${serviceInfo}`);
+      const dataWrapper = JSON.parse(serviceInfo)
+      const assetWrapper = JSON.parse(dataWrapper.serialized)
 
-            const dataWrapper = JSON.parse(serviceInfo);
-            const assetWrapper = JSON.parse(dataWrapper.serialized);
-
-            return assetWrapper.asset.endpoint;
-        } catch (err) {
-            this.fail(`Could not get asset endpoint: ${err}`);
-        }
+      return assetWrapper.asset.endpoint
+    } catch (err) {
+      this.fail(`Could not get asset endpoint: ${err}`)
     }
-
-    // Loads and unlocks the runtime identity using the key file and pass phrase.
-    private async loadIdentity(): Promise<any> {
-        try {
-            await fs.promises.access(this.keyFile);
-        } catch (error) {
-            this.fail(`Cannot read file "${this.keyFile}".`)
-        }
-
-        return this.api.identities.loadUnlock(this.keyFile, this.passPhrase);
+  }
+
+  // Loads and unlocks the runtime identity using the key file and pass phrase.
+  private async loadIdentity(): Promise<any> {
+    try {
+      await fs.promises.access(this.keyFile)
+    } catch (error) {
+      this.fail(`Cannot read file "${this.keyFile}".`)
     }
 
-    // Shows command usage. Overrides the abstract method from the base class.
-    protected showUsage() {
-        console.log(chalk.yellow(`
+    return this.api.identities.loadUnlock(this.keyFile, this.passPhrase)
+  }
+
+  // Shows command usage. Overrides the abstract method from the base class.
+  protected showUsage() {
+    console.log(
+      chalk.yellow(`
         Usage:   storage-cli upload mediaSourceFilePath dataObjectTypeId memberId keyFilePath passPhrase
         Example: storage-cli upload ./movie.mp4 1 1 ./keyFile.json secretPhrase
-      `));
-    }
+      `)
+    )
+  }
 
-    // Command executor.
-    async run() {
-        // Checks for input parameters, shows usage if they are invalid.
-        if (!this.assertParameters()) return;
+  // Command executor.
+  async run() {
+    // Checks for input parameters, shows usage if they are invalid.
+    if (!this.assertParameters()) return
 
-        let addContentParams = await this.getAddContentParams();
-        debug(`AddContent Tx params: ${JSON.stringify(addContentParams)}`);
-        debug(`Decoded CID: ${ContentId.decode(addContentParams.contentId).toString()}`);
+    const addContentParams = await this.getAddContentParams()
+    debug(`AddContent Tx params: ${JSON.stringify(addContentParams)}`)
+    debug(`Decoded CID: ${ContentId.decode(addContentParams.contentId).toString()}`)
 
-        let dataObject = await this.createContent(addContentParams);
-        debug(`Received data object: ${dataObject.toString()}`);
+    const dataObject = await this.createContent(addContentParams)
+    debug(`Received data object: ${dataObject.toString()}`)
 
-        let colossusEndpoint = await this.discoverStorageProviderEndpoint(dataObject.liaison.toString());
-        debug(`Discovered storage node endpoint: ${colossusEndpoint}`);
+    const colossusEndpoint = await this.discoverStorageProviderEndpoint(dataObject.liaison.toString())
+    debug(`Discovered storage node endpoint: ${colossusEndpoint}`)
 
-        let assetUrl = this.createAndLogAssetUrl(colossusEndpoint, addContentParams.contentId);
-        await this.uploadFile(assetUrl);
-    }
+    const assetUrl = this.createAndLogAssetUrl(colossusEndpoint, addContentParams.contentId)
+    await this.uploadFile(assetUrl)
+  }
 }