# JavaScript SDK

## ダウンロードとインストール <a href="#download-and-installation" id="download-and-installation"></a>

### **NPMによるインストール** <a href="#install-with-npm" id="install-with-npm"></a>

```bash
npm install @keeper-security/secrets-manager-core
```

詳細については、<https://www.npmjs.com/package/@keeper-security/secrets-manager-core>をご参照ください。

### **ソースコード** <a href="#source-code" id="source-code"></a>

JavaScriptのソースコードは、[GitHubリポジトリ](https://github.com/Keeper-Security/secrets-manager/tree/master/sdk/javascript)で入手できます。

## SDKの使用 <a href="#using-the-sdk" id="using-the-sdk"></a>

### ストレージの初期化 <a href="#initialize-storage" id="initialize-storage"></a>

{% hint style="info" %}
トークンのみを使用して新しい構成 (後で使用するため) を生成する場合、トークンをバインドして `config.json`を完全に生成するために、少なくとも1回の読み取り操作が必要です。
{% endhint %}

シークレットを取得するには、まずマシンのローカルストレージを初期化する必要があります。

```javascript
initializeStorage(storage:KeyValueStorage, clientKey:String? = null, hostName:String? = null)
```

| パラメータ       | 型                 | 必須    | デフォルト | 説明                                                             |
| ----------- | ----------------- | ----- | ----- | -------------------------------------------------------------- |
| `storage`   | `KeyValueStorage` | はい    |       | 保存場所                                                           |
| `clientKey` | string            | オプション | null  | Keeperシークレットマネージャーに接続するためのトークン                                 |
| `hostName`  | string            | オプション | null  | シークレットを取得するサーバーの場所。 何も指定しない場合は、keepersecurity.com (米国) が使用されます |

#### **使用例** <a href="#example-usage" id="example-usage"></a>

```javascript
const { getSecrets, initializeStorage, localConfigStorage } = require('@keeper-security/secrets-manager-core')

const getKeeperRecords = async () => {

    // ワンタイムトークンはストレージの初期化に一度だけ使用
    // 初回実行以降の呼び出しでは、ksm-config.jsonを使用
    const oneTimeToken = "<One Time Access Token>";
    
    const storage = localConfigStorage("ksm-config.json")
    
    await initializeStorage(storage, oneTimeToken)
    // トークンのみを使用して（後で使用するために）設定を生成するには
    // トークンをバインドするアクセス操作が少なくとも1回必要です
    // トークンをバインドするには、以下の呼び出しの行頭のコメントを外す
    // await getSecrets({storage: storage})
    
    const {records} = await getSecrets({storage: storage})
    console.log(records)

    const firstRecord = records[0]
    const firstRecordPassword = firstRecord.data.fields.find(x => x.type === 'password')
    console.log(firstRecordPassword.value[0])
}

getKeeperRecords().finally()
```

### シークレットの取得 <a href="#retrieve-secrets" id="retrieve-secrets"></a>

```javascript
getSecrets(options:SecretsManagerOptions, recordsFilter:List<String> = emptyList()):KeeperSecrets
```

| パラメータ           | 型                 | 必須    | デフォルト | 説明           |
| --------------- | ----------------- | ----- | ----- | ------------ |
| `storage`       | `KeyValueStorage` | はい    |       | 保存場所         |
| `recordsFilter` | string\[]         | オプション | 空のリスト | 取得するレコードのUID |

**レスポンス**

型: `KeeperSecrets`

すべてのKeeperのレコード、または指定したフィルタ条件に一致するレコードを含むオブジェクト

**使用例**

すべてのシークレットを取得

```javascript
const storage = inMemoryStorage() // 初期化の例を参照
const secrets = await getSecrets({storage: storage})
```

### タイトルでシークレットを取得 <a href="#retrieve-secrets-by-title" id="retrieve-secrets-by-title"></a>

```javascript
// 一致するレコードをすべて取得
getSecretsByTitle = async (options:SecretManagerOptions, recordTitle: string):Promise<KeeperRecord[]>

// 最初に一致したレコードだけを取得
getSecretByTitle = async (options:SecretManagerOptions, recordTitle: string):Promise<KeeperRecord>
```

<table><thead><tr><th width="178.10385756676556">パラメータ</th><th width="150">型</th><th width="150">必須</th><th>説明</th></tr></thead><tbody><tr><td><code>options</code></td><td>SecretsManagerOptions</td><td>はい</td><td>事前に設定されたオプション</td></tr><tr><td><code>recordTitle</code></td><td>string</td><td>はい</td><td>検索するレコードタイトル</td></tr></tbody></table>

**使用例**

```javascript
const {
    getSecretByTitle,
    localConfigStorage,
} = require('@keeper-security/secrets-manager-core')

const getKeeperRecord = async () => {
    const options = { storage: localConfigStorage("ksm-config.json") }
    const myCredential = await getSecretByTitle(options, "My Credential")
}

getKeeperRecord().finally()
```

### シークレットから値を取得 <a href="#retrieve-values-from-a-secret" id="retrieve-values-from-a-secret"></a>

**パスワードを取得**

{% tabs %}
{% tab title="パスワード取得" %}

```javascript
secret.data.fields.find(x => x.type === 'password')
```

{% endtab %}

{% tab title="用例" %}

```javascript
const { getSecrets, initializeStorage, localConfigStorage } = require('@keeper-security/secrets-manager-core')

const getKeeperRecords = async () => {
    const storage = localConfigStorage("ksm-config.json")
    // レコードを取得
    const {records} = await getSecrets({storage: storage})
    // 最初のレコードからパスワードを取得
    const firstRecord = records[0]
    const firstRecordPassword = firstRecord.data.fields.find(x => x.type === 'password')
}
```

{% endtab %}
{% endtabs %}

フィールドタイプはKeeper[レコードタイプ](/enterprise-guide/jp/record-types.md)に基づきます。利用可能なフィールドの詳細な一覧については、コマンダーで [`record-type-info`](/keeperpam/jp/commander-cli/command-reference/record-commands/record-type-commands.md#record-type-info-command) コマンドをご参照ください。

**Keeper表記法を使用して他のフィールドを取得**

{% tabs %}
{% tab title="値を取得" %}

```javascript
getValue(secrets:KeeperSecrets, query: string): any
```

{% endtab %}

{% tab title="用例" %}

```javascript
const {
    getSecrets,
    localConfigStorage,
    getValue
} = require('@keeper-security/secrets-manager-core')

const getKeeperRecords = async () => {
    const options = { storage: localConfigStorage("ksm-config.json") }
    
    // シークレットを取得
    const secrets = await getSecrets(options)

    // ドット記法でログインを取得
    const loginValue = getValue(secrets, 'RECORD_UID/field/login')
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Keeper表記法の形式と機能については、[Keeper表記法のページ](/keeperpam/jp/secrets-manager/about/keeper-notation.md)をご参照ください。
{% endhint %}

| パラメータ     | 型               | 必須 | デフォルト | 説明                |
| --------- | --------------- | -- | ----- | ----------------- |
| `secrets` | `KeeperSecrets` | はい |       | 照会するシークレット        |
| `query`   | `string`        | はい |       | Keeper表記法を使用したクエリ |

#### **戻り値** <a href="#returns" id="returns"></a>

型: `any`

ドット記法のクエリで指定した位置にフィールド値がある場合はその値。ない場合は `undefined`。

### **TOTPコードを取得** <a href="#retrieve-a-totp-code" id="retrieve-a-totp-code"></a>

{% tabs %}
{% tab title="TOTPコードを取得" %}

```javascript
getTotpCode(
    url: string,
    unixTimeSeconds?: number
): Promise<{
    code: string
    timeLeft: number
    period: number
} | null>
```

{% endtab %}

{% tab title="使用例" %}

```javascript
const {
    getSecrets,
    localConfigStorage,
    getTotpCode,
    getValue} = require('@keeper-security/secrets-manager-core')

const getKeeperRecords = async () => {
    const options = { storage: localConfigStorage("ksm-config.json") }

    // シークレットを取得
    const secrets = await getSecrets(options)

    // Keeper表記法でレコードからTOTPのURIを取得
    const totpUri = getValue(secrets, 'RECORD_UID/field/oneTimeCode')

    // TOTPコードを取得
    const totpResult = await getTotpCode(totpUri)

    if (totpResult) {
        console.log(`TOTP Code: ${totpResult.code}`)
        console.log(`Expires in: ${totpResult.timeLeft} seconds`)
        console.log(`Period: ${totpResult.period} seconds`)
    } else {
        console.log('Invalid TOTP URL')
    }
}

getKeeperRecords().finally()
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Keeper表記法の形式と機能については、[Keeper表記法のページ](/keeperpam/jp/secrets-manager/about/keeper-notation.md)をご参照ください。
{% endhint %}

| パラメータ | 型        | 必須 | デフォルト | 説明       |
| ----- | -------- | -- | ----- | -------- |
| `url` | `string` | はい |       | TOTP Url |

| パラメータ             | 型        | 必須    | デフォルト      | 説明                        |
| ----------------- | -------- | ----- | ---------- | ------------------------- |
| `url`             | `string` | はい    |            | TOTP URL                  |
| `unixTimeSeconds` | `number` | オプション | 現在のタイムスタンプ | 秒単位のUnixタイムスタンプ (テストや検証用) |

* 表記法のクエリで指定するレコードUIDは、`secrets` パラメーターに渡したシークレットに含まれる必要があります。含まれない場合、クエリでは見つかりません。

#### **戻り値** <a href="#returns-1" id="returns-1"></a>

型: `Promise<{code: string, timeLeft: number, period: number} | null>`

次のプロパティを持つオブジェクト。

* `code` - TOTPコード (6〜8桁)
* `timeLeft` - コードが失効するまでの残り秒数
* `period` - TOTPの周期 (秒)。通常は30

TOTP URLが無効な場合や処理できない場合は `null` を返します。

### シークレットを更新 <a href="#update-a-secret" id="update-a-secret"></a>

{% hint style="warning" %}
レコードを更新するコマンドは、成功してもローカルのレコード情報 (特に更新後のレコードのリビジョン) が自動では更新されません。そのため、すでに更新済みのレコードに続けて更新を行うと、リビジョンの不一致で失敗します。各更新バッチの後に、更新したレコードをすべて再読み込みしてください。
{% endhint %}

{% tabs %}
{% tab title="シークレットの更新" %}

```javascript
updateSecret(options, record)
```

{% endtab %}

{% tab title="使用例" %}

<pre class="language-javascript"><code class="lang-javascript"><strong>const { 
</strong>    getSecrets, 
    localConfigStorage, 
    updateSecret} = require('@keeper-security/secrets-manager-core')

const storage = localConfigStorage("ksm-config.json")

// レコードを取得
const {records} = await getSecrets({storage: storage})

// 最初のレコードを取得
const recordToUpdate = records[0]

// 新しいレコードタイトルとメモを設定
recordToUpdate.data.title = 'New Title'
recordToUpdate.data.notes = "New Notes"

// レコードの変更を保存
await updateSecret(options, recordToUpdate)
</code></pre>

{% endtab %}

{% tab title="トランザクションによる更新" %}

<pre class="language-javascript"><code class="lang-javascript"><strong>const { 
</strong>    getSecrets, 
    localConfigStorage, 
    updateSecret,
    completeTransaction,
    UpdateTransactionType,
    SecretManagerOptions
} = require('@keeper-security/secrets-manager-core')

// レコードを取得
const options = { storage: localConfigStorage("ksm-config.json") }
const {records} = await getSecrets(options)

// 最初のレコードのパスワードをローテーション
const secret = records[0]
const password = secret.data.fields.find(x => x.type === "password")
password.value[0] = "MyNewPassword"

// ボールト内のレコードを更新するためにトランザクションを開始
await updateSecret(options, secret, UpdateTransactionType.Rotation)

// リモートホスト上のパスワードをローテーション
const success = rotateRemoteSshPassword("MyNewPassword");

// トランザクションを完了（コミットまたはロールバック）
const rollback = !success
await completeTransaction(options, secret.recordUid, rollback)
</code></pre>

{% endtab %}
{% endtabs %}

<table data-header-hidden><thead><tr><th width="150">パラメータ</th><th width="257">型</th><th width="150">必須</th><th>デフォルト</th><th>説明</th></tr></thead><tbody><tr><td>パラメータ</td><td>型</td><td>必須</td><td>デフォルト</td><td>説明</td></tr><tr><td><code>options</code></td><td><code>SecretManagerOptions</code></td><td>はい</td><td></td><td></td></tr><tr><td><code>record</code></td><td><code>KeeperRecord</code></td><td>はい</td><td></td><td></td></tr></tbody></table>

**戻り値**

**型:** `Promise<void>`

### ランダムなパスワードを生成 <a href="#generate-a-random-password" id="generate-a-random-password"></a>

{% tabs %}
{% tab title="パスワードを生成" %}

```javascript
generatePassword(length, lowercase, uppercase, digits, specialCharacters)
```

{% endtab %}

{% tab title="使用例" %}

```javascript
const { 
    getSecrets,
    localConfigStorage,
    updateSecret,
    generatePassword } = require('@keeper-security/secrets-manager-core')

// ランダムなパスワードを生成
let newRandomPwd = await generatePassword()

const storage = localConfigStorage("ksm-config.json")
const {records} = await getSecrets({storage: storage})

// 最初のレコードを取得
const recordToUpdate = records[0]

// タイプが「password」のフィールドを検索
const recordToUpdatePasswordField = recordToUpdate.data.fields.find(x => x.type === 'password')

// 「password」フィールドに新しい値を設定
recordToUpdatePasswordField.value[0] = newRandomPwd

await updateSecret({storage: storage}, recordToUpdate)
```

{% endtab %}
{% endtabs %}

<table><thead><tr><th width="203.7142857142857">パラメータ</th><th width="150">型</th><th width="150">必須</th><th>デフォルト</th></tr></thead><tbody><tr><td>length</td><td><code>int</code></td><td>オプション</td><td>64</td></tr><tr><td>lowercase</td><td><code>int</code></td><td>オプション</td><td>0</td></tr><tr><td>uppercase</td><td><code>int</code></td><td>オプション</td><td>0</td></tr><tr><td>digits</td><td><code>int</code></td><td>オプション</td><td>0</td></tr><tr><td>specialCharacters</td><td><code>int</code></td><td>オプション</td><td>0</td></tr></tbody></table>

各パラメーターは、それぞれの文字タイプを最低何文字含めるかを指定します。たとえば、`uppercase` は「大文字を最低何文字含めるか」を示します。

#### 戻り値 <a href="#returns-2" id="returns-2"></a>

型: `String`

### ファイルのダウンロード <a href="#download-a-file" id="download-a-file"></a>

```javascript
downloadFile(file:KeeperFile):ByteArray
```

| パラメータ  | 型            | 必須 | デフォルト | 説明           |
| ------ | ------------ | -- | ----- | ------------ |
| `file` | `KeeperFile` | はい |       | ダウンロードするファイル |

**レスポンス**

型: `Promise<Uint8Array>`

ダウンロード用のファイルのバイト列

### **サムネイル**のダウンロード <a href="#download-a-thumbnail" id="download-a-thumbnail"></a>

```javascript
downloadThumbnail(file:KeeperFile):ByteArray
```

| パラメータ  | 型            | 必須 | デフォルト | 説明                  |
| ------ | ------------ | -- | ----- | ------------------- |
| `file` | `KeeperFile` | はい |       | ダウンロードするサムネイル付きファイル |

**レスポンス**

型: `Promise<Uint8Array>`

ダウンロード用サムネイルのバイト列

### ファイルのアップロード <a href="#upload-a-file" id="upload-a-file"></a>

ファイルのアップロード:

```javascript
uploadFile = async (options:SecretManagerOptions, ownerRecord:KeeperRecord, file:KeeperFileUpload):Promise<string>
```

<table><thead><tr><th width="184.14763231197773">パラメータ</th><th width="246.99431983802478">型</th><th width="150">必須</th><th>説明</th></tr></thead><tbody><tr><td><code>options</code></td><td>SecretsManagerOptions</td><td>はい</td><td>ストレージとクエリの設定</td></tr><tr><td><code>ownerRecord</code></td><td>KeeperRecord</td><td>はい</td><td>アップロードされたファイルを添付するレコード</td></tr><tr><td><code>file</code></td><td>KeeperFileUpload</td><td>はい</td><td>アップロードするファイル</td></tr></tbody></table>

Keeperファイルアップロードオブジェクトを作成:

```javascript
type KeeperFileUpload = {
    name: string
    title: string
    type?: string
    data:Uint8Array
}
```

<table><thead><tr><th width="169">パラメータ</th><th width="150">型</th><th width="150">必須</th><th>説明</th></tr></thead><tbody><tr><td><code>name</code></td><td>string</td><td>はい</td><td>アップロード後にKeeperに格納されるファイルの名前</td></tr><tr><td><code>title</code></td><td>string</td><td>はい</td><td>アップロード後にKeeperに格納されるファイルのタイトル</td></tr><tr><td><code>type</code></td><td>string</td><td>オプション</td><td>ファイルのデータのMIMEタイプ。何も指定しない場合は、「application/octet-stream」が使用されます</td></tr><tr><td><code>data</code></td><td>Uint8Array</td><td>はい</td><td>バイト型のファイルデータ</td></tr></tbody></table>

**使用例**

```javascript
// ファイルを添付するレコードを取得
const {records} = await getSecrets({storage: storage}, ['XXX'])
const ownerRecord = records[0]

// アップロードするファイルデータを取得
const fileData = fs.readFileSync('./assets/my-file.json')

// 選択したレコードにファイルをアップロード
await uploadFile(options, ownerRecord, {
    name: 'my-file.json',
    title:'Sample File',
    type: 'application/json',
    data: fileData
})
```

### シークレットの作成 <a href="#create-a-secret" id="create-a-secret"></a>

#### 要件 <a href="#prerequisites" id="prerequisites"></a>

* 共有フォルダのUID
  * 共有フォルダには、シークレットマネージャーアプリケーションからアクセスできること
  * ユーザーとシークレットマネージャーアプリケーションには編集権限が付与されていること
  * 共有フォルダには、少なくとも1つのレコードが存在すること
* 作成されたレコードとレコードのフィールドは正しい形式で設定されていること
  * 各レコードタイプのフィールド形式については、[こちらのページ](/keeperpam/jp/commander-cli/command-reference/record-commands/default-record-types.md#field-types)をご参照ください
* TOTPフィールドには、KSM SDK以外で生成されたURLのみを指定できます
* レコード作成後、添付ファイルは [uploadFile](#upload-a-file) でアップロードできます

{% tabs %}
{% tab title="レコードを作成" %}

<pre class="language-javascript"><code class="lang-javascript"><strong>createSecret(options, folderUid, record)
</strong></code></pre>

<table><thead><tr><th width="166">パラメータ</th><th width="226">型</th><th>必須</th><th>デフォルト</th></tr></thead><tbody><tr><td>options</td><td>SecretManagerOptions</td><td>はい</td><td></td></tr><tr><td>folderUid</td><td>string</td><td>はい</td><td></td></tr><tr><td>record</td><td>JSON Object</td><td>はい</td><td></td></tr></tbody></table>
{% endtab %}

{% tab title="サブフォルダでレコードを作成" %}

<pre class="language-javascript"><code class="lang-javascript"><strong>createSecret2(options, createOptions, record)
</strong></code></pre>

<table><thead><tr><th width="166">パラメータ</th><th width="226">型</th><th>必須</th><th>デフォルト</th></tr></thead><tbody><tr><td>options</td><td>SecretManagerOptions</td><td>はい</td><td></td></tr><tr><td>createOptions</td><td>CreateOptions</td><td>はい</td><td></td></tr><tr><td>record</td><td>JSON Object</td><td>はい</td><td></td></tr></tbody></table>
{% endtab %}

{% tab title="ログイン情報レコードの例" %}
この例では、ログイン値と生成されたパスワードを含むログイン情報タイプのレコードを作成します。

{% hint style="info" %}
例の `[FOLDER UID]` を、シークレットマネージャーアプリケーションがアクセスできる共有フォルダのUIDに置き換えます。
{% endhint %}

```javascript
let newRec = {
    "title": "Sample KSM Record: JavaScript",
    "type": "login",
    "fields": [
        { "type": "login",    "value": [ "username@email.com" ] },
        { "type": "password", "value": [ await generatePassword() ] }
    ],
    "notes": "This is a JavaScript record creation example"
}

let recordUid = await createSecret(options, folderUid, newRec)
```

{% endtab %}

{% tab title="カスタムタイプの例" %}
この例では、カスタムのレコードタイプのレコードを作成します。

{% hint style="info" %}
例の `[FOLDER UID]` を、シークレットマネージャーアプリケーションがアクセスできる共有フォルダのUIDに置き換えます。
{% endhint %}

```javascript
let newRec = {
    "title": "Sample Custom Type KSM Record: JavaScript",
    "type": "Custom Login",
    "fields": [
        {
            "type": "host",
            "label":"My Custom Host lbl",
            "value": [ {"hostName":"127.0.0.1", "port":"8080"} ],
            "required": true,
            "privacyScreen": false
        },
        {
            "type": "login",
            "label":"My Custom Login lbl",
            "value": [ "login@email.com" ],
            "required": true,
            "privacyScreen": false
        },
        {
            "type": "password",
            "label":"My Custom Password lbl",
            "value": [ await generatePassword() ],
            "required": true,
            "privacyScreen": false
        },
        {
            "type": "url",
            "label":"My Login Page",
            "value": [ "http://localhost:8080/login" ],
            "required": true,
            "privacyScreen": false
        },
        {
            "type": "securityQuestion",
            "label":"My Question 1",
            "value": [ {
                "question":"What is one plus one (write just a number)",
                "answer":"2"
            } ],
            "required": true,
            "privacyScreen": false
        },
        {
            "type": "phone",
            "value": [{
                "region":"US",
                "number":"510-444-3333",
                "ext":"2345",
                "type":"Mobile"
            }],
            "label":"My Phone Number"
        },
        {
            "type": "date",
            "value": [ 1641934793000 ],
            "label":"My Date Lbl",
            "required": true,
            "privacyScreen": false
        },
        {
            "type": "name",
            "value": [{
                "first":"John",
                "middle":"Patrick",
                "last":"Smith"
            }],
            "label":"My Custom Name lbl",
            "required": true,
            "privacyScreen": false
        },
        {
            "type": "oneTimeCode",
            "label":"My TOTP",
            "value": ["otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example"],
            "required": true,
            "privacyScreen": false
        }
    ],
    "custom": [
        {
            "type": "phone",
            "value": [{
                "region":"US",
                "number": "(510) 123-3456"
            }],
            "label":"My Custom Phone Lbl 1"
        },
        {
            "type": "phone",
            "value": [ {
                "region":"US",
                "number":"510-111-3333",
                "ext":"45674",
                "type":"Mobile" } ],
            "label":"My Custom Phone Lbl 2"
        }
    ],
    "notes": "\tThis custom type record was created\n\tvia KSM Katacoda JavaScript Example"
}

let recordUid = await createSecret(options, "[FOLDER UID]", newRec)
```

{% endtab %}
{% endtabs %}

### シークレットの削除 <a href="#delete-a-secret" id="delete-a-secret"></a>

JavaScript KSM SDKでKeeperボルトのレコードを削除できます。

{% tabs %}
{% tab title="シークレットの削除" %}

```javascript
deleteSecret(smOptions, recordUids);
```

<table><thead><tr><th>パラメータ</th><th width="250.66666666666666">型</th><th align="center">必須</th></tr></thead><tbody><tr><td><code>smOptions</code></td><td><code>SecretManagerOptions</code></td><td align="center">はい</td></tr><tr><td><code>recordUids</code></td><td><code>string[]</code></td><td align="center">はい</td></tr></tbody></table>
{% endtab %}

{% tab title="使用例" %}

<pre class="language-javascript"><code class="lang-javascript">// シークレットマネージャーを設定
const smOptions = { storage: localConfigStorage("ksm-config.json") 

// レコードUIDで特定のシークレットを削除
<strong>await deleteSecret(smOptions, ["EG6KdJaaLG7esRZbMnfbFA"]);
</strong></code></pre>

{% endtab %}
{% endtabs %}

### キャッシュ <a href="#caching" id="caching"></a>

ネットワークへのアクセスが失われた際にシークレットへのアクセスも失うという事態を避けるため、JavaScript SDKでは、シークレットを暗号化されたファイルとしてローカルマシンにキャッシュすることができます。

`SecretManagerOptions` に `queryFunction: cachingPostFunction` を追加

使用例:

```javascript
const options:SecretManagerOptions = {    
    storage: kvs,
    queryFunction: cachingPostFunction // `cachingPostFunction` をインポートする
}
```

### フォルダ <a href="#folders" id="folders"></a>

フォルダは完全なCRUD (作成、読み取り、更新、削除操作) に対応しています。

### フォルダの読み取り <a href="#read-folders" id="read-folders"></a>

フォルダの完全な階層構造をダウンロードします。

```javascript
getFolders = async (options:SecretManagerOptions):Promise<KeeperFolder[]>
```

**レスポンス**

型: `KeeperFolder[]`

**使用例**

```javascript
const storage = localConfigStorage("ksm-config.json")
const folders = await getFolders({storage: storage})
```

### フォルダの作成 <a href="#create-a-folder" id="create-a-folder"></a>

作成には `CreateOptions` とフォルダ名の指定が必要です。`CreateOptions` に含まれる `folder UID` パラメータは必須で、これは共有フォルダのUIDを指定します。`sub-folder UID` は任意で、省略された場合は、指定された共有フォルダの直下に通常のフォルダが新規作成されます。なお、`sub-folder UID` は必ずしも親の共有フォルダの直下である必要はなく、何階層も深い位置を指定することも可能です。

```javascript
createFolder = async (options:SecretManagerOptions, createOptions:CreateOptions, folderName: string):Promise<string>
```

<table><thead><tr><th width="181.85161529417937">パラメータ</th><th width="242.99431983802478">型</th><th width="102">必須</th><th>説明</th></tr></thead><tbody><tr><td><code>options</code></td><td><code>SecretsManagerOptions</code></td><td>はい</td><td>事前に設定されたオプション</td></tr><tr><td><code>createOptions</code></td><td><code>CreateOptions</code></td><td>はい</td><td>親およびサブフォルダのUID</td></tr><tr><td><code>folderName</code></td><td><code>string</code></td><td>はい</td><td>フォルダ名</td></tr></tbody></table>

```javascript
type CreateOptions = {
    folderUid: string
    subFolderUid?: string
}
```

**使用例**

```javascript
const storage = localConfigStorage("ksm-config.json")
const folderUid = await createFolder({storage: storage}, {folderUid: "[PARENT_SHARED_FOLDER_UID]"}, "new_folder")
```

### フォルダの更新 <a href="#update-a-folder" id="update-a-folder"></a>

フォルダのメタデータ (現在はフォルダ名のみ) を更新します。

```javascript
updateFolder = async (options:SecretManagerOptions, folderUid: string, folderName: string):Promise<void>
```

<table><thead><tr><th width="154.85161529417937">パラメータ</th><th width="243.99431983802478">型</th><th width="100">必須</th><th>説明</th></tr></thead><tbody><tr><td><code>options</code></td><td><code>SecretsManagerOptions</code></td><td>はい</td><td>事前に設定されたオプション</td></tr><tr><td><code>folderUid</code></td><td><code>string</code></td><td>はい</td><td>フォルダのUID</td></tr><tr><td><code>folderName</code></td><td><code>string</code></td><td>はい</td><td>新しいフォルダ名</td></tr></tbody></table>

**使用例**

```javascript
const storage = localConfigStorage("ksm-config.json")
await updateFolder({storage: storage}, "[FOLDER_UID]", "new_folder_name")
```

### フォルダの削除 <a href="#delete-folders" id="delete-folders"></a>

フォルダのリストを削除します。空でないフォルダを削除するには、`forceDeletion`フラグを使用します。

{% hint style="info" %}
`forceDeletion` を使用する際は、親フォルダとその子フォルダのUIDを同時に送信しないように注意してください。削除の順序によっては、エラーが発生する可能性があります (例: 親が先に削除され、その後で子フォルダを削除しようとした場合など)。UIDのリストが常にFIFO (先入れ先出し) 順に処理される保証はありません。
{% endhint %}

{% hint style="info" %}
ボルトに存在しないフォルダのUIDやKSMアプリケーションで共有されていないフォルダのUIDはエラーになりません。
{% endhint %}

```javascript
deleteFolder = async (options:SecretManagerOptions, folderUids: string[], forceDeletion?: boolean):Promise<SecretsManagerDeleteResponse>
```

<table><thead><tr><th width="180.85161529417937">パラメータ</th><th width="242.99431983802478">型</th><th width="100">必須</th><th width="89">デフォルト</th><th>説明</th></tr></thead><tbody><tr><td><code>options</code></td><td><code>SecretsManagerOptions</code></td><td>はい</td><td></td><td>事前に設定されたオプション</td></tr><tr><td><code>folderUids</code></td><td><code>string[]</code></td><td>はい</td><td></td><td>フォルダUIDリスト</td></tr><tr><td><code>forceDeletion</code></td><td><code>bool</code></td><td>いいえ</td><td><code>false</code></td><td>空でないフォルダを強制的に削除</td></tr></tbody></table>

**使用例**

```javascript
const storage = localConfigStorage("ksm-config.json")
await deleteFolder({storage: storage}, ["[FOLDER_UID1]", "[FOLDER_UID2]"], true)
```

### プロキシ対応 <a href="#proxy-support" id="proxy-support"></a>

プロキシを使用するには、`@keeper-security/secrets-manager-core` に含まれる\
`setCustomProxyAgent` を使用して、プロキシエージェントをインストールおよび設定する必要があります。

**使用例**

```javascript
const {
    getSecrets,
    initializeStorage,
    localConfigStorage,
    setCustomProxyAgent
} = require('@keeper-security/secrets-manager-core')
const { HttpsProxyAgent } = require('https-proxy-agent')

const getKeeperRecords = async () => {
    // プロキシのURLを設定
    setCustomProxyAgent(new HttpsProxyAgent('http://user:password@127.0.0.1:3128'))

    const storage = localConfigStorage("config.json")
    
    await initializeStorage(storage, 'US:EXAMPLE_ONE_TIME_TOKEN', 'keepersecurity.com')
    const {records} = await getSecrets({storage: storage})

    console.log(records)
}
```

{% hint style="danger" %}
`setCustomProxyAgent` は Node.js 環境でのみ動作し、ブラウザでは使用できません。
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.keeper.io/keeperpam/jp/secrets-manager/developer-sdk-library/javascript-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
