@sasjs/cli 4.6.0 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -192,8 +192,7 @@ describe('JobCommand', function () {
192
192
  _b.sent();
193
193
  (_a = expect(viyaExecuteModule.executeJobViya)).toHaveBeenCalledWith.apply(_a, __spreadArray([], __read(executeCalledWith({
194
194
  jobPath: jobPath,
195
- waitForJob: true,
196
- verbose: true
195
+ waitForJob: true
197
196
  })), false));
198
197
  return [2 /*return*/];
199
198
  }
@@ -321,6 +320,78 @@ describe('JobCommand', function () {
321
320
  }
322
321
  });
323
322
  }); });
323
+ it('should set verbose to true if verbose flag present', function () { return __awaiter(void 0, void 0, void 0, function () {
324
+ var sasjs;
325
+ return __generator(this, function (_a) {
326
+ switch (_a.label) {
327
+ case 0:
328
+ sasjs = new node_1.default();
329
+ jest
330
+ .spyOn(configUtils, 'getSASjsAndAuthConfig')
331
+ .mockImplementation(function (target) {
332
+ sasjs = configUtils.getSASjs(target);
333
+ jest.spyOn(sasjs, 'setVerboseMode');
334
+ return Promise.resolve({
335
+ sasjs: sasjs,
336
+ authConfig: authConfig
337
+ });
338
+ });
339
+ return [4 /*yield*/, executeCommandWrapper([jobPath, '--verbose'])];
340
+ case 1:
341
+ _a.sent();
342
+ expect(sasjs.setVerboseMode).toHaveBeenCalledWith(true);
343
+ return [2 /*return*/];
344
+ }
345
+ });
346
+ }); });
347
+ it('should set verbose to bleached if verbose flag present and is equal to bleached', function () { return __awaiter(void 0, void 0, void 0, function () {
348
+ var sasjs;
349
+ return __generator(this, function (_a) {
350
+ switch (_a.label) {
351
+ case 0:
352
+ sasjs = new node_1.default();
353
+ jest
354
+ .spyOn(configUtils, 'getSASjsAndAuthConfig')
355
+ .mockImplementation(function (target) {
356
+ sasjs = configUtils.getSASjs(target);
357
+ jest.spyOn(sasjs, 'setVerboseMode');
358
+ return Promise.resolve({
359
+ sasjs: sasjs,
360
+ authConfig: authConfig
361
+ });
362
+ });
363
+ return [4 /*yield*/, executeCommandWrapper([jobPath, '-v', 'bleached'])];
364
+ case 1:
365
+ _a.sent();
366
+ expect(sasjs.setVerboseMode).toHaveBeenCalledWith('bleached');
367
+ return [2 /*return*/];
368
+ }
369
+ });
370
+ }); });
371
+ it('should set verbose to false if verbose flag is not present', function () { return __awaiter(void 0, void 0, void 0, function () {
372
+ var sasjs;
373
+ return __generator(this, function (_a) {
374
+ switch (_a.label) {
375
+ case 0:
376
+ sasjs = new node_1.default();
377
+ jest
378
+ .spyOn(configUtils, 'getSASjsAndAuthConfig')
379
+ .mockImplementation(function (target) {
380
+ sasjs = configUtils.getSASjs(target);
381
+ jest.spyOn(sasjs, 'setVerboseMode');
382
+ return Promise.resolve({
383
+ sasjs: sasjs,
384
+ authConfig: authConfig
385
+ });
386
+ });
387
+ return [4 /*yield*/, executeCommandWrapper([jobPath])];
388
+ case 1:
389
+ _a.sent();
390
+ expect(sasjs.setVerboseMode).toHaveBeenCalledWith(false);
391
+ return [2 /*return*/];
392
+ }
393
+ });
394
+ }); });
324
395
  });
325
396
  describe('for server type sas9', function () {
326
397
  beforeEach(function () {
@@ -540,7 +611,7 @@ var setupMocksForSAS9 = function () {
540
611
  jest.spyOn(process.logger, 'error');
541
612
  };
542
613
  var executeCalledWith = function (_a) {
543
- var jobPath = _a.jobPath, _b = _a.waitForJob, waitForJob = _b === void 0 ? false : _b, _c = _a.output, output = _c === void 0 ? false : _c, _d = _a.logFile, logFile = _d === void 0 ? undefined : _d, _e = _a.statusFile, statusFile = _e === void 0 ? undefined : _e, _f = _a.ignoreWarnings, ignoreWarnings = _f === void 0 ? false : _f, _g = _a.source, source = _g === void 0 ? undefined : _g, _h = _a.streamLog, streamLog = _h === void 0 ? false : _h, _j = _a.verbose, verbose = _j === void 0 ? false : _j;
614
+ var jobPath = _a.jobPath, _b = _a.waitForJob, waitForJob = _b === void 0 ? false : _b, _c = _a.output, output = _c === void 0 ? false : _c, _d = _a.logFile, logFile = _d === void 0 ? undefined : _d, _e = _a.statusFile, statusFile = _e === void 0 ? undefined : _e, _f = _a.ignoreWarnings, ignoreWarnings = _f === void 0 ? false : _f, _g = _a.source, source = _g === void 0 ? undefined : _g, _h = _a.streamLog, streamLog = _h === void 0 ? false : _h;
544
615
  return [
545
616
  expect.anything(),
546
617
  authConfig,
@@ -552,8 +623,7 @@ var executeCalledWith = function (_a) {
552
623
  statusFile,
553
624
  ignoreWarnings,
554
625
  source,
555
- streamLog,
556
- verbose
626
+ streamLog
557
627
  ];
558
628
  };
559
629
  var executeCommandWrapper = function (additionalParams) { return __awaiter(void 0, void 0, void 0, function () {
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Generates VS Code snippets from the Doxygen headers in the SAS Macros.
3
+ * @param macroFolders an array of file paths of SAS Macros.
4
+ * @param outDirectory a folder path where generated snippets should be put into. If ends with '<file name>.json' then provided file name will be used, otherwise default file name ('sasjs-macro-snippets.json') will be used.
5
+ * @returns a promise that resolves into a file path with generated VS Code snippets.
6
+ */
7
+ export declare function generateSnippets(macroFolders: string[], outDirectory?: string): Promise<string>;
@@ -0,0 +1,192 @@
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 (g && (g = 0, op[0] && (_ = 0)), _) 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 __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
+ };
63
+ var __importDefault = (this && this.__importDefault) || function (mod) {
64
+ return (mod && mod.__esModule) ? mod : { "default": mod };
65
+ };
66
+ Object.defineProperty(exports, "__esModule", { value: true });
67
+ exports.generateSnippets = void 0;
68
+ var utils_1 = require("@sasjs/utils");
69
+ var path_1 = __importDefault(require("path"));
70
+ var sasRegExp = /\.sas$/; // to check if file has .sas extension
71
+ var briefRegExp = /^\s\s@brief\s/; // to get lines that has @brief keyword
72
+ var paramRegExp = /^\s\s@param\s/; // to get lines that has @param keyword
73
+ /**
74
+ * Generates VS Code snippets from the Doxygen headers in the SAS Macros.
75
+ * @param macroFolders an array of file paths of SAS Macros.
76
+ * @param outDirectory a folder path where generated snippets should be put into. If ends with '<file name>.json' then provided file name will be used, otherwise default file name ('sasjs-macro-snippets.json') will be used.
77
+ * @returns a promise that resolves into a file path with generated VS Code snippets.
78
+ */
79
+ function generateSnippets(macroFolders, outDirectory) {
80
+ return __awaiter(this, void 0, void 0, function () {
81
+ var snippets, defaultOutputFileName, buildDestinationResultsFolder, snippetsFilePath;
82
+ var _this = this;
83
+ return __generator(this, function (_a) {
84
+ switch (_a.label) {
85
+ case 0:
86
+ snippets = {};
87
+ // return an error if no macro folders has been provided
88
+ if (!macroFolders.length) {
89
+ return [2 /*return*/, Promise.reject("\"macroFolders\" array was not found in sasjs/sasjsconfig.json.")];
90
+ }
91
+ // generate snippets from all .sas file in macro folders
92
+ return [4 /*yield*/, (0, utils_1.asyncForEach)(macroFolders, function (folder) { return __awaiter(_this, void 0, void 0, function () {
93
+ var sasFiles;
94
+ var _this = this;
95
+ return __generator(this, function (_a) {
96
+ switch (_a.label) {
97
+ case 0: return [4 /*yield*/, (0, utils_1.listSasFilesInFolder)(folder, true)];
98
+ case 1:
99
+ sasFiles = (_a.sent())
100
+ .map(function (file) { return path_1.default.join(folder, file); })
101
+ .filter(function (file) { return !(0, utils_1.isTestFile)(file); });
102
+ return [4 /*yield*/, (0, utils_1.asyncForEach)(sasFiles, function (file) { return __awaiter(_this, void 0, void 0, function () {
103
+ var macro, _a, _b;
104
+ return __generator(this, function (_c) {
105
+ switch (_c.label) {
106
+ case 0:
107
+ macro = file.split(path_1.default.sep).pop().replace(sasRegExp, '');
108
+ // put generated snippet into snippets object
109
+ _a = snippets;
110
+ _b = macro;
111
+ return [4 /*yield*/, createSnippetFromMacro(file)];
112
+ case 1:
113
+ // put generated snippet into snippets object
114
+ _a[_b] = _c.sent();
115
+ return [2 /*return*/];
116
+ }
117
+ });
118
+ }); })];
119
+ case 2:
120
+ _a.sent();
121
+ return [2 /*return*/];
122
+ }
123
+ });
124
+ }); })
125
+ // return an error if no snippets has been generated
126
+ ];
127
+ case 1:
128
+ // generate snippets from all .sas file in macro folders
129
+ _a.sent();
130
+ // return an error if no snippets has been generated
131
+ if (!Object.keys(snippets).length) {
132
+ return [2 /*return*/, Promise.reject('No VS Code snippets has been found.')];
133
+ }
134
+ defaultOutputFileName = 'sasjs-macro-snippets.json';
135
+ buildDestinationResultsFolder = process.sasjsConstants.buildDestinationResultsFolder;
136
+ snippetsFilePath = path_1.default.join(outDirectory ? process.projectDir : buildDestinationResultsFolder, outDirectory
137
+ ? /\.json$/.test(outDirectory)
138
+ ? outDirectory
139
+ : path_1.default.join(outDirectory, defaultOutputFileName)
140
+ : defaultOutputFileName);
141
+ // create file with generated VS Code snippets
142
+ return [4 /*yield*/, (0, utils_1.createFile)(snippetsFilePath, JSON.stringify(snippets, null, 2))
143
+ // return file path with generated VS Code snippets
144
+ ];
145
+ case 2:
146
+ // create file with generated VS Code snippets
147
+ _a.sent();
148
+ // return file path with generated VS Code snippets
149
+ return [2 /*return*/, Promise.resolve(snippetsFilePath)];
150
+ }
151
+ });
152
+ });
153
+ }
154
+ exports.generateSnippets = generateSnippets;
155
+ /**
156
+ * Creates a VS Code snippet from SAS macro.
157
+ * @param file file path of SAS macro.
158
+ * @returns promise that resolves with VS Code snippet.
159
+ */
160
+ var createSnippetFromMacro = function (file) { return __awaiter(void 0, void 0, void 0, function () {
161
+ var fileContent, lineEnding, lines, brief, params, macro, description;
162
+ return __generator(this, function (_a) {
163
+ switch (_a.label) {
164
+ case 0: return [4 /*yield*/, (0, utils_1.readFile)(file)];
165
+ case 1:
166
+ fileContent = _a.sent();
167
+ lineEnding = (0, utils_1.getLineEnding)(fileContent) // LF or CRLF
168
+ ;
169
+ lines = fileContent.split(lineEnding);
170
+ brief = lines.filter(function (line) { return briefRegExp.test(line); });
171
+ params = lines.filter(function (line) { return paramRegExp.test(line); });
172
+ macro = file.split(path_1.default.sep).pop().replace(sasRegExp, '') // macro name
173
+ ;
174
+ // if brief present, remove @brief keyword
175
+ if (brief.length)
176
+ brief = [brief[0].replace(briefRegExp, '')];
177
+ // if params present, add a line break before list of params and a prefix to each param
178
+ if (params.length) {
179
+ brief.push('\r');
180
+ params = params.map(function (param) { return param.replace(paramRegExp, '-'); });
181
+ }
182
+ description = __spreadArray(__spreadArray(__spreadArray([], __read(brief), false), [
183
+ params.length ? "Params:" : ''
184
+ ], false), __read(params), false).filter(function (line) { return line; });
185
+ return [2 /*return*/, {
186
+ prefix: "%".concat(macro),
187
+ body: "%".concat(macro, "($1)"),
188
+ description: description
189
+ }];
190
+ }
191
+ });
192
+ }); };
@@ -0,0 +1,13 @@
1
+ import { ReturnCode } from '../../types/command';
2
+ import { TargetCommand } from '../../types/command/targetCommand';
3
+ /**
4
+ * 'snippets' command class.
5
+ */
6
+ export declare class SnippetsCommand extends TargetCommand {
7
+ constructor(args: string[]);
8
+ /**
9
+ * Command execution method.
10
+ * @returns promise that results into return code.
11
+ */
12
+ execute(): Promise<ReturnCode>;
13
+ }
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
18
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
19
+ return new (P || (P = Promise))(function (resolve, reject) {
20
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
21
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
22
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
23
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
24
+ });
25
+ };
26
+ var __generator = (this && this.__generator) || function (thisArg, body) {
27
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
28
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
29
+ function verb(n) { return function (v) { return step([n, v]); }; }
30
+ function step(op) {
31
+ if (f) throw new TypeError("Generator is already executing.");
32
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
33
+ 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;
34
+ if (y = 0, t) op = [op[0] & 2, t.value];
35
+ switch (op[0]) {
36
+ case 0: case 1: t = op; break;
37
+ case 4: _.label++; return { value: op[1], done: false };
38
+ case 5: _.label++; y = op[1]; op = [0]; continue;
39
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
40
+ default:
41
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
42
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
43
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
44
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
45
+ if (t[2]) _.ops.pop();
46
+ _.trys.pop(); continue;
47
+ }
48
+ op = body.call(thisArg, _);
49
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
50
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
51
+ }
52
+ };
53
+ Object.defineProperty(exports, "__esModule", { value: true });
54
+ exports.SnippetsCommand = void 0;
55
+ var snippets_1 = require("./snippets");
56
+ var command_1 = require("../../types/command");
57
+ var targetCommand_1 = require("../../types/command/targetCommand");
58
+ var utils_1 = require("../../utils");
59
+ var syntax = 'snippets';
60
+ var usage = 'sasjs snippets';
61
+ var description = "Generates VS Code snippets from the Doxygen headers in the SAS Macros.";
62
+ var examples = [
63
+ {
64
+ command: 'sasjs snippets',
65
+ description: description
66
+ }
67
+ ];
68
+ var parseOptions = {
69
+ outDirectory: {
70
+ type: 'string',
71
+ alias: 'o',
72
+ description: 'Path to the directory where the VS Code snippets output will be generated.'
73
+ }
74
+ };
75
+ /**
76
+ * 'snippets' command class.
77
+ */
78
+ var SnippetsCommand = /** @class */ (function (_super) {
79
+ __extends(SnippetsCommand, _super);
80
+ function SnippetsCommand(args) {
81
+ return _super.call(this, args, { syntax: syntax, usage: usage, description: description, examples: examples, parseOptions: parseOptions }) || this;
82
+ }
83
+ /**
84
+ * Command execution method.
85
+ * @returns promise that results into return code.
86
+ */
87
+ SnippetsCommand.prototype.execute = function () {
88
+ return __awaiter(this, void 0, void 0, function () {
89
+ var target, macroFolders, outDirectory;
90
+ return __generator(this, function (_a) {
91
+ switch (_a.label) {
92
+ case 0: return [4 /*yield*/, this.getTargetInfo()];
93
+ case 1:
94
+ target = (_a.sent()).target;
95
+ return [4 /*yield*/, (0, utils_1.getMacroFolders)(target)];
96
+ case 2:
97
+ macroFolders = _a.sent();
98
+ outDirectory = this.parsed.outDirectory;
99
+ return [4 /*yield*/, (0, snippets_1.generateSnippets)(macroFolders, outDirectory)
100
+ .then(function (filePath) {
101
+ var _a, _b;
102
+ // handle command execution success
103
+ (_a = process.logger) === null || _a === void 0 ? void 0 : _a.success("VS Code snippets generated! File location: ".concat(filePath));
104
+ (_b = process.logger) === null || _b === void 0 ? void 0 : _b.info("Follow these instructions https://cli.sasjs.io/snippets/#import-snippets-to-vs-code to import generated VS Code snippets into your VS Code.");
105
+ return command_1.ReturnCode.Success;
106
+ })
107
+ .catch(function (err) {
108
+ var _a;
109
+ // handle command execution failure
110
+ (_a = process.logger) === null || _a === void 0 ? void 0 : _a.error('Error generating VS Code snippets: ', err);
111
+ return command_1.ReturnCode.InternalError;
112
+ })];
113
+ case 3:
114
+ // Generate snippets
115
+ return [2 /*return*/, _a.sent()];
116
+ }
117
+ });
118
+ });
119
+ };
120
+ return SnippetsCommand;
121
+ }(targetCommand_1.TargetCommand));
122
+ exports.SnippetsCommand = SnippetsCommand;
@@ -0,0 +1 @@
1
+ export {};