@sasjs/cli 6.19.4 → 6.20.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.
@@ -125,8 +125,11 @@
125
125
  xhr.dispatchEvent(new ProgressEvent('loadend'))
126
126
  }
127
127
 
128
+ // `/api` is the short spelling of the API and `/SASjsApi` the canonical one:
129
+ // the build bridges both, so a caller that uses either reaches the mock.
128
130
  const isSasjs = (url) =>
129
- typeof url === 'string' && url.indexOf('/SASjsApi/') >= 0
131
+ typeof url === 'string' &&
132
+ (url.indexOf('/SASjsApi/') >= 0 || url.indexOf('/api/') >= 0)
130
133
 
131
134
  const proto = XMLHttpRequest.prototype
132
135
  const nativeOpen = proto.open
@@ -327,6 +327,15 @@ const RUNTIME = new BrowserRuntime()
327
327
  */
328
328
  const BASE = (self.location.pathname || '').replace(/\/sw\.js.*$/, '')
329
329
 
330
+ /**
331
+ * The short spelling of the App Stream landing page.
332
+ *
333
+ * It is the default: the interface links to `/app`, and sasjs/server serves it
334
+ * there while keeping `/AppStream` as a redirect. The worker mirrors that, so a
335
+ * link the interface builds reaches the same page on the static demo.
336
+ */
337
+ const SHORT_APP_STREAM_PATH = '/app'
338
+
330
339
  const withoutBase = (pathname) =>
331
340
  BASE && pathname.startsWith(BASE)
332
341
  ? pathname.slice(BASE.length) || '/'
@@ -889,6 +898,11 @@ const contentsResponse = (answer, path) => {
889
898
 
890
899
  const routeRequest = async (request, url) => {
891
900
  const path = withoutBase(url.pathname).replace(/\/+$/, '') || '/'
901
+ // `/api` is the short spelling of the API, and `/SASjsApi` the canonical one:
902
+ // both are answered, so the alias is stripped once here and everything below -
903
+ // the route lookup, the drive routes' plain-text refusals, the log - works
904
+ // from one path.
905
+ const apiPath = path.replace(/^\/api(?=\/|$)/i, '/SASjsApi')
892
906
  const query = {}
893
907
  for (const [k, v] of url.searchParams.entries()) query[k] = v
894
908
 
@@ -901,27 +915,31 @@ const routeRequest = async (request, url) => {
901
915
  // every visit. Unanswered, those requests reach the static host and the page
902
916
  // parses this site's index.html as JSON.
903
917
  //
904
- // The answers mirror the server's, because a caller cannot tell the two
905
- // hosts apart otherwise: `/AppStream` redirects to `/AppStream/`, the landing
906
- // page is served, and only a name under it is missing. The listing is empty
907
- // rather than read from `registry()`, which records this deployment's own
908
- // folder so the delete route has something to remove: the stream really does
909
- // serve nothing at `/AppStream/<name>/` here, and a listing that named it
910
- // would offer a tile that 404s.
911
- // `path` has its trailing slashes stripped, and these four answers differ by
912
- // exactly that, so they are decided on the request's own pathname - minus
913
- // the folder the site is served from, which the four patterns do not name.
918
+ // `/app` is the spelling the interface links to and the server serves; the
919
+ // canonical `/AppStream` still answers, because a client built before the
920
+ // short paths existed asks for it. The answers are the same either way, so
921
+ // `/AppStream` redirects to `/app` - exactly as the server redirects it -
922
+ // and the landing page, the listing and the missing-name refusal are decided
923
+ // on both.
924
+ //
925
+ // The listing is empty rather than read from `registry()`, which records this
926
+ // deployment's own folder so the delete route has something to remove: the
927
+ // stream really does serve nothing at `/app/<name>/` here, and a listing that
928
+ // named it would offer a tile that 404s.
929
+ // `path` has its trailing slashes stripped, and the landing answers differ by
930
+ // exactly that, so they are decided on the request's own pathname - minus the
931
+ // folder the site is served from, which the patterns do not name.
914
932
  const stream = withoutBase(url.pathname)
915
933
 
916
934
  if (/^\/AppStream$/i.test(stream))
917
935
  return new Response(null, {
918
936
  status: 301,
919
- headers: { location: `${BASE}/AppStream/` }
937
+ headers: { location: `${BASE}${SHORT_APP_STREAM_PATH}` }
920
938
  })
921
939
 
922
940
  if (
923
- /^\/AppStream\/$/i.test(stream) ||
924
- /^\/AppStream\/index\.html$/i.test(stream)
941
+ /^\/(app|AppStream)\/?$/i.test(stream) ||
942
+ /^\/(app|AppStream)\/index\.html$/i.test(stream)
925
943
  )
926
944
  return new Response(
927
945
  [
@@ -934,9 +952,10 @@ const routeRequest = async (request, url) => {
934
952
  { status: 200, headers: { 'content-type': 'text/html; charset=utf-8' } }
935
953
  )
936
954
 
937
- if (/^\/AppStream\/apps\.json$/i.test(stream)) return json({ apps: [] })
955
+ if (/^\/(app|AppStream)\/apps\.json$/i.test(stream))
956
+ return json({ apps: [] })
938
957
 
939
- if (/^\/AppStream\//i.test(stream)) {
958
+ if (/^\/(app|AppStream)\//i.test(stream)) {
940
959
  return json(
941
960
  {
942
961
  message:
@@ -948,8 +967,9 @@ const routeRequest = async (request, url) => {
948
967
 
949
968
  // The package's own matcher, so a route is recognised however its path is
950
969
  // cased and its parameters are read the way the document states them.
951
- const matched = API.findRoute(request.method, path)
952
- if (!matched) return json({ message: 'Not part of the API: ' + path }, 404)
970
+ const matched = API.findRoute(request.method, apiPath)
971
+ if (!matched)
972
+ return json({ message: 'Not part of the API: ' + apiPath }, 404)
953
973
 
954
974
  const routeId = matched.route.id
955
975
  const subject = await subjectOf(request, query)
@@ -1023,7 +1043,7 @@ const routeRequest = async (request, url) => {
1023
1043
  // envelope the other routes already answer with.
1024
1044
  if (API.isApiError(e)) {
1025
1045
  if (e.body !== undefined) return json(e.body, e.status)
1026
- if (path.includes('/SASjsApi/drive/')) return text(e.message, e.status)
1046
+ if (apiPath.includes('/SASjsApi/drive/')) return text(e.message, e.status)
1027
1047
  return json({ message: e.message }, e.status)
1028
1048
  }
1029
1049
  return json(
@@ -1079,10 +1099,17 @@ self.addEventListener('fetch', (event) => {
1079
1099
  // The host's own paths are answered here, including one the table does not
1080
1100
  // have - falling through to the static host would put the SPA's index.html
1081
1101
  // behind a typo in a caller's URL, or behind a listing an interface parses as
1082
- // JSON. `/AppStream` is one of those: the package serves app deployments, but
1083
- // the listing is the server's web route, and an interface that lists apps asks
1084
- // for it on every visit.
1085
- if (!/^\/(SASjsApi|SASLogon|AppStream)(\/|$)/i.test(path)) return
1102
+ // JSON. `/app` is one of those: the package serves app deployments, but the
1103
+ // listing is the server's web route, and an interface that lists apps asks for
1104
+ // it on every visit.
1105
+ //
1106
+ // `/api` and `/api/` on their own are the API's documentation page - a file
1107
+ // the build copies into the site - so the worker stays out of the way there
1108
+ // and the static host answers it. Every other `/api/...` is an API call on the
1109
+ // short spelling, which routeRequest canonicalises to `/SASjsApi`.
1110
+ if (/^\/api\/?$/i.test(path)) return
1111
+
1112
+ if (!/^\/(SASjsApi|SASLogon|AppStream|api|app)(\/|$)/i.test(path)) return
1086
1113
  event.respondWith(handle(event.request, url))
1087
1114
  })
1088
1115
 
@@ -173,13 +173,34 @@ describe('page-side bridge', function () {
173
173
  fetchImpl = jest.fn();
174
174
  XHR = loadBridge(fetchImpl).XHR;
175
175
  xhr = new XHR();
176
- xhr.open('GET', '/api/health');
176
+ xhr.open('GET', '/health');
177
177
  xhr.send();
178
178
  expect(xhr.sentWith).toBeUndefined();
179
179
  expect(fetchImpl).not.toHaveBeenCalled();
180
180
  return [2 /*return*/];
181
181
  });
182
182
  }); });
183
+ it('bridges the short API spelling as well as the canonical one', function () { return __awaiter(void 0, void 0, void 0, function () {
184
+ var fetchImpl, XHR, xhr, _a, url;
185
+ return __generator(this, function (_b) {
186
+ switch (_b.label) {
187
+ case 0:
188
+ fetchImpl = jest.fn(function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
189
+ return [2 /*return*/, jsonResponse('{"status":"ok"}')];
190
+ }); }); });
191
+ XHR = loadBridge(fetchImpl).XHR;
192
+ xhr = new XHR();
193
+ return [4 /*yield*/, run(xhr, 'GET', '/api/info')];
194
+ case 1:
195
+ _b.sent();
196
+ _a = __read(fetchImpl.mock.calls[0], 1), url = _a[0];
197
+ expect(url).toBe('/api/info');
198
+ expect(xhr.status).toBe(200);
199
+ expect(xhr.responseText).toBe('{"status":"ok"}');
200
+ return [2 /*return*/];
201
+ }
202
+ });
203
+ }); });
183
204
  it('converts a multipart body to JSON and replays the response onto the XHR', function () { return __awaiter(void 0, void 0, void 0, function () {
184
205
  var fetchImpl, XHR, form, xhr, _a, init;
185
206
  return __generator(this, function (_b) {
@@ -286,7 +307,7 @@ describe('page-side bridge', function () {
286
307
  expect(second.XHR.prototype).not.toBe(first.XHR.prototype);
287
308
  expect(Object.getPrototypeOf(second.XHR.prototype)).toBe(FakeXHR.prototype);
288
309
  var xhr = new second.XHR();
289
- xhr.open('GET', '/api/health');
310
+ xhr.open('GET', '/health');
290
311
  xhr.send();
291
312
  expect(xhr.nativeSendCount).toBe(1);
292
313
  });
@@ -35,6 +35,17 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
35
35
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
36
  }
37
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
+ };
38
49
  var __read = (this && this.__read) || function (o, n) {
39
50
  var m = typeof Symbol === "function" && o[Symbol.iterator];
40
51
  if (!m) return o;
@@ -51,17 +62,6 @@ var __read = (this && this.__read) || function (o, n) {
51
62
  }
52
63
  return ar;
53
64
  };
54
- var __values = (this && this.__values) || function(o) {
55
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
56
- if (m) return m.call(o);
57
- if (o && typeof o.length === "number") return {
58
- next: function () {
59
- if (o && i >= o.length) o = void 0;
60
- return { value: o && o[i++], done: !o };
61
- }
62
- };
63
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
64
- };
65
65
  var __importDefault = (this && this.__importDefault) || function (mod) {
66
66
  return (mod && mod.__esModule) ? mod : { "default": mod };
67
67
  };
@@ -898,51 +898,59 @@ describe('service worker host', function () {
898
898
  });
899
899
  }); });
900
900
  it('answers every route under the folder the site is published in', function () { return __awaiter(void 0, void 0, void 0, function () {
901
- var worker, info, _a, page, folder, stream, landing, apps, _b;
902
- var _c;
903
- return __generator(this, function (_d) {
904
- switch (_d.label) {
901
+ var worker, info, _a, page, folder, stream, landing, apps, _b, aliased, _c;
902
+ var _d;
903
+ return __generator(this, function (_e) {
904
+ switch (_e.label) {
905
905
  case 0:
906
906
  worker = loadWorker('/demo');
907
- worker.runtime.load((_c = {},
908
- _c[drivePath('services/public/getdata.js')] = '_webout = "seeded";',
909
- _c));
907
+ worker.runtime.load((_d = {},
908
+ _d[drivePath('services/public/getdata.js')] = '_webout = "seeded";',
909
+ _d));
910
910
  return [4 /*yield*/, worker.dispatch('/demo/SASjsApi/info')];
911
911
  case 1:
912
- info = _d.sent();
912
+ info = _e.sent();
913
913
  expect(info.status).toBe(200);
914
914
  _a = expect;
915
915
  return [4 /*yield*/, info.json()];
916
916
  case 2:
917
- _a.apply(void 0, [(_d.sent()).mode]).toBe('desktop');
917
+ _a.apply(void 0, [(_e.sent()).mode]).toBe('desktop');
918
918
  return [4 /*yield*/, worker.dispatch('/demo/')];
919
919
  case 3:
920
- page = _d.sent();
920
+ page = _e.sent();
921
921
  expect(page.status).toBe(200);
922
922
  expect(page.headers.get('content-type')).toContain('text/html');
923
923
  return [4 /*yield*/, worker.dispatch('/demo')];
924
924
  case 4:
925
- folder = _d.sent();
925
+ folder = _e.sent();
926
926
  expect(folder.status).toBe(200);
927
927
  expect(folder.headers.get('content-type')).toContain('text/html');
928
928
  return [4 /*yield*/, worker.dispatch('/demo/AppStream')];
929
929
  case 5:
930
- stream = _d.sent();
930
+ stream = _e.sent();
931
931
  expect(stream.status).toBe(301);
932
- expect(stream.headers.get('location')).toBe('/demo/AppStream/');
933
- return [4 /*yield*/, worker.dispatch('/demo/AppStream/')];
932
+ expect(stream.headers.get('location')).toBe('/demo/app');
933
+ return [4 /*yield*/, worker.dispatch('/demo/app')];
934
934
  case 6:
935
- landing = _d.sent();
935
+ landing = _e.sent();
936
936
  expect(landing.status).toBe(200);
937
937
  expect(landing.headers.get('content-type')).toContain('text/html');
938
- return [4 /*yield*/, worker.dispatch('/demo/AppStream/apps.json')];
938
+ return [4 /*yield*/, worker.dispatch('/demo/app/apps.json')];
939
939
  case 7:
940
- apps = _d.sent();
940
+ apps = _e.sent();
941
941
  expect(apps.status).toBe(200);
942
942
  _b = expect;
943
943
  return [4 /*yield*/, apps.json()];
944
944
  case 8:
945
- _b.apply(void 0, [_d.sent()]).toEqual({ apps: [] });
945
+ _b.apply(void 0, [_e.sent()]).toEqual({ apps: [] });
946
+ return [4 /*yield*/, worker.dispatch('/demo/api/info')];
947
+ case 9:
948
+ aliased = _e.sent();
949
+ expect(aliased.status).toBe(200);
950
+ _c = expect;
951
+ return [4 /*yield*/, aliased.json()];
952
+ case 10:
953
+ _c.apply(void 0, [(_e.sent()).mode]).toBe('desktop');
946
954
  // a path outside the folder is not the site's to answer
947
955
  expect(worker.dispatch('/other/SASjsApi/info')).toBeUndefined();
948
956
  return [2 /*return*/];
@@ -1333,42 +1341,157 @@ describe('service worker host', function () {
1333
1341
  }
1334
1342
  });
1335
1343
  }); });
1336
- it('answers the app stream as the server does, with nothing in it', function () { return __awaiter(void 0, void 0, void 0, function () {
1337
- var dispatch, listing, _a, root, landing, _b, app, _c;
1338
- return __generator(this, function (_d) {
1339
- switch (_d.label) {
1344
+ it('answers the app stream on the short path, and the canonical one as an alias', function () { return __awaiter(void 0, void 0, void 0, function () {
1345
+ var dispatch, _a, _b, path_2, listing, _c, e_1_1, _d, _e, path_3, landing, _f, e_2_1, root, canonicalLanding, _g, _h, _j, path_4, app, _k, e_3_1;
1346
+ var e_1, _l, e_2, _m, e_3, _o;
1347
+ return __generator(this, function (_p) {
1348
+ switch (_p.label) {
1340
1349
  case 0:
1341
1350
  dispatch = seeded().dispatch;
1342
- return [4 /*yield*/, dispatch('/AppStream/apps.json')];
1351
+ _p.label = 1;
1343
1352
  case 1:
1344
- listing = _d.sent();
1345
- expect(listing.status).toBe(200);
1346
- _a = expect;
1347
- return [4 /*yield*/, listing.json()];
1353
+ _p.trys.push([1, 7, 8, 9]);
1354
+ _a = __values(['/app/apps.json', '/AppStream/apps.json']), _b = _a.next();
1355
+ _p.label = 2;
1348
1356
  case 2:
1349
- _a.apply(void 0, [_d.sent()]).toEqual({ apps: [] });
1350
- return [4 /*yield*/, dispatch('/AppStream')];
1357
+ if (!!_b.done) return [3 /*break*/, 6];
1358
+ path_2 = _b.value;
1359
+ return [4 /*yield*/, dispatch(path_2)];
1351
1360
  case 3:
1352
- root = _d.sent();
1353
- expect(root.status).toBe(301);
1354
- expect(root.headers.get('location')).toBe('/AppStream/');
1355
- return [4 /*yield*/, dispatch('/AppStream/')];
1361
+ listing = _p.sent();
1362
+ expect(listing.status).toBe(200);
1363
+ _c = expect;
1364
+ return [4 /*yield*/, listing.json()];
1356
1365
  case 4:
1357
- landing = _d.sent();
1366
+ _c.apply(void 0, [_p.sent()]).toEqual({ apps: [] });
1367
+ _p.label = 5;
1368
+ case 5:
1369
+ _b = _a.next();
1370
+ return [3 /*break*/, 2];
1371
+ case 6: return [3 /*break*/, 9];
1372
+ case 7:
1373
+ e_1_1 = _p.sent();
1374
+ e_1 = { error: e_1_1 };
1375
+ return [3 /*break*/, 9];
1376
+ case 8:
1377
+ try {
1378
+ if (_b && !_b.done && (_l = _a.return)) _l.call(_a);
1379
+ }
1380
+ finally { if (e_1) throw e_1.error; }
1381
+ return [7 /*endfinally*/];
1382
+ case 9:
1383
+ _p.trys.push([9, 15, 16, 17]);
1384
+ _d = __values(['/app', '/app/', '/app/index.html']), _e = _d.next();
1385
+ _p.label = 10;
1386
+ case 10:
1387
+ if (!!_e.done) return [3 /*break*/, 14];
1388
+ path_3 = _e.value;
1389
+ return [4 /*yield*/, dispatch(path_3)];
1390
+ case 11:
1391
+ landing = _p.sent();
1358
1392
  expect(landing.status).toBe(200);
1359
1393
  expect(landing.headers.get('content-type')).toContain('text/html');
1360
- _b = expect;
1394
+ _f = expect;
1361
1395
  return [4 /*yield*/, landing.text()];
1362
- case 5:
1363
- _b.apply(void 0, [_d.sent()]).toContain('serves no apps');
1364
- return [4 /*yield*/, dispatch('/AppStream/Demo/')];
1365
- case 6:
1366
- app = _d.sent();
1396
+ case 12:
1397
+ _f.apply(void 0, [_p.sent()]).toContain('serves no apps');
1398
+ _p.label = 13;
1399
+ case 13:
1400
+ _e = _d.next();
1401
+ return [3 /*break*/, 10];
1402
+ case 14: return [3 /*break*/, 17];
1403
+ case 15:
1404
+ e_2_1 = _p.sent();
1405
+ e_2 = { error: e_2_1 };
1406
+ return [3 /*break*/, 17];
1407
+ case 16:
1408
+ try {
1409
+ if (_e && !_e.done && (_m = _d.return)) _m.call(_d);
1410
+ }
1411
+ finally { if (e_2) throw e_2.error; }
1412
+ return [7 /*endfinally*/];
1413
+ case 17: return [4 /*yield*/, dispatch('/AppStream')];
1414
+ case 18:
1415
+ root = _p.sent();
1416
+ expect(root.status).toBe(301);
1417
+ expect(root.headers.get('location')).toBe('/app');
1418
+ return [4 /*yield*/, dispatch('/AppStream/')];
1419
+ case 19:
1420
+ canonicalLanding = _p.sent();
1421
+ expect(canonicalLanding.status).toBe(200);
1422
+ _g = expect;
1423
+ return [4 /*yield*/, canonicalLanding.text()];
1424
+ case 20:
1425
+ _g.apply(void 0, [_p.sent()]).toContain('serves no apps');
1426
+ _p.label = 21;
1427
+ case 21:
1428
+ _p.trys.push([21, 27, 28, 29]);
1429
+ _h = __values(['/app/Demo/', '/AppStream/Demo/']), _j = _h.next();
1430
+ _p.label = 22;
1431
+ case 22:
1432
+ if (!!_j.done) return [3 /*break*/, 26];
1433
+ path_4 = _j.value;
1434
+ return [4 /*yield*/, dispatch(path_4)];
1435
+ case 23:
1436
+ app = _p.sent();
1367
1437
  expect(app.status).toBe(404);
1368
- _c = expect;
1438
+ _k = expect;
1369
1439
  return [4 /*yield*/, app.json()];
1370
- case 7:
1371
- _c.apply(void 0, [(_d.sent()).message]).toContain('serves no apps');
1440
+ case 24:
1441
+ _k.apply(void 0, [(_p.sent()).message]).toContain('serves no apps');
1442
+ _p.label = 25;
1443
+ case 25:
1444
+ _j = _h.next();
1445
+ return [3 /*break*/, 22];
1446
+ case 26: return [3 /*break*/, 29];
1447
+ case 27:
1448
+ e_3_1 = _p.sent();
1449
+ e_3 = { error: e_3_1 };
1450
+ return [3 /*break*/, 29];
1451
+ case 28:
1452
+ try {
1453
+ if (_j && !_j.done && (_o = _h.return)) _o.call(_h);
1454
+ }
1455
+ finally { if (e_3) throw e_3.error; }
1456
+ return [7 /*endfinally*/];
1457
+ case 29: return [2 /*return*/];
1458
+ }
1459
+ });
1460
+ }); });
1461
+ it('answers the API on /api as well as on /SASjsApi', function () { return __awaiter(void 0, void 0, void 0, function () {
1462
+ var dispatch, canonical, short, _a, _b, _c, missing, _d;
1463
+ return __generator(this, function (_e) {
1464
+ switch (_e.label) {
1465
+ case 0:
1466
+ dispatch = seeded().dispatch;
1467
+ return [4 /*yield*/, dispatch('/SASjsApi/info')];
1468
+ case 1:
1469
+ canonical = _e.sent();
1470
+ return [4 /*yield*/, dispatch('/api/info')];
1471
+ case 2:
1472
+ short = _e.sent();
1473
+ expect(short.status).toBe(200);
1474
+ _b = expect;
1475
+ return [4 /*yield*/, short.json()];
1476
+ case 3:
1477
+ _c = (_a = _b.apply(void 0, [_e.sent()])).toEqual;
1478
+ return [4 /*yield*/, canonical.json()];
1479
+ case 4:
1480
+ _c.apply(_a, [_e.sent()]);
1481
+ return [4 /*yield*/, dispatch('/api/drive/file?_filePath=' + encodeURIComponent('/missing.txt'))];
1482
+ case 5:
1483
+ missing = _e.sent();
1484
+ expect(missing.status).toBe(404);
1485
+ expect(missing.headers.get('content-type')).toContain('text/plain');
1486
+ _d = expect;
1487
+ return [4 /*yield*/, missing.text()];
1488
+ case 6:
1489
+ _d.apply(void 0, [_e.sent()]).toBe("File doesn't exist.");
1490
+ // The documentation page is a file the build copies into the site, so the
1491
+ // worker leaves `/api` and `/api/` to the static host instead of answering
1492
+ // them as routes.
1493
+ expect(dispatch('/api')).toBeUndefined();
1494
+ expect(dispatch('/api/')).toBeUndefined();
1372
1495
  return [2 /*return*/];
1373
1496
  }
1374
1497
  });
@@ -2223,7 +2346,7 @@ describe('service worker host', function () {
2223
2346
  }); });
2224
2347
  });
2225
2348
  describe('conformance corpus', function () {
2226
- var e_1, _a;
2349
+ var e_4, _a;
2227
2350
  /**
2228
2351
  * The corpus is what "the same API" means: the cases @sasjs/api runs against
2229
2352
  * its own services, and against a live sasjs/server, run here against this
@@ -2232,7 +2355,7 @@ describe('service worker host', function () {
2232
2355
  * used to have - and it is a test rather than a review.
2233
2356
  */
2234
2357
  var httpFor = function (testCase) {
2235
- var e_2, _a;
2358
+ var e_5, _a;
2236
2359
  var _b;
2237
2360
  var _c = __read(testCase.route.split(' '), 2), method = _c[0], routePath = _c[1];
2238
2361
  var query = new URLSearchParams();
@@ -2243,12 +2366,12 @@ describe('service worker host', function () {
2243
2366
  query.set(key, String(value));
2244
2367
  }
2245
2368
  }
2246
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
2369
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
2247
2370
  finally {
2248
2371
  try {
2249
2372
  if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
2250
2373
  }
2251
- finally { if (e_2) throw e_2.error; }
2374
+ finally { if (e_5) throw e_5.error; }
2252
2375
  }
2253
2376
  var suffix = query.toString() ? "?".concat(query) : '';
2254
2377
  var init = { method: method };
@@ -2279,8 +2402,8 @@ describe('service worker host', function () {
2279
2402
  * does.
2280
2403
  */
2281
2404
  var seedDrive = function (runtime, testCase) { return __awaiter(void 0, void 0, void 0, function () {
2282
- var text, _a, _b, _c, file, contents, _d, _e, _f, file, contents, e_3_1;
2283
- var e_4, _g, e_3, _h;
2405
+ var text, _a, _b, _c, file, contents, _d, _e, _f, file, contents, e_6_1;
2406
+ var e_7, _g, e_6, _h;
2284
2407
  return __generator(this, function (_j) {
2285
2408
  switch (_j.label) {
2286
2409
  case 0:
@@ -2292,12 +2415,12 @@ describe('service worker host', function () {
2292
2415
  text["/sasjs/drive/files".concat(file)] = contents;
2293
2416
  }
2294
2417
  }
2295
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
2418
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
2296
2419
  finally {
2297
2420
  try {
2298
2421
  if (_b && !_b.done && (_g = _a.return)) _g.call(_a);
2299
2422
  }
2300
- finally { if (e_4) throw e_4.error; }
2423
+ finally { if (e_7) throw e_7.error; }
2301
2424
  }
2302
2425
  return [4 /*yield*/, runtime.load(text)];
2303
2426
  case 1:
@@ -2320,14 +2443,14 @@ describe('service worker host', function () {
2320
2443
  return [3 /*break*/, 3];
2321
2444
  case 6: return [3 /*break*/, 9];
2322
2445
  case 7:
2323
- e_3_1 = _j.sent();
2324
- e_3 = { error: e_3_1 };
2446
+ e_6_1 = _j.sent();
2447
+ e_6 = { error: e_6_1 };
2325
2448
  return [3 /*break*/, 9];
2326
2449
  case 8:
2327
2450
  try {
2328
2451
  if (_e && !_e.done && (_h = _d.return)) _h.call(_d);
2329
2452
  }
2330
- finally { if (e_3) throw e_3.error; }
2453
+ finally { if (e_6) throw e_6.error; }
2331
2454
  return [7 /*endfinally*/];
2332
2455
  case 9: return [2 /*return*/];
2333
2456
  }
@@ -2395,12 +2518,12 @@ describe('service worker host', function () {
2395
2518
  _loop_1(testCase);
2396
2519
  }
2397
2520
  }
2398
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
2521
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
2399
2522
  finally {
2400
2523
  try {
2401
2524
  if (DRIVE_CORPUS_1_1 && !DRIVE_CORPUS_1_1.done && (_a = DRIVE_CORPUS_1.return)) _a.call(DRIVE_CORPUS_1);
2402
2525
  }
2403
- finally { if (e_1) throw e_1.error; }
2526
+ finally { if (e_4) throw e_4.error; }
2404
2527
  }
2405
2528
  });
2406
2529
  });
package/package.json CHANGED
@@ -125,5 +125,5 @@
125
125
  "ws": "8.21.0",
126
126
  "nanoid": "3.3.18"
127
127
  },
128
- "version": "6.19.4"
128
+ "version": "6.20.0"
129
129
  }