@sasjs/cli 3.23.6 → 3.24.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.
@@ -7,5 +7,6 @@ export declare class FSCommand extends TargetCommand {
7
7
  getOutputPath(): Promise<string>;
8
8
  execute(): Promise<ReturnCode>;
9
9
  compile(): Promise<ReturnCode>;
10
+ deploy(): Promise<ReturnCode.Success | ReturnCode.InternalError>;
10
11
  sync(): Promise<ReturnCode.Success | ReturnCode.InternalError>;
11
12
  }
@@ -108,11 +108,11 @@ var utils_1 = require("../../utils");
108
108
  var path_1 = __importDefault(require("path"));
109
109
  var utils_2 = require("@sasjs/utils");
110
110
  var executeCode_1 = require("./internal/executeCode");
111
- var extractHashArray_1 = require("./internal/extractHashArray");
112
111
  var FsSubCommand;
113
112
  (function (FsSubCommand) {
114
113
  FsSubCommand["Compile"] = "compile";
115
114
  FsSubCommand["Sync"] = "sync";
115
+ FsSubCommand["Deploy"] = "deploy";
116
116
  })(FsSubCommand || (FsSubCommand = {}));
117
117
  var syntax = 'fs <subCommand> [options]';
118
118
  var usage = 'Usage: sasjs fs <subCommand> [options]';
@@ -147,6 +147,15 @@ var syncCommandExamples = [
147
147
  }
148
148
  ];
149
149
  var syncCommandParseOptions = __assign(__assign({}, parseOptions), { local: { type: 'string', alias: 'l' }, remote: { type: 'string', alias: 'r' } });
150
+ var deployCommandSyntax = 'fs <subCommand> <local> <remote> [options]';
151
+ var deployCommandUsage = 'sasjs fs deploy <localFolder> <remoteFolder> [options]';
152
+ var deployCommandDescription = 'Compiles and deploys a local directory tree with one on a remote SAS server.';
153
+ var deployCommandExamples = [
154
+ {
155
+ command: 'sasjs fs deploy <path/of/folder> --output <path/of/outputProgram>',
156
+ description: 'deploys a SAS program with the contents of a local directory'
157
+ }
158
+ ];
150
159
  var FSCommand = /** @class */ (function (_super) {
151
160
  __extends(FSCommand, _super);
152
161
  function FSCommand(args) {
@@ -165,6 +174,12 @@ var FSCommand = /** @class */ (function (_super) {
165
174
  commandOptions.description = compileCommandDescription;
166
175
  commandOptions.examples = compileCommandExamples;
167
176
  break;
177
+ case FsSubCommand.Deploy:
178
+ commandOptions.syntax = deployCommandSyntax;
179
+ commandOptions.usage = deployCommandUsage;
180
+ commandOptions.description = deployCommandDescription;
181
+ commandOptions.examples = deployCommandExamples;
182
+ break;
168
183
  case FsSubCommand.Sync:
169
184
  commandOptions.syntax = syncCommandSyntax;
170
185
  commandOptions.usage = syncCommandUsage;
@@ -211,7 +226,7 @@ var FSCommand = /** @class */ (function (_super) {
211
226
  }
212
227
  }
213
228
  if (!outputPath) {
214
- return [2 /*return*/, path_1.default.join(process.sasjsConstants.buildDestinationResultsFolder, 'fs-sync', (0, utils_2.generateTimestamp)())];
229
+ return [2 /*return*/, path_1.default.join(process.sasjsConstants.buildDestinationResultsFolder, "fs-".concat(this.parsed.subcommand), (0, utils_2.generateTimestamp)())];
215
230
  }
216
231
  if (path_1.default.isAbsolute(outputPath)) {
217
232
  return [2 /*return*/, path_1.default.join(outputPath, (0, utils_2.generateTimestamp)())];
@@ -229,10 +244,14 @@ var FSCommand = /** @class */ (function (_super) {
229
244
  return [4 /*yield*/, this.compile()];
230
245
  case 1: return [2 /*return*/, _a.sent()];
231
246
  case 2:
232
- if (!(this.parsed.subCommand === FsSubCommand.Sync)) return [3 /*break*/, 4];
233
- return [4 /*yield*/, this.sync()];
247
+ if (!(this.parsed.subCommand === FsSubCommand.Deploy)) return [3 /*break*/, 4];
248
+ return [4 /*yield*/, this.deploy()];
234
249
  case 3: return [2 /*return*/, _a.sent()];
235
- case 4: return [2 /*return*/, command_1.ReturnCode.InvalidCommand];
250
+ case 4:
251
+ if (!(this.parsed.subCommand === FsSubCommand.Sync)) return [3 /*break*/, 6];
252
+ return [4 /*yield*/, this.sync()];
253
+ case 5: return [2 /*return*/, _a.sent()];
254
+ case 6: return [2 /*return*/, command_1.ReturnCode.InvalidCommand];
236
255
  }
237
256
  });
238
257
  });
@@ -265,6 +284,64 @@ var FSCommand = /** @class */ (function (_super) {
265
284
  });
266
285
  });
267
286
  };
287
+ FSCommand.prototype.deploy = function () {
288
+ var _a, _b, _c, _d, _e;
289
+ return __awaiter(this, void 0, void 0, function () {
290
+ var target, remoteFolderPath, localFolderPath, outputFolder, code, program, error_1, logPath;
291
+ var _this = this;
292
+ return __generator(this, function (_f) {
293
+ switch (_f.label) {
294
+ case 0: return [4 /*yield*/, this.getTargetInfo()];
295
+ case 1:
296
+ target = (_f.sent()).target;
297
+ remoteFolderPath = this.remoteFolder;
298
+ localFolderPath = this.localFolder;
299
+ return [4 /*yield*/, this.getOutputPath()];
300
+ case 2:
301
+ outputFolder = _f.sent();
302
+ _f.label = 3;
303
+ case 3:
304
+ _f.trys.push([3, 7, , 9]);
305
+ (_a = process.logger) === null || _a === void 0 ? void 0 : _a.info('generating compile program');
306
+ return [4 /*yield*/, (0, utils_2.generateCompileProgram)(localFolderPath)];
307
+ case 4:
308
+ code = _f.sent();
309
+ (_b = process.logger) === null || _b === void 0 ? void 0 : _b.info('setting fsTaregt at the start of compiled program');
310
+ program = "%let fsTarget=".concat((0, utils_2.generatePathForSas)(remoteFolderPath), ";\n").concat(code);
311
+ return [4 /*yield*/, createProgramFile(program, path_1.default.join(outputFolder, 'deploy.sas'))];
312
+ case 5:
313
+ _f.sent();
314
+ (_c = process.logger) === null || _c === void 0 ? void 0 : _c.info('executing program to deploy a local directory tree');
315
+ return [4 /*yield*/, (0, executeCode_1.executeCode)(target, program).then(function (_a) {
316
+ var log = _a.log;
317
+ return __awaiter(_this, void 0, void 0, function () {
318
+ return __generator(this, function (_b) {
319
+ switch (_b.label) {
320
+ case 0: return [4 /*yield*/, (0, utils_1.saveLog)(log, path_1.default.join(outputFolder, 'deploy.log'), '', false)];
321
+ case 1:
322
+ _b.sent();
323
+ return [2 /*return*/];
324
+ }
325
+ });
326
+ });
327
+ })];
328
+ case 6:
329
+ _f.sent();
330
+ (_d = process.logger) === null || _d === void 0 ? void 0 : _d.success("A local directory tree has been successfully deployed to remote sas server");
331
+ return [2 /*return*/, command_1.ReturnCode.Success];
332
+ case 7:
333
+ error_1 = _f.sent();
334
+ logPath = path_1.default.join(outputFolder, 'error.log');
335
+ return [4 /*yield*/, createErrorLogFile(error_1, logPath)];
336
+ case 8:
337
+ _f.sent();
338
+ (_e = process.logger) === null || _e === void 0 ? void 0 : _e.error("An error has occurred. For more info see ".concat(logPath));
339
+ return [2 /*return*/, command_1.ReturnCode.InternalError];
340
+ case 9: return [2 /*return*/];
341
+ }
342
+ });
343
+ });
344
+ };
268
345
  FSCommand.prototype.sync = function () {
269
346
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
270
347
  return __awaiter(this, void 0, void 0, function () {
@@ -295,7 +372,7 @@ var FSCommand = /** @class */ (function (_super) {
295
372
  return [2 /*return*/, command_1.ReturnCode.Success];
296
373
  }
297
374
  _loop_1 = function (obj) {
298
- var outputFolder, program, log, remoteHashes, localHash, remoteHashMap_1, hashedDiff, syncProgram, syncLog, syncedHash, syncedHashMap, syncedResources_1, resourcesNotPresentLocally, error_1, logPath;
375
+ var outputFolder, program, log, remoteHashes, localHash, remoteHashMap_1, hashedDiff, syncProgram, syncLog, syncedHash, syncedHashMap, syncedResources_1, resourcesNotPresentLocally, error_2, logPath;
299
376
  return __generator(this, function (_v) {
300
377
  switch (_v.label) {
301
378
  case 0: return [4 /*yield*/, this_1.getOutputPath()];
@@ -319,7 +396,7 @@ var FSCommand = /** @class */ (function (_super) {
319
396
  case 6:
320
397
  _v.sent();
321
398
  (_d = process.logger) === null || _d === void 0 ? void 0 : _d.info('extracting hashes from log');
322
- remoteHashes = (0, extractHashArray_1.extractHashArray)(log);
399
+ remoteHashes = (0, utils_2.extractHashArray)(log);
323
400
  return [4 /*yield*/, createHashFile(JSON.stringify(remoteHashes, null, 2), path_1.default.join(outputFolder, 'hashesBeforeSync.json'))];
324
401
  case 7:
325
402
  _v.sent();
@@ -357,7 +434,7 @@ var FSCommand = /** @class */ (function (_super) {
357
434
  return [4 /*yield*/, (0, utils_1.saveLog)(syncLog, path_1.default.join(outputFolder, 'sync.log'), '', false)];
358
435
  case 13:
359
436
  _v.sent();
360
- syncedHash = (0, extractHashArray_1.extractHashArray)(syncLog);
437
+ syncedHash = (0, utils_2.extractHashArray)(syncLog);
361
438
  return [4 /*yield*/, createHashFile(JSON.stringify(syncedHash, null, 2), path_1.default.join(outputFolder, 'hashesAfterSync.json'))];
362
439
  case 14:
363
440
  _v.sent();
@@ -391,9 +468,9 @@ var FSCommand = /** @class */ (function (_super) {
391
468
  }
392
469
  return [3 /*break*/, 17];
393
470
  case 15:
394
- error_1 = _v.sent();
471
+ error_2 = _v.sent();
395
472
  logPath = path_1.default.join(outputFolder, 'error.log');
396
- return [4 /*yield*/, createErrorLogFile(error_1, logPath)];
473
+ return [4 /*yield*/, createErrorLogFile(error_2, logPath)];
397
474
  case 16:
398
475
  _v.sent();
399
476
  (_m = process.logger) === null || _m === void 0 ? void 0 : _m.error("An error has occurred. For more info see ".concat(logPath));
@@ -88,7 +88,6 @@ var FSModule = __importStar(require("@sasjs/utils/fs"));
88
88
  var FileModule = __importStar(require("@sasjs/utils/file"));
89
89
  var configUtils = __importStar(require("../../../utils/config"));
90
90
  var executeCodeModule = __importStar(require("../internal/executeCode"));
91
- var extractHashArrayModule = __importStar(require("../internal/extractHashArray"));
92
91
  var defaultArgs = ['node', 'sasjs', 'fs'];
93
92
  var target = new utils_1.Target({
94
93
  name: 'test',
@@ -154,6 +153,67 @@ describe('FSCommand', function () {
154
153
  });
155
154
  }); });
156
155
  });
156
+ describe('deploy', function () {
157
+ beforeEach(function () {
158
+ process.logger = new utils_1.Logger(utils_1.LogLevel.Off);
159
+ jest.spyOn(process.logger, 'error');
160
+ jest.spyOn(process.logger, 'info');
161
+ jest
162
+ .spyOn(configUtils, 'findTargetInConfiguration')
163
+ .mockImplementation(function () {
164
+ return Promise.resolve({ target: target, isLocal: true });
165
+ });
166
+ jest
167
+ .spyOn(FSModule, 'generateCompileProgram')
168
+ .mockImplementation(function () { return Promise.resolve(''); });
169
+ jest
170
+ .spyOn(FileModule, 'createFile')
171
+ .mockImplementation(function () { return Promise.resolve(); });
172
+ jest
173
+ .spyOn(executeCodeModule, 'executeCode')
174
+ .mockImplementation(function () { return Promise.resolve({ log: '' }); });
175
+ });
176
+ it('should compile and deploy a local directory tree to a remote sas server', function () { return __awaiter(void 0, void 0, void 0, function () {
177
+ var returnCode;
178
+ return __generator(this, function (_a) {
179
+ switch (_a.label) {
180
+ case 0:
181
+ jest
182
+ .spyOn(FileModule, 'createFile')
183
+ .mockImplementation(function () { return Promise.resolve(); });
184
+ return [4 /*yield*/, executeCommandWrapper([
185
+ 'deploy',
186
+ 'localFolder',
187
+ 'remoteFolder'
188
+ ])];
189
+ case 1:
190
+ returnCode = _a.sent();
191
+ expect(returnCode).toEqual(command_1.ReturnCode.Success);
192
+ return [2 /*return*/];
193
+ }
194
+ });
195
+ }); });
196
+ it('should return an internal error return code', function () { return __awaiter(void 0, void 0, void 0, function () {
197
+ var returnCode;
198
+ return __generator(this, function (_a) {
199
+ switch (_a.label) {
200
+ case 0:
201
+ jest
202
+ .spyOn(FileModule, 'createFile')
203
+ .mockImplementationOnce(function () { return Promise.reject({}); });
204
+ return [4 /*yield*/, executeCommandWrapper([
205
+ 'deploy',
206
+ 'localFolder',
207
+ 'remoteFolder'
208
+ ])];
209
+ case 1:
210
+ returnCode = _a.sent();
211
+ expect(returnCode).toEqual(command_1.ReturnCode.InternalError);
212
+ return [2 /*return*/];
213
+ }
214
+ });
215
+ }); });
216
+ });
157
217
  describe('sync', function () {
158
218
  beforeEach(function () {
159
219
  process.logger = new utils_1.Logger(utils_1.LogLevel.Off);
@@ -197,17 +257,13 @@ describe('FSCommand', function () {
197
257
  return __generator(this, function (_a) {
198
258
  switch (_a.label) {
199
259
  case 0:
200
- jest
201
- .spyOn(extractHashArrayModule, 'extractHashArray')
202
- .mockImplementationOnce(function () { return [
260
+ jest.spyOn(FSModule, 'extractHashArray').mockImplementationOnce(function () { return [
203
261
  {
204
262
  FILE_PATH: 'mocked-file',
205
263
  FILE_HASH: 'hashOfMockedFile'
206
264
  }
207
265
  ]; });
208
- jest
209
- .spyOn(extractHashArrayModule, 'extractHashArray')
210
- .mockImplementationOnce(function () { return [
266
+ jest.spyOn(FSModule, 'extractHashArray').mockImplementationOnce(function () { return [
211
267
  {
212
268
  FILE_PATH: 'synced-file',
213
269
  FILE_HASH: 'hashOfSyncedFile'
@@ -239,9 +295,7 @@ describe('FSCommand', function () {
239
295
  return __generator(this, function (_a) {
240
296
  switch (_a.label) {
241
297
  case 0:
242
- jest
243
- .spyOn(extractHashArrayModule, 'extractHashArray')
244
- .mockImplementation(function () { return [
298
+ jest.spyOn(FSModule, 'extractHashArray').mockImplementation(function () { return [
245
299
  {
246
300
  FILE_PATH: 'mocked-file',
247
301
  FILE_HASH: 'hashOfMockedFile'
package/package.json CHANGED
@@ -52,8 +52,8 @@
52
52
  "dependencies": {
53
53
  "@sasjs/adapter": "4.1.0",
54
54
  "@sasjs/core": "4.45.4",
55
- "@sasjs/lint": "2.0.1",
56
- "@sasjs/utils": "2.51.3",
55
+ "@sasjs/lint": "2.1.2",
56
+ "@sasjs/utils": "2.51.5",
57
57
  "adm-zip": "0.5.9",
58
58
  "chalk": "4.1.2",
59
59
  "csv-stringify": "5.6.5",
@@ -101,5 +101,5 @@
101
101
  "typescript": "4.5.4",
102
102
  "util": "0.12.4"
103
103
  },
104
- "version": "3.23.6"
104
+ "version": "3.24.0"
105
105
  }
@@ -1 +0,0 @@
1
- export declare const extractHashArray: (log: string) => any;
@@ -1,20 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.extractHashArray = void 0;
4
- var utils_1 = require("../../../utils");
5
- var extractHashArray = function (log) {
6
- if (log.includes('>>weboutBEGIN<<')) {
7
- try {
8
- var webout = log
9
- .split(/>>weboutBEGIN<<\n/)[1]
10
- .split(/>>weboutEND<<\n/)[0];
11
- var jsonWebout = JSON.parse(webout);
12
- return jsonWebout.hashes;
13
- }
14
- catch (err) {
15
- (0, utils_1.displayError)(err, 'An error occurred while extracting hashes array from webout.');
16
- throw new Error('An error occurred while extracting hashes array from webout.');
17
- }
18
- }
19
- };
20
- exports.extractHashArray = extractHashArray;
@@ -1 +0,0 @@
1
- export {};
@@ -1,14 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var extractHashArray_1 = require("../internal/extractHashArray");
4
- var log = "\n>>weboutBEGIN<<\n{\n \"hashes\": [{\n \"FILE_HASH\": \"someCharacters\",\n \"FILE_PATH\": \"path/to/folder/file\"\n }]\n}\n>>weboutEND<<\n";
5
- var logWithInvalidJsonInWebout = "\n>>weboutBEGIN<<\n{\n \"invalid Json\"\n}\n>>weboutEND<<\n";
6
- describe('extractHashArray', function () {
7
- it('should extract hashed array from webout', function () {
8
- var hashes = (0, extractHashArray_1.extractHashArray)(log);
9
- expect(hashes).toBeArrayOfSize(1);
10
- });
11
- it('should throw error when log does not contain webout', function () {
12
- expect(function () { return (0, extractHashArray_1.extractHashArray)(logWithInvalidJsonInWebout); }).toThrow('An error occurred while extracting hashes array from webout.');
13
- });
14
- });