@sasjs/cli 4.18.2 → 4.18.3
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.
|
@@ -69,13 +69,17 @@ var setConstants = function (isLocal, target, configuration) {
|
|
|
69
69
|
buildDestinationDocsFolder = path_1.default.join(buildDestinationFolder, 'docs');
|
|
70
70
|
macroCorePath = (_a = process.env.macroCorePath) !== null && _a !== void 0 ? _a : '';
|
|
71
71
|
if (!(macroCorePath === '')) return [3 /*break*/, 2];
|
|
72
|
-
return [4 /*yield*/, (0, utils_1.getNodeModulePath)('@sasjs/core')];
|
|
72
|
+
return [4 /*yield*/, (0, utils_1.getNodeModulePath)('@sasjs/core', process.projectDir)];
|
|
73
73
|
case 1:
|
|
74
|
-
// If no environment variable is set/populated then check for an installed
|
|
75
|
-
// @sasjs/core in locations known to node.
|
|
76
74
|
macroCorePath = _b.sent();
|
|
77
75
|
_b.label = 2;
|
|
78
76
|
case 2:
|
|
77
|
+
if (!(macroCorePath === '')) return [3 /*break*/, 4];
|
|
78
|
+
return [4 /*yield*/, (0, utils_1.getNodeModulePath)('@sasjs/core')];
|
|
79
|
+
case 3:
|
|
80
|
+
macroCorePath = _b.sent();
|
|
81
|
+
_b.label = 4;
|
|
82
|
+
case 4:
|
|
79
83
|
buildDestinationResultsFolder = (0, utils_2.getAbsolutePath)(buildResultsFolder, isLocal ? process.projectDir : homeDir);
|
|
80
84
|
buildDestinationResultsLogsFolder = path_1.default.join(buildDestinationResultsFolder, 'logs');
|
|
81
85
|
sas9CredentialsError = 'The following attributes were not found:' +
|
|
@@ -179,7 +179,7 @@ describe('setConstants', function () {
|
|
|
179
179
|
}
|
|
180
180
|
});
|
|
181
181
|
}); });
|
|
182
|
-
test('should
|
|
182
|
+
test('should look up @sasjs/core scoped to process.projectDir, then fall back unscoped, when environment variable macroCorePath is undefined', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
183
183
|
var getNodeModulePathSpy;
|
|
184
184
|
return __generator(this, function (_a) {
|
|
185
185
|
switch (_a.label) {
|
|
@@ -187,18 +187,20 @@ describe('setConstants', function () {
|
|
|
187
187
|
process.env.macroCorePath = undefined;
|
|
188
188
|
getNodeModulePathSpy = jest
|
|
189
189
|
.spyOn(utils, 'getNodeModulePath')
|
|
190
|
-
.mockImplementation(function (
|
|
190
|
+
.mockImplementation(function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
191
191
|
return [2 /*return*/, Promise.resolve('')];
|
|
192
192
|
}); }); });
|
|
193
193
|
return [4 /*yield*/, (0, setConstants_1.setConstants)()];
|
|
194
194
|
case 1:
|
|
195
195
|
_a.sent();
|
|
196
|
-
expect(getNodeModulePathSpy).
|
|
196
|
+
expect(getNodeModulePathSpy).toHaveBeenNthCalledWith(1, '@sasjs/core', process.projectDir);
|
|
197
|
+
expect(getNodeModulePathSpy).toHaveBeenNthCalledWith(2, '@sasjs/core');
|
|
198
|
+
expect(getNodeModulePathSpy).toHaveBeenCalledTimes(2);
|
|
197
199
|
return [2 /*return*/];
|
|
198
200
|
}
|
|
199
201
|
});
|
|
200
202
|
}); });
|
|
201
|
-
test('should
|
|
203
|
+
test('should look up @sasjs/core scoped to process.projectDir, then fall back unscoped, when environment variable macroCorePath is blank', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
202
204
|
var getNodeModulePathSpy;
|
|
203
205
|
return __generator(this, function (_a) {
|
|
204
206
|
switch (_a.label) {
|
|
@@ -206,13 +208,15 @@ describe('setConstants', function () {
|
|
|
206
208
|
process.env.macroCorePath = '';
|
|
207
209
|
getNodeModulePathSpy = jest
|
|
208
210
|
.spyOn(utils, 'getNodeModulePath')
|
|
209
|
-
.mockImplementation(function (
|
|
211
|
+
.mockImplementation(function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
210
212
|
return [2 /*return*/, Promise.resolve('')];
|
|
211
213
|
}); }); });
|
|
212
214
|
return [4 /*yield*/, (0, setConstants_1.setConstants)()];
|
|
213
215
|
case 1:
|
|
214
216
|
_a.sent();
|
|
215
|
-
expect(getNodeModulePathSpy).
|
|
217
|
+
expect(getNodeModulePathSpy).toHaveBeenNthCalledWith(1, '@sasjs/core', process.projectDir);
|
|
218
|
+
expect(getNodeModulePathSpy).toHaveBeenNthCalledWith(2, '@sasjs/core');
|
|
219
|
+
expect(getNodeModulePathSpy).toHaveBeenCalledTimes(2);
|
|
216
220
|
return [2 /*return*/];
|
|
217
221
|
}
|
|
218
222
|
});
|
|
@@ -236,6 +240,54 @@ describe('setConstants', function () {
|
|
|
236
240
|
}
|
|
237
241
|
});
|
|
238
242
|
}); });
|
|
243
|
+
test('should prefer @sasjs/core resolved relative to process.projectDir over the CLI-relative fallback', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
244
|
+
var projectCorePath, getNodeModulePathSpy;
|
|
245
|
+
return __generator(this, function (_a) {
|
|
246
|
+
switch (_a.label) {
|
|
247
|
+
case 0:
|
|
248
|
+
process.env.macroCorePath = undefined;
|
|
249
|
+
projectCorePath = path_1.default.join('some', 'project', 'node_modules', '@sasjs', 'core');
|
|
250
|
+
getNodeModulePathSpy = jest
|
|
251
|
+
.spyOn(utils, 'getNodeModulePath')
|
|
252
|
+
.mockImplementation(function (_packageName, fromDir) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
253
|
+
return [2 /*return*/, Promise.resolve(fromDir ? projectCorePath : 'cli-relative-core-path')];
|
|
254
|
+
}); }); });
|
|
255
|
+
return [4 /*yield*/, (0, setConstants_1.setConstants)()
|
|
256
|
+
// found on the first, project-scoped lookup - the unscoped fallback
|
|
257
|
+
// should never be reached
|
|
258
|
+
];
|
|
259
|
+
case 1:
|
|
260
|
+
_a.sent();
|
|
261
|
+
// found on the first, project-scoped lookup - the unscoped fallback
|
|
262
|
+
// should never be reached
|
|
263
|
+
expect(getNodeModulePathSpy).toHaveBeenCalledTimes(1);
|
|
264
|
+
expect(process.sasjsConstants.macroCorePath).toEqual(projectCorePath);
|
|
265
|
+
return [2 /*return*/];
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
}); });
|
|
269
|
+
test('should fall back to the CLI-relative @sasjs/core when the project has none installed', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
270
|
+
var fallbackCorePath, getNodeModulePathSpy;
|
|
271
|
+
return __generator(this, function (_a) {
|
|
272
|
+
switch (_a.label) {
|
|
273
|
+
case 0:
|
|
274
|
+
process.env.macroCorePath = undefined;
|
|
275
|
+
fallbackCorePath = path_1.default.join('cli', 'node_modules', '@sasjs', 'core');
|
|
276
|
+
getNodeModulePathSpy = jest
|
|
277
|
+
.spyOn(utils, 'getNodeModulePath')
|
|
278
|
+
.mockImplementation(function (_packageName, fromDir) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
279
|
+
return [2 /*return*/, Promise.resolve(fromDir ? '' : fallbackCorePath)];
|
|
280
|
+
}); }); });
|
|
281
|
+
return [4 /*yield*/, (0, setConstants_1.setConstants)()];
|
|
282
|
+
case 1:
|
|
283
|
+
_a.sent();
|
|
284
|
+
expect(getNodeModulePathSpy).toHaveBeenNthCalledWith(1, '@sasjs/core', process.projectDir);
|
|
285
|
+
expect(getNodeModulePathSpy).toHaveBeenNthCalledWith(2, '@sasjs/core');
|
|
286
|
+
expect(process.sasjsConstants.macroCorePath).toEqual(fallbackCorePath);
|
|
287
|
+
return [2 /*return*/];
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
}); });
|
|
239
291
|
});
|
|
240
292
|
var verifySasjsConstants = function (appFolder, hasSasjsCore, isLocal) {
|
|
241
293
|
if (hasSasjsCore === void 0) { hasSasjsCore = false; }
|
|
@@ -493,6 +493,48 @@ describe('utils', function () {
|
|
|
493
493
|
}
|
|
494
494
|
});
|
|
495
495
|
}); });
|
|
496
|
+
it('should prefer a module installed under the given fromDir over default resolution', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
497
|
+
var fakeModuleName, fromDir, fakeModuleDir, resolvedPath;
|
|
498
|
+
return __generator(this, function (_a) {
|
|
499
|
+
switch (_a.label) {
|
|
500
|
+
case 0:
|
|
501
|
+
fakeModuleName = "sasjs-test-fake-module-".concat((0, utils_2.generateTimestamp)());
|
|
502
|
+
fromDir = path_1.default.join(require('os').tmpdir(), "getNodeModulePath-".concat((0, utils_2.generateTimestamp)()));
|
|
503
|
+
fakeModuleDir = path_1.default.join(fromDir, 'node_modules', fakeModuleName);
|
|
504
|
+
return [4 /*yield*/, (0, utils_2.createFolder)(fakeModuleDir)];
|
|
505
|
+
case 1:
|
|
506
|
+
_a.sent();
|
|
507
|
+
return [4 /*yield*/, (0, utils_2.createFile)(path_1.default.join(fakeModuleDir, 'package.json'), JSON.stringify({ name: fakeModuleName, version: '1.0.0' }))
|
|
508
|
+
// not resolvable at all without fromDir - it only exists in fromDir's
|
|
509
|
+
// own node_modules, nowhere on the default resolution path
|
|
510
|
+
];
|
|
511
|
+
case 2:
|
|
512
|
+
_a.sent();
|
|
513
|
+
// not resolvable at all without fromDir - it only exists in fromDir's
|
|
514
|
+
// own node_modules, nowhere on the default resolution path
|
|
515
|
+
return [4 /*yield*/, expect((0, utils_1.getNodeModulePath)(fakeModuleName)).resolves.toEqual('')];
|
|
516
|
+
case 3:
|
|
517
|
+
// not resolvable at all without fromDir - it only exists in fromDir's
|
|
518
|
+
// own node_modules, nowhere on the default resolution path
|
|
519
|
+
_a.sent();
|
|
520
|
+
return [4 /*yield*/, (0, utils_1.getNodeModulePath)(fakeModuleName, fromDir)
|
|
521
|
+
// compare tails rather than exact paths: require.resolve returns the
|
|
522
|
+
// real (symlink-resolved) path, which can differ from os.tmpdir()'s
|
|
523
|
+
// raw value (e.g. /var vs /private/var on macOS)
|
|
524
|
+
];
|
|
525
|
+
case 4:
|
|
526
|
+
resolvedPath = _a.sent();
|
|
527
|
+
// compare tails rather than exact paths: require.resolve returns the
|
|
528
|
+
// real (symlink-resolved) path, which can differ from os.tmpdir()'s
|
|
529
|
+
// raw value (e.g. /var vs /private/var on macOS)
|
|
530
|
+
expect(resolvedPath.endsWith(path_1.default.join('node_modules', fakeModuleName))).toEqual(true);
|
|
531
|
+
return [4 /*yield*/, (0, utils_2.deleteFolder)(fromDir)];
|
|
532
|
+
case 5:
|
|
533
|
+
_a.sent();
|
|
534
|
+
return [2 /*return*/];
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
}); });
|
|
496
538
|
});
|
|
497
539
|
describe('getUniqServicesObj', function () {
|
|
498
540
|
it('should return an empty object when services is falsy', function () {
|
package/build/utils/utils.d.ts
CHANGED
|
@@ -42,5 +42,23 @@ export declare const terminateProcess: (status: number) => never;
|
|
|
42
42
|
* @returns boolean
|
|
43
43
|
*/
|
|
44
44
|
export declare const isSASjsProject: () => Promise<boolean>;
|
|
45
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Locates an installed npm module and returns its root folder.
|
|
47
|
+
*
|
|
48
|
+
* Without `fromDir`, `require.resolve` searches relative to *this file's own*
|
|
49
|
+
* location on disk - i.e. wherever @sasjs/cli itself is installed - not the
|
|
50
|
+
* user's project. That's fine for CLI-internal dependencies, but wrong for
|
|
51
|
+
* anything the user is expected to manage in their own project's
|
|
52
|
+
* node_modules (e.g. @sasjs/core): since @sasjs/cli also depends on that
|
|
53
|
+
* same package, default resolution finds the CLI's own bundled copy first
|
|
54
|
+
* and never reaches the project's. Passing `fromDir` anchors the search at
|
|
55
|
+
* that directory instead (Node's `paths` option replaces, rather than
|
|
56
|
+
* extends, the default resolution paths), so callers that need
|
|
57
|
+
* project-first resolution should pass `process.projectDir` and fall back to
|
|
58
|
+
* an unscoped call if that returns nothing.
|
|
59
|
+
* @param {string} module - the name of the npm module to locate.
|
|
60
|
+
* @param {string} fromDir - optional directory to resolve `module` from,
|
|
61
|
+
* instead of this file's own location.
|
|
62
|
+
*/
|
|
63
|
+
export declare const getNodeModulePath: (module: string, fromDir?: string) => Promise<string>;
|
|
46
64
|
export declare const isSasJsServerInServerMode: (target: Target) => Promise<boolean>;
|
package/build/utils/utils.js
CHANGED
|
@@ -699,12 +699,30 @@ var isSASjsProject = function () { return __awaiter(void 0, void 0, void 0, func
|
|
|
699
699
|
});
|
|
700
700
|
}); };
|
|
701
701
|
exports.isSASjsProject = isSASjsProject;
|
|
702
|
-
|
|
702
|
+
/**
|
|
703
|
+
* Locates an installed npm module and returns its root folder.
|
|
704
|
+
*
|
|
705
|
+
* Without `fromDir`, `require.resolve` searches relative to *this file's own*
|
|
706
|
+
* location on disk - i.e. wherever @sasjs/cli itself is installed - not the
|
|
707
|
+
* user's project. That's fine for CLI-internal dependencies, but wrong for
|
|
708
|
+
* anything the user is expected to manage in their own project's
|
|
709
|
+
* node_modules (e.g. @sasjs/core): since @sasjs/cli also depends on that
|
|
710
|
+
* same package, default resolution finds the CLI's own bundled copy first
|
|
711
|
+
* and never reaches the project's. Passing `fromDir` anchors the search at
|
|
712
|
+
* that directory instead (Node's `paths` option replaces, rather than
|
|
713
|
+
* extends, the default resolution paths), so callers that need
|
|
714
|
+
* project-first resolution should pass `process.projectDir` and fall back to
|
|
715
|
+
* an unscoped call if that returns nothing.
|
|
716
|
+
* @param {string} module - the name of the npm module to locate.
|
|
717
|
+
* @param {string} fromDir - optional directory to resolve `module` from,
|
|
718
|
+
* instead of this file's own location.
|
|
719
|
+
*/
|
|
720
|
+
var getNodeModulePath = function (module, fromDir) { return __awaiter(void 0, void 0, void 0, function () {
|
|
703
721
|
var nodePackagePath;
|
|
704
722
|
return __generator(this, function (_a) {
|
|
705
723
|
// Look for ${module}/package.json, then return only the path
|
|
706
724
|
try {
|
|
707
|
-
nodePackagePath = path_1.default.dirname(require.resolve(path_1.default.join(module, 'package.json')));
|
|
725
|
+
nodePackagePath = path_1.default.dirname(require.resolve(path_1.default.join(module, 'package.json'), fromDir ? { paths: [fromDir] } : undefined));
|
|
708
726
|
if (nodePackagePath)
|
|
709
727
|
return [2 /*return*/, nodePackagePath];
|
|
710
728
|
}
|
package/package.json
CHANGED