> ## Documentation Index
> Fetch the complete documentation index at: https://support.locker.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Usages

> Guide to using the Locker Secrets Manager SDK for NodeJS

## Configure Access Keys

The SDK needs to be configured with your access key which is available in your Locker Secrets Dashboard. Initialize the accessKeyId and secretAccessKey to their value. You also need to set apiBase value (default value is [https://secrets-core.locker.io](https://secrets-core.locker.io)).

```jsx theme={null}
import { Locker } from 'lockerpm'
// You should not hardcode access key credentials. Instead, load them from environment variables
const locker = new Locker({
  accessKeyId: process.env.LOCKER_ACCESS_KEY_ID,
  secretAccessKey: process.env.LOCKER_ACCESS_KEY_SECRET,
  apiBase: '<your base api url>'
})
```

All initialization options are listed below:

| **Key**           | **Description**                                                                                                          | **Type**                     | **Required** |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------- | ------------ |
| `accessKeyId`     | Your access key id                                                                                                       | `string`                     | ✅            |
| `accessKeySecret` | Your access key secret                                                                                                   | `string`                     | ✅            |
| `apiBase`         | Your server base API URL, default value is [https://api.locker.io/locker\_secrets](https://api.locker.io/locker_secrets) | `string`                     | ❌            |
| `headers`         | Custom headers for API calls                                                                                             | `{[header: string]: string}` | ❌            |
| `unsafe`          | Set TLS to unsafe if you use a server with self-signed certificate, default value is `false`                             | `boolean`                    | ❌            |
| `logLevel`        | Refer to **Logging**, default value is `1`                                                                               | `number`                     | ❌            |

You can now use the SDK to get or set values.

***

## Get secrets

Methods:

* list: list all secrets

```javascript theme={null}
list: () => Promise<Secret[]>
```

* listSync: get all secrets, but synchronized

```javascript theme={null}
listSync: () => Secret[]
```

* get: get a secret by key and environment name (optional, defaults to ALL environment), can return a default value if no secret is found

```javascript theme={null}
get: (key: string, env?: string, defaultValue?: string) => Promise<string | undefined>
```

* getSync: get a secret but synchronized

```javascript theme={null}
getSync: (key: string, env?: string, defaultValue?: string) => string | undefined
```

Example:

```jsx theme={null}
// Get list secrets quickly
const secrets = await locker.list()
// or
const secrets = locker.listSync()

// Get a secret value by secret key
// Replace 'ENVIRONMENT' with null or undefined for the enviroment ALL
const secretValue1 = await locker.get('SECRET_NAME_1')
const secretValue2 = await locker.get('SECRET_NAME_2', 'ENVIRONMENT')
const secretValue3 = await locker.get('SECRET_NAME_3', 'ENVIRONMENT', 'default value')
// or
const secretValue3 = locker.getSync('SECRET_NAME_3', 'ENVIRONMENT', 'default value')
```

***

## Get a secret value

This function will get the secret value by a key. If the key does not exist, SDK will return the **default\_value**

```python theme={null}
secret_value = locker.get("REDIS_CONNECTION", default_value="TheDefaultValue")
print(secret_value)
```

You could get a secret value by a secret key and specific environment name by the `environment_name` parameter.
If the key does not exist, SDK will return the **default\_value**

```python theme={null}
secret_value = locker.get_secret(
	"REDIS_CONNECTION", 
	environment_name="staging", 
	default_value="TheDefaultValue"
)
print(secret_value)
```

***

## Create secrets

Methods:

* create: create a new secret with a name, value, environment name (optional) and description (optional). You cannot create secrets with the same key in the same environment. Returns the new secret.

```javascript theme={null}
create: (data: { key: string; value: string; environmentName?: string; description?: string }) => Promise<Secret>
```

Example

```jsx theme={null}
// Create new secret
const secret1 = await locker.create({
  key: 'key',
  value: 'value',
	description: 'a new secret'
})

// This will throw an Error
const secret2 = await locker.create({
  key: 'key',
  value: 'value 2',
})

// Use another env, this will not throw an Error
const secret3 = await locker.create({
  key: 'key',
  value: 'value',
	environmentName: 'prod'
})

// This will throw an Error
const secret4 = await locker.create({
  key: 'key',
  value: 'value 2',
	environmentName: 'prod'
})
```

***

## Update secrets

Methods:

* modify: edit the value, environment name or description of a secret. You cannot change the secret's key. You also cannot change the environment to a new environment that already has a secret with the same name. Returns the updated secret.

```javascript theme={null}
modify: (key: string, env: string, data: { value: string; environmentName?: string; description?: string }) => Promise<Secret>
```

Example:

```jsx theme={null}
// Update the secret "key" of env "ALL"
const secret = await locker.modify('key', '', {
  value: 'value 2',
	description: 'desc'
})

// Update the secret "key" of env "prod"
const secret = await locker.modify('key', 'prod', {
  value: 'value 2',
	environmentName: 'prod'
})

// This will update the env from "prod" to "ALL"
const secret = await locker.modify('key', 'prod', {
  value: 'value 2'
})

// This will update the env from "ALL" to "prod"
const secret = await locker.modify('key', '', {
  value: 'value 2',
	environmentName: 'prod'
})
```

***

## Get environments

Methods:

* listEnvironments: List all environments

```javascript theme={null}
listEnvironments: () => Promise<Environment[]>
```

* listEnvironmentsSync: List all environments but synchronized

```javascript theme={null}
listEnvironmentsSync: () => Environment[]
```

* getEnvironment: get an environment by name

```javascript theme={null}
getEnvironment: (name: string) => Promise<Environment | undefined>
```

* getEnvironmentSync: get an environment but synchronized

```javascript theme={null}
getEnvironmentSync: () => Environment | undefined
```

Example:

```jsx theme={null}
// List environments
const environments = await locker.listEnvironments()
// or
const environments = locker.listEnvironmentsSync()

// Get an environment object by name
const environment = await locker.getEnvironment('prod')
// or
const environment = locker.getEnvironmentSync('prod')
```

***

## Retrieve an environment

To retrieve an environment by name, use `.get_environment()`

```python theme={null}
prod_env = locker.get_environment("prod")
print(prod_env.name, prod_env.external_url)
```

***

## Create an environment

Methods:

* createEnvironment: create a new environment with a name, external url and description (optional). You cannot create environments with the same name. Returns the new environment.

```javascript theme={null}
createEnvironment: (data: { name: string; externalUrl: string; description?: string }) => Promise<Environment>
```

Example:

```jsx theme={null}
// Create a new environment
const env1 = await locker.createEnvironment({
  name: 'prod',
  externalUrl: 'product.prod',
	description: 'testing'
})

// This will throw an error
const env2 = await locker.createEnvironment({
  name: 'prod',
  externalUrl: 'product.prod.example'
})
```

***

## Update an environment

Methods:

* modifyEnvironment: edit the description and external url of an environment. You cannot change the name of an environment. Returns the updated environment.

```javascript theme={null}
modifyEnvironment: (name: string, data: { externalUrl: string; description?: string }) => Promise<Environment>
```

Example:

```jsx theme={null}
// Update an environment by name
const env = await locker.modifyEnvironment("name", {
  externalUrl: 'new value',
})
```

***

## Error Handling

Locker Secret SDK offers some kinds of errors. They can reflect external events, like invalid credentials, network interruptions, or code problems, like invalid API calls.

If an immediate problem prevents a function from continuing, the SDK raises an exception. It’s a best practice to catch and handle exceptions. To catch an exception, use Python’s `try/except` syntax. Catch `locker.error.LockerError` or its subclasses to handle Locker-specific exceptions only. Each subclass represents a different kind of exception. When you catch an exception, you can use its class to choose a response.

Example:

```python theme={null}
from locker import Locker
from locker.error import LockerError


# Create a new secret and handle error
try:
    new_secret = locker.create(key="YOUR_KEY", value="your_key_value", environment_name="staging")
    print(new_secret.key, new_secret.value, new_secret.description, new_secret.environment_name)
except LockerError as e:
    print(e.user_message)
    print(e.http_body)
    print(e.code)
    print(e.status_code)
```

In the SDK, error objects belong to `locker.error.LockerError` and its subclasses. Use the documentation for each class for advice about how to respond.

| **Code**            | **HTTP Status** | **Name**                | **Class**                            | **Description**                                                                          |
| ------------------- | --------------- | ----------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------- |
| `unauthorized`      | 401             | Authentication Error    | `locker.error.AuthenticationError`   | Invalid `access_client_id` or `secret_access_key`                                        |
| `permission_denied` | 403             | Permission Denied Error | `locker.error.PermissionDeniedError` | Your credential does not have enough permission                                          |
| `rate_limit`        | 429             | Rate Limit Error        | `locker.error.RateLimitError`        | Too many requests                                                                        |
| `not_found`         | 404             | Resource Not Found      | `locker.error.ResourceNotFoundError` | The requested resource is not found                                                      |
| `server_error`      | 500             | API Server Error        | `locker.error.APIServerError`        | Something went wrong on Locker's end (These are rare)                                    |
| `http_error`        | 503             | API Connect Error       | `locker.error.APIConnectionError`    | Network error                                                                            |
| `cli_error`         | —               | CLI Run Error           | `locker.error.CliRunError`           | The encryption/decryption binary runs error by invalid local data, process interruptions |
| `locker_error`      | —               | General Locker Error    | `locker.error.LockerError`           | The general error                                                                        |

***

## Logging

The library can be configured to emit logging that will give you better insight into what it’s doing. There are some levels: `NONE (0)`, `ERROR (1)`, `DEBUG (2)`. Set the logging level when creating a Locker instance to enabling it:

```javascript theme={null}
const locker = new Locker({
  // ...
  logLevel: 1  // default is ERROR
})
```
