@sasjs/cli 6.19.1 → 6.19.2
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/boot.js +34 -6
- package/build/commands/build/internal/mockSite/mockSite.js +21 -12
- package/build/commands/build/internal/mockSite/spec/boot.spec.js +109 -7
- package/build/commands/build/internal/mockSite/spec/mockSite.spec.js +61 -17
- package/build/types/index.d.ts +1 -0
- package/build/types/index.js +1 -0
- package/build/types/mockWebBasePath.d.ts +24 -0
- package/build/types/mockWebBasePath.js +2 -0
- package/package.json +1 -1
|
@@ -114,13 +114,41 @@
|
|
|
114
114
|
stamp = ''
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
// Registered
|
|
118
|
-
// the site is served from the origin root on
|
|
119
|
-
// another (a demonstration site beside its own
|
|
120
|
-
//
|
|
117
|
+
// Registered against the loader's own URL, which sits in <base>/host/, and
|
|
118
|
+
// scoped to the folder above it: the site is served from the origin root on
|
|
119
|
+
// one host and from a folder on another (a demonstration site beside its own
|
|
120
|
+
// docs). The page cannot be the reference - at `<base>` with no trailing
|
|
121
|
+
// slash a page-relative URL names the origin root, and './' resolves to '/',
|
|
122
|
+
// which is the mis-registration this is here to avoid.
|
|
123
|
+
//
|
|
124
|
+
// The tag the build emits is absolute (`<base>/host/boot.js`) when the target
|
|
125
|
+
// names a folder, and relative (`host/boot.js`) when it does not - so a site
|
|
126
|
+
// published in a folder without naming it depends on its own URL ending in a
|
|
127
|
+
// slash - and in both cases the loader's own URL then carries `<base>`. The
|
|
128
|
+
// fallback below is for the case where there is no currentScript to read.
|
|
129
|
+
var loaderSrc = (script && script.src) || loaderUrl()
|
|
130
|
+
|
|
131
|
+
// The loader always sits in <base>/host/, so without a currentScript the page
|
|
132
|
+
// still names the base. A path that does not end in a slash is ambiguous: it
|
|
133
|
+
// is the folder when its last segment has no dot (`/demo`), and a file when it
|
|
134
|
+
// does (`/demo/index.html`) - only the second has a segment to drop.
|
|
135
|
+
// `location.href` cannot do this: one level above `/demo` is the origin root.
|
|
136
|
+
function loaderUrl() {
|
|
137
|
+
var page = location.pathname
|
|
138
|
+
var lastSegment = page.slice(page.lastIndexOf('/') + 1)
|
|
139
|
+
var base
|
|
140
|
+
|
|
141
|
+
if (lastSegment.indexOf('.') === -1) {
|
|
142
|
+
base = page.charAt(page.length - 1) === '/' ? page : page + '/'
|
|
143
|
+
} else {
|
|
144
|
+
base = page.slice(0, page.lastIndexOf('/') + 1)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return location.origin + base + 'host/boot.js'
|
|
148
|
+
}
|
|
121
149
|
navigator.serviceWorker
|
|
122
|
-
.register(new URL('sw.js' + stamp,
|
|
123
|
-
scope: '
|
|
150
|
+
.register(new URL('../sw.js' + stamp, loaderSrc).href, {
|
|
151
|
+
scope: new URL('../', loaderSrc).pathname,
|
|
124
152
|
updateViaCache: 'none'
|
|
125
153
|
})
|
|
126
154
|
.then(function () {
|
|
@@ -517,8 +517,9 @@ var escapeAttribute = function (value) {
|
|
|
517
517
|
* order, plus the inline snippets some pages use to set up a global before the
|
|
518
518
|
* bundle runs - so the host does not dictate how the app is built.
|
|
519
519
|
*/
|
|
520
|
-
var bootTag = function (scripts, version) {
|
|
521
|
-
|
|
520
|
+
var bootTag = function (scripts, version, basePath) {
|
|
521
|
+
if (basePath === void 0) { basePath = ''; }
|
|
522
|
+
return "<script src=\"".concat(basePath ? "".concat(basePath, "/host/boot.js") : 'host/boot.js', "?v=").concat(version, "\" data-scripts='").concat(escapeAttribute(JSON.stringify(scripts)), "'></script>");
|
|
522
523
|
};
|
|
523
524
|
/**
|
|
524
525
|
* Script types the browser executes. Anything else (`application/ld+json`, a
|
|
@@ -531,28 +532,36 @@ var EXECUTABLE_TYPES = [
|
|
|
531
532
|
'application/javascript'
|
|
532
533
|
];
|
|
533
534
|
/**
|
|
534
|
-
* The folder the site is published under,
|
|
535
|
+
* The folder the site is published under, with a leading slash and no trailing
|
|
536
|
+
* one.
|
|
535
537
|
*
|
|
536
538
|
* Empty for the origin root, which is the ordinary case. A host that serves the
|
|
537
539
|
* demonstration site beside its documentation (a GitHub Pages site whose root is
|
|
538
540
|
* the docs) names the folder here, and every path the build emits follows it.
|
|
541
|
+
*
|
|
542
|
+
* The shapes the released build accepts keep working - a bare `demo`, a leading
|
|
543
|
+
* or trailing slash, surrounding space - and are normalised rather than
|
|
544
|
+
* refused, because a `fix(mock)` release must not fail a build that passes
|
|
545
|
+
* today. The sasjsconfig schema states the canonical form; this only rejects
|
|
546
|
+
* what could never have worked, a segment that is `.`, `..` or empty.
|
|
539
547
|
*/
|
|
540
548
|
var normaliseBasePath = function (value) {
|
|
541
549
|
if (!value)
|
|
542
550
|
return '';
|
|
543
|
-
var
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
551
|
+
var segments = String(value)
|
|
552
|
+
.trim()
|
|
553
|
+
.replace(/^\/+/, '')
|
|
554
|
+
.replace(/\/+$/, '')
|
|
555
|
+
.split('/');
|
|
548
556
|
if (!segments.length ||
|
|
549
557
|
segments.some(function (segment) {
|
|
550
|
-
return
|
|
558
|
+
return !segment ||
|
|
551
559
|
segment === '.' ||
|
|
552
|
-
segment === '..'
|
|
560
|
+
segment === '..' ||
|
|
561
|
+
!/^[A-Za-z0-9._~-]+$/.test(segment);
|
|
553
562
|
}))
|
|
554
563
|
throw new Error("mockWebBasePath is not a folder path: ".concat(JSON.stringify(value), ". Use a path such as \"/demo\", or leave it unset for the origin root."));
|
|
555
|
-
return
|
|
564
|
+
return '/' + segments.join('/');
|
|
556
565
|
};
|
|
557
566
|
/**
|
|
558
567
|
* Tells the interface that this page is answered by the browser host.
|
|
@@ -648,7 +657,7 @@ var patchIndexHtml = function (html, version, basePath) {
|
|
|
648
657
|
return '';
|
|
649
658
|
});
|
|
650
659
|
if (scripts.length) {
|
|
651
|
-
var tag = bootTag(scripts, version);
|
|
660
|
+
var tag = bootTag(scripts, version, basePath);
|
|
652
661
|
patched = /<\/body>/i.test(patched)
|
|
653
662
|
? patched.replace(/<\/body>/i, "".concat(tag, "\n</body>"))
|
|
654
663
|
: patched + tag;
|
|
@@ -56,15 +56,24 @@ var loadBoot = function (specs, options) {
|
|
|
56
56
|
};
|
|
57
57
|
return element;
|
|
58
58
|
};
|
|
59
|
+
// The page carries an absolute boot tag, `<base>/host/boot.js`, so the
|
|
60
|
+
// loader's own URL names the folder whether or not the page URL ends in a
|
|
61
|
+
// slash - a relative tag would resolve against the page and, at `/demo`, name
|
|
62
|
+
// the origin root.
|
|
63
|
+
var pageHref = options.href || 'http://localhost:8123/';
|
|
64
|
+
var stamp = options.noStamp ? '' : '?v=abc123';
|
|
65
|
+
// the tag the build emits: absolute when the target names a folder, relative
|
|
66
|
+
// to the page when it does not
|
|
67
|
+
var loaderSrc = options.basePath
|
|
68
|
+
? "".concat(new URL(pageHref).origin).concat(options.basePath, "/host/boot.js").concat(stamp)
|
|
69
|
+
: new URL('host/boot.js' + stamp, pageHref).href;
|
|
59
70
|
var document = {
|
|
60
71
|
currentScript: options.noScript
|
|
61
72
|
? null
|
|
62
73
|
: {
|
|
63
74
|
// the builder stamps the boot tag with the host version, and the
|
|
64
75
|
// loader reuses that query for the worker's own URL
|
|
65
|
-
src:
|
|
66
|
-
? 'http://localhost:8123/host/boot.js'
|
|
67
|
-
: 'http://localhost:8123/host/boot.js?v=abc123',
|
|
76
|
+
src: loaderSrc,
|
|
68
77
|
getAttribute: function (name) {
|
|
69
78
|
if (name !== 'data-scripts')
|
|
70
79
|
return null;
|
|
@@ -126,7 +135,9 @@ var loadBoot = function (specs, options) {
|
|
|
126
135
|
}
|
|
127
136
|
};
|
|
128
137
|
global.location = {
|
|
129
|
-
href:
|
|
138
|
+
href: pageHref,
|
|
139
|
+
pathname: new URL(pageHref).pathname,
|
|
140
|
+
origin: new URL(pageHref).origin,
|
|
130
141
|
reload: function () { return timeline.push('reload'); }
|
|
131
142
|
};
|
|
132
143
|
jest.spyOn(console, 'error').mockImplementation(function () { });
|
|
@@ -185,7 +196,7 @@ describe('the boot loader', function () {
|
|
|
185
196
|
// root on one host and from /demo beside its docs on another.
|
|
186
197
|
expect(registered).toEqual([
|
|
187
198
|
'http://localhost:8123/sw.js?v=abc123 ' +
|
|
188
|
-
JSON.stringify({ scope: '
|
|
199
|
+
JSON.stringify({ scope: '/', updateViaCache: 'none' })
|
|
189
200
|
]);
|
|
190
201
|
return [2 /*return*/];
|
|
191
202
|
}
|
|
@@ -196,13 +207,104 @@ describe('the boot loader', function () {
|
|
|
196
207
|
return __generator(this, function (_a) {
|
|
197
208
|
switch (_a.label) {
|
|
198
209
|
case 0:
|
|
199
|
-
registered = loadBoot([], {
|
|
210
|
+
registered = loadBoot([], {
|
|
211
|
+
href: 'http://localhost:8123/demo/',
|
|
212
|
+
basePath: '/demo'
|
|
213
|
+
}).registered;
|
|
200
214
|
return [4 /*yield*/, settle()];
|
|
201
215
|
case 1:
|
|
202
216
|
_a.sent();
|
|
203
217
|
expect(registered).toEqual([
|
|
204
218
|
'http://localhost:8123/demo/sw.js?v=abc123 ' +
|
|
205
|
-
JSON.stringify({ scope: '
|
|
219
|
+
JSON.stringify({ scope: '/demo/', updateViaCache: 'none' })
|
|
220
|
+
]);
|
|
221
|
+
return [2 /*return*/];
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}); });
|
|
225
|
+
it('registers under the folder when the page has no trailing slash', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
226
|
+
var registered;
|
|
227
|
+
return __generator(this, function (_a) {
|
|
228
|
+
switch (_a.label) {
|
|
229
|
+
case 0:
|
|
230
|
+
registered = loadBoot([], {
|
|
231
|
+
href: 'http://localhost:8123/demo',
|
|
232
|
+
basePath: '/demo'
|
|
233
|
+
}).registered;
|
|
234
|
+
return [4 /*yield*/, settle()];
|
|
235
|
+
case 1:
|
|
236
|
+
_a.sent();
|
|
237
|
+
expect(registered).toEqual([
|
|
238
|
+
'http://localhost:8123/demo/sw.js?v=abc123 ' +
|
|
239
|
+
JSON.stringify({ scope: '/demo/', updateViaCache: 'none' })
|
|
240
|
+
]);
|
|
241
|
+
return [2 /*return*/];
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}); });
|
|
245
|
+
it('finds the folder from the page when the document has no currentScript', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
246
|
+
var registered;
|
|
247
|
+
return __generator(this, function (_a) {
|
|
248
|
+
switch (_a.label) {
|
|
249
|
+
case 0:
|
|
250
|
+
registered = loadBoot([], {
|
|
251
|
+
href: 'http://localhost:8123/demo/',
|
|
252
|
+
basePath: '/demo',
|
|
253
|
+
noScript: true
|
|
254
|
+
}).registered;
|
|
255
|
+
return [4 /*yield*/, settle()
|
|
256
|
+
// no tag, no version: the fallback cannot carry the build's stamp, so this
|
|
257
|
+
// path registers the folder's worker without a cache-busting query
|
|
258
|
+
];
|
|
259
|
+
case 1:
|
|
260
|
+
_a.sent();
|
|
261
|
+
// no tag, no version: the fallback cannot carry the build's stamp, so this
|
|
262
|
+
// path registers the folder's worker without a cache-busting query
|
|
263
|
+
expect(registered).toEqual([
|
|
264
|
+
'http://localhost:8123/demo/sw.js ' +
|
|
265
|
+
JSON.stringify({ scope: '/demo/', updateViaCache: 'none' })
|
|
266
|
+
]);
|
|
267
|
+
return [2 /*return*/];
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
}); });
|
|
271
|
+
it('treats a path with no trailing slash as the folder, not a file', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
272
|
+
var registered;
|
|
273
|
+
return __generator(this, function (_a) {
|
|
274
|
+
switch (_a.label) {
|
|
275
|
+
case 0:
|
|
276
|
+
registered = loadBoot([], {
|
|
277
|
+
href: 'http://localhost:8123/demo',
|
|
278
|
+
basePath: '/demo',
|
|
279
|
+
noScript: true
|
|
280
|
+
}).registered;
|
|
281
|
+
return [4 /*yield*/, settle()];
|
|
282
|
+
case 1:
|
|
283
|
+
_a.sent();
|
|
284
|
+
expect(registered).toEqual([
|
|
285
|
+
'http://localhost:8123/demo/sw.js ' +
|
|
286
|
+
JSON.stringify({ scope: '/demo/', updateViaCache: 'none' })
|
|
287
|
+
]);
|
|
288
|
+
return [2 /*return*/];
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
}); });
|
|
292
|
+
it('drops a file name from the path, and keeps the folder above it', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
293
|
+
var registered;
|
|
294
|
+
return __generator(this, function (_a) {
|
|
295
|
+
switch (_a.label) {
|
|
296
|
+
case 0:
|
|
297
|
+
registered = loadBoot([], {
|
|
298
|
+
href: 'http://localhost:8123/demo/index.html',
|
|
299
|
+
basePath: '/demo',
|
|
300
|
+
noScript: true
|
|
301
|
+
}).registered;
|
|
302
|
+
return [4 /*yield*/, settle()];
|
|
303
|
+
case 1:
|
|
304
|
+
_a.sent();
|
|
305
|
+
expect(registered).toEqual([
|
|
306
|
+
'http://localhost:8123/demo/sw.js ' +
|
|
307
|
+
JSON.stringify({ scope: '/demo/', updateViaCache: 'none' })
|
|
206
308
|
]);
|
|
207
309
|
return [2 /*return*/];
|
|
208
310
|
}
|
|
@@ -375,9 +375,9 @@ describe('browser-hosted build', function () {
|
|
|
375
375
|
_a.sent();
|
|
376
376
|
html = fs_1.default.readFileSync(path_1.default.join(out(), 'index.html'), 'utf8');
|
|
377
377
|
expect(html).toContain('serverurl="/demo"');
|
|
378
|
-
// the
|
|
379
|
-
//
|
|
380
|
-
expect(html).toContain('<script src="host/boot.js?v=');
|
|
378
|
+
// the boot tag is absolute and names the folder, so a page at `/demo` with
|
|
379
|
+
// no trailing slash still loads the loader from `/demo/host/`
|
|
380
|
+
expect(html).toContain('<script src="/demo/host/boot.js?v=');
|
|
381
381
|
return [2 /*return*/];
|
|
382
382
|
}
|
|
383
383
|
});
|
|
@@ -395,6 +395,50 @@ describe('browser-hosted build', function () {
|
|
|
395
395
|
}
|
|
396
396
|
});
|
|
397
397
|
}); });
|
|
398
|
+
it('normalises the folder shapes the released build already accepts', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
399
|
+
var _a, _b, value, html_1, e_3_1, html;
|
|
400
|
+
var e_3, _c;
|
|
401
|
+
return __generator(this, function (_d) {
|
|
402
|
+
switch (_d.label) {
|
|
403
|
+
case 0:
|
|
404
|
+
_d.trys.push([0, 5, 6, 7]);
|
|
405
|
+
_a = __values(['/demo/', ' /demo ', 'demo']), _b = _a.next();
|
|
406
|
+
_d.label = 1;
|
|
407
|
+
case 1:
|
|
408
|
+
if (!!_b.done) return [3 /*break*/, 4];
|
|
409
|
+
value = _b.value;
|
|
410
|
+
return [4 /*yield*/, (0, mockSite_1.buildMockSite)(target({ mockWebBasePath: value }))];
|
|
411
|
+
case 2:
|
|
412
|
+
_d.sent();
|
|
413
|
+
html_1 = fs_1.default.readFileSync(path_1.default.join(out(), 'index.html'), 'utf8');
|
|
414
|
+
expect(html_1).toContain('serverurl="/demo"');
|
|
415
|
+
_d.label = 3;
|
|
416
|
+
case 3:
|
|
417
|
+
_b = _a.next();
|
|
418
|
+
return [3 /*break*/, 1];
|
|
419
|
+
case 4: return [3 /*break*/, 7];
|
|
420
|
+
case 5:
|
|
421
|
+
e_3_1 = _d.sent();
|
|
422
|
+
e_3 = { error: e_3_1 };
|
|
423
|
+
return [3 /*break*/, 7];
|
|
424
|
+
case 6:
|
|
425
|
+
try {
|
|
426
|
+
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
427
|
+
}
|
|
428
|
+
finally { if (e_3) throw e_3.error; }
|
|
429
|
+
return [7 /*endfinally*/];
|
|
430
|
+
case 7:
|
|
431
|
+
// explicit empty is the origin root, as it was before the option existed
|
|
432
|
+
return [4 /*yield*/, (0, mockSite_1.buildMockSite)(target({ mockWebBasePath: '' }))];
|
|
433
|
+
case 8:
|
|
434
|
+
// explicit empty is the origin root, as it was before the option existed
|
|
435
|
+
_d.sent();
|
|
436
|
+
html = fs_1.default.readFileSync(path_1.default.join(out(), 'index.html'), 'utf8');
|
|
437
|
+
expect(html).toContain('serverurl=""');
|
|
438
|
+
return [2 /*return*/];
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
}); });
|
|
398
442
|
it('points the app at itself and installs the boot loader', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
399
443
|
var html;
|
|
400
444
|
return __generator(this, function (_a) {
|
|
@@ -630,7 +674,7 @@ describe('browser-hosted build', function () {
|
|
|
630
674
|
}); });
|
|
631
675
|
it('stops seeding bytes once the drive budget is spent, and names the file', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
632
676
|
var chunk, _a, _b, name_1, seed, seeded;
|
|
633
|
-
var
|
|
677
|
+
var e_4, _c;
|
|
634
678
|
var _d;
|
|
635
679
|
return __generator(this, function (_e) {
|
|
636
680
|
switch (_e.label) {
|
|
@@ -643,12 +687,12 @@ describe('browser-hosted build', function () {
|
|
|
643
687
|
fs_1.default.writeFileSync(path_1.default.join(root, 'sasjsbuild', 'mock-storage', name_1), chunk);
|
|
644
688
|
}
|
|
645
689
|
}
|
|
646
|
-
catch (
|
|
690
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
647
691
|
finally {
|
|
648
692
|
try {
|
|
649
693
|
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
650
694
|
}
|
|
651
|
-
finally { if (
|
|
695
|
+
finally { if (e_4) throw e_4.error; }
|
|
652
696
|
}
|
|
653
697
|
return [4 /*yield*/, (0, mockSite_1.buildMockSite)(target())
|
|
654
698
|
// the budget is spent in path order, so the drive is the same on every host:
|
|
@@ -734,7 +778,7 @@ describe('browser-hosted build', function () {
|
|
|
734
778
|
*/
|
|
735
779
|
it('builds an interface that has no services, and says the drive is empty', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
736
780
|
var _a, _b, folder, warn, result;
|
|
737
|
-
var
|
|
781
|
+
var e_5, _c;
|
|
738
782
|
var _d;
|
|
739
783
|
return __generator(this, function (_e) {
|
|
740
784
|
switch (_e.label) {
|
|
@@ -749,12 +793,12 @@ describe('browser-hosted build', function () {
|
|
|
749
793
|
});
|
|
750
794
|
}
|
|
751
795
|
}
|
|
752
|
-
catch (
|
|
796
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
753
797
|
finally {
|
|
754
798
|
try {
|
|
755
799
|
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
756
800
|
}
|
|
757
|
-
finally { if (
|
|
801
|
+
finally { if (e_5) throw e_5.error; }
|
|
758
802
|
}
|
|
759
803
|
warn = jest.spyOn((_d = process.logger) !== null && _d !== void 0 ? _d : console, 'warn');
|
|
760
804
|
return [4 /*yield*/, (0, mockSite_1.buildMockSite)(target())];
|
|
@@ -776,7 +820,7 @@ describe('browser-hosted build', function () {
|
|
|
776
820
|
*/
|
|
777
821
|
it('warns when the build folder holds only folders that are not programs', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
778
822
|
var _a, _b, folder, warn, result;
|
|
779
|
-
var
|
|
823
|
+
var e_6, _c;
|
|
780
824
|
var _d;
|
|
781
825
|
return __generator(this, function (_e) {
|
|
782
826
|
switch (_e.label) {
|
|
@@ -790,12 +834,12 @@ describe('browser-hosted build', function () {
|
|
|
790
834
|
});
|
|
791
835
|
}
|
|
792
836
|
}
|
|
793
|
-
catch (
|
|
837
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
794
838
|
finally {
|
|
795
839
|
try {
|
|
796
840
|
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
797
841
|
}
|
|
798
|
-
finally { if (
|
|
842
|
+
finally { if (e_6) throw e_6.error; }
|
|
799
843
|
}
|
|
800
844
|
write(path_1.default.join(root, 'sasjsbuild', 'docs', 'index.html'), '<html></html>');
|
|
801
845
|
warn = jest.spyOn((_d = process.logger) !== null && _d !== void 0 ? _d : console, 'warn');
|
|
@@ -898,8 +942,8 @@ describe('browser-hosted build', function () {
|
|
|
898
942
|
});
|
|
899
943
|
}); });
|
|
900
944
|
it('refuses a mockWebFolder that would delete the project or its inputs', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
901
|
-
var _a, _b, mockWebFolder,
|
|
902
|
-
var
|
|
945
|
+
var _a, _b, mockWebFolder, e_7_1;
|
|
946
|
+
var e_7, _c;
|
|
903
947
|
return __generator(this, function (_d) {
|
|
904
948
|
switch (_d.label) {
|
|
905
949
|
case 0:
|
|
@@ -930,14 +974,14 @@ describe('browser-hosted build', function () {
|
|
|
930
974
|
return [3 /*break*/, 1];
|
|
931
975
|
case 4: return [3 /*break*/, 7];
|
|
932
976
|
case 5:
|
|
933
|
-
|
|
934
|
-
|
|
977
|
+
e_7_1 = _d.sent();
|
|
978
|
+
e_7 = { error: e_7_1 };
|
|
935
979
|
return [3 /*break*/, 7];
|
|
936
980
|
case 6:
|
|
937
981
|
try {
|
|
938
982
|
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
939
983
|
}
|
|
940
|
-
finally { if (
|
|
984
|
+
finally { if (e_7) throw e_7.error; }
|
|
941
985
|
return [7 /*endfinally*/];
|
|
942
986
|
case 7:
|
|
943
987
|
expect(fs_1.default.existsSync(path_1.default.join(root, 'client', 'dist', 'index.html'))).toBe(true);
|
package/build/types/index.d.ts
CHANGED
|
@@ -5,3 +5,4 @@ export { TargetScope } from './targetScope';
|
|
|
5
5
|
export { TestFlow, Coverage, CoverageReport, CoverageSummary, CoverageType, CoverageState, TestResults, TestResultStatus, TestDescription, TestResult, TestResultDescription, TestResultCsv } from './testing';
|
|
6
6
|
export { Flow, FlowWave, FlowWaveJob } from './flow';
|
|
7
7
|
export * from './log';
|
|
8
|
+
export * from './mockWebBasePath';
|
package/build/types/index.js
CHANGED
|
@@ -24,3 +24,4 @@ Object.defineProperty(exports, "CoverageType", { enumerable: true, get: function
|
|
|
24
24
|
Object.defineProperty(exports, "CoverageState", { enumerable: true, get: function () { return testing_1.CoverageState; } });
|
|
25
25
|
Object.defineProperty(exports, "TestResultStatus", { enumerable: true, get: function () { return testing_1.TestResultStatus; } });
|
|
26
26
|
__exportStar(require("./log"), exports);
|
|
27
|
+
__exportStar(require("./mockWebBasePath"), exports);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `mockWebBasePath` on a stream config.
|
|
3
|
+
*
|
|
4
|
+
* A `.ts` rather than a `.d.ts` so it compiles into `build/types/` with the
|
|
5
|
+
* rest of the package: tsc does not emit an ambient input file, and this one
|
|
6
|
+
* would otherwise type the CLI's own build and vanish from the published one.
|
|
7
|
+
*
|
|
8
|
+
* The option belongs to the mock target the CLI reads, but `StreamConfig` in
|
|
9
|
+
* @sasjs/utils 4.9.0 predates it, so without this the property is invisible to
|
|
10
|
+
* anyone typing a sasjsconfig and to anything that round-trips a target through
|
|
11
|
+
* the type. The field lands upstream in sasjs/utils#317; when the pin moves past
|
|
12
|
+
* that release, delete this file and the declaration merges from the package
|
|
13
|
+
* itself.
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
declare module '@sasjs/utils/types/config' {
|
|
17
|
+
interface StreamConfig {
|
|
18
|
+
/**
|
|
19
|
+
* The folder the mock site is published in, as a path with no trailing
|
|
20
|
+
* slash (`/demo`). Unset means the origin root.
|
|
21
|
+
*/
|
|
22
|
+
mockWebBasePath?: string;
|
|
23
|
+
}
|
|
24
|
+
}
|
package/package.json
CHANGED