@sasjs/cli 3.19.0 → 3.19.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -206,7 +206,7 @@ function getAndValidateUpdateExisting(targetScope, targetName) {
206
206
  return __generator(this, function (_b) {
207
207
  switch (_b.label) {
208
208
  case 0: return [4 /*yield*/, (0, config_1.findTargetInConfiguration)(targetName, targetScope)
209
- .then(function (res) { return res.target.toJson(); })
209
+ .then(function (res) { return res.target.toJson(false); })
210
210
  .catch(function (_) { return undefined; })];
211
211
  case 1:
212
212
  targetJson = _b.sent();
@@ -62,30 +62,14 @@ exports.angularAppFiles = {
62
62
  ],
63
63
  subFolders: [
64
64
  {
65
- folderName: 'components',
66
- files: [],
67
- subFolders: [
68
- {
69
- folderName: 'login-modal',
70
- files: [
71
- { fileName: 'login-modal.component.html' },
72
- { fileName: 'login-modal.component.scss' },
73
- { fileName: 'login-modal.component.spec.ts' },
74
- { fileName: 'login-modal.component.ts' }
75
- ],
76
- subFolders: []
77
- },
78
- {
79
- folderName: 'requests-modal',
80
- files: [
81
- { fileName: 'requests-modal.component.html' },
82
- { fileName: 'requests-modal.component.scss' },
83
- { fileName: 'requests-modal.component.spec.ts' },
84
- { fileName: 'requests-modal.component.ts' }
85
- ],
86
- subFolders: []
87
- }
88
- ]
65
+ folderName: 'sasjs-ui',
66
+ files: [
67
+ { fileName: 'sasjs-ui.component.html' },
68
+ { fileName: 'sasjs-ui.component.spec.ts' },
69
+ { fileName: 'sasjs-ui.component.scss' },
70
+ { fileName: 'sasjs-ui.component.ts' }
71
+ ],
72
+ subFolders: []
89
73
  },
90
74
  {
91
75
  folderName: 'data',
@@ -100,9 +100,9 @@ function deploy(target, isLocal, sasjs) {
100
100
  return [3 /*break*/, 8];
101
101
  case 6: return [4 /*yield*/, (0, utils_2.asyncForEach)(deployScripts, function (deployScript) { return __awaiter(_this, void 0, void 0, function () {
102
102
  var deployScriptPath, deployScriptContent, linesToExecute, deployScriptName, logPath;
103
- var _a, _b, _c;
104
- return __generator(this, function (_d) {
105
- switch (_d.label) {
103
+ var _a, _b, _c, _d;
104
+ return __generator(this, function (_e) {
105
+ switch (_e.label) {
106
106
  case 0:
107
107
  deployScriptPath = (0, utils_2.getAbsolutePath)(deployScript, process.projectDir);
108
108
  if (!(0, file_1.isSasFile)(deployScript)) return [3 /*break*/, 6];
@@ -111,7 +111,7 @@ function deploy(target, isLocal, sasjs) {
111
111
  // split into lines
112
112
  ];
113
113
  case 1:
114
- deployScriptContent = _d.sent();
114
+ deployScriptContent = _e.sent();
115
115
  linesToExecute = deployScriptContent
116
116
  .replace(/\r\n/g, '\n')
117
117
  .split('\n');
@@ -119,23 +119,26 @@ function deploy(target, isLocal, sasjs) {
119
119
  if (!(target.serverType === utils_2.ServerType.SasViya)) return [3 /*break*/, 3];
120
120
  return [4 /*yield*/, deployToSasViya(deployScriptName, target, isLocal, linesToExecute, logFilePath, streamConfig)];
121
121
  case 2:
122
- _d.sent();
122
+ _e.sent();
123
123
  return [3 /*break*/, 5];
124
124
  case 3: return [4 /*yield*/, deployToSas9(deployScriptName, target, linesToExecute, logFilePath, streamConfig)];
125
125
  case 4:
126
- _d.sent();
127
- _d.label = 5;
128
- case 5: return [3 /*break*/, 8];
126
+ _e.sent();
127
+ _e.label = 5;
128
+ case 5: return [3 /*break*/, 9];
129
129
  case 6:
130
130
  if (!(0, file_1.isShellScript)(deployScript)) return [3 /*break*/, 8];
131
131
  (_b = process.logger) === null || _b === void 0 ? void 0 : _b.info("Executing shell script ".concat(deployScript, " ..."));
132
132
  logPath = path_1.default.join(process.projectDir, 'sasjsbuild', "".concat(path_1.default.basename(deployScript).replace('.sh', ''), ".log"));
133
133
  return [4 /*yield*/, (0, utils_1.executeShellScript)(deployScriptPath, logPath)];
134
134
  case 7:
135
- _d.sent();
135
+ _e.sent();
136
136
  (_c = process.logger) === null || _c === void 0 ? void 0 : _c.success("Shell script execution completed! Log is here: ".concat(logPath));
137
- _d.label = 8;
138
- case 8: return [2 /*return*/];
137
+ return [3 /*break*/, 9];
138
+ case 8:
139
+ (_d = process.logger) === null || _d === void 0 ? void 0 : _d.error("Unable to process script located at ".concat(deployScriptPath));
140
+ _e.label = 9;
141
+ case 9: return [2 /*return*/];
139
142
  }
140
143
  });
141
144
  }); })];
@@ -209,10 +209,12 @@ function printHelpText() {
209
209
  },
210
210
  {
211
211
  name: 'run',
212
- title: 'run <sasFilePath> -t <targetName>',
212
+ title: 'run <sasFilePath> -t <targetName> --source /local/run.json -l <log/file/path>',
213
213
  description: [
214
214
  "lets the user run a given SAS file against a specified target.",
215
- "The target can exist either in the local project configuration or in the global .sasjsrc file."
215
+ "The target can exist either in the local project configuration or in the global .sasjsrc file.",
216
+ "Providing log flag (--log or -l) is optional. If not present, the log is stored locally with a timestamp. If present, CLI will fetch and save the log to the specified location. If a relative location, it will be relative to the directory in which the command is invoked.",
217
+ "Providing source flag (--source or -s) is optional. It should point to a JSON file with the following structure: {\"macroVars\": {\"var1\": \"val1\", \"var2\": \"val2\"}}. These will be parsed into SAS \"%let\" statements and pre-append to the SAS code being run."
216
218
  ]
217
219
  },
218
220
  {
@@ -42,9 +42,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
42
42
  exports.executeJobSas9 = void 0;
43
43
  var path_1 = __importDefault(require("path"));
44
44
  var utils_1 = require("@sasjs/utils");
45
- var file_1 = require("../../../../utils/file");
46
45
  var displayResult_1 = require("../../../../utils/displayResult");
47
46
  var utils_2 = require("../utils");
47
+ var parseSourceFile_1 = require("../../../../utils/parseSourceFile");
48
48
  /**
49
49
  * Triggers an existing Stored Process for execution as a "job". See online documentation here: https://cli.sasjs.io/job/
50
50
  * @param {object} sasjs - Configuration object of the SASJS adapter.
@@ -56,50 +56,35 @@ var utils_2 = require("../utils");
56
56
  */
57
57
  function executeJobSas9(sasjs, config, jobPath, logFile, output, source) {
58
58
  return __awaiter(this, void 0, void 0, function () {
59
- var macroVars, currentDirPath, startTime, result, endTime, outputJson, currentDirPath, outputPath, folderPath, parentFolderPath, error_1;
59
+ var macroVars, startTime, result, endTime, outputJson, currentDirPath, outputPath, folderPath, parentFolderPath, error_1;
60
60
  return __generator(this, function (_a) {
61
61
  switch (_a.label) {
62
62
  case 0:
63
63
  macroVars = null;
64
- if (!source) return [3 /*break*/, 3];
65
- currentDirPath = path_1.default.isAbsolute(source) ? '' : process.projectDir;
66
- source = path_1.default.join(currentDirPath, source);
67
- if (!(0, file_1.isJsonFile)(source))
68
- throw 'Source file has to be JSON.';
69
- return [4 /*yield*/, (0, utils_1.fileExists)(source).catch(function (_) {
70
- throw 'Error while checking if source file exists.';
71
- })];
64
+ if (!source) return [3 /*break*/, 2];
65
+ return [4 /*yield*/, (0, parseSourceFile_1.parseSourceFile)(source)];
72
66
  case 1:
73
- _a.sent();
74
- return [4 /*yield*/, (0, utils_1.readFile)(source).catch(function (_) {
75
- throw 'Error while reading source file.';
76
- })];
67
+ macroVars = _a.sent();
68
+ _a.label = 2;
77
69
  case 2:
78
- source = _a.sent();
79
- macroVars = JSON.parse(source);
80
- if (!(0, utils_1.isMacroVars)(macroVars)) {
81
- throw "Provided source is not valid. An example of valid source:\n{ macroVars: { name1: 'value1', name2: 'value2' } }";
82
- }
83
- _a.label = 3;
84
- case 3:
85
70
  startTime = new Date().getTime();
86
71
  return [4 /*yield*/, sasjs.request(jobPath, macroVars, config)];
87
- case 4:
72
+ case 3:
88
73
  result = _a.sent();
89
74
  endTime = new Date().getTime();
90
- if (!result) return [3 /*break*/, 15];
91
- if (!(result.status === 200)) return [3 /*break*/, 14];
75
+ if (!result) return [3 /*break*/, 14];
76
+ if (!(result.status === 200)) return [3 /*break*/, 13];
92
77
  process.logger.success("Job executed successfully! in ".concat((endTime - startTime) / 1000, " seconds"));
93
- if (!(!!logFile && result.log)) return [3 /*break*/, 6];
78
+ if (!(!!logFile && result.log)) return [3 /*break*/, 5];
94
79
  return [4 /*yield*/, (0, utils_2.saveLog)(result.log, logFile, jobPath, false)];
95
- case 5:
80
+ case 4:
96
81
  _a.sent();
82
+ _a.label = 5;
83
+ case 5:
84
+ if (!(!!output && result.result)) return [3 /*break*/, 12];
97
85
  _a.label = 6;
98
86
  case 6:
99
- if (!(!!output && result.result)) return [3 /*break*/, 13];
100
- _a.label = 7;
101
- case 7:
102
- _a.trys.push([7, 12, , 13]);
87
+ _a.trys.push([6, 11, , 12]);
103
88
  outputJson = JSON.stringify(result.result, null, 2);
104
89
  currentDirPath = path_1.default.isAbsolute(output)
105
90
  ? ''
@@ -111,27 +96,27 @@ function executeJobSas9(sasjs, config, jobPath, logFile, output, source) {
111
96
  folderPath.pop();
112
97
  parentFolderPath = folderPath.join(path_1.default.sep);
113
98
  return [4 /*yield*/, (0, utils_1.folderExists)(parentFolderPath)];
114
- case 8:
115
- if (!!(_a.sent())) return [3 /*break*/, 10];
99
+ case 7:
100
+ if (!!(_a.sent())) return [3 /*break*/, 9];
116
101
  return [4 /*yield*/, (0, utils_1.createFolder)(parentFolderPath)];
117
- case 9:
102
+ case 8:
118
103
  _a.sent();
119
- _a.label = 10;
120
- case 10: return [4 /*yield*/, (0, utils_1.createFile)(outputPath, outputJson)];
121
- case 11:
104
+ _a.label = 9;
105
+ case 9: return [4 /*yield*/, (0, utils_1.createFile)(outputPath, outputJson)];
106
+ case 10:
122
107
  _a.sent();
123
108
  (0, displayResult_1.displaySuccess)("Output saved to: ".concat(outputPath));
124
- return [3 /*break*/, 13];
125
- case 12:
109
+ return [3 /*break*/, 12];
110
+ case 11:
126
111
  error_1 = _a.sent();
127
112
  (0, displayResult_1.displayError)(error_1, 'An error has occurred when parsing an output of the job.');
128
- return [3 /*break*/, 13];
129
- case 13: return [3 /*break*/, 15];
130
- case 14:
113
+ return [3 /*break*/, 12];
114
+ case 12: return [3 /*break*/, 14];
115
+ case 13:
131
116
  process.logger.error(result.message);
132
117
  process.logger.error(JSON.stringify(result.error, null, 2));
133
- _a.label = 15;
134
- case 15: return [2 /*return*/, result];
118
+ _a.label = 14;
119
+ case 14: return [2 /*return*/, result];
135
120
  }
136
121
  });
137
122
  });
@@ -4,7 +4,8 @@ import { Target } from '@sasjs/utils';
4
4
  * @param {Target} target - the target to run the SAS code on.
5
5
  * @param {string} filePath - the path to the file containing SAS code.
6
6
  * @param {boolean} compile - compiles sas file present at 'filePath' before running code.
7
+ * @param {string} logFile - (Optional) Path to log file.
7
8
  */
8
- export declare function runSasCode(target: Target, filePath: string, compile?: boolean): Promise<{
9
+ export declare function runSasCode(target: Target, filePath: string, compile?: boolean, logFile?: string, source?: string): Promise<{
9
10
  log: any;
10
11
  }>;
@@ -35,6 +35,31 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
35
35
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
36
  }
37
37
  };
38
+ var __read = (this && this.__read) || function (o, n) {
39
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
40
+ if (!m) return o;
41
+ var i = m.call(o), r, ar = [], e;
42
+ try {
43
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
44
+ }
45
+ catch (error) { e = { error: error }; }
46
+ finally {
47
+ try {
48
+ if (r && !r.done && (m = i["return"])) m.call(i);
49
+ }
50
+ finally { if (e) throw e.error; }
51
+ }
52
+ return ar;
53
+ };
54
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
55
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
56
+ if (ar || !(i in from)) {
57
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
58
+ ar[i] = from[i];
59
+ }
60
+ }
61
+ return to.concat(ar || Array.prototype.slice.call(from));
62
+ };
38
63
  var __importDefault = (this && this.__importDefault) || function (mod) {
39
64
  return (mod && mod.__esModule) ? mod : { "default": mod };
40
65
  };
@@ -49,17 +74,20 @@ var __1 = require("../");
49
74
  var utils_2 = require("../../utils/");
50
75
  var axios_1 = __importDefault(require("axios"));
51
76
  var getDestinationPath_1 = require("../compile/internal/getDestinationPath");
77
+ var saveLog_1 = require("../../utils/saveLog");
78
+ var parseSourceFile_1 = require("../../utils/parseSourceFile");
52
79
  /**
53
80
  * Runs SAS code from a given file on the specified target.
54
81
  * @param {Target} target - the target to run the SAS code on.
55
82
  * @param {string} filePath - the path to the file containing SAS code.
56
83
  * @param {boolean} compile - compiles sas file present at 'filePath' before running code.
84
+ * @param {string} logFile - (Optional) Path to log file.
57
85
  */
58
- function runSasCode(target, filePath, compile) {
86
+ function runSasCode(target, filePath, compile, logFile, source) {
59
87
  var _a;
60
88
  if (compile === void 0) { compile = false; }
61
89
  return __awaiter(this, void 0, void 0, function () {
62
- var isTempFile, sourcefilePathParts, sourceFolderPath, sasFilePath, sasFileContent, linesToExecute, result;
90
+ var isTempFile, sourcefilePathParts, sourceFolderPath, sasFilePath, sasFileContent, linesToExecute, macroVars, macroVarStatements, result;
63
91
  var _b;
64
92
  return __generator(this, function (_c) {
65
93
  switch (_c.label) {
@@ -91,34 +119,42 @@ function runSasCode(target, filePath, compile) {
91
119
  case 6:
92
120
  sasFileContent = _c.sent();
93
121
  linesToExecute = sasFileContent.replace(/\r\n/g, '\n').split('\n');
94
- if (!(target.serverType === utils_1.ServerType.SasViya)) return [3 /*break*/, 8];
95
- return [4 /*yield*/, executeOnSasViya(filePath, target, linesToExecute)];
122
+ if (!source) return [3 /*break*/, 8];
123
+ return [4 /*yield*/, (0, parseSourceFile_1.parseSourceFile)(source)];
96
124
  case 7:
97
- result = _c.sent();
98
- return [3 /*break*/, 12];
125
+ macroVars = _c.sent();
126
+ macroVarStatements = (0, utils_2.convertToSASStatements)(macroVars).split('\n');
127
+ linesToExecute = __spreadArray(__spreadArray([], __read(macroVarStatements), false), __read(linesToExecute), false);
128
+ _c.label = 8;
99
129
  case 8:
100
- if (!(target.serverType === utils_1.ServerType.Sas9)) return [3 /*break*/, 10];
101
- return [4 /*yield*/, executeOnSas9(target, linesToExecute)];
130
+ if (!(target.serverType === utils_1.ServerType.SasViya)) return [3 /*break*/, 10];
131
+ return [4 /*yield*/, executeOnSasViya(filePath, target, linesToExecute, logFile)];
102
132
  case 9:
103
133
  result = _c.sent();
104
- return [3 /*break*/, 12];
105
- case 10: return [4 /*yield*/, executeOnSasJS(filePath, target, linesToExecute)];
134
+ return [3 /*break*/, 14];
135
+ case 10:
136
+ if (!(target.serverType === utils_1.ServerType.Sas9)) return [3 /*break*/, 12];
137
+ return [4 /*yield*/, executeOnSas9(target, linesToExecute, logFile)];
106
138
  case 11:
107
139
  result = _c.sent();
108
- _c.label = 12;
109
- case 12:
110
- if (!isTempFile) return [3 /*break*/, 14];
111
- return [4 /*yield*/, (0, utils_1.deleteFile)(filePath)];
140
+ return [3 /*break*/, 14];
141
+ case 12: return [4 /*yield*/, executeOnSasJS(filePath, target, linesToExecute, logFile)];
112
142
  case 13:
113
- _c.sent();
143
+ result = _c.sent();
114
144
  _c.label = 14;
115
- case 14: return [2 /*return*/, result];
145
+ case 14:
146
+ if (!isTempFile) return [3 /*break*/, 16];
147
+ return [4 /*yield*/, (0, utils_1.deleteFile)(filePath)];
148
+ case 15:
149
+ _c.sent();
150
+ _c.label = 16;
151
+ case 16: return [2 /*return*/, result];
116
152
  }
117
153
  });
118
154
  });
119
155
  }
120
156
  exports.runSasCode = runSasCode;
121
- function executeOnSasViya(filePath, target, linesToExecute) {
157
+ function executeOnSasViya(filePath, target, linesToExecute, logFile) {
122
158
  var _a, _b, _c, _d, _e;
123
159
  return __awaiter(this, void 0, void 0, function () {
124
160
  var sasjs, contextName, authConfig, executionResult, log, isOutput, buildDestinationResultsFolder, createdFilePath;
@@ -145,18 +181,16 @@ function executeOnSasViya(filePath, target, linesToExecute) {
145
181
  return [4 /*yield*/, sasjs
146
182
  .executeScriptSASViya(path_1.default.basename(filePath), linesToExecute, contextName, authConfig)
147
183
  .catch(function (err) { return __awaiter(_this, void 0, void 0, function () {
148
- var log, createdFilePath;
149
- var _a;
150
- return __generator(this, function (_b) {
151
- switch (_b.label) {
184
+ var log;
185
+ return __generator(this, function (_a) {
186
+ switch (_a.label) {
152
187
  case 0:
153
188
  log = err.log;
154
189
  if (!log)
155
190
  throw new node_2.ErrorResponse('We were not able to fetch the log this time.');
156
- return [4 /*yield*/, createOutputFile(log)];
191
+ return [4 /*yield*/, createOutputFile(log, logFile)];
157
192
  case 1:
158
- createdFilePath = _b.sent();
159
- (_a = process.logger) === null || _a === void 0 ? void 0 : _a.error("Log file has been created at ".concat(createdFilePath, " ."));
193
+ _a.sent();
160
194
  throw new node_2.ErrorResponse('Find more error details in the log file.');
161
195
  }
162
196
  });
@@ -178,7 +212,7 @@ function executeOnSasViya(filePath, target, linesToExecute) {
178
212
  (_c = process.logger) === null || _c === void 0 ? void 0 : _c.success('Job execution completed!');
179
213
  buildDestinationResultsFolder = process.sasjsConstants.buildDestinationResultsFolder;
180
214
  (_d = process.logger) === null || _d === void 0 ? void 0 : _d.info("Creating ".concat(isOutput ? 'output' : 'log', " file in ").concat(buildDestinationResultsFolder, " ."));
181
- return [4 /*yield*/, createOutputFile(log)];
215
+ return [4 /*yield*/, createOutputFile(log, undefined, isOutput)];
182
216
  case 3:
183
217
  createdFilePath = _f.sent();
184
218
  (_e = process.logger) === null || _e === void 0 ? void 0 : _e.success("".concat(isOutput ? 'Output' : 'Log', " file has been created at ").concat(createdFilePath, " ."));
@@ -187,13 +221,13 @@ function executeOnSasViya(filePath, target, linesToExecute) {
187
221
  });
188
222
  });
189
223
  }
190
- function executeOnSas9(target, linesToExecute) {
191
- var _a, _b, _c;
224
+ function executeOnSas9(target, linesToExecute, logFile) {
225
+ var _a;
192
226
  return __awaiter(this, void 0, void 0, function () {
193
- var username, password, sas9CredentialsError, sasjs, buildDestinationResultsFolder, executionResult, createdFilePath;
227
+ var username, password, sas9CredentialsError, sasjs, executionResult;
194
228
  var _this = this;
195
- return __generator(this, function (_d) {
196
- switch (_d.label) {
229
+ return __generator(this, function (_b) {
230
+ switch (_b.label) {
197
231
  case 0:
198
232
  if (target.authConfigSas9) {
199
233
  username = target.authConfigSas9.userName;
@@ -215,22 +249,18 @@ function executeOnSas9(target, linesToExecute) {
215
249
  serverType: target.serverType,
216
250
  debug: true
217
251
  });
218
- buildDestinationResultsFolder = process.sasjsConstants.buildDestinationResultsFolder;
219
252
  return [4 /*yield*/, sasjs
220
253
  .executeScriptSAS9(linesToExecute, username, password)
221
254
  .catch(function (err) { return __awaiter(_this, void 0, void 0, function () {
222
- var log, createdFilePath_1;
223
- var _a, _b;
224
- return __generator(this, function (_c) {
225
- switch (_c.label) {
255
+ var log;
256
+ return __generator(this, function (_a) {
257
+ switch (_a.label) {
226
258
  case 0:
227
259
  if (!(err && err.payload && err.payload.log)) return [3 /*break*/, 2];
228
260
  log = err.payload.log;
229
- (_a = process.logger) === null || _a === void 0 ? void 0 : _a.info("Creating log file in ".concat(buildDestinationResultsFolder, " ."));
230
- return [4 /*yield*/, createOutputFile(log)];
261
+ return [4 /*yield*/, createOutputFile(log, logFile)];
231
262
  case 1:
232
- createdFilePath_1 = _c.sent();
233
- (_b = process.logger) === null || _b === void 0 ? void 0 : _b.success("Log file has been created at ".concat(createdFilePath_1, " ."));
263
+ _a.sent();
234
264
  throw new node_2.ErrorResponse('Find more error details in the log file.');
235
265
  case 2:
236
266
  if (err && err.errorCode === 404) {
@@ -241,33 +271,30 @@ function executeOnSas9(target, linesToExecute) {
241
271
  });
242
272
  }); })];
243
273
  case 1:
244
- executionResult = _d.sent();
274
+ executionResult = _b.sent();
245
275
  (_a = process.logger) === null || _a === void 0 ? void 0 : _a.success('Job execution completed!');
246
- (_b = process.logger) === null || _b === void 0 ? void 0 : _b.info("Creating log file in ".concat(buildDestinationResultsFolder, " ."));
247
- return [4 /*yield*/, createOutputFile(executionResult || '')];
276
+ return [4 /*yield*/, createOutputFile(executionResult || '', logFile)];
248
277
  case 2:
249
- createdFilePath = _d.sent();
250
- (_c = process.logger) === null || _c === void 0 ? void 0 : _c.success("Log file has been created at ".concat(createdFilePath, " ."));
278
+ _b.sent();
251
279
  return [2 /*return*/, { log: executionResult }];
252
280
  }
253
281
  });
254
282
  });
255
283
  }
256
- function executeOnSasJS(filePath, target, linesToExecute) {
257
- var _a, _b, _c;
284
+ function executeOnSasJS(filePath, target, linesToExecute, logFile) {
285
+ var _a;
258
286
  return __awaiter(this, void 0, void 0, function () {
259
- var authConfig, buildDestinationResultsFolder, sasjs, fileExtension, executionResult, createdFilePath;
260
- return __generator(this, function (_d) {
261
- switch (_d.label) {
287
+ var authConfig, sasjs, fileExtension, executionResult;
288
+ return __generator(this, function (_b) {
289
+ switch (_b.label) {
262
290
  case 0: return [4 /*yield*/, (0, utils_2.isSasJsServerInServerMode)(target)];
263
291
  case 1:
264
- if (!_d.sent()) return [3 /*break*/, 3];
292
+ if (!_b.sent()) return [3 /*break*/, 3];
265
293
  return [4 /*yield*/, (0, config_1.getAuthConfig)(target)];
266
294
  case 2:
267
- authConfig = _d.sent();
268
- _d.label = 3;
295
+ authConfig = _b.sent();
296
+ _b.label = 3;
269
297
  case 3:
270
- buildDestinationResultsFolder = process.sasjsConstants.buildDestinationResultsFolder;
271
298
  sasjs = new node_1.default({
272
299
  serverUrl: target.serverUrl,
273
300
  httpsAgentOptions: target.httpsAgentOptions,
@@ -278,31 +305,31 @@ function executeOnSasJS(filePath, target, linesToExecute) {
278
305
  fileExtension = path_1.default.extname(filePath).slice(1);
279
306
  return [4 /*yield*/, sasjs.executeScriptSASjs(linesToExecute.join('\n'), fileExtension, authConfig)];
280
307
  case 4:
281
- executionResult = _d.sent();
308
+ executionResult = _b.sent();
282
309
  (_a = process.logger) === null || _a === void 0 ? void 0 : _a.success('Job execution completed!');
283
- (_b = process.logger) === null || _b === void 0 ? void 0 : _b.info("Creating log file in ".concat(buildDestinationResultsFolder, " ."));
284
- return [4 /*yield*/, createOutputFile(executionResult || '')];
310
+ return [4 /*yield*/, createOutputFile(executionResult || '', logFile)];
285
311
  case 5:
286
- createdFilePath = _d.sent();
287
- (_c = process.logger) === null || _c === void 0 ? void 0 : _c.success("Log file has been created at ".concat(createdFilePath, " ."));
312
+ _b.sent();
288
313
  return [2 /*return*/, { log: executionResult }];
289
314
  }
290
315
  });
291
316
  });
292
317
  }
293
- function createOutputFile(log) {
318
+ function createOutputFile(log, logFilePath, silent) {
294
319
  return __awaiter(this, void 0, void 0, function () {
295
- var timestamp, buildDestinationResultsFolder, outputFilePath;
320
+ var timestamp, buildDestinationResultsFolder;
296
321
  return __generator(this, function (_a) {
297
322
  switch (_a.label) {
298
323
  case 0:
299
324
  timestamp = (0, utils_1.generateTimestamp)();
300
325
  buildDestinationResultsFolder = process.sasjsConstants.buildDestinationResultsFolder;
301
- outputFilePath = path_1.default.join(buildDestinationResultsFolder, "sasjs-run-".concat(timestamp, ".log"));
302
- return [4 /*yield*/, (0, utils_1.createFile)(outputFilePath, log)];
326
+ if (!logFilePath) {
327
+ logFilePath = path_1.default.join(buildDestinationResultsFolder, "sasjs-run-".concat(timestamp, ".log"));
328
+ }
329
+ return [4 /*yield*/, (0, saveLog_1.saveLog)(log || '', logFilePath, '', false, silent)];
303
330
  case 1:
304
331
  _a.sent();
305
- return [2 /*return*/, outputFilePath];
332
+ return [2 /*return*/, logFilePath];
306
333
  }
307
334
  });
308
335
  });
@@ -72,6 +72,14 @@ var examples = [
72
72
  {
73
73
  command: 'sasjs run ./path/run-job.sas -t targetName -c',
74
74
  description: ''
75
+ },
76
+ {
77
+ command: 'sasjs run ./path/run-job.sas -t targetName -c --log ./path/file.log',
78
+ description: ''
79
+ },
80
+ {
81
+ command: 'sasjs run ./path/run-job.sas -t targetName --source ./path/source.json',
82
+ description: ''
75
83
  }
76
84
  ];
77
85
  var RunCommand = /** @class */ (function (_super) {
@@ -84,6 +92,17 @@ var RunCommand = /** @class */ (function (_super) {
84
92
  alias: 'c',
85
93
  default: false,
86
94
  description: 'Used to compile the program prior to execution. Useful for including dependent macros and includes. More info here: https://cli.sasjs.io/compile'
95
+ },
96
+ log: {
97
+ type: 'string',
98
+ alias: 'l',
99
+ default: '',
100
+ description: 'Path where the log of the finished job will be saved.'
101
+ },
102
+ source: {
103
+ type: 'string',
104
+ alias: 's',
105
+ description: 'Path to an input JSON containing job variables.'
87
106
  }
88
107
  },
89
108
  syntax: syntax,
@@ -94,14 +113,14 @@ var RunCommand = /** @class */ (function (_super) {
94
113
  }
95
114
  RunCommand.prototype.execute = function () {
96
115
  return __awaiter(this, void 0, void 0, function () {
97
- var target, _a, sasFilePath, compile;
116
+ var target, _a, sasFilePath, compile, log, source;
98
117
  return __generator(this, function (_b) {
99
118
  switch (_b.label) {
100
119
  case 0: return [4 /*yield*/, this.getTargetInfo()];
101
120
  case 1:
102
121
  target = (_b.sent()).target;
103
- _a = this.parsed, sasFilePath = _a.sasFilePath, compile = _a.compile;
104
- return [4 /*yield*/, (0, run_1.runSasCode)(target, sasFilePath, compile)
122
+ _a = this.parsed, sasFilePath = _a.sasFilePath, compile = _a.compile, log = _a.log, source = _a.source;
123
+ return [4 /*yield*/, (0, run_1.runSasCode)(target, sasFilePath, compile, log, source)
105
124
  .then(function () {
106
125
  return command_1.ReturnCode.Success;
107
126
  })
@@ -93,7 +93,9 @@ var target = new utils_1.Target({
93
93
  serverType: utils_1.ServerType.SasViya,
94
94
  contextName: 'test context'
95
95
  });
96
+ var sourceFilePath = 'path/to/source.json';
96
97
  var sasFilePath = 'path/to/soure.sas';
98
+ var logFilePath = 'path/to/log.log';
97
99
  describe('RunCommand', function () {
98
100
  beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
99
101
  return __generator(this, function (_a) {
@@ -111,10 +113,16 @@ describe('RunCommand', function () {
111
113
  it('should parse sasjs run command', function () { return __awaiter(void 0, void 0, void 0, function () {
112
114
  return __generator(this, function (_a) {
113
115
  switch (_a.label) {
114
- case 0: return [4 /*yield*/, executeCommandWrapper([sasFilePath])];
116
+ case 0: return [4 /*yield*/, executeCommandWrapper([
117
+ sasFilePath,
118
+ '--log',
119
+ logFilePath,
120
+ '-s',
121
+ sourceFilePath
122
+ ])];
115
123
  case 1:
116
124
  _a.sent();
117
- expect(runModule.runSasCode).toHaveBeenCalledWith(target, sasFilePath, false);
125
+ expect(runModule.runSasCode).toHaveBeenCalledWith(target, sasFilePath, false, logFilePath, sourceFilePath);
118
126
  return [2 /*return*/];
119
127
  }
120
128
  });
@@ -122,10 +130,19 @@ describe('RunCommand', function () {
122
130
  it('should parse sasjs run command with all arguments', function () { return __awaiter(void 0, void 0, void 0, function () {
123
131
  return __generator(this, function (_a) {
124
132
  switch (_a.label) {
125
- case 0: return [4 /*yield*/, executeCommandWrapper([sasFilePath, '--target', 'test', '--compile'])];
133
+ case 0: return [4 /*yield*/, executeCommandWrapper([
134
+ sasFilePath,
135
+ '--target',
136
+ 'test',
137
+ '--compile',
138
+ '--log',
139
+ logFilePath,
140
+ '--source',
141
+ sourceFilePath
142
+ ])];
126
143
  case 1:
127
144
  _a.sent();
128
- expect(runModule.runSasCode).toHaveBeenCalledWith(target, sasFilePath, true);
145
+ expect(runModule.runSasCode).toHaveBeenCalledWith(target, sasFilePath, true, logFilePath, sourceFilePath);
129
146
  return [2 /*return*/];
130
147
  }
131
148
  });
@@ -133,10 +150,19 @@ describe('RunCommand', function () {
133
150
  it('should parse a sasjs run command with all shorthand arguments', function () { return __awaiter(void 0, void 0, void 0, function () {
134
151
  return __generator(this, function (_a) {
135
152
  switch (_a.label) {
136
- case 0: return [4 /*yield*/, executeCommandWrapper([sasFilePath, '-t', 'test', '-c'])];
153
+ case 0: return [4 /*yield*/, executeCommandWrapper([
154
+ sasFilePath,
155
+ '-t',
156
+ 'test',
157
+ '-c',
158
+ '-l',
159
+ logFilePath,
160
+ '-s',
161
+ sourceFilePath
162
+ ])];
137
163
  case 1:
138
164
  _a.sent();
139
- expect(runModule.runSasCode).toHaveBeenCalledWith(target, sasFilePath, true);
165
+ expect(runModule.runSasCode).toHaveBeenCalledWith(target, sasFilePath, true, logFilePath, sourceFilePath);
140
166
  return [2 /*return*/];
141
167
  }
142
168
  });
@@ -0,0 +1,2 @@
1
+ import { MacroVars } from '@sasjs/utils';
2
+ export declare function parseSourceFile(source: string): Promise<MacroVars>;
@@ -0,0 +1,75 @@
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.parseSourceFile = void 0;
43
+ var utils_1 = require("@sasjs/utils");
44
+ var path_1 = __importDefault(require("path"));
45
+ var file_1 = require("./file");
46
+ function parseSourceFile(source) {
47
+ return __awaiter(this, void 0, void 0, function () {
48
+ var macroVars, currentDirPath;
49
+ return __generator(this, function (_a) {
50
+ switch (_a.label) {
51
+ case 0:
52
+ currentDirPath = path_1.default.isAbsolute(source) ? '' : process.projectDir;
53
+ source = path_1.default.join(currentDirPath, source);
54
+ if (!(0, file_1.isJsonFile)(source))
55
+ throw 'Source file has to be JSON.';
56
+ return [4 /*yield*/, (0, utils_1.fileExists)(source).catch(function (_) {
57
+ throw 'Error while checking if source file exists.';
58
+ })];
59
+ case 1:
60
+ _a.sent();
61
+ return [4 /*yield*/, (0, utils_1.readFile)(source).catch(function (_) {
62
+ throw 'Error while reading source file.';
63
+ })];
64
+ case 2:
65
+ source = _a.sent();
66
+ macroVars = JSON.parse(source);
67
+ if (!(0, utils_1.isMacroVars)(macroVars)) {
68
+ throw "Provided source is not valid. An example of valid source:\n{ macroVars: { name1: 'value1', name2: 'value2' } }";
69
+ }
70
+ return [2 /*return*/, macroVars];
71
+ }
72
+ });
73
+ });
74
+ }
75
+ exports.parseSourceFile = parseSourceFile;
@@ -1 +1 @@
1
- export declare const saveLog: (logData: any, logFile: string | undefined, jobPath: string, returnStatusOnly: boolean) => Promise<void>;
1
+ export declare const saveLog: (logData: any, logFile: string | undefined, jobPath: string, returnStatusOnly: boolean, silent?: boolean) => Promise<void>;
@@ -43,38 +43,42 @@ exports.saveLog = void 0;
43
43
  var utils_1 = require("@sasjs/utils");
44
44
  var path_1 = __importDefault(require("path"));
45
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, "".concat(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*/, (0, utils_1.folderExists)(parentFolderPath)];
62
- case 1:
63
- if (!!(_b.sent())) return [3 /*break*/, 3];
64
- return [4 /*yield*/, (0, utils_1.createFolder)(parentFolderPath)];
65
- case 2:
66
- _b.sent();
67
- _b.label = 3;
68
- case 3:
69
- logLines = typeof logData === 'object' ? (0, _1.parseLogLines)(logData) : logData;
70
- (_a = process.logger) === null || _a === void 0 ? void 0 : _a.info("Creating log file at ".concat(logPath, " ."));
71
- return [4 /*yield*/, (0, utils_1.createFile)(logPath, logLines)];
72
- case 4:
73
- _b.sent();
74
- if (!returnStatusOnly)
75
- (0, _1.displaySuccess)("Log saved to ".concat(logPath));
76
- return [2 /*return*/];
77
- }
46
+ var saveLog = function (logData, logFile, jobPath, returnStatusOnly, silent) {
47
+ if (silent === void 0) { silent = false; }
48
+ return __awaiter(void 0, void 0, void 0, function () {
49
+ var logPath, folderPath, parentFolderPath, logLines;
50
+ var _a;
51
+ return __generator(this, function (_b) {
52
+ switch (_b.label) {
53
+ case 0:
54
+ if (logFile) {
55
+ logPath = logFile;
56
+ }
57
+ else {
58
+ logPath = path_1.default.join(process.projectDir, "".concat(jobPath.split(path_1.default.sep).slice(-1).pop(), ".log"));
59
+ }
60
+ folderPath = logPath.split(path_1.default.sep);
61
+ folderPath.pop();
62
+ parentFolderPath = folderPath.join(path_1.default.sep);
63
+ return [4 /*yield*/, (0, utils_1.folderExists)(parentFolderPath)];
64
+ case 1:
65
+ if (!!(_b.sent())) return [3 /*break*/, 3];
66
+ return [4 /*yield*/, (0, utils_1.createFolder)(parentFolderPath)];
67
+ case 2:
68
+ _b.sent();
69
+ _b.label = 3;
70
+ case 3:
71
+ logLines = typeof logData === 'object' ? (0, _1.parseLogLines)(logData) : logData;
72
+ if (!silent)
73
+ (_a = process.logger) === null || _a === void 0 ? void 0 : _a.info("Creating log file at ".concat(logPath, " ."));
74
+ return [4 /*yield*/, (0, utils_1.createFile)(logPath, logLines)];
75
+ case 4:
76
+ _b.sent();
77
+ if (!returnStatusOnly && !silent)
78
+ (0, _1.displaySuccess)("Log saved to ".concat(logPath));
79
+ return [2 /*return*/];
80
+ }
81
+ });
78
82
  });
79
- }); };
83
+ };
80
84
  exports.saveLog = saveLog;
@@ -1,4 +1,4 @@
1
- import { Target } from '@sasjs/utils';
1
+ import { Target, MacroVars } from '@sasjs/utils';
2
2
  import SASjs from '@sasjs/adapter/node';
3
3
  export declare function inExistingProject(folderPath: string): Promise<boolean>;
4
4
  export declare function diff(a: any[], b: any[]): any[];
@@ -20,6 +20,14 @@ export declare function parseLogLines(logJson: {
20
20
  line: string;
21
21
  }[];
22
22
  }): string;
23
+ /**
24
+ * Converts MacroVars JSON from command source param to sas statements
25
+ * The JSON must have the following structure:
26
+ * {"macroVars": {"var1": "val1", "var2": "val2"}}
27
+ *
28
+ * @param {object} json
29
+ */
30
+ export declare function convertToSASStatements(json: MacroVars): string;
23
31
  export declare const arrToObj: (arr: any[]) => any;
24
32
  export declare const millisecondsToDdHhMmSs: (milliseconds: number) => string;
25
33
  export declare function checkNodeVersion(): void;
@@ -86,7 +86,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
86
86
  return (mod && mod.__esModule) ? mod : { "default": mod };
87
87
  };
88
88
  Object.defineProperty(exports, "__esModule", { value: true });
89
- exports.isSasJsServerInServerMode = exports.getNodeModulePath = exports.isSASjsProject = exports.terminateProcess = exports.prefixAppLoc = exports.loadEnvVariables = exports.displaySasjsRunnerError = exports.getAdapterInstance = exports.checkNodeVersion = exports.millisecondsToDdHhMmSs = exports.arrToObj = exports.parseLogLines = exports.executeShellScript = exports.getUniqServicesObj = exports.setupDoxygen = exports.setupGitIgnore = exports.setupNpmProject = exports.createTemplateApp = exports.createMinimalApp = exports.createAngularApp = exports.createReactApp = exports.diff = exports.inExistingProject = void 0;
89
+ exports.isSasJsServerInServerMode = exports.getNodeModulePath = exports.isSASjsProject = exports.terminateProcess = exports.prefixAppLoc = exports.loadEnvVariables = exports.displaySasjsRunnerError = exports.getAdapterInstance = exports.checkNodeVersion = exports.millisecondsToDdHhMmSs = exports.arrToObj = exports.convertToSASStatements = exports.parseLogLines = exports.executeShellScript = exports.getUniqServicesObj = exports.setupDoxygen = exports.setupGitIgnore = exports.setupNpmProject = exports.createTemplateApp = exports.createMinimalApp = exports.createAngularApp = exports.createReactApp = exports.diff = exports.inExistingProject = void 0;
90
90
  var shelljs_1 = __importDefault(require("shelljs"));
91
91
  var path_1 = __importDefault(require("path"));
92
92
  var ora_1 = __importDefault(require("ora"));
@@ -443,6 +443,35 @@ function parseLogLines(logJson) {
443
443
  return logLines;
444
444
  }
445
445
  exports.parseLogLines = parseLogLines;
446
+ /**
447
+ * Converts MacroVars JSON from command source param to sas statements
448
+ * The JSON must have the following structure:
449
+ * {"macroVars": {"var1": "val1", "var2": "val2"}}
450
+ *
451
+ * @param {object} json
452
+ */
453
+ function convertToSASStatements(json) {
454
+ var e_2, _a;
455
+ var sasStatements = '';
456
+ try {
457
+ for (var _b = __values(Object.keys(json.macroVars)), _c = _b.next(); !_c.done; _c = _b.next()) {
458
+ var macroVar = _c.value;
459
+ var key = macroVar;
460
+ var value = json.macroVars[macroVar];
461
+ var line = "%let ".concat(key, "=").concat(value, ";\n");
462
+ sasStatements += line;
463
+ }
464
+ }
465
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
466
+ finally {
467
+ try {
468
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
469
+ }
470
+ finally { if (e_2) throw e_2.error; }
471
+ }
472
+ return sasStatements;
473
+ }
474
+ exports.convertToSASStatements = convertToSASStatements;
446
475
  var arrToObj = function (arr) {
447
476
  return arr.reduce(function (o, key) {
448
477
  var _a;
package/package.json CHANGED
@@ -51,7 +51,7 @@
51
51
  "@sasjs/adapter": "3.10.15",
52
52
  "@sasjs/core": "4.35.3",
53
53
  "@sasjs/lint": "1.12.0",
54
- "@sasjs/utils": "2.47.0",
54
+ "@sasjs/utils": "2.47.1",
55
55
  "adm-zip": "0.5.9",
56
56
  "chalk": "4.1.2",
57
57
  "csv-stringify": "5.6.5",
@@ -97,5 +97,5 @@
97
97
  "typescript": "4.5.4",
98
98
  "util": "0.12.4"
99
99
  },
100
- "version": "3.19.0"
100
+ "version": "3.19.3"
101
101
  }