@sasjs/adapter 3.7.2 → 3.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SASjs.d.ts +7 -5
- package/file/generateFileUploadForm.d.ts +11 -1
- package/file/generateTableUploadForm.d.ts +3 -2
- package/index.js +2 -2
- package/job-execution/index.d.ts +0 -1
- package/node/SASjs.d.ts +7 -5
- package/node/file/generateFileUploadForm.d.ts +11 -1
- package/node/file/generateTableUploadForm.d.ts +3 -2
- package/node/index.js +2 -2
- package/node/job-execution/index.d.ts +0 -1
- package/package.json +1 -1
- package/src/SASjs.ts +10 -15
- package/src/file/generateFileUploadForm.ts +12 -2
- package/src/file/generateTableUploadForm.ts +5 -1
- package/src/job-execution/WebJobExecutor.ts +19 -2
- package/src/job-execution/index.ts +0 -1
- package/job-execution/SasJsJobExecutor.d.ts +0 -10
- package/node/job-execution/SasJsJobExecutor.d.ts +0 -10
- package/src/job-execution/SasJsJobExecutor.ts +0 -131
package/package.json
CHANGED
package/src/SASjs.ts
CHANGED
|
@@ -27,7 +27,6 @@ import {
|
|
|
27
27
|
ComputeJobExecutor,
|
|
28
28
|
JesJobExecutor,
|
|
29
29
|
Sas9JobExecutor,
|
|
30
|
-
SasJsJobExecutor,
|
|
31
30
|
FileUploader
|
|
32
31
|
} from './job-execution'
|
|
33
32
|
import { ErrorResponse } from './types/errors'
|
|
@@ -63,7 +62,6 @@ export default class SASjs {
|
|
|
63
62
|
private computeJobExecutor: JobExecutor | null = null
|
|
64
63
|
private jesJobExecutor: JobExecutor | null = null
|
|
65
64
|
private sas9JobExecutor: JobExecutor | null = null
|
|
66
|
-
private sasJsJobExecutor: JobExecutor | null = null
|
|
67
65
|
|
|
68
66
|
constructor(config?: Partial<SASjsConfig>) {
|
|
69
67
|
this.sasjsConfig = {
|
|
@@ -79,7 +77,8 @@ export default class SASjs {
|
|
|
79
77
|
}
|
|
80
78
|
|
|
81
79
|
/**
|
|
82
|
-
* Executes
|
|
80
|
+
* Executes code against a SAS 9 server. Requires a runner to be present in
|
|
81
|
+
* the users home directory in metadata.
|
|
83
82
|
* @param linesOfCode - lines of sas code from the file to run.
|
|
84
83
|
* @param username - a string representing the username.
|
|
85
84
|
* @param password - a string representing the password.
|
|
@@ -99,7 +98,7 @@ export default class SASjs {
|
|
|
99
98
|
}
|
|
100
99
|
|
|
101
100
|
/**
|
|
102
|
-
* Executes
|
|
101
|
+
* Executes sas code in a SAS Viya compute session.
|
|
103
102
|
* @param fileName - name of the file to run. It will be converted to path to the file being submitted for execution.
|
|
104
103
|
* @param linesOfCode - lines of sas code from the file to run.
|
|
105
104
|
* @param contextName - context name on which code will be run on the server.
|
|
@@ -643,7 +642,8 @@ export default class SASjs {
|
|
|
643
642
|
}
|
|
644
643
|
|
|
645
644
|
/**
|
|
646
|
-
* Makes a request to
|
|
645
|
+
* Makes a request to program specified in `SASjob` (could be a Viya Job, a
|
|
646
|
+
* SAS 9 Stored Process, or a SASjs Server Stored Program). The response
|
|
647
647
|
* object will always contain table names in lowercase, and column names in
|
|
648
648
|
* uppercase. Values are returned formatted by default, unformatted
|
|
649
649
|
* values can be configured as an option in the `%webout` macro.
|
|
@@ -652,7 +652,8 @@ export default class SASjs {
|
|
|
652
652
|
* the SAS `_program` parameter to run a Job Definition or SAS 9 Stored
|
|
653
653
|
* Process). Is prepended at runtime with the value of `appLoc`.
|
|
654
654
|
* @param data - a JSON object containing one or more tables to be sent to
|
|
655
|
-
* SAS.
|
|
655
|
+
* SAS. For an example of the table structure, see the project README. This
|
|
656
|
+
* value can be `null` if no inputs are required.
|
|
656
657
|
* @param config - provide any changes to the config here, for instance to
|
|
657
658
|
* enable/disable `debug`. Any change provided will override the global config,
|
|
658
659
|
* for that particular function call.
|
|
@@ -682,9 +683,10 @@ export default class SASjs {
|
|
|
682
683
|
|
|
683
684
|
const validationResult = this.validateInput(data)
|
|
684
685
|
|
|
686
|
+
// status is true if the data passes validation checks above
|
|
685
687
|
if (validationResult.status) {
|
|
686
688
|
if (config.serverType === ServerType.Sasjs) {
|
|
687
|
-
return await this.
|
|
689
|
+
return await this.webJobExecutor!.execute(
|
|
688
690
|
sasJob,
|
|
689
691
|
data,
|
|
690
692
|
config,
|
|
@@ -693,7 +695,7 @@ export default class SASjs {
|
|
|
693
695
|
extraResponseAttributes
|
|
694
696
|
)
|
|
695
697
|
} else if (
|
|
696
|
-
config.serverType
|
|
698
|
+
config.serverType === ServerType.SasViya &&
|
|
697
699
|
config.useComputeApi !== undefined &&
|
|
698
700
|
config.useComputeApi !== null
|
|
699
701
|
) {
|
|
@@ -1114,13 +1116,6 @@ export default class SASjs {
|
|
|
1114
1116
|
this.sasViyaApiClient!
|
|
1115
1117
|
)
|
|
1116
1118
|
|
|
1117
|
-
this.sasJsJobExecutor = new SasJsJobExecutor(
|
|
1118
|
-
this.sasjsConfig.serverUrl,
|
|
1119
|
-
this.sasjsConfig.serverType!,
|
|
1120
|
-
this.jobsPath,
|
|
1121
|
-
this.requestClient
|
|
1122
|
-
)
|
|
1123
|
-
|
|
1124
1119
|
this.sas9JobExecutor = new Sas9JobExecutor(
|
|
1125
1120
|
this.sasjsConfig.serverUrl,
|
|
1126
1121
|
this.sasjsConfig.serverType!,
|
|
@@ -1,9 +1,19 @@
|
|
|
1
|
+
import * as NodeFormData from 'form-data'
|
|
1
2
|
import { convertToCSV } from '../utils/convertToCsv'
|
|
2
3
|
|
|
4
|
+
/**
|
|
5
|
+
* One of the approaches SASjs takes to send tables-formatted JSON (see README)
|
|
6
|
+
* to SAS is as multipart form data, where each table is provided as a specially
|
|
7
|
+
* formatted CSV file.
|
|
8
|
+
* @param formData Different objects are used depending on whether the adapter is
|
|
9
|
+
* running in the browser, or in the CLI
|
|
10
|
+
* @param data Special, tables-formatted JSON (see README)
|
|
11
|
+
* @returns Populated formData
|
|
12
|
+
*/
|
|
3
13
|
export const generateFileUploadForm = (
|
|
4
|
-
formData: FormData,
|
|
14
|
+
formData: FormData | NodeFormData,
|
|
5
15
|
data: any
|
|
6
|
-
): FormData => {
|
|
16
|
+
): FormData | NodeFormData => {
|
|
7
17
|
for (const tableName in data) {
|
|
8
18
|
if (!Array.isArray(data[tableName])) continue
|
|
9
19
|
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import * as NodeFormData from 'form-data'
|
|
1
2
|
import { convertToCSV } from '../utils/convertToCsv'
|
|
2
3
|
import { splitChunks } from '../utils/splitChunks'
|
|
3
4
|
|
|
4
|
-
export const generateTableUploadForm = (
|
|
5
|
+
export const generateTableUploadForm = (
|
|
6
|
+
formData: FormData | NodeFormData,
|
|
7
|
+
data: any
|
|
8
|
+
) => {
|
|
5
9
|
const sasjsTables = []
|
|
6
10
|
const requestParams: any = {}
|
|
7
11
|
let tableCounter = 0
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as NodeFormData from 'form-data'
|
|
1
2
|
import {
|
|
2
3
|
AuthConfig,
|
|
3
4
|
ExtraResponseAttributes,
|
|
@@ -108,7 +109,12 @@ export class WebJobExecutor extends BaseJobExecutor {
|
|
|
108
109
|
...this.getRequestParams(config)
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Use the available form data object (FormData in Browser, NodeFormData in
|
|
114
|
+
* Node)
|
|
115
|
+
*/
|
|
116
|
+
let formData =
|
|
117
|
+
typeof FormData === 'undefined' ? new NodeFormData() : new FormData()
|
|
112
118
|
|
|
113
119
|
if (data) {
|
|
114
120
|
const stringifiedData = JSON.stringify(data)
|
|
@@ -143,8 +149,19 @@ export class WebJobExecutor extends BaseJobExecutor {
|
|
|
143
149
|
}
|
|
144
150
|
}
|
|
145
151
|
|
|
152
|
+
/* The NodeFormData object does not set the request header - so, set it */
|
|
153
|
+
const contentType =
|
|
154
|
+
formData instanceof NodeFormData
|
|
155
|
+
? `multipart/form-data; boundary=${formData.getBoundary()}`
|
|
156
|
+
: undefined
|
|
157
|
+
|
|
146
158
|
const requestPromise = new Promise((resolve, reject) => {
|
|
147
|
-
this.requestClient!.post(
|
|
159
|
+
this.requestClient!.post(
|
|
160
|
+
apiUrl,
|
|
161
|
+
formData,
|
|
162
|
+
authConfig?.access_token,
|
|
163
|
+
contentType
|
|
164
|
+
)
|
|
148
165
|
.then(async (res: any) => {
|
|
149
166
|
const parsedSasjsServerLog =
|
|
150
167
|
this.serverType === ServerType.Sasjs
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { AuthConfig, ExtraResponseAttributes, ServerType } from '@sasjs/utils/types';
|
|
2
|
-
import { RequestClient } from '../request/RequestClient';
|
|
3
|
-
import { BaseJobExecutor } from './JobExecutor';
|
|
4
|
-
export declare class SasJsJobExecutor extends BaseJobExecutor {
|
|
5
|
-
private jobsPath;
|
|
6
|
-
private requestClient;
|
|
7
|
-
constructor(serverUrl: string, serverType: ServerType, jobsPath: string, requestClient: RequestClient);
|
|
8
|
-
execute(sasJob: string, data: any, config: any, loginRequiredCallback?: any, authConfig?: AuthConfig, extraResponseAttributes?: ExtraResponseAttributes[]): Promise<unknown>;
|
|
9
|
-
private getRequestParams;
|
|
10
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { AuthConfig, ExtraResponseAttributes, ServerType } from '@sasjs/utils/types';
|
|
2
|
-
import { RequestClient } from '../request/RequestClient';
|
|
3
|
-
import { BaseJobExecutor } from './JobExecutor';
|
|
4
|
-
export declare class SasJsJobExecutor extends BaseJobExecutor {
|
|
5
|
-
private jobsPath;
|
|
6
|
-
private requestClient;
|
|
7
|
-
constructor(serverUrl: string, serverType: ServerType, jobsPath: string, requestClient: RequestClient);
|
|
8
|
-
execute(sasJob: string, data: any, config: any, loginRequiredCallback?: any, authConfig?: AuthConfig, extraResponseAttributes?: ExtraResponseAttributes[]): Promise<unknown>;
|
|
9
|
-
private getRequestParams;
|
|
10
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AuthConfig,
|
|
3
|
-
ExtraResponseAttributes,
|
|
4
|
-
ServerType
|
|
5
|
-
} from '@sasjs/utils/types'
|
|
6
|
-
import {
|
|
7
|
-
ErrorResponse,
|
|
8
|
-
JobExecutionError,
|
|
9
|
-
LoginRequiredError
|
|
10
|
-
} from '../types/errors'
|
|
11
|
-
import { RequestClient } from '../request/RequestClient'
|
|
12
|
-
import {
|
|
13
|
-
isRelativePath,
|
|
14
|
-
appendExtraResponseAttributes,
|
|
15
|
-
getValidJson
|
|
16
|
-
} from '../utils'
|
|
17
|
-
import { BaseJobExecutor } from './JobExecutor'
|
|
18
|
-
import { parseWeboutResponse } from '../utils/parseWeboutResponse'
|
|
19
|
-
|
|
20
|
-
export class SasJsJobExecutor extends BaseJobExecutor {
|
|
21
|
-
constructor(
|
|
22
|
-
serverUrl: string,
|
|
23
|
-
serverType: ServerType,
|
|
24
|
-
private jobsPath: string,
|
|
25
|
-
private requestClient: RequestClient
|
|
26
|
-
) {
|
|
27
|
-
super(serverUrl, serverType)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async execute(
|
|
31
|
-
sasJob: string,
|
|
32
|
-
data: any,
|
|
33
|
-
config: any,
|
|
34
|
-
loginRequiredCallback?: any,
|
|
35
|
-
authConfig?: AuthConfig,
|
|
36
|
-
extraResponseAttributes: ExtraResponseAttributes[] = []
|
|
37
|
-
) {
|
|
38
|
-
const loginCallback = loginRequiredCallback || (() => Promise.resolve())
|
|
39
|
-
const program = isRelativePath(sasJob)
|
|
40
|
-
? config.appLoc
|
|
41
|
-
? config.appLoc.replace(/\/?$/, '/') + sasJob.replace(/^\//, '')
|
|
42
|
-
: sasJob
|
|
43
|
-
: sasJob
|
|
44
|
-
let apiUrl = `${config.serverUrl}${this.jobsPath}/?${'_program=' + program}`
|
|
45
|
-
|
|
46
|
-
const requestParams = this.getRequestParams(config)
|
|
47
|
-
|
|
48
|
-
const requestPromise = new Promise((resolve, reject) => {
|
|
49
|
-
this.requestClient!.post(
|
|
50
|
-
apiUrl,
|
|
51
|
-
{ ...requestParams, ...data },
|
|
52
|
-
authConfig?.access_token
|
|
53
|
-
)
|
|
54
|
-
.then(async (res: any) => {
|
|
55
|
-
const parsedSasjsServerLog = res.result.log
|
|
56
|
-
.map((logLine: any) => logLine.line)
|
|
57
|
-
.join('\n')
|
|
58
|
-
|
|
59
|
-
const resObj = {
|
|
60
|
-
result: res.result._webout,
|
|
61
|
-
log: parsedSasjsServerLog
|
|
62
|
-
}
|
|
63
|
-
this.requestClient!.appendRequest(resObj, sasJob, config.debug)
|
|
64
|
-
|
|
65
|
-
let jsonResponse = res.result
|
|
66
|
-
|
|
67
|
-
if (config.debug) {
|
|
68
|
-
if (typeof res.result._webout === 'object') {
|
|
69
|
-
jsonResponse = res.result._webout
|
|
70
|
-
} else {
|
|
71
|
-
const webout = parseWeboutResponse(res.result._webout, apiUrl)
|
|
72
|
-
jsonResponse = getValidJson(webout)
|
|
73
|
-
}
|
|
74
|
-
} else {
|
|
75
|
-
jsonResponse = getValidJson(res.result._webout)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const responseObject = appendExtraResponseAttributes(
|
|
79
|
-
{ result: jsonResponse },
|
|
80
|
-
extraResponseAttributes
|
|
81
|
-
)
|
|
82
|
-
resolve(responseObject)
|
|
83
|
-
})
|
|
84
|
-
.catch(async (e: Error) => {
|
|
85
|
-
if (e instanceof JobExecutionError) {
|
|
86
|
-
this.requestClient!.appendRequest(e, sasJob, config.debug)
|
|
87
|
-
reject(new ErrorResponse(e?.message, e))
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (e instanceof LoginRequiredError) {
|
|
91
|
-
this.appendWaitingRequest(() => {
|
|
92
|
-
return this.execute(
|
|
93
|
-
sasJob,
|
|
94
|
-
data,
|
|
95
|
-
config,
|
|
96
|
-
loginRequiredCallback,
|
|
97
|
-
authConfig,
|
|
98
|
-
extraResponseAttributes
|
|
99
|
-
).then(
|
|
100
|
-
(res: any) => {
|
|
101
|
-
resolve(res)
|
|
102
|
-
},
|
|
103
|
-
(err: any) => {
|
|
104
|
-
reject(err)
|
|
105
|
-
}
|
|
106
|
-
)
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
await loginCallback()
|
|
110
|
-
} else {
|
|
111
|
-
reject(new ErrorResponse(e?.message, e))
|
|
112
|
-
}
|
|
113
|
-
})
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
return requestPromise
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
private getRequestParams(config: any): any {
|
|
120
|
-
const requestParams: any = {}
|
|
121
|
-
|
|
122
|
-
if (config.debug) {
|
|
123
|
-
requestParams['_omittextlog'] = 'false'
|
|
124
|
-
requestParams['_omitsessionresults'] = 'false'
|
|
125
|
-
|
|
126
|
-
requestParams['_debug'] = 131
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return requestParams
|
|
130
|
-
}
|
|
131
|
-
}
|