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

Compare commits

...

19 Commits

Author SHA1 Message Date
Yury Shkoda
ca18fcecf0 Merge pull request #167 from sasjs/cli-issue-249
feat(pollJobState): added ability to configure poll options
2020-11-30 12:55:11 +03:00
Yury Shkoda
009069169f chore(pollJobState): updated docs and added note 2020-11-30 12:45:37 +03:00
Yury Shkoda
6d166efd11 feat(pollJobState): made pollOptions optional and updated docs 2020-11-30 12:27:09 +03:00
Yury Shkoda
1b117a67aa feat(pollJobState): added ability to configure poll options 2020-11-30 10:21:49 +03:00
Yury Shkoda
505d85c256 Merge pull request #163 from sasjs/context-fix
fix(context): fixed result parsing
2020-11-26 13:36:07 +03:00
Yury Shkoda
71a3fe04a0 fix(context): fixed result parsing 2020-11-26 13:27:35 +03:00
Krishna Acondy
79bb27524c fix(package): include node version of adapter in package 2020-11-26 08:27:55 +00:00
Krishna Acondy
9651b7adb4 Merge pull request #161 from sasjs/fix-build-process
fix(*): export type declarations for node version of adapter
2020-11-25 21:06:20 +00:00
Krishna Acondy
59e5bec731 chore(*): fix PR template 2020-11-25 20:29:43 +00:00
Krishna Acondy
182e66216f fix(*): export type declarations for node version of adapter 2020-11-25 20:23:59 +00:00
Krishna Acondy
2408fd091e Merge pull request #155 from sasjs/dependabot/npm_and_yarn/semantic-release-17.3.0
chore(deps-dev): bump semantic-release from 17.2.3 to 17.3.0
2020-11-25 11:23:15 +00:00
dependabot-preview[bot]
0e38a24664 chore(deps-dev): bump semantic-release from 17.2.3 to 17.3.0
Bumps [semantic-release](https://github.com/semantic-release/semantic-release) from 17.2.3 to 17.3.0.
- [Release notes](https://github.com/semantic-release/semantic-release/releases)
- [Commits](https://github.com/semantic-release/semantic-release/compare/v17.2.3...v17.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-25 11:20:35 +00:00
Krishna Acondy
aa643d1782 Merge pull request #159 from sasjs/dependabot/npm_and_yarn/highlight.js-10.4.0
chore(deps): [security] bump highlight.js from 10.1.1 to 10.4.0
2020-11-25 11:18:17 +00:00
dependabot-preview[bot]
cdc91e9cda chore(deps): [security] bump highlight.js from 10.1.1 to 10.4.0
Bumps [highlight.js](https://github.com/highlightjs/highlight.js) from 10.1.1 to 10.4.0. **This update includes a security fix.**
- [Release notes](https://github.com/highlightjs/highlight.js/releases)
- [Changelog](https://github.com/highlightjs/highlight.js/blob/master/CHANGES.md)
- [Commits](https://github.com/highlightjs/highlight.js/compare/10.1.1...10.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-25 11:16:14 +00:00
Krishna Acondy
3f0590e0fe Merge pull request #158 from sasjs/issue157
Issue157
2020-11-25 11:14:39 +00:00
Mihajlo Medjedovic
5efb294ff2 fix: tests updated 2020-11-25 12:03:07 +01:00
Mihajlo Medjedovic
011e2d83dc fix: computeApi debug override 2020-11-24 15:19:19 +01:00
Mihajlo Medjedovic
e36b511530 test: make error and capture log, fixed 2020-11-24 13:02:17 +01:00
Mihajlo Medjedovic
b6a2a85d1d fix: compute api log not appended to sasjs requests 2020-11-24 11:59:17 +01:00
15 changed files with 156 additions and 134 deletions

2
.gitignore vendored
View File

@@ -1,2 +1,2 @@
node_modules node_modules
build build

View File

@@ -14,5 +14,5 @@ What code changes have been made to achieve the intent.
- [ ] Code is formatted correctly (`npm run lint:fix`). - [ ] Code is formatted correctly (`npm run lint:fix`).
- [ ] All unit tests are passing (`npm test`). - [ ] All unit tests are passing (`npm test`).
- [ ] All `sasjs-tests` unit tests are passing (`npm test`). - [ ] All `sasjs-cli` unit tests are passing (`npm test`).
- [ ] All `sasjs-tests` are passing (instructions available [here](https://github.com/sasjs/adapter/blob/master/sasjs-tests/README.md)). - [ ] All `sasjs-tests` are passing (instructions available [here](https://github.com/sasjs/adapter/blob/master/sasjs-tests/README.md)).

113
package-lock.json generated
View File

@@ -4794,9 +4794,9 @@
} }
}, },
"highlight.js": { "highlight.js": {
"version": "10.1.1", "version": "10.4.0",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.1.1.tgz", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.4.0.tgz",
"integrity": "sha512-b4L09127uVa+9vkMgPpdUQP78ickGbHEQTWeBrQFTJZ4/n2aihWOGS0ZoUqAwjVmfjhq/C76HRzkqwZhK4sBbg==", "integrity": "sha512-EfrUGcQ63oLJbj0J0RI9ebX6TAITbsDBLbsjr881L/X5fMO9+oadKzEF21C7R3ULKG6Gv3uoab2HiqVJa/4+oA==",
"dev": true "dev": true
}, },
"hmac-drbg": { "hmac-drbg": {
@@ -4936,14 +4936,6 @@
"dev": true, "dev": true,
"requires": { "requires": {
"resolve-from": "^5.0.0" "resolve-from": "^5.0.0"
},
"dependencies": {
"resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true
}
} }
}, },
"import-local": { "import-local": {
@@ -8571,9 +8563,9 @@
"dev": true "dev": true
}, },
"npm": { "npm": {
"version": "6.14.8", "version": "6.14.9",
"resolved": "https://registry.npmjs.org/npm/-/npm-6.14.8.tgz", "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.9.tgz",
"integrity": "sha512-HBZVBMYs5blsj94GTeQZel7s9odVuuSUHy1+AlZh7rPVux1os2ashvEGLy/STNK7vUjbrCg5Kq9/GXisJgdf6A==", "integrity": "sha512-yHi1+i9LyAZF1gAmgyYtVk+HdABlLy94PMIDoK1TRKWvmFQAt5z3bodqVwKvzY0s6dLqQPVsRLiwhJfNtiHeCg==",
"dev": true, "dev": true,
"requires": { "requires": {
"JSONStream": "^1.3.5", "JSONStream": "^1.3.5",
@@ -8656,7 +8648,7 @@
"npm-pick-manifest": "^3.0.2", "npm-pick-manifest": "^3.0.2",
"npm-profile": "^4.0.4", "npm-profile": "^4.0.4",
"npm-registry-fetch": "^4.0.7", "npm-registry-fetch": "^4.0.7",
"npm-user-validate": "~1.0.0", "npm-user-validate": "^1.0.1",
"npmlog": "~4.1.2", "npmlog": "~4.1.2",
"once": "~1.4.0", "once": "~1.4.0",
"opener": "^1.5.1", "opener": "^1.5.1",
@@ -8731,17 +8723,6 @@
"humanize-ms": "^1.2.1" "humanize-ms": "^1.2.1"
} }
}, },
"ajv": {
"version": "5.5.2",
"bundled": true,
"dev": true,
"requires": {
"co": "^4.6.0",
"fast-deep-equal": "^1.0.0",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.3.0"
}
},
"ansi-align": { "ansi-align": {
"version": "2.0.0", "version": "2.0.0",
"bundled": true, "bundled": true,
@@ -9072,11 +9053,6 @@
"mkdirp": "~0.5.0" "mkdirp": "~0.5.0"
} }
}, },
"co": {
"version": "4.6.0",
"bundled": true,
"dev": true
},
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
@@ -9525,11 +9501,6 @@
"bundled": true, "bundled": true,
"dev": true "dev": true
}, },
"fast-deep-equal": {
"version": "1.1.0",
"bundled": true,
"dev": true
},
"fast-json-stable-stringify": { "fast-json-stable-stringify": {
"version": "2.0.0", "version": "2.0.0",
"bundled": true, "bundled": true,
@@ -9850,12 +9821,35 @@
"dev": true "dev": true
}, },
"har-validator": { "har-validator": {
"version": "5.1.0", "version": "5.1.5",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"requires": { "requires": {
"ajv": "^5.3.0", "ajv": "^6.12.3",
"har-schema": "^2.0.0" "har-schema": "^2.0.0"
},
"dependencies": {
"ajv": {
"version": "6.12.6",
"bundled": true,
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"fast-deep-equal": {
"version": "3.1.3",
"bundled": true,
"dev": true
},
"json-schema-traverse": {
"version": "0.4.1",
"bundled": true,
"dev": true
}
} }
}, },
"has": { "has": {
@@ -10142,11 +10136,6 @@
"bundled": true, "bundled": true,
"dev": true "dev": true
}, },
"json-schema-traverse": {
"version": "0.3.1",
"bundled": true,
"dev": true
},
"json-stringify-safe": { "json-stringify-safe": {
"version": "5.0.1", "version": "5.0.1",
"bundled": true, "bundled": true,
@@ -10788,6 +10777,11 @@
"path-key": "^2.0.0" "path-key": "^2.0.0"
} }
}, },
"npm-user-validate": {
"version": "1.0.1",
"bundled": true,
"dev": true
},
"npmlog": { "npmlog": {
"version": "4.1.2", "version": "4.1.2",
"bundled": true, "bundled": true,
@@ -11788,6 +11782,21 @@
"xdg-basedir": "^3.0.0" "xdg-basedir": "^3.0.0"
} }
}, },
"uri-js": {
"version": "4.4.0",
"bundled": true,
"dev": true,
"requires": {
"punycode": "^2.1.0"
},
"dependencies": {
"punycode": {
"version": "2.1.1",
"bundled": true,
"dev": true
}
}
},
"url-parse-lax": { "url-parse-lax": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
@@ -12091,12 +12100,6 @@
"path-key": "^2.0.0" "path-key": "^2.0.0"
} }
}, },
"npm-user-validate": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/npm-user-validate/-/npm-user-validate-1.0.1.tgz",
"integrity": "sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw==",
"dev": true
},
"nwsapi": { "nwsapi": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
@@ -13244,9 +13247,9 @@
} }
}, },
"semantic-release": { "semantic-release": {
"version": "17.2.3", "version": "17.3.0",
"resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-17.2.3.tgz", "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-17.3.0.tgz",
"integrity": "sha512-MY1MlowGQrkOR7+leOD8ICkVOC6i1szbwDODdbJ0UdshtMx8Ms0bhpRQmEEliqYKEb5PLv/dqs6zKKuHT7UxTg==", "integrity": "sha512-enhDayMZRP4nWcWAMBFHHB7THRaIcRdUAZv3lxd65pXs2ttzay7IeCvRRrGayRWExtnY0ulwRz5Ycp88Dv/UeQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@semantic-release/commit-analyzer": "^8.0.0", "@semantic-release/commit-analyzer": "^8.0.0",
@@ -13337,12 +13340,6 @@
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true "dev": true
}, },
"resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
"integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
"dev": true
},
"semver": { "semver": {
"version": "7.3.2", "version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",

View File

@@ -2,7 +2,7 @@
"name": "@sasjs/adapter", "name": "@sasjs/adapter",
"description": "JavaScript adapter for SAS", "description": "JavaScript adapter for SAS",
"scripts": { "scripts": {
"build": "rimraf build && webpack", "build": "rimraf build && rimraf node && mkdir node && cp -r src/* node && webpack && rimraf build/src && rimraf node",
"package:lib": "npm run build && cp ./package.json build && cd build && npm version \"5.0.0\" && npm pack", "package:lib": "npm run build && cp ./package.json build && cd build && npm version \"5.0.0\" && npm pack",
"publish:lib": "npm run build && cd build && npm publish", "publish:lib": "npm run build && cd build && npm publish",
"lint:fix": "npx prettier --write 'src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}'", "lint:fix": "npx prettier --write 'src/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}'",
@@ -42,7 +42,7 @@
"jest": "^25.5.4", "jest": "^25.5.4",
"path": "^0.12.7", "path": "^0.12.7",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"semantic-release": "^17.2.3", "semantic-release": "^17.3.0",
"terser-webpack-plugin": "^4.2.3", "terser-webpack-plugin": "^4.2.3",
"ts-jest": "^25.5.1", "ts-jest": "^25.5.1",
"ts-loader": "^8.0.11", "ts-loader": "^8.0.11",

View File

@@ -1357,9 +1357,9 @@
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
}, },
"@sasjs/adapter": { "@sasjs/adapter": {
"version": "1.12.0", "version": "1.18.3",
"resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-1.12.0.tgz", "resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-1.18.3.tgz",
"integrity": "sha512-0uGQH9ynomWzdBaEujEtcR38q6V7LCgG0mrb1Wellv6cC/IHD3j6WfeZZAgtiMPeOSJjbCDBOlVnzC2TlBqJFw==", "integrity": "sha512-wzDFJRyt2dXFeQP+JzqRGunYUbujrAbU/Jc4IWg5URsCkGAzwsNl/4G0xJVbqOTy1MvoZ431rfCnvhkUlg7D3Q==",
"requires": { "requires": {
"es6-promise": "^4.2.8", "es6-promise": "^4.2.8",
"form-data": "^3.0.0", "form-data": "^3.0.0",

View File

@@ -4,7 +4,7 @@
"homepage": ".", "homepage": ".",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@sasjs/adapter": "^1.12.0", "@sasjs/adapter": "^1.18.2",
"@sasjs/test-framework": "^1.4.0", "@sasjs/test-framework": "^1.4.0",
"@testing-library/jest-dom": "^4.2.4", "@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0", "@testing-library/react": "^9.5.0",

View File

@@ -1,9 +0,0 @@
import React from "react";
import { render } from "@testing-library/react";
import App from "./App";
test("renders learn react link", () => {
const { getByText } = render(<App />);
const linkElement = getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View File

@@ -3,12 +3,12 @@ import { TestSuite } from "@sasjs/test-framework";
const defaultConfig: SASjsConfig = { const defaultConfig: SASjsConfig = {
serverUrl: window.location.origin, serverUrl: window.location.origin,
pathSAS9: "/SASStoredProcess/do", pathSAS9: '/SASStoredProcess/do',
pathSASViya: "/SASJobExecution", pathSASViya: '/SASJobExecution',
appLoc: "/Public/seedapp", appLoc: '/Public/seedapp',
serverType: ServerType.SASViya, serverType: ServerType.SASViya,
debug: true, debug: false,
contextName: "SAS Job Execution compute context", contextName: 'SAS Job Execution compute context',
useComputeApi: false useComputeApi: false
}; };
@@ -57,6 +57,7 @@ export const basicTests = (
}, },
assertion: (sasjsInstance: SASjs) => { assertion: (sasjsInstance: SASjs) => {
const sasjsConfig = sasjsInstance.getSasjsConfig(); const sasjsConfig = sasjsInstance.getSasjsConfig();
return ( return (
sasjsConfig.serverUrl === defaultConfig.serverUrl && sasjsConfig.serverUrl === defaultConfig.serverUrl &&
sasjsConfig.pathSAS9 === defaultConfig.pathSAS9 && sasjsConfig.pathSAS9 === defaultConfig.pathSAS9 &&

View File

@@ -88,7 +88,7 @@ export const sendArrTests = (adapter: SASjs): TestSuite => ({
return adapter.request("common/sendArr", data).catch((e) => e); return adapter.request("common/sendArr", data).catch((e) => e);
}, },
assertion: (error: any) => { assertion: (error: any) => {
return !!error && !!error.body && !!error.body.message; return !!error && !!error.error && !!error.error.message;
} }
}, },
{ {
@@ -185,7 +185,7 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
}; };
return adapter.request("common/sendObj", invalidData).catch((e) => e); return adapter.request("common/sendObj", invalidData).catch((e) => e);
}, },
assertion: (error: any) => !!error && !!error.body && !!error.body.message assertion: (error: any) => !!error && !!error.error && !!error.error.message
}, },
{ {
title: "Single string value", title: "Single string value",
@@ -219,7 +219,7 @@ export const sendObjTests = (adapter: SASjs): TestSuite => ({
.catch((e) => e); .catch((e) => e);
}, },
assertion: (error: any) => { assertion: (error: any) => {
return !!error && !!error.body && !!error.body.message; return !!error && !!error.error && !!error.error.message;
} }
}, },
{ {

View File

@@ -23,22 +23,24 @@ export const sasjsRequestTests = (adapter: SASjs): TestSuite => ({
}, },
{ {
title: "Make error and capture log", title: "Make error and capture log",
description: "Should make an error and capture log", description: "Should make an error and capture log, in the same time it is testing if debug override is working",
test: async () => { test: async () => {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
adapter adapter
.request("common/makeErr", data) .request("common/makeErr", data, {debug: true})
.then((res) => { .then((res) => {
//no action here, this request must throw error //no action here, this request must throw error
}) })
.catch((err) => { .catch((err) => {
let sasRequests = adapter.getSasRequests(); let sasRequests = adapter.getSasRequests();
let makeErrRequest = let makeErrRequest: any =
sasRequests.find((req) => sasRequests.find((req) =>
req.serviceLink.includes("makeErr") req.serviceLink.includes("makeErr")
) || null; ) || null;
resolve(!!makeErrRequest); if (!makeErrRequest) resolve(false)
resolve(!!(makeErrRequest.logFile && makeErrRequest.logFile.length > 0));
}); });
}); });
}, },

View File

@@ -17,7 +17,8 @@ import {
CsrfToken, CsrfToken,
EditContextInput, EditContextInput,
ErrorResponse, ErrorResponse,
JobDefinition JobDefinition,
PollOptions
} from './types' } from './types'
import { formatDataForRequest } from './utils/formatDataForRequest' import { formatDataForRequest } from './utils/formatDataForRequest'
import { SessionManager } from './SessionManager' import { SessionManager } from './SessionManager'
@@ -154,6 +155,7 @@ export class SASViyaApiClient {
context.name, context.name,
accessToken, accessToken,
null, null,
false,
true, true,
true true
).catch((err) => err) ).catch((err) => err)
@@ -164,30 +166,27 @@ export class SASViyaApiClient {
for (const promise of promises) results.push(await promise()) for (const promise of promises) results.push(await promise())
results.forEach((result: any, index: number) => { results.forEach((result: any, index: number) => {
if (result && result.error && result.error.details) { if (result && result.log) {
try { try {
const resultParsed = result.error.details const resultParsed = result.log
let sysUserId = ''
if (resultParsed && resultParsed.body) { const sysUserIdLog = resultParsed
let sysUserId = '' .split('\n')
.find((line: string) => line.startsWith('SYSUSERID='))
const sysUserIdLog = resultParsed.body if (sysUserIdLog) {
.split('\n') sysUserId = sysUserIdLog.replace('SYSUSERID=', '')
.find((line: string) => line.startsWith('SYSUSERID='))
if (sysUserIdLog) { executableContexts.push({
sysUserId = sysUserIdLog.replace('SYSUSERID=', '') createdBy: contextsList[index].createdBy,
id: contextsList[index].id,
executableContexts.push({ name: contextsList[index].name,
createdBy: contextsList[index].createdBy, version: contextsList[index].version,
id: contextsList[index].id, attributes: {
name: contextsList[index].name, sysUserId
version: contextsList[index].version, }
attributes: { })
sysUserId
}
})
}
} }
} catch (error) { } catch (error) {
throw error throw error
@@ -426,10 +425,11 @@ export class SASViyaApiClient {
* @param linesOfCode - an array of code lines to execute. * @param linesOfCode - an array of code lines to execute.
* @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 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).
* @param waitForResult - when set to true, function will return the session
* @param pollOptions - an object that represents poll interval(milliseconds) and maximum amount of attempts. Object example: { MAX_POLL_COUNT: 24 * 60 * 60, POLL_INTERVAL: 1000 }.
*/ */
public async executeScript( public async executeScript(
jobPath: string, jobPath: string,
@@ -437,8 +437,10 @@ export class SASViyaApiClient {
contextName: string, contextName: string,
accessToken?: string, accessToken?: string,
data = null, data = null,
debug: boolean = false,
expectWebout = false, expectWebout = false,
waitForResult = true waitForResult = true,
pollOptions?: PollOptions
): Promise<any> { ): Promise<any> {
try { try {
const headers: any = { const headers: any = {
@@ -467,7 +469,7 @@ export class SASViyaApiClient {
_OMITTEXTLOG: true _OMITTEXTLOG: true
} }
if (this.debug) { if (debug) {
jobArguments['_OMITTEXTLOG'] = false jobArguments['_OMITTEXTLOG'] = false
jobArguments['_OMITSESSIONRESULTS'] = false jobArguments['_OMITSESSIONRESULTS'] = false
jobArguments['_DEBUG'] = 131 jobArguments['_DEBUG'] = 131
@@ -535,7 +537,7 @@ export class SASViyaApiClient {
return session return session
} }
if (this.debug) { if (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}${
@@ -544,7 +546,12 @@ export class SASViyaApiClient {
) )
} }
const jobStatus = await this.pollJobState(postedJob, etag, accessToken) const jobStatus = await this.pollJobState(
postedJob,
etag,
accessToken,
pollOptions
)
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}`,
@@ -558,7 +565,7 @@ export class SASViyaApiClient {
const logLink = currentJob.links.find((l) => l.rel === 'log') const logLink = currentJob.links.find((l) => l.rel === 'log')
if (this.debug && logLink) { if (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`,
{ {
@@ -606,12 +613,10 @@ export class SASViyaApiClient {
throw err throw err
}) })
return Promise.reject( return Promise.reject({
new ErrorResponse('Job execution failed.', { status: 500,
status: 500, log: log
body: log })
})
)
} }
} }
return { return {
@@ -635,6 +640,7 @@ export class SASViyaApiClient {
contextName, contextName,
accessToken, accessToken,
data, data,
debug,
false, false,
true true
) )
@@ -951,14 +957,17 @@ export class SASViyaApiClient {
* @param accessToken - an optional access token for an authorized user. * @param accessToken - an optional access token for an authorized user.
* @param waitForResult - a boolean indicating if the function should wait for a result. * @param waitForResult - a boolean indicating if the function should wait for a result.
* @param expectWebout - a boolean indicating whether to expect a _webout response. * @param expectWebout - a boolean indicating whether to expect a _webout response.
* @param pollOptions - an object that represents poll interval(milliseconds) and maximum amount of attempts. Object example: { MAX_POLL_COUNT: 24 * 60 * 60, POLL_INTERVAL: 1000 }.
*/ */
public async executeComputeJob( public async executeComputeJob(
sasJob: string, sasJob: string,
contextName: string, contextName: string,
debug?: boolean,
data?: any, data?: any,
accessToken?: string, accessToken?: string,
waitForResult = true, waitForResult = true,
expectWebout = false expectWebout = false,
pollOptions?: PollOptions
) { ) {
if (isRelativePath(sasJob) && !this.rootFolderName) { if (isRelativePath(sasJob) && !this.rootFolderName) {
throw new Error( throw new Error(
@@ -1041,8 +1050,10 @@ export class SASViyaApiClient {
contextName, contextName,
accessToken, accessToken,
data, data,
debug,
expectWebout, expectWebout,
waitForResult waitForResult,
pollOptions
) )
} }
@@ -1235,13 +1246,21 @@ export class SASViyaApiClient {
this.folderMap.set(path, itemsAtRoot) this.folderMap.set(path, itemsAtRoot)
} }
// REFACTOR: set default value for 'pollOptions' attribute
private async pollJobState( private async pollJobState(
postedJob: any, postedJob: any,
etag: string | null, etag: string | null,
accessToken?: string accessToken?: string,
pollOptions?: PollOptions
) { ) {
const MAX_POLL_COUNT = 1000 let POLL_INTERVAL = 100
const POLL_INTERVAL = 100 let MAX_POLL_COUNT = 1000
if (pollOptions) {
POLL_INTERVAL = pollOptions.POLL_INTERVAL || POLL_INTERVAL
MAX_POLL_COUNT = pollOptions.MAX_POLL_COUNT || MAX_POLL_COUNT
}
let postedJobState = '' let postedJobState = ''
let pollCount = 0 let pollCount = 0
const headers: any = { const headers: any = {

View File

@@ -32,7 +32,8 @@ import {
CsrfToken, CsrfToken,
UploadFile, UploadFile,
EditContextInput, EditContextInput,
ErrorResponse ErrorResponse,
PollOptions
} from './types' } from './types'
import { SASViyaApiClient } from './SASViyaApiClient' import { SASViyaApiClient } from './SASViyaApiClient'
import { SAS9ApiClient } from './SAS9ApiClient' import { SAS9ApiClient } from './SAS9ApiClient'
@@ -711,13 +712,15 @@ export default class SASjs {
* @param accessToken - a valid access token that is authorised to execute compute jobs. * @param accessToken - a valid access token that is authorised to execute compute jobs.
* The access token is not required when the user is authenticated via the browser. * The access token is not required when the user is authenticated via the browser.
* @param waitForResult - a boolean that indicates whether the function needs to wait for execution to complete. * @param waitForResult - a boolean that indicates whether the function needs to wait for execution to complete.
* @param pollOptions - an object that represents poll interval(milliseconds) and maximum amount of attempts. Object example: { MAX_POLL_COUNT: 24 * 60 * 60, POLL_INTERVAL: 1000 }.
*/ */
public async startComputeJob( public async startComputeJob(
sasJob: string, sasJob: string,
data: any, data: any,
config: any = {}, config: any = {},
accessToken?: string, accessToken?: string,
waitForResult?: boolean waitForResult?: boolean,
pollOptions?: PollOptions
) { ) {
config = { config = {
...this.sasjsConfig, ...this.sasjsConfig,
@@ -734,10 +737,12 @@ export default class SASjs {
return this.sasViyaApiClient?.executeComputeJob( return this.sasViyaApiClient?.executeComputeJob(
sasJob, sasJob,
config.contextName, config.contextName,
config.debug,
data, data,
accessToken, accessToken,
!!waitForResult, !!waitForResult,
false false,
pollOptions
) )
} }
@@ -766,6 +771,7 @@ export default class SASjs {
?.executeComputeJob( ?.executeComputeJob(
sasJob, sasJob,
config.contextName, config.contextName,
config.debug,
data, data,
accessToken, accessToken,
waitForResult, waitForResult,
@@ -895,8 +901,8 @@ export default class SASjs {
return responseJson return responseJson
}) })
.catch(async (e) => { .catch(async (response) => {
if (needsRetry(JSON.stringify(e))) { if (needsRetry(JSON.stringify(response))) {
if (this.retryCountJeseApi < requestRetryLimit) { if (this.retryCountJeseApi < requestRetryLimit) {
let retryResponse = await this.executeJobViaJesApi( let retryResponse = await this.executeJobViaJesApi(
sasJob, sasJob,
@@ -917,11 +923,11 @@ export default class SASjs {
} }
} }
if (e?.log) { if (response?.log) {
this.appendSasjsRequest(e.log, sasJob, null) this.appendSasjsRequest(response.log, sasJob, null)
} }
if (e.toString().includes('Job was not found')) { if (response.toString().includes('Job was not found')) {
reject( reject(
new ErrorResponse('Service not found on the server.', { new ErrorResponse('Service not found on the server.', {
sasJob: sasJob sasJob: sasJob
@@ -929,7 +935,7 @@ export default class SASjs {
) )
} }
reject(new ErrorResponse('Job execution failed.', e)) reject(new ErrorResponse('Job execution failed.', response))
}) })
) )
} }

4
src/types/PollOptions.ts Normal file
View File

@@ -0,0 +1,4 @@
export interface PollOptions {
MAX_POLL_COUNT?: number
POLL_INTERVAL?: number
}

View File

@@ -12,3 +12,4 @@ export * from './SASjsWaitingRequest'
export * from './ServerType' export * from './ServerType'
export * from './Session' export * from './Session'
export * from './UploadFile' export * from './UploadFile'
export * from './PollOptions'

View File

@@ -47,6 +47,7 @@ const browserConfig = {
const nodeConfig = { const nodeConfig = {
...browserConfig, ...browserConfig,
target: 'node', target: 'node',
entry: './node/index.ts',
output: { output: {
...browserConfig.output, ...browserConfig.output,
path: path.resolve(__dirname, 'build', 'node') path: path.resolve(__dirname, 'build', 'node')