@sasjs/cli 6.28.0 → 6.30.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.
- package/build/commands/build/internal/mockSite/assets/sw.js +57 -4
- package/build/commands/build/internal/mockSite/mockSite.js +7 -6
- package/build/commands/build/internal/mockSite/spec/mockSite.spec.js +1 -0
- package/build/commands/build/internal/mockSite/spec/sw.spec.js +279 -0
- package/build/commands/create/spec/create.spec.js +22 -18
- package/build/commands/deploy/spec/cbd.spec.js +149 -65
- package/build/commands/shared/createLintConfigFile.js +24 -2
- package/build/commands/shared/spec/createLintConfigFile.spec.d.ts +1 -0
- package/build/commands/shared/spec/createLintConfigFile.spec.js +132 -0
- package/build/utils/test.d.ts +12 -0
- package/build/utils/test.js +71 -4
- package/build/utils/utils.d.ts +8 -0
- package/build/utils/utils.js +16 -4
- package/package.json +2 -2
- package/build/commands/create/spec/angularAppFiles.d.ts +0 -2
- package/build/commands/create/spec/angularAppFiles.js +0 -119
- package/build/commands/create/spec/minimalAppFiles.d.ts +0 -2
- package/build/commands/create/spec/minimalAppFiles.js +0 -44
- package/build/commands/create/spec/reactAppFiles.d.ts +0 -2
- package/build/commands/create/spec/reactAppFiles.js +0 -93
|
@@ -68,10 +68,38 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
68
68
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
72
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
73
|
+
if (!m) return o;
|
|
74
|
+
var i = m.call(o), r, ar = [], e;
|
|
75
|
+
try {
|
|
76
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
77
|
+
}
|
|
78
|
+
catch (error) { e = { error: error }; }
|
|
79
|
+
finally {
|
|
80
|
+
try {
|
|
81
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
82
|
+
}
|
|
83
|
+
finally { if (e) throw e.error; }
|
|
84
|
+
}
|
|
85
|
+
return ar;
|
|
86
|
+
};
|
|
87
|
+
var __values = (this && this.__values) || function(o) {
|
|
88
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
89
|
+
if (m) return m.call(o);
|
|
90
|
+
if (o && typeof o.length === "number") return {
|
|
91
|
+
next: function () {
|
|
92
|
+
if (o && i >= o.length) o = void 0;
|
|
93
|
+
return { value: o && o[i++], done: !o };
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
97
|
+
};
|
|
71
98
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
72
99
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
73
100
|
};
|
|
74
101
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
102
|
+
var fs_1 = __importDefault(require("fs"));
|
|
75
103
|
var path_1 = __importDefault(require("path"));
|
|
76
104
|
var node_1 = require("@sasjs/adapter/node");
|
|
77
105
|
var js_base64_1 = require("js-base64");
|
|
@@ -85,6 +113,13 @@ var compile_1 = require("../../compile/compile");
|
|
|
85
113
|
var deploy_1 = require("../deploy");
|
|
86
114
|
var utils_2 = require("./utils");
|
|
87
115
|
var config_1 = require("../../../utils/config");
|
|
116
|
+
/** Every file under a folder, recursively, as absolute paths. */
|
|
117
|
+
var listFiles = function (folderPath) {
|
|
118
|
+
return fs_1.default.readdirSync(folderPath, { withFileTypes: true }).flatMap(function (entry) {
|
|
119
|
+
var entryPath = path_1.default.join(folderPath, entry.name);
|
|
120
|
+
return entry.isDirectory() ? listFiles(entryPath) : [entryPath];
|
|
121
|
+
});
|
|
122
|
+
};
|
|
88
123
|
describe('sasjs cbd with server type SASJS', function () {
|
|
89
124
|
var target;
|
|
90
125
|
var appName;
|
|
@@ -115,9 +150,10 @@ describe('sasjs cbd with server type SASJS', function () {
|
|
|
115
150
|
});
|
|
116
151
|
}); });
|
|
117
152
|
it("should deploy compile and build to sasjs/server", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
118
|
-
var deployMock, _a, customTarget, macroCorePath, mf_getuser, _b, mp_jsonout, ms_webout, webout,
|
|
119
|
-
|
|
120
|
-
|
|
153
|
+
var deployMock, _a, customTarget, macroCorePath, mf_getuser, _b, mp_jsonout, ms_webout, webout, depsInserts, getCode, _c, payload, deployed, indexMembers, projectRoot, mocksRoot, mockFiles, mockFiles_1, mockFiles_1_1, filePath, relative, _d, _e, _f, e_1_1, serviceFiles, serviceFiles_1, serviceFiles_1_1, filePath, name_1, contents, member, e_2_1;
|
|
154
|
+
var e_1, _g, _h, e_2, _j;
|
|
155
|
+
return __generator(this, function (_k) {
|
|
156
|
+
switch (_k.label) {
|
|
121
157
|
case 0:
|
|
122
158
|
jest.spyOn(fileModule, 'fileExists').mockImplementation(function (filePath) {
|
|
123
159
|
if (filePath.endsWith('.zip'))
|
|
@@ -141,7 +177,7 @@ describe('sasjs cbd with server type SASJS', function () {
|
|
|
141
177
|
}
|
|
142
178
|
})];
|
|
143
179
|
case 1:
|
|
144
|
-
|
|
180
|
+
_k.sent();
|
|
145
181
|
return [4 /*yield*/, (0, utils_2.updateLocalTarget)(target.name, {
|
|
146
182
|
jobConfig: undefined,
|
|
147
183
|
serviceConfig: undefined,
|
|
@@ -151,91 +187,139 @@ describe('sasjs cbd with server type SASJS', function () {
|
|
|
151
187
|
}
|
|
152
188
|
})];
|
|
153
189
|
case 2:
|
|
154
|
-
|
|
190
|
+
_k.sent();
|
|
155
191
|
_a = process;
|
|
156
192
|
return [4 /*yield*/, (0, config_1.getLocalConfig)()];
|
|
157
193
|
case 3:
|
|
158
|
-
_a.sasjsConfig =
|
|
194
|
+
_a.sasjsConfig = _k.sent();
|
|
159
195
|
return [4 /*yield*/, (0, config_1.findTargetInConfiguration)(target.name, types_1.TargetScope.Local)];
|
|
160
196
|
case 4:
|
|
161
|
-
customTarget = (
|
|
197
|
+
customTarget = (_k.sent()).target;
|
|
162
198
|
return [4 /*yield*/, (0, compile_1.compile)(customTarget)];
|
|
163
199
|
case 5:
|
|
164
|
-
|
|
200
|
+
_k.sent();
|
|
165
201
|
return [4 /*yield*/, expect((0, build_1.build)(customTarget)).toResolve()];
|
|
166
202
|
case 6:
|
|
167
|
-
|
|
203
|
+
_k.sent();
|
|
168
204
|
return [4 /*yield*/, (0, deploy_1.deploy)(customTarget, true)];
|
|
169
205
|
case 7:
|
|
170
|
-
|
|
206
|
+
_k.sent();
|
|
171
207
|
macroCorePath = process.sasjsConstants.macroCorePath;
|
|
172
208
|
_b = utils_1.removeHeader;
|
|
173
209
|
return [4 /*yield*/, (0, utils_1.readFile)("".concat(macroCorePath, "/base/mf_getuser.sas"))];
|
|
174
210
|
case 8:
|
|
175
|
-
mf_getuser = _b.apply(void 0, [
|
|
211
|
+
mf_getuser = _b.apply(void 0, [_k.sent()]);
|
|
176
212
|
return [4 /*yield*/, (0, utils_1.readFile)("".concat(macroCorePath, "/base/mp_jsonout.sas"))];
|
|
177
213
|
case 9:
|
|
178
|
-
mp_jsonout =
|
|
214
|
+
mp_jsonout = _k.sent();
|
|
179
215
|
return [4 /*yield*/, (0, utils_1.readFile)("".concat(macroCorePath, "/server/ms_webout.sas"))];
|
|
180
216
|
case 10:
|
|
181
|
-
ms_webout =
|
|
217
|
+
ms_webout = _k.sent();
|
|
182
218
|
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";
|
|
183
|
-
mocksPath = path_1.default.join(__dirname, appName, 'sasjs', 'mocks');
|
|
184
|
-
appinitJSPath = path_1.default.join(mocksPath, 'services', 'common', 'appinit.js');
|
|
185
|
-
getdataJSPath = path_1.default.join(mocksPath, 'services', 'common', 'getdata.js');
|
|
186
|
-
return [4 /*yield*/, (0, utils_1.readFile)(appinitJSPath)];
|
|
187
|
-
case 11:
|
|
188
|
-
appinitJSContents = _c.sent();
|
|
189
|
-
return [4 /*yield*/, (0, utils_1.readFile)(getdataJSPath)];
|
|
190
|
-
case 12:
|
|
191
|
-
getdataJSContents = _c.sent();
|
|
192
219
|
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";
|
|
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";
|
|
194
|
-
getdata = "/**\n @file getdata.sas\n @brief Get Data 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\n%webout(FETCH)\n\nproc sql;\ncreate table springs as select * from mydb.springs\n where area in (select area from work.areas);\n\n%webout(OPEN)\n%webout(OBJ,springs)\n%webout(CLOSE)\n\n";
|
|
195
220
|
getCode = function (file) {
|
|
196
221
|
return "".concat(mf_getuser).concat(mp_jsonout).concat(ms_webout).concat(webout, "/* 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.);").concat(depsInserts).concat(file, "* Service end;");
|
|
197
222
|
};
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
223
|
+
// The payload is derived from the project the command created rather than
|
|
224
|
+
// listed by hand. A hand-kept list turned this spec red when the seed app
|
|
225
|
+
// gained a data file beside its services - a file the CLI deploys correctly
|
|
226
|
+
// - so the reference here is the project itself. What stays explicit is the
|
|
227
|
+
// CLI's own contribution: the wrapper, built by `getCode` above.
|
|
228
|
+
expect(deployMock).toHaveBeenCalledTimes(1);
|
|
229
|
+
_c = __read(deployMock.mock.calls[0], 1), payload = _c[0];
|
|
230
|
+
expect(payload.appLoc).toEqual(target.appLoc);
|
|
231
|
+
deployed = new Map();
|
|
232
|
+
indexMembers = function (members, prefix) {
|
|
233
|
+
if (members === void 0) { members = []; }
|
|
234
|
+
if (prefix === void 0) { prefix = ''; }
|
|
235
|
+
return members.forEach(function (member) {
|
|
236
|
+
var memberPath = prefix ? "".concat(prefix, "/").concat(member.name) : member.name;
|
|
237
|
+
if (member.type === 'folder')
|
|
238
|
+
indexMembers(member.members, memberPath);
|
|
239
|
+
else
|
|
240
|
+
deployed.set(memberPath, member);
|
|
241
|
+
});
|
|
242
|
+
};
|
|
243
|
+
indexMembers(payload.fileTree.members);
|
|
244
|
+
projectRoot = path_1.default.join(__dirname, appName);
|
|
245
|
+
mocksRoot = path_1.default.join(projectRoot, 'sasjs', 'mocks');
|
|
246
|
+
mockFiles = listFiles(mocksRoot);
|
|
247
|
+
_k.label = 11;
|
|
248
|
+
case 11:
|
|
249
|
+
_k.trys.push([11, 16, 17, 18]);
|
|
250
|
+
mockFiles_1 = __values(mockFiles), mockFiles_1_1 = mockFiles_1.next();
|
|
251
|
+
_k.label = 12;
|
|
252
|
+
case 12:
|
|
253
|
+
if (!!mockFiles_1_1.done) return [3 /*break*/, 15];
|
|
254
|
+
filePath = mockFiles_1_1.value;
|
|
255
|
+
relative = path_1.default
|
|
256
|
+
.relative(mocksRoot, filePath)
|
|
257
|
+
.split(path_1.default.sep)
|
|
258
|
+
.join('/');
|
|
259
|
+
_e = (_d = expect(deployed.get(relative))).toEqual;
|
|
260
|
+
_h = {
|
|
261
|
+
name: path_1.default.basename(filePath),
|
|
262
|
+
type: 'file',
|
|
263
|
+
encoding: 'base64'
|
|
264
|
+
};
|
|
265
|
+
_f = js_base64_1.encode;
|
|
266
|
+
return [4 /*yield*/, (0, utils_1.readFile)(filePath)];
|
|
267
|
+
case 13:
|
|
268
|
+
_e.apply(_d, [(_h.code = _f.apply(void 0, [_k.sent()]),
|
|
269
|
+
_h)]);
|
|
270
|
+
_k.label = 14;
|
|
271
|
+
case 14:
|
|
272
|
+
mockFiles_1_1 = mockFiles_1.next();
|
|
273
|
+
return [3 /*break*/, 12];
|
|
274
|
+
case 15: return [3 /*break*/, 18];
|
|
275
|
+
case 16:
|
|
276
|
+
e_1_1 = _k.sent();
|
|
277
|
+
e_1 = { error: e_1_1 };
|
|
278
|
+
return [3 /*break*/, 18];
|
|
279
|
+
case 17:
|
|
280
|
+
try {
|
|
281
|
+
if (mockFiles_1_1 && !mockFiles_1_1.done && (_g = mockFiles_1.return)) _g.call(mockFiles_1);
|
|
282
|
+
}
|
|
283
|
+
finally { if (e_1) throw e_1.error; }
|
|
284
|
+
return [7 /*endfinally*/];
|
|
285
|
+
case 18:
|
|
286
|
+
serviceFiles = listFiles(path_1.default.join(projectRoot, 'sasjs', 'services', 'common')).filter(function (filePath) { return filePath.endsWith('.sas'); });
|
|
287
|
+
_k.label = 19;
|
|
288
|
+
case 19:
|
|
289
|
+
_k.trys.push([19, 24, 25, 26]);
|
|
290
|
+
serviceFiles_1 = __values(serviceFiles), serviceFiles_1_1 = serviceFiles_1.next();
|
|
291
|
+
_k.label = 20;
|
|
292
|
+
case 20:
|
|
293
|
+
if (!!serviceFiles_1_1.done) return [3 /*break*/, 23];
|
|
294
|
+
filePath = serviceFiles_1_1.value;
|
|
295
|
+
name_1 = path_1.default.basename(filePath, '.sas');
|
|
296
|
+
return [4 /*yield*/, (0, utils_1.readFile)(filePath)];
|
|
297
|
+
case 21:
|
|
298
|
+
contents = _k.sent();
|
|
299
|
+
member = deployed.get("services/common/".concat(name_1));
|
|
300
|
+
expect(member).toMatchObject({ name: name_1, type: 'service' });
|
|
301
|
+
// the compiled service ends its text with a blank line before the end
|
|
302
|
+
// marker, whatever trailing whitespace the source file carries
|
|
303
|
+
expect(member.code).toEqual(getCode((0, utils_1.removeHeader)(contents).trimEnd() + '\n\n'));
|
|
304
|
+
_k.label = 22;
|
|
305
|
+
case 22:
|
|
306
|
+
serviceFiles_1_1 = serviceFiles_1.next();
|
|
307
|
+
return [3 /*break*/, 20];
|
|
308
|
+
case 23: return [3 /*break*/, 26];
|
|
309
|
+
case 24:
|
|
310
|
+
e_2_1 = _k.sent();
|
|
311
|
+
e_2 = { error: e_2_1 };
|
|
312
|
+
return [3 /*break*/, 26];
|
|
313
|
+
case 25:
|
|
314
|
+
try {
|
|
315
|
+
if (serviceFiles_1_1 && !serviceFiles_1_1.done && (_j = serviceFiles_1.return)) _j.call(serviceFiles_1);
|
|
316
|
+
}
|
|
317
|
+
finally { if (e_2) throw e_2.error; }
|
|
318
|
+
return [7 /*endfinally*/];
|
|
319
|
+
case 26:
|
|
320
|
+
// and nothing else: a member the CLI gains or loses shows as a difference
|
|
321
|
+
// in the count, rather than silently passing inside a hand-written tree
|
|
322
|
+
expect(deployed.size).toEqual(mockFiles.length + serviceFiles.length);
|
|
239
323
|
return [2 /*return*/];
|
|
240
324
|
}
|
|
241
325
|
});
|
|
@@ -1,4 +1,15 @@
|
|
|
1
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
|
+
};
|
|
2
13
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
14
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
15
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -43,18 +54,29 @@ exports.createLintConfigFile = void 0;
|
|
|
43
54
|
var path_1 = __importDefault(require("path"));
|
|
44
55
|
var lint_1 = require("@sasjs/lint");
|
|
45
56
|
var utils_1 = require("@sasjs/utils");
|
|
57
|
+
/**
|
|
58
|
+
* Where the settings of a `.sasjslint` are documented.
|
|
59
|
+
*
|
|
60
|
+
* The file is read as strict JSON, so it cannot carry comments - the same
|
|
61
|
+
* problem `sasjsconfig.json` answers with `$schema`, and the same address
|
|
62
|
+
* pattern (`sasjs init` writes https://cli.sasjs.io/sasjsconfig-schema.json).
|
|
63
|
+
* An editor that understands JSON schemas then completes the settings and
|
|
64
|
+
* shows each one's description as it is typed.
|
|
65
|
+
*/
|
|
66
|
+
var lintSchemaUrl = 'https://cli.sasjs.io/sasjslint-schema.json';
|
|
46
67
|
/**
|
|
47
68
|
* Creates a SASjs Lint configuration file.
|
|
48
69
|
* Its name will be of the form '.sasjslint'
|
|
49
70
|
* @param {string} parentFolderName- the name of the project folder.
|
|
50
71
|
*/
|
|
51
72
|
var createLintConfigFile = function (parentFolderName) { return __awaiter(void 0, void 0, void 0, function () {
|
|
52
|
-
var configDestinationPath;
|
|
73
|
+
var configDestinationPath, config;
|
|
53
74
|
return __generator(this, function (_a) {
|
|
54
75
|
switch (_a.label) {
|
|
55
76
|
case 0:
|
|
56
77
|
configDestinationPath = path_1.default.join(process.projectDir, parentFolderName, '.sasjslint');
|
|
57
|
-
|
|
78
|
+
config = __assign({ $schema: lintSchemaUrl }, lint_1.DefaultLintConfiguration);
|
|
79
|
+
return [4 /*yield*/, (0, utils_1.createFile)(configDestinationPath, JSON.stringify(config, null, 2))];
|
|
58
80
|
case 1:
|
|
59
81
|
_a.sent();
|
|
60
82
|
return [2 /*return*/];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
45
|
+
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);
|
|
46
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
47
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
48
|
+
function step(op) {
|
|
49
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
50
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
51
|
+
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;
|
|
52
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
53
|
+
switch (op[0]) {
|
|
54
|
+
case 0: case 1: t = op; break;
|
|
55
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
56
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
57
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
58
|
+
default:
|
|
59
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
60
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
61
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
62
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
63
|
+
if (t[2]) _.ops.pop();
|
|
64
|
+
_.trys.pop(); continue;
|
|
65
|
+
}
|
|
66
|
+
op = body.call(thisArg, _);
|
|
67
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
68
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
72
|
+
var t = {};
|
|
73
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
74
|
+
t[p] = s[p];
|
|
75
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
76
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
77
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
78
|
+
t[p[i]] = s[p[i]];
|
|
79
|
+
}
|
|
80
|
+
return t;
|
|
81
|
+
};
|
|
82
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
83
|
+
var promises_1 = require("fs/promises");
|
|
84
|
+
var os = __importStar(require("os"));
|
|
85
|
+
var path = __importStar(require("path"));
|
|
86
|
+
var lint_1 = require("@sasjs/lint");
|
|
87
|
+
var utils_1 = require("@sasjs/utils");
|
|
88
|
+
var createLintConfigFile_1 = require("../createLintConfigFile");
|
|
89
|
+
/**
|
|
90
|
+
* The file this writes is the first thing a new project has to edit, and the
|
|
91
|
+
* only place its settings are described: it is read as strict JSON, so it cannot
|
|
92
|
+
* carry comments, and `$schema` is what gives an editor the description of each
|
|
93
|
+
* setting where it is written.
|
|
94
|
+
*/
|
|
95
|
+
describe('createLintConfigFile', function () {
|
|
96
|
+
var originalProjectDir = process.projectDir;
|
|
97
|
+
var projectDir;
|
|
98
|
+
beforeEach(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
99
|
+
return __generator(this, function (_a) {
|
|
100
|
+
switch (_a.label) {
|
|
101
|
+
case 0:
|
|
102
|
+
projectDir = path.join(os.tmpdir(), "sasjs-lint-config-".concat(Date.now(), "-").concat(Math.random().toString(36).slice(2)));
|
|
103
|
+
return [4 /*yield*/, (0, utils_1.createFolder)(projectDir)];
|
|
104
|
+
case 1:
|
|
105
|
+
_a.sent();
|
|
106
|
+
process.projectDir = projectDir;
|
|
107
|
+
return [2 /*return*/];
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}); });
|
|
111
|
+
afterEach(function () {
|
|
112
|
+
process.projectDir = originalProjectDir;
|
|
113
|
+
});
|
|
114
|
+
it('writes every default setting, with the schema', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
115
|
+
var written, _a, _b, _schema, settings;
|
|
116
|
+
return __generator(this, function (_c) {
|
|
117
|
+
switch (_c.label) {
|
|
118
|
+
case 0: return [4 /*yield*/, (0, createLintConfigFile_1.createLintConfigFile)('.')];
|
|
119
|
+
case 1:
|
|
120
|
+
_c.sent();
|
|
121
|
+
_b = (_a = JSON).parse;
|
|
122
|
+
return [4 /*yield*/, (0, promises_1.readFile)(path.join(projectDir, '.sasjslint'), 'utf-8')];
|
|
123
|
+
case 2:
|
|
124
|
+
written = _b.apply(_a, [_c.sent()]);
|
|
125
|
+
expect(written.$schema).toEqual('https://cli.sasjs.io/sasjslint-schema.json');
|
|
126
|
+
_schema = written.$schema, settings = __rest(written, ["$schema"]);
|
|
127
|
+
expect(settings).toEqual(lint_1.DefaultLintConfiguration);
|
|
128
|
+
return [2 /*return*/];
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}); });
|
|
132
|
+
});
|
package/build/utils/test.d.ts
CHANGED
|
@@ -50,6 +50,18 @@ export declare const generateTestTarget: (targetName: string, appLoc: string, se
|
|
|
50
50
|
export declare const createTestGlobalTarget: (targetName: string, appLoc: string, serviceConfig?: ServiceConfig, serverType?: ServerType) => Promise<Target>;
|
|
51
51
|
export declare const verifyStep: (step?: "db" | "compile" | "build", buildFileName?: string, customFiles?: "custom" | "no") => Promise<void>;
|
|
52
52
|
export declare const mockProcessExit: () => jest.SpyInstance<never, [code?: string | number | null | undefined], any>;
|
|
53
|
+
/**
|
|
54
|
+
* The file tree of a seed app, read from the archive `sasjs create` downloads.
|
|
55
|
+
*
|
|
56
|
+
* A created project used to be compared against a hand-kept list of the files
|
|
57
|
+
* each template ships, so every seed release that added or removed one turned
|
|
58
|
+
* this suite red with no change to the CLI - twice in one afternoon, for
|
|
59
|
+
* `springs.json` and for the angular template's component specs. The template
|
|
60
|
+
* is what the command copies, so it is what the test compares against: the same
|
|
61
|
+
* repository, fetched the same way, with the copy's own normalisations applied
|
|
62
|
+
* where the command makes them.
|
|
63
|
+
*/
|
|
64
|
+
export declare const getTemplateFileTree: (repoUrl: string) => Promise<Folder>;
|
|
53
65
|
export declare const verifyFolder: (folder: Folder, parentFolderName?: string) => Promise<boolean>;
|
|
54
66
|
export declare const verifyPackageJsonContent: (parentFolderName?: string) => Promise<void>;
|
|
55
67
|
export declare const removeAllTargetsFromConfigs: () => Promise<void>;
|
package/build/utils/test.js
CHANGED
|
@@ -108,8 +108,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
108
108
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
109
109
|
};
|
|
110
110
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
111
|
-
exports.verifyGitNotPresent = exports.verifyCompiledJob = exports.verifyCompiledService = exports.verifyDotFilesNotGenerated = exports.verifyDotFiles = exports.verifyDocs = exports.updateConfig = exports.updateTarget = exports.removeAllTargetsFromConfigs = exports.verifyPackageJsonContent = exports.verifyFolder = exports.mockProcessExit = exports.verifyStep = exports.createTestGlobalTarget = exports.generateTestTarget = exports.removeTestServerFolder = exports.removeTestApp = exports.createTestMinimalApp = exports.createTestJobsApp = exports.createTestApp = exports.stubNpm = exports.npmCommands = exports.generateUniqueTimestamp = void 0;
|
|
111
|
+
exports.verifyGitNotPresent = exports.verifyCompiledJob = exports.verifyCompiledService = exports.verifyDotFilesNotGenerated = exports.verifyDotFiles = exports.verifyDocs = exports.updateConfig = exports.updateTarget = exports.removeAllTargetsFromConfigs = exports.verifyPackageJsonContent = exports.verifyFolder = exports.getTemplateFileTree = exports.mockProcessExit = exports.verifyStep = exports.createTestGlobalTarget = exports.generateTestTarget = exports.removeTestServerFolder = exports.removeTestApp = exports.createTestMinimalApp = exports.createTestJobsApp = exports.createTestApp = exports.stubNpm = exports.npmCommands = exports.generateUniqueTimestamp = void 0;
|
|
112
112
|
var fs_1 = __importDefault(require("fs"));
|
|
113
|
+
var os_1 = __importDefault(require("os"));
|
|
113
114
|
var path_1 = __importDefault(require("path"));
|
|
114
115
|
var dotenv_1 = __importDefault(require("dotenv"));
|
|
115
116
|
var utils_1 = require("@sasjs/utils");
|
|
@@ -122,6 +123,8 @@ var compiledFilesCustom1_1 = require("./fileStructures/compiledFilesCustom1");
|
|
|
122
123
|
var builtFiles_1 = require("./fileStructures/builtFiles");
|
|
123
124
|
var builtFilesCustom1_1 = require("./fileStructures/builtFilesCustom1");
|
|
124
125
|
var create_1 = require("../commands/create/create");
|
|
126
|
+
var utils_2 = require("./utils");
|
|
127
|
+
var zip_1 = require("./zip");
|
|
125
128
|
var setConstants_1 = require("./setConstants");
|
|
126
129
|
var shell = __importStar(require("./shell"));
|
|
127
130
|
/**
|
|
@@ -524,6 +527,68 @@ var verifyBuildJson = function (folders, buildJson, buildSas) {
|
|
|
524
527
|
});
|
|
525
528
|
return true;
|
|
526
529
|
};
|
|
530
|
+
/**
|
|
531
|
+
* The file tree of a seed app, read from the archive `sasjs create` downloads.
|
|
532
|
+
*
|
|
533
|
+
* A created project used to be compared against a hand-kept list of the files
|
|
534
|
+
* each template ships, so every seed release that added or removed one turned
|
|
535
|
+
* this suite red with no change to the CLI - twice in one afternoon, for
|
|
536
|
+
* `springs.json` and for the angular template's component specs. The template
|
|
537
|
+
* is what the command copies, so it is what the test compares against: the same
|
|
538
|
+
* repository, fetched the same way, with the copy's own normalisations applied
|
|
539
|
+
* where the command makes them.
|
|
540
|
+
*/
|
|
541
|
+
var getTemplateFileTree = function (repoUrl) { return __awaiter(void 0, void 0, void 0, function () {
|
|
542
|
+
var workspace, archive, main_1, root;
|
|
543
|
+
return __generator(this, function (_a) {
|
|
544
|
+
switch (_a.label) {
|
|
545
|
+
case 0:
|
|
546
|
+
if (!repoUrl) {
|
|
547
|
+
throw new Error("No seed app URL for that template - add it to seedAppUrls in src/utils/utils.ts");
|
|
548
|
+
}
|
|
549
|
+
workspace = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'sasjs-template-'));
|
|
550
|
+
_a.label = 1;
|
|
551
|
+
case 1:
|
|
552
|
+
_a.trys.push([1, , 3, 4]);
|
|
553
|
+
archive = path_1.default.join(workspace, 'main.zip');
|
|
554
|
+
main_1 = (0, utils_2.downloadFile)("".concat(repoUrl, "/archive/refs/heads/main.zip"), archive);
|
|
555
|
+
// the seed repos are on `main`, but the command falls back to `master` and
|
|
556
|
+
// the reference has to be taken from whatever it would have downloaded
|
|
557
|
+
if (main_1.code || main_1.stderr.includes('404')) {
|
|
558
|
+
(0, utils_2.downloadFile)("".concat(repoUrl, "/archive/refs/heads/master.zip"), archive);
|
|
559
|
+
}
|
|
560
|
+
return [4 /*yield*/, (0, zip_1.extractZip)(archive, workspace, true)];
|
|
561
|
+
case 2:
|
|
562
|
+
_a.sent();
|
|
563
|
+
root = fs_1.default
|
|
564
|
+
.readdirSync(workspace, { withFileTypes: true })
|
|
565
|
+
.find(function (entry) { return entry.isDirectory(); });
|
|
566
|
+
if (!root) {
|
|
567
|
+
throw new Error("Could not find the unzipped folder for ".concat(repoUrl));
|
|
568
|
+
}
|
|
569
|
+
return [2 /*return*/, toFileTree(path_1.default.join(workspace, root.name), root.name)];
|
|
570
|
+
case 3:
|
|
571
|
+
fs_1.default.rmSync(workspace, { recursive: true, force: true });
|
|
572
|
+
return [7 /*endfinally*/];
|
|
573
|
+
case 4: return [2 /*return*/];
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
}); };
|
|
577
|
+
exports.getTemplateFileTree = getTemplateFileTree;
|
|
578
|
+
var toFileTree = function (folderPath, folderName) {
|
|
579
|
+
var entries = fs_1.default.readdirSync(folderPath, { withFileTypes: true });
|
|
580
|
+
return {
|
|
581
|
+
folderName: folderName,
|
|
582
|
+
// `create` removes this once the docs have been fetched into the folder, so
|
|
583
|
+
// it is the one file the project is not expected to carry
|
|
584
|
+
files: entries
|
|
585
|
+
.filter(function (entry) { return entry.isFile() && entry.name !== '.gitmodules'; })
|
|
586
|
+
.map(function (entry) { return ({ fileName: entry.name }); }),
|
|
587
|
+
subFolders: entries
|
|
588
|
+
.filter(function (entry) { return entry.isDirectory(); })
|
|
589
|
+
.map(function (entry) { return toFileTree(path_1.default.join(folderPath, entry.name), entry.name); })
|
|
590
|
+
};
|
|
591
|
+
};
|
|
527
592
|
var verifyFolder = function (folder_1) {
|
|
528
593
|
var args_1 = [];
|
|
529
594
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
@@ -585,9 +650,11 @@ var verifyPackageJsonContent = function () {
|
|
|
585
650
|
case 2:
|
|
586
651
|
packageJsonContent = _a.sent();
|
|
587
652
|
packageJson = JSON.parse(packageJsonContent);
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
653
|
+
// Which map the seed app declares its SASjs dependency in is the seed's
|
|
654
|
+
// business - a web app carries @sasjs/core as a devDependency (it compiles
|
|
655
|
+
// the macros in) while the jobs template installs it as a dependency. What
|
|
656
|
+
// this asserts is that the template brings the macros with it at all.
|
|
657
|
+
expect(__assign(__assign({}, packageJson.devDependencies), packageJson.dependencies)).toEqual(expect.objectContaining({ '@sasjs/core': expect.anything() }));
|
|
591
658
|
return [2 /*return*/];
|
|
592
659
|
}
|
|
593
660
|
});
|
package/build/utils/utils.d.ts
CHANGED
|
@@ -4,6 +4,14 @@ import SASjs from '@sasjs/adapter/node';
|
|
|
4
4
|
import { LogJson } from '../types';
|
|
5
5
|
export declare function inExistingProject(folderPath: string): Promise<boolean>;
|
|
6
6
|
export declare function diff(a: any[], b: any[]): any[];
|
|
7
|
+
/**
|
|
8
|
+
* The seed apps `sasjs create` downloads, by template name.
|
|
9
|
+
*
|
|
10
|
+
* One map for the commands that fetch them and the specs that compare their
|
|
11
|
+
* output, so a template added here is covered by both rather than downloaded
|
|
12
|
+
* by one and unknown to the other.
|
|
13
|
+
*/
|
|
14
|
+
export declare const seedAppUrls: Record<string, string>;
|
|
7
15
|
export declare function createReactApp(folderPath: string): Promise<void>;
|
|
8
16
|
export declare function createAngularApp(folderPath: string): Promise<void>;
|
|
9
17
|
export declare function createMinimalApp(folderPath: string): Promise<void>;
|