node-vault-client 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,154 +1,264 @@
1
- # Node.js Vault Client
2
-
3
- [![Build Status](https://travis-ci.org/namecheap/node-vault-client.svg?branch=master)](https://travis-ci.org/namecheap/node-vault-client)
4
- ![npm](https://img.shields.io/npm/v/node-vault-client)
5
- ![npm](https://img.shields.io/npm/dm/node-vault-client)
6
-
7
- A Vault Client implemented in pure javascript for [HashiCorp Vault](https://github.com/hashicorp/vault).
8
- It supports variety of Auth Backends and performs lease renewal for issued auth token.
9
-
10
- ## Install
11
- ```
12
- npm install --save node-vault-client
13
- ```
14
-
15
- ## Example
16
-
17
- ```javascript
18
- const VaultClient = require('node-vault-client');
19
-
20
- const vaultClient = VaultClient.boot('main', {
21
- api: { url: 'https://vault.example.com:8200/' },
22
- auth: {
23
- type: 'appRole', // or 'token', 'iam'
24
- config: { role_id: '637c065f-c644-5e12-d3d1-e9fa4363af61' }
25
- },
26
- });
27
-
28
- vaultClient.read('secret/tst').then(v => {
29
- console.log(v);
30
- }).catch(e => console.error(e));
31
- ```
32
-
33
- ## Supported Auth Backends
34
-
35
- * [AWS IAM](https://www.vaultproject.io/docs/auth/aws.html#iam-auth-method)
36
- * [AppRole](https://www.vaultproject.io/docs/auth/approle.html)
37
- * [Token](https://www.vaultproject.io/docs/auth/token.html)
38
-
39
- ## API
40
-
41
- <a name="VaultClient"></a>
42
-
43
- ### VaultClient
44
-
45
- * [VaultClient](#VaultClient)
46
- * [new VaultClient(options)](#new_VaultClient_new)
47
- * _instance_
48
- * [.fillNodeConfig()](#VaultClient+fillNodeConfig)
49
- * [.read(path)](#VaultClient+read) ⇒ <code>Promise.&lt;Lease&gt;</code>
50
- * [.list(path)](#VaultClient+list) ⇒ <code>Promise.&lt;Lease&gt;</code>
51
- * [.write(path, data)](#VaultClient+write) ⇒ <code>Promise.&lt;(T\|never)&gt;</code>
52
- * _static_
53
- * [.boot(name, [options])](#VaultClient.boot) ⇒
54
- * [.get(name)](#VaultClient.get) ⇒
55
- * [.clear([name])](#VaultClient.clear)
56
-
57
- <a name="new_VaultClient_new"></a>
58
-
59
- #### new VaultClient(options)
60
- Client constructor function.
61
-
62
-
63
- | Param | Type | Default | Description |
64
- | --- | --- | --- | --- |
65
- | options | `Object` | | |
66
- | options.api | <code>Object</code> | | |
67
- | options.api.url | <code>String</code> | | the url of the vault server |
68
- | [options.api.apiVersion] | <code>String</code> | `v1` | |
69
- | options.auth | <code>Object</code> | | |
70
- | options.auth.type | <code>String</code> | | |
71
- | options.auth.config | <code>Object</code> | | auth configuration variables |
72
- | options.logger | <code>Object</code> | `false` | | Logger that supports "error", "info", "warn", "trace", "debug" methods. Uses `console` by default. Pass `false` to disable logging. |
73
-
74
- #### vaultClient.fillNodeConfig()
75
- Populates Vault's values to NPM "config" module
76
-
77
- **Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
78
- <a name="VaultClient+read"></a>
79
-
80
- #### vaultClient.read(path) ⇒ <code>Promise.&lt;Lease&gt;</code>
81
- Read secret from Vault
82
-
83
- **Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
84
-
85
- | Param | Type | Description |
86
- | --- | --- | --- |
87
- | path | <code>string</code> | path to the secret |
88
-
89
- <a name="VaultClient+list"></a>
90
-
91
- #### vaultClient.list(path) ⇒ <code>Promise.&lt;Lease&gt;</code>
92
- Retrieves secrets list
93
-
94
- **Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
95
-
96
- | Param | Type | Description |
97
- | --- | --- | --- |
98
- | path | <code>string</code> | path to the secret |
99
-
100
- <a name="VaultClient+write"></a>
101
-
102
- #### vaultClient.write(path, data) ⇒ <code>Promise.&lt;(T\|never)&gt;</code>
103
- Writes data to Vault
104
-
105
- **Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
106
-
107
- | Param | Type | Description |
108
- | --- | --- | --- |
109
- | path | | path used to write data |
110
- | data | <code>object</code> | data to write |
111
-
112
- <a name="VaultClient.boot"></a>
113
-
114
- #### VaultClient.boot(name, [options]) ⇒
115
- Boot an instance of Vault
116
-
117
- The instance will be stored in a local hash. Calling Vault.boot multiple
118
- times with the same name will return the same instance.
119
-
120
- **Kind**: static method of [<code>VaultClient</code>](#VaultClient)
121
- **Returns**: Vault
122
-
123
- | Param | Type | Description |
124
- | --- | --- | --- |
125
- | name | <code>String</code> | Vault instance name |
126
- | [options] | <code>Object</code> | options for [Vault#constructor](#new_VaultClient_new). |
127
-
128
- <a name="VaultClient.get"></a>
129
-
130
- #### VaultClient.get(name) ⇒
131
- Get an instance of Vault
132
-
133
- The instance will be stored in a local hash. Calling Vault.pop multiple
134
- times with the same name will return the same instance.
135
-
136
- **Kind**: static method of [<code>VaultClient</code>](#VaultClient)
137
- **Returns**: Vault
138
-
139
- | Param | Type | Description |
140
- | --- | --- | --- |
141
- | name | <code>String</code> | Vault instance name |
142
-
143
- <a name="VaultClient.clear"></a>
144
-
145
- #### VaultClient.clear([name])
146
- Clear named Vault instance
147
-
148
- If no name passed all named instances will be cleared.
149
-
150
- **Kind**: static method of [<code>VaultClient</code>](#VaultClient)
151
-
152
- | Param | Type | Description |
153
- | --- | --- | --- |
154
- | [name] | <code>String</code> | Vault instance name, all instances will be cleared if no name were passed |
1
+ # Node.js Vault Client
2
+
3
+ ![npm](https://img.shields.io/npm/v/node-vault-client)
4
+ ![npm](https://img.shields.io/npm/dm/node-vault-client)
5
+
6
+ A Vault Client implemented in pure javascript for [HashiCorp Vault](https://github.com/hashicorp/vault).
7
+ It supports variety of Auth Backends and performs lease renewal for issued auth token.
8
+
9
+ ## Install
10
+ ```
11
+ npm install --save node-vault-client
12
+ ```
13
+
14
+ ## Example
15
+
16
+ ```javascript
17
+ const VaultClient = require('node-vault-client');
18
+
19
+ const vaultClient = VaultClient.boot('main', {
20
+ api: { url: 'https://vault.example.com:8200/' },
21
+ auth: {
22
+ type: 'appRole', // or 'token', 'iam'
23
+ config: { role_id: '637c065f-c644-5e12-d3d1-e9fa4363af61' }
24
+ },
25
+ });
26
+
27
+ vaultClient.read('secret/tst').then(v => {
28
+ console.log(v);
29
+ }).catch(e => console.error(e));
30
+ ```
31
+
32
+ ## KV v2 support
33
+
34
+ This release adds transparent support for the [KV v2 secrets engine](https://developer.hashicorp.com/vault/docs/secrets/kv/kv-v2)
35
+ on top of the existing KV v1 / raw passthrough behaviour.
36
+
37
+ **It is fully opt-in and non-breaking.** With no extra configuration the client behaves exactly as
38
+ before: every path is treated as KV v1 / raw passthrough and no extra request is made. KV v2 is
39
+ activated per mount by setting `api.kv.autoDetect: true` **or** by supplying a static `api.engines`
40
+ map. Once enabled, the client rewrites paths (`secret/foo` → `secret/data/foo`) and unwraps the
41
+ nested KV v2 response automatically — callers never deal with the `data/` / `metadata/` segments
42
+ themselves.
43
+
44
+ ### Configuration options
45
+
46
+ | Option | Type | Default | Description |
47
+ |---|---|---|---|
48
+ | `api.kv.autoDetect` | `boolean` | `false` | Auto-detect the KV version of each mount on first use via `GET sys/internal/ui/mounts/<path>`. The result is cached per mount for the lifetime of the client. |
49
+ | `api.engines` | `Object` | `{}` | Static mount-to-version map, e.g. `{ secret: 2, legacy: 1 }`. Listed mounts resolve with no detection round-trip; use this when the token lacks permission on `sys/internal/ui/mounts`. |
50
+
51
+ `engines` always takes precedence over detection, so the two can be combined: matching mounts use
52
+ the map while unmatched mounts are auto-detected (when `autoDetect: true`) or treated as v1.
53
+
54
+ ### KV v1 (default — nothing to configure)
55
+
56
+ ```javascript
57
+ const client = VaultClient.boot('main', {
58
+ api: { url: 'https://vault.example.com:8200/' },
59
+ auth: { type: 'token', config: { token: '...' } },
60
+ });
61
+
62
+ const lease = await client.read('secret/my-app/config'); // GET secret/my-app/config
63
+ console.log(lease.getData()); // the secret object
64
+ console.log(lease.getMetadata()); // undefined on KV v1
65
+ ```
66
+
67
+ ### KV v2
68
+
69
+ Pass **logical** paths only — the client inserts the `data/` (and `metadata/` for `list`) segment
70
+ for you.
71
+
72
+ ```javascript
73
+ const client = VaultClient.boot('main', {
74
+ api: {
75
+ url: 'https://vault.example.com:8200/',
76
+ engines: { secret: 2 }, // or: kv: { autoDetect: true }
77
+ },
78
+ auth: { type: 'token', config: { token: '...' } },
79
+ });
80
+
81
+ // read → GET secret/data/my-app/config, response.data.data is unwrapped automatically
82
+ const lease = await client.read('secret/my-app/config');
83
+ console.log(lease.getData()); // the secret values
84
+ console.log(lease.getMetadata()); // { version, created_time, ... } on KV v2
85
+
86
+ // write → POST secret/data/my-app/config with { data: { ... } } wrapping done for you
87
+ await client.write('secret/my-app/config', { password: 's3cr3t' });
88
+
89
+ // list → LIST secret/metadata/my-app
90
+ await client.list('secret/my-app');
91
+ ```
92
+
93
+ ### Mixed v1 + v2 mounts on one client
94
+
95
+ Version resolution is **per mount**, so a single client can talk to v1 and v2 mounts at the same
96
+ time. List each mount's version in `api.engines`:
97
+
98
+ ```javascript
99
+ const client = VaultClient.boot('main', {
100
+ api: {
101
+ url: 'https://vault.example.com:8200/',
102
+ engines: {
103
+ 'secret-v2': 2, // KV v2 mount
104
+ // 'secret' is not listed → treated as KV v1 (passthrough)
105
+ },
106
+ },
107
+ auth: { type: 'token', config: { token: '...' } },
108
+ });
109
+
110
+ await client.read('secret/legacy/app'); // v1 → GET secret/legacy/app
111
+ await client.read('secret-v2/app/config'); // v2 → GET secret-v2/data/app/config
112
+ await client.read('database/creds/app-role'); // not KV → passthrough, GET as-is
113
+ ```
114
+
115
+ Or let the client figure it out with `autoDetect` (requires the token to read
116
+ `sys/internal/ui/mounts`):
117
+
118
+ ```javascript
119
+ const client = VaultClient.boot('main', {
120
+ api: { url: 'https://vault.example.com:8200/', kv: { autoDetect: true } },
121
+ auth: { type: 'token', config: { token: '...' } },
122
+ });
123
+
124
+ await client.read('secret/legacy/app'); // detected as v1
125
+ await client.read('secret-v2/app/config'); // detected as v2
126
+ ```
127
+
128
+ ### Notes & caveats
129
+
130
+ - **Do not include KV v2 segments in the path.** Pass `secret/foo`, not `secret/data/foo` — the
131
+ latter would be rewritten to `secret/data/data/foo` on a v2 mount.
132
+ - **Vault policy must allow the v2 paths.** KV v2 reads hit `<mount>/data/...` (and `list` hits
133
+ `<mount>/metadata/...`), so the auth token's policy must grant capabilities on those paths, not
134
+ on the logical path.
135
+ - Non-KV backends (database, transit, etc.) are always treated as passthrough — leave them out of
136
+ `api.engines`, and `autoDetect` recognises them as non-KV automatically.
137
+ - If detection fails (e.g. permission denied) and no `api.engines` override matches, the read
138
+ rejects with a `VaultError` — set `api.engines` to bypass detection in that case.
139
+
140
+ ## Supported Auth Backends
141
+
142
+ * [AWS IAM](https://www.vaultproject.io/docs/auth/aws.html#iam-auth-method)
143
+ * [AppRole](https://www.vaultproject.io/docs/auth/approle.html)
144
+ * [Token](https://www.vaultproject.io/docs/auth/token.html)
145
+
146
+ ## API
147
+
148
+ <a name="VaultClient"></a>
149
+
150
+ ### VaultClient
151
+
152
+ * [VaultClient](#VaultClient)
153
+ * [new VaultClient(options)](#new_VaultClient_new)
154
+ * _instance_
155
+ * [.fillNodeConfig()](#VaultClient+fillNodeConfig)
156
+ * [.read(path)](#VaultClient+read) ⇒ <code>Promise.&lt;Lease&gt;</code>
157
+ * [.list(path)](#VaultClient+list) ⇒ <code>Promise.&lt;Lease&gt;</code>
158
+ * [.write(path, data)](#VaultClient+write) ⇒ <code>Promise.&lt;(T\|never)&gt;</code>
159
+ * _static_
160
+ * [.boot(name, [options])](#VaultClient.boot) ⇒
161
+ * [.get(name)](#VaultClient.get) ⇒
162
+ * [.clear([name])](#VaultClient.clear)
163
+
164
+ <a name="new_VaultClient_new"></a>
165
+
166
+ #### new VaultClient(options)
167
+ Client constructor function.
168
+
169
+
170
+ | Param | Type | Default | Description |
171
+ | --- | --- | --- | --- |
172
+ | options | `Object` | | |
173
+ | options.api | <code>Object</code> | | |
174
+ | options.api.url | <code>String</code> | | the url of the vault server |
175
+ | [options.api.apiVersion] | <code>String</code> | `v1` | |
176
+ | [options.api.kv] | <code>Object</code> | | KV engine options |
177
+ | [options.api.kv.autoDetect] | <code>boolean</code> | `false` | Auto-detect the KV version per mount via `GET sys/internal/ui/mounts/<path>`. |
178
+ | [options.api.engines] | <code>Object</code> | `{}` | Static mount-to-version map, e.g. `{ secret: 2, legacy: 1 }`. Overrides detection. |
179
+ | options.auth | <code>Object</code> | | |
180
+ | options.auth.type | <code>String</code> | | |
181
+ | options.auth.config | <code>Object</code> | | auth configuration variables |
182
+ | options.logger | <code>Object</code> | `false` | | Logger that supports "error", "info", "warn", "trace", "debug" methods. Uses `console` by default. Pass `false` to disable logging. |
183
+
184
+ #### vaultClient.fillNodeConfig()
185
+ Populates Vault's values to NPM "config" module
186
+
187
+ **Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
188
+ <a name="VaultClient+read"></a>
189
+
190
+ #### vaultClient.read(path) ⇒ <code>Promise.&lt;Lease&gt;</code>
191
+ Read secret from Vault
192
+
193
+ **Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
194
+
195
+ | Param | Type | Description |
196
+ | --- | --- | --- |
197
+ | path | <code>string</code> | path to the secret |
198
+
199
+ <a name="VaultClient+list"></a>
200
+
201
+ #### vaultClient.list(path) ⇒ <code>Promise.&lt;Lease&gt;</code>
202
+ Retrieves secrets list
203
+
204
+ **Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
205
+
206
+ | Param | Type | Description |
207
+ | --- | --- | --- |
208
+ | path | <code>string</code> | path to the secret |
209
+
210
+ <a name="VaultClient+write"></a>
211
+
212
+ #### vaultClient.write(path, data) ⇒ <code>Promise.&lt;(T\|never)&gt;</code>
213
+ Writes data to Vault
214
+
215
+ **Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
216
+
217
+ | Param | Type | Description |
218
+ | --- | --- | --- |
219
+ | path | | path used to write data |
220
+ | data | <code>object</code> | data to write |
221
+
222
+ <a name="VaultClient.boot"></a>
223
+
224
+ #### VaultClient.boot(name, [options]) ⇒
225
+ Boot an instance of Vault
226
+
227
+ The instance will be stored in a local hash. Calling Vault.boot multiple
228
+ times with the same name will return the same instance.
229
+
230
+ **Kind**: static method of [<code>VaultClient</code>](#VaultClient)
231
+ **Returns**: Vault
232
+
233
+ | Param | Type | Description |
234
+ | --- | --- | --- |
235
+ | name | <code>String</code> | Vault instance name |
236
+ | [options] | <code>Object</code> | options for [Vault#constructor](#new_VaultClient_new). |
237
+
238
+ <a name="VaultClient.get"></a>
239
+
240
+ #### VaultClient.get(name) ⇒
241
+ Get an instance of Vault
242
+
243
+ The instance will be stored in a local hash. Calling Vault.pop multiple
244
+ times with the same name will return the same instance.
245
+
246
+ **Kind**: static method of [<code>VaultClient</code>](#VaultClient)
247
+ **Returns**: Vault
248
+
249
+ | Param | Type | Description |
250
+ | --- | --- | --- |
251
+ | name | <code>String</code> | Vault instance name |
252
+
253
+ <a name="VaultClient.clear"></a>
254
+
255
+ #### VaultClient.clear([name])
256
+ Clear named Vault instance
257
+
258
+ If no name passed all named instances will be cleared.
259
+
260
+ **Kind**: static method of [<code>VaultClient</code>](#VaultClient)
261
+
262
+ | Param | Type | Description |
263
+ | --- | --- | --- |
264
+ | [name] | <code>String</code> | Vault instance name, all instances will be cleared if no name were passed |
package/package.json CHANGED
@@ -1,44 +1,44 @@
1
- {
2
- "name": "node-vault-client",
3
- "version": "1.0.1",
4
- "description": "A Vault Client implemented in pure javascript for HashiCorp Vault. It supports variety of Auth Backends and performs lease renewal for issued auth token.",
5
- "repository": {
6
- "url": "git+https://github.com/namecheap/node-vault-client.git"
7
- },
8
- "engines": {
9
- "node": ">=14.0.0"
10
- },
11
- "main": "src/VaultClient.js",
12
- "files": [
13
- "src"
14
- ],
15
- "scripts": {
16
- "test": "mocha test/**/*.test.js",
17
- "version": "git add -A ."
18
- },
19
- "author": "Namecheap <opensource@namecheap.com>",
20
- "license": "Apache-2.0",
21
- "dependencies": {
22
- "@aws-sdk/credential-providers": "^3.382.0",
23
- "assign-deep": "^1.0.1",
24
- "aws4": "^1.8.0",
25
- "bluebird": "^3.7.0",
26
- "lodash": "^4.17.15",
27
- "long-timeout": "^0.1.1",
28
- "pretty-ms": "^2.1.0",
29
- "request": "^2.88.0",
30
- "request-promise": "^4.2.4",
31
- "url-join": "^2.0.5"
32
- },
33
- "peerDependencies": {
34
- "config": ">=1 <4"
35
- },
36
- "devDependencies": {
37
- "chai": "^3.5.0",
38
- "co-mocha": "^1.2.2",
39
- "deep-freeze": "^0.0.1",
40
- "mocha": "^3.5.3",
41
- "sinon": "^2.4.1",
42
- "sinon-chai": "^2.14.0"
43
- }
44
- }
1
+ {
2
+ "name": "node-vault-client",
3
+ "version": "1.0.3",
4
+ "description": "A Vault Client implemented in pure javascript for HashiCorp Vault. It supports variety of Auth Backends and performs lease renewal for issued auth token.",
5
+ "repository": {
6
+ "url": "git+https://github.com/namecheap/node-vault-client.git"
7
+ },
8
+ "engines": {
9
+ "node": ">=14.0.0"
10
+ },
11
+ "main": "src/VaultClient.js",
12
+ "files": [
13
+ "src"
14
+ ],
15
+ "scripts": {
16
+ "test": "mocha test/**/*.test.js",
17
+ "version": "git add -A ."
18
+ },
19
+ "author": "Namecheap <opensource@namecheap.com>",
20
+ "license": "Apache-2.0",
21
+ "dependencies": {
22
+ "@aws-sdk/credential-providers": "^3.382.0",
23
+ "assign-deep": "^1.0.1",
24
+ "aws4": "^1.8.0",
25
+ "bluebird": "^3.7.0",
26
+ "lodash": "^4.17.15",
27
+ "long-timeout": "^0.1.1",
28
+ "pretty-ms": "^2.1.0",
29
+ "request": "^2.88.0",
30
+ "request-promise": "^4.2.4",
31
+ "url-join": "^2.0.5"
32
+ },
33
+ "peerDependencies": {
34
+ "config": ">=1 <4"
35
+ },
36
+ "devDependencies": {
37
+ "chai": "^3.5.0",
38
+ "co-mocha": "^1.2.2",
39
+ "deep-freeze": "^0.0.1",
40
+ "mocha": "^3.5.3",
41
+ "sinon": "^2.4.1",
42
+ "sinon-chai": "^2.14.0"
43
+ }
44
+ }
package/src/Lease.js CHANGED
@@ -1,57 +1,70 @@
1
- 'use strict';
2
-
3
- const _ = require('lodash');
4
-
5
- class Lease {
6
- constructor(
7
- requestId,
8
- leaseId,
9
- leaseDuration,
10
- renewable,
11
- data
12
- ) {
13
- this.__requestId = requestId;
14
- this.__leaseId = leaseId;
15
- this.__leaseDuration = leaseDuration;
16
- this.__renewable = renewable;
17
- this.__data = data === undefined ? {} : data;
18
- }
19
-
20
- static fromResponse(response) {
21
- return new Lease(
22
- response.request_id,
23
- response.lease_id,
24
- response.lease_duration,
25
- response.renewable,
26
- response.data
27
- );
28
- }
29
-
30
- /**
31
- * @param {String} key
32
- * @returns {String}
33
- */
34
- getValue(key) {
35
- if (this.__data[key] === undefined) {
36
- throw new Error('Requested key does not exist');
37
- }
38
-
39
- return this.__data[key];
40
- }
41
-
42
- /**
43
- * @returns {Object}
44
- */
45
- getData() {
46
- return _.cloneDeep(this.__data);
47
- }
48
-
49
- /**
50
- * @returns {bool}
51
- */
52
- isRenewable() {
53
- return this.__renewable;
54
- }
55
- }
56
-
57
- module.exports = Lease;
1
+ 'use strict';
2
+
3
+ const _ = require('lodash');
4
+
5
+ class Lease {
6
+ constructor(
7
+ requestId,
8
+ leaseId,
9
+ leaseDuration,
10
+ renewable,
11
+ data,
12
+ metadata
13
+ ) {
14
+ this.__requestId = requestId;
15
+ this.__leaseId = leaseId;
16
+ this.__leaseDuration = leaseDuration;
17
+ this.__renewable = renewable;
18
+ this.__data = (data === undefined || data === null) ? {} : data;
19
+ this.__metadata = metadata;
20
+ }
21
+
22
+ static fromResponse(response) {
23
+ return new Lease(
24
+ response.request_id,
25
+ response.lease_id,
26
+ response.lease_duration,
27
+ response.renewable,
28
+ response.data,
29
+ response.metadata
30
+ );
31
+ }
32
+
33
+ /**
34
+ * @param {String} key
35
+ * @returns {String}
36
+ */
37
+ getValue(key) {
38
+ if (this.__data[key] === undefined) {
39
+ throw new Error('Requested key does not exist');
40
+ }
41
+
42
+ return this.__data[key];
43
+ }
44
+
45
+ /**
46
+ * @returns {Object}
47
+ */
48
+ getData() {
49
+ return _.cloneDeep(this.__data);
50
+ }
51
+
52
+ /**
53
+ * @returns {bool}
54
+ */
55
+ isRenewable() {
56
+ return this.__renewable;
57
+ }
58
+
59
+ /**
60
+ * KV v2 version metadata object (created_time, version, etc.).
61
+ * Returns undefined for KV v1 / non-KV leases.
62
+ *
63
+ * @returns {Object|undefined}
64
+ */
65
+ getMetadata() {
66
+ return this.__metadata;
67
+ }
68
+ }
69
+
70
+ module.exports = Lease;