@sasjs/cli 3.0.3 → 3.3.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 (36) hide show
  1. package/build/commands/add/addCredential.d.ts +6 -2
  2. package/build/commands/add/addCredential.js +79 -47
  3. package/build/commands/add/addTarget.js +32 -20
  4. package/build/commands/add/internal/input.d.ts +7 -0
  5. package/build/commands/add/internal/input.js +53 -8
  6. package/build/commands/add/spec/addTarget.spec.js +78 -0
  7. package/build/commands/compile/internal/compileServiceFile.js +31 -14
  8. package/build/commands/create/spec/reactAppFiles.js +5 -5
  9. package/build/commands/deploy/spec/cbd.spec.js +19 -3
  10. package/build/commands/job/internal/execute/viya.js +0 -6
  11. package/build/commands/job/internal/utils.js +6 -8
  12. package/build/commands/job/jobCommand.d.ts +1 -0
  13. package/build/commands/job/jobCommand.js +8 -3
  14. package/build/commands/job/spec/jobCommand.spec.js +10 -3
  15. package/build/commands/shared/fetchLogFileContent.js +6 -8
  16. package/build/commands/testing/internal/saveOutput.d.ts +1 -0
  17. package/build/commands/testing/internal/saveOutput.js +41 -1
  18. package/build/commands/testing/spec/testing.spec.server.js +10 -1
  19. package/build/commands/testing/test.js +6 -2
  20. package/build/commands/web/internal/getTags.d.ts +2 -1
  21. package/build/commands/web/internal/getTags.js +10 -12
  22. package/build/commands/web/internal/sasjsout.d.ts +1 -1
  23. package/build/commands/web/internal/sasjsout.js +1 -1
  24. package/build/commands/web/internal/spec/updateLinkTag.spec.d.ts +4 -0
  25. package/build/commands/web/internal/spec/updateLinkTag.spec.js +32 -0
  26. package/build/commands/web/internal/updateAllTags.js +33 -8
  27. package/build/commands/web/internal/updateLinkTag.d.ts +4 -0
  28. package/build/commands/web/internal/updateLinkTag.js +24 -0
  29. package/build/utils/auth.d.ts +10 -4
  30. package/build/utils/auth.js +17 -15
  31. package/build/utils/config.d.ts +1 -1
  32. package/build/utils/config.js +12 -14
  33. package/build/utils/utils.js +1 -5
  34. package/package.json +7 -13
  35. package/build/commands/web/internal/updateLinkHref.d.ts +0 -4
  36. package/build/commands/web/internal/updateLinkHref.js +0 -18
@@ -7,7 +7,10 @@ exports.reactAppFiles = {
7
7
  { fileName: 'package.json' },
8
8
  { fileName: 'package-lock.json' },
9
9
  { fileName: 'tsconfig.json' },
10
- { fileName: 'README.md' }
10
+ { fileName: 'README.md' },
11
+ { fileName: 'webpack.common.js' },
12
+ { fileName: 'webpack.dev.js' },
13
+ { fileName: 'webpack.prod.js' }
11
14
  ],
12
15
  subFolders: [
13
16
  {
@@ -36,12 +39,9 @@ exports.reactAppFiles = {
36
39
  folderName: 'src',
37
40
  files: [
38
41
  { fileName: 'App.scss' },
39
- { fileName: 'cached_data.ts' },
40
42
  { fileName: 'index.scss' },
41
43
  { fileName: 'index.tsx' },
42
- { fileName: 'logo.svg' },
43
- { fileName: 'react-app-env.d.ts' },
44
- { fileName: 'serviceWorker.ts' }
44
+ { fileName: 'logo.svg' }
45
45
  ],
46
46
  subFolders: [
47
47
  {
@@ -47,6 +47,7 @@ var build_1 = require("../../build/build");
47
47
  var deploy_1 = require("../deploy");
48
48
  var utils_2 = require("./utils");
49
49
  var config_1 = require("../../../utils/config");
50
+ var utils_3 = require("../../../utils");
50
51
  describe('sasjs cbd with server type SASJS', function () {
51
52
  var target;
52
53
  var appName;
@@ -77,7 +78,7 @@ describe('sasjs cbd with server type SASJS', function () {
77
78
  });
78
79
  }); });
79
80
  it("should deploy compile and build to sasjs/server", function () { return __awaiter(void 0, void 0, void 0, function () {
80
- var sasjs, customTarget;
81
+ var sasjs, customTarget, macroCorePath, mf_getuser, mp_jsonout, ms_webout, webout;
81
82
  return __generator(this, function (_a) {
82
83
  switch (_a.label) {
83
84
  case 0:
@@ -108,6 +109,19 @@ describe('sasjs cbd with server type SASJS', function () {
108
109
  return [4 /*yield*/, deploy_1.deploy(customTarget, true, sasjs)];
109
110
  case 4:
110
111
  _a.sent();
112
+ macroCorePath = process.sasjsConstants.macroCorePath;
113
+ return [4 /*yield*/, utils_1.readFile(macroCorePath + "/base/mf_getuser.sas")];
114
+ case 5:
115
+ mf_getuser = _a.sent();
116
+ return [4 /*yield*/, utils_1.readFile(macroCorePath + "/base/mp_jsonout.sas")];
117
+ case 6:
118
+ mp_jsonout = _a.sent();
119
+ return [4 /*yield*/, utils_1.readFile(macroCorePath + "/server/ms_webout.sas")];
120
+ case 7:
121
+ ms_webout = _a.sent();
122
+ webout = ' %macro webout(action,ds,dslabel=,fmt=);\n' +
123
+ ' %ms_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt)\n' +
124
+ ' %mend;\n';
111
125
  expect(sasjs.deployToSASjs).toHaveBeenCalledWith({
112
126
  members: [
113
127
  {
@@ -121,12 +135,14 @@ describe('sasjs cbd with server type SASJS', function () {
121
135
  {
122
136
  name: 'appinit',
123
137
  type: 'service',
124
- code: '/* provide additional debug info */\n%global _program;\n%put &=syscc;\n%put user=%mf_getuser();\n%put pgm=&_program;\n%put timestamp=%sysfunc(datetime(),datetime19.);\n* Service Variables start;\n*Service Variables end;\n* Dependencies start;\n* Dependencies end;\n* Programs start;\n*Programs end;\n* Service start;\nproc sql;\ncreate table areas as select distinct area\n from sashelp.springs;\n%webout(OPEN)\n%webout(OBJ,areas)\n%webout(CLOSE)\n* Service end;'
138
+ code: utils_3.removeComments("" + mf_getuser + mp_jsonout + ms_webout + webout +
139
+ '/* provide additional debug info */\n%global _program;\n%put &=syscc;\n%put user=%mf_getuser();\n%put pgm=&_program;\n%put timestamp=%sysfunc(datetime(),datetime19.);\n* Service Variables start;\n*Service Variables end;\n* Dependencies start;\n* Dependencies end;\n* Programs start;\n*Programs end;\n* Service start;\nproc sql;\ncreate table areas as select distinct area\n from sashelp.springs;\n%webout(OPEN)\n%webout(OBJ,areas)\n%webout(CLOSE)\n* Service end;')
125
140
  },
126
141
  {
127
142
  name: 'getdata',
128
143
  type: 'service',
129
- code: '/* provide additional debug info */\n%global _program;\n%put &=syscc;\n%put user=%mf_getuser();\n%put pgm=&_program;\n%put timestamp=%sysfunc(datetime(),datetime19.);\n* Service Variables start;\n*Service Variables end;\n* Dependencies start;\n* Dependencies end;\n* Programs start;\n*Programs end;\n* Service start;\n%webout(FETCH)\nproc sql;\ncreate table springs as select * from sashelp.springs\n where area in (select area from work.areas);\n%webout(OPEN)\n%webout(OBJ,springs)\n%webout(CLOSE)\n* Service end;'
144
+ code: utils_3.removeComments("" + mf_getuser + mp_jsonout + ms_webout + webout +
145
+ '/* provide additional debug info */\n%global _program;\n%put &=syscc;\n%put user=%mf_getuser();\n%put pgm=&_program;\n%put timestamp=%sysfunc(datetime(),datetime19.);\n* Service Variables start;\n*Service Variables end;\n* Dependencies start;\n* Dependencies end;\n* Programs start;\n*Programs end;\n* Service start;\n%webout(FETCH)\nproc sql;\ncreate table springs as select * from sashelp.springs\n where area in (select area from work.areas);\n%webout(OPEN)\n%webout(OBJ,springs)\n%webout(CLOSE)\n* Service end;')
130
146
  }
131
147
  ]
132
148
  }
@@ -170,12 +170,6 @@ function executeJobViya(sasjs, authConfig, jobPath, target, waitForJob, output,
170
170
  if (!result)
171
171
  result = true;
172
172
  sessionLink = submittedJob.links.find(function (l) { return l.method === 'GET' && l.rel === 'self'; }).href;
173
- if (!returnStatusOnly) {
174
- displayResult_1.displaySuccess((waitForJob
175
- ? "Job located at '" + jobPath + "' has been executed.\nJob details"
176
- : "Job session") +
177
- (" can be found at " + (target.serverUrl + sessionLink)));
178
- }
179
173
  if (!(output || logFile)) return [3 /*break*/, 20];
180
174
  _c.label = 9;
181
175
  case 9:
@@ -46,9 +46,8 @@ var utils_2 = require("../../../utils/utils");
46
46
  var displayResult_1 = require("../../../utils/displayResult");
47
47
  var saveLog = function (logData, logFile, jobPath, returnStatusOnly) { return __awaiter(void 0, void 0, void 0, function () {
48
48
  var logPath, folderPath, parentFolderPath, logLines;
49
- var _a;
50
- return __generator(this, function (_b) {
51
- switch (_b.label) {
49
+ return __generator(this, function (_a) {
50
+ switch (_a.label) {
52
51
  case 0:
53
52
  if (logFile) {
54
53
  logPath = logFile;
@@ -61,17 +60,16 @@ var saveLog = function (logData, logFile, jobPath, returnStatusOnly) { return __
61
60
  parentFolderPath = folderPath.join(path_1.default.sep);
62
61
  return [4 /*yield*/, utils_1.folderExists(parentFolderPath)];
63
62
  case 1:
64
- if (!!(_b.sent())) return [3 /*break*/, 3];
63
+ if (!!(_a.sent())) return [3 /*break*/, 3];
65
64
  return [4 /*yield*/, utils_1.createFolder(parentFolderPath)];
66
65
  case 2:
67
- _b.sent();
68
- _b.label = 3;
66
+ _a.sent();
67
+ _a.label = 3;
69
68
  case 3:
70
69
  logLines = typeof logData === 'object' ? utils_2.parseLogLines(logData) : logData;
71
- (_a = process.logger) === null || _a === void 0 ? void 0 : _a.info("Creating log file at " + logPath + " .");
72
70
  return [4 /*yield*/, utils_1.createFile(logPath, logLines)];
73
71
  case 4:
74
- _b.sent();
72
+ _a.sent();
75
73
  if (!returnStatusOnly)
76
74
  displayResult_1.displaySuccess("Log saved to " + logPath);
77
75
  return [2 /*return*/];
@@ -3,6 +3,7 @@ import { AuthConfig, Target } from '@sasjs/utils';
3
3
  import { ReturnCode } from '../../types/command';
4
4
  import { TargetCommand } from '../../types/command/targetCommand';
5
5
  export declare class JobCommand extends TargetCommand {
6
+ private jobSubCommands;
6
7
  constructor(args: string[]);
7
8
  execute(): Promise<ReturnCode>;
8
9
  executeJobSasjs(sasjs: SASjs, target: Target): Promise<ReturnCode>;
@@ -66,6 +66,7 @@ var execute_1 = require("./internal/execute");
66
66
  var JobSubCommand;
67
67
  (function (JobSubCommand) {
68
68
  JobSubCommand["Execute"] = "execute";
69
+ JobSubCommand["Exec"] = "exec";
69
70
  })(JobSubCommand || (JobSubCommand = {}));
70
71
  var syntax = 'job <subCommand> <jobPath> [options]';
71
72
  var usage = 'sasjs job <execute> <jobPath> [options]';
@@ -123,8 +124,11 @@ var JobCommand = /** @class */ (function (_super) {
123
124
  __extends(JobCommand, _super);
124
125
  function JobCommand(args) {
125
126
  var _this = this;
127
+ var jobSubCommands = Object.values(JobSubCommand);
126
128
  var subCommand = args[3];
127
- var parseOptions = subCommand === JobSubCommand.Execute ? executeParseOptions : {};
129
+ var parseOptions = jobSubCommands.includes(subCommand)
130
+ ? executeParseOptions
131
+ : {};
128
132
  _this = _super.call(this, args, {
129
133
  parseOptions: parseOptions,
130
134
  usage: usage,
@@ -132,6 +136,7 @@ var JobCommand = /** @class */ (function (_super) {
132
136
  examples: examples,
133
137
  syntax: syntax
134
138
  }) || this;
139
+ _this.jobSubCommands = jobSubCommands;
135
140
  return _this;
136
141
  }
137
142
  JobCommand.prototype.execute = function () {
@@ -166,7 +171,7 @@ var JobCommand = /** @class */ (function (_super) {
166
171
  authConfig = _e.sent();
167
172
  if (!authConfig)
168
173
  return [2 /*return*/, command_1.ReturnCode.InternalError];
169
- if (!(this.parsed.subCommand === JobSubCommand.Execute)) return [3 /*break*/, 5];
174
+ if (!this.jobSubCommands.includes(this.parsed.subCommand)) return [3 /*break*/, 5];
170
175
  return [4 /*yield*/, this.executeJobViya(target, sasjs, authConfig)];
171
176
  case 4:
172
177
  _c = _e.sent();
@@ -182,7 +187,7 @@ var JobCommand = /** @class */ (function (_super) {
182
187
  });
183
188
  if (typeof this.parsed.jobPath !== 'string')
184
189
  return [2 /*return*/, command_1.ReturnCode.InvalidCommand];
185
- if (!(this.parsed.subCommand === JobSubCommand.Execute)) return [3 /*break*/, 9];
190
+ if (!this.jobSubCommands.includes(this.parsed.subCommand)) return [3 /*break*/, 9];
186
191
  return [4 /*yield*/, this.executeJobSasjs(sasjs, target)];
187
192
  case 8:
188
193
  _d = _e.sent();
@@ -362,17 +362,24 @@ var executeCalledWith = function (_a) {
362
362
  var executeCommandWrapper = function (additionalParams, checkTarget) {
363
363
  if (checkTarget === void 0) { checkTarget = true; }
364
364
  return __awaiter(void 0, void 0, void 0, function () {
365
- var args, command, returnCode, targetInfo;
365
+ var subCommand, args, command, returnCode, targetInfo;
366
366
  return __generator(this, function (_a) {
367
367
  switch (_a.label) {
368
368
  case 0:
369
- args = __spreadArray(__spreadArray([], __read(defaultArgs)), __read(additionalParams));
369
+ subCommand = 'execute';
370
+ args = __spreadArray(__spreadArray([], __read(defaultArgs)), __read(additionalParams)).map(function (arg) {
371
+ if (arg === 'execute') {
372
+ arg = Math.random() > 0.5 ? 'exec' : arg;
373
+ subCommand = arg;
374
+ }
375
+ return arg;
376
+ });
370
377
  command = new jobCommand_1.JobCommand(args);
371
378
  return [4 /*yield*/, command.execute()];
372
379
  case 1:
373
380
  returnCode = _a.sent();
374
381
  expect(command.name).toEqual('job');
375
- expect(command.subCommand).toEqual('execute');
382
+ expect(command.subCommand).toEqual(subCommand);
376
383
  if (!checkTarget) return [3 /*break*/, 3];
377
384
  return [4 /*yield*/, command.getTargetInfo()];
378
385
  case 2:
@@ -68,28 +68,26 @@ exports.fetchLogFileContent = void 0;
68
68
  */
69
69
  var fetchLogFileContent = function (sasjs, accessToken, logUrl, logCount) { return __awaiter(void 0, void 0, void 0, function () {
70
70
  var logJson, loglimit, start, logChunkJson, _a, _b;
71
- var _c;
72
- return __generator(this, function (_d) {
73
- switch (_d.label) {
71
+ return __generator(this, function (_c) {
72
+ switch (_c.label) {
74
73
  case 0:
75
74
  logJson = { items: [] };
76
75
  loglimit = logCount < 10000 ? logCount : 10000;
77
76
  start = 0;
78
- _d.label = 1;
77
+ _c.label = 1;
79
78
  case 1:
80
- (_c = process.logger) === null || _c === void 0 ? void 0 : _c.info("Fetching logs from line no: " + (start + 1) + " to " + (start + loglimit) + " of " + logCount + ".");
81
79
  _b = (_a = JSON).parse;
82
80
  return [4 /*yield*/, sasjs.fetchLogFileContent(logUrl + "?start=" + start + "&limit=" + loglimit, accessToken)];
83
81
  case 2:
84
- logChunkJson = _b.apply(_a, [(_d.sent())]);
82
+ logChunkJson = _b.apply(_a, [(_c.sent())]);
85
83
  if (logChunkJson.items.length === 0)
86
84
  return [3 /*break*/, 4];
87
85
  logJson.items = __spreadArray(__spreadArray([], __read(logJson.items)), __read(logChunkJson.items));
88
86
  start += loglimit;
89
- _d.label = 3;
87
+ _c.label = 3;
90
88
  case 3:
91
89
  if (start < logCount) return [3 /*break*/, 1];
92
- _d.label = 4;
90
+ _c.label = 4;
93
91
  case 4: return [2 /*return*/, logJson];
94
92
  }
95
93
  });
@@ -6,3 +6,4 @@ export declare const saveResultCsv: (outDirectory: string, result: TestResults,
6
6
  csvPath: string;
7
7
  }>;
8
8
  export declare const saveResultXml: (outDirectory: string, result: TestResults) => Promise<string>;
9
+ export declare const saveCoverageLcov: (outDirectory: string, tests: string[]) => Promise<string>;
@@ -60,7 +60,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
60
60
  return (mod && mod.__esModule) ? mod : { "default": mod };
61
61
  };
62
62
  Object.defineProperty(exports, "__esModule", { value: true });
63
- exports.saveResultXml = exports.saveResultCsv = exports.saveResultJson = exports.saveLog = void 0;
63
+ exports.saveCoverageLcov = exports.saveResultXml = exports.saveResultCsv = exports.saveResultJson = exports.saveLog = void 0;
64
64
  var path_1 = __importDefault(require("path"));
65
65
  var utils_1 = require("@sasjs/utils");
66
66
  var file_1 = require("../../../utils/file");
@@ -262,3 +262,43 @@ var saveResultXml = function (outDirectory, result) { return __awaiter(void 0, v
262
262
  });
263
263
  }); };
264
264
  exports.saveResultXml = saveResultXml;
265
+ var saveCoverageLcov = function (outDirectory, tests) { return __awaiter(void 0, void 0, void 0, function () {
266
+ var testsPrefixRegExp, coverageReport, coveringFile, filePath;
267
+ return __generator(this, function (_a) {
268
+ switch (_a.label) {
269
+ case 0:
270
+ testsPrefixRegExp = new RegExp("^tests/");
271
+ coverageReport = [];
272
+ coveringFile = function (filePath) { return __awaiter(void 0, void 0, void 0, function () {
273
+ return __generator(this, function (_a) {
274
+ switch (_a.label) {
275
+ case 0: return [4 /*yield*/, utils_1.fileExists(path_1.default.join(process.sasjsConstants.buildDestinationFolder, filePath))];
276
+ case 1: return [2 /*return*/, (_a.sent())
277
+ ? filePath
278
+ : 'standalone'];
279
+ }
280
+ });
281
+ }); };
282
+ return [4 /*yield*/, utils_1.asyncForEach(tests, function (test) { return __awaiter(void 0, void 0, void 0, function () {
283
+ var _a, _b, _c;
284
+ return __generator(this, function (_d) {
285
+ switch (_d.label) {
286
+ case 0:
287
+ _b = (_a = coverageReport).push;
288
+ _c = "TN:" + test.split('/').pop() + "\nSF:";
289
+ return [4 /*yield*/, coveringFile(test.replace(testsPrefixRegExp, '').replace(utils_1.testFileRegExp, '.sas'))];
290
+ case 1: return [2 /*return*/, _b.apply(_a, [_c + (_d.sent()) + "\nFNF:1\nFNH:1\nLF:1\nLH:1\nBRF:1\nBRH:1\nend_of_record"])];
291
+ }
292
+ });
293
+ }); })];
294
+ case 1:
295
+ _a.sent();
296
+ filePath = path_1.default.join(outDirectory, 'coverage.lcov');
297
+ return [4 /*yield*/, utils_1.createFile(filePath, coverageReport.join('\n'))];
298
+ case 2:
299
+ _a.sent();
300
+ return [2 /*return*/, filePath];
301
+ }
302
+ });
303
+ }); };
304
+ exports.saveCoverageLcov = saveCoverageLcov;
@@ -99,7 +99,7 @@ describe('sasjs test', function () {
99
99
  });
100
100
  }); });
101
101
  it('should execute tests and create result CSV, XML and JSON files using default source and output locations', function () { return __awaiter(void 0, void 0, void 0, function () {
102
- var expectedResultsJson, expectedResultsCsv, resultsFolderPath, resultsJsonPath, resultsJson, resultsCsvPath, parsedResults, resultsCsv, resultsXmlPath, resultsXml, expectedResultsXml;
102
+ var expectedResultsJson, expectedResultsCsv, resultsFolderPath, resultsJsonPath, resultsJson, resultsCsvPath, parsedResults, resultsCsv, resultsXmlPath, resultsXml, expectedResultsXml, coverageLcovPath, expectedCoverageLcov, coverageLcov;
103
103
  return __generator(this, function (_a) {
104
104
  switch (_a.label) {
105
105
  case 0:
@@ -232,6 +232,15 @@ describe('sasjs test', function () {
232
232
  resultsXml = resultsXml.replace(/testsuites id="[^ ]*"/gm, "testsuites id=\"\"");
233
233
  resultsXml = resultsXml.replace(/testcase id="[^ ]*"/gm, "testcase id=\"\"");
234
234
  expect(resultsXml).toEqual(expectedResultsXml);
235
+ coverageLcovPath = path_1.default.join(resultsFolderPath, 'coverage.lcov');
236
+ return [4 /*yield*/, expect(utils_1.fileExists(coverageLcovPath)).resolves.toEqual(true)];
237
+ case 9:
238
+ _a.sent();
239
+ expectedCoverageLcov = "TN:testsetup.sas\nSF:standalone\nFNF:1\nFNH:1\nLF:1\nLH:1\nBRF:1\nBRH:1\nend_of_record\nTN:exampleprogram.test.sas\nSF:jobs/jobs/exampleprogram.sas\nFNF:1\nFNH:1\nLF:1\nLH:1\nBRF:1\nBRH:1\nend_of_record\nTN:standalone.test.sas\nSF:standalone\nFNF:1\nFNH:1\nLF:1\nLH:1\nBRF:1\nBRH:1\nend_of_record\nTN:examplemacro.test.sas\nSF:standalone\nFNF:1\nFNH:1\nLF:1\nLH:1\nBRF:1\nBRH:1\nend_of_record\nTN:shouldFail.test.sas\nSF:standalone\nFNF:1\nFNH:1\nLF:1\nLH:1\nBRF:1\nBRH:1\nend_of_record\nTN:dostuff.test.0.sas\nSF:services/admin/dostuff.sas\nFNF:1\nFNH:1\nLF:1\nLH:1\nBRF:1\nBRH:1\nend_of_record\nTN:dostuff.test.1.sas\nSF:services/admin/dostuff.sas\nFNF:1\nFNH:1\nLF:1\nLH:1\nBRF:1\nBRH:1\nend_of_record\nTN:testteardown.sas\nSF:standalone\nFNF:1\nFNH:1\nLF:1\nLH:1\nBRF:1\nBRH:1\nend_of_record";
240
+ return [4 /*yield*/, utils_1.readFile(coverageLcovPath)];
241
+ case 10:
242
+ coverageLcov = _a.sent();
243
+ expect(coverageLcov).toEqual(expectedCoverageLcov);
235
244
  return [2 /*return*/];
236
245
  }
237
246
  });
@@ -86,7 +86,7 @@ function runTest(target, testRegExps, outDirectory, flowSourcePath) {
86
86
  var _a, _b;
87
87
  if (testRegExps === void 0) { testRegExps = []; }
88
88
  return __awaiter(this, void 0, void 0, function () {
89
- var testFlowData, testFlow, flow, sasjs, authConfig, username, password, sas9CredentialsError, result, isCodeExamplePrinted, printCodeExample, jsonPath, xmlPath, _c, csvData, csvPath, resultTable, testsCount, passedTestsCount, testsWithResultsCount;
89
+ var testFlowData, testFlow, flow, sasjs, authConfig, username, password, sas9CredentialsError, result, isCodeExamplePrinted, printCodeExample, jsonPath, xmlPath, _c, csvData, csvPath, coverageReportPath, resultTable, testsCount, passedTestsCount, testsWithResultsCount;
90
90
  var _this = this;
91
91
  return __generator(this, function (_d) {
92
92
  switch (_d.label) {
@@ -205,6 +205,7 @@ function runTest(target, testRegExps, outDirectory, flowSourcePath) {
205
205
  testUrl = testUrl + "&_contextName=" + encodeURIComponent(target.contextName);
206
206
  }
207
207
  printTestUrl = function () { return process.logger.info("Test URL: " + testUrl); };
208
+ printTestUrl();
208
209
  return [4 /*yield*/, sasjs
209
210
  .request(sasJobLocation, {}, { username: username, password: password }, function () {
210
211
  displayResult_1.displayError(null, 'Login callback called. Request failed.');
@@ -247,7 +248,6 @@ function runTest(target, testRegExps, outDirectory, flowSourcePath) {
247
248
  }
248
249
  if (!((_a = res.result) === null || _a === void 0 ? void 0 : _a.test_results))
249
250
  lineBreak = false;
250
- printTestUrl();
251
251
  if (!res.log) return [3 /*break*/, 2];
252
252
  return [4 /*yield*/, saveOutput_1.saveLog(outDirectory, test, res.log, lineBreak)];
253
253
  case 1:
@@ -328,6 +328,9 @@ function runTest(target, testRegExps, outDirectory, flowSourcePath) {
328
328
  return [4 /*yield*/, saveOutput_1.saveResultCsv(outDirectory, result)];
329
329
  case 7:
330
330
  _c = _d.sent(), csvData = _c.csvData, csvPath = _c.csvPath;
331
+ return [4 /*yield*/, saveOutput_1.saveCoverageLcov(outDirectory, flow)];
332
+ case 8:
333
+ coverageReportPath = _d.sent();
331
334
  resultTable = {};
332
335
  if (Array.isArray(csvData)) {
333
336
  csvData.forEach(function (item) {
@@ -353,6 +356,7 @@ function runTest(target, testRegExps, outDirectory, flowSourcePath) {
353
356
  testsWithResultsCount = Object.values(resultTable).filter(function (res) { return res.test_suite_result !== types_1.TestResultStatus.notProvided; }).length;
354
357
  (_b = process.logger) === null || _b === void 0 ? void 0 : _b.info("Tests provided results: " + (testsWithResultsCount + '/' + testsCount) + " (" + chalk_1.default.greenBright(Math.round((testsWithResultsCount / testsCount) * 100 || 0) + '%') + ")\n Tests that pass: " + (passedTestsCount + '/' + testsWithResultsCount) + " (" + chalk_1.default.greenBright(Math.round((passedTestsCount / testsWithResultsCount) * 100 || 0) + '%') + ")\n ");
355
358
  displayResult_1.displaySuccess("Tests execution finished. The results are stored at:\n " + jsonPath + "\n " + csvPath + "\n " + xmlPath);
359
+ displayResult_1.displaySuccess("Tests coverage report:\n " + coverageReportPath);
356
360
  return [2 /*return*/];
357
361
  }
358
362
  });
@@ -1,4 +1,5 @@
1
1
  import { JSDOM } from 'jsdom';
2
2
  export declare const getScriptTags: (parsedHtml: JSDOM) => HTMLScriptElement[];
3
- export declare const getLinkTags: (parsedHtml: JSDOM) => HTMLLinkElement[];
3
+ export declare const getStyleTags: (parsedHtml: JSDOM) => HTMLLinkElement[];
4
4
  export declare const getFaviconTags: (parsedHtml: JSDOM) => HTMLLinkElement[];
5
+ export declare const getImgTags: (parsedHtml: JSDOM) => HTMLImageElement[];
@@ -1,21 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getFaviconTags = exports.getLinkTags = exports.getScriptTags = void 0;
3
+ exports.getImgTags = exports.getFaviconTags = exports.getStyleTags = exports.getScriptTags = void 0;
4
4
  var getScriptTags = function (parsedHtml) {
5
- return Array.from(parsedHtml.window.document.querySelectorAll('script'));
5
+ return Array.from(parsedHtml.window.document.getElementsByTagName('script'));
6
6
  };
7
7
  exports.getScriptTags = getScriptTags;
8
- var getLinkTags = function (parsedHtml) {
9
- var linkTags = Array.from(parsedHtml.window.document.querySelectorAll('link')).filter(function (s) { return s.getAttribute('rel') === 'stylesheet'; });
10
- return linkTags;
8
+ var getStyleTags = function (parsedHtml) {
9
+ return Array.from(parsedHtml.window.document.getElementsByTagName('link')).filter(function (s) { return s.getAttribute('rel') === 'stylesheet'; });
11
10
  };
12
- exports.getLinkTags = getLinkTags;
11
+ exports.getStyleTags = getStyleTags;
13
12
  var getFaviconTags = function (parsedHtml) {
14
- var linkTags = Array.from(parsedHtml.window.document.querySelectorAll('link')).filter(function (s) {
15
- return s.getAttribute('rel') &&
16
- s.getAttribute('rel') &&
17
- s.getAttribute('rel').includes('icon');
18
- });
19
- return linkTags;
13
+ return Array.from(parsedHtml.window.document.getElementsByTagName('link')).filter(function (s) { var _a; return (_a = s.getAttribute('rel')) === null || _a === void 0 ? void 0 : _a.includes('icon'); });
20
14
  };
21
15
  exports.getFaviconTags = getFaviconTags;
16
+ var getImgTags = function (parsedHtml) {
17
+ return Array.from(parsedHtml.window.document.getElementsByTagName('img')).filter(function (s) { return s.getAttribute('src'); });
18
+ };
19
+ exports.getImgTags = getImgTags;
@@ -1 +1 @@
1
- export declare const sasjsout = "\n%macro sasjsout(type,fref=sasjs);\n%global sysprocessmode SYS_JES_JOB_URI;\n%if \"&sysprocessmode\"=\"SAS Compute Server\" %then %do;\n %if &type=HTML %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name=\"_webout.json\"\n contenttype=\"text/html\";\n %end;\n %else %if &type=JS or &type=JS64 %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.js'\n contenttype='application/javascript';\n %end;\n %else %if &type=CSS or &type=CSS64 %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.css'\n contenttype='text/css';\n %end;\n %else %if &type=PNG %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.png'\n contenttype='image/png' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=ICO %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.ico'\n contenttype='image/vnd.microsoft.icon' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=JSON %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.json'\n contenttype='application/json' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=MP3 %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.mp3'\n contenttype='audio/mpeg' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=WAV %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.wav'\n contenttype='audio/x-wav' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=OGG %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.ogg'\n contenttype='audio/ogg' lrecl=2000000 recfm=n;\n %end;\n%end;\n%else %do;\n %if &type=JS or &type=JS64 %then %do;\n %let rc=%sysfunc(stpsrv_header(\n Content-type,application/javascript%str(;)charset=UTF-8\n ));\n %end;\n %else %if &type=CSS or &type=CSS64 %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,text/css));\n %end;\n %else %if &type=PNG %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,image/png));\n %end;\n %else %if &type=ICO %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,image/vnd.microsoft.icon));\n %end;\n %else %if &type=JSON %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,application/json));\n %end;\n %else %if &type=MP3 %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,audio/mpeg));\n %end;\n %else %if &type=WAV %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,audio/x-wav));\n %end;\n %else %if &type=OGG %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,audio/ogg));\n %end;\n%end;\n%if &type=HTML %then %do;\n /*\n We need to perform some substitutions -eg to get the APPLOC and SERVERTYPE.\n Therefore the developer should avoid writing lines that exceed 32k\n characters (eg base64 encoded images) as they will get truncated when passing\n through the datastep. This could of course be re-written using LUA, removing\n the length restriction. Pull requests are welcome!\n */\n filename _sjs temp;\n data _null_;\n file _sjs lrecl=32767 encoding='utf-8';\n infile &fref lrecl=32767;\n input;\n length appLoc expanded_path $1048;\n if _n_=1 then do;\n retain pgm \"&_program\" appLoc expanded_path;\n /* index is deployed in the /services/ folder under the appLoc */\n appLoc=substr(pgm,1,find(pgm,'/services/')-1);\n expanded_path=cats('?_PROGRAM=',appLoc,'/services/');\n end;\n if find(_infile_,' appLoc: ') then put ' appLoc: ' apploc:$quote1048. ',';\n else if find(_infile_,' serverType: ') then do;\n if symexist('_metaperson') then put ' serverType: \"SAS9\" ,';\n else put ' serverType: \"SASVIYA\" ,';\n end;\n else if find(_infile_,' hostUrl: ') then do;\n /* nothing - we are streaming, so remove to default as hostname */\n end;\n else do;\n length newline $32767;\n /* during SAS9 compilation, dependencies are assigned three slashes /// */\n newline=tranwrd(_infile_,'?_PROGRAM=///',cats(expanded_path));\n put newline;\n end;\n run;\n %let fref=_sjs;\n%end;\n\n/* stream byte by byte */\n/* in SAS9, JS & CSS files are base64 encoded to avoid UTF8 issues in WLATIN1 metadata */\n%if &type=PNG or &type=ICO or &type=MP3 or &type=JS64 or &type=CSS64 or &type=WAV or &type=OGG\n%then %do;\n data _null_;\n length filein 8 fileout 8;\n filein = fopen(\"&fref\",'I',4,'B');\n fileout = fopen(\"_webout\",'A',1,'B');\n char= '20'x;\n do while(fread(filein)=0);\n length raw $4 ;\n do i=1 to 4;\n rc=fget(filein,char,1);\n substr(raw,i,1)=char;\n end;\n rc = fput(fileout, input(raw,$base64X4.));\n rc =fwrite(fileout);\n end;\n rc = fclose(filein);\n rc = fclose(fileout);\n run;\n%end;\n%else %do;\n data _null_;\n length filein 8 fileid 8;\n filein = fopen(\"&fref\",'I',1,'B');\n fileid = fopen(\"_webout\",'A',1,'B');\n rec = '20'x;\n do while(fread(filein)=0);\n rc = fget(filein,rec,1);\n rc = fput(fileid, rec);\n rc =fwrite(fileid);\n end;\n rc = fclose(filein);\n rc = fclose(fileid);\n run;\n%end;\n%mend;";
1
+ export declare const sasjsout = "\n%macro sasjsout(type,fref=sasjs);\n%global sysprocessmode SYS_JES_JOB_URI;\n%if \"&sysprocessmode\"=\"SAS Compute Server\" %then %do;\n %if &type=HTML %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name=\"_webout.json\"\n contenttype=\"text/html\";\n %end;\n %else %if &type=JS or &type=JS64 %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.js'\n contenttype='application/javascript';\n %end;\n %else %if &type=CSS or &type=CSS64 %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.css'\n contenttype='text/css';\n %end;\n %else %if &type=PNG %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.png'\n contenttype='image/png' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=JPG %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.jpg'\n contenttype='image/jpg' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=JPEG %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.jpeg'\n contenttype='image/jpeg' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=ICO %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.ico'\n contenttype='image/vnd.microsoft.icon' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=JSON %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.json'\n contenttype='application/json' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=MP3 %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.mp3'\n contenttype='audio/mpeg' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=WAV %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.wav'\n contenttype='audio/x-wav' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=OGG %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.ogg'\n contenttype='audio/ogg' lrecl=2000000 recfm=n;\n %end;\n%end;\n%else %do;\n %if &type=JS or &type=JS64 %then %do;\n %let rc=%sysfunc(stpsrv_header(\n Content-type,application/javascript%str(;)charset=UTF-8\n ));\n %end;\n %else %if &type=CSS or &type=CSS64 %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,text/css));\n %end;\n %else %if &type=PNG %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,image/png));\n %end;\n %else %if &type=JPG %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,image/jpg));\n %end;\n %else %if &type=JPEG %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,image/jpeg));\n %end;\n %else %if &type=ICO %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,image/vnd.microsoft.icon));\n %end;\n %else %if &type=JSON %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,application/json));\n %end;\n %else %if &type=MP3 %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,audio/mpeg));\n %end;\n %else %if &type=WAV %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,audio/x-wav));\n %end;\n %else %if &type=OGG %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,audio/ogg));\n %end;\n%end;\n%if &type=HTML %then %do;\n /*\n We need to perform some substitutions -eg to get the APPLOC and SERVERTYPE.\n Therefore the developer should avoid writing lines that exceed 32k\n characters (eg base64 encoded images) as they will get truncated when passing\n through the datastep. This could of course be re-written using LUA, removing\n the length restriction. Pull requests are welcome!\n */\n filename _sjs temp;\n data _null_;\n file _sjs lrecl=32767 encoding='utf-8';\n infile &fref lrecl=32767;\n input;\n length appLoc expanded_path $1048;\n if _n_=1 then do;\n retain pgm \"&_program\" appLoc expanded_path;\n /* index is deployed in the /services/ folder under the appLoc */\n appLoc=substr(pgm,1,find(pgm,'/services/')-1);\n expanded_path=cats('?_PROGRAM=',appLoc,'/services/');\n end;\n if find(_infile_,' appLoc: ') then put ' appLoc: ' apploc:$quote1048. ',';\n else if find(_infile_,' serverType: ') then do;\n if symexist('_metaperson') then put ' serverType: \"SAS9\" ,';\n else put ' serverType: \"SASVIYA\" ,';\n end;\n else if find(_infile_,' hostUrl: ') then do;\n /* nothing - we are streaming, so remove to default as hostname */\n end;\n else do;\n length newline $32767;\n /* during SAS9 compilation, dependencies are assigned three slashes /// */\n newline=tranwrd(_infile_,'?_PROGRAM=///',cats(expanded_path));\n put newline;\n end;\n run;\n %let fref=_sjs;\n%end;\n\n/* stream byte by byte */\n/* in SAS9, JS & CSS files are base64 encoded to avoid UTF8 issues in WLATIN1 metadata */\n%if &type=PNG or &type=JPG or &type=JPEG or &type=ICO or &type=MP3 or &type=JS64 or &type=CSS64 or &type=WAV or &type=OGG\n%then %do;\n data _null_;\n length filein 8 fileout 8;\n filein = fopen(\"&fref\",'I',4,'B');\n fileout = fopen(\"_webout\",'A',1,'B');\n char= '20'x;\n do while(fread(filein)=0);\n length raw $4 ;\n do i=1 to 4;\n rc=fget(filein,char,1);\n substr(raw,i,1)=char;\n end;\n rc = fput(fileout, input(raw,$base64X4.));\n rc =fwrite(fileout);\n end;\n rc = fclose(filein);\n rc = fclose(fileout);\n run;\n%end;\n%else %do;\n data _null_;\n length filein 8 fileid 8;\n filein = fopen(\"&fref\",'I',1,'B');\n fileid = fopen(\"_webout\",'A',1,'B');\n rec = '20'x;\n do while(fread(filein)=0);\n rc = fget(filein,rec,1);\n rc = fput(fileid, rec);\n rc =fwrite(fileid);\n end;\n rc = fclose(filein);\n rc = fclose(fileid);\n run;\n%end;\n%mend;";
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.sasjsout = void 0;
4
- exports.sasjsout = "\n%macro sasjsout(type,fref=sasjs);\n%global sysprocessmode SYS_JES_JOB_URI;\n%if \"&sysprocessmode\"=\"SAS Compute Server\" %then %do;\n %if &type=HTML %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name=\"_webout.json\"\n contenttype=\"text/html\";\n %end;\n %else %if &type=JS or &type=JS64 %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.js'\n contenttype='application/javascript';\n %end;\n %else %if &type=CSS or &type=CSS64 %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.css'\n contenttype='text/css';\n %end;\n %else %if &type=PNG %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.png'\n contenttype='image/png' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=ICO %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.ico'\n contenttype='image/vnd.microsoft.icon' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=JSON %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.json'\n contenttype='application/json' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=MP3 %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.mp3'\n contenttype='audio/mpeg' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=WAV %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.wav'\n contenttype='audio/x-wav' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=OGG %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.ogg'\n contenttype='audio/ogg' lrecl=2000000 recfm=n;\n %end;\n%end;\n%else %do;\n %if &type=JS or &type=JS64 %then %do;\n %let rc=%sysfunc(stpsrv_header(\n Content-type,application/javascript%str(;)charset=UTF-8\n ));\n %end;\n %else %if &type=CSS or &type=CSS64 %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,text/css));\n %end;\n %else %if &type=PNG %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,image/png));\n %end;\n %else %if &type=ICO %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,image/vnd.microsoft.icon));\n %end;\n %else %if &type=JSON %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,application/json));\n %end;\n %else %if &type=MP3 %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,audio/mpeg));\n %end;\n %else %if &type=WAV %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,audio/x-wav));\n %end;\n %else %if &type=OGG %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,audio/ogg));\n %end;\n%end;\n%if &type=HTML %then %do;\n /*\n We need to perform some substitutions -eg to get the APPLOC and SERVERTYPE.\n Therefore the developer should avoid writing lines that exceed 32k\n characters (eg base64 encoded images) as they will get truncated when passing\n through the datastep. This could of course be re-written using LUA, removing\n the length restriction. Pull requests are welcome!\n */\n filename _sjs temp;\n data _null_;\n file _sjs lrecl=32767 encoding='utf-8';\n infile &fref lrecl=32767;\n input;\n length appLoc expanded_path $1048;\n if _n_=1 then do;\n retain pgm \"&_program\" appLoc expanded_path;\n /* index is deployed in the /services/ folder under the appLoc */\n appLoc=substr(pgm,1,find(pgm,'/services/')-1);\n expanded_path=cats('?_PROGRAM=',appLoc,'/services/');\n end;\n if find(_infile_,' appLoc: ') then put ' appLoc: ' apploc:$quote1048. ',';\n else if find(_infile_,' serverType: ') then do;\n if symexist('_metaperson') then put ' serverType: \"SAS9\" ,';\n else put ' serverType: \"SASVIYA\" ,';\n end;\n else if find(_infile_,' hostUrl: ') then do;\n /* nothing - we are streaming, so remove to default as hostname */\n end;\n else do;\n length newline $32767;\n /* during SAS9 compilation, dependencies are assigned three slashes /// */\n newline=tranwrd(_infile_,'?_PROGRAM=///',cats(expanded_path));\n put newline;\n end;\n run;\n %let fref=_sjs;\n%end;\n\n/* stream byte by byte */\n/* in SAS9, JS & CSS files are base64 encoded to avoid UTF8 issues in WLATIN1 metadata */\n%if &type=PNG or &type=ICO or &type=MP3 or &type=JS64 or &type=CSS64 or &type=WAV or &type=OGG\n%then %do;\n data _null_;\n length filein 8 fileout 8;\n filein = fopen(\"&fref\",'I',4,'B');\n fileout = fopen(\"_webout\",'A',1,'B');\n char= '20'x;\n do while(fread(filein)=0);\n length raw $4 ;\n do i=1 to 4;\n rc=fget(filein,char,1);\n substr(raw,i,1)=char;\n end;\n rc = fput(fileout, input(raw,$base64X4.));\n rc =fwrite(fileout);\n end;\n rc = fclose(filein);\n rc = fclose(fileout);\n run;\n%end;\n%else %do;\n data _null_;\n length filein 8 fileid 8;\n filein = fopen(\"&fref\",'I',1,'B');\n fileid = fopen(\"_webout\",'A',1,'B');\n rec = '20'x;\n do while(fread(filein)=0);\n rc = fget(filein,rec,1);\n rc = fput(fileid, rec);\n rc =fwrite(fileid);\n end;\n rc = fclose(filein);\n rc = fclose(fileid);\n run;\n%end;\n%mend;";
4
+ exports.sasjsout = "\n%macro sasjsout(type,fref=sasjs);\n%global sysprocessmode SYS_JES_JOB_URI;\n%if \"&sysprocessmode\"=\"SAS Compute Server\" %then %do;\n %if &type=HTML %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name=\"_webout.json\"\n contenttype=\"text/html\";\n %end;\n %else %if &type=JS or &type=JS64 %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.js'\n contenttype='application/javascript';\n %end;\n %else %if &type=CSS or &type=CSS64 %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.css'\n contenttype='text/css';\n %end;\n %else %if &type=PNG %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.png'\n contenttype='image/png' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=JPG %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.jpg'\n contenttype='image/jpg' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=JPEG %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.jpeg'\n contenttype='image/jpeg' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=ICO %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.ico'\n contenttype='image/vnd.microsoft.icon' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=JSON %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.json'\n contenttype='application/json' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=MP3 %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.mp3'\n contenttype='audio/mpeg' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=WAV %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.wav'\n contenttype='audio/x-wav' lrecl=2000000 recfm=n;\n %end;\n %else %if &type=OGG %then %do;\n filename _webout filesrvc parenturi=\"&SYS_JES_JOB_URI\" name='_webout.ogg'\n contenttype='audio/ogg' lrecl=2000000 recfm=n;\n %end;\n%end;\n%else %do;\n %if &type=JS or &type=JS64 %then %do;\n %let rc=%sysfunc(stpsrv_header(\n Content-type,application/javascript%str(;)charset=UTF-8\n ));\n %end;\n %else %if &type=CSS or &type=CSS64 %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,text/css));\n %end;\n %else %if &type=PNG %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,image/png));\n %end;\n %else %if &type=JPG %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,image/jpg));\n %end;\n %else %if &type=JPEG %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,image/jpeg));\n %end;\n %else %if &type=ICO %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,image/vnd.microsoft.icon));\n %end;\n %else %if &type=JSON %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,application/json));\n %end;\n %else %if &type=MP3 %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,audio/mpeg));\n %end;\n %else %if &type=WAV %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,audio/x-wav));\n %end;\n %else %if &type=OGG %then %do;\n %let rc=%sysfunc(stpsrv_header(Content-type,audio/ogg));\n %end;\n%end;\n%if &type=HTML %then %do;\n /*\n We need to perform some substitutions -eg to get the APPLOC and SERVERTYPE.\n Therefore the developer should avoid writing lines that exceed 32k\n characters (eg base64 encoded images) as they will get truncated when passing\n through the datastep. This could of course be re-written using LUA, removing\n the length restriction. Pull requests are welcome!\n */\n filename _sjs temp;\n data _null_;\n file _sjs lrecl=32767 encoding='utf-8';\n infile &fref lrecl=32767;\n input;\n length appLoc expanded_path $1048;\n if _n_=1 then do;\n retain pgm \"&_program\" appLoc expanded_path;\n /* index is deployed in the /services/ folder under the appLoc */\n appLoc=substr(pgm,1,find(pgm,'/services/')-1);\n expanded_path=cats('?_PROGRAM=',appLoc,'/services/');\n end;\n if find(_infile_,' appLoc: ') then put ' appLoc: ' apploc:$quote1048. ',';\n else if find(_infile_,' serverType: ') then do;\n if symexist('_metaperson') then put ' serverType: \"SAS9\" ,';\n else put ' serverType: \"SASVIYA\" ,';\n end;\n else if find(_infile_,' hostUrl: ') then do;\n /* nothing - we are streaming, so remove to default as hostname */\n end;\n else do;\n length newline $32767;\n /* during SAS9 compilation, dependencies are assigned three slashes /// */\n newline=tranwrd(_infile_,'?_PROGRAM=///',cats(expanded_path));\n put newline;\n end;\n run;\n %let fref=_sjs;\n%end;\n\n/* stream byte by byte */\n/* in SAS9, JS & CSS files are base64 encoded to avoid UTF8 issues in WLATIN1 metadata */\n%if &type=PNG or &type=JPG or &type=JPEG or &type=ICO or &type=MP3 or &type=JS64 or &type=CSS64 or &type=WAV or &type=OGG\n%then %do;\n data _null_;\n length filein 8 fileout 8;\n filein = fopen(\"&fref\",'I',4,'B');\n fileout = fopen(\"_webout\",'A',1,'B');\n char= '20'x;\n do while(fread(filein)=0);\n length raw $4 ;\n do i=1 to 4;\n rc=fget(filein,char,1);\n substr(raw,i,1)=char;\n end;\n rc = fput(fileout, input(raw,$base64X4.));\n rc =fwrite(fileout);\n end;\n rc = fclose(filein);\n rc = fclose(fileout);\n run;\n%end;\n%else %do;\n data _null_;\n length filein 8 fileid 8;\n filein = fopen(\"&fref\",'I',1,'B');\n fileid = fopen(\"_webout\",'A',1,'B');\n rec = '20'x;\n do while(fread(filein)=0);\n rc = fget(filein,rec,1);\n rc = fput(fileid, rec);\n rc =fwrite(fileid);\n end;\n rc = fclose(filein);\n rc = fclose(fileid);\n run;\n%end;\n%mend;";
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+ export {};
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * @jest-environment jsdom
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var updateLinkTag_1 = require("../updateLinkTag");
7
+ describe('updateLinkTag', function () {
8
+ it("should update href of link tag", function () {
9
+ var linkTag = document.createElement('link');
10
+ linkTag.setAttribute('href', './style.css');
11
+ var assetPathMap = [];
12
+ var sasProgramPath = '/SASJobExecution?_FILE=appLoc/services/streamWebFolder/style.css';
13
+ assetPathMap.push({
14
+ source: 'style.css',
15
+ target: sasProgramPath
16
+ });
17
+ updateLinkTag_1.updateLinkTag(linkTag, assetPathMap);
18
+ expect(linkTag.getAttribute('href')).toEqual(sasProgramPath);
19
+ });
20
+ it("should update src of image tag", function () {
21
+ var imgTag = document.createElement('img');
22
+ imgTag.setAttribute('src', './image.jpeg');
23
+ var assetPathMap = [];
24
+ var sasProgramPath = '/SASJobExecution?_FILE=appLoc/services/streamWebFolder/image.jpeg';
25
+ assetPathMap.push({
26
+ source: 'image.jpeg',
27
+ target: sasProgramPath
28
+ });
29
+ updateLinkTag_1.updateLinkTag(imgTag, assetPathMap, 'image');
30
+ expect(imgTag.getAttribute('src')).toEqual(sasProgramPath);
31
+ });
32
+ });
@@ -35,16 +35,37 @@ 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) {
55
+ for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
56
+ to[j] = from[i];
57
+ return to;
58
+ };
38
59
  Object.defineProperty(exports, "__esModule", { value: true });
39
60
  exports.updateAllTags = void 0;
40
61
  var utils_1 = require("@sasjs/utils");
41
62
  var getTags_1 = require("./getTags");
42
63
  var updateScriptTag_1 = require("./updateScriptTag");
43
- var updateLinkHref_1 = require("./updateLinkHref");
64
+ var updateLinkTag_1 = require("./updateLinkTag");
44
65
  var updateAllTags = function (parsedHtml, _a) {
45
66
  var webSourcePathFull = _a.webSourcePathFull, destinationPath = _a.destinationPath, serverType = _a.serverType, assetPathMap = _a.assetPathMap;
46
67
  return __awaiter(void 0, void 0, void 0, function () {
47
- var assetsNotFound, scriptTags, linkTags, faviconTags, notFoundErrors;
68
+ var assetsNotFound, scriptTags, styleTags, faviconTags, linkTags, imgTags, notFoundErrors;
48
69
  return __generator(this, function (_b) {
49
70
  switch (_b.label) {
50
71
  case 0:
@@ -62,21 +83,25 @@ var updateAllTags = function (parsedHtml, _a) {
62
83
  }); })];
63
84
  case 1:
64
85
  _b.sent();
65
- linkTags = getTags_1.getLinkTags(parsedHtml);
66
- linkTags.forEach(function (linkTag) {
86
+ styleTags = getTags_1.getStyleTags(parsedHtml);
87
+ faviconTags = getTags_1.getFaviconTags(parsedHtml);
88
+ linkTags = __spreadArray(__spreadArray([], __read(styleTags)), __read(faviconTags));
89
+ linkTags.forEach(function (tag) {
67
90
  try {
68
- updateLinkHref_1.updateLinkHref(linkTag, assetPathMap);
91
+ updateLinkTag_1.updateLinkTag(tag, assetPathMap);
69
92
  }
70
93
  catch (error) {
94
+ console.log(tag, error);
71
95
  assetsNotFound.push(error);
72
96
  }
73
97
  });
74
- faviconTags = getTags_1.getFaviconTags(parsedHtml);
75
- faviconTags.forEach(function (faviconTag) {
98
+ imgTags = getTags_1.getImgTags(parsedHtml);
99
+ imgTags.forEach(function (tag) {
76
100
  try {
77
- updateLinkHref_1.updateLinkHref(faviconTag, assetPathMap);
101
+ updateLinkTag_1.updateLinkTag(tag, assetPathMap, 'image');
78
102
  }
79
103
  catch (error) {
104
+ console.log(tag, error);
80
105
  assetsNotFound.push(error);
81
106
  }
82
107
  });
@@ -0,0 +1,4 @@
1
+ export declare const updateLinkTag: (linkTag: HTMLLinkElement | HTMLImageElement, assetPathMap: {
2
+ source: string;
3
+ target: string;
4
+ }[], tagType?: 'link' | 'image') => void;