@sasjs/adapter 3.2.1 → 3.4.1
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/.gitpod.yml +2 -0
- package/README.md +86 -8
- package/SASjs.d.ts +10 -2
- package/index.js +2 -2
- package/node/SASjs.d.ts +10 -2
- package/node/index.js +2 -2
- package/node/utils/convertToCsv.d.ts +5 -1
- package/package.json +35 -35
- package/src/SASjs.ts +8 -3
- package/src/SessionManager.ts +1 -1
- package/src/api/viya/pollJobState.ts +4 -3
- package/src/request/RequestClient.ts +9 -6
- package/src/request/SasjsRequestClient.ts +1 -1
- package/src/test/SAS_server_app.ts +1 -0
- package/src/utils/convertToCsv.ts +108 -52
- package/src/utils/formatDataForRequest.ts +10 -1
- package/test/utils/formatDataForRequest.spec.d.ts +1 -0
- package/utils/convertToCsv.d.ts +5 -1
package/.gitpod.yml
ADDED
package/README.md
CHANGED
|
@@ -142,6 +142,71 @@ The response object will contain returned tables and columns. Table names are a
|
|
|
142
142
|
|
|
143
143
|
The adapter will also cache the logs (if debug enabled) and even the work tables. For performance, it is best to keep debug mode off.
|
|
144
144
|
|
|
145
|
+
### Variable Types
|
|
146
|
+
|
|
147
|
+
The SAS type (char/numeric) of the values is determined according to a set of rules:
|
|
148
|
+
|
|
149
|
+
* If the values are numeric, the SAS type is numeric
|
|
150
|
+
* If the values are all string, the SAS type is character
|
|
151
|
+
* If the values contain a single character (a-Z + underscore) AND a numeric, then the SAS type is numeric (with special missing values).
|
|
152
|
+
* `null` is set to either '.' or '' depending on the assigned or derived type per the above rules. If entire column is `null` then the type will be numeric.
|
|
153
|
+
|
|
154
|
+
The following table illustrates the formats applied to columns under various scenarios:
|
|
155
|
+
|
|
156
|
+
|JS Values |SAS Format|
|
|
157
|
+
|---|---|
|
|
158
|
+
|'a', 'a' |$char1.|
|
|
159
|
+
|0, '_' |best.|
|
|
160
|
+
|'Z', 0 |best.|
|
|
161
|
+
|'a', 'aaa' |$char3.|
|
|
162
|
+
|null, 'a', 'aaa' | $char3.|
|
|
163
|
+
|null, 'a', 0 | best.|
|
|
164
|
+
|null, null | best.|
|
|
165
|
+
|null, '' | $char1.|
|
|
166
|
+
|null, 'a' | $char1.|
|
|
167
|
+
|'a' | $char1.|
|
|
168
|
+
|'a', null | $char1.|
|
|
169
|
+
|'a', null, 0 | best.|
|
|
170
|
+
|
|
171
|
+
Validation is also performed on the values. The following combinations will throw errors:
|
|
172
|
+
|
|
173
|
+
|JS Values |SAS Format|
|
|
174
|
+
|---|---|
|
|
175
|
+
|null, 'aaaa', 0 | Error: mixed types. 'aaaa' is not a special missing value.|
|
|
176
|
+
|0, 'a', '!' | Error: mixed types. '!' is not a special missing value|
|
|
177
|
+
|1.1, '.', 0| Error: mixed types. For regular nulls, use `null`|
|
|
178
|
+
|
|
179
|
+
### Variable Format Override
|
|
180
|
+
The auto-detect functionality above is thwarted in the following scenarios:
|
|
181
|
+
|
|
182
|
+
* A character column containing only `null` values (is considered numeric)
|
|
183
|
+
* A numeric column containing only special missing values (is considered character)
|
|
184
|
+
|
|
185
|
+
To cater for these scenarios, an optional array of formats can be passed along with the data to ensure that SAS will read them in correctly.
|
|
186
|
+
|
|
187
|
+
To understand these formats, it should be noted that the JSON data is NOT passed directly (as JSON) to SAS. It is first converted into CSV, and the header row is actually an `infile` statement in disguise. It looks a bit like this:
|
|
188
|
+
|
|
189
|
+
```csv
|
|
190
|
+
CHARVAR1:$char4. CHARVAR2:$char1. NUMVAR:best.
|
|
191
|
+
LOAD,,0
|
|
192
|
+
ABCD,X,.
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
To provide overrides to this header row, the tables object can be constructed as follows (with a leading '$' in the table name):
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
let specialData={
|
|
199
|
+
"tablewith2cols2rows": [
|
|
200
|
+
{"col1": "val1","specialMissingsCol": "A"},
|
|
201
|
+
{"col1": "val2","specialMissingsCol": "_"}
|
|
202
|
+
],
|
|
203
|
+
"$tablewith2cols2rows":{"formats":{"specialMissingsCol":"best."}
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
It is not necessary to provide formats for ALL the columns, only the ones that need to be overridden.
|
|
209
|
+
|
|
145
210
|
## SAS Inputs / Outputs
|
|
146
211
|
|
|
147
212
|
The SAS side is handled by a number of macros in the [macro core](https://github.com/sasjs/core) library.
|
|
@@ -153,16 +218,29 @@ The following snippet shows the process of SAS tables arriving / leaving:
|
|
|
153
218
|
%webout(FETCH)
|
|
154
219
|
|
|
155
220
|
/* some sas code */
|
|
156
|
-
data
|
|
221
|
+
data a b c;
|
|
157
222
|
set from js;
|
|
158
223
|
run;
|
|
159
224
|
|
|
160
|
-
%webout(OPEN) /*
|
|
161
|
-
%webout(OBJ,
|
|
162
|
-
%webout(ARR,
|
|
163
|
-
%webout(OBJ,
|
|
164
|
-
%webout(OBJ,
|
|
165
|
-
%webout(CLOSE) /*
|
|
225
|
+
%webout(OPEN) /* Open the JSON to be returned */
|
|
226
|
+
%webout(OBJ,a) /* Rows in table `a` are objects (easy to use) */
|
|
227
|
+
%webout(ARR,b) /* Rows in table `b` are arrays (compact) */
|
|
228
|
+
%webout(OBJ,c,fmt=N) /* Table `c` is sent unformatted (raw) */
|
|
229
|
+
%webout(OBJ,c,label=d) /* Rename as `d` on JS side */
|
|
230
|
+
%webout(CLOSE) /* Close the JSON and add default variables */
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
By default, special SAS numeric missings (_a-Z) are converted to `null` in the JSON. If you'd like to preserve these, use the `missing=STRING` option as follows:
|
|
234
|
+
|
|
235
|
+
```sas
|
|
236
|
+
%webout(OBJ,a,missing=STRING)
|
|
237
|
+
```
|
|
238
|
+
In this case, special missings (such as `.a`, `.b`) are converted to javascript string values (`'A', 'B'`).
|
|
239
|
+
|
|
240
|
+
Where an entire column is made up of special missing numerics, there would be no way to distinguish it from a single-character column by looking at the values. To cater for this scenario, it is possible to export the variable types (and other attributes such as label and format) by adding a `showmeta` param to the `webout()` macro as follows:
|
|
241
|
+
|
|
242
|
+
```sas
|
|
243
|
+
%webout(OBJ,a,missing=STRING,showmeta=YES)
|
|
166
244
|
```
|
|
167
245
|
|
|
168
246
|
## Configuration
|
|
@@ -170,7 +248,7 @@ run;
|
|
|
170
248
|
Configuration on the client side involves passing an object on startup, which can also be passed with each request. Technical documentation on the SASjsConfig class is available [here](https://adapter.sasjs.io/classes/types.sasjsconfig.html). The main config items are:
|
|
171
249
|
|
|
172
250
|
* `appLoc` - this is the folder under which the SAS services will be created.
|
|
173
|
-
* `serverType` - either `SAS9` or `
|
|
251
|
+
* `serverType` - either `SAS9`, `SASVIYA` or `SASJS`. The `SASJS` server type is for use with [sasjs/server](https://github.com/sasjs/server).
|
|
174
252
|
* `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.
|
|
175
253
|
* `debug` - if `true` then SAS Logs and extra debug information is returned.
|
|
176
254
|
* `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.
|
package/SASjs.d.ts
CHANGED
|
@@ -89,7 +89,11 @@ export default class SASjs {
|
|
|
89
89
|
* @param accessToken - an access token for an authorized user.
|
|
90
90
|
*/
|
|
91
91
|
deleteComputeContext(contextName: string, accessToken?: string): Promise<{
|
|
92
|
-
result: import("./types").Context;
|
|
92
|
+
result: import("./types").Context; /**
|
|
93
|
+
* Returns a JSON representation of a compute context.
|
|
94
|
+
* @param contextId - an id of the context to return.
|
|
95
|
+
* @param accessToken - an access token for an authorized user.
|
|
96
|
+
*/
|
|
93
97
|
etag: string;
|
|
94
98
|
}>;
|
|
95
99
|
/**
|
|
@@ -221,7 +225,11 @@ export default class SASjs {
|
|
|
221
225
|
* Logs out of the configured SAS server.
|
|
222
226
|
*/
|
|
223
227
|
logOut(): Promise<boolean | {
|
|
224
|
-
result: unknown;
|
|
228
|
+
result: unknown; /**
|
|
229
|
+
* Returns a JSON representation of a compute context.
|
|
230
|
+
* @param contextId - an id of the context to return.
|
|
231
|
+
* @param accessToken - an access token for an authorized user.
|
|
232
|
+
*/
|
|
225
233
|
etag: string;
|
|
226
234
|
}>;
|
|
227
235
|
/**
|