@sasjs/cli 6.4.8 → 6.6.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 (33) hide show
  1. package/README.md +1 -0
  2. package/build/commands/build/build.js +66 -29
  3. package/build/commands/build/buildDeployCommand.d.ts +6 -0
  4. package/build/commands/build/buildDeployCommand.js +120 -0
  5. package/build/commands/build/spec/build.spec.js +31 -1
  6. package/build/commands/build/spec/buildDeployCommand.spec.d.ts +1 -0
  7. package/build/commands/build/spec/buildDeployCommand.spec.js +234 -0
  8. package/build/commands/compile/compile.js +168 -33
  9. package/build/commands/compile/compileCommand.js +1 -1
  10. package/build/commands/compile/internal/checkCompileStatus.js +30 -11
  11. package/build/commands/compile/internal/compileFile.js +16 -7
  12. package/build/commands/compile/internal/compileManifest.d.ts +36 -0
  13. package/build/commands/compile/internal/compileManifest.js +610 -0
  14. package/build/commands/compile/internal/index.d.ts +2 -0
  15. package/build/commands/compile/internal/index.js +2 -0
  16. package/build/commands/compile/internal/passThrough.d.ts +12 -0
  17. package/build/commands/compile/internal/passThrough.js +17 -0
  18. package/build/commands/compile/internal/spec/compileTestFile.spec.js +9 -6
  19. package/build/commands/compile/spec/checkCompileStatus.spec.d.ts +1 -0
  20. package/build/commands/compile/spec/checkCompileStatus.spec.js +221 -0
  21. package/build/commands/compile/spec/compileCommand.spec.js +9 -2
  22. package/build/commands/compile/spec/compileManifest.spec.d.ts +1 -0
  23. package/build/commands/compile/spec/compileManifest.spec.js +401 -0
  24. package/build/commands/compile/spec/passThrough.spec.d.ts +1 -0
  25. package/build/commands/compile/spec/passThrough.spec.js +160 -0
  26. package/build/commands/deploy/spec/cbd.spec.js +11 -7
  27. package/build/commands/help/help.js +11 -0
  28. package/build/commands/testing/spec/testCommand.spec.js +12 -0
  29. package/build/commands/testing/spec/testing.spec.js +8 -2
  30. package/build/commands/testing/testCommand.js +3 -1
  31. package/build/types/command/commandAliases.js +2 -0
  32. package/build/types/command/commandFactory.js +2 -0
  33. package/package.json +1 -1
@@ -0,0 +1,401 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ 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);
24
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ 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;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __importDefault = (this && this.__importDefault) || function (mod) {
50
+ return (mod && mod.__esModule) ? mod : { "default": mod };
51
+ };
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ var path_1 = __importDefault(require("path"));
54
+ var promises_1 = require("fs/promises");
55
+ var utils_1 = require("@sasjs/utils");
56
+ var utils_2 = require("../../../utils");
57
+ var test_1 = require("../../../utils/test");
58
+ var internal_1 = require("../internal");
59
+ describe('compile manifest', function () {
60
+ var folderPath;
61
+ beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
62
+ return __generator(this, function (_a) {
63
+ switch (_a.label) {
64
+ case 0: return [4 /*yield*/, (0, utils_2.setConstants)(false)];
65
+ case 1:
66
+ _a.sent();
67
+ return [2 /*return*/];
68
+ }
69
+ });
70
+ }); });
71
+ beforeEach(function () { return __awaiter(void 0, void 0, void 0, function () {
72
+ return __generator(this, function (_a) {
73
+ switch (_a.label) {
74
+ case 0:
75
+ folderPath = path_1.default.join(__dirname, "cli-tests-manifest-".concat((0, test_1.generateUniqueTimestamp)()));
76
+ return [4 /*yield*/, (0, utils_1.createFolder)(folderPath)];
77
+ case 1:
78
+ _a.sent();
79
+ return [2 /*return*/];
80
+ }
81
+ });
82
+ }); });
83
+ afterEach(function () { return __awaiter(void 0, void 0, void 0, function () {
84
+ return __generator(this, function (_a) {
85
+ switch (_a.label) {
86
+ case 0: return [4 /*yield*/, (0, utils_1.deleteFolder)(folderPath)];
87
+ case 1:
88
+ _a.sent();
89
+ return [2 /*return*/];
90
+ }
91
+ });
92
+ }); });
93
+ it('records what the compile read, and reports nothing when it is unchanged', function () { return __awaiter(void 0, void 0, void 0, function () {
94
+ var manifest;
95
+ return __generator(this, function (_a) {
96
+ switch (_a.label) {
97
+ case 0: return [4 /*yield*/, (0, utils_1.createFile)(path_1.default.join(folderPath, 'service.sas'), '%put hello;')];
98
+ case 1:
99
+ _a.sent();
100
+ return [4 /*yield*/, (0, internal_1.writeCompileManifest)([folderPath])];
101
+ case 2:
102
+ _a.sent();
103
+ return [4 /*yield*/, (0, internal_1.readCompileManifest)()];
104
+ case 3:
105
+ manifest = _a.sent();
106
+ expect(manifest).not.toBeNull();
107
+ expect(Object.keys(manifest)).toHaveLength(1);
108
+ return [4 /*yield*/, expect((0, internal_1.getChangedFiles)([folderPath])).resolves.toEqual([])];
109
+ case 4:
110
+ _a.sent();
111
+ return [2 /*return*/];
112
+ }
113
+ });
114
+ }); });
115
+ it('reports a file whose content changed', function () { return __awaiter(void 0, void 0, void 0, function () {
116
+ var changed;
117
+ return __generator(this, function (_a) {
118
+ switch (_a.label) {
119
+ case 0: return [4 /*yield*/, (0, utils_1.createFile)(path_1.default.join(folderPath, 'service.sas'), '%put hello;')];
120
+ case 1:
121
+ _a.sent();
122
+ return [4 /*yield*/, (0, internal_1.writeCompileManifest)([folderPath])];
123
+ case 2:
124
+ _a.sent();
125
+ return [4 /*yield*/, (0, utils_1.createFile)(path_1.default.join(folderPath, 'service.sas'), '%put goodbye;')];
126
+ case 3:
127
+ _a.sent();
128
+ return [4 /*yield*/, (0, internal_1.getChangedFiles)([folderPath])];
129
+ case 4:
130
+ changed = _a.sent();
131
+ expect(changed).toHaveLength(1);
132
+ expect(changed[0]).toEqual(path_1.default.join(folderPath, 'service.sas'));
133
+ return [2 /*return*/];
134
+ }
135
+ });
136
+ }); });
137
+ it('reports a file the manifest has never seen, including in a sub folder', function () { return __awaiter(void 0, void 0, void 0, function () {
138
+ var changed;
139
+ return __generator(this, function (_a) {
140
+ switch (_a.label) {
141
+ case 0: return [4 /*yield*/, (0, internal_1.writeCompileManifest)([folderPath])];
142
+ case 1:
143
+ _a.sent();
144
+ return [4 /*yield*/, (0, utils_1.createFolder)(path_1.default.join(folderPath, 'editors'))];
145
+ case 2:
146
+ _a.sent();
147
+ return [4 /*yield*/, (0, utils_1.createFile)(path_1.default.join(folderPath, 'editors', 'getdata.js'), 'const a = 1')];
148
+ case 3:
149
+ _a.sent();
150
+ return [4 /*yield*/, (0, internal_1.getChangedFiles)([folderPath])];
151
+ case 4:
152
+ changed = _a.sent();
153
+ expect(changed).toHaveLength(1);
154
+ expect(changed[0]).toEqual(path_1.default.join(folderPath, 'editors', 'getdata.js'));
155
+ return [2 /*return*/];
156
+ }
157
+ });
158
+ }); });
159
+ it('hashes test files, which live in the service folders and are compiled too', function () { return __awaiter(void 0, void 0, void 0, function () {
160
+ var changed;
161
+ return __generator(this, function (_a) {
162
+ switch (_a.label) {
163
+ case 0: return [4 /*yield*/, (0, utils_1.createFile)(path_1.default.join(folderPath, 'getdata.test.1.sas'), '%put test;')];
164
+ case 1:
165
+ _a.sent();
166
+ return [4 /*yield*/, (0, internal_1.writeCompileManifest)([folderPath])];
167
+ case 2:
168
+ _a.sent();
169
+ return [4 /*yield*/, (0, utils_1.createFile)(path_1.default.join(folderPath, 'getdata.test.1.sas'), '%put changed test;')];
170
+ case 3:
171
+ _a.sent();
172
+ return [4 /*yield*/, (0, internal_1.getChangedFiles)([folderPath])];
173
+ case 4:
174
+ changed = _a.sent();
175
+ expect(changed).toHaveLength(1);
176
+ expect(changed[0]).toContain('getdata.test.1.sas');
177
+ return [2 /*return*/];
178
+ }
179
+ });
180
+ }); });
181
+ it('reports a stamp file whose content changed', function () { return __awaiter(void 0, void 0, void 0, function () {
182
+ var stamp;
183
+ return __generator(this, function (_a) {
184
+ switch (_a.label) {
185
+ case 0:
186
+ stamp = path_1.default.join(folderPath, 'package.json');
187
+ return [4 /*yield*/, (0, utils_1.createFile)(stamp, '{"dependencies":{"@sasjs/core":"6.1.0"}}')];
188
+ case 1:
189
+ _a.sent();
190
+ return [4 /*yield*/, (0, internal_1.writeCompileManifest)([], [stamp])];
191
+ case 2:
192
+ _a.sent();
193
+ return [4 /*yield*/, (0, utils_1.createFile)(stamp, '{"dependencies":{"@sasjs/core":"6.2.0"}}')];
194
+ case 3:
195
+ _a.sent();
196
+ return [4 /*yield*/, expect((0, internal_1.getChangedFiles)([], [stamp])).resolves.toEqual([stamp])];
197
+ case 4:
198
+ _a.sent();
199
+ return [2 /*return*/];
200
+ }
201
+ });
202
+ }); });
203
+ it('reports a stamp file the manifest has never seen', function () { return __awaiter(void 0, void 0, void 0, function () {
204
+ var stamp;
205
+ return __generator(this, function (_a) {
206
+ switch (_a.label) {
207
+ case 0:
208
+ stamp = path_1.default.join(folderPath, 'package-lock.json');
209
+ return [4 /*yield*/, (0, internal_1.writeCompileManifest)([])];
210
+ case 1:
211
+ _a.sent();
212
+ return [4 /*yield*/, (0, utils_1.createFile)(stamp, '{}')];
213
+ case 2:
214
+ _a.sent();
215
+ return [4 /*yield*/, expect((0, internal_1.getChangedFiles)([], [stamp])).resolves.toEqual([stamp])];
216
+ case 3:
217
+ _a.sent();
218
+ return [2 /*return*/];
219
+ }
220
+ });
221
+ }); });
222
+ it('treats a corrupt manifest as a project that has not been compiled', function () { return __awaiter(void 0, void 0, void 0, function () {
223
+ var changed;
224
+ return __generator(this, function (_a) {
225
+ switch (_a.label) {
226
+ case 0: return [4 /*yield*/, (0, internal_1.writeCompileManifest)([folderPath])];
227
+ case 1:
228
+ _a.sent();
229
+ return [4 /*yield*/, (0, utils_1.createFile)((0, internal_1.getManifestPath)(), 'not json at all')];
230
+ case 2:
231
+ _a.sent();
232
+ return [4 /*yield*/, (0, internal_1.getChangedFiles)([folderPath])];
233
+ case 3:
234
+ changed = _a.sent();
235
+ expect(changed).toHaveLength(1);
236
+ expect(changed[0]).toContain('no compile manifest');
237
+ return [2 /*return*/];
238
+ }
239
+ });
240
+ }); });
241
+ it('hashes a macro core that lives inside the project', function () { return __awaiter(void 0, void 0, void 0, function () {
242
+ var previousCorePath, folders;
243
+ return __generator(this, function (_a) {
244
+ switch (_a.label) {
245
+ case 0:
246
+ previousCorePath = process.sasjsConstants.macroCorePath;
247
+ process.sasjsConstants.macroCorePath = folderPath;
248
+ return [4 /*yield*/, (0, internal_1.getManifestFolders)({
249
+ name: 'core-in-project'
250
+ })];
251
+ case 1:
252
+ folders = _a.sent();
253
+ expect(folders).toContain(folderPath);
254
+ process.sasjsConstants.macroCorePath = previousCorePath;
255
+ return [2 /*return*/];
256
+ }
257
+ });
258
+ }); });
259
+ it('hashes the sync folder when the project syncs one', function () { return __awaiter(void 0, void 0, void 0, function () {
260
+ var previousConfig, folders;
261
+ return __generator(this, function (_a) {
262
+ switch (_a.label) {
263
+ case 0:
264
+ previousConfig = process.sasjsConfig;
265
+ process.sasjsConfig = __assign(__assign({}, (previousConfig || {})), { syncFolder: folderPath });
266
+ return [4 /*yield*/, (0, internal_1.getManifestFolders)({
267
+ name: 'sync-folder'
268
+ })];
269
+ case 1:
270
+ folders = _a.sent();
271
+ expect(folders.map(function (folder) { return path_1.default.resolve(folder); })).toContain(path_1.default.resolve(folderPath));
272
+ process.sasjsConfig = previousConfig;
273
+ return [2 /*return*/];
274
+ }
275
+ });
276
+ }); });
277
+ it('hashes the web source folder when the target streams the web', function () { return __awaiter(void 0, void 0, void 0, function () {
278
+ var folders;
279
+ return __generator(this, function (_a) {
280
+ switch (_a.label) {
281
+ case 0: return [4 /*yield*/, (0, internal_1.getManifestFolders)({
282
+ name: 'stream-web',
283
+ streamConfig: {
284
+ streamWeb: true,
285
+ streamWebFolder: 'web',
286
+ webSourcePath: folderPath,
287
+ streamServiceName: 'index'
288
+ }
289
+ })];
290
+ case 1:
291
+ folders = _a.sent();
292
+ expect(folders.map(function (folder) { return path_1.default.resolve(folder); })).toContain(path_1.default.resolve(folderPath));
293
+ return [2 /*return*/];
294
+ }
295
+ });
296
+ }); });
297
+ it('skips a file that cannot be read instead of failing the check', function () { return __awaiter(void 0, void 0, void 0, function () {
298
+ return __generator(this, function (_a) {
299
+ switch (_a.label) {
300
+ case 0: return [4 /*yield*/, (0, utils_1.createFile)(path_1.default.join(folderPath, 'service.sas'), '%put hello;')];
301
+ case 1:
302
+ _a.sent();
303
+ return [4 /*yield*/, (0, internal_1.writeCompileManifest)([folderPath])
304
+ // a broken link is listed but cannot be read: neither the write nor the
305
+ // check may throw over it
306
+ ];
307
+ case 2:
308
+ _a.sent();
309
+ // a broken link is listed but cannot be read: neither the write nor the
310
+ // check may throw over it
311
+ return [4 /*yield*/, (0, promises_1.symlink)(path_1.default.join(folderPath, 'no-such-target.sas'), path_1.default.join(folderPath, 'broken.sas'))];
312
+ case 3:
313
+ // a broken link is listed but cannot be read: neither the write nor the
314
+ // check may throw over it
315
+ _a.sent();
316
+ return [4 /*yield*/, expect((0, internal_1.writeCompileManifest)([folderPath])).resolves.toBeUndefined()];
317
+ case 4:
318
+ _a.sent();
319
+ return [4 /*yield*/, expect((0, internal_1.getChangedFiles)([folderPath])).resolves.toBeDefined()];
320
+ case 5:
321
+ _a.sent();
322
+ return [2 /*return*/];
323
+ }
324
+ });
325
+ }); });
326
+ it('does not fail the compile when the manifest cannot be written', function () { return __awaiter(void 0, void 0, void 0, function () {
327
+ var previous;
328
+ return __generator(this, function (_a) {
329
+ switch (_a.label) {
330
+ case 0:
331
+ previous = process.sasjsConstants.buildDestinationFolder;
332
+ // a file used as if it were a directory: the manifest write cannot succeed
333
+ process.sasjsConstants.buildDestinationFolder = path_1.default.join(__filename, 'no-such-folder');
334
+ return [4 /*yield*/, expect((0, internal_1.writeCompileManifest)([folderPath])).resolves.toBeUndefined()];
335
+ case 1:
336
+ _a.sent();
337
+ process.sasjsConstants.buildDestinationFolder = previous;
338
+ return [2 /*return*/];
339
+ }
340
+ });
341
+ }); });
342
+ it('treats a manifest that is not an object as unreadable', function () { return __awaiter(void 0, void 0, void 0, function () {
343
+ var changed;
344
+ return __generator(this, function (_a) {
345
+ switch (_a.label) {
346
+ case 0: return [4 /*yield*/, (0, internal_1.writeCompileManifest)([folderPath])];
347
+ case 1:
348
+ _a.sent();
349
+ return [4 /*yield*/, (0, utils_1.createFile)((0, internal_1.getManifestPath)(), '42')];
350
+ case 2:
351
+ _a.sent();
352
+ return [4 /*yield*/, (0, internal_1.getChangedFiles)([folderPath])];
353
+ case 3:
354
+ changed = _a.sent();
355
+ expect(changed[0]).toContain('no compile manifest');
356
+ return [2 /*return*/];
357
+ }
358
+ });
359
+ }); });
360
+ it('leaves out a configured folder that does not exist', function () { return __awaiter(void 0, void 0, void 0, function () {
361
+ var previousConfig, missing, folders;
362
+ return __generator(this, function (_a) {
363
+ switch (_a.label) {
364
+ case 0:
365
+ previousConfig = process.sasjsConfig;
366
+ missing = path_1.default.join(folderPath, 'not-created');
367
+ process.sasjsConfig = __assign(__assign({}, (previousConfig || {})), { syncFolder: missing });
368
+ return [4 /*yield*/, (0, internal_1.getManifestFolders)({
369
+ name: 'missing-sync-folder'
370
+ })];
371
+ case 1:
372
+ folders = _a.sent();
373
+ expect(folders.map(function (folder) { return path_1.default.resolve(folder); })).not.toContain(path_1.default.resolve(missing));
374
+ process.sasjsConfig = previousConfig;
375
+ return [2 /*return*/];
376
+ }
377
+ });
378
+ }); });
379
+ it('treats a missing manifest as a project that has not been compiled', function () { return __awaiter(void 0, void 0, void 0, function () {
380
+ var manifestPath, changed;
381
+ return __generator(this, function (_a) {
382
+ switch (_a.label) {
383
+ case 0:
384
+ manifestPath = (0, internal_1.getManifestPath)();
385
+ return [4 /*yield*/, (0, utils_1.fileExists)(manifestPath)];
386
+ case 1:
387
+ if (!_a.sent()) return [3 /*break*/, 3];
388
+ return [4 /*yield*/, (0, utils_1.deleteFile)(manifestPath)];
389
+ case 2:
390
+ _a.sent();
391
+ _a.label = 3;
392
+ case 3: return [4 /*yield*/, (0, internal_1.getChangedFiles)([folderPath])];
393
+ case 4:
394
+ changed = _a.sent();
395
+ expect(changed).toHaveLength(1);
396
+ expect(changed[0]).toContain('no compile manifest');
397
+ return [2 /*return*/];
398
+ }
399
+ });
400
+ }); });
401
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ var __values = (this && this.__values) || function(o) {
39
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
40
+ if (m) return m.call(o);
41
+ if (o && typeof o.length === "number") return {
42
+ next: function () {
43
+ if (o && i >= o.length) o = void 0;
44
+ return { value: o && o[i++], done: !o };
45
+ }
46
+ };
47
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
48
+ };
49
+ var __importDefault = (this && this.__importDefault) || function (mod) {
50
+ return (mod && mod.__esModule) ? mod : { "default": mod };
51
+ };
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ var path_1 = __importDefault(require("path"));
54
+ var utils_1 = require("@sasjs/utils");
55
+ var utils_2 = require("@sasjs/utils");
56
+ var test_1 = require("../../../utils/test");
57
+ var utils_3 = require("../../../utils");
58
+ var internal_1 = require("../internal");
59
+ var jsService = "/**\n @file getdata.js\n @brief returns rows for a dropdown\n**/\n\nconst nodePath = require('path')\n\nfunction rows() {\n return [{ LIBDS: 'SASControlTable' }]\n}\n";
60
+ var buildTarget = function (serverType, name) {
61
+ return ({
62
+ name: name,
63
+ appLoc: '/Public/app',
64
+ serverType: serverType,
65
+ serviceConfig: {},
66
+ jobConfig: {},
67
+ buildConfig: {}
68
+ });
69
+ };
70
+ describe('pass-through files', function () {
71
+ beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
72
+ return __generator(this, function (_a) {
73
+ switch (_a.label) {
74
+ case 0: return [4 /*yield*/, (0, utils_3.setConstants)(false)];
75
+ case 1:
76
+ _a.sent();
77
+ return [2 /*return*/];
78
+ }
79
+ });
80
+ }); });
81
+ describe('shouldPassThrough', function () {
82
+ it('passes a .js file through', function () {
83
+ expect((0, internal_1.shouldPassThrough)('getdata.js')).toBe(true);
84
+ });
85
+ it('passes a file with no extension through', function () {
86
+ expect((0, internal_1.shouldPassThrough)('payload')).toBe(true);
87
+ });
88
+ it('does not pass a .sas file through', function () {
89
+ expect((0, internal_1.shouldPassThrough)('getdata.sas')).toBe(false);
90
+ });
91
+ });
92
+ describe('compileFile', function () {
93
+ var e_1, _a;
94
+ var folderPath;
95
+ var filePath;
96
+ beforeEach(function () { return __awaiter(void 0, void 0, void 0, function () {
97
+ return __generator(this, function (_a) {
98
+ switch (_a.label) {
99
+ case 0:
100
+ folderPath = path_1.default.join(__dirname, "cli-tests-pass-through-".concat((0, test_1.generateUniqueTimestamp)()));
101
+ return [4 /*yield*/, (0, utils_2.createFolder)(folderPath)];
102
+ case 1:
103
+ _a.sent();
104
+ filePath = path_1.default.join(folderPath, 'getdata.js');
105
+ return [4 /*yield*/, (0, utils_2.createFile)(filePath, jsService)];
106
+ case 2:
107
+ _a.sent();
108
+ return [2 /*return*/];
109
+ }
110
+ });
111
+ }); });
112
+ afterEach(function () { return __awaiter(void 0, void 0, void 0, function () {
113
+ return __generator(this, function (_a) {
114
+ switch (_a.label) {
115
+ case 0: return [4 /*yield*/, (0, utils_2.deleteFolder)(folderPath)];
116
+ case 1:
117
+ _a.sent();
118
+ return [2 /*return*/];
119
+ }
120
+ });
121
+ }); });
122
+ var _loop_1 = function (serverType) {
123
+ it("leaves the file untouched on ".concat(serverType), function () { return __awaiter(void 0, void 0, void 0, function () {
124
+ var target;
125
+ return __generator(this, function (_a) {
126
+ switch (_a.label) {
127
+ case 0:
128
+ target = buildTarget(serverType, 'pass-through-test');
129
+ return [4 /*yield*/, (0, internal_1.compileFile)(target, filePath, [], [], undefined, (0, internal_1.getCompileTree)(target), 'service', folderPath)];
130
+ case 1:
131
+ _a.sent();
132
+ return [4 /*yield*/, expect((0, utils_2.readFile)(filePath)).resolves.toEqual(jsService)];
133
+ case 2:
134
+ _a.sent();
135
+ return [2 /*return*/];
136
+ }
137
+ });
138
+ }); });
139
+ };
140
+ try {
141
+ // The same project must produce the same pack whatever the target: a file
142
+ // that is not SAS is shipped as written, not reinterpreted per server type.
143
+ for (var _b = __values([
144
+ utils_1.ServerType.Sasjs,
145
+ utils_1.ServerType.SasViya,
146
+ utils_1.ServerType.Sas9
147
+ ]), _c = _b.next(); !_c.done; _c = _b.next()) {
148
+ var serverType = _c.value;
149
+ _loop_1(serverType);
150
+ }
151
+ }
152
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
153
+ finally {
154
+ try {
155
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
156
+ }
157
+ finally { if (e_1) throw e_1.error; }
158
+ }
159
+ });
160
+ });
@@ -81,6 +81,7 @@ var test_1 = require("../../../utils/test");
81
81
  var utilsModule = __importStar(require("../../../utils/utils"));
82
82
  var types_1 = require("../../../types");
83
83
  var build_1 = require("../../build/build");
84
+ var compile_1 = require("../../compile/compile");
84
85
  var deploy_1 = require("../deploy");
85
86
  var utils_2 = require("./utils");
86
87
  var config_1 = require("../../../utils/config");
@@ -158,32 +159,35 @@ describe('sasjs cbd with server type SASJS', function () {
158
159
  return [4 /*yield*/, (0, config_1.findTargetInConfiguration)(target.name, types_1.TargetScope.Local)];
159
160
  case 4:
160
161
  customTarget = (_c.sent()).target;
161
- return [4 /*yield*/, expect((0, build_1.build)(customTarget)).toResolve()];
162
+ return [4 /*yield*/, (0, compile_1.compile)(customTarget)];
162
163
  case 5:
163
164
  _c.sent();
164
- return [4 /*yield*/, (0, deploy_1.deploy)(customTarget, true)];
165
+ return [4 /*yield*/, expect((0, build_1.build)(customTarget)).toResolve()];
165
166
  case 6:
167
+ _c.sent();
168
+ return [4 /*yield*/, (0, deploy_1.deploy)(customTarget, true)];
169
+ case 7:
166
170
  _c.sent();
167
171
  macroCorePath = process.sasjsConstants.macroCorePath;
168
172
  _b = utils_1.removeHeader;
169
173
  return [4 /*yield*/, (0, utils_1.readFile)("".concat(macroCorePath, "/base/mf_getuser.sas"))];
170
- case 7:
174
+ case 8:
171
175
  mf_getuser = _b.apply(void 0, [_c.sent()]);
172
176
  return [4 /*yield*/, (0, utils_1.readFile)("".concat(macroCorePath, "/base/mp_jsonout.sas"))];
173
- case 8:
177
+ case 9:
174
178
  mp_jsonout = _c.sent();
175
179
  return [4 /*yield*/, (0, utils_1.readFile)("".concat(macroCorePath, "/server/ms_webout.sas"))];
176
- case 9:
180
+ case 10:
177
181
  ms_webout = _c.sent();
178
182
  webout = "%macro webout(action,ds,dslabel=,fmt=,missing=NULL,showmeta=NO,maxobs=MAX);\n %ms_webout(&action,ds=&ds,dslabel=&dslabel,fmt=&fmt\n ,missing=&missing\n ,showmeta=&showmeta\n ,maxobs=&maxobs\n )\n%mend;\n";
179
183
  mocksPath = path_1.default.join(__dirname, appName, 'sasjs', 'mocks');
180
184
  appinitJSPath = path_1.default.join(mocksPath, 'services', 'common', 'appinit.js');
181
185
  getdataJSPath = path_1.default.join(mocksPath, 'services', 'common', 'getdata.js');
182
186
  return [4 /*yield*/, (0, utils_1.readFile)(appinitJSPath)];
183
- case 10:
187
+ case 11:
184
188
  appinitJSContents = _c.sent();
185
189
  return [4 /*yield*/, (0, utils_1.readFile)(getdataJSPath)];
186
- case 11:
190
+ case 12:
187
191
  getdataJSContents = _c.sent();
188
192
  depsInserts = "\n\n* Service Variables start;\n\n\n* Service Variables end;\n* SAS Macros start;\n\n\n\n* SAS Macros end;\n* SAS Includes start;\n\n* SAS Includes end;\n* Binary Files start;\n\n* Binary Files end;\n\n\n* Service start;\n";
189
193
  appinit = "/**\n @file appinit.sas\n @brief Initialisation service - runs on app startup\n @details This is always the first service called when the app is opened.\n\n <h4> SAS Macros </h4>\n\n**/\n\nproc sql;\ncreate table areas as select distinct area\n from mydb.springs;\n\n%webout(OPEN)\n%webout(OBJ,areas)\n%webout(CLOSE)\n\n";
@@ -113,6 +113,15 @@ function printHelpText() {
113
113
  "It will also perform ".concat(chalk_1.default.greenBright('compile'), " command if services are not compiled.")
114
114
  ]
115
115
  },
116
+ {
117
+ name: 'builddeploy',
118
+ title: 'builddeploy <targetName>',
119
+ description: [
120
+ "builds the project and deploys the result to the target's server.",
121
+ "Unlike ".concat(chalk_1.default.greenBright('compilebuilddeploy'), " it does not recompile first - it ships the compiled services already in the build folder, and compiles only when that folder is missing."),
122
+ "Use ".concat(chalk_1.default.cyanBright('sasjs bd'), " as a shorthand.")
123
+ ]
124
+ },
116
125
  {
117
126
  name: 'compilebuild',
118
127
  title: 'compilebuild <targetName>',
@@ -344,6 +353,7 @@ function printHelpText() {
344
353
  ];
345
354
  aliases = [
346
355
  { name: 'build', aliases: ['b'] },
356
+ { name: 'builddeploy', aliases: ['bd'] },
347
357
  { name: 'compile', aliases: ['c'] },
348
358
  { name: 'compilebuild', aliases: ['cb'] },
349
359
  { name: 'compilebuilddeploy', aliases: ['cbd'] },
@@ -353,6 +363,7 @@ function printHelpText() {
353
363
  { name: 'help', aliases: ['h'] },
354
364
  { name: 'request', aliases: ['rq'] },
355
365
  { name: 'run', aliases: ['r'] },
366
+ { name: 'test', aliases: ['t'] },
356
367
  { name: 'version', aliases: ['v', '-v', '--version'] },
357
368
  { name: 'web', aliases: ['w'] }
358
369
  ];
@@ -117,6 +117,18 @@ describe('TestCommand', function () {
117
117
  expect(command.name).toEqual('test');
118
118
  expect(command.subCommand).toEqual('');
119
119
  });
120
+ it('should parse the t shorthand', function () {
121
+ var args = __spreadArray(__spreadArray([], __read(defaultArgs), false), ['t'], false);
122
+ var command = new testCommand_1.TestCommand(args);
123
+ expect(command.name).toEqual('test');
124
+ expect(command.subCommand).toEqual('');
125
+ });
126
+ it('should accept filtering strings after the t shorthand', function () {
127
+ var args = __spreadArray(__spreadArray([], __read(defaultArgs), false), ['t', 'pattern-1', '-t', 'testTarget'], false);
128
+ var command = new testCommand_1.TestCommand(args);
129
+ expect(command.name).toEqual('test');
130
+ expect(command.parsed.filteringString).toEqual(['pattern-1']);
131
+ });
120
132
  it('should parse a sasjs test command with all arguments', function () { return __awaiter(void 0, void 0, void 0, function () {
121
133
  var args, command, targetInfo;
122
134
  return __generator(this, function (_a) {