mirror of
https://github.com/sasjs/adapter.git
synced 2025-12-11 09:24:35 +00:00
Merge pull request #19 from sasjs/issue17
File upload function and separate WEB and API csrf tokens
This commit is contained in:
2
.github/workflows/npmpublish.yml
vendored
2
.github/workflows/npmpublish.yml
vendored
@@ -6,7 +6,7 @@ name: SASjs Build and Publish
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
@@ -16,7 +16,7 @@ Tests are run using cypress. Before running tests, you need to define the follow
|
||||
|
||||
```
|
||||
|
||||
filename mc url "https://raw.githubusercontent.com/macropeople/macrocore/main/mc_all.sas?_=1";
|
||||
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
||||
%inc mc;
|
||||
filename ft15f001 temp;
|
||||
parmcards4;
|
||||
@@ -40,18 +40,13 @@ parmcards4;
|
||||
# Viya
|
||||
|
||||
```
|
||||
filename mc url "https://raw.githubusercontent.com/macropeople/macrocore/main/mc_all.sas";
|
||||
filename mc url "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
||||
%inc mc;
|
||||
|
||||
filename ft15f001 temp;
|
||||
parmcards4;
|
||||
%webout(FETCH)
|
||||
%webout(OPEN)
|
||||
%global sasjs_tables;
|
||||
%let sasjs_tables=&sasjs_tables;
|
||||
%put &=sasjs_tables;
|
||||
%let sasjs_tables=&sasjs_tables;
|
||||
%macro x();
|
||||
%global sasjs_tables;
|
||||
%do i=1 %to %sysfunc(countw(&sasjs_tables));
|
||||
%let table=%scan(&sasjs_tables,&i);
|
||||
%webout(OBJ,&table)
|
||||
@@ -60,13 +55,11 @@ parmcards4;
|
||||
%x()
|
||||
%webout(CLOSE)
|
||||
;;;;
|
||||
%mv_createwebservice(path=/Public/app/common,name=sendObj)
|
||||
%mp_createwebservice(path=/Public/app/common,name=sendObj)
|
||||
filename ft15f001 temp;
|
||||
parmcards4;
|
||||
%webout(FETCH)
|
||||
%webout(OPEN)
|
||||
%global sasjs_tables;
|
||||
%let sasjs_tables=&sasjs_tables;
|
||||
%put &=sasjs_tables;
|
||||
%macro x();
|
||||
%do i=1 %to %sysfunc(countw(&sasjs_tables));
|
||||
%let table=%scan(&sasjs_tables,&i);
|
||||
@@ -76,7 +69,7 @@ parmcards4;
|
||||
%x()
|
||||
%webout(CLOSE)
|
||||
;;;;
|
||||
%mv_createwebservice(path=/Public/app/common,name=sendArr)
|
||||
%mp_createwebservice(path=/Public/app/common,name=sendArr)
|
||||
```
|
||||
|
||||
The above services will return anything you send. To run the tests simply launch `npm run cypress`.
|
||||
|
||||
@@ -10,13 +10,13 @@ SASjs is a open-source framework for building Web Apps on SAS® platforms. You c
|
||||
|
||||
3 - Reference directly from the CDN - in which case click [here](https://www.jsdelivr.com/package/npm/@sasjs/adapter?tab=collection) and select "SRI" to get the script tag with the integrity hash.
|
||||
|
||||
If you are short on time and just need to build an app quickly, then check out [this video](https://vimeo.com/393161794) and the [react-seed-app](https://github.com/macropeople/react-seed-app) which provides some boilerplate.
|
||||
If you are short on time and just need to build an app quickly, then check out [this video](https://vimeo.com/393161794) and the [react-seed-app](https://github.com/sasjs/react-seed-app) which provides some boilerplate.
|
||||
|
||||
For more information on building web apps with SAS, check out [sasjs.io](https://sasjs.io)
|
||||
|
||||
## None of this makes sense. How do I build an app with it?
|
||||
|
||||
Ok ok. Deploy this [example.html](https://github.com/sasjs/adapter/blob/main/example.html) file to your web server, and update `servertype` to `SAS9` or `SASVIYA` depending on your backend.
|
||||
Ok ok. Deploy this [example.html](https://raw.githubusercontent.com/sasjs/adapter/master/example.html) file to your web server, and update `servertype` to `SAS9` or `SASVIYA` depending on your backend.
|
||||
|
||||
The backend part can be deployed as follows:
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
294
docs/classes/reflection-588.reflection-1.sas9apiclient.html
Normal file
294
docs/classes/reflection-588.reflection-1.sas9apiclient.html
Normal file
File diff suppressed because one or more lines are too long
1017
docs/classes/reflection-588.reflection-1.sasjs.html
Normal file
1017
docs/classes/reflection-588.reflection-1.sasjs.html
Normal file
File diff suppressed because one or more lines are too long
913
docs/classes/reflection-588.reflection-1.sasviyaapiclient.html
Normal file
913
docs/classes/reflection-588.reflection-1.sasviyaapiclient.html
Normal file
File diff suppressed because one or more lines are too long
227
docs/classes/reflection-588.reflection-1.sessionmanager.html
Normal file
227
docs/classes/reflection-588.reflection-1.sessionmanager.html
Normal file
File diff suppressed because one or more lines are too long
224
docs/classes/reflection-607.reflection-145.fileuploader.html
Normal file
224
docs/classes/reflection-607.reflection-145.fileuploader.html
Normal file
File diff suppressed because one or more lines are too long
297
docs/classes/reflection-607.reflection-145.sas9apiclient.html
Normal file
297
docs/classes/reflection-607.reflection-145.sas9apiclient.html
Normal file
File diff suppressed because one or more lines are too long
1021
docs/classes/reflection-607.reflection-145.sasjs.html
Normal file
1021
docs/classes/reflection-607.reflection-145.sasjs.html
Normal file
File diff suppressed because one or more lines are too long
916
docs/classes/reflection-607.reflection-145.sasviyaapiclient.html
Normal file
916
docs/classes/reflection-607.reflection-145.sasviyaapiclient.html
Normal file
File diff suppressed because one or more lines are too long
230
docs/classes/reflection-607.reflection-145.sessionmanager.html
Normal file
230
docs/classes/reflection-607.reflection-145.sessionmanager.html
Normal file
File diff suppressed because one or more lines are too long
221
docs/classes/reflection-610.reflection-149.fileuploader.html
Normal file
221
docs/classes/reflection-610.reflection-149.fileuploader.html
Normal file
File diff suppressed because one or more lines are too long
297
docs/classes/reflection-610.reflection-149.sas9apiclient.html
Normal file
297
docs/classes/reflection-610.reflection-149.sas9apiclient.html
Normal file
File diff suppressed because one or more lines are too long
1015
docs/classes/reflection-610.reflection-149.sasjs.html
Normal file
1015
docs/classes/reflection-610.reflection-149.sasjs.html
Normal file
File diff suppressed because one or more lines are too long
916
docs/classes/reflection-610.reflection-149.sasviyaapiclient.html
Normal file
916
docs/classes/reflection-610.reflection-149.sasviyaapiclient.html
Normal file
File diff suppressed because one or more lines are too long
230
docs/classes/reflection-610.reflection-149.sessionmanager.html
Normal file
230
docs/classes/reflection-610.reflection-149.sessionmanager.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
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
198
docs/interfaces/types.uploadfile.html
Normal file
198
docs/interfaces/types.uploadfile.html
Normal file
File diff suppressed because one or more lines are too long
107
docs/modules/reflection-588.html
Normal file
107
docs/modules/reflection-588.html
Normal file
File diff suppressed because one or more lines are too long
125
docs/modules/reflection-588.reflection-1.html
Normal file
125
docs/modules/reflection-588.reflection-1.html
Normal file
File diff suppressed because one or more lines are too long
107
docs/modules/reflection-607.html
Normal file
107
docs/modules/reflection-607.html
Normal file
File diff suppressed because one or more lines are too long
129
docs/modules/reflection-607.reflection-145.html
Normal file
129
docs/modules/reflection-607.reflection-145.html
Normal file
File diff suppressed because one or more lines are too long
107
docs/modules/reflection-610.html
Normal file
107
docs/modules/reflection-610.html
Normal file
File diff suppressed because one or more lines are too long
129
docs/modules/reflection-610.reflection-149.html
Normal file
129
docs/modules/reflection-610.reflection-149.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
12
example.html
12
example.html
@@ -1,12 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
|
||||
<script src="https://cdn.jsdelivr.net/combine/npm/chart.js@2.9.3,npm/jquery@3.5.1,npm/@sasjs/adapter@1"></script>
|
||||
<script src="https://cdn.jsdelivr.net/combine/npm/chart.js@2.9.3,npm/jquery@3.5.1,npm/@sasjs/adapter@1.0.6"></script>
|
||||
<script>
|
||||
var sasJs = new SASjs.default({appLoc: "/Products/demo/readme"
|
||||
,serverType:"SAS9", debug: "false"
|
||||
var sasJs = new SASjs.default({
|
||||
appLoc: "/Public/app/readme"
|
||||
,serverType:"SAS9"
|
||||
,debug: false
|
||||
});
|
||||
function initSasJs() {
|
||||
$('#loading-spinner').show()
|
||||
@@ -70,6 +70,8 @@
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<meta charset="utf-8" http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fluid" style="text-align: center; margin-top: 10px;">
|
||||
|
||||
18
package-lock.json
generated
18
package-lock.json
generated
@@ -1648,9 +1648,9 @@
|
||||
}
|
||||
},
|
||||
"@types/jest": {
|
||||
"version": "26.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.4.tgz",
|
||||
"integrity": "sha512-4fQNItvelbNA9+sFgU+fhJo8ZFF+AS4Egk3GWwCW2jFtViukXbnztccafAdLhzE/0EiCogljtQQXP8aQ9J7sFg==",
|
||||
"version": "26.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.5.tgz",
|
||||
"integrity": "sha512-heU+7w8snfwfjtcj2H458aTx3m5unIToOJhx75ebHilBiiQ39OIdA18WkG4LP08YKeAoWAGvWg8s+22w/PeJ6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jest-diff": "^25.2.1",
|
||||
@@ -14874,9 +14874,9 @@
|
||||
}
|
||||
},
|
||||
"ts-loader": {
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz",
|
||||
"integrity": "sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig==",
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.1.tgz",
|
||||
"integrity": "sha512-I9Nmly0ufJoZRMuAT9d5ijsC2B7oSPvUnOJt/GhgoATlPGYfa17VicDKPcqwUCrHpOkCxr/ybLYwbnS4cOxmvQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^2.3.0",
|
||||
@@ -15073,9 +15073,9 @@
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "3.9.6",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.6.tgz",
|
||||
"integrity": "sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw==",
|
||||
"version": "3.9.7",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz",
|
||||
"integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==",
|
||||
"dev": true
|
||||
},
|
||||
"uglify-js": {
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
{
|
||||
"pkgRoot": "/build"
|
||||
}
|
||||
],
|
||||
"branches": [
|
||||
"main"
|
||||
]
|
||||
},
|
||||
"keywords": [
|
||||
@@ -40,7 +37,7 @@
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@types/isomorphic-fetch": "0.0.35",
|
||||
"@types/jest": "^26.0.4",
|
||||
"@types/jest": "^26.0.5",
|
||||
"cp": "^0.2.0",
|
||||
"jest": "^25.5.4",
|
||||
"path": "^0.12.7",
|
||||
@@ -48,13 +45,13 @@
|
||||
"rimraf": "^3.0.2",
|
||||
"semantic-release": "^17.1.1",
|
||||
"ts-jest": "^25.5.1",
|
||||
"ts-loader": "^7.0.5",
|
||||
"ts-loader": "^8.0.1",
|
||||
"tslint": "^6.1.2",
|
||||
"tslint-config-prettier": "^1.18.0",
|
||||
"typedoc": "^0.17.8",
|
||||
"typedoc-neo-theme": "^1.0.9",
|
||||
"typedoc-plugin-external-module-name": "^4.0.3",
|
||||
"typescript": "^3.9.6",
|
||||
"typescript": "^3.9.7",
|
||||
"uglifyjs-webpack-plugin": "^2.2.0",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
|
||||
97
src/FileUploader.ts
Normal file
97
src/FileUploader.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { isLogInRequired, needsRetry } from "./utils";
|
||||
import { CsrfToken } from "./types/CsrfToken";
|
||||
import { UploadFile } from "./types/UploadFile";
|
||||
|
||||
const requestRetryLimit = 5;
|
||||
|
||||
export class FileUploader {
|
||||
constructor(
|
||||
private appLoc: string,
|
||||
private serverUrl: string,
|
||||
private jobsPath: string,
|
||||
private csrfToken: CsrfToken | null = null
|
||||
) {}
|
||||
private retryCount = 0;
|
||||
|
||||
public uploadFile(sasJob: string, files: UploadFile[], params: any) {
|
||||
if (files?.length < 1) throw new Error("Atleast one file must be provided");
|
||||
|
||||
let paramsString = "";
|
||||
|
||||
for (let param in params) {
|
||||
if (params.hasOwnProperty(param)) {
|
||||
paramsString += `&${param}=${params[param]}`;
|
||||
}
|
||||
}
|
||||
|
||||
const program = this.appLoc
|
||||
? this.appLoc.replace(/\/?$/, "/") + sasJob.replace(/^\//, "")
|
||||
: sasJob;
|
||||
const uploadUrl = `${this.serverUrl}${this.jobsPath}/?${
|
||||
"_program=" + program
|
||||
}${paramsString}`;
|
||||
|
||||
const headers = {
|
||||
"cache-control": "no-cache",
|
||||
};
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const formData = new FormData();
|
||||
|
||||
for (let file of files) {
|
||||
formData.append("file", file.file, file.fileName);
|
||||
}
|
||||
|
||||
if (this.csrfToken) formData.append("_csrf", this.csrfToken.value);
|
||||
|
||||
fetch(uploadUrl, {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
referrerPolicy: "same-origin",
|
||||
headers,
|
||||
})
|
||||
.then(async (response) => {
|
||||
if (!response.ok) {
|
||||
if (response.status === 403) {
|
||||
const tokenHeader = response.headers.get("X-CSRF-HEADER");
|
||||
|
||||
if (tokenHeader) {
|
||||
const token = response.headers.get(tokenHeader);
|
||||
this.csrfToken = {
|
||||
headerName: tokenHeader,
|
||||
value: token || "",
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response.text();
|
||||
})
|
||||
.then((responseText) => {
|
||||
if (isLogInRequired(responseText))
|
||||
reject("You must be logged in to upload a fle");
|
||||
|
||||
if (needsRetry(responseText)) {
|
||||
if (this.retryCount < requestRetryLimit) {
|
||||
this.retryCount++;
|
||||
this.uploadFile(sasJob, files, params).then(
|
||||
(res: any) => resolve(res),
|
||||
(err: any) => reject(err)
|
||||
);
|
||||
} else {
|
||||
this.retryCount = 0;
|
||||
reject(responseText);
|
||||
}
|
||||
} else {
|
||||
this.retryCount = 0;
|
||||
|
||||
try {
|
||||
resolve(JSON.parse(responseText));
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
122
src/SASjs.ts
122
src/SASjs.ts
@@ -21,9 +21,11 @@ import {
|
||||
SASjsWaitingRequest,
|
||||
ServerType,
|
||||
CsrfToken,
|
||||
UploadFile
|
||||
} from "./types";
|
||||
import { SASViyaApiClient } from "./SASViyaApiClient";
|
||||
import { SAS9ApiClient } from "./SAS9ApiClient";
|
||||
import { FileUploader } from "./FileUploader";
|
||||
|
||||
const defaultConfig: SASjsConfig = {
|
||||
serverUrl: "",
|
||||
@@ -47,8 +49,9 @@ export default class SASjs {
|
||||
private jobsPath: string = "";
|
||||
private logoutUrl: string = "";
|
||||
private loginUrl: string = "";
|
||||
private csrfToken: CsrfToken | null = null;
|
||||
private retryCount: number = 0;
|
||||
private csrfTokenApi: CsrfToken | null = null;
|
||||
private csrfTokenWeb: CsrfToken | null = null;
|
||||
private retryCountWeb: number = 0;
|
||||
private retryCountComputeApi: number = 0;
|
||||
private retryCountJeseApi: number = 0;
|
||||
private sasjsRequests: SASjsRequest[] = [];
|
||||
@@ -56,13 +59,14 @@ export default class SASjs {
|
||||
private userName: string = "";
|
||||
private sasViyaApiClient: SASViyaApiClient | null = null;
|
||||
private sas9ApiClient: SAS9ApiClient | null = null;
|
||||
private fileUploader: FileUploader | null = null;
|
||||
|
||||
constructor(config?: any) {
|
||||
this.sasjsConfig = {
|
||||
...defaultConfig,
|
||||
...config,
|
||||
};
|
||||
|
||||
|
||||
this.setupConfiguration();
|
||||
}
|
||||
|
||||
@@ -237,11 +241,19 @@ export default class SASjs {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the _csrf token of the current session.
|
||||
* Returns the _csrf token of the current session for the API approach
|
||||
*
|
||||
*/
|
||||
public getCsrf() {
|
||||
return this.csrfToken?.value;
|
||||
public getCsrfApi() {
|
||||
return this.csrfTokenApi?.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the _csrf token of the current session for the WEB approach.
|
||||
*
|
||||
*/
|
||||
public getCsrfWeb() {
|
||||
return this.csrfTokenWeb?.value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -365,6 +377,26 @@ export default class SASjs {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads a file to the given service
|
||||
* @param sasJob - The path to the SAS program (ultimately resolves to
|
||||
* the SAS `_program` parameter to run a Job Definition or SAS 9 Stored
|
||||
* Process.) Is prepended at runtime with the value of `appLoc`.
|
||||
* @param file - Array of files to be uploaded, including File object and file name.
|
||||
* @param params - Request URL paramaters
|
||||
*/
|
||||
public uploadFile(sasJob: string, files: UploadFile[], params: any) {
|
||||
const fileUploader =
|
||||
this.fileUploader ||
|
||||
new FileUploader(
|
||||
this.sasjsConfig.appLoc,
|
||||
this.sasjsConfig.serverUrl,
|
||||
this.jobsPath,
|
||||
this.csrfTokenWeb
|
||||
);
|
||||
return fileUploader.uploadFile(sasJob, files, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to the SAS Service specified in `SASjob`. The response
|
||||
* object will always contain table names in lowercase, and column names in
|
||||
@@ -377,7 +409,7 @@ export default class SASjs {
|
||||
* @param data - A JSON object containing one or more tables to be sent to
|
||||
* SAS. Can be `null` if no inputs required.
|
||||
* @param config - Provide any changes to the config here, for instance to
|
||||
* enable / disable `debug`. Any change provided will override the global config,
|
||||
* enable / disable `debug`. Any change provided will override the global config,
|
||||
* for that particular function call.
|
||||
* @param loginRequiredCallback - provide a function here to be called if the
|
||||
* user is not logged in (eg to display a login form). The request will be
|
||||
@@ -394,15 +426,12 @@ export default class SASjs {
|
||||
|
||||
config = {
|
||||
...this.sasjsConfig,
|
||||
...config
|
||||
}
|
||||
...config,
|
||||
};
|
||||
|
||||
sasJob = sasJob.startsWith("/") ? sasJob.replace("/", "") : sasJob;
|
||||
|
||||
if (
|
||||
config.serverType === ServerType.SASViya &&
|
||||
config.contextName
|
||||
) {
|
||||
if (config.serverType === ServerType.SASViya && config.contextName) {
|
||||
if (config.useComputeApi) {
|
||||
requestResponse = await this.executeJobViaComputeApi(
|
||||
sasJob,
|
||||
@@ -470,7 +499,7 @@ export default class SASjs {
|
||||
serverUrl,
|
||||
appLoc,
|
||||
this.sasjsConfig.contextName,
|
||||
this.setCsrfToken
|
||||
this.setCsrfTokenApi
|
||||
);
|
||||
} else if (this.sasjsConfig.serverType === ServerType.SAS9) {
|
||||
sasApiClient = new SAS9ApiClient(serverUrl);
|
||||
@@ -511,7 +540,7 @@ export default class SASjs {
|
||||
reject: null,
|
||||
},
|
||||
SASjob: sasJob,
|
||||
data
|
||||
data,
|
||||
};
|
||||
|
||||
sasjsWaitingRequest.requestPromise.promise = new Promise(
|
||||
@@ -582,7 +611,7 @@ export default class SASjs {
|
||||
reject: null,
|
||||
},
|
||||
SASjob: sasJob,
|
||||
data
|
||||
data,
|
||||
};
|
||||
|
||||
sasjsWaitingRequest.requestPromise.promise = new Promise(
|
||||
@@ -655,23 +684,21 @@ export default class SASjs {
|
||||
reject: null,
|
||||
},
|
||||
SASjob: sasJob,
|
||||
data
|
||||
data,
|
||||
};
|
||||
const program = config.appLoc
|
||||
? config.appLoc.replace(/\/?$/, "/") + sasJob.replace(/^\//, "")
|
||||
: sasJob;
|
||||
const jobUri =
|
||||
config.serverType === "SASVIYA"
|
||||
? await this.getJobUri(sasJob)
|
||||
: "";
|
||||
config.serverType === "SASVIYA" ? await this.getJobUri(sasJob) : "";
|
||||
const apiUrl = `${config.serverUrl}${this.jobsPath}/?${
|
||||
jobUri.length > 0
|
||||
? "__program=" + program + "&_job=" + jobUri
|
||||
: "_program=" + program
|
||||
}`;
|
||||
|
||||
|
||||
const requestParams = {
|
||||
...this.getRequestParams(),
|
||||
...this.getRequestParamsWeb(),
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
@@ -750,8 +777,8 @@ export default class SASjs {
|
||||
reject({ MESSAGE: errorMsg });
|
||||
}
|
||||
const headers: any = {};
|
||||
if (this.csrfToken) {
|
||||
headers[this.csrfToken.headerName] = this.csrfToken.value;
|
||||
if (this.csrfTokenWeb) {
|
||||
headers[this.csrfTokenWeb.headerName] = this.csrfTokenWeb.value;
|
||||
}
|
||||
fetch(apiUrl, {
|
||||
method: "POST",
|
||||
@@ -766,18 +793,15 @@ export default class SASjs {
|
||||
|
||||
if (tokenHeader) {
|
||||
const token = response.headers.get(tokenHeader);
|
||||
this.csrfToken = {
|
||||
this.csrfTokenWeb = {
|
||||
headerName: tokenHeader,
|
||||
value: token || ''
|
||||
}
|
||||
value: token || "",
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
response.redirected &&
|
||||
config.serverType === ServerType.SAS9
|
||||
) {
|
||||
if (response.redirected && config.serverType === ServerType.SAS9) {
|
||||
isRedirected = true;
|
||||
}
|
||||
|
||||
@@ -788,18 +812,18 @@ export default class SASjs {
|
||||
(needsRetry(responseText) || isRedirected) &&
|
||||
!isLogInRequired(responseText)
|
||||
) {
|
||||
if (this.retryCount < requestRetryLimit) {
|
||||
this.retryCount++;
|
||||
if (this.retryCountWeb < requestRetryLimit) {
|
||||
this.retryCountWeb++;
|
||||
this.request(sasJob, data).then(
|
||||
(res: any) => resolve(res),
|
||||
(err: any) => reject(err)
|
||||
);
|
||||
} else {
|
||||
this.retryCount = 0;
|
||||
this.retryCountWeb = 0;
|
||||
reject(responseText);
|
||||
}
|
||||
} else {
|
||||
this.retryCount = 0;
|
||||
this.retryCountWeb = 0;
|
||||
this.parseLogFromResponse(responseText, program);
|
||||
|
||||
if (isLogInRequired(responseText)) {
|
||||
@@ -809,10 +833,7 @@ export default class SASjs {
|
||||
sasjsWaitingRequest.config = config;
|
||||
this.sasjsWaitingRequests.push(sasjsWaitingRequest);
|
||||
} else {
|
||||
if (
|
||||
config.serverType === ServerType.SAS9 &&
|
||||
config.debug
|
||||
) {
|
||||
if (config.serverType === ServerType.SAS9 && config.debug) {
|
||||
this.updateUsername(responseText);
|
||||
const jsonResponseText = this.parseSAS9Response(responseText);
|
||||
|
||||
@@ -865,16 +886,13 @@ export default class SASjs {
|
||||
return sasjsWaitingRequest.requestPromise.promise;
|
||||
}
|
||||
|
||||
private setCsrfToken = (csrfToken: CsrfToken) => {
|
||||
this.csrfToken = csrfToken;
|
||||
private setCsrfTokenApi = (csrfToken: CsrfToken) => {
|
||||
this.csrfTokenApi = csrfToken;
|
||||
};
|
||||
|
||||
private async resendWaitingRequests() {
|
||||
for (const sasjsWaitingRequest of this.sasjsWaitingRequests) {
|
||||
this.request(
|
||||
sasjsWaitingRequest.SASjob,
|
||||
sasjsWaitingRequest.data
|
||||
).then(
|
||||
this.request(sasjsWaitingRequest.SASjob, sasjsWaitingRequest.data).then(
|
||||
(res: any) => {
|
||||
sasjsWaitingRequest.requestPromise.resolve(res);
|
||||
},
|
||||
@@ -887,11 +905,11 @@ export default class SASjs {
|
||||
this.sasjsWaitingRequests = [];
|
||||
}
|
||||
|
||||
private getRequestParams(): any {
|
||||
private getRequestParamsWeb(): any {
|
||||
const requestParams: any = {};
|
||||
|
||||
if (this.csrfToken) {
|
||||
requestParams["_csrf"] = this.csrfToken.value;
|
||||
if (this.csrfTokenWeb) {
|
||||
requestParams["_csrf"] = this.csrfTokenWeb.value;
|
||||
}
|
||||
|
||||
if (this.sasjsConfig.debug) {
|
||||
@@ -1129,7 +1147,7 @@ export default class SASjs {
|
||||
this.sasjsConfig.serverUrl,
|
||||
this.sasjsConfig.appLoc,
|
||||
this.sasjsConfig.contextName,
|
||||
this.setCsrfToken
|
||||
this.setCsrfTokenApi
|
||||
);
|
||||
}
|
||||
if (this.sasjsConfig.serverType === ServerType.SAS9) {
|
||||
@@ -1137,6 +1155,12 @@ export default class SASjs {
|
||||
this.sas9ApiClient!.setConfig(this.sasjsConfig.serverUrl);
|
||||
else this.sas9ApiClient = new SAS9ApiClient(this.sasjsConfig.serverUrl);
|
||||
}
|
||||
|
||||
this.fileUploader = new FileUploader(
|
||||
this.sasjsConfig.appLoc,
|
||||
this.sasjsConfig.serverUrl,
|
||||
this.jobsPath
|
||||
);
|
||||
}
|
||||
|
||||
private setLoginUrl = (matches: RegExpExecArray) => {
|
||||
|
||||
9
src/types/UploadFile.ts
Normal file
9
src/types/UploadFile.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Represents a object that is passed to file uploader
|
||||
*
|
||||
*/
|
||||
export interface UploadFile {
|
||||
file: File;
|
||||
fileName: string;
|
||||
}
|
||||
|
||||
@@ -8,3 +8,4 @@ export * from "./SASjsRequest";
|
||||
export * from "./SASjsWaitingRequest";
|
||||
export * from "./ServerType";
|
||||
export * from "./Session";
|
||||
export * from "./UploadFile";
|
||||
|
||||
Reference in New Issue
Block a user