@sasjs/cli 3.4.1 → 3.6.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.
@@ -101,8 +101,11 @@ function getPreCodeForServicePack(serverType) {
101
101
  '/* so we provide instead as __program */\n' +
102
102
  '%global __program _program;\n' +
103
103
  '%let _program=%sysfunc(coalescec(&__program,&_program));\n' +
104
- '%macro webout(action,ds,dslabel=,fmt=,missing=NULL);\n' +
105
- '%mv_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt,missing=&missing)\n' +
104
+ '%macro webout(action,ds,dslabel=,fmt=,missing=NULL,showmeta=NO);\n' +
105
+ ' %mv_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt\n' +
106
+ ' ,missing=&missing\n' +
107
+ ' ,showmeta=&showmeta\n' +
108
+ ' )' +
106
109
  '%mend;\n';
107
110
  return [3 /*break*/, 14];
108
111
  case 5:
@@ -119,8 +122,11 @@ function getPreCodeForServicePack(serverType) {
119
122
  case 8:
120
123
  content = _g + _l.sent();
121
124
  content +=
122
- ' %macro webout(action,ds,dslabel=,fmt=,missing=NULL);\n' +
123
- ' %mm_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt,missing=&missing)\n' +
125
+ ' %macro webout(action,ds,dslabel=,fmt=,missing=NULL,showmeta=NO);\n' +
126
+ ' %mm_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt\n' +
127
+ ' ,missing=&missing\n' +
128
+ ' ,showmeta=&showmeta\n' +
129
+ ' )' +
124
130
  ' %mend;\n';
125
131
  return [3 /*break*/, 14];
126
132
  case 9:
@@ -137,8 +143,11 @@ function getPreCodeForServicePack(serverType) {
137
143
  case 12:
138
144
  content = _k + _l.sent();
139
145
  content +=
140
- ' %macro webout(action,ds,dslabel=,fmt=,missing=NULL);\n' +
141
- ' %ms_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt,missing=&missing)\n' +
146
+ ' %macro webout(action,ds,dslabel=,fmt=,missing=NULL,showmeta=NO);\n' +
147
+ ' %ms_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt\n' +
148
+ ' ,missing=&missing\n' +
149
+ ' ,showmeta=&showmeta\n' +
150
+ ' )' +
142
151
  ' %mend;\n';
143
152
  return [3 /*break*/, 14];
144
153
  case 13: throw new error_1.ServerTypeError();
@@ -42,7 +42,7 @@ var config_1 = require("../../../utils/config");
42
42
  function loadDependencies(target, filePath, macroFolders, programFolders, type) {
43
43
  var _a;
44
44
  return __awaiter(this, void 0, void 0, function () {
45
- var fileContent, configuration, _b, buildSourceFolder, macroCorePath;
45
+ var fileContent, configuration, _b, buildSourceFolder, macroCorePath, binaryFolders;
46
46
  return __generator(this, function (_c) {
47
47
  switch (_c.label) {
48
48
  case 0:
@@ -54,6 +54,9 @@ function loadDependencies(target, filePath, macroFolders, programFolders, type)
54
54
  case 2:
55
55
  configuration = (_c.sent()).configuration;
56
56
  _b = process.sasjsConstants, buildSourceFolder = _b.buildSourceFolder, macroCorePath = _b.macroCorePath;
57
+ return [4 /*yield*/, config_1.getBinaryFolders(target)];
58
+ case 3:
59
+ binaryFolders = _c.sent();
57
60
  headerSyntaxNotices(fileContent);
58
61
  return [4 /*yield*/, utils_1.loadDependenciesFile({
59
62
  fileContent: fileContent,
@@ -64,9 +67,10 @@ function loadDependencies(target, filePath, macroFolders, programFolders, type)
64
67
  macroFolders: macroFolders,
65
68
  programFolders: programFolders,
66
69
  buildSourceFolder: buildSourceFolder,
67
- macroCorePath: macroCorePath
70
+ macroCorePath: macroCorePath,
71
+ binaryFolders: binaryFolders
68
72
  })];
69
- case 3: return [2 /*return*/, _c.sent()];
73
+ case 4: return [2 /*return*/, _c.sent()];
70
74
  }
71
75
  });
72
76
  });
@@ -128,10 +128,10 @@ describe('compileTestFile', function () {
128
128
  return [4 /*yield*/, utils_1.readFile(compiledTestFilePath)];
129
129
  case 2:
130
130
  testFileContent = _a.apply(void 0, [_b.sent()]);
131
- testVar = replaceLineBreaks("* Test Variables start;\n\n%let " + Object.keys(target.testConfig.macroVars)[0] + "=" + Object.values(target.testConfig.macroVars)[0] + ";\n\n*Test Variables end;");
131
+ testVar = replaceLineBreaks("* Test Variables start;\n\n%let " + Object.keys(target.testConfig.macroVars)[0] + "=" + Object.values(target.testConfig.macroVars)[0] + ";\n\n* Test Variables end;");
132
132
  testInit = replaceLineBreaks("* TestInit start;\n/**\n @file\n @brief setting up the test\n\n <h4> SAS Macros </h4>\n**/\n\n%put testing, init;\n* TestInit end;");
133
133
  testTerm = replaceLineBreaks("* TestTerm start;\n/**\n @file\n @brief ending the test\n\n <h4> SAS Macros </h4>\n**/\n\n%put testing, termed;\n* TestTerm end;");
134
- mvWebout = "%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y);";
134
+ mvWebout = "%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y,stream=Y,missing=NULL<br> ,showmeta=NO<br>);";
135
135
  expect(testFileContent.indexOf(testVar)).toBeGreaterThan(-1);
136
136
  expect(testFileContent.indexOf(testInit)).toBeGreaterThan(-1);
137
137
  expect(testFileContent.indexOf(testTerm)).toBeGreaterThan(-1);
@@ -121,7 +121,7 @@ var serviceConfig = function (root) {
121
121
  }
122
122
  });
123
123
  };
124
- var compiledVars = function (type) { return "* " + type + " Variables start;\n\n%let macrovar1=macro " + type.toLowerCase() + " value configuration 1;\n%let macrovar2=macro " + type.toLowerCase() + " value target 2;\n%let macrovar3=macro " + type.toLowerCase() + " value target 3;\n\n*" + type + " Variables end;"; };
124
+ var compiledVars = function (type) { return "* " + type + " Variables start;\n\n%let macrovar1=macro " + type.toLowerCase() + " value configuration 1;\n%let macrovar2=macro " + type.toLowerCase() + " value target 2;\n%let macrovar3=macro " + type.toLowerCase() + " value target 3;\n\n* " + type + " Variables end;"; };
125
125
  describe('loadDependencies', function () {
126
126
  var appName = "cli-tests-load-dependencies-" + utils_1.generateTimestamp();
127
127
  var temp = test_1.generateTestTarget(appName, '/Public/app', {
@@ -119,8 +119,11 @@ describe('sasjs cbd with server type SASJS', function () {
119
119
  return [4 /*yield*/, utils_1.readFile(macroCorePath + "/server/ms_webout.sas")];
120
120
  case 7:
121
121
  ms_webout = _a.sent();
122
- webout = ' %macro webout(action,ds,dslabel=,fmt=,missing=NULL);\n' +
123
- ' %ms_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt,missing=&missing)\n' +
122
+ webout = ' %macro webout(action,ds,dslabel=,fmt=,missing=NULL,showmeta=NO);\n' +
123
+ ' %ms_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt\n' +
124
+ ' ,missing=&missing\n' +
125
+ ' ,showmeta=&showmeta\n' +
126
+ ' )' +
124
127
  ' %mend;\n';
125
128
  expect(sasjs.deployToSASjs).toHaveBeenCalledWith({
126
129
  members: [
@@ -136,13 +139,13 @@ describe('sasjs cbd with server type SASJS', function () {
136
139
  name: 'appinit',
137
140
  type: 'service',
138
141
  code: utils_3.removeComments("" + mf_getuser + mp_jsonout + ms_webout + webout +
139
- '/* provide additional debug info */\n%global _program;\n%put &=syscc;\n%put user=%mf_getuser();\n%put pgm=&_program;\n%put timestamp=%sysfunc(datetime(),datetime19.);\n* Service Variables start;\n*Service Variables end;\n* Dependencies start;\n* Dependencies end;\n* Programs start;\n*Programs end;\n* Service start;\nproc sql;\ncreate table areas as select distinct area\n from sashelp.springs;\n%webout(OPEN)\n%webout(OBJ,areas)\n%webout(CLOSE)\n* Service end;')
142
+ '/* provide additional debug info */\n%global _program;\n%put &=syscc;\n%put user=%mf_getuser();\n%put pgm=&_program;\n%put timestamp=%sysfunc(datetime(),datetime19.);\n* Service Variables start;\n* Service Variables end;\n* SAS Macros start;\n* SAS Macros end;\n* SAS Includes start;\n* SAS Includes end;\n* Binary Files start;\n* Binary Files end;\n* Service start;\nproc sql;\ncreate table areas as select distinct area\n from sashelp.springs;\n%webout(OPEN)\n%webout(OBJ,areas)\n%webout(CLOSE)\n* Service end;')
140
143
  },
141
144
  {
142
145
  name: 'getdata',
143
146
  type: 'service',
144
147
  code: utils_3.removeComments("" + mf_getuser + mp_jsonout + ms_webout + webout +
145
- '/* provide additional debug info */\n%global _program;\n%put &=syscc;\n%put user=%mf_getuser();\n%put pgm=&_program;\n%put timestamp=%sysfunc(datetime(),datetime19.);\n* Service Variables start;\n*Service Variables end;\n* Dependencies start;\n* Dependencies end;\n* Programs start;\n*Programs end;\n* Service start;\n%webout(FETCH)\nproc sql;\ncreate table springs as select * from sashelp.springs\n where area in (select area from work.areas);\n%webout(OPEN)\n%webout(OBJ,springs)\n%webout(CLOSE)\n* Service end;')
148
+ '/* provide additional debug info */\n%global _program;\n%put &=syscc;\n%put user=%mf_getuser();\n%put pgm=&_program;\n%put timestamp=%sysfunc(datetime(),datetime19.);\n* Service Variables start;\n* Service Variables end;\n* SAS Macros start;\n* SAS Macros end;\n* SAS Includes start;\n* SAS Includes end;\n* Binary Files start;\n* Binary Files end;\n* Service start;\n%webout(FETCH)\nproc sql;\ncreate table springs as select * from sashelp.springs\n where area in (select area from work.areas);\n%webout(OPEN)\n%webout(OBJ,springs)\n%webout(CLOSE)\n* Service end;')
146
149
  }
147
150
  ]
148
151
  }
@@ -53,7 +53,7 @@ var saveLog = function (logData, logFile, jobPath, returnStatusOnly) { return __
53
53
  logPath = logFile;
54
54
  }
55
55
  else {
56
- logPath = path_1.default.join(process.projectDir, jobPath.split('/').slice(-1).pop() + ".log");
56
+ logPath = path_1.default.join(process.projectDir, jobPath.split(path_1.default.sep).slice(-1).pop() + ".log");
57
57
  }
58
58
  folderPath = logPath.split(path_1.default.sep);
59
59
  folderPath.pop();
@@ -61,6 +61,7 @@ var path_1 = __importDefault(require("path"));
61
61
  var command_1 = require("../../types/command");
62
62
  var targetCommand_1 = require("../../types/command/targetCommand");
63
63
  var utils_2 = require("../../utils");
64
+ var getLogFilePath_1 = require("../../utils/getLogFilePath");
64
65
  var prefixAppLoc_1 = require("../../utils/prefixAppLoc");
65
66
  var execute_1 = require("./internal/execute");
66
67
  var JobSubCommand;
@@ -232,7 +233,7 @@ var JobCommand = /** @class */ (function (_super) {
232
233
  switch (_d.label) {
233
234
  case 0:
234
235
  jobPath = prefixAppLoc_1.prefixAppLoc(target.appLoc, this.parsed.jobPath);
235
- log = getLogFilePath(this.parsed.log, jobPath);
236
+ log = getLogFilePath_1.getLogFilePath(this.parsed.log, jobPath);
236
237
  wait = this.parsed.wait || !!log;
237
238
  output = ((_a = this.parsed.output) === null || _a === void 0 ? void 0 : _a.length)
238
239
  ? this.parsed.output
@@ -268,19 +269,6 @@ var JobCommand = /** @class */ (function (_super) {
268
269
  return JobCommand;
269
270
  }(targetCommand_1.TargetCommand));
270
271
  exports.JobCommand = JobCommand;
271
- var getLogFilePath = function (logArg, jobPath) {
272
- if (logArg === undefined) {
273
- return undefined;
274
- }
275
- if (logArg) {
276
- var currentDirPath = path_1.default.isAbsolute(logArg)
277
- ? ''
278
- : process.projectDir;
279
- return path_1.default.join(currentDirPath, logArg);
280
- }
281
- var logFileName = jobPath.split('/').slice(-1).pop() + ".log";
282
- return path_1.default.join(process.projectDir, logFileName);
283
- };
284
272
  var getStatusFilePath = function (statusFileArg) {
285
273
  if (statusFileArg) {
286
274
  var currentDirPath = path_1.default.isAbsolute(statusFileArg)
@@ -1,2 +1,2 @@
1
1
  import { AuthConfig, Target } from '@sasjs/utils/types';
2
- export declare function runSasJob(target: Target, isLocal: boolean, sasJobLocation: string, dataFilePath?: string, configFilePath?: string, authConfig?: AuthConfig): Promise<undefined>;
2
+ export declare function runSasJob(target: Target, isLocal: boolean, sasJobLocation: string, dataFilePath?: string, configFilePath?: string, authConfig?: AuthConfig, logFile?: string, jobPath?: string | null, outputPathParam?: string | undefined): Promise<undefined>;
@@ -46,16 +46,19 @@ var utils_1 = require("@sasjs/utils");
46
46
  var displayResult_1 = require("../../utils/displayResult");
47
47
  var types_1 = require("@sasjs/utils/types");
48
48
  var utils_2 = require("../../utils/utils");
49
- function runSasJob(target, isLocal, sasJobLocation, dataFilePath, configFilePath, authConfig) {
49
+ var saveLog_1 = require("../../utils/saveLog");
50
+ var getLogFilePath_1 = require("../../utils/getLogFilePath");
51
+ function runSasJob(target, isLocal, sasJobLocation, dataFilePath, configFilePath, authConfig, logFile, jobPath, outputPathParam) {
50
52
  return __awaiter(this, void 0, void 0, function () {
51
- var dataJson, configJson, dataFile, configFile, sas9CredentialsError, sasjs, result;
53
+ var dataJson, configJson, dataFile, configFile, sas9CredentialsError, sasjs, result, isError, sasRequests, currentRequestLog;
52
54
  var _this = this;
53
55
  return __generator(this, function (_a) {
54
56
  switch (_a.label) {
55
57
  case 0:
56
- dataJson = {};
58
+ dataJson = null;
57
59
  configJson = {};
58
60
  if (!dataFilePath) return [3 /*break*/, 2];
61
+ dataJson = {};
59
62
  if (dataFilePath.split('.').slice(-1)[0] !== 'json') {
60
63
  throw new Error('Provided data file must be valid json.');
61
64
  }
@@ -106,61 +109,129 @@ function runSasJob(target, isLocal, sasJobLocation, dataFilePath, configFilePath
106
109
  appLoc: target.appLoc,
107
110
  serverType: target.serverType,
108
111
  contextName: target.contextName,
109
- useComputeApi: false
112
+ useComputeApi: false,
113
+ debug: true
110
114
  });
111
- if (!dataJson)
112
- dataJson = null;
115
+ isError = false;
113
116
  return [4 /*yield*/, sasjs
114
117
  .request(sasJobLocation, dataJson, configJson, function () {
115
118
  displayResult_1.displayError(null, 'Login callback called. Request failed.');
116
119
  }, authConfig)
117
120
  .then(function (res) { return __awaiter(_this, void 0, void 0, function () {
118
- var output, outputPath;
121
+ var output;
119
122
  return __generator(this, function (_a) {
120
123
  switch (_a.label) {
121
124
  case 0:
125
+ if ((res && res.errorCode) || res.error)
126
+ isError = true;
122
127
  if (res === null || res === void 0 ? void 0 : res.result)
123
128
  res = res.result;
124
- try {
125
- output = JSON.stringify(res, null, 2);
129
+ if (typeof res !== 'object') {
130
+ try {
131
+ output = JSON.stringify(res, null, 2);
132
+ }
133
+ catch (error) {
134
+ displayResult_1.displayError(error, 'Result parsing failed.');
135
+ return [2 /*return*/, error];
136
+ }
126
137
  }
127
- catch (error) {
128
- displayResult_1.displayError(error, 'Result parsing failed.');
129
- return [2 /*return*/, error];
138
+ else {
139
+ output = res;
130
140
  }
131
- outputPath = path_1.default.join(process.projectDir, isLocal ? '/sasjsbuild' : '');
132
- return [4 /*yield*/, utils_1.folderExists(outputPath)];
141
+ return [4 /*yield*/, writeOutput(outputPathParam, output, isLocal)];
133
142
  case 1:
134
- if (!!(_a.sent())) return [3 /*break*/, 3];
135
- return [4 /*yield*/, utils_1.createFolder(outputPath)];
136
- case 2:
137
- _a.sent();
138
- _a.label = 3;
139
- case 3:
140
- outputPath += '/output.json';
141
- return [4 /*yield*/, utils_1.createFile(outputPath, output)];
142
- case 4:
143
143
  _a.sent();
144
144
  result = true;
145
- displayResult_1.displaySuccess("Request finished. Output is stored at '" + outputPath + "'");
146
145
  return [2 /*return*/];
147
146
  }
148
147
  });
149
148
  }); })
150
- .catch(function (err) {
151
- result = err;
152
- if (err && err.errorCode === 404) {
153
- utils_2.displaySasjsRunnerError(configJson.username);
154
- }
155
- else {
156
- displayResult_1.displayError(err, 'An error occurred while executing the request.');
157
- }
158
- })];
149
+ .catch(function (err) { return __awaiter(_this, void 0, void 0, function () {
150
+ return __generator(this, function (_a) {
151
+ switch (_a.label) {
152
+ case 0:
153
+ isError = true;
154
+ if (err && err.errorCode === 404) {
155
+ utils_2.displaySasjsRunnerError(configJson.username);
156
+ }
157
+ else {
158
+ displayResult_1.displayError('', 'An error occurred while executing the request.');
159
+ }
160
+ return [4 /*yield*/, writeOutput(outputPathParam, err, isLocal)];
161
+ case 1:
162
+ _a.sent();
163
+ result = err;
164
+ return [2 /*return*/];
165
+ }
166
+ });
167
+ }); })];
159
168
  case 5:
160
169
  _a.sent();
161
- return [2 /*return*/, result];
170
+ sasRequests = sasjs.getSasRequests();
171
+ currentRequestLog = sasRequests.find(function (x) { return x.serviceLink === sasJobLocation; });
172
+ if (!(currentRequestLog && ((logFile && jobPath) || isError))) return [3 /*break*/, 7];
173
+ if (!logFile)
174
+ logFile = getLogFilePath_1.getLogFilePath('', jobPath || '');
175
+ return [4 /*yield*/, saveLog_1.saveLog(currentRequestLog.logFile, logFile, jobPath || '', false)];
176
+ case 6:
177
+ _a.sent();
178
+ _a.label = 7;
179
+ case 7: return [2 /*return*/, result];
162
180
  }
163
181
  });
164
182
  });
165
183
  }
166
184
  exports.runSasJob = runSasJob;
185
+ /**
186
+ * Writes output to the file
187
+ * @param outputPathParam path to output file
188
+ * @param output data to be written to output file
189
+ * @param isLocal is local target, othervise it is global
190
+ * @returns output path for the file created
191
+ */
192
+ var writeOutput = function (outputPathParam, output, isLocal) { return __awaiter(void 0, void 0, void 0, function () {
193
+ var outputPath, outputFilename, outputPathArr, outputString;
194
+ return __generator(this, function (_a) {
195
+ switch (_a.label) {
196
+ case 0:
197
+ outputPath = path_1.default.join(process.projectDir, isLocal ? '' : '');
198
+ if (outputPathParam && typeof outputPathParam === 'string') {
199
+ outputPathParam = path_1.default.join(process.projectDir, outputPathParam || '');
200
+ outputPathArr = outputPathParam.split(path_1.default.sep);
201
+ outputFilename = outputPathArr.pop();
202
+ outputPath = outputPathArr.join(path_1.default.sep);
203
+ }
204
+ return [4 /*yield*/, utils_1.folderExists(outputPath)];
205
+ case 1:
206
+ if (!!(_a.sent())) return [3 /*break*/, 3];
207
+ return [4 /*yield*/, utils_1.createFolder(outputPath)];
208
+ case 2:
209
+ _a.sent();
210
+ _a.label = 3;
211
+ case 3:
212
+ if (outputFilename) {
213
+ outputPath += "" + path_1.default.sep + outputFilename;
214
+ }
215
+ else {
216
+ outputPath += path_1.default.sep + "output.json";
217
+ }
218
+ outputString = '';
219
+ if (typeof output === 'object') {
220
+ outputString = JSON.stringify(output);
221
+ }
222
+ else {
223
+ outputString = output;
224
+ }
225
+ if (!outputString) return [3 /*break*/, 5];
226
+ return [4 /*yield*/, utils_1.createFile(outputPath, outputString)];
227
+ case 4:
228
+ _a.sent();
229
+ displayResult_1.displaySuccess("Request finished. Output is stored at '" + outputPath + "'");
230
+ return [3 /*break*/, 6];
231
+ case 5:
232
+ displayResult_1.displayError("There was a problem with writing output file. Data not present.");
233
+ _a.label = 6;
234
+ case 6: return [2 /*return*/];
235
+ }
236
+ });
237
+ }); };
@@ -57,8 +57,9 @@ var command_1 = require("../../types/command");
57
57
  var targetCommand_1 = require("../../types/command/targetCommand");
58
58
  var utils_2 = require("../../utils");
59
59
  var request_1 = require("./request");
60
+ var getLogFilePath_1 = require("../../utils/getLogFilePath");
60
61
  var syntax = 'request <sasProgramPath> [options]';
61
- var usage = 'sasjs request <sasProgramPath> --data <path-to-datafile> --config <path-to-configfile> --target <target-name>';
62
+ var usage = 'sasjs request <sasProgramPath> --data <path-to-datafile> --config <path-to-configfile> --target <target-name> --output <path-to-outputfile> --log <path-to-logfile>';
62
63
  var description = "Lets the user run a SAS job against a specified target.\n" +
63
64
  "The target can exist either in the local project configuration or in the global .sasjsrc file.";
64
65
  var examples = [
@@ -73,6 +74,10 @@ var examples = [
73
74
  {
74
75
  command: 'sasjs request ./path/run-job.sas -t targetName -d ./path/data.json -c ./path/config.json',
75
76
  description: ''
77
+ },
78
+ {
79
+ command: 'sasjs request ./path/run-job.sas -t targetName -l ./jobLog.log -o ./jobOutput.json',
80
+ description: ''
76
81
  }
77
82
  ];
78
83
  var RequestCommand = /** @class */ (function (_super) {
@@ -89,6 +94,16 @@ var RequestCommand = /** @class */ (function (_super) {
89
94
  type: 'string',
90
95
  alias: 'c',
91
96
  description: 'The path to a json file containting the config to be used when executing a request.'
97
+ },
98
+ log: {
99
+ type: 'string',
100
+ alias: 'l',
101
+ description: 'Path where the log of the finished job will be saved. If used, -w is implied.'
102
+ },
103
+ output: {
104
+ type: 'string',
105
+ alias: 'o',
106
+ description: 'path where output of the finished job execution will be saved.'
92
107
  }
93
108
  },
94
109
  syntax: syntax,
@@ -99,12 +114,17 @@ var RequestCommand = /** @class */ (function (_super) {
99
114
  }
100
115
  RequestCommand.prototype.execute = function () {
101
116
  return __awaiter(this, void 0, void 0, function () {
102
- var _a, target, isLocal, authConfig, _b, _c, sasProgramPath, data, config;
117
+ var _a, target, isLocal, jobPath, log, output, authConfig, _b, _c, sasProgramPath, data, config;
103
118
  return __generator(this, function (_d) {
104
119
  switch (_d.label) {
105
120
  case 0: return [4 /*yield*/, this.getTargetInfo()];
106
121
  case 1:
107
122
  _a = _d.sent(), target = _a.target, isLocal = _a.isLocal;
123
+ jobPath = utils_2.prefixAppLoc(target.appLoc, process.currentDir);
124
+ log = this.parsed.log
125
+ ? getLogFilePath_1.getLogFilePath(this.parsed.log || '', jobPath || '')
126
+ : undefined;
127
+ output = this.parsed.output || undefined;
108
128
  if (!(target.serverType === utils_1.ServerType.SasViya)) return [3 /*break*/, 3];
109
129
  return [4 /*yield*/, utils_2.getAuthConfig(target)];
110
130
  case 2:
@@ -116,7 +136,7 @@ var RequestCommand = /** @class */ (function (_super) {
116
136
  case 4:
117
137
  authConfig = _b;
118
138
  _c = this.parsed, sasProgramPath = _c.sasProgramPath, data = _c.data, config = _c.config;
119
- return [4 /*yield*/, request_1.runSasJob(target, isLocal, sasProgramPath, data, config, authConfig)
139
+ return [4 /*yield*/, request_1.runSasJob(target, isLocal, sasProgramPath, data, config, authConfig, log, jobPath, output)
120
140
  .then(function () {
121
141
  return command_1.ReturnCode.Success;
122
142
  })
@@ -59,6 +59,8 @@ var request_1 = require("../request");
59
59
  var build_1 = require("../../build/build");
60
60
  var deploy_1 = require("../../deploy/deploy");
61
61
  var utils_3 = require("../../../utils");
62
+ var getLogFilePath_1 = require("../../../utils/getLogFilePath");
63
+ var fs_1 = require("fs");
62
64
  var sampleDataJson = {
63
65
  table1: [
64
66
  { col1: 'first col value1', col2: 'second col value1' },
@@ -90,6 +92,14 @@ var expectedDataObj = {
90
92
  }
91
93
  ]
92
94
  };
95
+ var getOutputJson = function () { return __awaiter(void 0, void 0, void 0, function () { var _a, _b; return __generator(this, function (_c) {
96
+ switch (_c.label) {
97
+ case 0:
98
+ _b = (_a = JSON).parse;
99
+ return [4 /*yield*/, utils_1.readFile(path_1.default.join(process.projectDir, 'output.json'))];
100
+ case 1: return [2 /*return*/, _b.apply(_a, [_c.sent()])];
101
+ }
102
+ }); }); };
93
103
  describe('sasjs request without compute API', function () {
94
104
  var appName = 'cli-tests-request-' + utils_2.generateTimestamp();
95
105
  var target = test_1.generateTestTarget(appName, "/Public/app/cli-tests/" + appName, {
@@ -155,47 +165,89 @@ describe('sasjs request without compute API', function () {
155
165
  });
156
166
  }); });
157
167
  it("should execute service 'sendArr' with absolute path", function () { return __awaiter(void 0, void 0, void 0, function () {
158
- var rawData, output;
159
- return __generator(this, function (_a) {
160
- switch (_a.label) {
168
+ var _a, _b;
169
+ return __generator(this, function (_c) {
170
+ switch (_c.label) {
161
171
  case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, "/Public/app/cli-tests/" + target.name + "/services/runRequest/sendArr", dataPathRel, undefined, authConfig)).toResolve()];
162
172
  case 1:
163
- _a.sent();
164
- return [4 /*yield*/, utils_1.readFile(process.projectDir + "/output.json")];
173
+ _c.sent();
174
+ _a = expect;
175
+ return [4 /*yield*/, getOutputJson()];
165
176
  case 2:
166
- rawData = _a.sent();
167
- output = JSON.parse(rawData);
168
- expect(output.table1).toEqual(expectedDataArr.table1);
169
- expect(output.table2).toEqual(expectedDataArr.table2);
177
+ _a.apply(void 0, [(_c.sent()).table1]).toEqual(expectedDataArr.table1);
178
+ _b = expect;
179
+ return [4 /*yield*/, getOutputJson()];
180
+ case 3:
181
+ _b.apply(void 0, [(_c.sent()).table2]).toEqual(expectedDataArr.table2);
170
182
  return [2 /*return*/];
171
183
  }
172
184
  });
173
185
  }); });
174
186
  it("should execute service 'sendObj' with absolute path", function () { return __awaiter(void 0, void 0, void 0, function () {
175
- var rawData, output;
176
- return __generator(this, function (_a) {
177
- switch (_a.label) {
187
+ var _a, _b;
188
+ return __generator(this, function (_c) {
189
+ switch (_c.label) {
178
190
  case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, "/Public/app/cli-tests/" + target.name + "/services/runRequest/sendObj", dataPathRel, undefined, authConfig)).toResolve()];
179
191
  case 1:
180
- _a.sent();
181
- return [4 /*yield*/, utils_1.readFile(process.projectDir + "/output.json")];
192
+ _c.sent();
193
+ _a = expect;
194
+ return [4 /*yield*/, getOutputJson()];
182
195
  case 2:
183
- rawData = _a.sent();
184
- output = JSON.parse(rawData);
185
- expect(output.table1).toEqual(expectedDataObj.table1);
186
- expect(output.table2).toEqual(expectedDataObj.table2);
196
+ _a.apply(void 0, [(_c.sent()).table1]).toEqual(expectedDataObj.table1);
197
+ _b = expect;
198
+ return [4 /*yield*/, getOutputJson()];
199
+ case 3:
200
+ _b.apply(void 0, [(_c.sent()).table2]).toEqual(expectedDataObj.table2);
187
201
  return [2 /*return*/];
188
202
  }
189
203
  });
190
204
  }); });
191
205
  it("should execute service 'sendArr' with relative path", function () { return __awaiter(void 0, void 0, void 0, function () {
206
+ var _a, _b;
207
+ return __generator(this, function (_c) {
208
+ switch (_c.label) {
209
+ case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, 'services/runRequest/sendArr', dataPathRel, undefined, authConfig)).toResolve()];
210
+ case 1:
211
+ _c.sent();
212
+ _a = expect;
213
+ return [4 /*yield*/, getOutputJson()];
214
+ case 2:
215
+ _a.apply(void 0, [(_c.sent()).table1]).toEqual(expectedDataArr.table1);
216
+ _b = expect;
217
+ return [4 /*yield*/, getOutputJson()];
218
+ case 3:
219
+ _b.apply(void 0, [(_c.sent()).table2]).toEqual(expectedDataArr.table2);
220
+ return [2 /*return*/];
221
+ }
222
+ });
223
+ }); });
224
+ it("should execute service 'sendObj' with relative path", function () { return __awaiter(void 0, void 0, void 0, function () {
225
+ var _a, _b;
226
+ return __generator(this, function (_c) {
227
+ switch (_c.label) {
228
+ case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, 'services/runRequest/sendObj', dataPathRel, undefined, authConfig)).toResolve()];
229
+ case 1:
230
+ _c.sent();
231
+ _a = expect;
232
+ return [4 /*yield*/, getOutputJson()];
233
+ case 2:
234
+ _a.apply(void 0, [(_c.sent()).table1]).toEqual(expectedDataObj.table1);
235
+ _b = expect;
236
+ return [4 /*yield*/, getOutputJson()];
237
+ case 3:
238
+ _b.apply(void 0, [(_c.sent()).table2]).toEqual(expectedDataObj.table2);
239
+ return [2 /*return*/];
240
+ }
241
+ });
242
+ }); });
243
+ it("should execute service 'sendArr' with absolute path with output path", function () { return __awaiter(void 0, void 0, void 0, function () {
192
244
  var rawData, output;
193
245
  return __generator(this, function (_a) {
194
246
  switch (_a.label) {
195
- case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, 'services/runRequest/sendArr', dataPathRel, undefined, authConfig)).toResolve()];
247
+ case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, "/Public/app/cli-tests/" + target.name + "/services/runRequest/sendArr", dataPathRel, undefined, authConfig, undefined, undefined, './myoutput.json')).toResolve()];
196
248
  case 1:
197
249
  _a.sent();
198
- return [4 /*yield*/, utils_1.readFile(process.projectDir + "/output.json")];
250
+ return [4 /*yield*/, utils_1.readFile(path_1.default.join(process.projectDir, 'myoutput.json'))];
199
251
  case 2:
200
252
  rawData = _a.sent();
201
253
  output = JSON.parse(rawData);
@@ -205,19 +257,38 @@ describe('sasjs request without compute API', function () {
205
257
  }
206
258
  });
207
259
  }); });
208
- it("should execute service 'sendObj' with relative path", function () { return __awaiter(void 0, void 0, void 0, function () {
209
- var rawData, output;
260
+ it("should execute service 'err' with absolute path with log path", function () { return __awaiter(void 0, void 0, void 0, function () {
261
+ var jobPath, log, rawLogDataStats, rawDataStats;
210
262
  return __generator(this, function (_a) {
211
263
  switch (_a.label) {
212
- case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, 'services/runRequest/sendObj', dataPathRel, undefined, authConfig)).toResolve()];
264
+ case 0:
265
+ jobPath = utils_3.prefixAppLoc(target.appLoc, 'services/runRequest/err');
266
+ log = getLogFilePath_1.getLogFilePath('./mylog.txt', jobPath || '');
267
+ return [4 /*yield*/, expect(request_1.runSasJob(target, false, jobPath, dataPathRel, undefined, authConfig, log, jobPath)).toResolve()];
213
268
  case 1:
214
269
  _a.sent();
215
- return [4 /*yield*/, utils_1.readFile(process.projectDir + "/output.json")];
216
- case 2:
217
- rawData = _a.sent();
218
- output = JSON.parse(rawData);
219
- expect(output.table1).toEqual(expectedDataObj.table1);
220
- expect(output.table2).toEqual(expectedDataObj.table2);
270
+ rawLogDataStats = fs_1.statSync(log);
271
+ rawDataStats = fs_1.statSync(path_1.default.join(process.projectDir, 'output.json'));
272
+ expect(rawLogDataStats.size).toBeGreaterThan(10);
273
+ expect(rawDataStats.size).toBeGreaterThan(10);
274
+ return [2 /*return*/];
275
+ }
276
+ });
277
+ }); });
278
+ it("should execute service 'err' with absolute path with default log path", function () { return __awaiter(void 0, void 0, void 0, function () {
279
+ var jobPath, log, rawLogDataStats, rawDataStats;
280
+ return __generator(this, function (_a) {
281
+ switch (_a.label) {
282
+ case 0:
283
+ jobPath = utils_3.prefixAppLoc(target.appLoc, 'services/runRequest/err');
284
+ log = getLogFilePath_1.getLogFilePath('', jobPath || '');
285
+ return [4 /*yield*/, expect(request_1.runSasJob(target, false, jobPath, dataPathRel, undefined, authConfig, log, jobPath)).toResolve()];
286
+ case 1:
287
+ _a.sent();
288
+ rawLogDataStats = fs_1.statSync(log);
289
+ rawDataStats = fs_1.statSync(path_1.default.join(process.projectDir, 'output.json'));
290
+ expect(rawLogDataStats.size).toBeGreaterThan(10);
291
+ expect(rawDataStats.size).toBeGreaterThan(10);
221
292
  return [2 /*return*/];
222
293
  }
223
294
  });
@@ -284,47 +355,89 @@ describe('sasjs request with SAS9', function () {
284
355
  });
285
356
  }); });
286
357
  it("should execute service 'sendArr' with absolute path", function () { return __awaiter(void 0, void 0, void 0, function () {
287
- var rawData, output;
288
- return __generator(this, function (_a) {
289
- switch (_a.label) {
358
+ var _a, _b;
359
+ return __generator(this, function (_c) {
360
+ switch (_c.label) {
290
361
  case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, "/Public/app/cli-tests/" + target.name + "/services/runRequest/sendArr", dataPathRel)).toResolve()];
291
362
  case 1:
292
- _a.sent();
293
- return [4 /*yield*/, utils_1.readFile(process.projectDir + "/output.json")];
363
+ _c.sent();
364
+ _a = expect;
365
+ return [4 /*yield*/, getOutputJson()];
294
366
  case 2:
295
- rawData = _a.sent();
296
- output = JSON.parse(rawData);
297
- expect(output.table1).toEqual(expectedDataArr.table1);
298
- expect(output.table2).toEqual(expectedDataArr.table2);
367
+ _a.apply(void 0, [(_c.sent()).table1]).toEqual(expectedDataArr.table1);
368
+ _b = expect;
369
+ return [4 /*yield*/, getOutputJson()];
370
+ case 3:
371
+ _b.apply(void 0, [(_c.sent()).table2]).toEqual(expectedDataArr.table2);
299
372
  return [2 /*return*/];
300
373
  }
301
374
  });
302
375
  }); });
303
376
  it("should execute service 'sendObj' with absolute path", function () { return __awaiter(void 0, void 0, void 0, function () {
304
- var rawData, output;
305
- return __generator(this, function (_a) {
306
- switch (_a.label) {
377
+ var _a, _b;
378
+ return __generator(this, function (_c) {
379
+ switch (_c.label) {
307
380
  case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, "/Public/app/cli-tests/" + target.name + "/services/runRequest/sendObj", dataPathRel)).toResolve()];
308
381
  case 1:
309
- _a.sent();
310
- return [4 /*yield*/, utils_1.readFile(process.projectDir + "/output.json")];
382
+ _c.sent();
383
+ _a = expect;
384
+ return [4 /*yield*/, getOutputJson()];
311
385
  case 2:
312
- rawData = _a.sent();
313
- output = JSON.parse(rawData);
314
- expect(output.table1).toEqual(expectedDataObj.table1);
315
- expect(output.table2).toEqual(expectedDataObj.table2);
386
+ _a.apply(void 0, [(_c.sent()).table1]).toEqual(expectedDataObj.table1);
387
+ _b = expect;
388
+ return [4 /*yield*/, getOutputJson()];
389
+ case 3:
390
+ _b.apply(void 0, [(_c.sent()).table2]).toEqual(expectedDataObj.table2);
316
391
  return [2 /*return*/];
317
392
  }
318
393
  });
319
394
  }); });
320
395
  it("should execute service 'sendArr' with relative path", function () { return __awaiter(void 0, void 0, void 0, function () {
396
+ var _a, _b;
397
+ return __generator(this, function (_c) {
398
+ switch (_c.label) {
399
+ case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, 'services/runRequest/sendArr', dataPathRel)).toResolve()];
400
+ case 1:
401
+ _c.sent();
402
+ _a = expect;
403
+ return [4 /*yield*/, getOutputJson()];
404
+ case 2:
405
+ _a.apply(void 0, [(_c.sent()).table1]).toEqual(expectedDataArr.table1);
406
+ _b = expect;
407
+ return [4 /*yield*/, getOutputJson()];
408
+ case 3:
409
+ _b.apply(void 0, [(_c.sent()).table2]).toEqual(expectedDataArr.table2);
410
+ return [2 /*return*/];
411
+ }
412
+ });
413
+ }); });
414
+ it("should execute service 'sendObj' with relative path", function () { return __awaiter(void 0, void 0, void 0, function () {
415
+ var _a, _b;
416
+ return __generator(this, function (_c) {
417
+ switch (_c.label) {
418
+ case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, 'services/runRequest/sendObj', dataPathRel)).toResolve()];
419
+ case 1:
420
+ _c.sent();
421
+ _a = expect;
422
+ return [4 /*yield*/, getOutputJson()];
423
+ case 2:
424
+ _a.apply(void 0, [(_c.sent()).table1]).toEqual(expectedDataObj.table1);
425
+ _b = expect;
426
+ return [4 /*yield*/, getOutputJson()];
427
+ case 3:
428
+ _b.apply(void 0, [(_c.sent()).table2]).toEqual(expectedDataObj.table2);
429
+ return [2 /*return*/];
430
+ }
431
+ });
432
+ }); });
433
+ it("should execute service 'sendArr' with absolute path with output path", function () { return __awaiter(void 0, void 0, void 0, function () {
321
434
  var rawData, output;
322
435
  return __generator(this, function (_a) {
323
436
  switch (_a.label) {
324
- case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, 'services/runRequest/sendArr', dataPathRel)).toResolve()];
437
+ case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, "/Public/app/cli-tests/" + target.name + "/services/runRequest/sendArr", dataPathRel, undefined, undefined, undefined, undefined, './myoutput.json')).toResolve()];
325
438
  case 1:
326
439
  _a.sent();
327
- return [4 /*yield*/, utils_1.readFile(process.projectDir + "/output.json")];
440
+ return [4 /*yield*/, utils_1.readFile(path_1.default.join(process.projectDir, 'myoutput.json'))];
328
441
  case 2:
329
442
  rawData = _a.sent();
330
443
  output = JSON.parse(rawData);
@@ -334,19 +447,38 @@ describe('sasjs request with SAS9', function () {
334
447
  }
335
448
  });
336
449
  }); });
337
- it("should execute service 'sendObj' with relative path", function () { return __awaiter(void 0, void 0, void 0, function () {
338
- var rawData, output;
450
+ it("should execute service 'err' with absolute path with log path", function () { return __awaiter(void 0, void 0, void 0, function () {
451
+ var jobPath, log, rawLogDataStats, rawDataStats;
339
452
  return __generator(this, function (_a) {
340
453
  switch (_a.label) {
341
- case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, 'services/runRequest/sendObj', dataPathRel)).toResolve()];
454
+ case 0:
455
+ jobPath = utils_3.prefixAppLoc(target.appLoc, 'services/runRequest/err');
456
+ log = getLogFilePath_1.getLogFilePath('./mylog.txt', jobPath || '');
457
+ return [4 /*yield*/, expect(request_1.runSasJob(target, false, jobPath, dataPathRel, undefined, undefined, log, jobPath)).toResolve()];
342
458
  case 1:
343
459
  _a.sent();
344
- return [4 /*yield*/, utils_1.readFile(process.projectDir + "/output.json")];
345
- case 2:
346
- rawData = _a.sent();
347
- output = JSON.parse(rawData);
348
- expect(output.table1).toEqual(expectedDataObj.table1);
349
- expect(output.table2).toEqual(expectedDataObj.table2);
460
+ rawLogDataStats = fs_1.statSync(log);
461
+ rawDataStats = fs_1.statSync(path_1.default.join(process.projectDir, 'output.json'));
462
+ expect(rawLogDataStats.size).toBeGreaterThan(10);
463
+ expect(rawDataStats.size).toBeGreaterThan(10);
464
+ return [2 /*return*/];
465
+ }
466
+ });
467
+ }); });
468
+ it("should execute service 'err' with absolute path with default log path", function () { return __awaiter(void 0, void 0, void 0, function () {
469
+ var jobPath, log, rawLogDataStats, rawDataStats;
470
+ return __generator(this, function (_a) {
471
+ switch (_a.label) {
472
+ case 0:
473
+ jobPath = utils_3.prefixAppLoc(target.appLoc, 'services/runRequest/err');
474
+ log = getLogFilePath_1.getLogFilePath('', jobPath || '');
475
+ return [4 /*yield*/, expect(request_1.runSasJob(target, false, jobPath, dataPathRel, undefined, undefined, log, jobPath)).toResolve()];
476
+ case 1:
477
+ _a.sent();
478
+ rawLogDataStats = fs_1.statSync(log);
479
+ rawDataStats = fs_1.statSync(path_1.default.join(process.projectDir, 'output.json'));
480
+ expect(rawLogDataStats.size).toBeGreaterThan(10);
481
+ expect(rawDataStats.size).toBeGreaterThan(10);
350
482
  return [2 /*return*/];
351
483
  }
352
484
  });
@@ -412,69 +544,77 @@ describe("sasjs request with compute API", function () {
412
544
  });
413
545
  }); });
414
546
  it("should execute service 'sendArr' with absolute path", function () { return __awaiter(void 0, void 0, void 0, function () {
415
- var rawData, output;
416
- return __generator(this, function (_a) {
417
- switch (_a.label) {
547
+ var _a, _b;
548
+ return __generator(this, function (_c) {
549
+ switch (_c.label) {
418
550
  case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, "/Public/app/cli-tests/" + target.name + "/services/runRequest/sendArr", dataPathRel, configPathRel, authConfig)).toResolve()];
419
551
  case 1:
420
- _a.sent();
421
- return [4 /*yield*/, utils_1.readFile(process.projectDir + "/output.json")];
552
+ _c.sent();
553
+ _a = expect;
554
+ return [4 /*yield*/, getOutputJson()];
422
555
  case 2:
423
- rawData = _a.sent();
424
- output = JSON.parse(rawData);
425
- expect(output.table1).toEqual(expectedDataArr.table1);
426
- expect(output.table2).toEqual(expectedDataArr.table2);
556
+ _a.apply(void 0, [(_c.sent()).table1]).toEqual(expectedDataArr.table1);
557
+ _b = expect;
558
+ return [4 /*yield*/, getOutputJson()];
559
+ case 3:
560
+ _b.apply(void 0, [(_c.sent()).table2]).toEqual(expectedDataArr.table2);
427
561
  return [2 /*return*/];
428
562
  }
429
563
  });
430
564
  }); });
431
565
  it("should execute service 'sendObj' with absolute path", function () { return __awaiter(void 0, void 0, void 0, function () {
432
- var rawData, output;
433
- return __generator(this, function (_a) {
434
- switch (_a.label) {
566
+ var _a, _b;
567
+ return __generator(this, function (_c) {
568
+ switch (_c.label) {
435
569
  case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, "/Public/app/cli-tests/" + target.name + "/services/runRequest/sendObj", dataPathRel, configPathRel, authConfig)).toResolve()];
436
570
  case 1:
437
- _a.sent();
438
- return [4 /*yield*/, utils_1.readFile(process.projectDir + "/output.json")];
571
+ _c.sent();
572
+ _a = expect;
573
+ return [4 /*yield*/, getOutputJson()];
439
574
  case 2:
440
- rawData = _a.sent();
441
- output = JSON.parse(rawData);
442
- expect(output.table1).toEqual(expectedDataObj.table1);
443
- expect(output.table2).toEqual(expectedDataObj.table2);
575
+ _a.apply(void 0, [(_c.sent()).table1]).toEqual(expectedDataObj.table1);
576
+ _b = expect;
577
+ return [4 /*yield*/, getOutputJson()];
578
+ case 3:
579
+ _b.apply(void 0, [(_c.sent()).table2]).toEqual(expectedDataObj.table2);
444
580
  return [2 /*return*/];
445
581
  }
446
582
  });
447
583
  }); });
448
584
  it("should execute service 'sendArr' with relative path", function () { return __awaiter(void 0, void 0, void 0, function () {
449
- var rawData, output;
450
- return __generator(this, function (_a) {
451
- switch (_a.label) {
585
+ var _a, _b;
586
+ return __generator(this, function (_c) {
587
+ switch (_c.label) {
452
588
  case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, 'services/runRequest/sendArr', dataPathRel, undefined, authConfig)).toResolve()];
453
589
  case 1:
454
- _a.sent();
455
- return [4 /*yield*/, utils_1.readFile(process.projectDir + "/output.json")];
590
+ _c.sent();
591
+ _a = expect;
592
+ return [4 /*yield*/, getOutputJson()];
456
593
  case 2:
457
- rawData = _a.sent();
458
- output = JSON.parse(rawData);
459
- expect(output.table1).toEqual(expectedDataArr.table1);
460
- expect(output.table2).toEqual(expectedDataArr.table2);
594
+ _a.apply(void 0, [(_c.sent()).table1]).toEqual(expectedDataArr.table1);
595
+ _b = expect;
596
+ return [4 /*yield*/, getOutputJson()];
597
+ case 3:
598
+ _b.apply(void 0, [(_c.sent()).table2]).toEqual(expectedDataArr.table2);
461
599
  return [2 /*return*/];
462
600
  }
463
601
  });
464
602
  }); });
465
603
  it("should execute service 'sendObj' with relative path", function () { return __awaiter(void 0, void 0, void 0, function () {
466
- var rawData, output;
467
- return __generator(this, function (_a) {
468
- switch (_a.label) {
604
+ var _a, _b;
605
+ return __generator(this, function (_c) {
606
+ switch (_c.label) {
469
607
  case 0: return [4 /*yield*/, expect(request_1.runSasJob(target, false, 'services/runRequest/sendObj', dataPathRel, undefined, authConfig)).toResolve()];
470
608
  case 1:
471
- _a.sent();
472
- return [4 /*yield*/, utils_1.readFile(process.projectDir + "/output.json")];
609
+ _c.sent();
610
+ _a = expect;
611
+ return [4 /*yield*/, getOutputJson()];
473
612
  case 2:
474
- rawData = _a.sent();
475
- output = JSON.parse(rawData);
476
- expect(output.table1).toEqual(expectedDataObj.table1);
477
- expect(output.table2).toEqual(expectedDataObj.table2);
613
+ _a.apply(void 0, [(_c.sent()).table1]).toEqual(expectedDataObj.table1);
614
+ _b = expect;
615
+ return [4 /*yield*/, getOutputJson()];
616
+ case 3:
617
+ _b.apply(void 0, [(_c.sent()).table2]).toEqual(expectedDataObj.table2);
478
618
  return [2 /*return*/];
479
619
  }
480
620
  });
@@ -92,6 +92,8 @@ var target = new utils_1.Target({
92
92
  var sasProgramPath = 'path/to/soure.sas';
93
93
  var dataFilePath = 'path/to/data.json';
94
94
  var configFilePath = 'path/to/config.json';
95
+ var outputPath = './output.txt';
96
+ var logPath = './log.txt';
95
97
  describe('RequestCommand', function () {
96
98
  beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
97
99
  return __generator(this, function (_a) {
@@ -122,7 +124,7 @@ describe('RequestCommand', function () {
122
124
  expect(command.name).toEqual('request');
123
125
  expect(targetInfo.target).toEqual(target);
124
126
  expect(targetInfo.isLocal).toBeTrue();
125
- expect(requestModule.runSasJob).toHaveBeenCalledWith(target, true, sasProgramPath, undefined, undefined, undefined);
127
+ expect(requestModule.runSasJob).toHaveBeenCalledWith(target, true, sasProgramPath, undefined, undefined, undefined, undefined, null, undefined);
126
128
  return [2 /*return*/];
127
129
  }
128
130
  });
@@ -166,7 +168,7 @@ describe('RequestCommand', function () {
166
168
  expect(command.name).toEqual('request');
167
169
  expect(targetInfo.target).toEqual(mockViyaTarget);
168
170
  expect(targetInfo.isLocal).toBeTrue();
169
- expect(requestModule.runSasJob).toHaveBeenCalledWith(mockViyaTarget, true, sasProgramPath, undefined, undefined, mockAuthConfig);
171
+ expect(requestModule.runSasJob).toHaveBeenCalledWith(mockViyaTarget, true, sasProgramPath, undefined, undefined, mockAuthConfig, undefined, null, undefined);
170
172
  return [2 /*return*/];
171
173
  }
172
174
  });
@@ -184,7 +186,11 @@ describe('RequestCommand', function () {
184
186
  '--data',
185
187
  dataFilePath,
186
188
  '--config',
187
- configFilePath
189
+ configFilePath,
190
+ '--output',
191
+ outputPath,
192
+ '--log',
193
+ logPath
188
194
  ]);
189
195
  command = new requestCommand_1.RequestCommand(args);
190
196
  return [4 /*yield*/, command.execute()];
@@ -196,7 +202,7 @@ describe('RequestCommand', function () {
196
202
  expect(command.name).toEqual('request');
197
203
  expect(targetInfo.target).toEqual(target);
198
204
  expect(targetInfo.isLocal).toBeTrue();
199
- expect(requestModule.runSasJob).toHaveBeenCalledWith(target, true, sasProgramPath, dataFilePath, configFilePath, undefined);
205
+ expect(requestModule.runSasJob).toHaveBeenCalledWith(target, true, sasProgramPath, dataFilePath, configFilePath, undefined, undefined, null, outputPath);
200
206
  return [2 /*return*/];
201
207
  }
202
208
  });
@@ -214,7 +220,11 @@ describe('RequestCommand', function () {
214
220
  '-d',
215
221
  dataFilePath,
216
222
  '-c',
217
- configFilePath
223
+ configFilePath,
224
+ '-o',
225
+ outputPath,
226
+ '-l',
227
+ logPath
218
228
  ]);
219
229
  command = new requestCommand_1.RequestCommand(args);
220
230
  return [4 /*yield*/, command.execute()];
@@ -226,7 +236,7 @@ describe('RequestCommand', function () {
226
236
  expect(command.name).toEqual('request');
227
237
  expect(targetInfo.target).toEqual(target);
228
238
  expect(targetInfo.isLocal).toBeTrue();
229
- expect(requestModule.runSasJob).toHaveBeenCalledWith(target, true, sasProgramPath, dataFilePath, configFilePath, undefined);
239
+ expect(requestModule.runSasJob).toHaveBeenCalledWith(target, true, sasProgramPath, dataFilePath, configFilePath, undefined, undefined, null, outputPath);
230
240
  return [2 /*return*/];
231
241
  }
232
242
  });
package/build/config.json CHANGED
@@ -235,6 +235,7 @@
235
235
  },
236
236
  "macroFolders": ["sasjs/macros"],
237
237
  "programFolders": ["sasjs/programs"],
238
+ "binaryFolders": ["sasjs/binaries"],
238
239
  "serverType": "SASVIYA",
239
240
  "targets": [
240
241
  {
@@ -39,6 +39,7 @@ export declare function getFolders(): Promise<any>;
39
39
  * @param {Target} target- the target to check program folders for.
40
40
  */
41
41
  export declare function getProgramFolders(target: Target): Promise<string[]>;
42
+ export declare function getBinaryFolders(target: Target): Promise<string[]>;
42
43
  /**
43
44
  * Returns SAS macro folders from configuration.
44
45
  * This list includes both common and target-specific folders.
@@ -71,7 +71,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
71
71
  return (mod && mod.__esModule) ? mod : { "default": mod };
72
72
  };
73
73
  Object.defineProperty(exports, "__esModule", { value: true });
74
- exports.getTestTearDown = exports.getTestSetUp = exports.overrideEnvVariables = exports.getAccessToken = exports.getAuthConfig = exports.getProjectRoot = exports.sanitizeAppLoc = exports.getMacroCorePath = exports.getStreamConfig = exports.getMacroFolders = exports.getProgramFolders = exports.getFolders = exports.saveToLocalConfig = exports.saveLocalConfigFile = exports.getLocalOrGlobalConfig = exports.getLocalConfig = exports.removeFromLocalConfig = exports.removeFromGlobalConfig = exports.saveToGlobalConfig = exports.saveGlobalRcFile = exports.getLocalRcFile = exports.getGlobalRcFile = exports.findTargetInConfiguration = exports.getConfiguration = void 0;
74
+ exports.getTestTearDown = exports.getTestSetUp = exports.overrideEnvVariables = exports.getAccessToken = exports.getAuthConfig = exports.getProjectRoot = exports.sanitizeAppLoc = exports.getMacroCorePath = exports.getStreamConfig = exports.getMacroFolders = exports.getBinaryFolders = exports.getProgramFolders = exports.getFolders = exports.saveToLocalConfig = exports.saveLocalConfigFile = exports.getLocalOrGlobalConfig = exports.getLocalConfig = exports.removeFromLocalConfig = exports.removeFromGlobalConfig = exports.saveToGlobalConfig = exports.saveGlobalRcFile = exports.getLocalRcFile = exports.getGlobalRcFile = exports.findTargetInConfiguration = exports.getConfiguration = void 0;
75
75
  var node_1 = __importDefault(require("@sasjs/adapter/node"));
76
76
  var utils_1 = require("@sasjs/utils");
77
77
  var auth_1 = require("./auth");
@@ -641,6 +641,32 @@ function getProgramFolders(target) {
641
641
  });
642
642
  }
643
643
  exports.getProgramFolders = getProgramFolders;
644
+ function getBinaryFolders(target) {
645
+ return __awaiter(this, void 0, void 0, function () {
646
+ var binaryFolders, localConfig, buildSourceFolder;
647
+ return __generator(this, function (_a) {
648
+ switch (_a.label) {
649
+ case 0:
650
+ binaryFolders = [];
651
+ return [4 /*yield*/, getLocalConfig().catch(function () { return null; })];
652
+ case 1:
653
+ localConfig = _a.sent();
654
+ if (localConfig === null || localConfig === void 0 ? void 0 : localConfig.binaryFolders) {
655
+ binaryFolders = binaryFolders.concat(localConfig.binaryFolders);
656
+ }
657
+ if (target === null || target === void 0 ? void 0 : target.binaryFolders) {
658
+ binaryFolders = binaryFolders.concat(target.binaryFolders);
659
+ }
660
+ buildSourceFolder = process.sasjsConstants.buildSourceFolder;
661
+ binaryFolders = binaryFolders.map(function (binaryFolder) {
662
+ return utils_1.getAbsolutePath(binaryFolder, buildSourceFolder);
663
+ });
664
+ return [2 /*return*/, __spreadArray([], __read(new Set(binaryFolders)))];
665
+ }
666
+ });
667
+ });
668
+ }
669
+ exports.getBinaryFolders = getBinaryFolders;
644
670
  /**
645
671
  * Returns SAS macro folders from configuration.
646
672
  * This list includes both common and target-specific folders.
@@ -12,7 +12,7 @@ function displayError(err, errorMessage) {
12
12
  if (errorMessage === void 0) { errorMessage = ''; }
13
13
  if (errorMessage)
14
14
  errorMessage = errorMessage + "\n";
15
- if (err) {
15
+ if (err !== undefined) {
16
16
  var failureDetails = '';
17
17
  if (err.hasOwnProperty('error')) {
18
18
  var body = err.error || null;
@@ -0,0 +1 @@
1
+ export declare const getLogFilePath: (logArg: unknown, jobPath: string) => string | undefined;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getLogFilePath = void 0;
7
+ var path_1 = __importDefault(require("path"));
8
+ var getLogFilePath = function (logArg, jobPath) {
9
+ if (logArg === undefined || !jobPath || jobPath === '')
10
+ return undefined;
11
+ if (logArg) {
12
+ var currentDirPath = path_1.default.isAbsolute(logArg)
13
+ ? ''
14
+ : process.projectDir;
15
+ return path_1.default.join(currentDirPath, logArg);
16
+ }
17
+ var logFileName = jobPath.split('/').slice(-1).pop() + ".log";
18
+ return path_1.default.join(process.projectDir, logFileName);
19
+ };
20
+ exports.getLogFilePath = getLogFilePath;
@@ -0,0 +1 @@
1
+ export declare const saveLog: (logData: any, logFile: string | undefined, jobPath: string, returnStatusOnly: boolean) => Promise<void>;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.saveLog = void 0;
43
+ var utils_1 = require("@sasjs/utils");
44
+ var path_1 = __importDefault(require("path"));
45
+ var _1 = require(".");
46
+ var saveLog = function (logData, logFile, jobPath, returnStatusOnly) { return __awaiter(void 0, void 0, void 0, function () {
47
+ var logPath, folderPath, parentFolderPath, logLines;
48
+ var _a;
49
+ return __generator(this, function (_b) {
50
+ switch (_b.label) {
51
+ case 0:
52
+ if (logFile) {
53
+ logPath = logFile;
54
+ }
55
+ else {
56
+ logPath = path_1.default.join(process.projectDir, jobPath.split(path_1.default.sep).slice(-1).pop() + ".log");
57
+ }
58
+ folderPath = logPath.split(path_1.default.sep);
59
+ folderPath.pop();
60
+ parentFolderPath = folderPath.join(path_1.default.sep);
61
+ return [4 /*yield*/, utils_1.folderExists(parentFolderPath)];
62
+ case 1:
63
+ if (!!(_b.sent())) return [3 /*break*/, 3];
64
+ return [4 /*yield*/, utils_1.createFolder(parentFolderPath)];
65
+ case 2:
66
+ _b.sent();
67
+ _b.label = 3;
68
+ case 3:
69
+ logLines = typeof logData === 'object' ? _1.parseLogLines(logData) : logData;
70
+ (_a = process.logger) === null || _a === void 0 ? void 0 : _a.info("Creating log file at " + logPath + " .");
71
+ return [4 /*yield*/, utils_1.createFile(logPath, logLines)];
72
+ case 4:
73
+ _b.sent();
74
+ if (!returnStatusOnly)
75
+ _1.displaySuccess("Log saved to " + logPath);
76
+ return [2 /*return*/];
77
+ }
78
+ });
79
+ }); };
80
+ exports.saveLog = saveLog;
@@ -350,7 +350,9 @@ var verifyPackageJsonContent = function (parentFolderName) {
350
350
  case 2:
351
351
  packageJsonContent = _a.sent();
352
352
  packageJson = JSON.parse(packageJsonContent);
353
- expect(packageJson.dependencies).toEqual(expect.objectContaining({ '@sasjs/core': expect.anything() }));
353
+ expect(parentFolderName.includes('minimal')
354
+ ? packageJson.devDependencies
355
+ : packageJson.dependencies).toEqual(expect.objectContaining({ '@sasjs/core': expect.anything() }));
354
356
  return [2 /*return*/];
355
357
  }
356
358
  });
@@ -410,7 +410,7 @@ function executeShellScript(filePath, logFilePath) {
410
410
  return __generator(this, function (_b) {
411
411
  switch (_b.label) {
412
412
  case 0:
413
- shellCommand = exports.isWindows() ? "" + filePath : "bash " + filePath;
413
+ shellCommand = exports.isWindows() ? "sh " + filePath : "bash " + filePath;
414
414
  result = shelljs_1.default.exec(shellCommand, { silent: true });
415
415
  if (!result.code) return [3 /*break*/, 1];
416
416
  (_a = process.logger) === null || _a === void 0 ? void 0 : _a.error("Error: " + result.stderr);
package/package.json CHANGED
@@ -49,10 +49,10 @@
49
49
  "access": "public"
50
50
  },
51
51
  "dependencies": {
52
- "@sasjs/adapter": "3.3.1",
53
- "@sasjs/core": "^3.8.0",
52
+ "@sasjs/adapter": "3.4.1",
53
+ "@sasjs/core": "3.10.0",
54
54
  "@sasjs/lint": "1.11.2",
55
- "@sasjs/utils": "2.34.1",
55
+ "@sasjs/utils": "2.35.0",
56
56
  "chalk": "4.1.2",
57
57
  "csv-stringify": "5.6.5",
58
58
  "dotenv": "10.0.0",
@@ -67,7 +67,7 @@
67
67
  "node-graphviz": "0.1.0",
68
68
  "ora": "5.4.1",
69
69
  "rimraf": "3.0.2",
70
- "shelljs": "0.8.4",
70
+ "shelljs": "0.8.5",
71
71
  "xml": "1.0.1",
72
72
  "yargs": "17.2.1"
73
73
  },
@@ -97,5 +97,5 @@
97
97
  "typescript": "4.3.5",
98
98
  "util": "0.12.4"
99
99
  },
100
- "version": "3.4.1"
100
+ "version": "3.6.1"
101
101
  }