1
0
mirror of https://github.com/sasjs/adapter.git synced 2026-01-05 19:50:06 +00:00

Compare commits

...

7 Commits

Author SHA1 Message Date
Krishna Acondy
fa531b34fd Merge pull request #120 from sasjs/session-manager-debug
fix(debug): propagate debug value from SASjs config
2020-10-03 17:41:35 +01:00
Krishna Acondy
354443c98b fix(debug): propagate debug value from SASjs config 2020-10-03 16:53:00 +01:00
Krishna Acondy
ee30ab195f Merge pull request #115 from sasjs/issue-114
chore(error-message): updated error message for forbidden request
2020-10-01 09:10:35 +01:00
Yury Shkoda
02c1712d22 chore(error-message): updated error message for forbidden request 2020-10-01 09:49:24 +03:00
Krishna Acondy
37def7a956 Merge pull request #111 from sasjs/dependabot/npm_and_yarn/isomorphic-fetch-3.0.0
chore(deps): bump isomorphic-fetch from 2.2.1 to 3.0.0
2020-09-29 20:03:06 +01:00
Krishna Acondy
653e3d05e0 Merge branch 'master' into dependabot/npm_and_yarn/isomorphic-fetch-3.0.0 2020-09-29 19:55:08 +01:00
dependabot-preview[bot]
e2ea3f4ddc chore(deps): bump isomorphic-fetch from 2.2.1 to 3.0.0
Bumps [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch) from 2.2.1 to 3.0.0.
- [Release notes](https://github.com/matthew-andrews/isomorphic-fetch/releases)
- [Commits](https://github.com/matthew-andrews/isomorphic-fetch/compare/v2.2.1...v3.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-25 23:51:17 +00:00
6 changed files with 55 additions and 115 deletions

45
package-lock.json generated
View File

@@ -3703,14 +3703,6 @@
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true "dev": true
}, },
"encoding": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
"requires": {
"iconv-lite": "~0.4.13"
}
},
"end-of-stream": { "end-of-stream": {
"version": "1.4.4", "version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -4967,6 +4959,7 @@
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dev": true,
"requires": { "requires": {
"safer-buffer": ">= 2.1.2 < 3" "safer-buffer": ">= 2.1.2 < 3"
} }
@@ -5256,7 +5249,8 @@
"is-stream": { "is-stream": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
}, },
"is-text-path": { "is-text-path": {
"version": "1.0.1", "version": "1.0.1",
@@ -5304,23 +5298,12 @@
"dev": true "dev": true
}, },
"isomorphic-fetch": { "isomorphic-fetch": {
"version": "2.2.1", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz",
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==",
"requires": { "requires": {
"node-fetch": "^1.0.1", "node-fetch": "^2.6.1",
"whatwg-fetch": ">=0.10.0" "whatwg-fetch": "^3.4.1"
},
"dependencies": {
"node-fetch": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
"requires": {
"encoding": "^0.1.11",
"is-stream": "^1.0.1"
}
}
} }
}, },
"isstream": { "isstream": {
@@ -8475,8 +8458,7 @@
"node-fetch": { "node-fetch": {
"version": "2.6.1", "version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
"dev": true
}, },
"node-int64": { "node-int64": {
"version": "0.4.0", "version": "0.4.0",
@@ -13577,7 +13559,8 @@
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true
}, },
"sane": { "sane": {
"version": "4.1.0", "version": "4.1.0",
@@ -16070,9 +16053,9 @@
} }
}, },
"whatwg-fetch": { "whatwg-fetch": {
"version": "3.0.0", "version": "3.4.1",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz",
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" "integrity": "sha512-sofZVzE1wKwO+EYPbWfiwzaKovWiZXf4coEzjGP9b2GBVgQRLQUZ2QcuPpQExGDAW5GItpEm6Tl4OU5mywnAoQ=="
}, },
"whatwg-mimetype": { "whatwg-mimetype": {
"version": "2.3.0", "version": "2.3.0",

View File

@@ -59,6 +59,6 @@
"dependencies": { "dependencies": {
"es6-promise": "^4.2.8", "es6-promise": "^4.2.8",
"form-data": "^3.0.0", "form-data": "^3.0.0",
"isomorphic-fetch": "^2.2.1" "isomorphic-fetch": "^3.0.0"
} }
} }

View File

@@ -38,6 +38,7 @@ export class SASViyaApiClient {
private csrfToken: CsrfToken | null = null private csrfToken: CsrfToken | null = null
private fileUploadCsrfToken: CsrfToken | null = null private fileUploadCsrfToken: CsrfToken | null = null
private _debug = false
private sessionManager = new SessionManager( private sessionManager = new SessionManager(
this.serverUrl, this.serverUrl,
this.contextName, this.contextName,
@@ -45,6 +46,15 @@ export class SASViyaApiClient {
) )
private folderMap = new Map<string, Job[]>() private folderMap = new Map<string, Job[]>()
public get debug() {
return this._debug
}
public set debug(value: boolean) {
this._debug = value
this.sessionManager.debug = value
}
/** /**
* Returns a list of jobs in the currently set root folder. * Returns a list of jobs in the currently set root folder.
*/ */
@@ -140,7 +150,6 @@ export class SASViyaApiClient {
linesOfCode, linesOfCode,
context.name, context.name,
accessToken, accessToken,
false,
null, null,
true true
).catch(() => null) ).catch(() => null)
@@ -404,7 +413,6 @@ export class SASViyaApiClient {
* @param contextName - the context to execute the code in. * @param contextName - the context to execute the code in.
* @param accessToken - an access token for an authorized user. * @param accessToken - an access token for an authorized user.
* @param sessionId - optional session ID to reuse. * @param sessionId - optional session ID to reuse.
* @param silent - optional flag to disable logging.
* @param data - execution data. * @param data - execution data.
* @param debug - when set to true, the log will be returned. * @param debug - when set to true, the log will be returned.
* @param expectWebout - when set to true, the automatic _webout fileref will be checked for content, and that content returned. This fileref is used when the Job contains a SASjs web request (as opposed to executing arbitrary SAS code). * @param expectWebout - when set to true, the automatic _webout fileref will be checked for content, and that content returned. This fileref is used when the Job contains a SASjs web request (as opposed to executing arbitrary SAS code).
@@ -414,12 +422,9 @@ export class SASViyaApiClient {
linesOfCode: string[], linesOfCode: string[],
contextName: string, contextName: string,
accessToken?: string, accessToken?: string,
silent = false,
data = null, data = null,
debug = false,
expectWebout = false expectWebout = false
): Promise<any> { ): Promise<any> {
silent = !debug
try { try {
const headers: any = { const headers: any = {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
@@ -442,7 +447,7 @@ export class SASViyaApiClient {
_OMITTEXTLOG: true _OMITTEXTLOG: true
} }
if (debug) { if (this.debug) {
jobArguments['_OMITTEXTLOG'] = false jobArguments['_OMITTEXTLOG'] = false
jobArguments['_OMITSESSIONRESULTS'] = false jobArguments['_OMITSESSIONRESULTS'] = false
jobArguments['_DEBUG'] = 131 jobArguments['_DEBUG'] = 131
@@ -502,7 +507,7 @@ export class SASViyaApiClient {
postJobRequest postJobRequest
) )
if (!silent) { if (this.debug) {
console.log(`Job has been submitted for '${fileName}'.`) console.log(`Job has been submitted for '${fileName}'.`)
console.log( console.log(
`You can monitor the job progress at '${this.serverUrl}${ `You can monitor the job progress at '${this.serverUrl}${
@@ -511,12 +516,7 @@ export class SASViyaApiClient {
) )
} }
const jobStatus = await this.pollJobState( const jobStatus = await this.pollJobState(postedJob, etag, accessToken)
postedJob,
etag,
accessToken,
silent
)
const { result: currentJob } = await this.request<Job>( const { result: currentJob } = await this.request<Job>(
`${this.serverUrl}/compute/sessions/${executionSessionId}/jobs/${postedJob.id}`, `${this.serverUrl}/compute/sessions/${executionSessionId}/jobs/${postedJob.id}`,
@@ -528,7 +528,7 @@ export class SASViyaApiClient {
const logLink = currentJob.links.find((l) => l.rel === 'log') const logLink = currentJob.links.find((l) => l.rel === 'log')
if (debug && logLink) { if (this.debug && logLink) {
log = await this.request<any>( log = await this.request<any>(
`${this.serverUrl}${logLink.href}/content?limit=10000`, `${this.serverUrl}${logLink.href}/content?limit=10000`,
{ {
@@ -590,9 +590,7 @@ export class SASViyaApiClient {
linesOfCode, linesOfCode,
contextName, contextName,
accessToken, accessToken,
silent, data
data,
debug
) )
} else { } else {
throw e throw e
@@ -991,9 +989,7 @@ export class SASViyaApiClient {
linesToExecute, linesToExecute,
contextName, contextName,
accessToken, accessToken,
true,
data, data,
debug,
true true
) )
} }
@@ -1125,12 +1121,7 @@ export class SASViyaApiClient {
`${this.serverUrl}/jobExecution/jobs?_action=wait`, `${this.serverUrl}/jobExecution/jobs?_action=wait`,
postJobRequest postJobRequest
) )
const jobStatus = await this.pollJobState( const jobStatus = await this.pollJobState(postedJob, etag, accessToken)
postedJob,
etag,
accessToken,
true
)
const { result: currentJob } = await this.request<Job>( const { result: currentJob } = await this.request<Job>(
`${this.serverUrl}/jobExecution/jobs/${postedJob.id}`, `${this.serverUrl}/jobExecution/jobs/${postedJob.id}`,
{ headers } { headers }
@@ -1195,8 +1186,7 @@ export class SASViyaApiClient {
private async pollJobState( private async pollJobState(
postedJob: any, postedJob: any,
etag: string | null, etag: string | null,
accessToken?: string, accessToken?: string
silent = false
) { ) {
const MAX_POLL_COUNT = 1000 const MAX_POLL_COUNT = 1000
const POLL_INTERVAL = 100 const POLL_INTERVAL = 100
@@ -1235,7 +1225,7 @@ export class SASViyaApiClient {
postedJobState === 'pending' postedJobState === 'pending'
) { ) {
if (stateLink) { if (stateLink) {
if (!silent) { if (this.debug) {
console.log('Polling job status... \n') console.log('Polling job status... \n')
} }
const { result: jobState } = await this.request<string>( const { result: jobState } = await this.request<string>(
@@ -1247,7 +1237,7 @@ export class SASViyaApiClient {
) )
postedJobState = jobState.trim() postedJobState = jobState.trim()
if (!silent) { if (this.debug) {
console.log(`Current state: ${postedJobState}\n`) console.log(`Current state: ${postedJobState}\n`)
} }
pollCount++ pollCount++
@@ -1263,49 +1253,6 @@ export class SASViyaApiClient {
}) })
} }
private async waitForSession(
session: Session,
etag: string | null,
accessToken?: string,
silent = false
) {
let sessionState = session.state
let pollCount = 0
const headers: any = {
'Content-Type': 'application/json',
'If-None-Match': etag
}
if (accessToken) {
headers.Authorization = `Bearer ${accessToken}`
}
const stateLink = session.links.find((l: any) => l.rel === 'state')
return new Promise(async (resolve, _) => {
if (sessionState === 'pending') {
if (stateLink) {
if (!silent) {
console.log('Polling session status... \n')
}
const { result: state } = await this.request<string>(
`${this.serverUrl}${stateLink.href}?wait=30`,
{
headers
},
'text'
)
sessionState = state.trim()
if (!silent) {
console.log(`Current state: ${sessionState}\n`)
}
pollCount++
resolve(sessionState)
}
} else {
resolve(sessionState)
}
})
}
private async uploadTables(data: any, accessToken?: string) { private async uploadTables(data: any, accessToken?: string) {
const uploadedFiles = [] const uploadedFiles = []
const headers: any = { const headers: any = {

View File

@@ -209,9 +209,7 @@ export default class SASjs {
fileName: string, fileName: string,
linesOfCode: string[], linesOfCode: string[],
contextName: string, contextName: string,
accessToken?: string, accessToken?: string
sessionId = '',
silent = false
) { ) {
this.isMethodSupported('executeScriptSASViya', ServerType.SASViya) this.isMethodSupported('executeScriptSASViya', ServerType.SASViya)
@@ -220,9 +218,7 @@ export default class SASjs {
linesOfCode, linesOfCode,
contextName, contextName,
accessToken, accessToken,
silent, null
null,
this.sasjsConfig.debug
) )
} }
@@ -410,6 +406,9 @@ export default class SASjs {
*/ */
public setDebugState(value: boolean) { public setDebugState(value: boolean) {
this.sasjsConfig.debug = value this.sasjsConfig.debug = value
if (this.sasViyaApiClient) {
this.sasViyaApiClient.debug = value
}
} }
/** /**
@@ -635,6 +634,7 @@ export default class SASjs {
this.sasjsConfig.contextName, this.sasjsConfig.contextName,
this.setCsrfTokenApi this.setCsrfTokenApi
) )
sasApiClient.debug = this.sasjsConfig.debug
} else if (this.sasjsConfig.serverType === ServerType.SAS9) { } else if (this.sasjsConfig.serverType === ServerType.SAS9) {
sasApiClient = new SAS9ApiClient(serverUrl) sasApiClient = new SAS9ApiClient(serverUrl)
} }
@@ -1352,6 +1352,8 @@ export default class SASjs {
this.sasjsConfig.contextName, this.sasjsConfig.contextName,
this.setCsrfTokenApi this.setCsrfTokenApi
) )
this.sasViyaApiClient.debug = this.sasjsConfig.debug
} }
if (this.sasjsConfig.serverType === ServerType.SAS9) { if (this.sasjsConfig.serverType === ServerType.SAS9) {
if (this.sas9ApiClient) if (this.sas9ApiClient)

View File

@@ -15,6 +15,15 @@ export class SessionManager {
private sessions: Session[] = [] private sessions: Session[] = []
private currentContext: Context | null = null private currentContext: Context | null = null
private csrfToken: CsrfToken | null = null private csrfToken: CsrfToken | null = null
private _debug: boolean = false
public get debug() {
return this._debug
}
public set debug(value: boolean) {
this._debug = value
}
async getSession(accessToken?: string) { async getSession(accessToken?: string) {
await this.createSessions(accessToken) await this.createSessions(accessToken)
@@ -115,8 +124,7 @@ export class SessionManager {
private async waitForSession( private async waitForSession(
session: Session, session: Session,
etag: string | null, etag: string | null,
accessToken?: string, accessToken?: string
silent = false
) { ) {
let sessionState = session.state let sessionState = session.state
const headers: any = { const headers: any = {
@@ -127,7 +135,7 @@ export class SessionManager {
return new Promise(async (resolve, _) => { return new Promise(async (resolve, _) => {
if (sessionState === 'pending') { if (sessionState === 'pending') {
if (stateLink) { if (stateLink) {
if (!silent) { if (this.debug) {
console.log('Polling session status... \n') // ? console.log('Polling session status... \n') // ?
} }
const { result: state } = await this.request<string>( const { result: state } = await this.request<string>(
@@ -139,7 +147,7 @@ export class SessionManager {
) )
sessionState = state.trim() sessionState = state.trim()
if (!silent) { if (this.debug) {
console.log(`Current state is '${sessionState}'\n`) console.log(`Current state is '${sessionState}'\n`)
} }
resolve(sessionState) resolve(sessionState)

View File

@@ -48,7 +48,7 @@ export async function makeRequest<T>(
try { try {
body = JSON.parse(body) body = JSON.parse(body)
body.message = `Forbidden. Check your permissions and user groups. ${ body.message = `Forbidden. Check your permissions and user groups, and also the scopes granted when registering your CLIENT_ID. ${
body.message || '' body.message || ''
}` }`