AzureStorage[FileShare]をNodejsから操作する(ダウンロード)

# 初めに
前回書いた[AzureStorageBlobのダウンロード](https://qiita.com/RyotaAmano/items/7b36fbbce016c5905318)のFileShare版です。


AzureのクラウドストレージであるAzureStorageFileShare。
そのFile共有サービスの中にある全てのファイルをローカル環境に一括ダウンロードするためのプログラム(TypeScript)を紹介します。

# 環境
* Node v14.17.0
* Windows10
* Typescript

# コード
1ファイルで紹介したかったため1ファイルにすべて詰め込んでありますが、
適宜管理しやすいようにファイルを分けたほうがいいと思います。
## package.json
前回と同じため割愛。
見たい方は前回の記事に書いてあるため、そちらをご確認ください。

## メインファイル

```index.ts
import fs from 'fs'
import path from 'path';
import { ShareServiceClient } from '@azure/storage-file-share';

interface AzureStorageFileSharedConfig {
  type: 'SAS' | 'CONSTR',
  connStr?: string,//CONSTR
  account?: string,//SAS
  sasToken?: string,//SAS
  shares: { shareName: string, directoryName: string[] },
}

const AuthController = (authobj: AzureStorageFileSharedConfig) => {
  switch (authobj.type) {
    case 'SAS':
      if (authobj.account && authobj.sasToken) {
        return AuthSas(authobj.account, authobj.sasToken)
      } else {
        console.log(authobj.type + 'の認証情報が足りません')
      }
      break
    case 'CONSTR':
      if (authobj.connStr) {
        return AuthConstr(authobj.connStr)
      } else {
        console.log(authobj.type + 'の認証情報が足りません')
      }
      break
  }
}

const AuthSas = (account: string, sastoken: string): ShareServiceClient => {
  return new ShareServiceClient(`https://${account}.file.core.windows.net/${sastoken}`);
}

const AuthConstr = (connstr: string): ShareServiceClient => {
  return ShareServiceClient.fromConnectionString(connstr);
}

//IIFE 即時関数
(async function main() {
  try {
    const authObj: AzureStorageFileSharedConfig = {
      type: 'CONSTR',
      connStr:'{your connection String}',
      shares: {
        shareName: '{your sharename}',
        directoryName: ['{your directory names}']
      }
    }

    const serviceClient = AuthController(authObj)

    if (serviceClient) {
      const AllfileASFileShared = async (sharename: string, dirname: string, serviceClient: ShareServiceClient, authObj: AzureStorageFileSharedConfig): Promise<any> => {
        let fileList: string[] = []
        const shareName = sharename;
        const directoryName = dirname;

        const directoryClient = serviceClient.getShareClient(shareName).getDirectoryClient(directoryName);
        let dirIter = directoryClient.listFilesAndDirectories();

        for await (const item of dirIter) {
          if (item.kind === "directory") {
            fileList.push(await AllfileASFileShared(sharename, `${dirname}/${item.name}`, serviceClient, authObj))
          } else {
            fileList.push(`./download/${shareName}/${directoryName}/${item.name}`)
          }
        }
        return fileList.flat(Infinity)
      }

      //downloadファイルのパス取得
      const fileList = await Promise.all(authObj.shares.directoryName.map(async dirname =>
        await AllfileASFileShared(authObj.shares.shareName, dirname, serviceClient, authObj)
      ))

      //download
      Promise.all(fileList.flat(Infinity).map(async value => {
        if (serviceClient) {
          const regex = new RegExp(`^.*?${authObj.shares.shareName}/`)
          //filePathからshareNameとファイル名を取り除く
          const direpath = path.dirname(value).replace(/^.*?download\//, '').replace(regex, '')
          const fileClient = serviceClient.getShareClient(authObj.shares.shareName).getDirectoryClient(direpath).getFileClient(path.basename(value));
          fs.mkdirSync(path.dirname(value), { recursive: true })
          console.log(value.replace(regex, ''))
          return await fileClient.downloadToFile(value);
        }
      }
      ))
    }
  } catch (e) {
    console.log(e)
  }
})()

```



# 使用方法
1. npmのインストール

1. メインファイルの即時関数と書いてあるあたりにある`authObj`に認証情報を入力する。
認証タイプは`接続文字列`、`SAS`の2つから選ぶことが出来ます。
`shareName`にはファイル共有の名前(ファイル共有の青色フォルダアイコンがある名前)
`directoryName`にはshareName内にあるフォルダの名前を入力して下さい。directoryNameは配列で複数入力することができます。
また、**sub1/sub2**のように/をつけて入力するとsub1フォルダ内のsub2フォルダ以下のファイルをダウンロードすることができます。

1. ダウンロードファイルの保存フォルダの確認
(デフォルトではメインファイルの階層に`downloadフォルダ`が作成され、そこに保存されます)

1. ダウンロードの実行`npm start`


# 終わりに
Blob版のほうもそうでしたが、認証の書き方に苦労しました。しかしAzureについては多くの文献や先駆者の方がいるため何とか形にできました。
皆様のお役に立てれば何よりです。ますます精進していきます。