@sasjs/cli 6.6.0 → 6.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.
Files changed (57) hide show
  1. package/README.md +2 -1
  2. package/build/commands/flow/flowCommand.js +11 -1
  3. package/build/commands/flow/internal/executeFlow.js +44 -19
  4. package/build/commands/flow/internal/saveLog.d.ts +12 -1
  5. package/build/commands/flow/internal/saveLog.js +2 -2
  6. package/build/commands/flow/internal/spec/executeFlow.spec.js +44 -1
  7. package/build/commands/flow/spec/flowCommand.spec.js +44 -0
  8. package/build/commands/help/help.js +10 -0
  9. package/build/commands/index.d.ts +1 -0
  10. package/build/commands/index.js +3 -1
  11. package/build/commands/job/internal/execute/sas9.js +16 -13
  12. package/build/commands/job/internal/execute/sasjs.js +12 -9
  13. package/build/commands/job/internal/execute/viya.js +41 -36
  14. package/build/commands/job/jobCommand.js +13 -0
  15. package/build/commands/job/spec/executeLogOrder.spec.d.ts +1 -0
  16. package/build/commands/job/spec/executeLogOrder.spec.js +119 -0
  17. package/build/commands/job/spec/jobCommand.spec.js +32 -0
  18. package/build/commands/logcheck/collectLogs.d.ts +60 -0
  19. package/build/commands/logcheck/collectLogs.js +386 -0
  20. package/build/commands/logcheck/logCheckConfig.d.ts +83 -0
  21. package/build/commands/logcheck/logCheckConfig.js +343 -0
  22. package/build/commands/logcheck/logcheckCommand.d.ts +6 -0
  23. package/build/commands/logcheck/logcheckCommand.js +200 -0
  24. package/build/commands/logcheck/processLogCheck.d.ts +44 -0
  25. package/build/commands/logcheck/processLogCheck.js +242 -0
  26. package/build/commands/logcheck/renderLogCheck.d.ts +129 -0
  27. package/build/commands/logcheck/renderLogCheck.js +424 -0
  28. package/build/commands/logcheck/spec/collectLogs.spec.d.ts +1 -0
  29. package/build/commands/logcheck/spec/collectLogs.spec.js +477 -0
  30. package/build/commands/logcheck/spec/logCheckConfig.spec.d.ts +1 -0
  31. package/build/commands/logcheck/spec/logCheckConfig.spec.js +384 -0
  32. package/build/commands/logcheck/spec/logcheckCommand.spec.d.ts +1 -0
  33. package/build/commands/logcheck/spec/logcheckCommand.spec.js +360 -0
  34. package/build/commands/logcheck/spec/processLogCheck.spec.d.ts +1 -0
  35. package/build/commands/logcheck/spec/processLogCheck.spec.js +354 -0
  36. package/build/commands/logcheck/spec/renderLogCheck.spec.d.ts +1 -0
  37. package/build/commands/logcheck/spec/renderLogCheck.spec.js +426 -0
  38. package/build/commands/logcheck/types.d.ts +106 -0
  39. package/build/commands/logcheck/types.js +14 -0
  40. package/build/commands/request/request.js +66 -27
  41. package/build/commands/request/requestCommand.js +11 -1
  42. package/build/commands/request/spec/requestCommand.spec.js +40 -0
  43. package/build/commands/run/run.d.ts +1 -3
  44. package/build/commands/run/run.js +20 -5
  45. package/build/commands/run/runCommand.js +9 -0
  46. package/build/commands/run/spec/runCommand.spec.js +50 -0
  47. package/build/types/command/commandAliases.js +1 -0
  48. package/build/types/command/commandFactory.js +2 -0
  49. package/build/types/command/returnCode.d.ts +2 -1
  50. package/build/types/command/returnCode.js +4 -0
  51. package/build/utils/index.d.ts +1 -0
  52. package/build/utils/index.js +1 -0
  53. package/build/utils/logcheck.d.ts +44 -0
  54. package/build/utils/logcheck.js +224 -0
  55. package/build/utils/spec/logcheck.spec.d.ts +1 -0
  56. package/build/utils/spec/logcheck.spec.js +297 -0
  57. package/package.json +3 -3
@@ -58,6 +58,7 @@ var targetCommand_1 = require("../../types/command/targetCommand");
58
58
  var utils_2 = require("../../utils");
59
59
  var request_1 = require("./request");
60
60
  var getLogFilePath_1 = require("../../utils/getLogFilePath");
61
+ var logcheck_1 = require("../../utils/logcheck");
61
62
  var syntax = 'request <sasProgramPath> [options]';
62
63
  var usage = 'sasjs request <sasProgramPath> --data <path-to-datafile> --config <path-to-configfile> --target <target-name> --output <path-to-outputfile> --log <path-to-logfile>';
63
64
  var description = "Lets the user run a SAS job against a specified target.\n" +
@@ -104,6 +105,11 @@ var RequestCommand = /** @class */ (function (_super) {
104
105
  type: 'string',
105
106
  alias: 'o',
106
107
  description: 'path where output of the finished job execution will be saved.'
108
+ },
109
+ logcheck: {
110
+ type: 'boolean',
111
+ default: undefined,
112
+ description: 'Check the SAS log this request received, and fail when logCheck in sasjsconfig.json says so. --no-logcheck switches both the report and the verdict off.'
107
113
  }
108
114
  },
109
115
  syntax: syntax,
@@ -117,7 +123,9 @@ var RequestCommand = /** @class */ (function (_super) {
117
123
  var _a, target, isLocal, jobPath, log, output, authConfig, _b, e_1, _c, sasProgramPath, data, config;
118
124
  return __generator(this, function (_d) {
119
125
  switch (_d.label) {
120
- case 0: return [4 /*yield*/, this.getTargetInfo()];
126
+ case 0:
127
+ (0, logcheck_1.setLogCheckMode)((0, logcheck_1.logCheckModeOf)(this.parsed.logcheck));
128
+ return [4 /*yield*/, this.getTargetInfo()];
121
129
  case 1:
122
130
  _a = _d.sent(), target = _a.target, isLocal = _a.isLocal;
123
131
  jobPath = (0, utils_2.prefixAppLoc)(target.appLoc, process.currentDir);
@@ -152,6 +160,8 @@ var RequestCommand = /** @class */ (function (_super) {
152
160
  return command_1.ReturnCode.Success;
153
161
  })
154
162
  .catch(function (err) {
163
+ if ((0, logcheck_1.isLogCheckFailure)(err))
164
+ return command_1.ReturnCode.LogCheckError;
155
165
  (0, utils_2.displayError)(err, 'An error has occurred when running your SAS job.');
156
166
  return command_1.ReturnCode.InternalError;
157
167
  })];
@@ -100,6 +100,7 @@ var utils_1 = require("@sasjs/utils");
100
100
  var configUtils = __importStar(require("../../../utils/config"));
101
101
  var setConstantsUtils = __importStar(require("../../../utils/setConstants"));
102
102
  var command_1 = require("../../../types/command");
103
+ var logcheck_1 = require("../../../utils/logcheck");
103
104
  var defaultArgs = ['node', 'sasjs'];
104
105
  var target = new utils_1.Target({
105
106
  name: 'test',
@@ -116,6 +117,45 @@ describe('RequestCommand', function () {
116
117
  beforeEach(function () {
117
118
  setupMocks();
118
119
  });
120
+ afterEach(function () { return (0, logcheck_1.setLogCheckMode)('auto'); });
121
+ it('should return the logcheck code when the log check failed the request', function () { return __awaiter(void 0, void 0, void 0, function () {
122
+ var command, _a;
123
+ return __generator(this, function (_b) {
124
+ switch (_b.label) {
125
+ case 0:
126
+ jest
127
+ .spyOn(requestModule, 'runSasJob')
128
+ .mockImplementation(function () { return Promise.reject(new logcheck_1.LogCheckFailure('1 error')); });
129
+ command = new requestCommand_1.RequestCommand(__spreadArray(__spreadArray([], __read(defaultArgs), false), [
130
+ 'request',
131
+ sasProgramPath
132
+ ], false));
133
+ _a = expect;
134
+ return [4 /*yield*/, command.execute()];
135
+ case 1:
136
+ _a.apply(void 0, [_b.sent()]).toEqual(command_1.ReturnCode.LogCheckError);
137
+ return [2 /*return*/];
138
+ }
139
+ });
140
+ }); });
141
+ it('should switch the log check off for --no-logcheck', function () { return __awaiter(void 0, void 0, void 0, function () {
142
+ var command;
143
+ return __generator(this, function (_a) {
144
+ switch (_a.label) {
145
+ case 0:
146
+ command = new requestCommand_1.RequestCommand(__spreadArray(__spreadArray([], __read(defaultArgs), false), [
147
+ 'request',
148
+ sasProgramPath,
149
+ '--no-logcheck'
150
+ ], false));
151
+ return [4 /*yield*/, command.execute()];
152
+ case 1:
153
+ _a.sent();
154
+ expect((0, logcheck_1.getLogCheckMode)()).toEqual('off');
155
+ return [2 /*return*/];
156
+ }
157
+ });
158
+ }); });
119
159
  it('should parse sasjs request command', function () { return __awaiter(void 0, void 0, void 0, function () {
120
160
  var args, command, targetInfo;
121
161
  return __generator(this, function (_a) {
@@ -6,6 +6,4 @@ import { Target } from '@sasjs/utils';
6
6
  * @param {boolean} compile - compiles sas file present at 'filePath' before running code.
7
7
  * @param {string} logFile - (Optional) Path to log file.
8
8
  */
9
- export declare function runSasCode(target: Target, filePath: string, compile?: boolean, logFile?: string, source?: string): Promise<{
10
- log: any;
11
- }>;
9
+ export declare function runSasCode(target: Target, filePath: string, compile?: boolean, logFile?: string, source?: string): Promise<any>;
@@ -74,6 +74,7 @@ var utils_2 = require("../../utils/");
74
74
  var axios_1 = __importDefault(require("axios"));
75
75
  var saveLog_1 = require("../../utils/saveLog");
76
76
  var parseSourceFile_1 = require("../../utils/parseSourceFile");
77
+ var logcheck_1 = require("../../utils/logcheck");
77
78
  /**
78
79
  * Runs SAS code from a given file on the specified target.
79
80
  * @param {Target} target - the target to run the SAS code on.
@@ -83,7 +84,7 @@ var parseSourceFile_1 = require("../../utils/parseSourceFile");
83
84
  */
84
85
  function runSasCode(target_1, filePath_1) {
85
86
  return __awaiter(this, arguments, void 0, function (target, filePath, compile, logFile, source) {
86
- var isTempFile, sasFilePath, sasFileContent, linesToExecute, macroVars, macroVarStatements, _a;
87
+ var isTempFile, sasFilePath, sasFileContent, linesToExecute, macroVars, macroVarStatements, result, _a;
87
88
  var _b;
88
89
  var _c;
89
90
  if (compile === void 0) { compile = false; }
@@ -137,12 +138,26 @@ function runSasCode(target_1, filePath_1) {
137
138
  }
138
139
  return [3 /*break*/, 17];
139
140
  case 11: return [4 /*yield*/, executeOnSasViya(filePath, target, linesToExecute, logFile)];
140
- case 12: return [2 /*return*/, _d.sent()];
141
+ case 12:
142
+ result = _d.sent();
143
+ return [3 /*break*/, 17];
141
144
  case 13: return [4 /*yield*/, executeOnSas9(target, linesToExecute, logFile)];
142
- case 14: return [2 /*return*/, _d.sent()];
145
+ case 14:
146
+ result = _d.sent();
147
+ return [3 /*break*/, 17];
143
148
  case 15: return [4 /*yield*/, executeOnSasJS(filePath, target, linesToExecute, logFile)];
144
- case 16: return [2 /*return*/, _d.sent()];
145
- case 17: return [2 /*return*/];
149
+ case 16:
150
+ result = _d.sent();
151
+ _d.label = 17;
152
+ case 17:
153
+ // Only a run that claims to have worked is worth checking: an executor that
154
+ // threw has already written the log it failed on, truncated at the failure.
155
+ return [4 /*yield*/, (0, logcheck_1.checkLog)(result === null || result === void 0 ? void 0 : result.log, path_1.default.basename(filePath))];
156
+ case 18:
157
+ // Only a run that claims to have worked is worth checking: an executor that
158
+ // threw has already written the log it failed on, truncated at the failure.
159
+ _d.sent();
160
+ return [2 /*return*/, result];
146
161
  }
147
162
  });
148
163
  });
@@ -55,6 +55,7 @@ exports.RunCommand = void 0;
55
55
  var command_1 = require("../../types/command");
56
56
  var targetCommand_1 = require("../../types/command/targetCommand");
57
57
  var utils_1 = require("../../utils");
58
+ var logcheck_1 = require("../../utils/logcheck");
58
59
  var run_1 = require("./run");
59
60
  var syntax = 'run <sasFilePath> [options]';
60
61
  var usage = 'sasjs run <sasFilePath> --target <target-name>';
@@ -103,6 +104,11 @@ var RunCommand = /** @class */ (function (_super) {
103
104
  type: 'string',
104
105
  alias: 's',
105
106
  description: 'Path to an input JSON containing job variables.'
107
+ },
108
+ logcheck: {
109
+ type: 'boolean',
110
+ default: undefined,
111
+ description: 'Check the SAS log this command received, and fail when logCheck in sasjsconfig.json says so. --no-logcheck switches both the report and the verdict off.'
106
112
  }
107
113
  },
108
114
  syntax: syntax,
@@ -120,11 +126,14 @@ var RunCommand = /** @class */ (function (_super) {
120
126
  case 1:
121
127
  target = (_b.sent()).target;
122
128
  _a = this.parsed, sasFilePath = _a.sasFilePath, compile = _a.compile, log = _a.log, source = _a.source;
129
+ (0, logcheck_1.setLogCheckMode)((0, logcheck_1.logCheckModeOf)(this.parsed.logcheck));
123
130
  return [4 /*yield*/, (0, run_1.runSasCode)(target, sasFilePath, compile, log, source)
124
131
  .then(function () {
125
132
  return command_1.ReturnCode.Success;
126
133
  })
127
134
  .catch(function (err) {
135
+ if ((0, logcheck_1.isLogCheckFailure)(err))
136
+ return command_1.ReturnCode.LogCheckError;
128
137
  (0, utils_1.displayError)(err, 'An error has occurred when running your SAS code.');
129
138
  return command_1.ReturnCode.InternalError;
130
139
  })];
@@ -100,6 +100,7 @@ var utils_1 = require("@sasjs/utils");
100
100
  var configUtils = __importStar(require("../../../utils/config"));
101
101
  var setConstantsUtils = __importStar(require("../../../utils/setConstants"));
102
102
  var command_1 = require("../../../types/command");
103
+ var logcheck_1 = require("../../../utils/logcheck");
103
104
  var defaultArgs = ['node', 'sasjs', 'run'];
104
105
  var target = new utils_1.Target({
105
106
  name: 'test',
@@ -114,6 +115,55 @@ describe('RunCommand', function () {
114
115
  beforeEach(function () {
115
116
  setupMocks();
116
117
  });
118
+ afterEach(function () { return (0, logcheck_1.setLogCheckMode)('auto'); });
119
+ it('should return the logcheck code when the log check failed the run', function () { return __awaiter(void 0, void 0, void 0, function () {
120
+ var command, _a;
121
+ return __generator(this, function (_b) {
122
+ switch (_b.label) {
123
+ case 0:
124
+ jest
125
+ .spyOn(runModule, 'runSasCode')
126
+ .mockImplementation(function () { return Promise.reject(new logcheck_1.LogCheckFailure('2 errors')); });
127
+ command = new runCommand_1.RunCommand(__spreadArray(__spreadArray([], __read(defaultArgs), false), [sasFilePath], false));
128
+ _a = expect;
129
+ return [4 /*yield*/, command.execute()];
130
+ case 1:
131
+ _a.apply(void 0, [_b.sent()]).toEqual(command_1.ReturnCode.LogCheckError);
132
+ return [2 /*return*/];
133
+ }
134
+ });
135
+ }); });
136
+ it('should switch the log check off for --no-logcheck', function () { return __awaiter(void 0, void 0, void 0, function () {
137
+ var command;
138
+ return __generator(this, function (_a) {
139
+ switch (_a.label) {
140
+ case 0:
141
+ command = new runCommand_1.RunCommand(__spreadArray(__spreadArray([], __read(defaultArgs), false), [
142
+ sasFilePath,
143
+ '--no-logcheck'
144
+ ], false));
145
+ return [4 /*yield*/, command.execute()];
146
+ case 1:
147
+ _a.sent();
148
+ expect((0, logcheck_1.getLogCheckMode)()).toEqual('off');
149
+ return [2 /*return*/];
150
+ }
151
+ });
152
+ }); });
153
+ it('should switch the log check on for --logcheck', function () { return __awaiter(void 0, void 0, void 0, function () {
154
+ var command;
155
+ return __generator(this, function (_a) {
156
+ switch (_a.label) {
157
+ case 0:
158
+ command = new runCommand_1.RunCommand(__spreadArray(__spreadArray([], __read(defaultArgs), false), [sasFilePath, '--logcheck'], false));
159
+ return [4 /*yield*/, command.execute()];
160
+ case 1:
161
+ _a.sent();
162
+ expect((0, logcheck_1.getLogCheckMode)()).toEqual('on');
163
+ return [2 /*return*/];
164
+ }
165
+ });
166
+ }); });
117
167
  it('should parse sasjs run command', function () { return __awaiter(void 0, void 0, void 0, function () {
118
168
  return __generator(this, function (_a) {
119
169
  switch (_a.label) {
@@ -11,6 +11,7 @@ exports.aliasMap = new Map([
11
11
  ['deploy', ['d']],
12
12
  ['doc', ['docs']],
13
13
  ['help', ['h']],
14
+ ['logcheck', ['lc']],
14
15
  ['request', ['rq']],
15
16
  ['run', ['r']],
16
17
  ['test', ['t']],
@@ -24,6 +24,7 @@ var requestCommand_1 = require("../../commands/request/requestCommand");
24
24
  var helpCommand_1 = require("../../commands/help/helpCommand");
25
25
  var jobCommand_1 = require("../../commands/job/jobCommand");
26
26
  var lintCommand_1 = require("../../commands/lint/lintCommand");
27
+ var logcheckCommand_1 = require("../../commands/logcheck/logcheckCommand");
27
28
  var flowCommand_1 = require("../../commands/flow/flowCommand");
28
29
  var fsCommand_1 = require("../../commands/fs/fsCommand");
29
30
  var snippetsCommand_1 = require("../../commands/snippets/snippetsCommand");
@@ -49,6 +50,7 @@ exports.commandFactory = new Map([
49
50
  ['init', function (args) { return new initCommand_1.InitCommand(args); }],
50
51
  ['job', function (args) { return new jobCommand_1.JobCommand(args); }],
51
52
  ['lint', function (args) { return new lintCommand_1.LintCommand(args); }],
53
+ ['logcheck', function (args) { return new logcheckCommand_1.LogCheckCommand(args); }],
52
54
  ['flow', function (args) { return new flowCommand_1.FlowCommand(args); }],
53
55
  ['request', function (args) { return new requestCommand_1.RequestCommand(args); }],
54
56
  ['run', function (args) { return new runCommand_1.RunCommand(args); }],
@@ -3,5 +3,6 @@ export declare enum ReturnCode {
3
3
  InvalidCommand = 1,
4
4
  InternalError = 2,
5
5
  LintError = 3,
6
- AlreadyInitialised = 4
6
+ AlreadyInitialised = 4,
7
+ LogCheckError = 5
7
8
  }
@@ -11,4 +11,8 @@ var ReturnCode;
11
11
  // InvalidCommand, which also covers unparseable arguments, so a script can
12
12
  // tell a refusal from a bad invocation.
13
13
  ReturnCode[ReturnCode["AlreadyInitialised"] = 4] = "AlreadyInitialised";
14
+ // `logcheck` found issues at or above the configured failure policy. Kept
15
+ // apart from LintError so a pipeline can tell a code-quality failure from a
16
+ // run that SAS complained about.
17
+ ReturnCode[ReturnCode["LogCheckError"] = 5] = "LogCheckError";
14
18
  })(ReturnCode || (exports.ReturnCode = ReturnCode = {}));
@@ -3,6 +3,7 @@ export * from './config';
3
3
  export * from './displayResult';
4
4
  export * from './file';
5
5
  export * from './loadEnvVariables';
6
+ export * from './logcheck';
6
7
  export * from './saveLog';
7
8
  export * from './setConstants';
8
9
  export * from './setProjectDir';
@@ -19,6 +19,7 @@ __exportStar(require("./config"), exports);
19
19
  __exportStar(require("./displayResult"), exports);
20
20
  __exportStar(require("./file"), exports);
21
21
  __exportStar(require("./loadEnvVariables"), exports);
22
+ __exportStar(require("./logcheck"), exports);
22
23
  __exportStar(require("./saveLog"), exports);
23
24
  __exportStar(require("./setConstants"), exports);
24
25
  __exportStar(require("./setProjectDir"), exports);
@@ -0,0 +1,44 @@
1
+ /**
2
+ * How the log a command just received is treated.
3
+ *
4
+ * `auto` decides from `logCheck.autoCheck` in the project config, which is off
5
+ * by default; `on` and `off` are the `--logcheck` / `--no-logcheck` flags. The
6
+ * distinction matters because the two halves of the behaviour are separate:
7
+ * reporting what SAS printed is always worth doing, while changing the exit
8
+ * code of a command whose status a pipeline already trusts is not something to
9
+ * do behind a project's back.
10
+ */
11
+ export type LogCheckMode = 'auto' | 'on' | 'off';
12
+ export declare const setLogCheckMode: (value: LogCheckMode) => void;
13
+ export declare const getLogCheckMode: () => LogCheckMode;
14
+ /** Reads a tri-state yargs boolean: absent is `undefined`, not `false`. */
15
+ export declare const logCheckModeOf: (flag: unknown) => LogCheckMode;
16
+ /**
17
+ * A run whose log broke the policy, once `autoCheck` or `--logcheck` asked for
18
+ * the verdict to count.
19
+ *
20
+ * It is an error rather than a return value because it is raised several
21
+ * frames below the command, from whichever executor received the log, and the
22
+ * command is the only place that can turn it into an exit code.
23
+ */
24
+ export declare class LogCheckFailure extends Error {
25
+ /**
26
+ * Marker rather than `instanceof`: the CLI is compiled to a target where a
27
+ * subclass of a built-in loses its prototype chain, so `instanceof` answers
28
+ * false in the built artefact while answering true under the test transform.
29
+ * The flag is read by {@link isLogCheckFailure} and cannot be faked by an
30
+ * unrelated error.
31
+ */
32
+ readonly logCheckFailure = true;
33
+ constructor(message: string);
34
+ }
35
+ export declare const isLogCheckFailure: (error: unknown) => error is LogCheckFailure;
36
+ /**
37
+ * Reports the issues in a log a command just received, and throws when the
38
+ * policy says the run should fail.
39
+ *
40
+ * Nothing is printed for a clean log: the commands this runs inside already
41
+ * have their own success output, and a check that announces itself on every
42
+ * green run is noise that gets switched off.
43
+ */
44
+ export declare const checkLog: (logText: string | undefined | null, label: string) => Promise<void>;
@@ -0,0 +1,224 @@
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 __assign = (this && this.__assign) || function () {
18
+ __assign = Object.assign || function(t) {
19
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
20
+ s = arguments[i];
21
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
22
+ t[p] = s[p];
23
+ }
24
+ return t;
25
+ };
26
+ return __assign.apply(this, arguments);
27
+ };
28
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
29
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
30
+ return new (P || (P = Promise))(function (resolve, reject) {
31
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
32
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
33
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
34
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
35
+ });
36
+ };
37
+ var __generator = (this && this.__generator) || function (thisArg, body) {
38
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
39
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
40
+ function verb(n) { return function (v) { return step([n, v]); }; }
41
+ function step(op) {
42
+ if (f) throw new TypeError("Generator is already executing.");
43
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
44
+ 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;
45
+ if (y = 0, t) op = [op[0] & 2, t.value];
46
+ switch (op[0]) {
47
+ case 0: case 1: t = op; break;
48
+ case 4: _.label++; return { value: op[1], done: false };
49
+ case 5: _.label++; y = op[1]; op = [0]; continue;
50
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
51
+ default:
52
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
53
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
54
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
55
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
56
+ if (t[2]) _.ops.pop();
57
+ _.trys.pop(); continue;
58
+ }
59
+ op = body.call(thisArg, _);
60
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
61
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
62
+ }
63
+ };
64
+ var __read = (this && this.__read) || function (o, n) {
65
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
66
+ if (!m) return o;
67
+ var i = m.call(o), r, ar = [], e;
68
+ try {
69
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
70
+ }
71
+ catch (error) { e = { error: error }; }
72
+ finally {
73
+ try {
74
+ if (r && !r.done && (m = i["return"])) m.call(i);
75
+ }
76
+ finally { if (e) throw e.error; }
77
+ }
78
+ return ar;
79
+ };
80
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
81
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
82
+ if (ar || !(i in from)) {
83
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
84
+ ar[i] = from[i];
85
+ }
86
+ }
87
+ return to.concat(ar || Array.prototype.slice.call(from));
88
+ };
89
+ var __importDefault = (this && this.__importDefault) || function (mod) {
90
+ return (mod && mod.__esModule) ? mod : { "default": mod };
91
+ };
92
+ Object.defineProperty(exports, "__esModule", { value: true });
93
+ exports.checkLog = exports.isLogCheckFailure = exports.LogCheckFailure = exports.logCheckModeOf = exports.getLogCheckMode = exports.setLogCheckMode = void 0;
94
+ var logs_1 = require("@sasjs/utils/logs");
95
+ var chalk_1 = __importDefault(require("chalk"));
96
+ var collectLogs_1 = require("../commands/logcheck/collectLogs");
97
+ var logCheckConfig_1 = require("../commands/logcheck/logCheckConfig");
98
+ var processLogCheck_1 = require("../commands/logcheck/processLogCheck");
99
+ var renderLogCheck_1 = require("../commands/logcheck/renderLogCheck");
100
+ var mode = 'auto';
101
+ var setLogCheckMode = function (value) {
102
+ mode = value;
103
+ };
104
+ exports.setLogCheckMode = setLogCheckMode;
105
+ var getLogCheckMode = function () { return mode; };
106
+ exports.getLogCheckMode = getLogCheckMode;
107
+ /** Reads a tri-state yargs boolean: absent is `undefined`, not `false`. */
108
+ var logCheckModeOf = function (flag) {
109
+ return flag === true ? 'on' : flag === false ? 'off' : 'auto';
110
+ };
111
+ exports.logCheckModeOf = logCheckModeOf;
112
+ /**
113
+ * A run whose log broke the policy, once `autoCheck` or `--logcheck` asked for
114
+ * the verdict to count.
115
+ *
116
+ * It is an error rather than a return value because it is raised several
117
+ * frames below the command, from whichever executor received the log, and the
118
+ * command is the only place that can turn it into an exit code.
119
+ */
120
+ var LogCheckFailure = /** @class */ (function (_super) {
121
+ __extends(LogCheckFailure, _super);
122
+ function LogCheckFailure(message) {
123
+ var _this = _super.call(this, message) || this;
124
+ /**
125
+ * Marker rather than `instanceof`: the CLI is compiled to a target where a
126
+ * subclass of a built-in loses its prototype chain, so `instanceof` answers
127
+ * false in the built artefact while answering true under the test transform.
128
+ * The flag is read by {@link isLogCheckFailure} and cannot be faked by an
129
+ * unrelated error.
130
+ */
131
+ _this.logCheckFailure = true;
132
+ _this.name = 'LogCheckFailure';
133
+ return _this;
134
+ }
135
+ return LogCheckFailure;
136
+ }(Error));
137
+ exports.LogCheckFailure = LogCheckFailure;
138
+ var isLogCheckFailure = function (error) {
139
+ return (error === null || error === void 0 ? void 0 : error.logCheckFailure) === true;
140
+ };
141
+ exports.isLogCheckFailure = isLogCheckFailure;
142
+ /**
143
+ * Reports the issues in a log a command just received, and throws when the
144
+ * policy says the run should fail.
145
+ *
146
+ * Nothing is printed for a clean log: the commands this runs inside already
147
+ * have their own success output, and a check that announces itself on every
148
+ * green run is noise that gets switched off.
149
+ */
150
+ var checkLog = function (logText, label) { return __awaiter(void 0, void 0, void 0, function () {
151
+ var config, error_1, _a, issues, suppressed, counts, failing, totals, failure;
152
+ var _b;
153
+ return __generator(this, function (_c) {
154
+ switch (_c.label) {
155
+ case 0:
156
+ if (mode === 'off' || !logText)
157
+ return [2 /*return*/];
158
+ _c.label = 1;
159
+ case 1:
160
+ _c.trys.push([1, 3, , 4]);
161
+ return [4 /*yield*/, (0, logCheckConfig_1.readLogCheckConfig)()];
162
+ case 2:
163
+ config = _c.sent();
164
+ return [3 /*break*/, 4];
165
+ case 3:
166
+ error_1 = _c.sent();
167
+ // An automatic check must never break the command it is riding on: a
168
+ // config it cannot read is worth a warning, not a failed run.
169
+ (_b = process.logger) === null || _b === void 0 ? void 0 : _b.warn("Skipping the SAS log check: ".concat(error_1.message));
170
+ return [2 /*return*/];
171
+ case 4:
172
+ _a = (0, collectLogs_1.partitionIssues)((0, logs_1.parseLog)(logText), config.ignoreCodes), issues = _a.issues, suppressed = _a.suppressed;
173
+ if (!issues.length)
174
+ return [2 /*return*/];
175
+ counts = (0, collectLogs_1.countIssues)(issues);
176
+ failing = mode === 'on' || config.autoCheck === true;
177
+ totals = __assign(__assign({}, counts), { suppressed: suppressed.length, logs: 1, skipped: 0 });
178
+ failure = failing ? (0, processLogCheck_1.describeFailure)(totals, config) : undefined;
179
+ renderInline(label, issues, counts, suppressed.length, config, failure);
180
+ if (failure) {
181
+ throw new LogCheckFailure("SAS log check failed for ".concat(label, ": ").concat(failure));
182
+ }
183
+ return [2 /*return*/];
184
+ }
185
+ });
186
+ }); };
187
+ exports.checkLog = checkLog;
188
+ /**
189
+ * The inline report: the heading, the issues, and the verdict when there is
190
+ * one. Deliberately narrower than the `logcheck` report - there is one log
191
+ * here and its name is already on screen, so there is no file table.
192
+ */
193
+ var renderInline = function (label, issues, counts, suppressedCount, config, failure) {
194
+ var _a;
195
+ var lines = [
196
+ "".concat(chalk_1.default.bold('SAS log check'), " ").concat(chalk_1.default.dim(label), " - ").concat(describe(counts))
197
+ ];
198
+ lines.push.apply(lines, __spreadArray([], __read((0, renderLogCheck_1.columns)(issues.map(function (issue) { return [
199
+ (0, renderLogCheck_1.lineLabel)(issue),
200
+ (0, renderLogCheck_1.severityLabel)(issue.severity),
201
+ issue.code || chalk_1.default.dim('-'),
202
+ (0, renderLogCheck_1.truncate)(issue.message)
203
+ ]; }), ['LINE:COL', 'SEVERITY', 'CODE', 'MESSAGE'], ' ', ' ')), false));
204
+ if (suppressedCount) {
205
+ lines.push(chalk_1.default.dim(" ".concat(suppressedCount, " issue").concat(suppressedCount === 1 ? '' : 's', " suppressed by message code").concat(config.ignoreCodes.length ? " (".concat(config.ignoreCodes.join(', '), ")") : '')));
206
+ }
207
+ if (failure) {
208
+ lines.push("".concat(chalk_1.default.red.bold(' Logcheck failed: ')).concat(chalk_1.default.red(failure)));
209
+ }
210
+ (_a = process.logger) === null || _a === void 0 ? void 0 : _a.log(lines.join('\n'));
211
+ };
212
+ var describe = function (counts) {
213
+ var parts = [];
214
+ if (counts.errors)
215
+ parts.push(plural(counts.errors, 'error'));
216
+ if (counts.warnings)
217
+ parts.push(plural(counts.warnings, 'warning'));
218
+ if (counts.notes)
219
+ parts.push(plural(counts.notes, 'note'));
220
+ return parts.join(', ');
221
+ };
222
+ var plural = function (count, noun) {
223
+ return "".concat(count, " ").concat(noun).concat(count === 1 ? '' : 's');
224
+ };
@@ -0,0 +1 @@
1
+ export {};