mirror of
https://github.com/sasjs/adapter.git
synced 2025-12-12 17:54:35 +00:00
Compare commits
89 Commits
v2.11.2
...
sasjs-test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f881fba72 | ||
|
|
4e125ce38f | ||
|
|
4a963ffbf5 | ||
|
|
f25d9ec09d | ||
|
|
4197ad5aa8 | ||
|
|
2ebd6e11ba | ||
|
|
098e7f8590 | ||
|
|
42aec96410 | ||
|
|
f2905ee169 | ||
|
|
1ba9291746 | ||
|
|
c44766ea14 | ||
|
|
2c10b9c65c | ||
|
|
c56874fe00 | ||
|
|
ebe9c2ffeb | ||
|
|
b645d1495b | ||
| 3a4a4c3460 | |||
|
|
182de51f9b | ||
|
|
712d1549c7 | ||
|
|
5a478c8936 | ||
| c9ecc1dde4 | |||
| bdf9e2fd5b | |||
|
|
0b795b26c0 | ||
| 96aac0cfa2 | |||
|
|
a82e1f33e3 | ||
|
|
058c887cd3 | ||
|
|
81d959c7c1 | ||
| 7c5adeabb5 | |||
|
|
cb88376bda | ||
|
|
4c8ddeca25 | ||
|
|
d264a3f239 | ||
|
|
840b1aa1bf | ||
|
|
e26fd307c8 | ||
|
|
62deaf9f03 | ||
|
|
865bf71f7d | ||
|
|
734c5bccaa | ||
|
|
bc82cb5f5e | ||
|
|
f25c76fdfd | ||
|
|
e649b41e9e | ||
|
|
a962979765 | ||
|
|
01d76fa66f | ||
|
|
49cfde9f7d | ||
|
|
ce04ffea05 | ||
| 9dc0499f66 | |||
|
|
bc1a7dc54f | ||
|
|
93c267fd4e | ||
|
|
0457eb6663 | ||
|
|
519494718b | ||
|
|
de5c38f0fb | ||
|
|
208470e7d9 | ||
|
|
0321f77451 | ||
|
|
6c5fdc01eb | ||
|
|
2aa0cd8d7a | ||
|
|
397bc4524f | ||
|
|
8dce9f3e48 | ||
| 8e9f1df1ce | |||
|
|
ff4915f7f3 | ||
|
|
6ff8eece7b | ||
|
|
2849e6ed07 | ||
|
|
90b11fe3fa | ||
|
|
147609842d | ||
|
|
dd6f9cd617 | ||
|
|
7f590c35da | ||
|
|
a38de108e3 | ||
|
|
e975e7de97 | ||
|
|
d418a7e971 | ||
|
|
a5b5052a5f | ||
|
|
7638595523 | ||
|
|
70d64f6eec | ||
|
|
f0ecfa57e5 | ||
|
|
5f3416ecd7 | ||
|
|
d8b1a72da2 | ||
|
|
7e64819eb2 | ||
|
|
2f1d403af4 | ||
|
|
075d410f7d | ||
|
|
f964bcef9e | ||
|
|
5784232d4e | ||
|
|
70ecc8b50e | ||
|
|
369a035e8a | ||
|
|
e5655033c1 | ||
|
|
c7af30bfa3 | ||
|
|
c8da3a54cf | ||
|
|
100da16803 | ||
|
|
dc91679040 | ||
| 28c8ebfc65 | |||
|
|
0c4d30afe3 | ||
|
|
bc015b72b6 | ||
| 085a3f84e9 | |||
|
|
f241d75f0a | ||
|
|
42d01b4044 |
10
.github/dependabot.yml
vendored
10
.github/dependabot.yml
vendored
@@ -1,7 +1,7 @@
|
|||||||
version: 2
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
- package-ecosystem: npm
|
- package-ecosystem: npm
|
||||||
directory: "/"
|
directory: '/'
|
||||||
schedule:
|
schedule:
|
||||||
interval: daily
|
interval: monthly
|
||||||
open-pull-requests-limit: 10
|
open-pull-requests-limit: 10
|
||||||
|
|||||||
5
.github/workflows/build.yml
vendored
5
.github/workflows/build.yml
vendored
@@ -13,14 +13,15 @@ jobs:
|
|||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [15.x]
|
node-version: [lts/fermium]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
|
cache: npm
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
- name: Check code style
|
- name: Check code style
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,4 +5,4 @@ build
|
|||||||
|
|
||||||
/coverage
|
/coverage
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ docs/
|
|||||||
.github/
|
.github/
|
||||||
*.md
|
*.md
|
||||||
*.spec.ts
|
*.spec.ts
|
||||||
|
.all-contributorsrc
|
||||||
|
|||||||
16
README.md
16
README.md
@@ -36,7 +36,7 @@ Ok ok. Deploy this [example.html](https://raw.githubusercontent.com/sasjs/adapte
|
|||||||
|
|
||||||
The backend part can be deployed as follows:
|
The backend part can be deployed as follows:
|
||||||
|
|
||||||
```
|
```sas
|
||||||
%let appLoc=/Public/app/readme; /* Metadata or Viya Folder per SASjs config */
|
%let appLoc=/Public/app/readme; /* Metadata or Viya Folder per SASjs config */
|
||||||
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
||||||
%inc mc; /* compile macros (can also be downloaded & compiled seperately) */
|
%inc mc; /* compile macros (can also be downloaded & compiled seperately) */
|
||||||
@@ -85,11 +85,11 @@ let sasJs = new SASjs.default(
|
|||||||
);
|
);
|
||||||
```
|
```
|
||||||
If you've installed it via NPM, you can import it as a default import like so:
|
If you've installed it via NPM, you can import it as a default import like so:
|
||||||
```
|
```js
|
||||||
import SASjs from '@sasjs/adapter';
|
import SASjs from '@sasjs/adapter';
|
||||||
```
|
```
|
||||||
You can then instantiate it with:
|
You can then instantiate it with:
|
||||||
```
|
```js
|
||||||
const sasJs = new SASjs({your config})
|
const sasJs = new SASjs({your config})
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -119,6 +119,7 @@ sasJs.request("/path/to/my/service", dataObject)
|
|||||||
console.log(response.tablewith2cols1row[0].COL1.value)
|
console.log(response.tablewith2cols1row[0].COL1.value)
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
We supply the path to the SAS service, and a data object. The data object can be null (for services with no input), or can contain one or more tables in the following format:
|
We supply the path to the SAS service, and a data object. The data object can be null (for services with no input), or can contain one or more tables in the following format:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@@ -146,6 +147,7 @@ The adapter will also cache the logs (if debug enabled) and even the work tables
|
|||||||
The SAS side is handled by a number of macros in the [macro core](https://github.com/sasjs/core) library.
|
The SAS side is handled by a number of macros in the [macro core](https://github.com/sasjs/core) library.
|
||||||
|
|
||||||
The following snippet shows the process of SAS tables arriving / leaving:
|
The following snippet shows the process of SAS tables arriving / leaving:
|
||||||
|
|
||||||
```sas
|
```sas
|
||||||
/* fetch all input tables sent from frontend - they arrive as work tables */
|
/* fetch all input tables sent from frontend - they arrive as work tables */
|
||||||
%webout(FETCH)
|
%webout(FETCH)
|
||||||
@@ -161,7 +163,6 @@ run;
|
|||||||
%webout(OBJ,tables,fmt=N) /* unformatted (raw) data */
|
%webout(OBJ,tables,fmt=N) /* unformatted (raw) data */
|
||||||
%webout(OBJ,tables,label=newtable) /* rename tables on export */
|
%webout(OBJ,tables,label=newtable) /* rename tables on export */
|
||||||
%webout(CLOSE) /* close the JSON and send some extra useful variables too */
|
%webout(CLOSE) /* close the JSON and send some extra useful variables too */
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
@@ -172,6 +173,7 @@ Configuration on the client side involves passing an object on startup, which ca
|
|||||||
* `serverType` - either `SAS9` or `SASVIYA`.
|
* `serverType` - either `SAS9` or `SASVIYA`.
|
||||||
* `serverUrl` - the location (including http protocol and port) of the SAS Server. Can be omitted, eg if serving directly from the SAS Web Server, or in streaming mode.
|
* `serverUrl` - the location (including http protocol and port) of the SAS Server. Can be omitted, eg if serving directly from the SAS Web Server, or in streaming mode.
|
||||||
* `debug` - if `true` then SAS Logs and extra debug information is returned.
|
* `debug` - if `true` then SAS Logs and extra debug information is returned.
|
||||||
|
* `LoginMechanism` - either `Default` or `Redirected`. If `Redirected` then authentication occurs through the injection of an additional screen, which contains the SASLogon prompt. This allows for more complex authentication flows (such as 2FA) and avoids the need to handle passwords in the application itself. The styling of the redirect flow can also be modified. If left at "Default" then the developer must capture the username and password and use these with the `.login()` method.
|
||||||
* `useComputeApi` - Only relevant when the serverType is `SASVIYA`. If `true` the [Compute API](#using-the-compute-api) is used. If `false` the [JES API](#using-the-jes-api) is used. If `null` or `undefined` the [Web](#using-jes-web-app) approach is used.
|
* `useComputeApi` - Only relevant when the serverType is `SASVIYA`. If `true` the [Compute API](#using-the-compute-api) is used. If `false` the [JES API](#using-the-jes-api) is used. If `null` or `undefined` the [Web](#using-jes-web-app) approach is used.
|
||||||
* `contextName` - Compute context on which the requests will be called. If missing or not provided, defaults to `Job Execution Compute context`.
|
* `contextName` - Compute context on which the requests will be called. If missing or not provided, defaults to `Job Execution Compute context`.
|
||||||
|
|
||||||
@@ -196,7 +198,7 @@ Here we are running Jobs using the Job Execution Service except this time we are
|
|||||||
|
|
||||||
This approach (`useComputeApi: false`) also ensures that jobs are displayed in Environment Manager.
|
This approach (`useComputeApi: false`) also ensures that jobs are displayed in Environment Manager.
|
||||||
|
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
appLoc:"/Your/Path",
|
appLoc:"/Your/Path",
|
||||||
serverType:"SASVIYA",
|
serverType:"SASVIYA",
|
||||||
@@ -210,12 +212,12 @@ This approach is by far the fastest, as a result of the optimisations we have bu
|
|||||||
|
|
||||||
With this approach (`useComputeApi: true`), the requests/logs will _not_ appear in the list in Environment manager.
|
With this approach (`useComputeApi: true`), the requests/logs will _not_ appear in the list in Environment manager.
|
||||||
|
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
appLoc:"/Your/Path",
|
appLoc:"/Your/Path",
|
||||||
serverType:"SASVIYA",
|
serverType:"SASVIYA",
|
||||||
useComputeApi: true,
|
useComputeApi: true,
|
||||||
contextName: 'yourComputeContext'
|
contextName: "yourComputeContext"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
225
docs/classes/api_viya_spec.mockstream.html
Normal file
225
docs/classes/api_viya_spec.mockstream.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
358
docs/classes/job_execution.fileuploader.html
Normal file
358
docs/classes/job_execution.fileuploader.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
366
docs/classes/job_execution.sas9jobexecutor.html
Normal file
366
docs/classes/job_execution.sas9jobexecutor.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1168
docs/classes/request.sas9requestclient.html
Normal file
1168
docs/classes/request.sas9requestclient.html
Normal file
File diff suppressed because one or more lines are too long
1131
docs/classes/request.sasjsrequestclient.html
Normal file
1131
docs/classes/request.sasjsrequestclient.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
420
docs/classes/root.sasjsapiclient.html
Normal file
420
docs/classes/root.sasjsapiclient.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
281
docs/classes/types_errors.invalidjsonerror.html
Normal file
281
docs/classes/types_errors.invalidjsonerror.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
308
docs/classes/types_errors.jobstatepollerror.html
Normal file
308
docs/classes/types_errors.jobstatepollerror.html
Normal file
File diff suppressed because one or more lines are too long
281
docs/classes/types_errors.jsonparsearrayerror.html
Normal file
281
docs/classes/types_errors.jsonparsearrayerror.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
347
docs/classes/types_errors.nosessionstateerror.html
Normal file
347
docs/classes/types_errors.nosessionstateerror.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
293
docs/classes/types_errors.rootfoldernotfounderror.html
Normal file
293
docs/classes/types_errors.rootfoldernotfounderror.html
Normal file
File diff suppressed because one or more lines are too long
281
docs/classes/types_errors.sas9autherror.html
Normal file
281
docs/classes/types_errors.sas9autherror.html
Normal file
File diff suppressed because one or more lines are too long
305
docs/classes/types_errors.weboutresponseerror.html
Normal file
305
docs/classes/types_errors.weboutresponseerror.html
Normal file
File diff suppressed because one or more lines are too long
235
docs/enums/types.loginmechanism.html
Normal file
235
docs/enums/types.loginmechanism.html
Normal file
File diff suppressed because one or more lines are too long
235
docs/enums/types.membertype.html
Normal file
235
docs/enums/types.membertype.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
139
docs/index.html
139
docs/index.html
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
183
docs/interfaces/root.sasjsauthresponse.html
Normal file
183
docs/interfaces/root.sasjsauthresponse.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
243
docs/interfaces/types.executionquery.html
Normal file
243
docs/interfaces/types.executionquery.html
Normal file
File diff suppressed because one or more lines are too long
279
docs/interfaces/types.file.html
Normal file
279
docs/interfaces/types.file.html
Normal file
File diff suppressed because one or more lines are too long
225
docs/interfaces/types.filetree.html
Normal file
225
docs/interfaces/types.filetree.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
261
docs/interfaces/types.foldermember.html
Normal file
261
docs/interfaces/types.foldermember.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
225
docs/interfaces/types.loginoptions.html
Normal file
225
docs/interfaces/types.loginoptions.html
Normal file
File diff suppressed because one or more lines are too long
243
docs/interfaces/types.loginresult.html
Normal file
243
docs/interfaces/types.loginresult.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
147
docs/interfaces/types.process.html
Normal file
147
docs/interfaces/types.process.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
261
docs/interfaces/types.servicemember.html
Normal file
261
docs/interfaces/types.servicemember.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
285
docs/interfaces/types.writestream.html
Normal file
285
docs/interfaces/types.writestream.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
455
docs/modules/api_viya.html
Normal file
455
docs/modules/api_viya.html
Normal file
File diff suppressed because one or more lines are too long
452
docs/modules/api_viya_spec.html
Normal file
452
docs/modules/api_viya_spec.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
251
docs/modules/test.html
Normal file
251
docs/modules/test.html
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
20061
package-lock.json
generated
20061
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
22
package.json
22
package.json
@@ -41,36 +41,40 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/axios": "^0.14.0",
|
"@types/axios": "^0.14.0",
|
||||||
|
"@types/express": "^4.17.13",
|
||||||
"@types/form-data": "^2.5.0",
|
"@types/form-data": "^2.5.0",
|
||||||
"@types/jest": "^27.0.1",
|
"@types/jest": "^27.0.2",
|
||||||
"@types/mime": "^2.0.3",
|
"@types/mime": "^2.0.3",
|
||||||
|
"@types/pem": "^1.9.6",
|
||||||
"@types/tough-cookie": "^4.0.1",
|
"@types/tough-cookie": "^4.0.1",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"cp": "^0.2.0",
|
"cp": "^0.2.0",
|
||||||
"dotenv": "^10.0.0",
|
"dotenv": "^10.0.0",
|
||||||
"jest": "^27.1.0",
|
"express": "^4.17.1",
|
||||||
|
"jest": "^27.2.0",
|
||||||
"jest-extended": "^0.11.5",
|
"jest-extended": "^0.11.5",
|
||||||
"node-polyfill-webpack-plugin": "^1.1.4",
|
"node-polyfill-webpack-plugin": "^1.1.4",
|
||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
|
"pem": "^1.14.4",
|
||||||
"process": "^0.11.10",
|
"process": "^0.11.10",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"semantic-release": "^17.4.7",
|
"semantic-release": "^18.0.0",
|
||||||
"terser-webpack-plugin": "^5.2.0",
|
"terser-webpack-plugin": "^5.2.4",
|
||||||
"ts-jest": "^27.0.3",
|
"ts-jest": "^27.0.3",
|
||||||
"ts-loader": "^9.2.2",
|
"ts-loader": "^9.2.6",
|
||||||
"tslint": "^6.1.3",
|
"tslint": "^6.1.3",
|
||||||
"tslint-config-prettier": "^1.18.0",
|
"tslint-config-prettier": "^1.18.0",
|
||||||
"typedoc": "^0.21.9",
|
"typedoc": "0.19.2",
|
||||||
"typedoc-neo-theme": "^1.1.1",
|
"typedoc-neo-theme": "^1.1.1",
|
||||||
"typedoc-plugin-external-module-name": "^4.0.6",
|
"typedoc-plugin-external-module-name": "^4.0.6",
|
||||||
"typescript": "4.3.5",
|
"typescript": "4.3.5",
|
||||||
"webpack": "^5.44.0",
|
"webpack": "^5.56.0",
|
||||||
"webpack-cli": "^4.7.2"
|
"webpack-cli": "^4.7.2"
|
||||||
},
|
},
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sasjs/utils": "^2.30.0",
|
"@sasjs/utils": "^2.32.0",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.4",
|
||||||
"axios-cookiejar-support": "^1.0.1",
|
"axios-cookiejar-support": "^1.0.1",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"https": "^1.0.0",
|
"https": "^1.0.0",
|
||||||
|
|||||||
31222
sasjs-tests/package-lock.json
generated
31222
sasjs-tests/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sasjs/adapter": "file:../build/sasjs-adapter-5.0.0.tgz",
|
"@sasjs/adapter": "file:../build/sasjs-adapter-5.0.0.tgz",
|
||||||
"@sasjs/test-framework": "^1.4.0",
|
"@sasjs/test-framework": "^1.4.2",
|
||||||
"@types/jest": "^26.0.20",
|
"@types/jest": "^26.0.20",
|
||||||
"@types/node": "^14.14.41",
|
"@types/node": "^14.14.41",
|
||||||
"@types/react": "^17.0.1",
|
"@types/react": "^17.0.1",
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ const defaultConfig: SASjsConfig = {
|
|||||||
debug: false,
|
debug: false,
|
||||||
contextName: 'SAS Job Execution compute context',
|
contextName: 'SAS Job Execution compute context',
|
||||||
useComputeApi: false,
|
useComputeApi: false,
|
||||||
allowInsecureRequests: false,
|
|
||||||
loginMechanism: LoginMechanism.Default
|
loginMechanism: LoginMechanism.Default
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,8 +77,8 @@ export const basicTests = (
|
|||||||
'common/sendArr',
|
'common/sendArr',
|
||||||
stringData,
|
stringData,
|
||||||
undefined,
|
undefined,
|
||||||
() => {
|
async () => {
|
||||||
adapter.logIn(userName, password)
|
await adapter.logIn(userName, password)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import * as https from 'https'
|
||||||
import { generateTimestamp } from '@sasjs/utils/time'
|
import { generateTimestamp } from '@sasjs/utils/time'
|
||||||
import * as NodeFormData from 'form-data'
|
import * as NodeFormData from 'form-data'
|
||||||
import { Sas9RequestClient } from './request/Sas9RequestClient'
|
import { Sas9RequestClient } from './request/Sas9RequestClient'
|
||||||
@@ -13,10 +14,10 @@ export class SAS9ApiClient {
|
|||||||
constructor(
|
constructor(
|
||||||
private serverUrl: string,
|
private serverUrl: string,
|
||||||
private jobsPath: string,
|
private jobsPath: string,
|
||||||
allowInsecureRequests: boolean
|
httpsAgentOptions?: https.AgentOptions
|
||||||
) {
|
) {
|
||||||
if (serverUrl) isUrl(serverUrl)
|
if (serverUrl) isUrl(serverUrl)
|
||||||
this.requestClient = new Sas9RequestClient(serverUrl, allowInsecureRequests)
|
this.requestClient = new Sas9RequestClient(serverUrl, httpsAgentOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import { pollJobState } from './api/viya/pollJobState'
|
|||||||
import { getTokens } from './auth/getTokens'
|
import { getTokens } from './auth/getTokens'
|
||||||
import { uploadTables } from './api/viya/uploadTables'
|
import { uploadTables } from './api/viya/uploadTables'
|
||||||
import { executeScript } from './api/viya/executeScript'
|
import { executeScript } from './api/viya/executeScript'
|
||||||
import { getAccessToken } from './auth/getAccessToken'
|
import { getAccessTokenForViya } from './auth/getAccessTokenForViya'
|
||||||
import { refreshTokens } from './auth/refreshTokens'
|
import { refreshTokensForViya } from './auth/refreshTokensForViya'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A client for interfacing with the SAS Viya REST API.
|
* A client for interfacing with the SAS Viya REST API.
|
||||||
@@ -534,21 +534,26 @@ export class SASViyaApiClient {
|
|||||||
clientSecret: string,
|
clientSecret: string,
|
||||||
authCode: string
|
authCode: string
|
||||||
): Promise<SasAuthResponse> {
|
): Promise<SasAuthResponse> {
|
||||||
return getAccessToken(this.requestClient, clientId, clientSecret, authCode)
|
return getAccessTokenForViya(
|
||||||
|
this.requestClient,
|
||||||
|
clientId,
|
||||||
|
clientSecret,
|
||||||
|
authCode
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exchanges the refresh token for an access token for the given client.
|
* Exchanges the refresh token for an access token for the given client.
|
||||||
* @param clientId - the client ID to authenticate with.
|
* @param clientId - the client ID to authenticate with.
|
||||||
* @param clientSecret - the client secret to authenticate with.
|
* @param clientSecret - the client secret to authenticate with.
|
||||||
* @param authCode - the refresh token received from the server.
|
* @param refreshToken - the refresh token received from the server.
|
||||||
*/
|
*/
|
||||||
public async refreshTokens(
|
public async refreshTokens(
|
||||||
clientId: string,
|
clientId: string,
|
||||||
clientSecret: string,
|
clientSecret: string,
|
||||||
refreshToken: string
|
refreshToken: string
|
||||||
) {
|
) {
|
||||||
return refreshTokens(
|
return refreshTokensForViya(
|
||||||
this.requestClient,
|
this.requestClient,
|
||||||
clientId,
|
clientId,
|
||||||
clientSecret,
|
clientSecret,
|
||||||
|
|||||||
162
src/SASjs.ts
162
src/SASjs.ts
@@ -4,18 +4,24 @@ import {
|
|||||||
UploadFile,
|
UploadFile,
|
||||||
EditContextInput,
|
EditContextInput,
|
||||||
PollOptions,
|
PollOptions,
|
||||||
LoginMechanism
|
LoginMechanism,
|
||||||
|
FolderMember,
|
||||||
|
ServiceMember,
|
||||||
|
ExecutionQuery
|
||||||
} from './types'
|
} from './types'
|
||||||
import { SASViyaApiClient } from './SASViyaApiClient'
|
import { SASViyaApiClient } from './SASViyaApiClient'
|
||||||
import { SAS9ApiClient } from './SAS9ApiClient'
|
import { SAS9ApiClient } from './SAS9ApiClient'
|
||||||
|
import { SASjsApiClient, SASjsAuthResponse } from './SASjsApiClient'
|
||||||
import { AuthManager } from './auth'
|
import { AuthManager } from './auth'
|
||||||
import {
|
import {
|
||||||
ServerType,
|
ServerType,
|
||||||
MacroVar,
|
MacroVar,
|
||||||
AuthConfig,
|
AuthConfig,
|
||||||
ExtraResponseAttributes
|
ExtraResponseAttributes,
|
||||||
|
SasAuthResponse
|
||||||
} from '@sasjs/utils/types'
|
} from '@sasjs/utils/types'
|
||||||
import { RequestClient } from './request/RequestClient'
|
import { RequestClient } from './request/RequestClient'
|
||||||
|
import { SasjsRequestClient } from './request/SasjsRequestClient'
|
||||||
import {
|
import {
|
||||||
JobExecutor,
|
JobExecutor,
|
||||||
WebJobExecutor,
|
WebJobExecutor,
|
||||||
@@ -29,6 +35,7 @@ import { LoginOptions, LoginResult } from './types/Login'
|
|||||||
|
|
||||||
const defaultConfig: SASjsConfig = {
|
const defaultConfig: SASjsConfig = {
|
||||||
serverUrl: '',
|
serverUrl: '',
|
||||||
|
pathSASJS: '/SASjsApi/stp/execute',
|
||||||
pathSAS9: '/SASStoredProcess/do',
|
pathSAS9: '/SASStoredProcess/do',
|
||||||
pathSASViya: '/SASJobExecution',
|
pathSASViya: '/SASJobExecution',
|
||||||
appLoc: '/Public/seedapp',
|
appLoc: '/Public/seedapp',
|
||||||
@@ -36,7 +43,6 @@ const defaultConfig: SASjsConfig = {
|
|||||||
debug: false,
|
debug: false,
|
||||||
contextName: 'SAS Job Execution compute context',
|
contextName: 'SAS Job Execution compute context',
|
||||||
useComputeApi: null,
|
useComputeApi: null,
|
||||||
allowInsecureRequests: false,
|
|
||||||
loginMechanism: LoginMechanism.Default
|
loginMechanism: LoginMechanism.Default
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,6 +55,7 @@ export default class SASjs {
|
|||||||
private jobsPath: string = ''
|
private jobsPath: string = ''
|
||||||
private sasViyaApiClient: SASViyaApiClient | null = null
|
private sasViyaApiClient: SASViyaApiClient | null = null
|
||||||
private sas9ApiClient: SAS9ApiClient | null = null
|
private sas9ApiClient: SAS9ApiClient | null = null
|
||||||
|
private sasJSApiClient: SASjsApiClient | null = null
|
||||||
private fileUploader: FileUploader | null = null
|
private fileUploader: FileUploader | null = null
|
||||||
private authManager: AuthManager | null = null
|
private authManager: AuthManager | null = null
|
||||||
private requestClient: RequestClient | null = null
|
private requestClient: RequestClient | null = null
|
||||||
@@ -57,7 +64,7 @@ export default class SASjs {
|
|||||||
private jesJobExecutor: JobExecutor | null = null
|
private jesJobExecutor: JobExecutor | null = null
|
||||||
private sas9JobExecutor: JobExecutor | null = null
|
private sas9JobExecutor: JobExecutor | null = null
|
||||||
|
|
||||||
constructor(config?: any) {
|
constructor(config?: Partial<SASjsConfig>) {
|
||||||
this.sasjsConfig = {
|
this.sasjsConfig = {
|
||||||
...defaultConfig,
|
...defaultConfig,
|
||||||
...config
|
...config
|
||||||
@@ -75,7 +82,7 @@ export default class SASjs {
|
|||||||
userName: string,
|
userName: string,
|
||||||
password: string
|
password: string
|
||||||
) {
|
) {
|
||||||
this.isMethodSupported('executeScriptSAS9', ServerType.Sas9)
|
this.isMethodSupported('executeScriptSAS9', [ServerType.Sas9])
|
||||||
|
|
||||||
return await this.sas9ApiClient?.executeScript(
|
return await this.sas9ApiClient?.executeScript(
|
||||||
linesOfCode,
|
linesOfCode,
|
||||||
@@ -89,7 +96,7 @@ export default class SASjs {
|
|||||||
* @param accessToken - an access token for an authorized user.
|
* @param accessToken - an access token for an authorized user.
|
||||||
*/
|
*/
|
||||||
public async getComputeContexts(accessToken: string) {
|
public async getComputeContexts(accessToken: string) {
|
||||||
this.isMethodSupported('getComputeContexts', ServerType.SasViya)
|
this.isMethodSupported('getComputeContexts', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.getComputeContexts(accessToken)
|
return await this.sasViyaApiClient!.getComputeContexts(accessToken)
|
||||||
}
|
}
|
||||||
@@ -99,7 +106,7 @@ export default class SASjs {
|
|||||||
* @param accessToken - an access token for an authorized user.
|
* @param accessToken - an access token for an authorized user.
|
||||||
*/
|
*/
|
||||||
public async getLauncherContexts(accessToken: string) {
|
public async getLauncherContexts(accessToken: string) {
|
||||||
this.isMethodSupported('getLauncherContexts', ServerType.SasViya)
|
this.isMethodSupported('getLauncherContexts', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.getLauncherContexts(accessToken)
|
return await this.sasViyaApiClient!.getLauncherContexts(accessToken)
|
||||||
}
|
}
|
||||||
@@ -108,7 +115,7 @@ export default class SASjs {
|
|||||||
* Gets default(system) launcher contexts.
|
* Gets default(system) launcher contexts.
|
||||||
*/
|
*/
|
||||||
public getDefaultComputeContexts() {
|
public getDefaultComputeContexts() {
|
||||||
this.isMethodSupported('getDefaultComputeContexts', ServerType.SasViya)
|
this.isMethodSupported('getDefaultComputeContexts', [ServerType.SasViya])
|
||||||
|
|
||||||
return this.sasViyaApiClient!.getDefaultComputeContexts()
|
return this.sasViyaApiClient!.getDefaultComputeContexts()
|
||||||
}
|
}
|
||||||
@@ -118,7 +125,7 @@ export default class SASjs {
|
|||||||
* @param authConfig - an access token, refresh token, client and secret for an authorized user.
|
* @param authConfig - an access token, refresh token, client and secret for an authorized user.
|
||||||
*/
|
*/
|
||||||
public async getExecutableContexts(authConfig: AuthConfig) {
|
public async getExecutableContexts(authConfig: AuthConfig) {
|
||||||
this.isMethodSupported('getExecutableContexts', ServerType.SasViya)
|
this.isMethodSupported('getExecutableContexts', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.getExecutableContexts(authConfig)
|
return await this.sasViyaApiClient!.getExecutableContexts(authConfig)
|
||||||
}
|
}
|
||||||
@@ -140,7 +147,7 @@ export default class SASjs {
|
|||||||
accessToken: string,
|
accessToken: string,
|
||||||
authorizedUsers?: string[]
|
authorizedUsers?: string[]
|
||||||
) {
|
) {
|
||||||
this.isMethodSupported('createComputeContext', ServerType.SasViya)
|
this.isMethodSupported('createComputeContext', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.createComputeContext(
|
return await this.sasViyaApiClient!.createComputeContext(
|
||||||
contextName,
|
contextName,
|
||||||
@@ -165,7 +172,7 @@ export default class SASjs {
|
|||||||
launchType: string,
|
launchType: string,
|
||||||
accessToken: string
|
accessToken: string
|
||||||
) {
|
) {
|
||||||
this.isMethodSupported('createLauncherContext', ServerType.SasViya)
|
this.isMethodSupported('createLauncherContext', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.createLauncherContext(
|
return await this.sasViyaApiClient!.createLauncherContext(
|
||||||
contextName,
|
contextName,
|
||||||
@@ -186,7 +193,7 @@ export default class SASjs {
|
|||||||
editedContext: EditContextInput,
|
editedContext: EditContextInput,
|
||||||
accessToken?: string
|
accessToken?: string
|
||||||
) {
|
) {
|
||||||
this.isMethodSupported('editComputeContext', ServerType.SasViya)
|
this.isMethodSupported('editComputeContext', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.editComputeContext(
|
return await this.sasViyaApiClient!.editComputeContext(
|
||||||
contextName,
|
contextName,
|
||||||
@@ -201,7 +208,7 @@ export default class SASjs {
|
|||||||
* @param accessToken - an access token for an authorized user.
|
* @param accessToken - an access token for an authorized user.
|
||||||
*/
|
*/
|
||||||
public async deleteComputeContext(contextName: string, accessToken?: string) {
|
public async deleteComputeContext(contextName: string, accessToken?: string) {
|
||||||
this.isMethodSupported('deleteComputeContext', ServerType.SasViya)
|
this.isMethodSupported('deleteComputeContext', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.deleteComputeContext(
|
return await this.sasViyaApiClient!.deleteComputeContext(
|
||||||
contextName,
|
contextName,
|
||||||
@@ -219,7 +226,7 @@ export default class SASjs {
|
|||||||
contextName: string,
|
contextName: string,
|
||||||
accessToken?: string
|
accessToken?: string
|
||||||
) {
|
) {
|
||||||
this.isMethodSupported('getComputeContextByName', ServerType.SasViya)
|
this.isMethodSupported('getComputeContextByName', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.getComputeContextByName(
|
return await this.sasViyaApiClient!.getComputeContextByName(
|
||||||
contextName,
|
contextName,
|
||||||
@@ -233,7 +240,7 @@ export default class SASjs {
|
|||||||
* @param accessToken - an access token for an authorized user.
|
* @param accessToken - an access token for an authorized user.
|
||||||
*/
|
*/
|
||||||
public async getComputeContextById(contextId: string, accessToken?: string) {
|
public async getComputeContextById(contextId: string, accessToken?: string) {
|
||||||
this.isMethodSupported('getComputeContextById', ServerType.SasViya)
|
this.isMethodSupported('getComputeContextById', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.getComputeContextById(
|
return await this.sasViyaApiClient!.getComputeContextById(
|
||||||
contextId,
|
contextId,
|
||||||
@@ -242,7 +249,7 @@ export default class SASjs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async createSession(contextName: string, accessToken: string) {
|
public async createSession(contextName: string, accessToken: string) {
|
||||||
this.isMethodSupported('createSession', ServerType.SasViya)
|
this.isMethodSupported('createSession', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.createSession(contextName, accessToken)
|
return await this.sasViyaApiClient!.createSession(contextName, accessToken)
|
||||||
}
|
}
|
||||||
@@ -262,7 +269,7 @@ export default class SASjs {
|
|||||||
authConfig?: AuthConfig,
|
authConfig?: AuthConfig,
|
||||||
debug?: boolean
|
debug?: boolean
|
||||||
) {
|
) {
|
||||||
this.isMethodSupported('executeScriptSASViya', ServerType.SasViya)
|
this.isMethodSupported('executeScriptSASViya', [ServerType.SasViya])
|
||||||
if (!contextName) {
|
if (!contextName) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Context name is undefined. Please set a `contextName` in your SASjs or override config.'
|
'Context name is undefined. Please set a `contextName` in your SASjs or override config.'
|
||||||
@@ -352,7 +359,7 @@ export default class SASjs {
|
|||||||
* @param accessToken - the access token to authorize the request.
|
* @param accessToken - the access token to authorize the request.
|
||||||
*/
|
*/
|
||||||
public async getFolder(folderPath: string, accessToken?: string) {
|
public async getFolder(folderPath: string, accessToken?: string) {
|
||||||
this.isMethodSupported('getFolder', ServerType.SasViya)
|
this.isMethodSupported('getFolder', [ServerType.SasViya])
|
||||||
return await this.sasViyaApiClient!.getFolder(folderPath, accessToken)
|
return await this.sasViyaApiClient!.getFolder(folderPath, accessToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,7 +369,7 @@ export default class SASjs {
|
|||||||
* @param accessToken - an access token for authorizing the request.
|
* @param accessToken - an access token for authorizing the request.
|
||||||
*/
|
*/
|
||||||
public async deleteFolder(folderPath: string, accessToken: string) {
|
public async deleteFolder(folderPath: string, accessToken: string) {
|
||||||
this.isMethodSupported('deleteFolder', ServerType.SasViya)
|
this.isMethodSupported('deleteFolder', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient?.deleteFolder(folderPath, accessToken)
|
return await this.sasViyaApiClient?.deleteFolder(folderPath, accessToken)
|
||||||
}
|
}
|
||||||
@@ -377,7 +384,7 @@ export default class SASjs {
|
|||||||
accessToken?: string,
|
accessToken?: string,
|
||||||
limit?: number
|
limit?: number
|
||||||
) {
|
) {
|
||||||
this.isMethodSupported('listFolder', ServerType.SasViya)
|
this.isMethodSupported('listFolder', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient?.listFolder(
|
return await this.sasViyaApiClient?.listFolder(
|
||||||
sourceFolder,
|
sourceFolder,
|
||||||
@@ -399,7 +406,7 @@ export default class SASjs {
|
|||||||
targetFolderName: string,
|
targetFolderName: string,
|
||||||
accessToken: string
|
accessToken: string
|
||||||
) {
|
) {
|
||||||
this.isMethodSupported('moveFolder', ServerType.SasViya)
|
this.isMethodSupported('moveFolder', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient?.moveFolder(
|
return await this.sasViyaApiClient?.moveFolder(
|
||||||
sourceFolder,
|
sourceFolder,
|
||||||
@@ -417,7 +424,7 @@ export default class SASjs {
|
|||||||
accessToken?: string,
|
accessToken?: string,
|
||||||
sasApiClient?: SASViyaApiClient
|
sasApiClient?: SASViyaApiClient
|
||||||
) {
|
) {
|
||||||
this.isMethodSupported('createJobDefinition', ServerType.SasViya)
|
this.isMethodSupported('createJobDefinition', [ServerType.SasViya])
|
||||||
|
|
||||||
if (sasApiClient)
|
if (sasApiClient)
|
||||||
return await sasApiClient!.createJobDefinition(
|
return await sasApiClient!.createJobDefinition(
|
||||||
@@ -437,7 +444,7 @@ export default class SASjs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async getAuthCode(clientId: string) {
|
public async getAuthCode(clientId: string) {
|
||||||
this.isMethodSupported('getAuthCode', ServerType.SasViya)
|
this.isMethodSupported('getAuthCode', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.getAuthCode(clientId)
|
return await this.sasViyaApiClient!.getAuthCode(clientId)
|
||||||
}
|
}
|
||||||
@@ -452,8 +459,14 @@ export default class SASjs {
|
|||||||
clientId: string,
|
clientId: string,
|
||||||
clientSecret: string,
|
clientSecret: string,
|
||||||
authCode: string
|
authCode: string
|
||||||
) {
|
): Promise<SasAuthResponse | SASjsAuthResponse> {
|
||||||
this.isMethodSupported('getAccessToken', ServerType.SasViya)
|
this.isMethodSupported('getAccessToken', [
|
||||||
|
ServerType.SasViya,
|
||||||
|
ServerType.Sasjs
|
||||||
|
])
|
||||||
|
|
||||||
|
if (this.sasjsConfig.serverType === ServerType.Sasjs)
|
||||||
|
return await this.sasJSApiClient!.getAccessToken(clientId, authCode)
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.getAccessToken(
|
return await this.sasViyaApiClient!.getAccessToken(
|
||||||
clientId,
|
clientId,
|
||||||
@@ -462,12 +475,24 @@ export default class SASjs {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exchanges the refresh token for an access token for the given client.
|
||||||
|
* @param clientId - the client ID to authenticate with.
|
||||||
|
* @param clientSecret - the client secret to authenticate with.
|
||||||
|
* @param refreshToken - the refresh token received from the server.
|
||||||
|
*/
|
||||||
public async refreshTokens(
|
public async refreshTokens(
|
||||||
clientId: string,
|
clientId: string,
|
||||||
clientSecret: string,
|
clientSecret: string,
|
||||||
refreshToken: string
|
refreshToken: string
|
||||||
) {
|
): Promise<SasAuthResponse | SASjsAuthResponse> {
|
||||||
this.isMethodSupported('refreshTokens', ServerType.SasViya)
|
this.isMethodSupported('refreshTokens', [
|
||||||
|
ServerType.SasViya,
|
||||||
|
ServerType.Sasjs
|
||||||
|
])
|
||||||
|
|
||||||
|
if (this.sasjsConfig.serverType === ServerType.Sasjs)
|
||||||
|
return await this.sasJSApiClient!.refreshTokens(refreshToken)
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.refreshTokens(
|
return await this.sasViyaApiClient!.refreshTokens(
|
||||||
clientId,
|
clientId,
|
||||||
@@ -477,7 +502,7 @@ export default class SASjs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async deleteClient(clientId: string, accessToken: string) {
|
public async deleteClient(clientId: string, accessToken: string) {
|
||||||
this.isMethodSupported('deleteClient', ServerType.SasViya)
|
this.isMethodSupported('deleteClient', [ServerType.SasViya])
|
||||||
|
|
||||||
return await this.sasViyaApiClient!.deleteClient(clientId, accessToken)
|
return await this.sasViyaApiClient!.deleteClient(clientId, accessToken)
|
||||||
}
|
}
|
||||||
@@ -533,18 +558,29 @@ export default class SASjs {
|
|||||||
* Logs into the SAS server with the supplied credentials.
|
* Logs into the SAS server with the supplied credentials.
|
||||||
* @param username - a string representing the username.
|
* @param username - a string representing the username.
|
||||||
* @param password - a string representing the password.
|
* @param password - a string representing the password.
|
||||||
|
* @param clientId - a string representing the client ID.
|
||||||
*/
|
*/
|
||||||
public async logIn(
|
public async logIn(
|
||||||
username?: string,
|
username?: string,
|
||||||
password?: string,
|
password?: string,
|
||||||
|
clientId?: string,
|
||||||
options: LoginOptions = {}
|
options: LoginOptions = {}
|
||||||
): Promise<LoginResult> {
|
): Promise<LoginResult> {
|
||||||
if (this.sasjsConfig.loginMechanism === LoginMechanism.Default) {
|
if (this.sasjsConfig.loginMechanism === LoginMechanism.Default) {
|
||||||
if (!username || !password) {
|
if (!username || !password)
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'A username and password are required when using the default login mechanism.'
|
'A username and password are required when using the default login mechanism.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (this.sasjsConfig.serverType === ServerType.Sasjs) {
|
||||||
|
if (!clientId)
|
||||||
|
throw new Error(
|
||||||
|
'A username, password and clientId are required when using the default login mechanism with server type SASJS.'
|
||||||
|
)
|
||||||
|
|
||||||
|
return this.authManager!.logInSasjs(username, password, clientId)
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.authManager!.logIn(username, password)
|
return this.authManager!.logIn(username, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -770,7 +806,7 @@ export default class SASjs {
|
|||||||
accessToken?: string,
|
accessToken?: string,
|
||||||
isForced = false
|
isForced = false
|
||||||
) {
|
) {
|
||||||
this.isMethodSupported('deployServicePack', ServerType.SasViya)
|
this.isMethodSupported('deployServicePack', [ServerType.SasViya])
|
||||||
|
|
||||||
let sasApiClient: any = null
|
let sasApiClient: any = null
|
||||||
if (serverUrl || appLoc) {
|
if (serverUrl || appLoc) {
|
||||||
@@ -792,7 +828,7 @@ export default class SASjs {
|
|||||||
sasApiClient = new SAS9ApiClient(
|
sasApiClient = new SAS9ApiClient(
|
||||||
serverUrl,
|
serverUrl,
|
||||||
this.jobsPath,
|
this.jobsPath,
|
||||||
this.sasjsConfig.allowInsecureRequests
|
this.sasjsConfig.httpsAgentOptions
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -824,6 +860,14 @@ export default class SASjs {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async deployToSASjs(members: [FolderMember, ServiceMember]) {
|
||||||
|
return await this.sasJSApiClient?.deploy(members, this.sasjsConfig.appLoc)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async executeJobSASjs(query: ExecutionQuery) {
|
||||||
|
return await this.sasJSApiClient?.executeJob(query)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kicks off execution of the given job via the compute API.
|
* Kicks off execution of the given job via the compute API.
|
||||||
* @returns an object representing the compute session created for the given job.
|
* @returns an object representing the compute session created for the given job.
|
||||||
@@ -857,7 +901,7 @@ export default class SASjs {
|
|||||||
...config
|
...config
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isMethodSupported('startComputeJob', ServerType.SasViya)
|
this.isMethodSupported('startComputeJob', [ServerType.SasViya])
|
||||||
if (!config.contextName) {
|
if (!config.contextName) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Context name is undefined. Please set a `contextName` in your SASjs or override config.'
|
'Context name is undefined. Please set a `contextName` in your SASjs or override config.'
|
||||||
@@ -949,21 +993,27 @@ export default class SASjs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this.requestClient) {
|
if (!this.requestClient) {
|
||||||
this.requestClient = new RequestClient(
|
const RequestClientClass =
|
||||||
|
this.sasjsConfig.serverType === ServerType.Sasjs
|
||||||
|
? SasjsRequestClient
|
||||||
|
: RequestClient
|
||||||
|
this.requestClient = new RequestClientClass(
|
||||||
this.sasjsConfig.serverUrl,
|
this.sasjsConfig.serverUrl,
|
||||||
this.sasjsConfig.allowInsecureRequests
|
this.sasjsConfig.httpsAgentOptions
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
this.requestClient.setConfig(
|
this.requestClient.setConfig(
|
||||||
this.sasjsConfig.serverUrl,
|
this.sasjsConfig.serverUrl,
|
||||||
this.sasjsConfig.allowInsecureRequests
|
this.sasjsConfig.httpsAgentOptions
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.jobsPath =
|
this.jobsPath =
|
||||||
this.sasjsConfig.serverType === ServerType.SasViya
|
this.sasjsConfig.serverType === ServerType.SasViya
|
||||||
? this.sasjsConfig.pathSASViya
|
? this.sasjsConfig.pathSASViya
|
||||||
: this.sasjsConfig.pathSAS9
|
: this.sasjsConfig.serverType === ServerType.Sas9
|
||||||
|
? this.sasjsConfig.pathSAS9
|
||||||
|
: this.sasjsConfig.pathSASJS || ''
|
||||||
|
|
||||||
this.authManager = new AuthManager(
|
this.authManager = new AuthManager(
|
||||||
this.sasjsConfig.serverUrl,
|
this.sasjsConfig.serverUrl,
|
||||||
@@ -973,30 +1023,44 @@ export default class SASjs {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (this.sasjsConfig.serverType === ServerType.SasViya) {
|
if (this.sasjsConfig.serverType === ServerType.SasViya) {
|
||||||
if (this.sasViyaApiClient)
|
if (this.sasViyaApiClient) {
|
||||||
this.sasViyaApiClient!.setConfig(
|
this.sasViyaApiClient!.setConfig(
|
||||||
this.sasjsConfig.serverUrl,
|
this.sasjsConfig.serverUrl,
|
||||||
this.sasjsConfig.appLoc
|
this.sasjsConfig.appLoc
|
||||||
)
|
)
|
||||||
else
|
} else {
|
||||||
this.sasViyaApiClient = new SASViyaApiClient(
|
this.sasViyaApiClient = new SASViyaApiClient(
|
||||||
this.sasjsConfig.serverUrl,
|
this.sasjsConfig.serverUrl,
|
||||||
this.sasjsConfig.appLoc,
|
this.sasjsConfig.appLoc,
|
||||||
this.sasjsConfig.contextName,
|
this.sasjsConfig.contextName,
|
||||||
this.requestClient
|
this.requestClient
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
this.sasViyaApiClient.debug = this.sasjsConfig.debug
|
this.sasViyaApiClient.debug = this.sasjsConfig.debug
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.sasjsConfig.serverType === ServerType.Sas9) {
|
if (this.sasjsConfig.serverType === ServerType.Sas9) {
|
||||||
if (this.sas9ApiClient)
|
if (this.sas9ApiClient) {
|
||||||
this.sas9ApiClient!.setConfig(this.sasjsConfig.serverUrl)
|
this.sas9ApiClient!.setConfig(this.sasjsConfig.serverUrl)
|
||||||
else
|
} else {
|
||||||
this.sas9ApiClient = new SAS9ApiClient(
|
this.sas9ApiClient = new SAS9ApiClient(
|
||||||
this.sasjsConfig.serverUrl,
|
this.sasjsConfig.serverUrl,
|
||||||
this.jobsPath,
|
this.jobsPath,
|
||||||
this.sasjsConfig.allowInsecureRequests
|
this.sasjsConfig.httpsAgentOptions
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.sasjsConfig.serverType === ServerType.Sasjs) {
|
||||||
|
if (this.sasJSApiClient) {
|
||||||
|
this.sasJSApiClient.setConfig(this.sasjsConfig.serverUrl)
|
||||||
|
} else {
|
||||||
|
this.sasJSApiClient = new SASjsApiClient(
|
||||||
|
this.sasjsConfig.serverUrl,
|
||||||
|
this.requestClient
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fileUploader = new FileUploader(
|
this.fileUploader = new FileUploader(
|
||||||
@@ -1018,7 +1082,8 @@ export default class SASjs {
|
|||||||
this.sasjsConfig.serverUrl,
|
this.sasjsConfig.serverUrl,
|
||||||
this.sasjsConfig.serverType!,
|
this.sasjsConfig.serverType!,
|
||||||
this.jobsPath,
|
this.jobsPath,
|
||||||
this.sasjsConfig.allowInsecureRequests
|
this.requestClient,
|
||||||
|
this.sasjsConfig.httpsAgentOptions
|
||||||
)
|
)
|
||||||
|
|
||||||
this.computeJobExecutor = new ComputeJobExecutor(
|
this.computeJobExecutor = new ComputeJobExecutor(
|
||||||
@@ -1085,12 +1150,15 @@ export default class SASjs {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private isMethodSupported(method: string, serverType: string) {
|
private isMethodSupported(method: string, serverTypes: ServerType[]) {
|
||||||
if (this.sasjsConfig.serverType !== serverType) {
|
if (
|
||||||
|
!this.sasjsConfig.serverType ||
|
||||||
|
!serverTypes.includes(this.sasjsConfig.serverType)
|
||||||
|
) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Method '${method}' is only supported on ${
|
`Method '${method}' is only supported on ${serverTypes.join(
|
||||||
serverType === ServerType.Sas9 ? 'SAS9' : 'SAS Viya'
|
', '
|
||||||
} servers.`
|
)} servers.`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
82
src/SASjsApiClient.ts
Normal file
82
src/SASjsApiClient.ts
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import { FolderMember, ServiceMember, ExecutionQuery } from './types'
|
||||||
|
import { RequestClient } from './request/RequestClient'
|
||||||
|
import { getAccessTokenForSasjs } from './auth/getAccessTokenForSasjs'
|
||||||
|
import { refreshTokensForSasjs } from './auth/refreshTokensForSasjs'
|
||||||
|
import { getAuthCodeForSasjs } from './auth/getAuthCodeForSasjs'
|
||||||
|
|
||||||
|
export class SASjsApiClient {
|
||||||
|
constructor(
|
||||||
|
private serverUrl: string,
|
||||||
|
private requestClient: RequestClient
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public setConfig(serverUrl: string) {
|
||||||
|
if (serverUrl) this.serverUrl = serverUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
public async deploy(members: [FolderMember, ServiceMember], appLoc: string) {
|
||||||
|
const { result } = await this.requestClient.post<{
|
||||||
|
status: string
|
||||||
|
message: string
|
||||||
|
example?: {}
|
||||||
|
}>(
|
||||||
|
'SASjsApi/drive/deploy',
|
||||||
|
{ fileTree: members, appLoc: appLoc },
|
||||||
|
undefined
|
||||||
|
)
|
||||||
|
|
||||||
|
return Promise.resolve(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async executeJob(query: ExecutionQuery) {
|
||||||
|
const { result } = await this.requestClient.post<{
|
||||||
|
status: string
|
||||||
|
message: string
|
||||||
|
log?: string
|
||||||
|
logPath?: string
|
||||||
|
error?: {}
|
||||||
|
}>('SASjsApi/stp/execute', query, undefined)
|
||||||
|
|
||||||
|
return Promise.resolve(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exchanges the auth code for an access token for the given client.
|
||||||
|
* @param clientId - the client ID to authenticate with.
|
||||||
|
* @param authCode - the auth code received from the server.
|
||||||
|
*/
|
||||||
|
public async getAccessToken(
|
||||||
|
clientId: string,
|
||||||
|
authCode: string
|
||||||
|
): Promise<SASjsAuthResponse> {
|
||||||
|
return getAccessTokenForSasjs(this.requestClient, clientId, authCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exchanges the refresh token for an access token.
|
||||||
|
* @param refreshToken - the refresh token received from the server.
|
||||||
|
*/
|
||||||
|
public async refreshTokens(refreshToken: string): Promise<SASjsAuthResponse> {
|
||||||
|
return refreshTokensForSasjs(this.requestClient, refreshToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a login authenticate and returns an auth code for the given client.
|
||||||
|
* @param username - a string representing the username.
|
||||||
|
* @param password - a string representing the password.
|
||||||
|
* @param clientId - the client ID to authenticate with.
|
||||||
|
*/
|
||||||
|
public async getAuthCode(
|
||||||
|
username: string,
|
||||||
|
password: string,
|
||||||
|
clientId: string
|
||||||
|
) {
|
||||||
|
return getAuthCodeForSasjs(this.requestClient, username, password, clientId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo move to sasjs/utils
|
||||||
|
export interface SASjsAuthResponse {
|
||||||
|
access_token: string
|
||||||
|
refresh_token: string
|
||||||
|
}
|
||||||
@@ -168,7 +168,7 @@ export class SessionManager {
|
|||||||
) {
|
) {
|
||||||
if (stateLink) {
|
if (stateLink) {
|
||||||
if (this.debug && !this.printedSessionState.printed) {
|
if (this.debug && !this.printedSessionState.printed) {
|
||||||
logger.info('Polling session status...')
|
logger.info(`Polling: ${this.serverUrl + stateLink.href}`)
|
||||||
|
|
||||||
this.printedSessionState.printed = true
|
this.printedSessionState.printed = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -206,10 +206,11 @@ const doPoll = async (
|
|||||||
|
|
||||||
pollCount++
|
pollCount++
|
||||||
|
|
||||||
|
const jobHref = postedJob.links.find((l: Link) => l.rel === 'self')!.href
|
||||||
|
|
||||||
if (pollOptions?.streamLog) {
|
if (pollOptions?.streamLog) {
|
||||||
const jobUrl = postedJob.links.find((l: Link) => l.rel === 'self')
|
|
||||||
const { result: job } = await requestClient.get<Job>(
|
const { result: job } = await requestClient.get<Job>(
|
||||||
jobUrl!.href,
|
jobHref,
|
||||||
authConfig?.access_token
|
authConfig?.access_token
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -231,7 +232,7 @@ const doPoll = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (debug && printedState !== state) {
|
if (debug && printedState !== state) {
|
||||||
logger.info('Polling job status...')
|
logger.info(`Polling: ${requestClient.getBaseUrl() + jobHref}/state`)
|
||||||
logger.info(`Current job state: ${state}`)
|
logger.info(`Current job state: ${state}`)
|
||||||
|
|
||||||
printedState = state
|
printedState = state
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ import * as isNodeModule from '../../../utils/isNode'
|
|||||||
import { PollOptions } from '../../../types'
|
import { PollOptions } from '../../../types'
|
||||||
import { WriteStream } from 'fs'
|
import { WriteStream } from 'fs'
|
||||||
|
|
||||||
|
const baseUrl = 'http://localhost'
|
||||||
const requestClient = new (<jest.Mock<RequestClient>>RequestClient)()
|
const requestClient = new (<jest.Mock<RequestClient>>RequestClient)()
|
||||||
|
requestClient['httpClient'].defaults.baseURL = baseUrl
|
||||||
|
|
||||||
const defaultPollOptions: PollOptions = {
|
const defaultPollOptions: PollOptions = {
|
||||||
maxPollCount: 100,
|
maxPollCount: 100,
|
||||||
pollInterval: 500,
|
pollInterval: 500,
|
||||||
@@ -195,7 +198,7 @@ describe('pollJobState', () => {
|
|||||||
expect((process as any).logger.info).toHaveBeenCalledTimes(4)
|
expect((process as any).logger.info).toHaveBeenCalledTimes(4)
|
||||||
expect((process as any).logger.info).toHaveBeenNthCalledWith(
|
expect((process as any).logger.info).toHaveBeenNthCalledWith(
|
||||||
1,
|
1,
|
||||||
'Polling job status...'
|
`Polling: ${baseUrl}/job/state`
|
||||||
)
|
)
|
||||||
expect((process as any).logger.info).toHaveBeenNthCalledWith(
|
expect((process as any).logger.info).toHaveBeenNthCalledWith(
|
||||||
2,
|
2,
|
||||||
@@ -203,7 +206,7 @@ describe('pollJobState', () => {
|
|||||||
)
|
)
|
||||||
expect((process as any).logger.info).toHaveBeenNthCalledWith(
|
expect((process as any).logger.info).toHaveBeenNthCalledWith(
|
||||||
3,
|
3,
|
||||||
'Polling job status...'
|
`Polling: ${baseUrl}/job/state`
|
||||||
)
|
)
|
||||||
expect((process as any).logger.info).toHaveBeenNthCalledWith(
|
expect((process as any).logger.info).toHaveBeenNthCalledWith(
|
||||||
4,
|
4,
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { ServerType } from '@sasjs/utils/types'
|
|||||||
import { RequestClient } from '../request/RequestClient'
|
import { RequestClient } from '../request/RequestClient'
|
||||||
import { LoginOptions, LoginResult } from '../types/Login'
|
import { LoginOptions, LoginResult } from '../types/Login'
|
||||||
import { serialize } from '../utils'
|
import { serialize } from '../utils'
|
||||||
|
import { getAccessTokenForSasjs } from './getAccessTokenForSasjs'
|
||||||
|
import { getAuthCodeForSasjs } from './getAuthCodeForSasjs'
|
||||||
import { openWebPage } from './openWebPage'
|
import { openWebPage } from './openWebPage'
|
||||||
import { verifySas9Login } from './verifySas9Login'
|
import { verifySas9Login } from './verifySas9Login'
|
||||||
import { verifySasViyaLogin } from './verifySasViyaLogin'
|
import { verifySasViyaLogin } from './verifySasViyaLogin'
|
||||||
@@ -21,7 +23,9 @@ export class AuthManager {
|
|||||||
this.logoutUrl =
|
this.logoutUrl =
|
||||||
this.serverType === ServerType.Sas9
|
this.serverType === ServerType.Sas9
|
||||||
? '/SASLogon/logout?'
|
? '/SASLogon/logout?'
|
||||||
: '/SASLogon/logout.do?'
|
: this.serverType === ServerType.SasViya
|
||||||
|
? '/SASLogon/logout.do?'
|
||||||
|
: '/SASjsApi/auth/logout'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,6 +83,39 @@ export class AuthManager {
|
|||||||
return { isLoggedIn: false, userName: '' }
|
return { isLoggedIn: false, userName: '' }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs into the SAS server with the supplied credentials.
|
||||||
|
* @param userName - a string representing the username.
|
||||||
|
* @param password - a string representing the password.
|
||||||
|
* @param clientId - a string representing the client ID.
|
||||||
|
* @returns - a boolean `isLoggedin` and a string `username`
|
||||||
|
*/
|
||||||
|
public async logInSasjs(
|
||||||
|
username: string,
|
||||||
|
password: string,
|
||||||
|
clientId: string
|
||||||
|
): Promise<LoginResult> {
|
||||||
|
const isLoggedIn = await this.sendLoginRequestSasjs(
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
clientId
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
this.userName = username
|
||||||
|
this.requestClient.saveLocalStorageToken(
|
||||||
|
res.access_token,
|
||||||
|
res.refresh_token
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
.catch(() => false)
|
||||||
|
|
||||||
|
return {
|
||||||
|
isLoggedIn,
|
||||||
|
userName: this.userName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs into the SAS server with the supplied credentials.
|
* Logs into the SAS server with the supplied credentials.
|
||||||
* @param username - a string representing the username.
|
* @param username - a string representing the username.
|
||||||
@@ -178,6 +215,19 @@ export class AuthManager {
|
|||||||
return loginResponse
|
return loginResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async sendLoginRequestSasjs(
|
||||||
|
username: string,
|
||||||
|
password: string,
|
||||||
|
clientId: string
|
||||||
|
) {
|
||||||
|
const authCode = await getAuthCodeForSasjs(
|
||||||
|
this.requestClient,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
clientId
|
||||||
|
)
|
||||||
|
return getAccessTokenForSasjs(this.requestClient, clientId, authCode)
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Checks whether a session is active, or login is required.
|
* Checks whether a session is active, or login is required.
|
||||||
* @returns - a promise which resolves with an object containing three values
|
* @returns - a promise which resolves with an object containing three values
|
||||||
@@ -198,7 +248,8 @@ export class AuthManager {
|
|||||||
//Residue can happen in case of session expiration
|
//Residue can happen in case of session expiration
|
||||||
await this.logOut()
|
await this.logOut()
|
||||||
|
|
||||||
loginForm = await this.getNewLoginForm()
|
if (this.serverType !== ServerType.Sasjs)
|
||||||
|
loginForm = await this.getNewLoginForm()
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
@@ -222,12 +273,12 @@ export class AuthManager {
|
|||||||
isLoggedIn: boolean
|
isLoggedIn: boolean
|
||||||
userName: string
|
userName: string
|
||||||
}> {
|
}> {
|
||||||
//For VIYA we will send request on API endpoint. Which is faster then pinging SASJobExecution.
|
|
||||||
//For SAS9 we will send request on SASStoredProcess
|
|
||||||
const url =
|
const url =
|
||||||
this.serverType === ServerType.SasViya
|
this.serverType === ServerType.SasViya
|
||||||
? `${this.serverUrl}/identities/users/@currentUser`
|
? `${this.serverUrl}/identities/users/@currentUser`
|
||||||
: `${this.serverUrl}/SASStoredProcess`
|
: this.serverType === ServerType.Sas9
|
||||||
|
? `${this.serverUrl}/SASStoredProcess`
|
||||||
|
: `${this.serverUrl}/SASjsApi/session`
|
||||||
|
|
||||||
const { result: loginResponse } = await this.requestClient
|
const { result: loginResponse } = await this.requestClient
|
||||||
.get<string>(url, undefined, 'text/plain')
|
.get<string>(url, undefined, 'text/plain')
|
||||||
@@ -256,6 +307,13 @@ export class AuthManager {
|
|||||||
.split(' ')
|
.split(' ')
|
||||||
.map((name: string) => name.slice(0, 3).toLowerCase())
|
.map((name: string) => name.slice(0, 3).toLowerCase())
|
||||||
.join('')
|
.join('')
|
||||||
|
|
||||||
|
case ServerType.Sasjs:
|
||||||
|
return response?.username
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.error('Server Type not found in extractUserName function')
|
||||||
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,9 +360,21 @@ export class AuthManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs out of the configured SAS server.
|
* Logs out of the configured SAS server.
|
||||||
|
* @param accessToken - an optional access token is required for SASjs server type.
|
||||||
*/
|
*/
|
||||||
public logOut() {
|
public async logOut() {
|
||||||
|
if (this.serverType === ServerType.Sasjs) {
|
||||||
|
return this.requestClient
|
||||||
|
.delete(this.logoutUrl)
|
||||||
|
.catch(() => true)
|
||||||
|
.finally(() => {
|
||||||
|
this.requestClient.clearLocalStorageTokens()
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
this.requestClient.clearCsrfTokens()
|
this.requestClient.clearCsrfTokens()
|
||||||
|
|
||||||
return this.requestClient.get(this.logoutUrl, undefined).then(() => true)
|
return this.requestClient.get(this.logoutUrl, undefined).then(() => true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
36
src/auth/getAccessTokenForSasjs.ts
Normal file
36
src/auth/getAccessTokenForSasjs.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { prefixMessage } from '@sasjs/utils/error'
|
||||||
|
import { RequestClient } from '../request/RequestClient'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exchanges the auth code for an access token for the given client.
|
||||||
|
* @param requestClient - the pre-configured HTTP request client
|
||||||
|
* @param clientId - the client ID to authenticate with.
|
||||||
|
* @param authCode - the auth code received from the server.
|
||||||
|
*/
|
||||||
|
export async function getAccessTokenForSasjs(
|
||||||
|
requestClient: RequestClient,
|
||||||
|
clientId: string,
|
||||||
|
authCode: string
|
||||||
|
) {
|
||||||
|
const url = '/SASjsApi/auth/token'
|
||||||
|
const data = {
|
||||||
|
clientId,
|
||||||
|
code: authCode
|
||||||
|
}
|
||||||
|
|
||||||
|
return await requestClient
|
||||||
|
.post(url, data, undefined)
|
||||||
|
.then((res) => {
|
||||||
|
const sasAuth = res.result as {
|
||||||
|
accessToken: string
|
||||||
|
refreshToken: string
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
access_token: sasAuth.accessToken,
|
||||||
|
refresh_token: sasAuth.refreshToken
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
throw prefixMessage(err, 'Error while getting access token. ')
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ import { RequestClient } from '../request/RequestClient'
|
|||||||
* @param clientSecret - the client secret to authenticate with.
|
* @param clientSecret - the client secret to authenticate with.
|
||||||
* @param authCode - the auth code received from the server.
|
* @param authCode - the auth code received from the server.
|
||||||
*/
|
*/
|
||||||
export async function getAccessToken(
|
export async function getAccessTokenForViya(
|
||||||
requestClient: RequestClient,
|
requestClient: RequestClient,
|
||||||
clientId: string,
|
clientId: string,
|
||||||
clientSecret: string,
|
clientSecret: string,
|
||||||
@@ -46,7 +46,7 @@ export async function getAccessToken(
|
|||||||
)
|
)
|
||||||
.then((res) => res.result as SasAuthResponse)
|
.then((res) => res.result as SasAuthResponse)
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
throw prefixMessage(err, 'Error while getting access token')
|
throw prefixMessage(err, 'Error while getting access token. ')
|
||||||
})
|
})
|
||||||
|
|
||||||
return authResponse
|
return authResponse
|
||||||
31
src/auth/getAuthCodeForSasjs.ts
Normal file
31
src/auth/getAuthCodeForSasjs.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { prefixMessage } from '@sasjs/utils/error'
|
||||||
|
import { RequestClient } from '../request/RequestClient'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a login authenticate and returns an auth code for the given client.
|
||||||
|
* @param requestClient - the pre-configured HTTP request client
|
||||||
|
* @param username - a string representing the username.
|
||||||
|
* @param password - a string representing the password.
|
||||||
|
* @param clientId - the client ID to authenticate with.
|
||||||
|
*/
|
||||||
|
export const getAuthCodeForSasjs = async (
|
||||||
|
requestClient: RequestClient,
|
||||||
|
username: string,
|
||||||
|
password: string,
|
||||||
|
clientId: string
|
||||||
|
) => {
|
||||||
|
const url = '/SASjsApi/auth/authorize'
|
||||||
|
const data = { username, password, clientId }
|
||||||
|
|
||||||
|
const { code: authCode } = await requestClient
|
||||||
|
.post<{ code: string }>(url, data, undefined)
|
||||||
|
.then((res) => res.result)
|
||||||
|
.catch((err) => {
|
||||||
|
throw prefixMessage(
|
||||||
|
err,
|
||||||
|
'Error while authenticating with provided username, password and clientId. '
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
return authCode
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user