@sasjs/utils 2.48.2 → 2.49.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.
Files changed (163) hide show
  1. package/fs/generateCompileProgram.d.ts +1 -0
  2. package/fs/generateCompileProgram.js +154 -0
  3. package/fs/generateCompileProgram.js.map +1 -0
  4. package/fs/hash.d.ts +22 -0
  5. package/fs/hash.js +225 -0
  6. package/fs/hash.js.map +1 -0
  7. package/fs/index.d.ts +3 -0
  8. package/fs/index.js +13 -0
  9. package/fs/index.js.map +1 -0
  10. package/fs/internal/helper.d.ts +4 -0
  11. package/fs/internal/helper.js +125 -0
  12. package/fs/internal/helper.js.map +1 -0
  13. package/fs/sync.d.ts +6 -0
  14. package/fs/sync.js +208 -0
  15. package/fs/sync.js.map +1 -0
  16. package/index.d.ts +1 -0
  17. package/index.js +1 -0
  18. package/index.js.map +1 -1
  19. package/macros/mf_abort.sas +27 -0
  20. package/macros/mf_dedup.sas +53 -0
  21. package/macros/mf_deletefile.sas +31 -0
  22. package/macros/mf_existds.sas +30 -0
  23. package/macros/mf_existfeature.sas +59 -0
  24. package/macros/mf_existfileref.sas +33 -0
  25. package/macros/mf_existfunction.sas +37 -0
  26. package/macros/mf_existvar.sas +39 -0
  27. package/macros/mf_existvarlist.sas +56 -0
  28. package/macros/mf_fmtdttm.sas +42 -0
  29. package/macros/mf_getapploc.sas +78 -0
  30. package/macros/mf_getattrc.sas +34 -0
  31. package/macros/mf_getattrn.sas +34 -0
  32. package/macros/mf_getengine.sas +54 -0
  33. package/macros/mf_getfilesize.sas +64 -0
  34. package/macros/mf_getfmtlist.sas +61 -0
  35. package/macros/mf_getfmtname.sas +44 -0
  36. package/macros/mf_getkeyvalue.sas +32 -0
  37. package/macros/mf_getplatform.sas +75 -0
  38. package/macros/mf_getquotedstr.sas +57 -0
  39. package/macros/mf_getschema.sas +43 -0
  40. package/macros/mf_getuniquefileref.sas +60 -0
  41. package/macros/mf_getuniquelibref.sas +57 -0
  42. package/macros/mf_getuniquename.sas +22 -0
  43. package/macros/mf_getuser.sas +44 -0
  44. package/macros/mf_getvalue.sas +36 -0
  45. package/macros/mf_getvarcount.sas +49 -0
  46. package/macros/mf_getvarformat.sas +72 -0
  47. package/macros/mf_getvarlen.sas +56 -0
  48. package/macros/mf_getvarlist.sas +74 -0
  49. package/macros/mf_getvarnum.sas +58 -0
  50. package/macros/mf_getvartype.sas +52 -0
  51. package/macros/mf_getxengine.sas +43 -0
  52. package/macros/mf_increment.sas +29 -0
  53. package/macros/mf_isblank.sas +27 -0
  54. package/macros/mf_isdir.sas +34 -0
  55. package/macros/mf_isint.sas +36 -0
  56. package/macros/mf_islibds.sas +40 -0
  57. package/macros/mf_loc.sas +29 -0
  58. package/macros/mf_mkdir.sas +67 -0
  59. package/macros/mf_mval.sas +19 -0
  60. package/macros/mf_nobs.sas +26 -0
  61. package/macros/mf_trimstr.sas +50 -0
  62. package/macros/mf_uid.sas +21 -0
  63. package/macros/mf_verifymacvars.sas +72 -0
  64. package/macros/mf_wordsinstr1andstr2.sas +53 -0
  65. package/macros/mf_wordsinstr1butnotstr2.sas +54 -0
  66. package/macros/mf_writefile.sas +67 -0
  67. package/macros/mp_abort.sas +301 -0
  68. package/macros/mp_appendfile.sas +57 -0
  69. package/macros/mp_applyformats.sas +181 -0
  70. package/macros/mp_assert.sas +56 -0
  71. package/macros/mp_assertcols.sas +145 -0
  72. package/macros/mp_assertcolvals.sas +168 -0
  73. package/macros/mp_assertdsobs.sas +121 -0
  74. package/macros/mp_assertscope.sas +147 -0
  75. package/macros/mp_base64copy.sas +117 -0
  76. package/macros/mp_binarycopy.sas +79 -0
  77. package/macros/mp_chop.sas +194 -0
  78. package/macros/mp_cleancsv.sas +78 -0
  79. package/macros/mp_cntlout.sas +85 -0
  80. package/macros/mp_copyfolder.sas +84 -0
  81. package/macros/mp_coretable.sas +73 -0
  82. package/macros/mp_createconstraints.sas +70 -0
  83. package/macros/mp_createwebservice.sas +32 -0
  84. package/macros/mp_csv2ds.sas +140 -0
  85. package/macros/mp_deleteconstraints.sas +52 -0
  86. package/macros/mp_deletefolder.sas +70 -0
  87. package/macros/mp_dictionary.sas +52 -0
  88. package/macros/mp_dirlist.sas +263 -0
  89. package/macros/mp_distinctfmtvalues.sas +50 -0
  90. package/macros/mp_dropmembers.sas +46 -0
  91. package/macros/mp_ds2cards.sas +291 -0
  92. package/macros/mp_ds2csv.sas +212 -0
  93. package/macros/mp_ds2ddl.sas +30 -0
  94. package/macros/mp_ds2fmtds.sas +105 -0
  95. package/macros/mp_ds2inserts.sas +180 -0
  96. package/macros/mp_ds2md.sas +103 -0
  97. package/macros/mp_ds2squeeze.sas +120 -0
  98. package/macros/mp_dsmeta.sas +110 -0
  99. package/macros/mp_filtercheck.sas +251 -0
  100. package/macros/mp_filtergenerate.sas +105 -0
  101. package/macros/mp_filterstore.sas +254 -0
  102. package/macros/mp_filtervalidate.sas +105 -0
  103. package/macros/mp_getcols.sas +67 -0
  104. package/macros/mp_getconstraints.sas +115 -0
  105. package/macros/mp_getdbml.sas +335 -0
  106. package/macros/mp_getddl.sas +400 -0
  107. package/macros/mp_getformats.sas +124 -0
  108. package/macros/mp_getmaxvarlengths.sas +130 -0
  109. package/macros/mp_getpk.sas +281 -0
  110. package/macros/mp_gsubfile.sas +58 -0
  111. package/macros/mp_guesspk.sas +332 -0
  112. package/macros/mp_hashdataset.sas +91 -0
  113. package/macros/mp_hashdirectory.sas +162 -0
  114. package/macros/mp_include.sas +106 -0
  115. package/macros/mp_init.sas +76 -0
  116. package/macros/mp_jsonout.sas +406 -0
  117. package/macros/mp_lib2cards.sas +78 -0
  118. package/macros/mp_lib2inserts.sas +77 -0
  119. package/macros/mp_loadformat.sas +303 -0
  120. package/macros/mp_lockanytable.sas +243 -0
  121. package/macros/mp_lockfilecheck.sas +103 -0
  122. package/macros/mp_makedata.sas +107 -0
  123. package/macros/mp_md5.sas +58 -0
  124. package/macros/mp_perflog.sas +43 -0
  125. package/macros/mp_prevobs.sas +88 -0
  126. package/macros/mp_recursivejoin.sas +90 -0
  127. package/macros/mp_replace.sas +151 -0
  128. package/macros/mp_reseterror.sas +27 -0
  129. package/macros/mp_resetoption.sas +39 -0
  130. package/macros/mp_retainedkey.sas +247 -0
  131. package/macros/mp_runddl.sas +49 -0
  132. package/macros/mp_searchcols.sas +103 -0
  133. package/macros/mp_searchdata.sas +131 -0
  134. package/macros/mp_setkeyvalue.sas +55 -0
  135. package/macros/mp_sortinplace.sas +122 -0
  136. package/macros/mp_stackdiffs.sas +592 -0
  137. package/macros/mp_storediffs.sas +230 -0
  138. package/macros/mp_stprequests.sas +74 -0
  139. package/macros/mp_streamfile.sas +212 -0
  140. package/macros/mp_testjob.sas +92 -0
  141. package/macros/mp_testservice.sas +39 -0
  142. package/macros/mp_testwritespeedlibrary.sas +59 -0
  143. package/macros/mp_tree.sas +71 -0
  144. package/macros/mp_unzip.sas +90 -0
  145. package/macros/mp_updatevarlength.sas +93 -0
  146. package/macros/mp_validatecol.sas +97 -0
  147. package/macros/mp_wait4file.sas +35 -0
  148. package/macros/mp_webin.sas +59 -0
  149. package/macros/mp_zip.sas +85 -0
  150. package/package.json +5 -2
  151. package/scripts/copySASjsCore.ts +36 -0
  152. package/types/hash.d.ts +9 -0
  153. package/types/hash.js +3 -0
  154. package/types/hash.js.map +1 -0
  155. package/types/index.d.ts +1 -0
  156. package/types/index.js +1 -0
  157. package/types/index.js.map +1 -1
  158. package/utils/index.d.ts +1 -1
  159. package/utils/index.js +2 -1
  160. package/utils/index.js.map +1 -1
  161. package/utils/utils.d.ts +1 -0
  162. package/utils/utils.js +7 -1
  163. package/utils/utils.js.map +1 -1
@@ -0,0 +1,71 @@
1
+ /**
2
+ @file
3
+ @brief Recursively scans a directory tree to get all subfolders and content
4
+ @details
5
+ Usage:
6
+
7
+ %mp_tree(dir=/tmp, outds=work.tree)
8
+
9
+ Credits:
10
+
11
+ Roger Deangelis:
12
+ https://communities.sas.com/t5/SAS-Programming/listing-all-files-within-a-directory-and-subdirectories/m-p/332616/highlight/true#M74887
13
+
14
+ Tom:
15
+ https://communities.sas.com/t5/SAS-Programming/listing-all-files-of-all-types-from-all-subdirectories/m-p/334113/highlight/true#M75419
16
+
17
+
18
+ @param dir= Directory to be scanned (default=/tmp)
19
+ @param outds= Dataset to create (default=work.mp_tree)
20
+
21
+ @returns outds contains the following variables:
22
+
23
+ - `dir`: a flag (1/0) to say whether it is a directory or not. This is not
24
+ reliable - folders that you do not have permission to open will be flagged
25
+ as directories.
26
+ - `ext`: file extension
27
+ - `filename`: file name
28
+ - `dirname`: directory name
29
+ - `fullpath`: directory + file name
30
+
31
+ @version 9.2
32
+ **/
33
+
34
+ %macro mp_tree(dir=/tmp
35
+ ,outds=work.mp_tree
36
+ )/*/STORE SOURCE*/;
37
+
38
+ data &outds ;
39
+ length dir 8 ext filename dirname $256 fullpath $512 ;
40
+ call missing(of _all_);
41
+ fullpath = "&dir";
42
+ run;
43
+
44
+ %local sep;
45
+ %if &sysscp=WIN or &SYSSCP eq DNTHOST %then %let sep=\;
46
+ %else %let sep=/;
47
+
48
+ data &outds ;
49
+ modify &outds ;
50
+ retain sep "&sep";
51
+ rc=filename('tmp',fullpath);
52
+ dir_id=dopen('tmp');
53
+ dir = (dir_id ne 0) ;
54
+ if dir then dirname=fullpath;
55
+ else do;
56
+ filename=scan(fullpath,-1,sep) ;
57
+ dirname =substrn(fullpath,1,length(fullpath)-length(filename));
58
+ if index(filename,'.')>1 then ext=scan(filename,-1,'.');
59
+ end;
60
+ replace;
61
+ if dir then do;
62
+ do i=1 to dnum(dir_id);
63
+ fullpath=cats(dirname,sep,dread(dir_id,i));
64
+ output;
65
+ end;
66
+ rc=dclose(dir_id);
67
+ end;
68
+ rc=filename('tmp');
69
+ run;
70
+
71
+ %mend mp_tree;
@@ -0,0 +1,90 @@
1
+ /**
2
+ @file mp_unzip.sas
3
+ @brief Unzips a zip file
4
+ @details Opens the zip file and copies all the contents to another directory.
5
+ It is not possible to retain permissions / timestamps, also the BOF marker
6
+ is lost so it cannot extract binary files.
7
+
8
+ Usage:
9
+
10
+ filename mc url
11
+ "https://raw.githubusercontent.com/sasjs/core/main/all.sas";
12
+ %inc mc;
13
+
14
+ %mp_unzip(ziploc="/some/file.zip",outdir=/some/folder)
15
+
16
+ More info: https://blogs.sas.com/content/sasdummy/2015/05/11/using-filename-zip-to-unzip-and-read-data-files-in-sas/
17
+
18
+ @param ziploc= Fileref or quoted full path to zip file ("/path/to/file.zip")
19
+ @param outdir= (%sysfunc(pathname(work))) Directory in which to write the
20
+ outputs (created if non existant)
21
+
22
+ <h4> SAS Macros </h4>
23
+ @li mf_mkdir.sas
24
+ @li mf_getuniquefileref.sas
25
+ @li mp_binarycopy.sas
26
+
27
+ @version 9.4
28
+ @author Allan Bowe
29
+ @source https://github.com/sasjs/core
30
+
31
+ **/
32
+
33
+ %macro mp_unzip(
34
+ ziploc=
35
+ ,outdir=%sysfunc(pathname(work))
36
+ )/*/STORE SOURCE*/;
37
+
38
+ %local f1 f2 ;
39
+ %let f1=%mf_getuniquefileref();
40
+ %let f2=%mf_getuniquefileref();
41
+
42
+ /* Macro variable &datazip would be read from the file */
43
+ filename &f1 ZIP &ziploc;
44
+
45
+ /* create target folder */
46
+ %mf_mkdir(&outdir)
47
+
48
+ /* Read the "members" (files) from the ZIP file */
49
+ data _data_(keep=memname isFolder);
50
+ length memname $200 isFolder 8;
51
+ fid=dopen("&f1");
52
+ if fid=0 then stop;
53
+ memcount=dnum(fid);
54
+ do i=1 to memcount;
55
+ memname=dread(fid,i);
56
+ /* check for trailing / in folder name */
57
+ isFolder = (first(reverse(trim(memname)))='/');
58
+ output;
59
+ end;
60
+ rc=dclose(fid);
61
+ run;
62
+
63
+ filename &f2 temp;
64
+
65
+ /* loop through each entry and either create the subfolder or extract member */
66
+ data _null_;
67
+ set &syslast;
68
+ file &f2;
69
+ if isFolder then call execute('%mf_mkdir(&outdir/'!!memname!!')');
70
+ else do;
71
+ qname=quote(cats("&outdir/",memname));
72
+ bname=cats('(',memname,')');
73
+ put '/* hat tip: "data _null_" on SAS-L */';
74
+ put 'data _null_;';
75
+ put ' infile &f1 ' bname ' lrecl=256 recfm=F length=length eof=eof unbuf;';
76
+ put ' file ' qname ' lrecl=256 recfm=N;';
77
+ put ' input;';
78
+ put ' put _infile_ $varying256. length;';
79
+ put ' return;';
80
+ put 'eof:';
81
+ put ' stop;';
82
+ put 'run;';
83
+ end;
84
+ run;
85
+
86
+ %inc &f2/source2;
87
+
88
+ filename &f2 clear;
89
+
90
+ %mend mp_unzip;
@@ -0,0 +1,93 @@
1
+ /**
2
+ @file mp_updatevarlength.sas
3
+ @brief Change the length of a variable
4
+ @details The library is assumed to be assigned. Simple character updates
5
+ currently supported, numerics are more complicated and will follow.
6
+
7
+ data example;
8
+ a='1';
9
+ b='12';
10
+ c='123';
11
+ run;
12
+ %mp_updatevarlength(example,a,3)
13
+ %mp_updatevarlength(example,c,1)
14
+ proc sql;
15
+ describe table example;
16
+
17
+ @param libds the library.dataset to be modified
18
+ @param var The variable to modify
19
+ @param len The new length to apply
20
+
21
+ <h4> SAS Macros </h4>
22
+ @li mf_existds.sas
23
+ @li mp_abort.sas
24
+ @li mf_existvar.sas
25
+ @li mf_getvarlen.sas
26
+ @li mf_getvartype.sas
27
+ @li mf_getnobs.sas
28
+ @li mp_createconstraints.sas
29
+ @li mp_getconstraints.sas
30
+ @li mp_deleteconstraints.sas
31
+
32
+ @version 9.2
33
+ @author Allan Bowe
34
+
35
+ **/
36
+
37
+ %macro mp_updatevarlength(libds,var,len
38
+ )/*/STORE SOURCE*/;
39
+
40
+ %if %index(&libds,.)=0 %then %let libds=WORK.&libds;
41
+
42
+ %mp_abort(iftrue=(%mf_existds(&libds)=0)
43
+ ,mac=&sysmacroname
44
+ ,msg=%str(Table &libds not found!)
45
+ )
46
+
47
+ %mp_abort(iftrue=(%mf_existvar(&libds,&var)=0)
48
+ ,mac=&sysmacroname
49
+ ,msg=%str(Variable &var not found on &libds!)
50
+ )
51
+
52
+ /* not possible to in-place modify a numeric length, to add later */
53
+ %mp_abort(iftrue=(%mf_getvartype(&libds,&var)=0)
54
+ ,mac=&sysmacroname
55
+ ,msg=%str(Only character resizings are currently supported)
56
+ )
57
+
58
+ %local oldlen;
59
+ %let oldlen=%mf_getvarlen(&libds,&var);
60
+ %if &oldlen=&len %then %do;
61
+ %put &sysmacroname: Old and new lengths (&len) match!;
62
+ %return;
63
+ %end;
64
+
65
+ %let libds=%upcase(&libds);
66
+
67
+
68
+ data;run;
69
+ %local dsconst; %let dsconst=&syslast;
70
+ %mp_getconstraints(lib=%scan(&libds,1,.),ds=%scan(&libds,2,.),outds=&dsconst)
71
+
72
+ %mp_abort(iftrue=(&syscc ne 0)
73
+ ,mac=&sysmacroname
74
+ ,msg=%str(syscc=&syscc)
75
+ )
76
+
77
+ %if %mf_getnobs(&dscont)=0 %then %do;
78
+ /* must use SQL as proc datasets does not support length changes */
79
+ proc sql;
80
+ alter table &libds modify &var char(&len);
81
+ %return;
82
+ %end;
83
+
84
+ /* we have constraints! */
85
+
86
+ %mp_deleteconstraints(inds=&dsconst,outds=&dsconst._dropd,execute=YES)
87
+
88
+ proc sql;
89
+ alter table &libds modify &var char(&len);
90
+
91
+ %mp_createconstraints(inds=&dsconst,outds=&dsconst._addd,execute=YES)
92
+
93
+ %mend mp_updatevarlength;
@@ -0,0 +1,97 @@
1
+ /**
2
+ @file
3
+ @brief Used to validate variables in a dataset
4
+ @details Useful when sanitising inputs, to ensure that they arrive with a
5
+ certain pattern.
6
+ Usage:
7
+
8
+ data test;
9
+ infile datalines4 dsd;
10
+ input;
11
+ libds=_infile_;
12
+ %mp_validatecol(libds,LIBDS,is_libds)
13
+ datalines4;
14
+ some.libname
15
+ !lib.blah
16
+ %abort
17
+ definite.ok
18
+ not.ok!
19
+ nineletrs._
20
+ ;;;;
21
+ run;
22
+
23
+ For more examples, see mp_validatecol.test.sas
24
+
25
+ Tip - when contributing, use https://regex101.com to test the regex validity!
26
+
27
+ @param [in] incol The column to be validated
28
+ @param [in] rule The rule to apply. Current rules:
29
+ @li ISINT - checks if the variable is an integer
30
+ @li ISNUM - checks if the variable is numeric
31
+ @li LIBDS - matches LIBREF.DATASET format
32
+ @li FORMAT - checks if the provided format is syntactically valid
33
+ @param [out] outcol The variable to create, with the results of the match
34
+
35
+ <h4> SAS Macros </h4>
36
+ @li mf_getuniquename.sas
37
+
38
+ <h4> Related Macros </h4>
39
+ @li mp_validatecol.test.sas
40
+
41
+ @version 9.3
42
+ **/
43
+
44
+ %macro mp_validatecol(incol,rule,outcol);
45
+
46
+ /* tempcol is given a unique name with every invocation */
47
+ %local tempcol;
48
+ %let tempcol=%mf_getuniquename();
49
+
50
+ %if &rule=ISINT %then %do;
51
+ &outcol=0;
52
+ if not missing(&incol) then do;
53
+ &tempcol=input(&incol,?? best32.);
54
+ if not missing(&tempcol) then if mod(&tempcol,1)=0 then &outcol=1;
55
+ end;
56
+ drop &tempcol;
57
+ %end;
58
+ %else %if &rule=ISNUM %then %do;
59
+ /*
60
+ credit SØREN LASSEN
61
+ https://sasmacro.blogspot.com/2009/06/welcome-isnum-macro.html
62
+ */
63
+ &tempcol=input(&incol,?? best32.);
64
+ if missing(&tempcol) then &outcol=0;
65
+ else &outcol=1;
66
+ drop &tempcol;
67
+ %end;
68
+ %else %if &rule=LIBDS %then %do;
69
+ /* match libref.dataset */
70
+ if _n_=1 then do;
71
+ retain &tempcol;
72
+ &tempcol=prxparse('/^[_a-z]\w{0,7}\.[_a-z]\w{0,31}$/i');
73
+ if missing(&tempcol) then do;
74
+ putlog "%str(ERR)OR: Invalid expression for LIBDS";
75
+ stop;
76
+ end;
77
+ drop &tempcol;
78
+ end;
79
+ if prxmatch(&tempcol, trim(&incol)) then &outcol=1;
80
+ else &outcol=0;
81
+ %end;
82
+ %else %if &rule=FORMAT %then %do;
83
+ /* match valid format - regex could probably be improved */
84
+ if _n_=1 then do;
85
+ retain &tempcol;
86
+ &tempcol=prxparse('/^[_a-z\$]\w{0,31}\.[0-9]*$/i');
87
+ if missing(&tempcol) then do;
88
+ putlog "%str(ERR)OR: Invalid expression for FORMAT";
89
+ stop;
90
+ end;
91
+ drop &tempcol;
92
+ end;
93
+ if prxmatch(&tempcol, trim(&incol)) then &outcol=1;
94
+ else &outcol=0;
95
+ %end;
96
+
97
+ %mend mp_validatecol;
@@ -0,0 +1,35 @@
1
+ /**
2
+ @file
3
+ @brief Wait until a file arrives before continuing execution
4
+ @details Loops with a `sleep()` command until a file arrives or the max wait
5
+ period expires.
6
+
7
+ Example: Wait 3 minutes OR for /tmp/flag.txt to appear
8
+
9
+ %mp_wait4file(/tmp/flag.txt , maxwait=60*3)
10
+
11
+ @param [in] file The file to wait for. Must be provided.
12
+ @param [in] maxwait= (0) Number of seconds to wait. If set to zero, will
13
+ loop indefinitely (to a maximum of 46 days, per SAS [documentation](
14
+ https://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a001418809.htm
15
+ )). Otherwise, execution will proceed upon sleep expiry.
16
+ @param [in] interval= (1) The wait period between sleeps, in seconds
17
+
18
+
19
+ **/
20
+
21
+ %macro mp_wait4file(file, maxwait=0, interval=1);
22
+
23
+ %if %str(&file)=%str() %then %do;
24
+ %put %str(ERR)OR: file not provided;
25
+ %end;
26
+
27
+ data _null_;
28
+ maxwait=&maxwait;
29
+ if maxwait=0 then maxwait=60*60*24*46;
30
+ do until (fileexist("&file") or slept>maxwait );
31
+ slept=sum(slept,sleep(&interval,1));
32
+ end;
33
+ run;
34
+
35
+ %mend mp_wait4file;
@@ -0,0 +1,59 @@
1
+ /**
2
+ @file
3
+ @brief Fix the `_WEBIN` variables provided to SAS web services
4
+ @details When uploading files to SAS Stored Processes or Viya Jobs a number
5
+ of global macro variables are automatically created - however there are some
6
+ differences in behaviour both between SAS 9 and Viya, and also between a
7
+ single file upload and a multi-file upload.
8
+
9
+ This macro "straightens" up the global macro variables to make it easier /
10
+ simpler to write code that works in both environments and with a variable
11
+ number of file inputs.
12
+
13
+ After running this macro, the following global variables will *always* exist:
14
+ @li `_WEBIN_FILE_COUNT`
15
+ @li `_WEBIN_FILENAME1`
16
+ @li `_WEBIN_FILEREF1`
17
+ @li `_WEBIN_NAME1`
18
+
19
+ Usage:
20
+
21
+ %mp_webin()
22
+
23
+ This was created as a macro procedure (over a macro function) as it will also
24
+ use the filename statement in Viya environments (where `_webin_fileuri` is
25
+ provided).
26
+
27
+ <h4> SAS Macros </h4>
28
+ @li mf_getplatform.sas
29
+ @li mf_getuniquefileref.sas
30
+
31
+ **/
32
+
33
+ %macro mp_webin();
34
+
35
+ /* prepare global variables */
36
+ %global _webin_file_count
37
+ _webin_filename _webin_filename1
38
+ _webin_fileref _webin_fileref1
39
+ _webin_fileuri _webin_fileuri1
40
+ _webin_name _webin_name1
41
+ ;
42
+
43
+ /* create initial versions */
44
+ %let _webin_file_count=%eval(&_webin_file_count+0);
45
+ %let _webin_filename1=%sysfunc(coalescec(&_webin_filename1,&_webin_filename));
46
+ %let _webin_fileref1=%sysfunc(coalescec(&_webin_fileref1,&_webin_fileref));
47
+ %let _webin_fileuri1=%sysfunc(coalescec(&_webin_fileuri1,&_webin_fileuri));
48
+ %let _webin_name1=%sysfunc(coalescec(&_webin_name1,&_webin_name));
49
+
50
+
51
+ /* If Viya, create temporary fileref(s) */
52
+ %local i;
53
+ %if %mf_getplatform()=SASVIYA %then %do i=1 %to &_webin_file_count;
54
+ %let _webin_fileref&i=%mf_getuniquefileref();
55
+ filename &&_webin_fileref&i filesrvc "&&_webin_fileuri&i";
56
+ %end;
57
+
58
+
59
+ %mend mp_webin;
@@ -0,0 +1,85 @@
1
+ /**
2
+ @file
3
+ @brief Creates a zip file
4
+ @details For DIRECTORY usage, will ignore subfolders. For DATASET usage,
5
+ provide a column that contains the full file path to each file to be zipped.
6
+
7
+ %mp_zip(in=myzips,type=directory,outname=myDir)
8
+ %mp_zip(in=/my/file/path.txt,type=FILE,outname=myFile)
9
+ %mp_zip(in=SOMEDS,incol=FPATH,type=DATASET,outname=myFile)
10
+
11
+ If you are sending zipped output to the _webout destination as part of an STP
12
+ be sure that _debug is not set (else the SPWA will send non zipped content
13
+ as well).
14
+
15
+ <h4> SAS Macros </h4>
16
+ @li mp_dirlist.sas
17
+
18
+ @param in= unquoted filepath, dataset of files or directory to zip
19
+ @param type= (FILE) Valid values:
20
+ @li FILE - /full/path/and/filename.extension to a particular file
21
+ @li DATASET - a dataset containing a list of files to zip (see `incol`)
22
+ @li DIRECTORY - a directory to zip
23
+ @param outname= (FILE) Output file to create, _without_ .zip extension
24
+ @param outpath= (%sysfunc(pathname(WORK))) Parent folder for output zip file
25
+ @param incol= if DATASET input, say which column contains the filepath
26
+
27
+ <h4> Related Macros </h4>
28
+ @li mp_unzip.sas
29
+ @li mp_zip.test.sas
30
+
31
+ @version 9.2
32
+ @author Allan Bowe
33
+ @source https://github.com/sasjs/core
34
+
35
+ **/
36
+
37
+ %macro mp_zip(
38
+ in=
39
+ ,type=FILE
40
+ ,outname=FILE
41
+ ,outpath=%sysfunc(pathname(WORK))
42
+ ,incol=
43
+ ,debug=NO
44
+ )/*/STORE SOURCE*/;
45
+
46
+ %let type=%upcase(&type);
47
+ %local ds;
48
+
49
+ ods package open nopf;
50
+
51
+ %if &type=FILE %then %do;
52
+ ods package add file="&in" mimetype="application/x-compress";
53
+ %end;
54
+ %else %if &type=DIRECTORY %then %do;
55
+ %mp_dirlist(path=&in,outds=_data_)
56
+ %let ds=&syslast;
57
+ data _null_;
58
+ set &ds;
59
+ length __command $4000;
60
+ if file_or_folder='file';
61
+ __command=cats('ods package add file="',filepath
62
+ ,'" mimetype="application/x-compress";');
63
+ call execute(__command);
64
+ run;
65
+ /* tidy up */
66
+ %if &debug=NO %then %do;
67
+ proc sql; drop table &ds;quit;
68
+ %end;
69
+ %end;
70
+ %else %if &type=DATASET %then %do;
71
+ data _null_;
72
+ set &in;
73
+ length __command $4000;
74
+ __command=cats('ods package add file="',&incol
75
+ ,'" mimetype="application/x-compress";');
76
+ call execute(__command);
77
+ run;
78
+ %end;
79
+
80
+
81
+ ods package publish archive properties
82
+ (archive_name="&outname..zip" archive_path="&outpath");
83
+ ods package close;
84
+
85
+ %mend mp_zip;
package/package.json CHANGED
@@ -15,6 +15,8 @@
15
15
  "preinstall": "npm run nodeVersionMessage",
16
16
  "prebuild": "npm run nodeVersionMessage",
17
17
  "build": "rimraf build && tsc",
18
+ "postbuild": "npm run copy:macros",
19
+ "copy:macros": "ts-node ./scripts/copySASjsCore.ts",
18
20
  "prepublishOnly": "cp -r ./build/* . && rm -rf ./build && rm -rf ./src && rm jest.config.js && rm tsconfig.json",
19
21
  "postpublish": "git clean -fd",
20
22
  "package:lib": "npm run build && cp ./package.json build && cp README.md build && cd build && npm version \"5.0.0\" && npm pack",
@@ -34,7 +36,7 @@
34
36
  },
35
37
  "homepage": "https://github.com/sasjs/utils#readme",
36
38
  "devDependencies": {
37
- "@sasjs/core": "3.10.0",
39
+ "@sasjs/core": "4.41.0",
38
40
  "@types/cli-table": "0.3.0",
39
41
  "@types/find": "0.2.1",
40
42
  "@types/jest": "27.4.0",
@@ -45,6 +47,7 @@
45
47
  "jest-extended": "1.1.0",
46
48
  "ts-jest": "27.1.3",
47
49
  "ts-loader": "9.2.6",
50
+ "ts-node": "10.9.1",
48
51
  "typescript": "4.5.4"
49
52
  },
50
53
  "dependencies": {
@@ -61,5 +64,5 @@
61
64
  "rimraf": "3.0.2",
62
65
  "valid-url": "1.0.9"
63
66
  },
64
- "version": "2.48.2"
67
+ "version": "2.49.1"
65
68
  }
@@ -0,0 +1,36 @@
1
+ import path from 'path'
2
+ import { asyncForEach, copy, createFolder, deleteFolder } from '../src'
3
+
4
+ const root = path.join(__dirname, '..')
5
+
6
+ const sasjsCorePath = path.join(root, 'node_modules', '@sasjs', 'core')
7
+
8
+ export const macrosPath = path.join(root, 'build', 'macros')
9
+
10
+ /**
11
+ * We need @sasjs/core macros at runtime for compilation of programs, but we
12
+ * can't directly import them like a javascript file.
13
+ * So, we have to read the macro files directly. For this we can't use the
14
+ * node_modules folder, as it will not always be available after the library is
15
+ * built / packed (eg in the VS Code extension)
16
+ * Therefore, we copy the macros to a folder in the post build step, so that we
17
+ * can read them at runtime.
18
+ *
19
+ * These macros are / will be used by the sasjs fs command / fs sync utilites
20
+ * as well as for general compilation of SAS Jobs, Services, and Tests.
21
+ */
22
+
23
+ export const copySASjsCore = async () => {
24
+ await deleteFolder(macrosPath)
25
+ await createFolder(macrosPath)
26
+
27
+ const foldersToCopy = ['base']
28
+
29
+ await asyncForEach(foldersToCopy, async (coreSubFolder) => {
30
+ const coreSubFolderPath = path.join(sasjsCorePath, coreSubFolder)
31
+
32
+ await copy(coreSubFolderPath, macrosPath)
33
+ })
34
+ }
35
+
36
+ copySASjsCore()
@@ -0,0 +1,9 @@
1
+ export interface HashedFile {
2
+ hash: string;
3
+ absolutePath: string;
4
+ relativePath: string;
5
+ isFile: boolean;
6
+ }
7
+ export interface HashedFolder extends HashedFile {
8
+ members: (HashedFile | HashedFolder)[];
9
+ }
package/types/hash.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/types/hash.ts"],"names":[],"mappings":""}
package/types/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export * from './configuration';
3
3
  export * from './decodedToken';
4
4
  export * from './extraResponseAttributes';
5
5
  export * from './fileTree';
6
+ export * from './hash';
6
7
  export * from './httpsAgentOptions';
7
8
  export * from './macro';
8
9
  export * from './sasAuthResponse';
package/types/index.js CHANGED
@@ -15,6 +15,7 @@ __exportStar(require("./configuration"), exports);
15
15
  __exportStar(require("./decodedToken"), exports);
16
16
  __exportStar(require("./extraResponseAttributes"), exports);
17
17
  __exportStar(require("./fileTree"), exports);
18
+ __exportStar(require("./hash"), exports);
18
19
  __exportStar(require("./httpsAgentOptions"), exports);
19
20
  __exportStar(require("./macro"), exports);
20
21
  __exportStar(require("./sasAuthResponse"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAwB;AACxB,kDAA+B;AAC/B,iDAA8B;AAC9B,4DAAyC;AACzC,6CAA0B;AAC1B,sDAAmC;AACnC,0CAAuB;AACvB,oDAAiC;AACjC,kDAA+B;AAC/B,gDAA6B;AAC7B,+CAA4B;AAC5B,gDAA6B;AAC7B,2CAAwB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAwB;AACxB,kDAA+B;AAC/B,iDAA8B;AAC9B,4DAAyC;AACzC,6CAA0B;AAC1B,yCAAsB;AACtB,sDAAmC;AACnC,0CAAuB;AACvB,oDAAiC;AACjC,kDAA+B;AAC/B,gDAA6B;AAC7B,+CAA4B;AAC5B,gDAA6B;AAC7B,2CAAwB"}
package/utils/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { uuidv4, asyncForEach, uniqArray, isWindows, isLinux, escapeWinSlashes } from './utils';
1
+ export { uuidv4, asyncForEach, uniqArray, isWindows, isLinux, escapeWinSlashes, getMacrosPath } from './utils';
2
2
  export * from './fileTree';
3
3
  export { urlOrigin } from './url';
4
4
  export { encodeToBase64, decodeFromBase64 } from './base64';
package/utils/index.js CHANGED
@@ -10,7 +10,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
10
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.chunk = exports.diff = exports.bytesToSize = exports.getExecutorPath = exports.decodeFromBase64 = exports.encodeToBase64 = exports.urlOrigin = exports.escapeWinSlashes = exports.isLinux = exports.isWindows = exports.uniqArray = exports.asyncForEach = exports.uuidv4 = void 0;
13
+ exports.chunk = exports.diff = exports.bytesToSize = exports.getExecutorPath = exports.decodeFromBase64 = exports.encodeToBase64 = exports.urlOrigin = exports.getMacrosPath = exports.escapeWinSlashes = exports.isLinux = exports.isWindows = exports.uniqArray = exports.asyncForEach = exports.uuidv4 = void 0;
14
14
  var utils_1 = require("./utils");
15
15
  Object.defineProperty(exports, "uuidv4", { enumerable: true, get: function () { return utils_1.uuidv4; } });
16
16
  Object.defineProperty(exports, "asyncForEach", { enumerable: true, get: function () { return utils_1.asyncForEach; } });
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "uniqArray", { enumerable: true, get: function ()
18
18
  Object.defineProperty(exports, "isWindows", { enumerable: true, get: function () { return utils_1.isWindows; } });
19
19
  Object.defineProperty(exports, "isLinux", { enumerable: true, get: function () { return utils_1.isLinux; } });
20
20
  Object.defineProperty(exports, "escapeWinSlashes", { enumerable: true, get: function () { return utils_1.escapeWinSlashes; } });
21
+ Object.defineProperty(exports, "getMacrosPath", { enumerable: true, get: function () { return utils_1.getMacrosPath; } });
21
22
  __exportStar(require("./fileTree"), exports);
22
23
  var url_1 = require("./url");
23
24
  Object.defineProperty(exports, "urlOrigin", { enumerable: true, get: function () { return url_1.urlOrigin; } });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,iCAOgB;AANd,+FAAA,MAAM,OAAA;AACN,qGAAA,YAAY,OAAA;AACZ,kGAAA,SAAS,OAAA;AACT,kGAAA,SAAS,OAAA;AACT,gGAAA,OAAO,OAAA;AACP,yGAAA,gBAAgB,OAAA;AAElB,6CAA0B;AAE1B,6BAAiC;AAAxB,gGAAA,SAAS,OAAA;AAElB,mCAA2D;AAAlD,wGAAA,cAAc,OAAA;AAAE,0GAAA,gBAAgB,OAAA;AAEzC,uCAA4C;AAAnC,2GAAA,eAAe,OAAA;AAExB,6CAA2C;AAAlC,0GAAA,WAAW,OAAA;AACpB,+BAA6B;AAApB,4FAAA,IAAI,OAAA;AACb,iCAA+B;AAAtB,8FAAA,KAAK,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,iCAQgB;AAPd,+FAAA,MAAM,OAAA;AACN,qGAAA,YAAY,OAAA;AACZ,kGAAA,SAAS,OAAA;AACT,kGAAA,SAAS,OAAA;AACT,gGAAA,OAAO,OAAA;AACP,yGAAA,gBAAgB,OAAA;AAChB,sGAAA,aAAa,OAAA;AAEf,6CAA0B;AAE1B,6BAAiC;AAAxB,gGAAA,SAAS,OAAA;AAElB,mCAA2D;AAAlD,wGAAA,cAAc,OAAA;AAAE,0GAAA,gBAAgB,OAAA;AAEzC,uCAA4C;AAAnC,2GAAA,eAAe,OAAA;AAExB,6CAA2C;AAAlC,0GAAA,WAAW,OAAA;AACpB,+BAA6B;AAApB,4FAAA,IAAI,OAAA;AACb,iCAA+B;AAAtB,8FAAA,KAAK,OAAA"}
package/utils/utils.d.ts CHANGED
@@ -7,3 +7,4 @@ export declare const isLinux: () => boolean;
7
7
  * replace single backslash with double backslash
8
8
  */
9
9
  export declare const escapeWinSlashes: (path: string) => string;
10
+ export declare const getMacrosPath: () => string;