@sasjs/utils 3.5.8 → 3.6.0
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/.github/workflows/publish.yml +53 -8
- package/auth/auth.js +38 -4
- package/auth/auth.js.map +1 -1
- package/macros/mf_getschema.sas +2 -1
- package/macros/mf_getvalue.sas +27 -8
- package/macros/mf_wordsinstr1andstr2.sas +12 -17
- package/macros/mf_wordsinstr1butnotstr2.sas +13 -18
- package/macros/mp_assert.sas +2 -1
- package/macros/mp_assertcols.sas +1 -1
- package/macros/mp_assertcolvals.sas +1 -1
- package/macros/mp_assertdsobs.sas +1 -1
- package/macros/mp_assertscope.sas +3 -2
- package/macros/mp_ds2csv.sas +2 -2
- package/macros/mp_hashdataset.sas +7 -7
- package/macros/mp_init.sas +3 -1
- package/macros/mp_loadformat.sas +13 -4
- package/macros/mp_md5.sas +5 -0
- package/macros/mp_retainedkey.sas +6 -5
- package/macros/mp_rowhash.sas +90 -0
- package/macros/mp_validatecol.sas +15 -1
- package/package.json +27 -3
- package/types/config.d.ts +10 -2
- package/types/targetValidators.js.map +1 -1
- package/.github/reviewer-lottery.yml +0 -12
- package/.github/workflows/assign-reviewer.yml +0 -13
|
@@ -9,26 +9,71 @@ on:
|
|
|
9
9
|
- main
|
|
10
10
|
|
|
11
11
|
jobs:
|
|
12
|
-
|
|
12
|
+
build:
|
|
13
13
|
runs-on: ubuntu-latest
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write
|
|
16
|
+
id-token: write # required for npm provenance (trusted publisher)
|
|
17
|
+
issues: write # optional: lets @semantic-release/github comment on issues
|
|
18
|
+
pull-requests: write # optional: lets @semantic-release/github comment on PRs
|
|
19
|
+
|
|
20
|
+
strategy:
|
|
21
|
+
matrix:
|
|
22
|
+
node-version: [22]
|
|
23
|
+
|
|
14
24
|
steps:
|
|
15
|
-
-
|
|
16
|
-
|
|
25
|
+
# Mint a short-lived GitHub App token (bypass-capable)
|
|
26
|
+
- name: Generate token
|
|
27
|
+
id: app-token
|
|
28
|
+
uses: actions/create-github-app-token@v1
|
|
29
|
+
with:
|
|
30
|
+
app-id: ${{ secrets.APP_ID }}
|
|
31
|
+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
|
|
32
|
+
|
|
33
|
+
# Checkout using the app token so the release commit can be pushed
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
with:
|
|
36
|
+
token: ${{ steps.app-token.outputs.token }}
|
|
37
|
+
persist-credentials: true
|
|
38
|
+
fetch-depth: 0 # semantic-release needs full history + tags
|
|
39
|
+
|
|
40
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
41
|
+
uses: actions/setup-node@v4
|
|
42
|
+
with:
|
|
43
|
+
node-version: ${{ matrix.node-version }}
|
|
44
|
+
registry-url: https://registry.npmjs.org
|
|
45
|
+
|
|
46
|
+
# Node 22 ships npm 10.x — OIDC trusted publishing needs npm >= 11.5.1
|
|
47
|
+
- name: Update npm
|
|
48
|
+
run: npm install -g npm@latest
|
|
49
|
+
|
|
50
|
+
# Restore npm cache manually
|
|
51
|
+
- name: Restore npm cache
|
|
52
|
+
uses: actions/cache@v4
|
|
53
|
+
id: npm-cache
|
|
54
|
+
with:
|
|
55
|
+
path: ~/.npm
|
|
56
|
+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
57
|
+
restore-keys: |
|
|
58
|
+
${{ runner.os }}-node-
|
|
17
59
|
|
|
18
60
|
- name: Install Dependencies
|
|
19
61
|
run: npm ci
|
|
20
62
|
|
|
21
|
-
- name: Check
|
|
63
|
+
- name: Check code style
|
|
22
64
|
run: npm run lint
|
|
23
65
|
|
|
24
66
|
- name: Build Project
|
|
25
67
|
run: npm run build
|
|
26
68
|
|
|
27
|
-
- name:
|
|
69
|
+
- name: Clean up ready for publishing
|
|
28
70
|
run: npm run publishInit
|
|
29
71
|
|
|
30
72
|
- name: Semantic Release
|
|
31
|
-
|
|
73
|
+
run: npx semantic-release
|
|
32
74
|
env:
|
|
33
|
-
GITHUB_TOKEN: ${{
|
|
34
|
-
|
|
75
|
+
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} # <-- app token, not secrets.GITHUB_TOKEN
|
|
76
|
+
|
|
77
|
+
- name: Publish to npm with trusted publisher
|
|
78
|
+
if: success()
|
|
79
|
+
run: npm publish --access public
|
package/auth/auth.js
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
4
20
|
};
|
|
5
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
22
|
exports.decodeToken = exports.hasTokenExpired = exports.isRefreshTokenExpiring = exports.isAccessTokenExpiring = void 0;
|
|
7
|
-
const jwt_decode_1 =
|
|
23
|
+
const jwt_decode_1 = __importStar(require("jwt-decode"));
|
|
8
24
|
/**
|
|
9
25
|
* Checks if the Access Token is expired or is expiring in 1 hour. A default Access Token
|
|
10
26
|
* lasts 12 hours. If the Access Token expires, the Refresh Token is used to fetch a new
|
|
@@ -50,7 +66,25 @@ function hasTokenExpired(token) {
|
|
|
50
66
|
}
|
|
51
67
|
exports.hasTokenExpired = hasTokenExpired;
|
|
52
68
|
function isTokenExpiring(token, timeToLiveSeconds) {
|
|
53
|
-
|
|
69
|
+
let payload;
|
|
70
|
+
try {
|
|
71
|
+
payload = (0, jwt_decode_1.default)(token);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
// Only tolerate undecodable (opaque / non-JWT) tokens - anything else
|
|
75
|
+
// is a genuine bug and should surface.
|
|
76
|
+
if (!(err instanceof jwt_decode_1.InvalidTokenError))
|
|
77
|
+
throw err;
|
|
78
|
+
// Opaque tokens cannot be expiry-checked client-side.
|
|
79
|
+
// Assume the token is usable and let the server reject it if expired.
|
|
80
|
+
console.debug('isTokenExpiring: token is not a decodable JWT, treating it as not expiring.');
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
// A JWT without an `exp` claim cannot be expiry-checked either.
|
|
84
|
+
// Note: `== null` (not `!`) - exp of 0 is a real (long-expired) claim,
|
|
85
|
+
// not a missing one.
|
|
86
|
+
if (payload.exp == null)
|
|
87
|
+
return false;
|
|
54
88
|
const timeToLive = payload.exp - new Date().valueOf() / 1000;
|
|
55
89
|
return timeToLive <= timeToLiveSeconds;
|
|
56
90
|
}
|
package/auth/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth/auth.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,yDAAyD;AAGzD;;;;;;;;GAQG;AACH,SAAgB,qBAAqB,CACnC,KAAc,EACd,iBAAiB,GAAG,IAAI;IAExB,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,eAAe,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAA;AAClD,CAAC;AARD,sDAQC;AAED;;;;;;;;GAQG;AACH,SAAgB,sBAAsB,CACpC,KAAc,EACd,iBAAiB,GAAG,EAAE;IAEtB,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,eAAe,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAA;AAClD,CAAC;AARD,wDAQC;AAED;;;;GAIG;AACH,SAAgB,eAAe,CAAC,KAAc;IAC5C,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,IAAI,CAAA;KACZ;IACD,OAAO,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;AAClC,CAAC;AALD,0CAKC;AAED,SAAS,eAAe,CAAC,KAAa,EAAE,iBAAyB;IAC/D,IAAI,OAAyB,CAAA;IAC7B,IAAI;QACF,OAAO,GAAG,IAAA,oBAAS,EAAmB,KAAK,CAAC,CAAA;KAC7C;IAAC,OAAO,GAAG,EAAE;QACZ,sEAAsE;QACtE,uCAAuC;QACvC,IAAI,CAAC,CAAC,GAAG,YAAY,8BAAiB,CAAC;YAAE,MAAM,GAAG,CAAA;QAClD,sDAAsD;QACtD,sEAAsE;QACtE,OAAO,CAAC,KAAK,CACX,6EAA6E,CAC9E,CAAA;QACD,OAAO,KAAK,CAAA;KACb;IAED,gEAAgE;IAChE,uEAAuE;IACvE,qBAAqB;IACrB,IAAI,OAAO,CAAC,GAAG,IAAI,IAAI;QAAE,OAAO,KAAK,CAAA;IAErC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,CAAA;IAE5D,OAAO,UAAU,IAAI,iBAAiB,CAAA;AACxC,CAAC;AAED,SAAgB,WAAW,CAAC,KAAa;IACvC,IAAI,OAAqB,CAAA;IACzB,IAAI;QACF,OAAO,GAAG,IAAA,oBAAS,EAAC,KAAK,CAAC,CAAA;KAC3B;IAAC,OAAO,GAAG,EAAE;QACZ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAA;KAC3C;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AATD,kCASC"}
|
package/macros/mf_getschema.sas
CHANGED
|
@@ -25,8 +25,9 @@
|
|
|
25
25
|
%local dsid vnum rc schema;
|
|
26
26
|
/* in case the parameter is a libref.tablename, pull off just the libref */
|
|
27
27
|
%let libref = %upcase(%scan(&libref, 1, %str(.)));
|
|
28
|
+
/* sysname can be 'Schema/Owner' or just 'Schema' (eg snowflake) */
|
|
28
29
|
%let dsid=%sysfunc(open(sashelp.vlibnam(where=(
|
|
29
|
-
libname="%upcase(&libref)" and sysname
|
|
30
|
+
libname="%upcase(&libref)" and sysname=:'Schema'
|
|
30
31
|
)),i));
|
|
31
32
|
%if (&dsid ^= 0) %then %do;
|
|
32
33
|
%let vnum=%sysfunc(varnum(&dsid,SYSVALUE));
|
package/macros/mf_getvalue.sas
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
@file
|
|
3
|
-
@brief Retrieves a value from a dataset.
|
|
4
|
-
|
|
3
|
+
@brief Retrieves a value from a dataset. Returned value is fetched from the
|
|
4
|
+
'fetchobs=' record (row 1 by default), after applying the optional filter.
|
|
5
|
+
|
|
5
6
|
@details Be sure to <code>%quote()</code> your where clause. Example usage:
|
|
6
7
|
|
|
7
8
|
%put %mf_getvalue(sashelp.class,name,filter=%quote(age=15));
|
|
@@ -16,21 +17,39 @@
|
|
|
16
17
|
@param [in] libds dataset to query
|
|
17
18
|
@param [in] variable the variable which contains the value to return.
|
|
18
19
|
@param [in] filter= (1) contents of where clause
|
|
20
|
+
@param [in] fetchobs= (1) observation to fetch. NB: Filter applies first.
|
|
19
21
|
|
|
20
22
|
@version 9.2
|
|
21
23
|
@author Allan Bowe
|
|
22
24
|
**/
|
|
23
25
|
|
|
24
|
-
%macro mf_getvalue(libds,variable,filter=1
|
|
26
|
+
%macro mf_getvalue(libds,variable,filter=1,fetchobs=1
|
|
25
27
|
)/*/STORE SOURCE*/;
|
|
26
|
-
%
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
%local dsid;
|
|
29
|
+
|
|
30
|
+
%let dsid=%sysfunc(open(&libds(where=(&filter))));
|
|
31
|
+
%if (&dsid) %then %do;
|
|
32
|
+
%local rc &variable;
|
|
29
33
|
%syscall set(dsid);
|
|
30
|
-
%let rc = %sysfunc(
|
|
34
|
+
%let rc = %sysfunc(fetchobs(&dsid,&fetchobs));
|
|
35
|
+
%if (&rc ne 0) %then %do;
|
|
36
|
+
%put NOTE: Problem reading obs &fetchobs from &libds..;
|
|
37
|
+
%put %sysfunc(sysmsg());
|
|
38
|
+
/* Coerce an rc value of -1 (read past end of data) to a 4
|
|
39
|
+
that, in SAS condition code terms, represents the sysmsg
|
|
40
|
+
w@rning it generates. */
|
|
41
|
+
%if &rc eq -1 %then %let rc = 4;
|
|
42
|
+
/* And update SYSCC if the &rc value is higher */
|
|
43
|
+
%let syscc = %sysfunc(max(&syscc,&rc));
|
|
44
|
+
%end;
|
|
31
45
|
%let rc = %sysfunc(close(&dsid));
|
|
32
46
|
|
|
33
47
|
%trim(&&&variable)
|
|
34
48
|
|
|
35
49
|
%end;
|
|
36
|
-
%
|
|
50
|
+
%else %do;
|
|
51
|
+
%put %sysfunc(sysmsg());
|
|
52
|
+
%let syscc = %sysfunc(max(&syscc,%sysfunc(sysrc())));
|
|
53
|
+
%end;
|
|
54
|
+
|
|
55
|
+
%mend mf_getvalue;
|
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
@brief Returns words that are in both string 1 and string 2
|
|
4
4
|
@details Compares two space separated strings and returns the words that are
|
|
5
5
|
in both.
|
|
6
|
+
|
|
7
|
+
If either string is empty, nothing is returned.
|
|
8
|
+
|
|
6
9
|
Usage:
|
|
7
10
|
|
|
8
|
-
%put %
|
|
11
|
+
%put %mf_wordsinstr1andstr2(
|
|
9
12
|
Str1=blah sss blaaah brah bram boo
|
|
10
13
|
,Str2= blah blaaah brah ssss
|
|
11
14
|
);
|
|
@@ -23,31 +26,23 @@
|
|
|
23
26
|
|
|
24
27
|
**/
|
|
25
28
|
|
|
26
|
-
%macro
|
|
29
|
+
%macro mf_wordsinstr1andstr2(
|
|
27
30
|
Str1= /* string containing words to extract */
|
|
28
31
|
,Str2= /* used to compare with the extract string */
|
|
29
32
|
)/*/STORE SOURCE*/;
|
|
30
33
|
|
|
31
|
-
%local
|
|
34
|
+
%local count_extr i extr_word outvar;
|
|
32
35
|
%if %length(&str1)=0 or %length(&str2)=0 %then %do;
|
|
33
|
-
%put
|
|
34
|
-
%put compare string (str2) = &str2;
|
|
36
|
+
%put &sysmacroname: empty input string, nothing to compare;
|
|
35
37
|
%return;
|
|
36
38
|
%end;
|
|
37
|
-
%let count_base=%sysfunc(countw(&Str2));
|
|
38
39
|
%let count_extr=%sysfunc(countw(&Str1));
|
|
39
40
|
|
|
40
41
|
%do i=1 %to &count_extr;
|
|
41
42
|
%let extr_word=%scan(&Str1,&i,%str( ));
|
|
42
|
-
%
|
|
43
|
-
|
|
44
|
-
%let base_word=%scan(&Str2,&i2,%str( ));
|
|
45
|
-
%if &extr_word=&base_word %then %let match=1;
|
|
46
|
-
%end;
|
|
47
|
-
%if &match=1 %then %let outvar=&outvar &extr_word;
|
|
43
|
+
%if %sysfunc(indexw(%superq(str2),%superq(extr_word)))>0 %then
|
|
44
|
+
%let outvar=&outvar &extr_word;
|
|
48
45
|
%end;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
%mend mf_wordsInStr1andStr2;
|
|
53
|
-
|
|
46
|
+
/* send out the result without any surrounding whitespace */
|
|
47
|
+
%do;&outvar%end;
|
|
48
|
+
%mend mf_wordsinstr1andstr2;
|
|
@@ -6,9 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
Note - case sensitive!
|
|
8
8
|
|
|
9
|
+
If str1 is empty, nothing is returned. If str2 is empty, all the words in
|
|
10
|
+
str1 are returned.
|
|
11
|
+
|
|
9
12
|
Usage:
|
|
10
13
|
|
|
11
|
-
%let x= %
|
|
14
|
+
%let x= %mf_wordsinstr1butnotstr2(
|
|
12
15
|
Str1=blah sss blaaah brah bram boo
|
|
13
16
|
,Str2= blah blaaah brah ssss
|
|
14
17
|
);
|
|
@@ -24,31 +27,23 @@
|
|
|
24
27
|
|
|
25
28
|
**/
|
|
26
29
|
|
|
27
|
-
%macro
|
|
30
|
+
%macro mf_wordsinstr1butnotstr2(
|
|
28
31
|
Str1= /* string containing words to extract */
|
|
29
32
|
,Str2= /* used to compare with the extract string */
|
|
30
33
|
)/*/STORE SOURCE*/;
|
|
31
34
|
|
|
32
|
-
%local
|
|
33
|
-
%if %length(&str1)=0
|
|
34
|
-
%put
|
|
35
|
-
%put compare string (str2) = &str2;
|
|
35
|
+
%local count_extr i extr_word outvar;
|
|
36
|
+
%if %length(&str1)=0 %then %do;
|
|
37
|
+
%put &sysmacroname: str1 is empty, nothing to compare;
|
|
36
38
|
%return;
|
|
37
39
|
%end;
|
|
38
|
-
%let count_base=%sysfunc(countw(&Str2));
|
|
39
40
|
%let count_extr=%sysfunc(countw(&Str1));
|
|
40
41
|
|
|
41
42
|
%do i=1 %to &count_extr;
|
|
42
43
|
%let extr_word=%scan(&Str1,&i,%str( ));
|
|
43
|
-
%
|
|
44
|
-
|
|
45
|
-
%let base_word=%scan(&Str2,&i2,%str( ));
|
|
46
|
-
%if &extr_word=&base_word %then %let match=1;
|
|
47
|
-
%end;
|
|
48
|
-
%if &match=0 %then %let outvar=&outvar &extr_word;
|
|
44
|
+
%if %sysfunc(indexw(%superq(str2),%superq(extr_word)))=0 %then
|
|
45
|
+
%let outvar=&outvar &extr_word;
|
|
49
46
|
%end;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
%mend mf_wordsInStr1ButNotStr2;
|
|
54
|
-
|
|
47
|
+
/* send out the result without any surrounding whitespace */
|
|
48
|
+
%do;&outvar%end;
|
|
49
|
+
%mend mf_wordsinstr1butnotstr2;
|
package/macros/mp_assert.sas
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
)/*/STORE SOURCE*/;
|
|
36
36
|
|
|
37
37
|
data ;
|
|
38
|
-
length
|
|
38
|
+
length test_result $4 test_description $256 test_comments $256;
|
|
39
39
|
test_description=symget('desc');
|
|
40
40
|
test_comments="&sysmacroname: Test result of "!!symget('iftrue');
|
|
41
41
|
%if %eval(%unquote(&iftrue)) %then %do;
|
|
@@ -52,5 +52,6 @@
|
|
|
52
52
|
run;
|
|
53
53
|
proc sql;
|
|
54
54
|
drop table &ds;
|
|
55
|
+
quit;
|
|
55
56
|
|
|
56
57
|
%mend mp_assert;
|
package/macros/mp_assertcols.sas
CHANGED
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
%end;
|
|
109
109
|
|
|
110
110
|
data;
|
|
111
|
-
length
|
|
111
|
+
length test_result $4 test_description $256 test_comments $256;
|
|
112
112
|
test_description=symget('desc');
|
|
113
113
|
if test_description='0'
|
|
114
114
|
then test_description="Testing &inds for existence of &test of: &cols";
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
)
|
|
144
144
|
|
|
145
145
|
data;
|
|
146
|
-
length
|
|
146
|
+
length test_result $4 test_description $256 test_comments $256;
|
|
147
147
|
test_description=symget('desc');
|
|
148
148
|
test_result='FAIL';
|
|
149
149
|
test_comments="&sysmacroname: &lib..&ds..&col has &result/&orig values "
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
%end;
|
|
88
88
|
|
|
89
89
|
data &ds;
|
|
90
|
-
length
|
|
90
|
+
length test_result $4 test_description $256 test_comments $256;
|
|
91
91
|
test_description=symget('desc');
|
|
92
92
|
test_result='FAIL';
|
|
93
93
|
test_comments="&sysmacroname: Dataset &inds has &nobs observations.";
|
|
@@ -92,6 +92,7 @@
|
|
|
92
92
|
from dictionary.macros
|
|
93
93
|
where scope="&scope" and upcase(name) not in (%mf_getquotedstr(&ilist))
|
|
94
94
|
order by name,offset;
|
|
95
|
+
quit;
|
|
95
96
|
%end;
|
|
96
97
|
%else %if &action=COMPARE %then %do;
|
|
97
98
|
|
|
@@ -129,9 +130,8 @@
|
|
|
129
130
|
%let test_comments=%str(Mod:(&mod) Add:(&add) Del:(&del));
|
|
130
131
|
%end;
|
|
131
132
|
|
|
132
|
-
|
|
133
133
|
data ;
|
|
134
|
-
length
|
|
134
|
+
length test_result $4 test_description $256 test_comments $256;
|
|
135
135
|
test_description=symget('desc');
|
|
136
136
|
test_comments=symget('test_comments');
|
|
137
137
|
test_result=symget('test_result');
|
|
@@ -142,6 +142,7 @@
|
|
|
142
142
|
run;
|
|
143
143
|
proc sql;
|
|
144
144
|
drop table &ds;
|
|
145
|
+
quit;
|
|
145
146
|
%end;
|
|
146
147
|
|
|
147
148
|
%mend mp_assertscope;
|
package/macros/mp_ds2csv.sas
CHANGED
|
@@ -130,10 +130,10 @@ data _null_;
|
|
|
130
130
|
* there is not much point importing a short length numeric like this,
|
|
131
131
|
* eg with best4., as the resulting variable will still be stored as
|
|
132
132
|
* length 8. We need a length or format statement to ensure variable
|
|
133
|
-
* is
|
|
133
|
+
* is created with the smaller length...
|
|
134
134
|
**/
|
|
135
135
|
else if vlen<8 then header=cats(varnm,':best',vlen,'.');
|
|
136
|
-
else header=cats(varnm,':
|
|
136
|
+
else header=cats(varnm,':best32.');
|
|
137
137
|
end;
|
|
138
138
|
%end;
|
|
139
139
|
%else %do;
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
@li mf_getattrn.sas
|
|
18
18
|
@li mf_getuniquename.sas
|
|
19
19
|
@li mf_getvarlist.sas
|
|
20
|
-
@li
|
|
20
|
+
@li mp_rowhash.sas
|
|
21
21
|
|
|
22
22
|
<h4> Related Files </h4>
|
|
23
23
|
@li mp_hashdataset.test.sas
|
|
@@ -46,8 +46,7 @@
|
|
|
46
46
|
|
|
47
47
|
%local keyvar /* roll up the md5 */
|
|
48
48
|
prevkeyvar /* retain prev record md5 */
|
|
49
|
-
lastvar /* last var in input ds
|
|
50
|
-
cvars nvars;
|
|
49
|
+
lastvar /* last var in input ds */;
|
|
51
50
|
|
|
52
51
|
%if not(%eval(%unquote(&iftrue))) %then %return;
|
|
53
52
|
|
|
@@ -79,10 +78,11 @@
|
|
|
79
78
|
retain &prevkeyvar;
|
|
80
79
|
if _n_=1 then &prevkeyvar=put(md5("&salt"),$hex32.);
|
|
81
80
|
set &libds end=&lastvar;
|
|
82
|
-
/* hash should include previous row */
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
/* hash should include previous row - listed first so it is hashed first */
|
|
82
|
+
%mp_rowhash(
|
|
83
|
+
md5_col=&keyvar
|
|
84
|
+
,cvars=&prevkeyvar %mf_getvarlist(&libds,typefilter=C)
|
|
85
|
+
,nvars=%mf_getvarlist(&libds,typefilter=N)
|
|
86
86
|
);
|
|
87
87
|
&prevkeyvar=&keyvar;
|
|
88
88
|
if &lastvar then output;
|
package/macros/mp_init.sas
CHANGED
|
@@ -37,12 +37,14 @@
|
|
|
37
37
|
|
|
38
38
|
%global
|
|
39
39
|
SASJS_PREFIX /* the ONLY hard-coded global macro variable in SASjs */
|
|
40
|
+
&prefix.PROCESSMODE &prefix._STPSRV_HEADER_LOC /* SASjs server specific vars*/
|
|
40
41
|
&prefix._FUNCTIONS /* used in mcf_init() to track core function compilation */
|
|
41
42
|
&prefix._INIT_NUM /* initialisation time as numeric */
|
|
42
43
|
&prefix._INIT_DTTM /* initialisation time in E8601DT26.6 format */
|
|
43
44
|
&prefix.WORK /* avoid typing %sysfunc(pathname(work)) every time */
|
|
45
|
+
&prefix.PROCESSMODE
|
|
46
|
+
&prefix._STPSRV_HEADER_LOC
|
|
44
47
|
;
|
|
45
|
-
|
|
46
48
|
%let sasjs_prefix=&prefix;
|
|
47
49
|
|
|
48
50
|
data _null_;
|
package/macros/mp_loadformat.sas
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
@li mp_aligndecimal.sas
|
|
46
46
|
@li mp_cntlout.sas
|
|
47
47
|
@li mp_lockanytable.sas
|
|
48
|
-
@li
|
|
48
|
+
@li mp_rowhash.sas
|
|
49
49
|
@li mp_storediffs.sas
|
|
50
50
|
|
|
51
51
|
<h4> Related Macros </h4>
|
|
@@ -174,14 +174,19 @@ select distinct
|
|
|
174
174
|
%let nvars=FMTROW MIN MAX DEFAULT LENGTH FUZZ MULT NOEDIT;
|
|
175
175
|
data &base_fmts/note2err;
|
|
176
176
|
set &base_fmts;
|
|
177
|
-
fmthash
|
|
177
|
+
length fmthash $32;
|
|
178
|
+
%mp_rowhash(
|
|
179
|
+
md5_col=fmthash
|
|
180
|
+
,cvars=&cvars
|
|
181
|
+
,nvars=&nvars
|
|
182
|
+
)
|
|
178
183
|
run;
|
|
179
184
|
|
|
180
185
|
/**
|
|
181
186
|
* Ensure input table and base_formats have consistent lengths and types
|
|
182
187
|
*/
|
|
183
188
|
data &inlibds/nonote2err;
|
|
184
|
-
length &delete_col $3 FMTROW 8 start end label $32767;
|
|
189
|
+
length &delete_col $3 FMTROW 8 start end label $32767 fmthash $32;
|
|
185
190
|
if 0 then set &base_fmts;
|
|
186
191
|
set &libds;
|
|
187
192
|
by type fmtname notsorted;
|
|
@@ -203,7 +208,11 @@ data &inlibds/nonote2err;
|
|
|
203
208
|
%mp_aligndecimal(end,width=16)
|
|
204
209
|
end;
|
|
205
210
|
|
|
206
|
-
|
|
211
|
+
%mp_rowhash(
|
|
212
|
+
md5_col=fmthash
|
|
213
|
+
,cvars=&cvars
|
|
214
|
+
,nvars=&nvars
|
|
215
|
+
)
|
|
207
216
|
run;
|
|
208
217
|
|
|
209
218
|
/**
|
package/macros/mp_md5.sas
CHANGED
|
@@ -28,11 +28,16 @@
|
|
|
28
28
|
@li Global option: `options dsoptions=nonote2err;`
|
|
29
29
|
@li Data step option: `data YOURLIB.YOURDATASET /nonote2err;`
|
|
30
30
|
|
|
31
|
+
For very wide tables (hundreds or thousands of columns) consider using
|
|
32
|
+
`mp_rowhash.sas`, which builds the same type of row hash iteratively and
|
|
33
|
+
avoids creating a single, very long concatenated SAS expression.
|
|
34
|
+
|
|
31
35
|
@param [in] cvars= () Space seperated list of character variables
|
|
32
36
|
@param [in] nvars= () Space seperated list of numeric variables
|
|
33
37
|
|
|
34
38
|
<h4> Related Programs </h4>
|
|
35
39
|
@li mp_init.sas
|
|
40
|
+
@li mp_rowhash.sas
|
|
36
41
|
|
|
37
42
|
@version 9.2
|
|
38
43
|
@author Allan Bowe
|
|
@@ -148,7 +148,8 @@
|
|
|
148
148
|
%mp_abort(iftrue=(&iserr=1),mac=mp_retainedkey,msg=%superq(msg))
|
|
149
149
|
|
|
150
150
|
proc sql noprint;
|
|
151
|
-
select sum(max(&retained_key),0) into: maxkey
|
|
151
|
+
select sum(max(&retained_key),0) format=32. into: maxkey trimmed
|
|
152
|
+
from &base_libds;
|
|
152
153
|
|
|
153
154
|
/**
|
|
154
155
|
* get base table RK and bus field values for lookup
|
|
@@ -217,19 +218,19 @@ quit;
|
|
|
217
218
|
insert into &maxkeytable
|
|
218
219
|
set keytable="&base_libds"
|
|
219
220
|
,keycolumn="&retained_key"
|
|
220
|
-
,max_key=%
|
|
221
|
+
,max_key=%sysevalf(&maxkey+&newkey_cnt)
|
|
221
222
|
,processed_dttm="%sysfunc(datetime(),%mf_fmtdttm())"dt;
|
|
222
223
|
%end;
|
|
223
224
|
%else %do;
|
|
224
225
|
update &maxkeytable
|
|
225
|
-
set max_key=%
|
|
226
|
+
set max_key=%sysevalf(&maxkey+&newkey_cnt)
|
|
226
227
|
,processed_dttm="%sysfunc(datetime(),%mf_fmtdttm())"dt
|
|
227
228
|
where keytable="&base_libds";
|
|
228
229
|
%end;
|
|
229
230
|
%mp_lockanytable(UNLOCK
|
|
230
231
|
,lib=%scan(&maxkeytable,1,.)
|
|
231
232
|
,ds=%scan(&maxkeytable,2,.)
|
|
232
|
-
,ref=Updating maxkeyvalues with maxkey=%
|
|
233
|
+
,ref=Updating maxkeyvalues with maxkey=%sysevalf(&maxkey+&newkey_cnt)
|
|
233
234
|
,ctl_ds=&locktable
|
|
234
235
|
)
|
|
235
236
|
%end;
|
|
@@ -237,7 +238,7 @@ quit;
|
|
|
237
238
|
/* fill in the missing retained key values */
|
|
238
239
|
%let tempvar=%mf_getuniquename();
|
|
239
240
|
data &outds(drop=&tempvar);
|
|
240
|
-
retain &tempvar %
|
|
241
|
+
retain &tempvar %sysevalf(&maxkey+1);
|
|
241
242
|
set &tempds2;
|
|
242
243
|
if &retained_key =. then &retained_key=&tempvar;
|
|
243
244
|
&tempvar=&tempvar+1;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@file
|
|
3
|
+
@brief Iterative row-level MD5 hash generator
|
|
4
|
+
@details Generates DATA step statements that compute a deterministic,
|
|
5
|
+
row-level MD5 hash using a Merkle-style construction. Each variable is
|
|
6
|
+
hashed independently and the resulting raw 16-byte digests are combined
|
|
7
|
+
iteratively. This avoids concatenating the per-variable hex digests into a
|
|
8
|
+
single SAS character expression, which overflows when datasets contain many
|
|
9
|
+
variables.
|
|
10
|
+
|
|
11
|
+
Temporary variables use five leading underscores.
|
|
12
|
+
|
|
13
|
+
This macro is called from inside a DATA step. The caller is responsible
|
|
14
|
+
for declaring the output hash column if it does not already exist on the
|
|
15
|
+
input dataset.
|
|
16
|
+
|
|
17
|
+
Variables are hashed in the order supplied. If a particular variable
|
|
18
|
+
needs to influence the hash first (for example the previous row hash in
|
|
19
|
+
`mp_hashdataset`, or business dates in Data Controller's bitemporal
|
|
20
|
+
loader) simply list it first in `cvars` or `nvars`.
|
|
21
|
+
|
|
22
|
+
@param [in] md5_col= Name of the output hash column.
|
|
23
|
+
@param [in] cvars= Space separated list of character variables to hash.
|
|
24
|
+
@param [in] nvars= Space separated list of numeric variables to hash.
|
|
25
|
+
|
|
26
|
+
@version 9.3M5
|
|
27
|
+
@author Allan Bowe
|
|
28
|
+
**/
|
|
29
|
+
|
|
30
|
+
%macro mp_rowhash(
|
|
31
|
+
md5_col=
|
|
32
|
+
,cvars=
|
|
33
|
+
,nvars=
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
/* DATA step temp variables use five leading underscores. The names
|
|
37
|
+
are generated at macro invocation to avoid clashing with data columns. */
|
|
38
|
+
%local state digest pair numtext normal i chars nums;
|
|
39
|
+
%let state=%mf_getuniquename(prefix=_____state_);
|
|
40
|
+
%let digest=%mf_getuniquename(prefix=_____digest_);
|
|
41
|
+
%let pair=%mf_getuniquename(prefix=_____pair_);
|
|
42
|
+
%let numtext=%mf_getuniquename(prefix=_____numtext_);
|
|
43
|
+
%let normal=%mf_getuniquename(prefix=_____normal_);
|
|
44
|
+
%let i=%mf_getuniquename(prefix=_____i_);
|
|
45
|
+
%let chars=%mf_getuniquename(prefix=_____chars_);
|
|
46
|
+
%let nums=%mf_getuniquename(prefix=_____nums_);
|
|
47
|
+
|
|
48
|
+
length &state $16
|
|
49
|
+
&digest $16
|
|
50
|
+
&pair $32
|
|
51
|
+
&numtext $64
|
|
52
|
+
&normal &i 8;
|
|
53
|
+
if _n_=1 then call missing(&state,&digest,&pair,&numtext,&normal,&i);
|
|
54
|
+
drop &state &digest &pair &numtext &normal &i;
|
|
55
|
+
|
|
56
|
+
/* Versioned seed prevents confusion with other hashing schemes. */
|
|
57
|
+
&state = md5('DC HASH v2');
|
|
58
|
+
|
|
59
|
+
%if %length(&cvars)>0 %then %do;
|
|
60
|
+
array &chars{*} $ &cvars;
|
|
61
|
+
do &i = 1 to dim(&chars);
|
|
62
|
+
/* Leading blanks are retained. */
|
|
63
|
+
&digest = md5(trimn(&chars[&i]));
|
|
64
|
+
substr(&pair, 1, 16) = &state;
|
|
65
|
+
substr(&pair, 17, 16) = &digest;
|
|
66
|
+
&state = md5(&pair);
|
|
67
|
+
end;
|
|
68
|
+
%end;
|
|
69
|
+
|
|
70
|
+
%if %length(&nvars)>0 %then %do;
|
|
71
|
+
array &nums{*} &nvars;
|
|
72
|
+
do &i = 1 to dim(&nums);
|
|
73
|
+
/*
|
|
74
|
+
multiply-by-one for consistent cross-system precision.
|
|
75
|
+
Ignore null to protect SAS special missing values.
|
|
76
|
+
Cannot use IFN() as it evaluates both sides
|
|
77
|
+
*/
|
|
78
|
+
if missing(&nums[&i]) then &normal = &nums[&i];
|
|
79
|
+
else &normal = &nums[&i] * 1;
|
|
80
|
+
&numtext = put(&normal, binary64.);
|
|
81
|
+
&digest = md5(trim(&numtext));
|
|
82
|
+
substr(&pair, 1, 16) = &state;
|
|
83
|
+
substr(&pair, 17, 16) = &digest;
|
|
84
|
+
&state = md5(&pair);
|
|
85
|
+
end;
|
|
86
|
+
%end;
|
|
87
|
+
|
|
88
|
+
&md5_col = put(&state, $hex32.);
|
|
89
|
+
|
|
90
|
+
%mend mp_rowhash;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
@file
|
|
3
|
-
@brief Used to validate
|
|
3
|
+
@brief Used to validate values in a data step
|
|
4
4
|
@details Useful when sanitising inputs, to ensure that they arrive with a
|
|
5
5
|
certain pattern.
|
|
6
6
|
Usage:
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
@param [in] incol The column to be validated
|
|
28
28
|
@param [in] rule The rule to apply. Current rules:
|
|
29
29
|
@li ISINT - checks if the variable is an integer
|
|
30
|
+
@li ISLIB - checks if the value is a valid libref (NOT whether it exists)
|
|
30
31
|
@li ISNUM - checks if the variable is numeric
|
|
31
32
|
@li LIBDS - matches LIBREF.DATASET format
|
|
32
33
|
@li FORMAT - checks if the provided format is syntactically valid
|
|
@@ -65,6 +66,19 @@
|
|
|
65
66
|
else &outcol=1;
|
|
66
67
|
drop &tempcol;
|
|
67
68
|
%end;
|
|
69
|
+
%else %if &rule=ISLIB %then %do;
|
|
70
|
+
if _n_=1 then do;
|
|
71
|
+
retain &tempcol;
|
|
72
|
+
&tempcol=prxparse('/^[_a-z]\w{0,7}$/i');
|
|
73
|
+
if missing(&tempcol) then do;
|
|
74
|
+
putlog 'ERR' +(-1) "OR: Invalid expression for ISLIB";
|
|
75
|
+
stop;
|
|
76
|
+
end;
|
|
77
|
+
drop &tempcol;
|
|
78
|
+
end;
|
|
79
|
+
if prxmatch(&tempcol, trim(&incol)) then &outcol=1;
|
|
80
|
+
else &outcol=0;
|
|
81
|
+
%end;
|
|
68
82
|
%else %if &rule=LIBDS %then %do;
|
|
69
83
|
/* match libref.dataset */
|
|
70
84
|
if _n_=1 then do;
|
package/package.json
CHANGED
|
@@ -7,6 +7,26 @@
|
|
|
7
7
|
"release": {
|
|
8
8
|
"branches": [
|
|
9
9
|
"main"
|
|
10
|
+
],
|
|
11
|
+
"plugins": [
|
|
12
|
+
"@semantic-release/commit-analyzer",
|
|
13
|
+
"@semantic-release/release-notes-generator",
|
|
14
|
+
[
|
|
15
|
+
"@semantic-release/exec",
|
|
16
|
+
{
|
|
17
|
+
"prepareCmd": "npm version ${nextRelease.version} --no-git-tag-version"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
[
|
|
21
|
+
"@semantic-release/git",
|
|
22
|
+
{
|
|
23
|
+
"assets": [
|
|
24
|
+
"package.json",
|
|
25
|
+
"package-lock.json"
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"@semantic-release/github"
|
|
10
30
|
]
|
|
11
31
|
},
|
|
12
32
|
"typings": "./index.d.ts",
|
|
@@ -19,7 +39,8 @@
|
|
|
19
39
|
"test": "jest --config=jest.config.js --coverage",
|
|
20
40
|
"lint:fix": "npx prettier --write \"{src,test}/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\"",
|
|
21
41
|
"lint": "npx prettier --check \"{src,test}/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\"",
|
|
22
|
-
"prepare": "git rev-parse --git-dir && git config core.hooksPath ./.git-hooks || true"
|
|
42
|
+
"prepare": "git rev-parse --git-dir && git config core.hooksPath ./.git-hooks || true",
|
|
43
|
+
"semantic-release": "semantic-release"
|
|
23
44
|
},
|
|
24
45
|
"repository": {
|
|
25
46
|
"type": "git",
|
|
@@ -32,7 +53,9 @@
|
|
|
32
53
|
},
|
|
33
54
|
"homepage": "https://github.com/sasjs/utils#readme",
|
|
34
55
|
"devDependencies": {
|
|
35
|
-
"@sasjs/core": "4.
|
|
56
|
+
"@sasjs/core": "4.68.1",
|
|
57
|
+
"@semantic-release/exec": "6.0.3",
|
|
58
|
+
"@semantic-release/git": "10.0.1",
|
|
36
59
|
"@types/cli-table": "0.3.0",
|
|
37
60
|
"@types/find": "0.2.1",
|
|
38
61
|
"@types/jest": "29.4.0",
|
|
@@ -40,6 +63,7 @@
|
|
|
40
63
|
"babel-jest": "29.4.3",
|
|
41
64
|
"jest": "29.4.3",
|
|
42
65
|
"jest-extended": "3.2.4",
|
|
66
|
+
"semantic-release": "25.0.8",
|
|
43
67
|
"ts-jest": "29.0.5",
|
|
44
68
|
"ts-loader": "9.2.6",
|
|
45
69
|
"ts-node": "10.9.1",
|
|
@@ -58,5 +82,5 @@
|
|
|
58
82
|
"prompts": "2.4.1",
|
|
59
83
|
"valid-url": "1.0.9"
|
|
60
84
|
},
|
|
61
|
-
"version": "3.
|
|
85
|
+
"version": "3.6.0"
|
|
62
86
|
}
|
package/types/config.d.ts
CHANGED
|
@@ -58,8 +58,16 @@ export interface StreamConfig {
|
|
|
58
58
|
export interface AuthConfig {
|
|
59
59
|
access_token: string;
|
|
60
60
|
refresh_token: string;
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
/**
|
|
62
|
+
* OAuth client ID. Optional: tokens minted without a registered client
|
|
63
|
+
* (e.g. via the password grant against the built-in public `sas.cli`
|
|
64
|
+
* client) have none. When absent, refresh falls back to `sas.cli`.
|
|
65
|
+
*/
|
|
66
|
+
client?: string;
|
|
67
|
+
/**
|
|
68
|
+
* OAuth client secret. Optional for the same reason as `client`.
|
|
69
|
+
*/
|
|
70
|
+
secret?: string;
|
|
63
71
|
}
|
|
64
72
|
export interface AuthConfigSas9 {
|
|
65
73
|
userName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"targetValidators.js","sourceRoot":"","sources":["../../src/types/targetValidators.ts"],"names":[],"mappings":";;;;;;AAAA,0DAAgC;AAChC,wBAAiD;AAcjD,MAAM,oBAAoB,GAAG,mCAAmC,CAAA;AAChE,MAAM,mBAAmB,GAAG,QAAQ,CAAA;AACpC,MAAM,uBAAuB,GAAG,YAAY,CAAA;AAE/B,QAAA,0BAA0B,GAAG,YAAY,CAAA;AACzC,QAAA,4BAA4B,GAAG,cAAc,CAAA;AAEnD,MAAM,kBAAkB,GAAG,CAAC,UAAe,EAAc,EAAE;IAChE,IAAI,CAAC,UAAU,EAAE;QACf,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAA;KACF;IAED,
|
|
1
|
+
{"version":3,"file":"targetValidators.js","sourceRoot":"","sources":["../../src/types/targetValidators.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
groups:
|
|
2
|
-
- name: SASjs Devs # name of the group
|
|
3
|
-
reviewers: 1 # how many reviewers do you want to assign?
|
|
4
|
-
usernames: # github usernames of the reviewers
|
|
5
|
-
# - krishna-acondy
|
|
6
|
-
- YuryShkoda
|
|
7
|
-
- medjedovicm
|
|
8
|
-
- sabhas
|
|
9
|
-
# - name: SASjs QA
|
|
10
|
-
# reviewers: 1
|
|
11
|
-
# usernames:
|
|
12
|
-
# - VladislavParhomchik
|