@looker/sdk-node 24.14.0 → 24.16.2
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/CHANGELOG.md +44 -0
- package/README.md +17 -21
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/nodeSession.apitest.js +78 -0
- package/lib/esm/nodeSession.apitest.js.map +1 -0
- package/lib/esm/nodeSession.js +6 -1
- package/lib/esm/nodeSession.js.map +1 -1
- package/lib/esm/nodeSettings.js.map +1 -1
- package/lib/esm/nodeTransport.apitest.js +127 -0
- package/lib/esm/nodeTransport.apitest.js.map +1 -0
- package/lib/esm/nodeTransport.js +129 -161
- package/lib/esm/nodeTransport.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/nodeSession.apitest.d.ts +1 -0
- package/lib/nodeSession.apitest.js +82 -0
- package/lib/nodeSession.apitest.js.map +1 -0
- package/lib/nodeSession.js +6 -1
- package/lib/nodeSession.js.map +1 -1
- package/lib/nodeSettings.js.map +1 -1
- package/lib/nodeTransport.apitest.d.ts +1 -0
- package/lib/nodeTransport.apitest.js +129 -0
- package/lib/nodeTransport.apitest.js.map +1 -0
- package/lib/nodeTransport.d.ts +7 -11
- package/lib/nodeTransport.js +135 -164
- package/lib/nodeTransport.js.map +1 -1
- package/package.json +11 -13
- package/lib/esm/testUtils/index.js +0 -2
- package/lib/esm/testUtils/index.js.map +0 -1
- package/lib/esm/testUtils/testUtils.js +0 -43
- package/lib/esm/testUtils/testUtils.js.map +0 -1
- package/lib/testUtils/index.js +0 -17
- package/lib/testUtils/index.js.map +0 -1
- package/lib/testUtils/testUtils.js +0 -53
- package/lib/testUtils/testUtils.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,50 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [24.16.2](https://github.com/looker-open-source/sdk-codegen/compare/sdk-node-v24.16.1...sdk-node-v24.16.2) (2024-09-16)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* allow node 20 for the TS SDK ([#1506](https://github.com/looker-open-source/sdk-codegen/issues/1506)) ([d4deac4](https://github.com/looker-open-source/sdk-codegen/commit/d4deac485ff3bf748924ab747a6aee0d47581e10))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Dependencies
|
|
17
|
+
|
|
18
|
+
* The following workspace dependencies were updated
|
|
19
|
+
* dependencies
|
|
20
|
+
* @looker/sdk bumped from 24.16.1 to 24.16.2
|
|
21
|
+
|
|
22
|
+
## [24.16.1](https://github.com/looker-open-source/sdk-codegen/compare/sdk-node-v24.16.0...sdk-node-v24.16.1) (2024-09-14)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* fix release 24.16.2 ([#1505](https://github.com/looker-open-source/sdk-codegen/issues/1505)) ([1cd1806](https://github.com/looker-open-source/sdk-codegen/commit/1cd180615901d2daf1fb112b41f2a72d2caacf61))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Dependencies
|
|
31
|
+
|
|
32
|
+
* The following workspace dependencies were updated
|
|
33
|
+
* dependencies
|
|
34
|
+
* @looker/sdk bumped from 24.16.0 to 24.16.1
|
|
35
|
+
* @looker/sdk-rtl bumped from 21.6.2 to 21.6.3
|
|
36
|
+
|
|
37
|
+
## [24.16.0](https://github.com/looker-open-source/sdk-codegen/compare/sdk-node-v24.14.0...sdk-node-v24.16.0) (2024-09-11)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
### Bug Fixes
|
|
41
|
+
|
|
42
|
+
* Remove the requests package from the TypeScript SDK ([#1491](https://github.com/looker-open-source/sdk-codegen/issues/1491)) ([670377c](https://github.com/looker-open-source/sdk-codegen/commit/670377c46a546bbd8dcc6679b8aeb041da1b4670)), closes [#1439](https://github.com/looker-open-source/sdk-codegen/issues/1439)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
### Dependencies
|
|
46
|
+
|
|
47
|
+
* The following workspace dependencies were updated
|
|
48
|
+
* dependencies
|
|
49
|
+
* @looker/sdk bumped from 24.14.0 to 24.16.0
|
|
50
|
+
* @looker/sdk-rtl bumped from 21.6.1 to 21.6.2
|
|
51
|
+
|
|
8
52
|
## [24.14.0](https://github.com/looker-open-source/sdk-codegen/compare/sdk-node-v24.12.1...sdk-node-v24.14.0) (2024-08-12)
|
|
9
53
|
|
|
10
54
|
|
package/README.md
CHANGED
|
@@ -34,10 +34,6 @@ npm install @looker/sdk @looker/sdk-rtl @looker/sdk-node
|
|
|
34
34
|
|
|
35
35
|
Some other dependencies may be required for your project to build and run correctly.
|
|
36
36
|
|
|
37
|
-
```bash
|
|
38
|
-
yarn install @types/readable-stream @types/request @types/request-promise-native -D
|
|
39
|
-
```
|
|
40
|
-
|
|
41
37
|
### TypeScript SDK packages
|
|
42
38
|
|
|
43
39
|
The Looker TypeScript SDK has different packages to prevent node dependencies being linked into browser usage of the SDK (the node dependencies are not available in the browser and can cause compilation errors). There are three packages for the Typescript SDK available on npm:
|
|
@@ -123,7 +119,7 @@ The `settings` provided to the `NodeSession` class include the base URL for the
|
|
|
123
119
|
|
|
124
120
|
### Sudo behavior with NodeSession
|
|
125
121
|
|
|
126
|
-
|
|
122
|
+
`NodeSession` also directly supports logging in as another user, which is usually called `sudo as` another user in the Looker browser application.
|
|
127
123
|
|
|
128
124
|
An API user with appropriate permissions can `sudo` as another user by passing a different user ID to the `NodeSession.login()` method. Only one user can be impersonated at a time via `NodeSession`. When a `sudo` session is active, all SDK requests are processed as that user.
|
|
129
125
|
|
|
@@ -144,7 +140,7 @@ describe('sudo', () => {
|
|
|
144
140
|
|
|
145
141
|
// find users who are not the API user
|
|
146
142
|
const others = all
|
|
147
|
-
.filter(
|
|
143
|
+
.filter(u => u.id !== apiUser.id && !u.is_disabled)
|
|
148
144
|
.slice(0, 2);
|
|
149
145
|
expect(others.length).toEqual(2);
|
|
150
146
|
if (others.length > 1) {
|
|
@@ -199,11 +195,19 @@ const sdk = LookerNodeSDK.init40(new NodeSettings());
|
|
|
199
195
|
const me = await sdk.ok(sdk.me());
|
|
200
196
|
```
|
|
201
197
|
|
|
202
|
-
|
|
198
|
+
## Streaming with the SDK
|
|
199
|
+
|
|
200
|
+
The [deprecated NodeJS `request` package](https://www.npmjs.com/package/request) dependency has been removed from all Looker TypeScript packages. This removal prompted a **BREAKING** interface change for the streaming SDK.
|
|
201
|
+
The streaming method callback signature changed from `(readable: Readable) => Promise<x>` to `(response: Response) => Promise<x>`. Using `Response` as the parameter to the callback greatly
|
|
202
|
+
increases the flexibility of streaming implementations and provides other valuable information like `Content-Type` and other headers to the streaming callback.
|
|
203
|
+
|
|
204
|
+
For the Browser SDK (`@looker/sdk`), the standard `fetch` function is still used. For the Node SDK (`@looker/sdk-node`), the global [`fetch`](https://nodejs.org/api/globals.html#fetch) function from NodeJS is used, which was marked **stable** in version 22.
|
|
205
|
+
|
|
206
|
+
This means the Looker Node SDK now requires Node 20 or above.
|
|
203
207
|
|
|
204
208
|
The streaming version of the SDK methods should be initialized using the same `AuthSession` as the main SDK to reduce authentication thrashing.
|
|
205
209
|
|
|
206
|
-
Construction of the streaming SDK can use code similar to the following, which is taken from the [downloadTile.ts example](/examples/typescript/downloadTile.ts#
|
|
210
|
+
Construction of the streaming SDK can use code similar to the following, which is taken from the [downloadTile.ts example](/examples/typescript/downloadTile.ts#L129:L157):
|
|
207
211
|
|
|
208
212
|
```ts
|
|
209
213
|
/**
|
|
@@ -218,10 +222,9 @@ const downloadTileAs = async (
|
|
|
218
222
|
tile: IDashboardElement,
|
|
219
223
|
format: string
|
|
220
224
|
) => {
|
|
221
|
-
|
|
222
|
-
fileName = `${tile.title}.${format}`;
|
|
225
|
+
const fileName = `${tile.title}.${format}`;
|
|
223
226
|
|
|
224
|
-
const writer = fs.createWriteStream(fileName);
|
|
227
|
+
const writer = createWritableStream(fs.createWriteStream(fileName));
|
|
225
228
|
const request: IRequestRunQuery = {
|
|
226
229
|
result_format: format,
|
|
227
230
|
query_id: tile.query_id!,
|
|
@@ -229,16 +232,9 @@ const downloadTileAs = async (
|
|
|
229
232
|
// apply_vis: true
|
|
230
233
|
};
|
|
231
234
|
const sdkStream = new Looker40SDKStream(sdk.authSession);
|
|
232
|
-
await sdkStream.run_query(async (
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
.pipe(writer)
|
|
236
|
-
.on('error', () => {
|
|
237
|
-
fileName = undefined;
|
|
238
|
-
throw reject;
|
|
239
|
-
})
|
|
240
|
-
.on('finish', resolve);
|
|
241
|
-
});
|
|
235
|
+
await sdkStream.run_query(async (response: Response) => {
|
|
236
|
+
await response.body.pipeTo(writer);
|
|
237
|
+
return 'streamed';
|
|
242
238
|
}, request);
|
|
243
239
|
|
|
244
240
|
return fileName;
|
package/lib/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nexport * from './nodeServices';\nexport * from './nodeSession';\nexport * from './nodeSettings';\nexport * from './nodeTransport';\nexport * from './nodeSdk';\n"],"mappings":"AA0BA,cAAc,gBAAgB;AAC9B,cAAc,eAAe;AAC7B,cAAc,gBAAgB;AAC9B,cAAc,iBAAiB;AAC/B,cAAc,WAAW"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
2
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import * as process from 'node:process';
|
|
5
|
+
import { describe, it } from 'node:test';
|
|
6
|
+
import { expect } from 'expect';
|
|
7
|
+
import { ApiConfigMap, boolDefault, defaultTimeout } from '@looker/sdk-rtl';
|
|
8
|
+
import { TestConfig } from '@looker/sdk-rtl/src/testUtils';
|
|
9
|
+
import { NodeTransport } from './nodeTransport';
|
|
10
|
+
import { NodeSession } from './nodeSession';
|
|
11
|
+
import { ApiConfig, NodeSettings, NodeSettingsIniFile } from './nodeSettings';
|
|
12
|
+
var config = TestConfig();
|
|
13
|
+
var envPrefix = 'LOOKERSDK';
|
|
14
|
+
var localIni = config.localIni;
|
|
15
|
+
describe('NodeSession', () => {
|
|
16
|
+
var settings = new NodeSettingsIniFile(envPrefix, localIni, 'Looker');
|
|
17
|
+
var transport = new NodeTransport(settings);
|
|
18
|
+
describe('isAuthenticated', () => {
|
|
19
|
+
it('unauthenticated logout returns false', _asyncToGenerator(function* () {
|
|
20
|
+
var session = new NodeSession(settings, transport);
|
|
21
|
+
expect(session.isAuthenticated()).toEqual(false);
|
|
22
|
+
var actual = yield session.logout();
|
|
23
|
+
expect(actual).toEqual(false);
|
|
24
|
+
expect(session.isAuthenticated()).toEqual(false);
|
|
25
|
+
}));
|
|
26
|
+
});
|
|
27
|
+
describe('integration tests', () => {
|
|
28
|
+
it('initializes', () => {
|
|
29
|
+
var session = new NodeSession(settings, transport);
|
|
30
|
+
expect(session.settings).toEqual(settings);
|
|
31
|
+
expect(session.isAuthenticated()).toEqual(false);
|
|
32
|
+
expect(session.isSudo()).toEqual(false);
|
|
33
|
+
});
|
|
34
|
+
it('default auth logs in and out with good credentials', _asyncToGenerator(function* () {
|
|
35
|
+
var session = new NodeSession(settings, transport);
|
|
36
|
+
expect(session.isAuthenticated()).toEqual(false);
|
|
37
|
+
var token = yield session.login();
|
|
38
|
+
expect(token).toBeDefined();
|
|
39
|
+
expect(token.access_token).toBeDefined();
|
|
40
|
+
expect(session.isAuthenticated()).toEqual(true);
|
|
41
|
+
var result = yield session.logout();
|
|
42
|
+
expect(result).toEqual(true);
|
|
43
|
+
expect(session.isAuthenticated()).toEqual(false);
|
|
44
|
+
}));
|
|
45
|
+
});
|
|
46
|
+
describe('environmental configuration', () => {
|
|
47
|
+
it('no INI file', _asyncToGenerator(function* () {
|
|
48
|
+
var section = ApiConfig(fs.readFileSync(localIni, 'utf8')).Looker;
|
|
49
|
+
var verify_ssl = boolDefault(section.verify_ssl, false).toString();
|
|
50
|
+
var envPrefix = 'LOOKERSDK';
|
|
51
|
+
var envKey = ApiConfigMap(envPrefix);
|
|
52
|
+
process.env[envKey.timeout] = section.timeout || defaultTimeout.toString();
|
|
53
|
+
process.env[envKey.client_id] = section.client_id;
|
|
54
|
+
process.env[envKey.client_secret] = section.client_secret;
|
|
55
|
+
process.env[envKey.base_url] = section.base_url;
|
|
56
|
+
process.env[envKey.verify_ssl] = verify_ssl.toString();
|
|
57
|
+
var settings = new NodeSettings(envPrefix);
|
|
58
|
+
expect(settings.base_url).toEqual(section.base_url);
|
|
59
|
+
expect(settings.timeout.toString()).toEqual(section.timeout || defaultTimeout.toString());
|
|
60
|
+
expect(settings.verify_ssl.toString()).toEqual(verify_ssl);
|
|
61
|
+
var session = new NodeSession(settings, transport);
|
|
62
|
+
expect(session.isAuthenticated()).toEqual(false);
|
|
63
|
+
var token = yield session.login();
|
|
64
|
+
expect(token).toBeDefined();
|
|
65
|
+
expect(token.access_token).toBeDefined();
|
|
66
|
+
expect(session.isAuthenticated()).toEqual(true);
|
|
67
|
+
var result = yield session.logout();
|
|
68
|
+
expect(result).toEqual(true);
|
|
69
|
+
expect(session.isAuthenticated()).toEqual(false);
|
|
70
|
+
delete process.env[envKey.timeout];
|
|
71
|
+
delete process.env[envKey.client_id];
|
|
72
|
+
delete process.env[envKey.client_secret];
|
|
73
|
+
delete process.env[envKey.base_url];
|
|
74
|
+
delete process.env[envKey.verify_ssl];
|
|
75
|
+
}));
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=nodeSession.apitest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodeSession.apitest.js","names":["fs","process","describe","it","expect","ApiConfigMap","boolDefault","defaultTimeout","TestConfig","NodeTransport","NodeSession","ApiConfig","NodeSettings","NodeSettingsIniFile","config","envPrefix","localIni","settings","transport","_asyncToGenerator","session","isAuthenticated","toEqual","actual","logout","isSudo","token","login","toBeDefined","access_token","result","section","readFileSync","Looker","verify_ssl","toString","envKey","env","timeout","client_id","client_secret","base_url"],"sources":["../../src/nodeSession.apitest.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nimport * as fs from 'fs';\nimport * as process from 'node:process';\nimport { describe, it } from 'node:test';\nimport { expect } from 'expect';\nimport { ApiConfigMap, boolDefault, defaultTimeout } from '@looker/sdk-rtl';\nimport { TestConfig } from '@looker/sdk-rtl/src/testUtils';\nimport { NodeTransport } from './nodeTransport';\nimport { NodeSession } from './nodeSession';\nimport { ApiConfig, NodeSettings, NodeSettingsIniFile } from './nodeSettings';\n\nconst config = TestConfig();\nconst envPrefix = 'LOOKERSDK';\nconst localIni = config.localIni;\n\ndescribe('NodeSession', () => {\n const settings = new NodeSettingsIniFile(envPrefix, localIni, 'Looker');\n const transport = new NodeTransport(settings);\n\n describe('isAuthenticated', () => {\n it('unauthenticated logout returns false', async () => {\n const session = new NodeSession(settings, transport);\n expect(session.isAuthenticated()).toEqual(false);\n const actual = await session.logout();\n expect(actual).toEqual(false);\n expect(session.isAuthenticated()).toEqual(false);\n });\n });\n\n describe('integration tests', () => {\n it('initializes', () => {\n const session = new NodeSession(settings, transport);\n expect(session.settings).toEqual(settings);\n expect(session.isAuthenticated()).toEqual(false);\n expect(session.isSudo()).toEqual(false);\n });\n\n it('default auth logs in and out with good credentials', async () => {\n const session = new NodeSession(settings, transport);\n expect(session.isAuthenticated()).toEqual(false);\n const token = await session.login();\n expect(token).toBeDefined();\n expect(token.access_token).toBeDefined();\n expect(session.isAuthenticated()).toEqual(true);\n const result = await session.logout();\n expect(result).toEqual(true);\n expect(session.isAuthenticated()).toEqual(false);\n });\n });\n\n describe('environmental configuration', () => {\n it('no INI file', async () => {\n const section = ApiConfig(fs.readFileSync(localIni, 'utf8')).Looker;\n const verify_ssl = boolDefault(section.verify_ssl, false).toString();\n const envPrefix = 'LOOKERSDK';\n const envKey = ApiConfigMap(envPrefix);\n // populate environment variables\n process.env[envKey.timeout] =\n section.timeout || defaultTimeout.toString();\n process.env[envKey.client_id] = section.client_id;\n process.env[envKey.client_secret] = section.client_secret;\n process.env[envKey.base_url] = section.base_url;\n process.env[envKey.verify_ssl] = verify_ssl.toString();\n\n const settings = new NodeSettings(envPrefix);\n expect(settings.base_url).toEqual(section.base_url);\n expect(settings.timeout.toString()).toEqual(\n section.timeout || defaultTimeout.toString()\n );\n expect(settings.verify_ssl.toString()).toEqual(verify_ssl);\n\n const session = new NodeSession(settings, transport);\n expect(session.isAuthenticated()).toEqual(false);\n const token = await session.login();\n expect(token).toBeDefined();\n expect(token.access_token).toBeDefined();\n expect(session.isAuthenticated()).toEqual(true);\n const result = await session.logout();\n expect(result).toEqual(true);\n expect(session.isAuthenticated()).toEqual(false);\n\n // reset environment variables\n delete process.env[envKey.timeout];\n delete process.env[envKey.client_id];\n delete process.env[envKey.client_secret];\n delete process.env[envKey.base_url];\n delete process.env[envKey.verify_ssl];\n });\n });\n});\n"],"mappings":"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"}
|
package/lib/esm/nodeSession.js
CHANGED
|
@@ -108,7 +108,12 @@ export class NodeSession extends AuthSession {
|
|
|
108
108
|
client_id: clientId,
|
|
109
109
|
client_secret: clientSecret
|
|
110
110
|
});
|
|
111
|
-
var
|
|
111
|
+
var headers = {
|
|
112
|
+
'content-type': 'application/x-www-form-urlencoded'
|
|
113
|
+
};
|
|
114
|
+
var token = yield _this6.ok(_this6.transport.request(strPost, "".concat(_this6.apiPath, "/login"), undefined, body, undefined, {
|
|
115
|
+
headers
|
|
116
|
+
}));
|
|
112
117
|
_this6._authToken.setToken(token);
|
|
113
118
|
}
|
|
114
119
|
if (_this6.sudoId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeSession.js","names":["AuthSession","AuthToken","encodeParams","sdkError","NodeTransport","strPost","strDelete","NodeSession","constructor","settings","transport","_defineProperty","activeToken","_sudoToken","access_token","_authToken","isAuthenticated","token","isActive","authenticate","props","_this","_asyncToGenerator","getToken","headers","Authorization","concat","isSudo","sudoId","_this2","login","reset","_this3","_login","toString","logout","_this4","result","_logout","sudoLogout","_this5","newId","_this6","section","readConfig","clientId","client_id","clientSecret","client_secret","message","body","ok","request","apiPath","undefined","setToken","promise","encodeURI","init","accessToken","_this7"],"sources":["../../src/nodeSession.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nimport type {\n HttpMethod,\n IAccessToken,\n IApiSettings,\n IError,\n IRequestProps,\n ITransport,\n} from '@looker/sdk-rtl';\nimport {\n AuthSession,\n AuthToken,\n encodeParams,\n sdkError,\n} from '@looker/sdk-rtl';\nimport { NodeTransport } from './nodeTransport';\n\nconst strPost: HttpMethod = 'POST';\nconst strDelete: HttpMethod = 'DELETE';\n\nexport class NodeSession extends AuthSession {\n private readonly apiPath: string = '/api/4.0';\n _authToken: AuthToken = new AuthToken();\n _sudoToken: AuthToken = new AuthToken();\n\n constructor(\n public settings: IApiSettings,\n transport?: ITransport\n ) {\n super(settings, transport || new NodeTransport(settings));\n }\n\n /**\n * Abstraction of AuthToken retrieval to support sudo mode\n */\n get activeToken() {\n if (this._sudoToken.access_token) {\n return this._sudoToken;\n }\n return this._authToken;\n }\n\n /**\n * Is there an active authentication token?\n */\n isAuthenticated() {\n // TODO I think this can be simplified\n const token = this.activeToken;\n if (!(token && token.access_token)) return false;\n return token.isActive();\n }\n\n /**\n * Add authentication data to the pending API request\n * @param props initialized API request properties\n *\n * @returns the updated request properties\n */\n async authenticate(props: IRequestProps) {\n const token = await this.getToken();\n if (token && token.access_token) {\n props.headers.Authorization = `Bearer ${token.access_token}`;\n }\n return props;\n }\n\n isSudo() {\n return !!this.sudoId && this._sudoToken.isActive();\n }\n\n /**\n * retrieve the current authentication token. If there is no active token, performs default\n * login to retrieve the token\n */\n async getToken() {\n if (!this.isAuthenticated()) {\n await this.login();\n }\n return this.activeToken;\n }\n\n /**\n * Reset the authentication session\n */\n reset() {\n this.sudoId = '';\n this._authToken.reset();\n this._sudoToken.reset();\n }\n\n /**\n * Activate the authentication token for the API3 or sudo user\n * @param sudoId {string | number}: optional. If provided, impersonates the user specified\n *\n */\n async login(sudoId?: string | number) {\n if (sudoId || sudoId !== this.sudoId || !this.isAuthenticated()) {\n if (sudoId) {\n await this._login(sudoId.toString());\n } else {\n await this._login();\n }\n }\n return this.activeToken;\n }\n\n /**\n * Logout the active user. If the active user is sudo, the session reverts to the API3 user\n */\n async logout() {\n let result = false;\n if (this.isAuthenticated()) {\n result = await this._logout();\n }\n return result;\n }\n\n private async sudoLogout() {\n let result = false;\n if (this.isSudo()) {\n result = await this.logout(); // Logout the current sudo\n this._sudoToken.reset();\n }\n return result;\n }\n\n // internal login method that manages default auth token and sudo workflow\n private async _login(newId?: string) {\n // for linty freshness, always logout sudo if set\n await this.sudoLogout();\n\n if (newId !== this.sudoId) {\n // Assign new requested sudo id\n this.sudoId = newId || '';\n }\n\n if (!this._authToken.isActive()) {\n this.reset();\n // only retain client API3 credentials for the lifetime of the login request\n const section = this.settings.readConfig();\n const clientId = section.client_id;\n const clientSecret = section.client_secret;\n if (!clientId || !clientSecret) {\n throw sdkError({\n message: 'API credentials client_id and/or client_secret are not set',\n });\n }\n const body = encodeParams({\n client_id: clientId,\n client_secret: clientSecret,\n });\n // authenticate client\n const token = await this.ok(\n this.transport.request<IAccessToken, IError>(\n strPost,\n `${this.apiPath}/login`,\n undefined,\n body\n )\n );\n this._authToken.setToken(token);\n }\n\n if (this.sudoId) {\n // Use the API user auth to sudo\n const token = this.activeToken;\n const promise = this.transport.request<IAccessToken, IError>(\n strPost,\n encodeURI(`${this.apiPath}/login/${newId}`),\n null,\n null,\n // ensure the auth token is included in the sudo request\n (init: IRequestProps) => {\n if (token.access_token) {\n init.headers.Authorization = `Bearer ${token.access_token}`;\n }\n return init;\n },\n this.settings // TODO this may not be needed here\n );\n\n const accessToken = await this.ok(promise);\n\n this._sudoToken.setToken(accessToken);\n }\n\n return this.activeToken;\n }\n\n private async _logout() {\n const token = this.activeToken;\n const promise = this.transport.request<string, IError>(\n strDelete,\n `${this.apiPath}/logout`,\n null,\n null,\n // ensure the auth token is included in the logout promise\n (init: IRequestProps) => {\n if (token.access_token) {\n init.headers.Authorization = `Bearer ${token.access_token}`;\n }\n return init;\n },\n this.settings\n );\n\n await this.ok(promise);\n\n // If no error was thrown, logout was successful\n if (this.sudoId) {\n // User was logged out, so set auth back to default\n this.sudoId = '';\n this._sudoToken.reset();\n if (!this._authToken.isActive()) {\n await this.login();\n }\n } else {\n // completely logged out\n this.reset();\n }\n return true;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nodeSession.js","names":["AuthSession","AuthToken","encodeParams","sdkError","NodeTransport","strPost","strDelete","NodeSession","constructor","settings","transport","_defineProperty","activeToken","_sudoToken","access_token","_authToken","isAuthenticated","token","isActive","authenticate","props","_this","_asyncToGenerator","getToken","headers","Authorization","concat","isSudo","sudoId","_this2","login","reset","_this3","_login","toString","logout","_this4","result","_logout","sudoLogout","_this5","newId","_this6","section","readConfig","clientId","client_id","clientSecret","client_secret","message","body","ok","request","apiPath","undefined","setToken","promise","encodeURI","init","accessToken","_this7"],"sources":["../../src/nodeSession.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nimport type {\n HttpMethod,\n IAccessToken,\n IApiSettings,\n IError,\n IRequestProps,\n ITransport,\n} from '@looker/sdk-rtl';\nimport {\n AuthSession,\n AuthToken,\n encodeParams,\n sdkError,\n} from '@looker/sdk-rtl';\nimport { NodeTransport } from './nodeTransport';\n\nconst strPost: HttpMethod = 'POST';\nconst strDelete: HttpMethod = 'DELETE';\n\nexport class NodeSession extends AuthSession {\n private readonly apiPath: string = '/api/4.0';\n _authToken: AuthToken = new AuthToken();\n _sudoToken: AuthToken = new AuthToken();\n\n constructor(public settings: IApiSettings, transport?: ITransport) {\n super(settings, transport || new NodeTransport(settings));\n }\n\n /**\n * Abstraction of AuthToken retrieval to support sudo mode\n */\n get activeToken() {\n if (this._sudoToken.access_token) {\n return this._sudoToken;\n }\n return this._authToken;\n }\n\n /**\n * Is there an active authentication token?\n */\n isAuthenticated() {\n // TODO I think this can be simplified\n const token = this.activeToken;\n if (!(token && token.access_token)) return false;\n return token.isActive();\n }\n\n /**\n * Add authentication data to the pending API request\n * @param props initialized API request properties\n *\n * @returns the updated request properties\n */\n async authenticate(props: IRequestProps) {\n const token = await this.getToken();\n if (token && token.access_token) {\n props.headers.Authorization = `Bearer ${token.access_token}`;\n }\n return props;\n }\n\n isSudo() {\n return !!this.sudoId && this._sudoToken.isActive();\n }\n\n /**\n * retrieve the current authentication token. If there is no active token, performs default\n * login to retrieve the token\n */\n async getToken() {\n if (!this.isAuthenticated()) {\n await this.login();\n }\n return this.activeToken;\n }\n\n /**\n * Reset the authentication session\n */\n reset() {\n this.sudoId = '';\n this._authToken.reset();\n this._sudoToken.reset();\n }\n\n /**\n * Activate the authentication token for the API3 or sudo user\n * @param sudoId {string | number}: optional. If provided, impersonates the user specified\n *\n */\n async login(sudoId?: string | number) {\n if (sudoId || sudoId !== this.sudoId || !this.isAuthenticated()) {\n if (sudoId) {\n await this._login(sudoId.toString());\n } else {\n await this._login();\n }\n }\n return this.activeToken;\n }\n\n /**\n * Logout the active user. If the active user is sudo, the session reverts to the API3 user\n */\n async logout() {\n let result = false;\n if (this.isAuthenticated()) {\n result = await this._logout();\n }\n return result;\n }\n\n private async sudoLogout() {\n let result = false;\n if (this.isSudo()) {\n result = await this.logout(); // Logout the current sudo\n this._sudoToken.reset();\n }\n return result;\n }\n\n // internal login method that manages default auth token and sudo workflow\n private async _login(newId?: string) {\n // for linty freshness, always logout sudo if set\n await this.sudoLogout();\n\n if (newId !== this.sudoId) {\n // Assign new requested sudo id\n this.sudoId = newId || '';\n }\n\n if (!this._authToken.isActive()) {\n this.reset();\n // only retain client API3 credentials for the lifetime of the login request\n const section = this.settings.readConfig();\n const clientId = section.client_id;\n const clientSecret = section.client_secret;\n if (!clientId || !clientSecret) {\n throw sdkError({\n message: 'API credentials client_id and/or client_secret are not set',\n });\n }\n const body = encodeParams({\n client_id: clientId,\n client_secret: clientSecret,\n });\n const headers = { 'content-type': 'application/x-www-form-urlencoded' };\n // authenticate client\n const token = await this.ok(\n this.transport.request<IAccessToken, IError>(\n strPost,\n `${this.apiPath}/login`,\n undefined,\n body,\n undefined,\n { headers }\n )\n );\n this._authToken.setToken(token);\n }\n\n if (this.sudoId) {\n // Use the API user auth to sudo\n const token = this.activeToken;\n const promise = this.transport.request<IAccessToken, IError>(\n strPost,\n encodeURI(`${this.apiPath}/login/${newId}`),\n null,\n null,\n // ensure the auth token is included in the sudo request\n (init: IRequestProps) => {\n if (token.access_token) {\n init.headers.Authorization = `Bearer ${token.access_token}`;\n }\n return init;\n },\n this.settings // TODO this may not be needed here\n );\n\n const accessToken = await this.ok(promise);\n\n this._sudoToken.setToken(accessToken);\n }\n\n return this.activeToken;\n }\n\n private async _logout() {\n const token = this.activeToken;\n const promise = this.transport.request<string, IError>(\n strDelete,\n `${this.apiPath}/logout`,\n null,\n null,\n // ensure the auth token is included in the logout promise\n (init: IRequestProps) => {\n if (token.access_token) {\n init.headers.Authorization = `Bearer ${token.access_token}`;\n }\n return init;\n },\n this.settings\n );\n\n await this.ok(promise);\n\n // If no error was thrown, logout was successful\n if (this.sudoId) {\n // User was logged out, so set auth back to default\n this.sudoId = '';\n this._sudoToken.reset();\n if (!this._authToken.isActive()) {\n await this.login();\n }\n } else {\n // completely logged out\n this.reset();\n }\n return true;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeSettings.js","names":["fs","ini","ApiConfigMap","ApiSettings","DefaultSettings","ValueSettings","sdkError","unquote","getenv","name","defaultValue","arguments","length","undefined","val","process","env","ApiConfig","contents","parse","ApiConfigSection","section","config","Object","keys","settings","Error","concat","api_version","console","warn","readEnvConfig","envPrefix","values","configMap","forEach","key","envKey","readIniConfig","fileName","existsSync","_objectSpread","readFileSync","NodeSettings","constructor","_defineProperty","readConfig","_section","NodeSettingsIniFile","message"],"sources":["../../src/nodeSettings.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nimport * as fs from 'fs';\nimport * as ini from 'ini';\nimport type { IApiSection, IApiSettings } from '@looker/sdk-rtl';\nimport {\n ApiConfigMap,\n ApiSettings,\n DefaultSettings,\n ValueSettings,\n sdkError,\n unquote,\n} from '@looker/sdk-rtl';\n\n/**\n * Read an environment key. Use defaultValue if it doesn't exist\n * @param {string} name Environment variable name\n * @param {string | undefined} defaultValue\n * @returns {string | undefined} The value of the environment variable if it exists, or defaultValue\n */\nexport const getenv = (\n name: string,\n defaultValue: string | undefined = undefined\n) => {\n const val = process.env[name];\n return val === undefined ? defaultValue : val;\n};\n\n/**\n * Complete .INI file parse results\n */\nexport interface IApiConfig {\n [key: string]: any;\n}\n\n/**\n * Parses `.ini` formatted content\n * @param contents formatted as an `.ini` file\n * @constructor\n */\nexport const ApiConfig = (contents: string): IApiConfig => ini.parse(contents);\n\n/**\n * Extract named or (default) first section from INI file\n * @param contents {string} Parameters formatted as an INI file\n * @param section {[key: string]: any;} Contents of INI section\n * @constructor\n */\nexport const ApiConfigSection = (\n contents: string,\n section?: string\n): IApiSection => {\n const config = ApiConfig(contents);\n if (!section) {\n // default to the first section if not specified\n section = Object.keys(config)[0];\n }\n const settings = config[section];\n if (!settings) {\n throw new Error(`No section named \"${section}\" was found`);\n }\n if (settings.api_version) {\n console.warn(\n 'api_version is no longer read from a configuration file by the SDK'\n );\n }\n return settings;\n};\n\n/**\n * A utility function that loads environment variables and maps them to the standard configuration values\n *\n * @returns the populated `IApiSection`, which may be empty\n */\nexport const readEnvConfig = (envPrefix: string) => {\n const values: IApiSection = {};\n const configMap = ApiConfigMap(envPrefix);\n Object.keys(configMap).forEach((key) => {\n const envKey = configMap[key];\n if (process.env[envKey] !== undefined) {\n // Value exists. Map environment variable keys to config variable keys\n const val = unquote(process.env[envKey]);\n values[key] = val;\n }\n });\n return values;\n};\n\n/**\n * A utility function that loads the configuration values from the specified file name and overrides them\n * with environment variable values, if the environment variables exist\n *\n * @param {string} fileName Name of configuration file to read\n * @param envPrefix environment variable prefix. Pass an empty string to skip environment reading.\n * @param {string} section Optional. Name of section of configuration file to read\n * @returns {IApiSection} containing the configuration values\n */\nexport const readIniConfig = (\n fileName: string,\n envPrefix: string,\n section?: string\n) => {\n // get environment variables\n let config = readEnvConfig(envPrefix);\n if (fileName && fs.existsSync(fileName)) {\n // override any config file settings with environment values if the environment value is set\n config = {\n ...ApiConfigSection(fs.readFileSync(fileName, 'utf8'), section),\n ...config,\n };\n }\n // Unquote any quoted configuration values\n Object.keys(config).forEach((key) => {\n const val = config[key];\n if (typeof val === 'string') {\n config[key] = unquote(val);\n }\n });\n return config;\n};\n\n/**\n * Read configuration settings from Node environment variables\n *\n * This class initializes SDK settings **only** from the values passed in to its constructor and\n * (potentially) configured environment variables, and does not read a configuration file at all\n *\n * Any environment variables that **are** set, will override the values passed in to the constructor\n * with the same key\n *\n */\nexport class NodeSettings extends ApiSettings {\n protected readonly envPrefix!: string;\n public section: string;\n\n /**\n * Initialize config settings for the node SDK runtime\n * @param envPrefix Environment variable name prefix. Use empty string to not read the environment\n * @param contents contents of the read config\n * @param section name of ini section to process\n */\n constructor(\n envPrefix: string,\n contents?: string | IApiSettings,\n section?: string\n ) {\n let settings: IApiSettings;\n if (contents) {\n if (typeof contents === 'string') {\n settings = ApiConfigSection(contents, section) as IApiSettings;\n } else {\n settings = contents;\n }\n settings = { ...readEnvConfig(envPrefix), ...settings };\n } else {\n settings = readEnvConfig(envPrefix) as IApiSettings;\n }\n super({ ...DefaultSettings(), ...settings });\n this.section = section ?? '';\n this.envPrefix = envPrefix;\n }\n\n /**\n * **NOTE**: If `envPrefix` is defined in the constructor, environment variables will be read in this call.\n *\n * @param _section section name is ignored here.\n */\n readConfig(_section?: string): IApiSection {\n return readEnvConfig(this.envPrefix);\n }\n}\n\n/**\n * Example class that reads a configuration from a file in node\n *\n * If `fileName` is not specified in the constructor, the default file name is `./looker.ini`\n *\n * **Warning**: `.ini` files storing credentials should be secured in the run-time environment, and\n * ignored by version control systems so credentials never get checked in to source code repositories.\n * A recommended pattern is using Node environment variables to specify confidential API credentials\n * while using an `.ini` file for values like `base_url`.\n *\n * **Note**: If the configuration file is specified but does **not** exist, an error will be thrown.\n * No error is thrown if the fileName defaulted to `./looker.ini` inside the constructor and that\n * file does not exist. In that case, configuration from environment variables will be required.\n *\n */\nexport class NodeSettingsIniFile extends NodeSettings {\n private readonly fileName!: string;\n\n constructor(envPrefix: string, fileName = '', section?: string) {\n if (fileName && !fs.existsSync(fileName)) {\n throw sdkError({ message: `File ${fileName} was not found` });\n }\n // default fileName to looker.ini\n fileName = fileName || './looker.ini';\n const config = readIniConfig(fileName, envPrefix, section);\n const settings = ValueSettings(config, envPrefix);\n super(envPrefix, settings, section);\n this.fileName = fileName;\n }\n\n /**\n * Read a configuration section and return it as a generic keyed collection\n * If the configuration file doesn't exist, environment variables will be used for the values\n * Environment variables, if set, also override the configuration file values\n *\n * **NOTE**: If `envPrefix` is defined in the constructor, environment variables will be read in this call.\n *\n * @param section {string} Name of Ini section to read. Optional. Defaults to first section.\n *\n */\n readConfig(section?: string): IApiSection {\n section = section || this.section;\n return readIniConfig(this.fileName, this.envPrefix, section);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nodeSettings.js","names":["fs","ini","ApiConfigMap","ApiSettings","DefaultSettings","ValueSettings","sdkError","unquote","getenv","name","defaultValue","arguments","length","undefined","val","process","env","ApiConfig","contents","parse","ApiConfigSection","section","config","Object","keys","settings","Error","concat","api_version","console","warn","readEnvConfig","envPrefix","values","configMap","forEach","key","envKey","readIniConfig","fileName","existsSync","_objectSpread","readFileSync","NodeSettings","constructor","_defineProperty","readConfig","_section","NodeSettingsIniFile","message"],"sources":["../../src/nodeSettings.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nimport * as fs from 'fs';\nimport * as ini from 'ini';\nimport type { IApiSection, IApiSettings } from '@looker/sdk-rtl';\nimport {\n ApiConfigMap,\n ApiSettings,\n DefaultSettings,\n ValueSettings,\n sdkError,\n unquote,\n} from '@looker/sdk-rtl';\n\n/**\n * Read an environment key. Use defaultValue if it doesn't exist\n * @param {string} name Environment variable name\n * @param {string | undefined} defaultValue\n * @returns {string | undefined} The value of the environment variable if it exists, or defaultValue\n */\nexport const getenv = (\n name: string,\n defaultValue: string | undefined = undefined\n) => {\n const val = process.env[name];\n return val === undefined ? defaultValue : val;\n};\n\n/**\n * Complete .INI file parse results\n */\nexport interface IApiConfig {\n [key: string]: any;\n}\n\n/**\n * Parses `.ini` formatted content\n * @param contents formatted as an `.ini` file\n * @constructor\n */\nexport const ApiConfig = (contents: string): IApiConfig => ini.parse(contents);\n\n/**\n * Extract named or (default) first section from INI file\n * @param contents {string} Parameters formatted as an INI file\n * @param section {[key: string]: any;} Contents of INI section\n * @constructor\n */\nexport const ApiConfigSection = (\n contents: string,\n section?: string\n): IApiSection => {\n const config = ApiConfig(contents);\n if (!section) {\n // default to the first section if not specified\n section = Object.keys(config)[0];\n }\n const settings = config[section];\n if (!settings) {\n throw new Error(`No section named \"${section}\" was found`);\n }\n if (settings.api_version) {\n console.warn(\n 'api_version is no longer read from a configuration file by the SDK'\n );\n }\n return settings;\n};\n\n/**\n * A utility function that loads environment variables and maps them to the standard configuration values\n *\n * @returns the populated `IApiSection`, which may be empty\n */\nexport const readEnvConfig = (envPrefix: string) => {\n const values: IApiSection = {};\n const configMap = ApiConfigMap(envPrefix);\n Object.keys(configMap).forEach(key => {\n const envKey = configMap[key];\n if (process.env[envKey] !== undefined) {\n // Value exists. Map environment variable keys to config variable keys\n const val = unquote(process.env[envKey]);\n values[key] = val;\n }\n });\n return values;\n};\n\n/**\n * A utility function that loads the configuration values from the specified file name and overrides them\n * with environment variable values, if the environment variables exist\n *\n * @param {string} fileName Name of configuration file to read\n * @param envPrefix environment variable prefix. Pass an empty string to skip environment reading.\n * @param {string} section Optional. Name of section of configuration file to read\n * @returns {IApiSection} containing the configuration values\n */\nexport const readIniConfig = (\n fileName: string,\n envPrefix: string,\n section?: string\n) => {\n // get environment variables\n let config = readEnvConfig(envPrefix);\n if (fileName && fs.existsSync(fileName)) {\n // override any config file settings with environment values if the environment value is set\n config = {\n ...ApiConfigSection(fs.readFileSync(fileName, 'utf8'), section),\n ...config,\n };\n }\n // Unquote any quoted configuration values\n Object.keys(config).forEach(key => {\n const val = config[key];\n if (typeof val === 'string') {\n config[key] = unquote(val);\n }\n });\n return config;\n};\n\n/**\n * Read configuration settings from Node environment variables\n *\n * This class initializes SDK settings **only** from the values passed in to its constructor and\n * (potentially) configured environment variables, and does not read a configuration file at all\n *\n * Any environment variables that **are** set, will override the values passed in to the constructor\n * with the same key\n *\n */\nexport class NodeSettings extends ApiSettings {\n protected readonly envPrefix!: string;\n public section: string;\n\n /**\n * Initialize config settings for the node SDK runtime\n * @param envPrefix Environment variable name prefix. Use empty string to not read the environment\n * @param contents contents of the read config\n * @param section name of ini section to process\n */\n constructor(\n envPrefix: string,\n contents?: string | IApiSettings,\n section?: string\n ) {\n let settings: IApiSettings;\n if (contents) {\n if (typeof contents === 'string') {\n settings = ApiConfigSection(contents, section) as IApiSettings;\n } else {\n settings = contents;\n }\n settings = { ...readEnvConfig(envPrefix), ...settings };\n } else {\n settings = readEnvConfig(envPrefix) as IApiSettings;\n }\n super({ ...DefaultSettings(), ...settings });\n this.section = section ?? '';\n this.envPrefix = envPrefix;\n }\n\n /**\n * **NOTE**: If `envPrefix` is defined in the constructor, environment variables will be read in this call.\n *\n * @param _section section name is ignored here.\n */\n readConfig(_section?: string): IApiSection {\n return readEnvConfig(this.envPrefix);\n }\n}\n\n/**\n * Example class that reads a configuration from a file in node\n *\n * If `fileName` is not specified in the constructor, the default file name is `./looker.ini`\n *\n * **Warning**: `.ini` files storing credentials should be secured in the run-time environment, and\n * ignored by version control systems so credentials never get checked in to source code repositories.\n * A recommended pattern is using Node environment variables to specify confidential API credentials\n * while using an `.ini` file for values like `base_url`.\n *\n * **Note**: If the configuration file is specified but does **not** exist, an error will be thrown.\n * No error is thrown if the fileName defaulted to `./looker.ini` inside the constructor and that\n * file does not exist. In that case, configuration from environment variables will be required.\n *\n */\nexport class NodeSettingsIniFile extends NodeSettings {\n private readonly fileName!: string;\n\n constructor(envPrefix: string, fileName = '', section?: string) {\n if (fileName && !fs.existsSync(fileName)) {\n throw sdkError({ message: `File ${fileName} was not found` });\n }\n // default fileName to looker.ini\n fileName = fileName || './looker.ini';\n const config = readIniConfig(fileName, envPrefix, section);\n const settings = ValueSettings(config, envPrefix);\n super(envPrefix, settings, section);\n this.fileName = fileName;\n }\n\n /**\n * Read a configuration section and return it as a generic keyed collection\n * If the configuration file doesn't exist, environment variables will be used for the values\n * Environment variables, if set, also override the configuration file values\n *\n * **NOTE**: If `envPrefix` is defined in the constructor, environment variables will be read in this call.\n *\n * @param section {string} Name of Ini section to read. Optional. Defaults to first section.\n *\n */\n readConfig(section?: string): IApiSection {\n section = section || this.section;\n return readIniConfig(this.fileName, this.envPrefix, section);\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
2
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
3
|
+
import { describe, it } from 'node:test';
|
|
4
|
+
import { expect } from 'expect';
|
|
5
|
+
import { StatusCode, sdkOk } from '@looker/sdk-rtl';
|
|
6
|
+
import { NodeCryptoHash, NodeTransport } from './nodeTransport';
|
|
7
|
+
describe('NodeTransport', () => {
|
|
8
|
+
var hostname = 'https://looker.sdk';
|
|
9
|
+
var settings = {
|
|
10
|
+
base_url: hostname
|
|
11
|
+
};
|
|
12
|
+
var xp = new NodeTransport(settings);
|
|
13
|
+
var fullPath = 'https://github.com/looker-open-source/sdk-codegen';
|
|
14
|
+
var badPath = fullPath + '_bogus';
|
|
15
|
+
it('raw request retrieves fully qualified url', _asyncToGenerator(function* () {
|
|
16
|
+
var response = yield xp.rawRequest('GET', fullPath);
|
|
17
|
+
expect(response).toBeDefined();
|
|
18
|
+
expect(response.ok).toEqual(true);
|
|
19
|
+
expect(response.method).toEqual('GET');
|
|
20
|
+
expect(response.statusCode).toEqual(200);
|
|
21
|
+
expect(response.statusMessage).toEqual('OK');
|
|
22
|
+
expect(response.contentType).toContain('text/html');
|
|
23
|
+
expect(response.body).toBeDefined();
|
|
24
|
+
var html = yield response.body;
|
|
25
|
+
expect(html).toContain('One SDK to rule them all, and in the codegen bind them');
|
|
26
|
+
}));
|
|
27
|
+
describe('transport errors', () => {
|
|
28
|
+
it('gracefully handles transport errors', _asyncToGenerator(function* () {
|
|
29
|
+
var response = yield xp.rawRequest('GET', badPath);
|
|
30
|
+
var errorMessage = 'Not Found';
|
|
31
|
+
expect(response).toBeDefined();
|
|
32
|
+
expect(response.ok).toEqual(false);
|
|
33
|
+
expect(response.method).toEqual('GET');
|
|
34
|
+
expect(response.statusCode).toEqual(404);
|
|
35
|
+
expect(response.body).toBeDefined();
|
|
36
|
+
expect(response.statusMessage).toEqual(errorMessage);
|
|
37
|
+
}));
|
|
38
|
+
});
|
|
39
|
+
it('retrieves fully qualified url', _asyncToGenerator(function* () {
|
|
40
|
+
var response = yield xp.request('GET', fullPath);
|
|
41
|
+
expect(response).toBeDefined();
|
|
42
|
+
expect(response.ok).toEqual(true);
|
|
43
|
+
if (response.ok) {
|
|
44
|
+
var content = response.value;
|
|
45
|
+
expect(content).toContain('One SDK to rule them all, and in the codegen bind them');
|
|
46
|
+
}
|
|
47
|
+
}));
|
|
48
|
+
describe('ok check', () => {
|
|
49
|
+
var raw = {
|
|
50
|
+
method: 'GET',
|
|
51
|
+
contentType: 'application/json',
|
|
52
|
+
headers: {},
|
|
53
|
+
url: 'bogus',
|
|
54
|
+
ok: true,
|
|
55
|
+
statusCode: StatusCode.OK,
|
|
56
|
+
statusMessage: 'Mocked success',
|
|
57
|
+
body: 'body',
|
|
58
|
+
requestStarted: 1000,
|
|
59
|
+
responseCompleted: 2000
|
|
60
|
+
};
|
|
61
|
+
it('ok is ok', () => {
|
|
62
|
+
expect(xp.ok(raw)).toEqual(true);
|
|
63
|
+
});
|
|
64
|
+
it('All 2xx responses are ok', () => {
|
|
65
|
+
raw.statusCode = StatusCode.IMUsed;
|
|
66
|
+
expect(xp.ok(raw)).toEqual(true);
|
|
67
|
+
});
|
|
68
|
+
it('Non-2xx responses are not ok', () => {
|
|
69
|
+
raw.statusCode = 422;
|
|
70
|
+
expect(xp.ok(raw)).toEqual(false);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
it('does a standard get', _asyncToGenerator(function* () {
|
|
74
|
+
var xp = new NodeTransport({});
|
|
75
|
+
var actual = yield xp.rawRequest('GET', 'https://example.com');
|
|
76
|
+
expect(actual).toBeDefined();
|
|
77
|
+
}));
|
|
78
|
+
it('just deserializes JSON into an object', _asyncToGenerator(function* () {
|
|
79
|
+
var xp = new NodeTransport({});
|
|
80
|
+
var resp = {
|
|
81
|
+
headers: {},
|
|
82
|
+
url: '',
|
|
83
|
+
ok: true,
|
|
84
|
+
contentType: 'application/json',
|
|
85
|
+
statusCode: 200,
|
|
86
|
+
statusMessage: 'mock',
|
|
87
|
+
method: 'GET',
|
|
88
|
+
body: "\n{\n \"string1\": 1,\n \"num1\": 1,\n \"string2\": \"2\",\n \"num2\": \"2\",\n \"string3\": \"3\",\n \"num3\": 3,\n \"string4\": \"4\",\n \"num4\": 4\n}\n",
|
|
89
|
+
requestStarted: 1000,
|
|
90
|
+
responseCompleted: 2000
|
|
91
|
+
};
|
|
92
|
+
var untyped = yield sdkOk(xp.parseResponse(resp));
|
|
93
|
+
expect(untyped.string1).toBe(1);
|
|
94
|
+
expect(untyped.num1).toBe(1);
|
|
95
|
+
expect(untyped.string2).toBe('2');
|
|
96
|
+
expect(untyped.num2).toBe('2');
|
|
97
|
+
expect(untyped.string3).toBe('3');
|
|
98
|
+
expect(untyped.num3).toBe(3);
|
|
99
|
+
expect(untyped.string4).toBe('4');
|
|
100
|
+
expect(untyped.num4).toBe(4);
|
|
101
|
+
var typed = yield sdkOk(xp.parseResponse(resp));
|
|
102
|
+
expect(typed.string1).toBe(1);
|
|
103
|
+
expect(typed.num1).toBe(1);
|
|
104
|
+
expect(typed.string2).toBe('2');
|
|
105
|
+
expect(typed.num2).toBe('2');
|
|
106
|
+
expect(typed.string3).toBe('3');
|
|
107
|
+
expect(typed.num3).toBe(3);
|
|
108
|
+
expect(typed.string4).toBe('4');
|
|
109
|
+
expect(typed.num4).toBe(4);
|
|
110
|
+
}));
|
|
111
|
+
describe('NodeCryptoHash', () => {
|
|
112
|
+
it('secureRandom', () => {
|
|
113
|
+
var hasher = new NodeCryptoHash();
|
|
114
|
+
var rand1 = hasher.secureRandom(5);
|
|
115
|
+
expect(rand1.length).toEqual(10);
|
|
116
|
+
var rand2 = hasher.secureRandom(32);
|
|
117
|
+
expect(rand2.length).toEqual(64);
|
|
118
|
+
});
|
|
119
|
+
it('sha256hash', _asyncToGenerator(function* () {
|
|
120
|
+
var hasher = new NodeCryptoHash();
|
|
121
|
+
var message = 'The quick brown fox jumped over the lazy dog.';
|
|
122
|
+
var hash = yield hasher.sha256Hash(message);
|
|
123
|
+
expect(hash).toEqual('aLEoK5HeLAVMNmKcuN1EfxLwltPjxYeXjcIkhERjNIM=');
|
|
124
|
+
}));
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=nodeTransport.apitest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodeTransport.apitest.js","names":["describe","it","expect","StatusCode","sdkOk","NodeCryptoHash","NodeTransport","hostname","settings","base_url","xp","fullPath","badPath","_asyncToGenerator","response","rawRequest","toBeDefined","ok","toEqual","method","statusCode","statusMessage","contentType","toContain","body","html","errorMessage","request","content","value","raw","headers","url","OK","requestStarted","responseCompleted","IMUsed","actual","resp","untyped","parseResponse","string1","toBe","num1","string2","num2","string3","num3","string4","num4","typed","hasher","rand1","secureRandom","length","rand2","message","hash","sha256Hash"],"sources":["../../src/nodeTransport.apitest.ts"],"sourcesContent":["/*\n\n MIT License\n\n Copyright (c) 2021 Looker Data Sciences, Inc.\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n\n */\n\nimport { describe, it } from 'node:test';\nimport { expect } from 'expect';\nimport type {\n IRawResponse,\n ISDKError,\n ITransportSettings,\n} from '@looker/sdk-rtl';\nimport { StatusCode, sdkOk } from '@looker/sdk-rtl';\nimport { NodeCryptoHash, NodeTransport } from './nodeTransport';\n\ndescribe('NodeTransport', () => {\n const hostname = 'https://looker.sdk';\n const settings = { base_url: hostname } as ITransportSettings;\n const xp = new NodeTransport(settings);\n const fullPath = 'https://github.com/looker-open-source/sdk-codegen';\n const badPath = fullPath + '_bogus';\n // const queryParams = { a: 'b c', d: false, nil: null, skip: undefined }\n\n it('raw request retrieves fully qualified url', async () => {\n const response = await xp.rawRequest('GET', fullPath);\n expect(response).toBeDefined();\n expect(response.ok).toEqual(true);\n expect(response.method).toEqual('GET');\n expect(response.statusCode).toEqual(200);\n expect(response.statusMessage).toEqual('OK');\n expect(response.contentType).toContain('text/html');\n expect(response.body).toBeDefined();\n const html = await response.body;\n expect(html).toContain(\n 'One SDK to rule them all, and in the codegen bind them'\n );\n });\n\n describe('transport errors', () => {\n it('gracefully handles transport errors', async () => {\n const response = await xp.rawRequest('GET', badPath);\n const errorMessage = 'Not Found';\n expect(response).toBeDefined();\n expect(response.ok).toEqual(false);\n expect(response.method).toEqual('GET');\n expect(response.statusCode).toEqual(404);\n expect(response.body).toBeDefined();\n expect(response.statusMessage).toEqual(errorMessage);\n });\n });\n\n it('retrieves fully qualified url', async () => {\n const response = await xp.request<string, Error>('GET', fullPath);\n expect(response).toBeDefined();\n expect(response.ok).toEqual(true);\n if (response.ok) {\n const content = response.value;\n expect(content).toContain(\n 'One SDK to rule them all, and in the codegen bind them'\n );\n }\n });\n\n describe('ok check', () => {\n const raw: IRawResponse = {\n method: 'GET',\n contentType: 'application/json',\n headers: {},\n url: 'bogus',\n ok: true,\n statusCode: StatusCode.OK,\n statusMessage: 'Mocked success',\n body: 'body',\n requestStarted: 1000,\n responseCompleted: 2000,\n };\n\n it('ok is ok', () => {\n expect(xp.ok(raw)).toEqual(true);\n });\n\n it('All 2xx responses are ok', () => {\n raw.statusCode = StatusCode.IMUsed;\n expect(xp.ok(raw)).toEqual(true);\n });\n\n it('Non-2xx responses are not ok', () => {\n raw.statusCode = 422;\n expect(xp.ok(raw)).toEqual(false);\n });\n });\n\n it('does a standard get', async () => {\n const xp = new NodeTransport({} as ITransportSettings);\n const actual = await xp.rawRequest('GET', 'https://example.com');\n expect(actual).toBeDefined();\n });\n\n it('just deserializes JSON into an object', async () => {\n const xp = new NodeTransport({} as ITransportSettings);\n interface ITestModel {\n string1: string;\n num1: number;\n string2: string;\n num2: number;\n string3: string;\n num3: number;\n }\n const resp: IRawResponse = {\n headers: {},\n url: '',\n ok: true,\n contentType: 'application/json',\n statusCode: 200,\n statusMessage: 'mock',\n method: 'GET',\n body: `\n{\n \"string1\": 1,\n \"num1\": 1,\n \"string2\": \"2\",\n \"num2\": \"2\",\n \"string3\": \"3\",\n \"num3\": 3,\n \"string4\": \"4\",\n \"num4\": 4\n}\n`,\n requestStarted: 1000,\n responseCompleted: 2000,\n };\n const untyped: any = await sdkOk(xp.parseResponse(resp));\n expect(untyped.string1).toBe(1);\n expect(untyped.num1).toBe(1);\n expect(untyped.string2).toBe('2');\n expect(untyped.num2).toBe('2');\n expect(untyped.string3).toBe('3');\n expect(untyped.num3).toBe(3);\n expect(untyped.string4).toBe('4');\n expect(untyped.num4).toBe(4);\n const typed = await sdkOk(xp.parseResponse<ITestModel, ISDKError>(resp));\n expect(typed.string1).toBe(1);\n expect(typed.num1).toBe(1);\n expect(typed.string2).toBe('2');\n expect(typed.num2).toBe('2');\n expect(typed.string3).toBe('3');\n expect(typed.num3).toBe(3);\n expect((typed as any).string4).toBe('4');\n expect((typed as any).num4).toBe(4);\n });\n describe('NodeCryptoHash', () => {\n it('secureRandom', () => {\n const hasher = new NodeCryptoHash();\n const rand1 = hasher.secureRandom(5);\n expect(rand1.length).toEqual(10);\n const rand2 = hasher.secureRandom(32);\n expect(rand2.length).toEqual(64);\n });\n\n it('sha256hash', async () => {\n const hasher = new NodeCryptoHash();\n const message = 'The quick brown fox jumped over the lazy dog.';\n const hash = await hasher.sha256Hash(message);\n expect(hash).toEqual('aLEoK5HeLAVMNmKcuN1EfxLwltPjxYeXjcIkhERjNIM=');\n });\n });\n});\n"],"mappings":"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"}
|