@backstage/backend-test-utils 0.3.8-next.2 → 0.3.9-next.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/CHANGELOG.md +28 -0
- package/dist/index.cjs.js +275 -479
- package/dist/index.cjs.js.map +1 -1
- package/package.json +7 -7
package/dist/index.cjs.js
CHANGED
|
@@ -6,11 +6,11 @@ var crypto = require('crypto');
|
|
|
6
6
|
var createConnection = require('knex');
|
|
7
7
|
var uuid = require('uuid');
|
|
8
8
|
var os = require('os');
|
|
9
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
9
10
|
var fs = require('fs-extra');
|
|
10
11
|
var textextensions = require('textextensions');
|
|
11
12
|
var path = require('path');
|
|
12
13
|
var backendAppApi = require('@backstage/backend-app-api');
|
|
13
|
-
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
14
14
|
var errors = require('@backstage/errors');
|
|
15
15
|
var cookie = require('cookie');
|
|
16
16
|
var pluginEventsNode = require('@backstage/plugin-events-node');
|
|
@@ -29,14 +29,13 @@ function isDockerDisabledForTests() {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
async function waitForMysqlReady(connection) {
|
|
32
|
-
var _a;
|
|
33
32
|
const startTime = Date.now();
|
|
34
33
|
const db = createConnection__default.default({ client: "mysql2", connection });
|
|
35
34
|
try {
|
|
36
35
|
for (; ; ) {
|
|
37
36
|
try {
|
|
38
37
|
const result = await db.select(db.raw("version() AS version"));
|
|
39
|
-
if (
|
|
38
|
+
if (result[0]?.version) {
|
|
40
39
|
return;
|
|
41
40
|
}
|
|
42
41
|
} catch (e) {
|
|
@@ -67,14 +66,13 @@ async function startMysqlContainer(image) {
|
|
|
67
66
|
}
|
|
68
67
|
|
|
69
68
|
async function waitForPostgresReady(connection) {
|
|
70
|
-
var _a;
|
|
71
69
|
const startTime = Date.now();
|
|
72
70
|
const db = createConnection__default.default({ client: "pg", connection });
|
|
73
71
|
try {
|
|
74
72
|
for (; ; ) {
|
|
75
73
|
try {
|
|
76
74
|
const result = await db.select(db.raw("version()"));
|
|
77
|
-
if (Array.isArray(result) &&
|
|
75
|
+
if (Array.isArray(result) && result[0]?.version) {
|
|
78
76
|
return;
|
|
79
77
|
}
|
|
80
78
|
} catch (e) {
|
|
@@ -163,25 +161,16 @@ const allDatabases = Object.freeze({
|
|
|
163
161
|
}
|
|
164
162
|
});
|
|
165
163
|
|
|
166
|
-
var __defProp$3 = Object.defineProperty;
|
|
167
|
-
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
168
|
-
var __publicField$3 = (obj, key, value) => {
|
|
169
|
-
__defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
170
|
-
return value;
|
|
171
|
-
};
|
|
172
164
|
const LARGER_POOL_CONFIG = {
|
|
173
165
|
pool: {
|
|
174
166
|
min: 0,
|
|
175
167
|
max: 50
|
|
176
168
|
}
|
|
177
169
|
};
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
this.instanceById = /* @__PURE__ */ new Map();
|
|
183
|
-
this.supportedIds = supportedIds;
|
|
184
|
-
}
|
|
170
|
+
class TestDatabases {
|
|
171
|
+
instanceById;
|
|
172
|
+
supportedIds;
|
|
173
|
+
static defaultIds;
|
|
185
174
|
/**
|
|
186
175
|
* Creates an empty `TestDatabases` instance, and sets up Jest to clean up
|
|
187
176
|
* all of its acquired resources after all tests finish.
|
|
@@ -194,14 +183,13 @@ const _TestDatabases = class _TestDatabases {
|
|
|
194
183
|
* is very fast.
|
|
195
184
|
*/
|
|
196
185
|
static create(options) {
|
|
197
|
-
|
|
198
|
-
const
|
|
199
|
-
const disableDocker = (_a = options == null ? void 0 : options.disableDocker) != null ? _a : isDockerDisabledForTests();
|
|
186
|
+
const ids = options?.ids;
|
|
187
|
+
const disableDocker = options?.disableDocker ?? isDockerDisabledForTests();
|
|
200
188
|
let testDatabaseIds;
|
|
201
189
|
if (ids) {
|
|
202
190
|
testDatabaseIds = ids;
|
|
203
|
-
} else if (
|
|
204
|
-
testDatabaseIds =
|
|
191
|
+
} else if (TestDatabases.defaultIds) {
|
|
192
|
+
testDatabaseIds = TestDatabases.defaultIds;
|
|
205
193
|
} else {
|
|
206
194
|
testDatabaseIds = Object.keys(allDatabases);
|
|
207
195
|
}
|
|
@@ -221,7 +209,7 @@ const _TestDatabases = class _TestDatabases {
|
|
|
221
209
|
}
|
|
222
210
|
return true;
|
|
223
211
|
});
|
|
224
|
-
const databases = new
|
|
212
|
+
const databases = new TestDatabases(supportedIds);
|
|
225
213
|
if (supportedIds.length > 0) {
|
|
226
214
|
afterAll(async () => {
|
|
227
215
|
await databases.shutdown();
|
|
@@ -230,7 +218,11 @@ const _TestDatabases = class _TestDatabases {
|
|
|
230
218
|
return databases;
|
|
231
219
|
}
|
|
232
220
|
static setDefaults(options) {
|
|
233
|
-
|
|
221
|
+
TestDatabases.defaultIds = options.ids;
|
|
222
|
+
}
|
|
223
|
+
constructor(supportedIds) {
|
|
224
|
+
this.instanceById = /* @__PURE__ */ new Map();
|
|
225
|
+
this.supportedIds = supportedIds;
|
|
234
226
|
}
|
|
235
227
|
supports(id) {
|
|
236
228
|
return this.supportedIds.includes(id);
|
|
@@ -396,14 +388,14 @@ const _TestDatabases = class _TestDatabases {
|
|
|
396
388
|
}
|
|
397
389
|
}
|
|
398
390
|
try {
|
|
399
|
-
await
|
|
391
|
+
await dropDatabases?.();
|
|
400
392
|
} catch (error) {
|
|
401
393
|
console.warn(`TestDatabases: Failed to drop databases`, {
|
|
402
394
|
error
|
|
403
395
|
});
|
|
404
396
|
}
|
|
405
397
|
try {
|
|
406
|
-
await
|
|
398
|
+
await stopContainer?.();
|
|
407
399
|
} catch (error) {
|
|
408
400
|
console.warn(`TestDatabases: Failed to stop container`, {
|
|
409
401
|
databaseManager,
|
|
@@ -412,9 +404,7 @@ const _TestDatabases = class _TestDatabases {
|
|
|
412
404
|
}
|
|
413
405
|
}
|
|
414
406
|
}
|
|
415
|
-
}
|
|
416
|
-
__publicField$3(_TestDatabases, "defaultIds");
|
|
417
|
-
let TestDatabases = _TestDatabases;
|
|
407
|
+
}
|
|
418
408
|
|
|
419
409
|
function setupRequestMockHandlers(worker) {
|
|
420
410
|
beforeAll(() => worker.listen({ onUnhandledRequest: "error" }));
|
|
@@ -422,63 +412,27 @@ function setupRequestMockHandlers(worker) {
|
|
|
422
412
|
afterEach(() => worker.resetHandlers());
|
|
423
413
|
}
|
|
424
414
|
|
|
425
|
-
var __defProp$2 = Object.defineProperty;
|
|
426
|
-
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
427
|
-
var __publicField$2 = (obj, key, value) => {
|
|
428
|
-
__defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
429
|
-
return value;
|
|
430
|
-
};
|
|
431
|
-
var __accessCheck$5 = (obj, member, msg) => {
|
|
432
|
-
if (!member.has(obj))
|
|
433
|
-
throw TypeError("Cannot " + msg);
|
|
434
|
-
};
|
|
435
|
-
var __privateGet$5 = (obj, member, getter) => {
|
|
436
|
-
__accessCheck$5(obj, member, "read from private field");
|
|
437
|
-
return member.get(obj);
|
|
438
|
-
};
|
|
439
|
-
var __privateAdd$5 = (obj, member, value) => {
|
|
440
|
-
if (member.has(obj))
|
|
441
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
442
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
443
|
-
};
|
|
444
|
-
var __privateSet$5 = (obj, member, value, setter) => {
|
|
445
|
-
__accessCheck$5(obj, member, "write to private field");
|
|
446
|
-
member.set(obj, value);
|
|
447
|
-
return value;
|
|
448
|
-
};
|
|
449
|
-
var __privateMethod$4 = (obj, member, method) => {
|
|
450
|
-
__accessCheck$5(obj, member, "access private method");
|
|
451
|
-
return method;
|
|
452
|
-
};
|
|
453
|
-
var _root, _transformInput, transformInput_fn;
|
|
454
415
|
const tmpdirMarker = Symbol("os-tmpdir-mock");
|
|
455
416
|
class MockDirectoryImpl {
|
|
417
|
+
#root;
|
|
456
418
|
constructor(root) {
|
|
457
|
-
|
|
458
|
-
__privateAdd$5(this, _root, void 0);
|
|
459
|
-
__publicField$2(this, "clear", () => {
|
|
460
|
-
this.setContent({});
|
|
461
|
-
});
|
|
462
|
-
__publicField$2(this, "remove", () => {
|
|
463
|
-
fs__default.default.rmSync(__privateGet$5(this, _root), { recursive: true, force: true, maxRetries: 10 });
|
|
464
|
-
});
|
|
465
|
-
__privateSet$5(this, _root, root);
|
|
419
|
+
this.#root = root;
|
|
466
420
|
}
|
|
467
421
|
get path() {
|
|
468
|
-
return
|
|
422
|
+
return this.#root;
|
|
469
423
|
}
|
|
470
424
|
resolve(...paths) {
|
|
471
|
-
return path.resolve(
|
|
425
|
+
return path.resolve(this.#root, ...paths);
|
|
472
426
|
}
|
|
473
427
|
setContent(root) {
|
|
474
428
|
this.remove();
|
|
475
429
|
return this.addContent(root);
|
|
476
430
|
}
|
|
477
431
|
addContent(root) {
|
|
478
|
-
const entries =
|
|
432
|
+
const entries = this.#transformInput(root);
|
|
479
433
|
for (const entry of entries) {
|
|
480
|
-
const fullPath = path.resolve(
|
|
481
|
-
if (!
|
|
434
|
+
const fullPath = path.resolve(this.#root, entry.path);
|
|
435
|
+
if (!backendPluginApi.isChildPath(this.#root, fullPath)) {
|
|
482
436
|
throw new Error(
|
|
483
437
|
`Provided path must resolve to a child path of the mock directory, got '${fullPath}'`
|
|
484
438
|
);
|
|
@@ -500,10 +454,9 @@ class MockDirectoryImpl {
|
|
|
500
454
|
}
|
|
501
455
|
}
|
|
502
456
|
content(options) {
|
|
503
|
-
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
if (!backendCommon.isChildPath(__privateGet$5(this, _root), root)) {
|
|
457
|
+
const shouldReadAsText = (typeof options?.shouldReadAsText === "boolean" ? () => options?.shouldReadAsText : options?.shouldReadAsText) ?? ((path$1) => textextensions__default.default.includes(path.extname(path$1).slice(1)));
|
|
458
|
+
const root = path.resolve(this.#root, options?.path ?? "");
|
|
459
|
+
if (!backendPluginApi.isChildPath(this.#root, root)) {
|
|
507
460
|
throw new Error(
|
|
508
461
|
`Provided path must resolve to a child path of the mock directory, got '${root}'`
|
|
509
462
|
);
|
|
@@ -530,37 +483,41 @@ class MockDirectoryImpl {
|
|
|
530
483
|
}
|
|
531
484
|
return read(root);
|
|
532
485
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
486
|
+
clear = () => {
|
|
487
|
+
this.setContent({});
|
|
488
|
+
};
|
|
489
|
+
remove = () => {
|
|
490
|
+
fs__default.default.rmSync(this.#root, { recursive: true, force: true, maxRetries: 10 });
|
|
491
|
+
};
|
|
492
|
+
#transformInput(input) {
|
|
493
|
+
const entries = [];
|
|
494
|
+
function traverse(node, path) {
|
|
495
|
+
if (typeof node === "string") {
|
|
496
|
+
entries.push({
|
|
497
|
+
type: "file",
|
|
498
|
+
path,
|
|
499
|
+
content: Buffer.from(node, "utf8")
|
|
500
|
+
});
|
|
501
|
+
} else if (node instanceof Buffer) {
|
|
502
|
+
entries.push({ type: "file", path, content: node });
|
|
503
|
+
} else if (typeof node === "function") {
|
|
504
|
+
entries.push({ type: "callback", path, callback: node });
|
|
505
|
+
} else {
|
|
506
|
+
entries.push({ type: "dir", path });
|
|
507
|
+
for (const [name, child] of Object.entries(node)) {
|
|
508
|
+
traverse(child, path ? `${path}/${name}` : name);
|
|
509
|
+
}
|
|
553
510
|
}
|
|
554
511
|
}
|
|
512
|
+
traverse(input, "");
|
|
513
|
+
return entries;
|
|
555
514
|
}
|
|
556
|
-
|
|
557
|
-
return entries;
|
|
558
|
-
};
|
|
515
|
+
}
|
|
559
516
|
function createMockDirectory(options) {
|
|
560
517
|
const tmpDir = process.env.RUNNER_TEMP || os__default.default.tmpdir();
|
|
561
518
|
const root = fs__default.default.mkdtempSync(path.join(tmpDir, "backstage-tmp-test-dir-"));
|
|
562
519
|
const mocker = new MockDirectoryImpl(root);
|
|
563
|
-
const origTmpdir =
|
|
520
|
+
const origTmpdir = options?.mockOsTmpDir ? os__default.default.tmpdir : void 0;
|
|
564
521
|
if (origTmpdir) {
|
|
565
522
|
if (Object.hasOwn(origTmpdir, tmpdirMarker)) {
|
|
566
523
|
throw new Error(
|
|
@@ -585,7 +542,7 @@ function createMockDirectory(options) {
|
|
|
585
542
|
});
|
|
586
543
|
} catch {
|
|
587
544
|
}
|
|
588
|
-
if (options
|
|
545
|
+
if (options?.content) {
|
|
589
546
|
mocker.setContent(options.content);
|
|
590
547
|
}
|
|
591
548
|
return mocker;
|
|
@@ -604,29 +561,6 @@ class MockIdentityService {
|
|
|
604
561
|
}
|
|
605
562
|
}
|
|
606
563
|
|
|
607
|
-
var __accessCheck$4 = (obj, member, msg) => {
|
|
608
|
-
if (!member.has(obj))
|
|
609
|
-
throw TypeError("Cannot " + msg);
|
|
610
|
-
};
|
|
611
|
-
var __privateGet$4 = (obj, member, getter) => {
|
|
612
|
-
__accessCheck$4(obj, member, "read from private field");
|
|
613
|
-
return member.get(obj);
|
|
614
|
-
};
|
|
615
|
-
var __privateAdd$4 = (obj, member, value) => {
|
|
616
|
-
if (member.has(obj))
|
|
617
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
618
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
619
|
-
};
|
|
620
|
-
var __privateSet$4 = (obj, member, value, setter) => {
|
|
621
|
-
__accessCheck$4(obj, member, "write to private field");
|
|
622
|
-
member.set(obj, value);
|
|
623
|
-
return value;
|
|
624
|
-
};
|
|
625
|
-
var __privateMethod$3 = (obj, member, method) => {
|
|
626
|
-
__accessCheck$4(obj, member, "access private method");
|
|
627
|
-
return method;
|
|
628
|
-
};
|
|
629
|
-
var _level, _meta, _log, log_fn;
|
|
630
564
|
const levels = {
|
|
631
565
|
none: 0,
|
|
632
566
|
error: 1,
|
|
@@ -634,50 +568,43 @@ const levels = {
|
|
|
634
568
|
info: 3,
|
|
635
569
|
debug: 4
|
|
636
570
|
};
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
__privateAdd$4(this, _level, void 0);
|
|
641
|
-
__privateAdd$4(this, _meta, void 0);
|
|
642
|
-
__privateSet$4(this, _level, level);
|
|
643
|
-
__privateSet$4(this, _meta, meta);
|
|
644
|
-
}
|
|
571
|
+
class MockRootLoggerService {
|
|
572
|
+
#level;
|
|
573
|
+
#meta;
|
|
645
574
|
static create(options) {
|
|
646
|
-
|
|
647
|
-
const level = (_a = options == null ? void 0 : options.level) != null ? _a : "none";
|
|
575
|
+
const level = options?.level ?? "none";
|
|
648
576
|
if (!(level in levels)) {
|
|
649
577
|
throw new Error(`Invalid log level '${level}'`);
|
|
650
578
|
}
|
|
651
|
-
return new
|
|
579
|
+
return new MockRootLoggerService(levels[level], {});
|
|
652
580
|
}
|
|
653
581
|
error(message, meta) {
|
|
654
|
-
|
|
582
|
+
this.#log("error", message, meta);
|
|
655
583
|
}
|
|
656
584
|
warn(message, meta) {
|
|
657
|
-
|
|
585
|
+
this.#log("warn", message, meta);
|
|
658
586
|
}
|
|
659
587
|
info(message, meta) {
|
|
660
|
-
|
|
588
|
+
this.#log("info", message, meta);
|
|
661
589
|
}
|
|
662
590
|
debug(message, meta) {
|
|
663
|
-
|
|
591
|
+
this.#log("debug", message, meta);
|
|
664
592
|
}
|
|
665
593
|
child(meta) {
|
|
666
|
-
return new
|
|
594
|
+
return new MockRootLoggerService(this.#level, { ...this.#meta, ...meta });
|
|
667
595
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
_log = new WeakSet();
|
|
672
|
-
log_fn = function(level, message, meta) {
|
|
673
|
-
var _a;
|
|
674
|
-
const levelValue = (_a = levels[level]) != null ? _a : 0;
|
|
675
|
-
if (levelValue <= __privateGet$4(this, _level)) {
|
|
676
|
-
const labels = Object.entries(__privateGet$4(this, _meta)).map(([key, value]) => `${key}=${value}`).join(",");
|
|
677
|
-
console[level](`${labels} ${message}`, meta);
|
|
596
|
+
constructor(level, meta) {
|
|
597
|
+
this.#level = level;
|
|
598
|
+
this.#meta = meta;
|
|
678
599
|
}
|
|
679
|
-
|
|
680
|
-
|
|
600
|
+
#log(level, message, meta) {
|
|
601
|
+
const levelValue = levels[level] ?? 0;
|
|
602
|
+
if (levelValue <= this.#level) {
|
|
603
|
+
const labels = Object.entries(this.#meta).map(([key, value]) => `${key}=${value}`).join(",");
|
|
604
|
+
console[level](`${labels} ${message}`, meta);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
681
608
|
|
|
682
609
|
const DEFAULT_MOCK_USER_ENTITY_REF = "user:default/mock";
|
|
683
610
|
const DEFAULT_MOCK_SERVICE_SUBJECT = "external:test-service";
|
|
@@ -781,7 +708,7 @@ exports.mockCredentials = void 0;
|
|
|
781
708
|
function token(options) {
|
|
782
709
|
if (options) {
|
|
783
710
|
const { targetPluginId, onBehalfOf } = options;
|
|
784
|
-
const oboPrincipal = onBehalfOf
|
|
711
|
+
const oboPrincipal = onBehalfOf?.principal;
|
|
785
712
|
const obo = oboPrincipal.type === "user" ? oboPrincipal.userEntityRef : void 0;
|
|
786
713
|
const subject = oboPrincipal.type === "service" ? oboPrincipal.subject : void 0;
|
|
787
714
|
return `${MOCK_SERVICE_TOKEN_PREFIX}${JSON.stringify({
|
|
@@ -808,16 +735,10 @@ exports.mockCredentials = void 0;
|
|
|
808
735
|
})(service = mockCredentials2.service || (mockCredentials2.service = {}));
|
|
809
736
|
})(exports.mockCredentials || (exports.mockCredentials = {}));
|
|
810
737
|
|
|
811
|
-
var __defProp$1 = Object.defineProperty;
|
|
812
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
813
|
-
var __publicField$1 = (obj, key, value) => {
|
|
814
|
-
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
815
|
-
return value;
|
|
816
|
-
};
|
|
817
738
|
class MockAuthService {
|
|
739
|
+
pluginId;
|
|
740
|
+
disableDefaultAuthPolicy;
|
|
818
741
|
constructor(options) {
|
|
819
|
-
__publicField$1(this, "pluginId");
|
|
820
|
-
__publicField$1(this, "disableDefaultAuthPolicy");
|
|
821
742
|
this.pluginId = options.pluginId;
|
|
822
743
|
this.disableDefaultAuthPolicy = options.disableDefaultAuthPolicy;
|
|
823
744
|
}
|
|
@@ -843,7 +764,7 @@ class MockAuthService {
|
|
|
843
764
|
return exports.mockCredentials.user(userEntityRef);
|
|
844
765
|
}
|
|
845
766
|
if (token.startsWith(MOCK_USER_LIMITED_TOKEN_PREFIX)) {
|
|
846
|
-
if (!
|
|
767
|
+
if (!options?.allowLimitedAccess) {
|
|
847
768
|
throw new errors.AuthenticationError("Limited user token is not allowed");
|
|
848
769
|
}
|
|
849
770
|
const { sub: userEntityRef } = JSON.parse(
|
|
@@ -918,60 +839,63 @@ class MockAuthService {
|
|
|
918
839
|
}
|
|
919
840
|
}
|
|
920
841
|
|
|
921
|
-
var __accessCheck$3 = (obj, member, msg) => {
|
|
922
|
-
if (!member.has(obj))
|
|
923
|
-
throw TypeError("Cannot " + msg);
|
|
924
|
-
};
|
|
925
|
-
var __privateGet$3 = (obj, member, getter) => {
|
|
926
|
-
__accessCheck$3(obj, member, "read from private field");
|
|
927
|
-
return member.get(obj);
|
|
928
|
-
};
|
|
929
|
-
var __privateAdd$3 = (obj, member, value) => {
|
|
930
|
-
if (member.has(obj))
|
|
931
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
932
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
933
|
-
};
|
|
934
|
-
var __privateSet$3 = (obj, member, value, setter) => {
|
|
935
|
-
__accessCheck$3(obj, member, "write to private field");
|
|
936
|
-
member.set(obj, value);
|
|
937
|
-
return value;
|
|
938
|
-
};
|
|
939
|
-
var __privateMethod$2 = (obj, member, method) => {
|
|
940
|
-
__accessCheck$3(obj, member, "access private method");
|
|
941
|
-
return method;
|
|
942
|
-
};
|
|
943
|
-
var _auth, _defaultCredentials, _getCredentials, getCredentials_fn;
|
|
944
842
|
class MockHttpAuthService {
|
|
843
|
+
#auth;
|
|
844
|
+
#defaultCredentials;
|
|
945
845
|
constructor(pluginId, defaultCredentials) {
|
|
946
|
-
|
|
947
|
-
__privateAdd$3(this, _auth, void 0);
|
|
948
|
-
__privateAdd$3(this, _defaultCredentials, void 0);
|
|
949
|
-
__privateSet$3(this, _auth, new MockAuthService({
|
|
846
|
+
this.#auth = new MockAuthService({
|
|
950
847
|
pluginId,
|
|
951
848
|
disableDefaultAuthPolicy: false
|
|
952
|
-
})
|
|
953
|
-
|
|
849
|
+
});
|
|
850
|
+
this.#defaultCredentials = defaultCredentials;
|
|
851
|
+
}
|
|
852
|
+
async #getCredentials(req, allowLimitedAccess) {
|
|
853
|
+
const header = req.headers.authorization;
|
|
854
|
+
const token = typeof header === "string" ? header.match(/^Bearer[ ]+(\S+)$/i)?.[1] : void 0;
|
|
855
|
+
if (token) {
|
|
856
|
+
if (token === MOCK_NONE_TOKEN) {
|
|
857
|
+
return this.#auth.getNoneCredentials();
|
|
858
|
+
}
|
|
859
|
+
return await this.#auth.authenticate(token, {
|
|
860
|
+
allowLimitedAccess
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
if (allowLimitedAccess) {
|
|
864
|
+
const cookieHeader = req.headers.cookie;
|
|
865
|
+
if (cookieHeader) {
|
|
866
|
+
const cookies = cookie.parse(cookieHeader);
|
|
867
|
+
const cookie$1 = cookies[MOCK_AUTH_COOKIE];
|
|
868
|
+
if (cookie$1) {
|
|
869
|
+
return await this.#auth.authenticate(cookie$1, {
|
|
870
|
+
allowLimitedAccess: true
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
return this.#defaultCredentials;
|
|
954
876
|
}
|
|
955
877
|
async credentials(req, options) {
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
878
|
+
const credentials = await this.#getCredentials(
|
|
879
|
+
req,
|
|
880
|
+
options?.allowLimitedAccess ?? false
|
|
881
|
+
);
|
|
882
|
+
const allowedPrincipalTypes = options?.allow;
|
|
959
883
|
if (!allowedPrincipalTypes) {
|
|
960
884
|
return credentials;
|
|
961
885
|
}
|
|
962
|
-
if (
|
|
886
|
+
if (this.#auth.isPrincipal(credentials, "none")) {
|
|
963
887
|
if (allowedPrincipalTypes.includes("none")) {
|
|
964
888
|
return credentials;
|
|
965
889
|
}
|
|
966
890
|
throw new errors.AuthenticationError("Missing credentials");
|
|
967
|
-
} else if (
|
|
891
|
+
} else if (this.#auth.isPrincipal(credentials, "user")) {
|
|
968
892
|
if (allowedPrincipalTypes.includes("user")) {
|
|
969
893
|
return credentials;
|
|
970
894
|
}
|
|
971
895
|
throw new errors.NotAllowedError(
|
|
972
896
|
`This endpoint does not allow 'user' credentials`
|
|
973
897
|
);
|
|
974
|
-
} else if (
|
|
898
|
+
} else if (this.#auth.isPrincipal(credentials, "service")) {
|
|
975
899
|
if (allowedPrincipalTypes.includes("service")) {
|
|
976
900
|
return credentials;
|
|
977
901
|
}
|
|
@@ -984,8 +908,7 @@ class MockHttpAuthService {
|
|
|
984
908
|
);
|
|
985
909
|
}
|
|
986
910
|
async issueUserCookie(res, options) {
|
|
987
|
-
|
|
988
|
-
const credentials = (_a = options == null ? void 0 : options.credentials) != null ? _a : await this.credentials(res.req, { allow: ["user"] });
|
|
911
|
+
const credentials = options?.credentials ?? await this.credentials(res.req, { allow: ["user"] });
|
|
989
912
|
res.setHeader(
|
|
990
913
|
"Set-Cookie",
|
|
991
914
|
exports.mockCredentials.limitedUser.cookie(credentials.principal.userEntityRef)
|
|
@@ -993,46 +916,11 @@ class MockHttpAuthService {
|
|
|
993
916
|
return { expiresAt: new Date(Date.now() + 36e5) };
|
|
994
917
|
}
|
|
995
918
|
}
|
|
996
|
-
_auth = new WeakMap();
|
|
997
|
-
_defaultCredentials = new WeakMap();
|
|
998
|
-
_getCredentials = new WeakSet();
|
|
999
|
-
getCredentials_fn = async function(req, allowLimitedAccess) {
|
|
1000
|
-
var _a;
|
|
1001
|
-
const header = req.headers.authorization;
|
|
1002
|
-
const token = typeof header === "string" ? (_a = header.match(/^Bearer[ ]+(\S+)$/i)) == null ? void 0 : _a[1] : void 0;
|
|
1003
|
-
if (token) {
|
|
1004
|
-
if (token === MOCK_NONE_TOKEN) {
|
|
1005
|
-
return __privateGet$3(this, _auth).getNoneCredentials();
|
|
1006
|
-
}
|
|
1007
|
-
return await __privateGet$3(this, _auth).authenticate(token, {
|
|
1008
|
-
allowLimitedAccess
|
|
1009
|
-
});
|
|
1010
|
-
}
|
|
1011
|
-
if (allowLimitedAccess) {
|
|
1012
|
-
const cookieHeader = req.headers.cookie;
|
|
1013
|
-
if (cookieHeader) {
|
|
1014
|
-
const cookies = cookie.parse(cookieHeader);
|
|
1015
|
-
const cookie$1 = cookies[MOCK_AUTH_COOKIE];
|
|
1016
|
-
if (cookie$1) {
|
|
1017
|
-
return await __privateGet$3(this, _auth).authenticate(cookie$1, {
|
|
1018
|
-
allowLimitedAccess: true
|
|
1019
|
-
});
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1023
|
-
return __privateGet$3(this, _defaultCredentials);
|
|
1024
|
-
};
|
|
1025
919
|
|
|
1026
|
-
var __defProp = Object.defineProperty;
|
|
1027
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1028
|
-
var __publicField = (obj, key, value) => {
|
|
1029
|
-
__defNormalProp(obj, key + "" , value);
|
|
1030
|
-
return value;
|
|
1031
|
-
};
|
|
1032
920
|
class MockUserInfoService {
|
|
921
|
+
customInfo;
|
|
1033
922
|
constructor(customInfo) {
|
|
1034
|
-
|
|
1035
|
-
this.customInfo = customInfo != null ? customInfo : {};
|
|
923
|
+
this.customInfo = customInfo ?? {};
|
|
1036
924
|
}
|
|
1037
925
|
async getUserInfo(credentials) {
|
|
1038
926
|
const principal = credentials.principal;
|
|
@@ -1049,6 +937,15 @@ class MockUserInfoService {
|
|
|
1049
937
|
}
|
|
1050
938
|
}
|
|
1051
939
|
|
|
940
|
+
function createLoggerMock() {
|
|
941
|
+
return {
|
|
942
|
+
child: jest.fn().mockImplementation(createLoggerMock),
|
|
943
|
+
debug: jest.fn(),
|
|
944
|
+
error: jest.fn(),
|
|
945
|
+
info: jest.fn(),
|
|
946
|
+
warn: jest.fn()
|
|
947
|
+
};
|
|
948
|
+
}
|
|
1052
949
|
function simpleFactory(ref, factory) {
|
|
1053
950
|
return backendPluginApi.createServiceFactory((options) => ({
|
|
1054
951
|
service: ref,
|
|
@@ -1082,7 +979,7 @@ function simpleMock(ref, mockFactory) {
|
|
|
1082
979
|
exports.mockServices = void 0;
|
|
1083
980
|
((mockServices2) => {
|
|
1084
981
|
function rootConfig(options) {
|
|
1085
|
-
return new config.ConfigReader(options
|
|
982
|
+
return new config.ConfigReader(options?.data, "mock-config");
|
|
1086
983
|
}
|
|
1087
984
|
mockServices2.rootConfig = rootConfig;
|
|
1088
985
|
((rootConfig2) => {
|
|
@@ -1136,10 +1033,9 @@ exports.mockServices = void 0;
|
|
|
1136
1033
|
}));
|
|
1137
1034
|
})(identity = mockServices2.identity || (mockServices2.identity = {}));
|
|
1138
1035
|
function auth(options) {
|
|
1139
|
-
var _a;
|
|
1140
1036
|
return new MockAuthService({
|
|
1141
|
-
pluginId:
|
|
1142
|
-
disableDefaultAuthPolicy: Boolean(options
|
|
1037
|
+
pluginId: options?.pluginId ?? "test",
|
|
1038
|
+
disableDefaultAuthPolicy: Boolean(options?.disableDefaultAuthPolicy)
|
|
1143
1039
|
});
|
|
1144
1040
|
}
|
|
1145
1041
|
mockServices2.auth = auth;
|
|
@@ -1192,10 +1088,9 @@ exports.mockServices = void 0;
|
|
|
1192
1088
|
}));
|
|
1193
1089
|
})(discovery = mockServices2.discovery || (mockServices2.discovery = {}));
|
|
1194
1090
|
function httpAuth(options) {
|
|
1195
|
-
var _a, _b;
|
|
1196
1091
|
return new MockHttpAuthService(
|
|
1197
|
-
|
|
1198
|
-
|
|
1092
|
+
options?.pluginId ?? "test",
|
|
1093
|
+
options?.defaultCredentials ?? exports.mockCredentials.user()
|
|
1199
1094
|
);
|
|
1200
1095
|
}
|
|
1201
1096
|
mockServices2.httpAuth = httpAuth;
|
|
@@ -1204,13 +1099,10 @@ exports.mockServices = void 0;
|
|
|
1204
1099
|
(options) => ({
|
|
1205
1100
|
service: backendPluginApi.coreServices.httpAuth,
|
|
1206
1101
|
deps: { plugin: backendPluginApi.coreServices.pluginMetadata },
|
|
1207
|
-
factory: ({ plugin }) =>
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
(_a = options == null ? void 0 : options.defaultCredentials) != null ? _a : exports.mockCredentials.user()
|
|
1212
|
-
);
|
|
1213
|
-
}
|
|
1102
|
+
factory: ({ plugin }) => new MockHttpAuthService(
|
|
1103
|
+
plugin.getId(),
|
|
1104
|
+
options?.defaultCredentials ?? exports.mockCredentials.user()
|
|
1105
|
+
)
|
|
1214
1106
|
})
|
|
1215
1107
|
);
|
|
1216
1108
|
httpAuth2.mock = simpleMock(backendPluginApi.coreServices.httpAuth, () => ({
|
|
@@ -1271,13 +1163,10 @@ exports.mockServices = void 0;
|
|
|
1271
1163
|
})(mockServices2.lifecycle || (mockServices2.lifecycle = {}));
|
|
1272
1164
|
((logger2) => {
|
|
1273
1165
|
logger2.factory = backendAppApi.loggerServiceFactory;
|
|
1274
|
-
logger2.mock = simpleMock(
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
info: jest.fn(),
|
|
1279
|
-
warn: jest.fn()
|
|
1280
|
-
}));
|
|
1166
|
+
logger2.mock = simpleMock(
|
|
1167
|
+
backendPluginApi.coreServices.logger,
|
|
1168
|
+
() => createLoggerMock()
|
|
1169
|
+
);
|
|
1281
1170
|
})(mockServices2.logger || (mockServices2.logger = {}));
|
|
1282
1171
|
((permissions2) => {
|
|
1283
1172
|
permissions2.factory = backendAppApi.permissionsServiceFactory;
|
|
@@ -1442,16 +1331,15 @@ function unwrapFeature(feature) {
|
|
|
1442
1331
|
}
|
|
1443
1332
|
const backendInstancesToCleanUp = new Array();
|
|
1444
1333
|
async function startTestBackend(options) {
|
|
1445
|
-
var _a, _b;
|
|
1446
1334
|
const { extensionPoints, ...otherOptions } = options;
|
|
1447
1335
|
const features = await Promise.all(
|
|
1448
|
-
|
|
1336
|
+
options.features?.map(async (val) => {
|
|
1449
1337
|
if (isPromise(val)) {
|
|
1450
1338
|
const { default: feature } = await val;
|
|
1451
1339
|
return unwrapFeature(feature);
|
|
1452
1340
|
}
|
|
1453
1341
|
return unwrapFeature(val);
|
|
1454
|
-
})
|
|
1342
|
+
}) ?? []
|
|
1455
1343
|
);
|
|
1456
1344
|
let server;
|
|
1457
1345
|
const rootHttpRouterFactory = backendPluginApi.createServiceFactory({
|
|
@@ -1552,29 +1440,6 @@ function isInternalBackendFeature(feature) {
|
|
|
1552
1440
|
return typeof feature.getRegistrations === "function";
|
|
1553
1441
|
}
|
|
1554
1442
|
|
|
1555
|
-
var __accessCheck$2 = (obj, member, msg) => {
|
|
1556
|
-
if (!member.has(obj))
|
|
1557
|
-
throw TypeError("Cannot " + msg);
|
|
1558
|
-
};
|
|
1559
|
-
var __privateGet$2 = (obj, member, getter) => {
|
|
1560
|
-
__accessCheck$2(obj, member, "read from private field");
|
|
1561
|
-
return member.get(obj);
|
|
1562
|
-
};
|
|
1563
|
-
var __privateAdd$2 = (obj, member, value) => {
|
|
1564
|
-
if (member.has(obj))
|
|
1565
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
1566
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1567
|
-
};
|
|
1568
|
-
var __privateSet$2 = (obj, member, value, setter) => {
|
|
1569
|
-
__accessCheck$2(obj, member, "write to private field");
|
|
1570
|
-
member.set(obj, value);
|
|
1571
|
-
return value;
|
|
1572
|
-
};
|
|
1573
|
-
var __privateMethod$1 = (obj, member, method) => {
|
|
1574
|
-
__accessCheck$2(obj, member, "access private method");
|
|
1575
|
-
return method;
|
|
1576
|
-
};
|
|
1577
|
-
var _nodeIds, _cycleKeys, _getCycleKey, getCycleKey_fn, _nodes, _allProvided;
|
|
1578
1443
|
class Node {
|
|
1579
1444
|
constructor(value, consumes, provides) {
|
|
1580
1445
|
this.value = value;
|
|
@@ -1589,45 +1454,29 @@ class Node {
|
|
|
1589
1454
|
);
|
|
1590
1455
|
}
|
|
1591
1456
|
}
|
|
1592
|
-
|
|
1593
|
-
constructor(nodes) {
|
|
1594
|
-
__privateAdd$2(this, _getCycleKey);
|
|
1595
|
-
__privateAdd$2(this, _nodeIds, void 0);
|
|
1596
|
-
__privateAdd$2(this, _cycleKeys, void 0);
|
|
1597
|
-
__privateSet$2(this, _nodeIds, new Map(nodes.map((n, i) => [n.value, i])));
|
|
1598
|
-
__privateSet$2(this, _cycleKeys, /* @__PURE__ */ new Set());
|
|
1599
|
-
}
|
|
1457
|
+
class CycleKeySet {
|
|
1600
1458
|
static from(nodes) {
|
|
1601
|
-
return new
|
|
1459
|
+
return new CycleKeySet(nodes);
|
|
1460
|
+
}
|
|
1461
|
+
#nodeIds;
|
|
1462
|
+
#cycleKeys;
|
|
1463
|
+
constructor(nodes) {
|
|
1464
|
+
this.#nodeIds = new Map(nodes.map((n, i) => [n.value, i]));
|
|
1465
|
+
this.#cycleKeys = /* @__PURE__ */ new Set();
|
|
1602
1466
|
}
|
|
1603
1467
|
tryAdd(path) {
|
|
1604
|
-
const cycleKey =
|
|
1605
|
-
if (
|
|
1468
|
+
const cycleKey = this.#getCycleKey(path);
|
|
1469
|
+
if (this.#cycleKeys.has(cycleKey)) {
|
|
1606
1470
|
return false;
|
|
1607
1471
|
}
|
|
1608
|
-
|
|
1472
|
+
this.#cycleKeys.add(cycleKey);
|
|
1609
1473
|
return true;
|
|
1610
1474
|
}
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
_cycleKeys = new WeakMap();
|
|
1614
|
-
_getCycleKey = new WeakSet();
|
|
1615
|
-
getCycleKey_fn = function(path) {
|
|
1616
|
-
return path.map((n) => __privateGet$2(this, _nodeIds).get(n)).sort().join(",");
|
|
1617
|
-
};
|
|
1618
|
-
let CycleKeySet = _CycleKeySet;
|
|
1619
|
-
const _DependencyGraph = class _DependencyGraph {
|
|
1620
|
-
constructor(nodes) {
|
|
1621
|
-
__privateAdd$2(this, _nodes, void 0);
|
|
1622
|
-
__privateAdd$2(this, _allProvided, void 0);
|
|
1623
|
-
__privateSet$2(this, _nodes, nodes);
|
|
1624
|
-
__privateSet$2(this, _allProvided, /* @__PURE__ */ new Set());
|
|
1625
|
-
for (const node of __privateGet$2(this, _nodes).values()) {
|
|
1626
|
-
for (const produced of node.provides) {
|
|
1627
|
-
__privateGet$2(this, _allProvided).add(produced);
|
|
1628
|
-
}
|
|
1629
|
-
}
|
|
1475
|
+
#getCycleKey(path) {
|
|
1476
|
+
return path.map((n) => this.#nodeIds.get(n)).sort().join(",");
|
|
1630
1477
|
}
|
|
1478
|
+
}
|
|
1479
|
+
class DependencyGraph {
|
|
1631
1480
|
static fromMap(nodes) {
|
|
1632
1481
|
return this.fromIterable(
|
|
1633
1482
|
Object.entries(nodes).map(([key, node]) => ({
|
|
@@ -1641,16 +1490,27 @@ const _DependencyGraph = class _DependencyGraph {
|
|
|
1641
1490
|
for (const nodeInput of nodeInputs) {
|
|
1642
1491
|
nodes.push(Node.from(nodeInput));
|
|
1643
1492
|
}
|
|
1644
|
-
return new
|
|
1493
|
+
return new DependencyGraph(nodes);
|
|
1494
|
+
}
|
|
1495
|
+
#nodes;
|
|
1496
|
+
#allProvided;
|
|
1497
|
+
constructor(nodes) {
|
|
1498
|
+
this.#nodes = nodes;
|
|
1499
|
+
this.#allProvided = /* @__PURE__ */ new Set();
|
|
1500
|
+
for (const node of this.#nodes.values()) {
|
|
1501
|
+
for (const produced of node.provides) {
|
|
1502
|
+
this.#allProvided.add(produced);
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1645
1505
|
}
|
|
1646
1506
|
/**
|
|
1647
1507
|
* Find all nodes that consume dependencies that are not provided by any other node.
|
|
1648
1508
|
*/
|
|
1649
1509
|
findUnsatisfiedDeps() {
|
|
1650
1510
|
const unsatisfiedDependencies = [];
|
|
1651
|
-
for (const node of
|
|
1511
|
+
for (const node of this.#nodes.values()) {
|
|
1652
1512
|
const unsatisfied = Array.from(node.consumes).filter(
|
|
1653
|
-
(id) => !
|
|
1513
|
+
(id) => !this.#allProvided.has(id)
|
|
1654
1514
|
);
|
|
1655
1515
|
if (unsatisfied.length > 0) {
|
|
1656
1516
|
unsatisfiedDependencies.push({ value: node.value, unsatisfied });
|
|
@@ -1670,8 +1530,8 @@ const _DependencyGraph = class _DependencyGraph {
|
|
|
1670
1530
|
* form a cycle, with the same node as the first and last element of the array.
|
|
1671
1531
|
*/
|
|
1672
1532
|
*detectCircularDependencies() {
|
|
1673
|
-
const cycleKeys = CycleKeySet.from(
|
|
1674
|
-
for (const startNode of
|
|
1533
|
+
const cycleKeys = CycleKeySet.from(this.#nodes);
|
|
1534
|
+
for (const startNode of this.#nodes) {
|
|
1675
1535
|
const visited = /* @__PURE__ */ new Set();
|
|
1676
1536
|
const stack = new Array([
|
|
1677
1537
|
startNode,
|
|
@@ -1684,7 +1544,7 @@ const _DependencyGraph = class _DependencyGraph {
|
|
|
1684
1544
|
}
|
|
1685
1545
|
visited.add(node);
|
|
1686
1546
|
for (const consumed of node.consumes) {
|
|
1687
|
-
const providerNodes =
|
|
1547
|
+
const providerNodes = this.#nodes.filter(
|
|
1688
1548
|
(other) => other.provides.has(consumed)
|
|
1689
1549
|
);
|
|
1690
1550
|
for (const provider of providerNodes) {
|
|
@@ -1713,9 +1573,9 @@ const _DependencyGraph = class _DependencyGraph {
|
|
|
1713
1573
|
* Dependencies of nodes that are not produced by any other nodes will be ignored.
|
|
1714
1574
|
*/
|
|
1715
1575
|
async parallelTopologicalTraversal(fn) {
|
|
1716
|
-
const allProvided =
|
|
1576
|
+
const allProvided = this.#allProvided;
|
|
1717
1577
|
const producedSoFar = /* @__PURE__ */ new Set();
|
|
1718
|
-
const waiting = new Set(
|
|
1578
|
+
const waiting = new Set(this.#nodes.values());
|
|
1719
1579
|
const visited = /* @__PURE__ */ new Set();
|
|
1720
1580
|
const results = new Array();
|
|
1721
1581
|
let inFlight = 0;
|
|
@@ -1756,34 +1616,8 @@ const _DependencyGraph = class _DependencyGraph {
|
|
|
1756
1616
|
await processMoreNodes();
|
|
1757
1617
|
return results;
|
|
1758
1618
|
}
|
|
1759
|
-
}
|
|
1760
|
-
_nodes = new WeakMap();
|
|
1761
|
-
_allProvided = new WeakMap();
|
|
1762
|
-
let DependencyGraph = _DependencyGraph;
|
|
1619
|
+
}
|
|
1763
1620
|
|
|
1764
|
-
var __accessCheck$1 = (obj, member, msg) => {
|
|
1765
|
-
if (!member.has(obj))
|
|
1766
|
-
throw TypeError("Cannot " + msg);
|
|
1767
|
-
};
|
|
1768
|
-
var __privateGet$1 = (obj, member, getter) => {
|
|
1769
|
-
__accessCheck$1(obj, member, "read from private field");
|
|
1770
|
-
return member.get(obj);
|
|
1771
|
-
};
|
|
1772
|
-
var __privateAdd$1 = (obj, member, value) => {
|
|
1773
|
-
if (member.has(obj))
|
|
1774
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
1775
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1776
|
-
};
|
|
1777
|
-
var __privateSet$1 = (obj, member, value, setter) => {
|
|
1778
|
-
__accessCheck$1(obj, member, "write to private field");
|
|
1779
|
-
member.set(obj, value);
|
|
1780
|
-
return value;
|
|
1781
|
-
};
|
|
1782
|
-
var __privateMethod = (obj, member, method) => {
|
|
1783
|
-
__accessCheck$1(obj, member, "access private method");
|
|
1784
|
-
return method;
|
|
1785
|
-
};
|
|
1786
|
-
var _providedFactories, _loadedDefaultFactories, _implementations, _rootServiceImplementations, _addedFactoryIds, _instantiatedFactories, _resolveFactory, resolveFactory_fn, _checkForMissingDeps, checkForMissingDeps_fn;
|
|
1787
1621
|
function toInternalServiceFactory(factory) {
|
|
1788
1622
|
const f = factory;
|
|
1789
1623
|
if (f.$$type !== "@backstage/BackendFeature") {
|
|
@@ -1798,33 +1632,77 @@ const pluginMetadataServiceFactory = backendPluginApi.createServiceFactory(
|
|
|
1798
1632
|
(options) => ({
|
|
1799
1633
|
service: backendPluginApi.coreServices.pluginMetadata,
|
|
1800
1634
|
deps: {},
|
|
1801
|
-
factory: async () => ({ getId: () => options
|
|
1635
|
+
factory: async () => ({ getId: () => options?.pluginId })
|
|
1802
1636
|
})
|
|
1803
1637
|
);
|
|
1804
|
-
|
|
1805
|
-
constructor(factories) {
|
|
1806
|
-
__privateAdd$1(this, _resolveFactory);
|
|
1807
|
-
__privateAdd$1(this, _checkForMissingDeps);
|
|
1808
|
-
__privateAdd$1(this, _providedFactories, void 0);
|
|
1809
|
-
__privateAdd$1(this, _loadedDefaultFactories, void 0);
|
|
1810
|
-
__privateAdd$1(this, _implementations, void 0);
|
|
1811
|
-
__privateAdd$1(this, _rootServiceImplementations, /* @__PURE__ */ new Map());
|
|
1812
|
-
__privateAdd$1(this, _addedFactoryIds, /* @__PURE__ */ new Set());
|
|
1813
|
-
__privateAdd$1(this, _instantiatedFactories, /* @__PURE__ */ new Set());
|
|
1814
|
-
__privateSet$1(this, _providedFactories, new Map(
|
|
1815
|
-
factories.map((sf) => [sf.service.id, toInternalServiceFactory(sf)])
|
|
1816
|
-
));
|
|
1817
|
-
__privateSet$1(this, _loadedDefaultFactories, /* @__PURE__ */ new Map());
|
|
1818
|
-
__privateSet$1(this, _implementations, /* @__PURE__ */ new Map());
|
|
1819
|
-
}
|
|
1638
|
+
class ServiceRegistry {
|
|
1820
1639
|
static create(factories) {
|
|
1821
|
-
const registry = new
|
|
1640
|
+
const registry = new ServiceRegistry(factories);
|
|
1822
1641
|
registry.checkForCircularDeps();
|
|
1823
1642
|
return registry;
|
|
1824
1643
|
}
|
|
1644
|
+
#providedFactories;
|
|
1645
|
+
#loadedDefaultFactories;
|
|
1646
|
+
#implementations;
|
|
1647
|
+
#rootServiceImplementations = /* @__PURE__ */ new Map();
|
|
1648
|
+
#addedFactoryIds = /* @__PURE__ */ new Set();
|
|
1649
|
+
#instantiatedFactories = /* @__PURE__ */ new Set();
|
|
1650
|
+
constructor(factories) {
|
|
1651
|
+
this.#providedFactories = new Map(
|
|
1652
|
+
factories.map((sf) => [sf.service.id, toInternalServiceFactory(sf)])
|
|
1653
|
+
);
|
|
1654
|
+
this.#loadedDefaultFactories = /* @__PURE__ */ new Map();
|
|
1655
|
+
this.#implementations = /* @__PURE__ */ new Map();
|
|
1656
|
+
}
|
|
1657
|
+
#resolveFactory(ref, pluginId) {
|
|
1658
|
+
if (ref.id === backendPluginApi.coreServices.pluginMetadata.id) {
|
|
1659
|
+
return Promise.resolve(
|
|
1660
|
+
toInternalServiceFactory(pluginMetadataServiceFactory({ pluginId }))
|
|
1661
|
+
);
|
|
1662
|
+
}
|
|
1663
|
+
let resolvedFactory = this.#providedFactories.get(ref.id);
|
|
1664
|
+
const { __defaultFactory: defaultFactory } = ref;
|
|
1665
|
+
if (!resolvedFactory && !defaultFactory) {
|
|
1666
|
+
return void 0;
|
|
1667
|
+
}
|
|
1668
|
+
if (!resolvedFactory) {
|
|
1669
|
+
let loadedFactory = this.#loadedDefaultFactories.get(defaultFactory);
|
|
1670
|
+
if (!loadedFactory) {
|
|
1671
|
+
loadedFactory = Promise.resolve().then(() => defaultFactory(ref)).then(
|
|
1672
|
+
(f) => toInternalServiceFactory(typeof f === "function" ? f() : f)
|
|
1673
|
+
);
|
|
1674
|
+
this.#loadedDefaultFactories.set(defaultFactory, loadedFactory);
|
|
1675
|
+
}
|
|
1676
|
+
resolvedFactory = loadedFactory.catch((error) => {
|
|
1677
|
+
throw new Error(
|
|
1678
|
+
`Failed to instantiate service '${ref.id}' because the default factory loader threw an error, ${errors.stringifyError(
|
|
1679
|
+
error
|
|
1680
|
+
)}`
|
|
1681
|
+
);
|
|
1682
|
+
});
|
|
1683
|
+
}
|
|
1684
|
+
return Promise.resolve(resolvedFactory);
|
|
1685
|
+
}
|
|
1686
|
+
#checkForMissingDeps(factory, pluginId) {
|
|
1687
|
+
const missingDeps = Object.values(factory.deps).filter((ref) => {
|
|
1688
|
+
if (ref.id === backendPluginApi.coreServices.pluginMetadata.id) {
|
|
1689
|
+
return false;
|
|
1690
|
+
}
|
|
1691
|
+
if (this.#providedFactories.get(ref.id)) {
|
|
1692
|
+
return false;
|
|
1693
|
+
}
|
|
1694
|
+
return !ref.__defaultFactory;
|
|
1695
|
+
});
|
|
1696
|
+
if (missingDeps.length) {
|
|
1697
|
+
const missing = missingDeps.map((r) => `'${r.id}'`).join(", ");
|
|
1698
|
+
throw new Error(
|
|
1699
|
+
`Failed to instantiate service '${factory.service.id}' for '${pluginId}' because the following dependent services are missing: ${missing}`
|
|
1700
|
+
);
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1825
1703
|
checkForCircularDeps() {
|
|
1826
1704
|
const graph = DependencyGraph.fromIterable(
|
|
1827
|
-
Array.from(
|
|
1705
|
+
Array.from(this.#providedFactories).map(
|
|
1828
1706
|
([serviceId, serviceFactory]) => ({
|
|
1829
1707
|
value: serviceId,
|
|
1830
1708
|
provides: [serviceId],
|
|
@@ -1846,21 +1724,21 @@ const _ServiceRegistry = class _ServiceRegistry {
|
|
|
1846
1724
|
`The ${backendPluginApi.coreServices.pluginMetadata.id} service cannot be overridden`
|
|
1847
1725
|
);
|
|
1848
1726
|
}
|
|
1849
|
-
if (
|
|
1727
|
+
if (this.#addedFactoryIds.has(factoryId)) {
|
|
1850
1728
|
throw new Error(
|
|
1851
1729
|
`Duplicate service implementations provided for ${factoryId}`
|
|
1852
1730
|
);
|
|
1853
1731
|
}
|
|
1854
|
-
if (
|
|
1732
|
+
if (this.#instantiatedFactories.has(factoryId)) {
|
|
1855
1733
|
throw new Error(
|
|
1856
1734
|
`Unable to set service factory with id ${factoryId}, service has already been instantiated`
|
|
1857
1735
|
);
|
|
1858
1736
|
}
|
|
1859
|
-
|
|
1860
|
-
|
|
1737
|
+
this.#addedFactoryIds.add(factoryId);
|
|
1738
|
+
this.#providedFactories.set(factoryId, toInternalServiceFactory(factory));
|
|
1861
1739
|
}
|
|
1862
1740
|
async initializeEagerServicesWithScope(scope, pluginId = "root") {
|
|
1863
|
-
for (const factory of
|
|
1741
|
+
for (const factory of this.#providedFactories.values()) {
|
|
1864
1742
|
if (factory.service.scope === scope) {
|
|
1865
1743
|
if (scope === "root" && factory.initialization !== "lazy") {
|
|
1866
1744
|
await this.get(factory.service, pluginId);
|
|
@@ -1871,13 +1749,12 @@ const _ServiceRegistry = class _ServiceRegistry {
|
|
|
1871
1749
|
}
|
|
1872
1750
|
}
|
|
1873
1751
|
get(ref, pluginId) {
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
return (_a = __privateMethod(this, _resolveFactory, resolveFactory_fn).call(this, ref, pluginId)) == null ? void 0 : _a.then((factory) => {
|
|
1752
|
+
this.#instantiatedFactories.add(ref.id);
|
|
1753
|
+
return this.#resolveFactory(ref, pluginId)?.then((factory) => {
|
|
1877
1754
|
if (factory.service.scope === "root") {
|
|
1878
|
-
let existing =
|
|
1755
|
+
let existing = this.#rootServiceImplementations.get(factory);
|
|
1879
1756
|
if (!existing) {
|
|
1880
|
-
|
|
1757
|
+
this.#checkForMissingDeps(factory, pluginId);
|
|
1881
1758
|
const rootDeps = new Array();
|
|
1882
1759
|
for (const [name, serviceRef] of Object.entries(factory.deps)) {
|
|
1883
1760
|
if (serviceRef.scope !== "root") {
|
|
@@ -1891,13 +1768,13 @@ const _ServiceRegistry = class _ServiceRegistry {
|
|
|
1891
1768
|
existing = Promise.all(rootDeps).then(
|
|
1892
1769
|
(entries) => factory.factory(Object.fromEntries(entries), void 0)
|
|
1893
1770
|
);
|
|
1894
|
-
|
|
1771
|
+
this.#rootServiceImplementations.set(factory, existing);
|
|
1895
1772
|
}
|
|
1896
1773
|
return existing;
|
|
1897
1774
|
}
|
|
1898
|
-
let implementation =
|
|
1775
|
+
let implementation = this.#implementations.get(factory);
|
|
1899
1776
|
if (!implementation) {
|
|
1900
|
-
|
|
1777
|
+
this.#checkForMissingDeps(factory, pluginId);
|
|
1901
1778
|
const rootDeps = new Array();
|
|
1902
1779
|
for (const [name, serviceRef] of Object.entries(factory.deps)) {
|
|
1903
1780
|
if (serviceRef.scope === "root") {
|
|
@@ -1907,10 +1784,7 @@ const _ServiceRegistry = class _ServiceRegistry {
|
|
|
1907
1784
|
}
|
|
1908
1785
|
implementation = {
|
|
1909
1786
|
context: Promise.all(rootDeps).then(
|
|
1910
|
-
(entries) =>
|
|
1911
|
-
var _a2;
|
|
1912
|
-
return (_a2 = factory.createRootContext) == null ? void 0 : _a2.call(factory, Object.fromEntries(entries));
|
|
1913
|
-
}
|
|
1787
|
+
(entries) => factory.createRootContext?.(Object.fromEntries(entries))
|
|
1914
1788
|
).catch((error) => {
|
|
1915
1789
|
const cause = errors.stringifyError(error);
|
|
1916
1790
|
throw new Error(
|
|
@@ -1919,7 +1793,7 @@ const _ServiceRegistry = class _ServiceRegistry {
|
|
|
1919
1793
|
}),
|
|
1920
1794
|
byPlugin: /* @__PURE__ */ new Map()
|
|
1921
1795
|
};
|
|
1922
|
-
|
|
1796
|
+
this.#implementations.set(factory, implementation);
|
|
1923
1797
|
}
|
|
1924
1798
|
let result = implementation.byPlugin.get(pluginId);
|
|
1925
1799
|
if (!result) {
|
|
@@ -1943,89 +1817,11 @@ const _ServiceRegistry = class _ServiceRegistry {
|
|
|
1943
1817
|
return result;
|
|
1944
1818
|
});
|
|
1945
1819
|
}
|
|
1946
|
-
}
|
|
1947
|
-
_providedFactories = new WeakMap();
|
|
1948
|
-
_loadedDefaultFactories = new WeakMap();
|
|
1949
|
-
_implementations = new WeakMap();
|
|
1950
|
-
_rootServiceImplementations = new WeakMap();
|
|
1951
|
-
_addedFactoryIds = new WeakMap();
|
|
1952
|
-
_instantiatedFactories = new WeakMap();
|
|
1953
|
-
_resolveFactory = new WeakSet();
|
|
1954
|
-
resolveFactory_fn = function(ref, pluginId) {
|
|
1955
|
-
if (ref.id === backendPluginApi.coreServices.pluginMetadata.id) {
|
|
1956
|
-
return Promise.resolve(
|
|
1957
|
-
toInternalServiceFactory(pluginMetadataServiceFactory({ pluginId }))
|
|
1958
|
-
);
|
|
1959
|
-
}
|
|
1960
|
-
let resolvedFactory = __privateGet$1(this, _providedFactories).get(ref.id);
|
|
1961
|
-
const { __defaultFactory: defaultFactory } = ref;
|
|
1962
|
-
if (!resolvedFactory && !defaultFactory) {
|
|
1963
|
-
return void 0;
|
|
1964
|
-
}
|
|
1965
|
-
if (!resolvedFactory) {
|
|
1966
|
-
let loadedFactory = __privateGet$1(this, _loadedDefaultFactories).get(defaultFactory);
|
|
1967
|
-
if (!loadedFactory) {
|
|
1968
|
-
loadedFactory = Promise.resolve().then(() => defaultFactory(ref)).then(
|
|
1969
|
-
(f) => toInternalServiceFactory(typeof f === "function" ? f() : f)
|
|
1970
|
-
);
|
|
1971
|
-
__privateGet$1(this, _loadedDefaultFactories).set(defaultFactory, loadedFactory);
|
|
1972
|
-
}
|
|
1973
|
-
resolvedFactory = loadedFactory.catch((error) => {
|
|
1974
|
-
throw new Error(
|
|
1975
|
-
`Failed to instantiate service '${ref.id}' because the default factory loader threw an error, ${errors.stringifyError(
|
|
1976
|
-
error
|
|
1977
|
-
)}`
|
|
1978
|
-
);
|
|
1979
|
-
});
|
|
1980
|
-
}
|
|
1981
|
-
return Promise.resolve(resolvedFactory);
|
|
1982
|
-
};
|
|
1983
|
-
_checkForMissingDeps = new WeakSet();
|
|
1984
|
-
checkForMissingDeps_fn = function(factory, pluginId) {
|
|
1985
|
-
const missingDeps = Object.values(factory.deps).filter((ref) => {
|
|
1986
|
-
if (ref.id === backendPluginApi.coreServices.pluginMetadata.id) {
|
|
1987
|
-
return false;
|
|
1988
|
-
}
|
|
1989
|
-
if (__privateGet$1(this, _providedFactories).get(ref.id)) {
|
|
1990
|
-
return false;
|
|
1991
|
-
}
|
|
1992
|
-
return !ref.__defaultFactory;
|
|
1993
|
-
});
|
|
1994
|
-
if (missingDeps.length) {
|
|
1995
|
-
const missing = missingDeps.map((r) => `'${r.id}'`).join(", ");
|
|
1996
|
-
throw new Error(
|
|
1997
|
-
`Failed to instantiate service '${factory.service.id}' for '${pluginId}' because the following dependent services are missing: ${missing}`
|
|
1998
|
-
);
|
|
1999
|
-
}
|
|
2000
|
-
};
|
|
2001
|
-
let ServiceRegistry = _ServiceRegistry;
|
|
1820
|
+
}
|
|
2002
1821
|
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
};
|
|
2007
|
-
var __privateGet = (obj, member, getter) => {
|
|
2008
|
-
__accessCheck(obj, member, "read from private field");
|
|
2009
|
-
return member.get(obj);
|
|
2010
|
-
};
|
|
2011
|
-
var __privateAdd = (obj, member, value) => {
|
|
2012
|
-
if (member.has(obj))
|
|
2013
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
2014
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
2015
|
-
};
|
|
2016
|
-
var __privateSet = (obj, member, value, setter) => {
|
|
2017
|
-
__accessCheck(obj, member, "write to private field");
|
|
2018
|
-
member.set(obj, value);
|
|
2019
|
-
return value;
|
|
2020
|
-
};
|
|
2021
|
-
var _subject, _registry;
|
|
2022
|
-
const _ServiceFactoryTester = class _ServiceFactoryTester {
|
|
2023
|
-
constructor(subject, registry) {
|
|
2024
|
-
__privateAdd(this, _subject, void 0);
|
|
2025
|
-
__privateAdd(this, _registry, void 0);
|
|
2026
|
-
__privateSet(this, _subject, subject);
|
|
2027
|
-
__privateSet(this, _registry, registry);
|
|
2028
|
-
}
|
|
1822
|
+
class ServiceFactoryTester {
|
|
1823
|
+
#subject;
|
|
1824
|
+
#registry;
|
|
2029
1825
|
/**
|
|
2030
1826
|
* Creates a new {@link ServiceFactoryTester} used to test the provided subject.
|
|
2031
1827
|
*
|
|
@@ -2034,16 +1830,19 @@ const _ServiceFactoryTester = class _ServiceFactoryTester {
|
|
|
2034
1830
|
* @returns A new tester instance for the provided subject.
|
|
2035
1831
|
*/
|
|
2036
1832
|
static from(subject, options) {
|
|
2037
|
-
var _a, _b;
|
|
2038
1833
|
const subjectFactory = typeof subject === "function" ? subject() : subject;
|
|
2039
1834
|
const registry = ServiceRegistry.create([
|
|
2040
1835
|
...defaultServiceFactories,
|
|
2041
|
-
...
|
|
1836
|
+
...options?.dependencies?.map(
|
|
2042
1837
|
(f) => typeof f === "function" ? f() : f
|
|
2043
|
-
)
|
|
1838
|
+
) ?? [],
|
|
2044
1839
|
subjectFactory
|
|
2045
1840
|
]);
|
|
2046
|
-
return new
|
|
1841
|
+
return new ServiceFactoryTester(subjectFactory.service, registry);
|
|
1842
|
+
}
|
|
1843
|
+
constructor(subject, registry) {
|
|
1844
|
+
this.#subject = subject;
|
|
1845
|
+
this.#registry = registry;
|
|
2047
1846
|
}
|
|
2048
1847
|
/**
|
|
2049
1848
|
* Returns the service instance for the subject.
|
|
@@ -2057,7 +1856,7 @@ const _ServiceFactoryTester = class _ServiceFactoryTester {
|
|
|
2057
1856
|
*/
|
|
2058
1857
|
async get(...args) {
|
|
2059
1858
|
const [pluginId] = args;
|
|
2060
|
-
return
|
|
1859
|
+
return this.#registry.get(this.#subject, pluginId ?? "test");
|
|
2061
1860
|
}
|
|
2062
1861
|
/**
|
|
2063
1862
|
* Return the service instance for any of the provided dependencies or built-in services.
|
|
@@ -2068,16 +1867,13 @@ const _ServiceFactoryTester = class _ServiceFactoryTester {
|
|
|
2068
1867
|
*/
|
|
2069
1868
|
async getService(service, ...args) {
|
|
2070
1869
|
const [pluginId] = args;
|
|
2071
|
-
const instance = await
|
|
1870
|
+
const instance = await this.#registry.get(service, pluginId ?? "test");
|
|
2072
1871
|
if (instance === void 0) {
|
|
2073
1872
|
throw new Error(`Service '${service.id}' not found`);
|
|
2074
1873
|
}
|
|
2075
1874
|
return instance;
|
|
2076
1875
|
}
|
|
2077
|
-
}
|
|
2078
|
-
_subject = new WeakMap();
|
|
2079
|
-
_registry = new WeakMap();
|
|
2080
|
-
let ServiceFactoryTester = _ServiceFactoryTester;
|
|
1876
|
+
}
|
|
2081
1877
|
|
|
2082
1878
|
exports.ServiceFactoryTester = ServiceFactoryTester;
|
|
2083
1879
|
exports.TestDatabases = TestDatabases;
|