@backstage/backend-app-api 0.5.0-next.2 → 0.5.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.
Potentially problematic release.
This version of @backstage/backend-app-api might be problematic. Click here for more details.
- package/CHANGELOG.md +37 -0
- package/alpha/package.json +1 -1
- package/dist/index.cjs.js +528 -312
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/package.json +10 -10
package/dist/index.cjs.js
CHANGED
|
@@ -585,31 +585,31 @@ function createCorsOriginMatcher(allowedOriginPatterns) {
|
|
|
585
585
|
};
|
|
586
586
|
}
|
|
587
587
|
|
|
588
|
-
var __accessCheck$
|
|
588
|
+
var __accessCheck$8 = (obj, member, msg) => {
|
|
589
589
|
if (!member.has(obj))
|
|
590
590
|
throw TypeError("Cannot " + msg);
|
|
591
591
|
};
|
|
592
|
-
var __privateGet$
|
|
593
|
-
__accessCheck$
|
|
592
|
+
var __privateGet$8 = (obj, member, getter) => {
|
|
593
|
+
__accessCheck$8(obj, member, "read from private field");
|
|
594
594
|
return getter ? getter.call(obj) : member.get(obj);
|
|
595
595
|
};
|
|
596
|
-
var __privateAdd$
|
|
596
|
+
var __privateAdd$8 = (obj, member, value) => {
|
|
597
597
|
if (member.has(obj))
|
|
598
598
|
throw TypeError("Cannot add the same private member more than once");
|
|
599
599
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
600
600
|
};
|
|
601
|
-
var __privateSet$
|
|
602
|
-
__accessCheck$
|
|
601
|
+
var __privateSet$8 = (obj, member, value, setter) => {
|
|
602
|
+
__accessCheck$8(obj, member, "write to private field");
|
|
603
603
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
604
604
|
return value;
|
|
605
605
|
};
|
|
606
606
|
var _config, _logger;
|
|
607
607
|
const _MiddlewareFactory = class _MiddlewareFactory {
|
|
608
608
|
constructor(options) {
|
|
609
|
-
__privateAdd$
|
|
610
|
-
__privateAdd$
|
|
611
|
-
__privateSet$
|
|
612
|
-
__privateSet$
|
|
609
|
+
__privateAdd$8(this, _config, void 0);
|
|
610
|
+
__privateAdd$8(this, _logger, void 0);
|
|
611
|
+
__privateSet$8(this, _config, options.config);
|
|
612
|
+
__privateSet$8(this, _logger, options.logger);
|
|
613
613
|
}
|
|
614
614
|
/**
|
|
615
615
|
* Creates a new {@link MiddlewareFactory}.
|
|
@@ -655,7 +655,7 @@ const _MiddlewareFactory = class _MiddlewareFactory {
|
|
|
655
655
|
* @returns An Express request handler
|
|
656
656
|
*/
|
|
657
657
|
logging() {
|
|
658
|
-
const logger = __privateGet$
|
|
658
|
+
const logger = __privateGet$8(this, _logger).child({
|
|
659
659
|
type: "incomingRequest"
|
|
660
660
|
});
|
|
661
661
|
return morgan__default["default"]("combined", {
|
|
@@ -679,7 +679,7 @@ const _MiddlewareFactory = class _MiddlewareFactory {
|
|
|
679
679
|
* @returns An Express request handler
|
|
680
680
|
*/
|
|
681
681
|
helmet() {
|
|
682
|
-
return helmet__default["default"](readHelmetOptions(__privateGet$
|
|
682
|
+
return helmet__default["default"](readHelmetOptions(__privateGet$8(this, _config).getOptionalConfig("backend")));
|
|
683
683
|
}
|
|
684
684
|
/**
|
|
685
685
|
* Returns a middleware that implements the cors library.
|
|
@@ -694,7 +694,7 @@ const _MiddlewareFactory = class _MiddlewareFactory {
|
|
|
694
694
|
* @returns An Express request handler
|
|
695
695
|
*/
|
|
696
696
|
cors() {
|
|
697
|
-
return cors__default["default"](readCorsOptions(__privateGet$
|
|
697
|
+
return cors__default["default"](readCorsOptions(__privateGet$8(this, _config).getOptionalConfig("backend")));
|
|
698
698
|
}
|
|
699
699
|
/**
|
|
700
700
|
* Express middleware to handle errors during request processing.
|
|
@@ -719,7 +719,7 @@ const _MiddlewareFactory = class _MiddlewareFactory {
|
|
|
719
719
|
error(options = {}) {
|
|
720
720
|
var _a;
|
|
721
721
|
const showStackTraces = (_a = options.showStackTraces) != null ? _a : process.env.NODE_ENV === "development";
|
|
722
|
-
const logger = __privateGet$
|
|
722
|
+
const logger = __privateGet$8(this, _logger).child({
|
|
723
723
|
type: "errorHandler"
|
|
724
724
|
});
|
|
725
725
|
return (error, req, res, next) => {
|
|
@@ -777,31 +777,31 @@ const escapeRegExp = (text) => {
|
|
|
777
777
|
return text.replace(/[.*+?^${}(\)|[\]\\]/g, "\\$&");
|
|
778
778
|
};
|
|
779
779
|
|
|
780
|
-
var __accessCheck$
|
|
780
|
+
var __accessCheck$7 = (obj, member, msg) => {
|
|
781
781
|
if (!member.has(obj))
|
|
782
782
|
throw TypeError("Cannot " + msg);
|
|
783
783
|
};
|
|
784
|
-
var __privateGet$
|
|
785
|
-
__accessCheck$
|
|
784
|
+
var __privateGet$7 = (obj, member, getter) => {
|
|
785
|
+
__accessCheck$7(obj, member, "read from private field");
|
|
786
786
|
return getter ? getter.call(obj) : member.get(obj);
|
|
787
787
|
};
|
|
788
|
-
var __privateAdd$
|
|
788
|
+
var __privateAdd$7 = (obj, member, value) => {
|
|
789
789
|
if (member.has(obj))
|
|
790
790
|
throw TypeError("Cannot add the same private member more than once");
|
|
791
791
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
792
792
|
};
|
|
793
|
-
var __privateSet$
|
|
794
|
-
__accessCheck$
|
|
793
|
+
var __privateSet$7 = (obj, member, value, setter) => {
|
|
794
|
+
__accessCheck$7(obj, member, "write to private field");
|
|
795
795
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
796
796
|
return value;
|
|
797
797
|
};
|
|
798
798
|
var _winston, _addRedactions;
|
|
799
799
|
const _WinstonLogger = class _WinstonLogger {
|
|
800
800
|
constructor(winston, addRedactions) {
|
|
801
|
-
__privateAdd$
|
|
802
|
-
__privateAdd$
|
|
803
|
-
__privateSet$
|
|
804
|
-
__privateSet$
|
|
801
|
+
__privateAdd$7(this, _winston, void 0);
|
|
802
|
+
__privateAdd$7(this, _addRedactions, void 0);
|
|
803
|
+
__privateSet$7(this, _winston, winston);
|
|
804
|
+
__privateSet$7(this, _addRedactions, addRedactions);
|
|
805
805
|
}
|
|
806
806
|
/**
|
|
807
807
|
* Creates a {@link WinstonLogger} instance.
|
|
@@ -878,44 +878,44 @@ const _WinstonLogger = class _WinstonLogger {
|
|
|
878
878
|
);
|
|
879
879
|
}
|
|
880
880
|
error(message, meta) {
|
|
881
|
-
__privateGet$
|
|
881
|
+
__privateGet$7(this, _winston).error(message, meta);
|
|
882
882
|
}
|
|
883
883
|
warn(message, meta) {
|
|
884
|
-
__privateGet$
|
|
884
|
+
__privateGet$7(this, _winston).warn(message, meta);
|
|
885
885
|
}
|
|
886
886
|
info(message, meta) {
|
|
887
|
-
__privateGet$
|
|
887
|
+
__privateGet$7(this, _winston).info(message, meta);
|
|
888
888
|
}
|
|
889
889
|
debug(message, meta) {
|
|
890
|
-
__privateGet$
|
|
890
|
+
__privateGet$7(this, _winston).debug(message, meta);
|
|
891
891
|
}
|
|
892
892
|
child(meta) {
|
|
893
|
-
return new _WinstonLogger(__privateGet$
|
|
893
|
+
return new _WinstonLogger(__privateGet$7(this, _winston).child(meta));
|
|
894
894
|
}
|
|
895
895
|
addRedactions(redactions) {
|
|
896
896
|
var _a;
|
|
897
|
-
(_a = __privateGet$
|
|
897
|
+
(_a = __privateGet$7(this, _addRedactions)) == null ? void 0 : _a.call(this, redactions);
|
|
898
898
|
}
|
|
899
899
|
};
|
|
900
900
|
_winston = new WeakMap();
|
|
901
901
|
_addRedactions = new WeakMap();
|
|
902
902
|
let WinstonLogger = _WinstonLogger;
|
|
903
903
|
|
|
904
|
-
var __accessCheck$
|
|
904
|
+
var __accessCheck$6 = (obj, member, msg) => {
|
|
905
905
|
if (!member.has(obj))
|
|
906
906
|
throw TypeError("Cannot " + msg);
|
|
907
907
|
};
|
|
908
|
-
var __privateGet$
|
|
909
|
-
__accessCheck$
|
|
908
|
+
var __privateGet$6 = (obj, member, getter) => {
|
|
909
|
+
__accessCheck$6(obj, member, "read from private field");
|
|
910
910
|
return getter ? getter.call(obj) : member.get(obj);
|
|
911
911
|
};
|
|
912
|
-
var __privateAdd$
|
|
912
|
+
var __privateAdd$6 = (obj, member, value) => {
|
|
913
913
|
if (member.has(obj))
|
|
914
914
|
throw TypeError("Cannot add the same private member more than once");
|
|
915
915
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
916
916
|
};
|
|
917
|
-
var __privateSet$
|
|
918
|
-
__accessCheck$
|
|
917
|
+
var __privateSet$6 = (obj, member, value, setter) => {
|
|
918
|
+
__accessCheck$6(obj, member, "write to private field");
|
|
919
919
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
920
920
|
return value;
|
|
921
921
|
};
|
|
@@ -923,25 +923,25 @@ var _hasStarted$1, _startupTasks$1, _hasShutdown, _shutdownTasks;
|
|
|
923
923
|
class BackendLifecycleImpl {
|
|
924
924
|
constructor(logger) {
|
|
925
925
|
this.logger = logger;
|
|
926
|
-
__privateAdd$
|
|
927
|
-
__privateAdd$
|
|
928
|
-
__privateAdd$
|
|
929
|
-
__privateAdd$
|
|
926
|
+
__privateAdd$6(this, _hasStarted$1, false);
|
|
927
|
+
__privateAdd$6(this, _startupTasks$1, []);
|
|
928
|
+
__privateAdd$6(this, _hasShutdown, false);
|
|
929
|
+
__privateAdd$6(this, _shutdownTasks, []);
|
|
930
930
|
}
|
|
931
931
|
addStartupHook(hook, options) {
|
|
932
|
-
if (__privateGet$
|
|
932
|
+
if (__privateGet$6(this, _hasStarted$1)) {
|
|
933
933
|
throw new Error("Attempted to add startup hook after startup");
|
|
934
934
|
}
|
|
935
|
-
__privateGet$
|
|
935
|
+
__privateGet$6(this, _startupTasks$1).push({ hook, options });
|
|
936
936
|
}
|
|
937
937
|
async startup() {
|
|
938
|
-
if (__privateGet$
|
|
938
|
+
if (__privateGet$6(this, _hasStarted$1)) {
|
|
939
939
|
return;
|
|
940
940
|
}
|
|
941
|
-
__privateSet$
|
|
942
|
-
this.logger.debug(`Running ${__privateGet$
|
|
941
|
+
__privateSet$6(this, _hasStarted$1, true);
|
|
942
|
+
this.logger.debug(`Running ${__privateGet$6(this, _startupTasks$1).length} startup tasks...`);
|
|
943
943
|
await Promise.all(
|
|
944
|
-
__privateGet$
|
|
944
|
+
__privateGet$6(this, _startupTasks$1).map(async ({ hook, options }) => {
|
|
945
945
|
var _a;
|
|
946
946
|
const logger = (_a = options == null ? void 0 : options.logger) != null ? _a : this.logger;
|
|
947
947
|
try {
|
|
@@ -954,21 +954,21 @@ class BackendLifecycleImpl {
|
|
|
954
954
|
);
|
|
955
955
|
}
|
|
956
956
|
addShutdownHook(hook, options) {
|
|
957
|
-
if (__privateGet$
|
|
957
|
+
if (__privateGet$6(this, _hasShutdown)) {
|
|
958
958
|
throw new Error("Attempted to add shutdown hook after shutdown");
|
|
959
959
|
}
|
|
960
|
-
__privateGet$
|
|
960
|
+
__privateGet$6(this, _shutdownTasks).push({ hook, options });
|
|
961
961
|
}
|
|
962
962
|
async shutdown() {
|
|
963
|
-
if (__privateGet$
|
|
963
|
+
if (__privateGet$6(this, _hasShutdown)) {
|
|
964
964
|
return;
|
|
965
965
|
}
|
|
966
|
-
__privateSet$
|
|
966
|
+
__privateSet$6(this, _hasShutdown, true);
|
|
967
967
|
this.logger.debug(
|
|
968
|
-
`Running ${__privateGet$
|
|
968
|
+
`Running ${__privateGet$6(this, _shutdownTasks).length} shutdown tasks...`
|
|
969
969
|
);
|
|
970
970
|
await Promise.all(
|
|
971
|
-
__privateGet$
|
|
971
|
+
__privateGet$6(this, _shutdownTasks).map(async ({ hook, options }) => {
|
|
972
972
|
var _a;
|
|
973
973
|
const logger = (_a = options == null ? void 0 : options.logger) != null ? _a : this.logger;
|
|
974
974
|
try {
|
|
@@ -995,21 +995,21 @@ const rootLifecycleServiceFactory = backendPluginApi.createServiceFactory({
|
|
|
995
995
|
}
|
|
996
996
|
});
|
|
997
997
|
|
|
998
|
-
var __accessCheck$
|
|
998
|
+
var __accessCheck$5 = (obj, member, msg) => {
|
|
999
999
|
if (!member.has(obj))
|
|
1000
1000
|
throw TypeError("Cannot " + msg);
|
|
1001
1001
|
};
|
|
1002
|
-
var __privateGet$
|
|
1003
|
-
__accessCheck$
|
|
1002
|
+
var __privateGet$5 = (obj, member, getter) => {
|
|
1003
|
+
__accessCheck$5(obj, member, "read from private field");
|
|
1004
1004
|
return getter ? getter.call(obj) : member.get(obj);
|
|
1005
1005
|
};
|
|
1006
|
-
var __privateAdd$
|
|
1006
|
+
var __privateAdd$5 = (obj, member, value) => {
|
|
1007
1007
|
if (member.has(obj))
|
|
1008
1008
|
throw TypeError("Cannot add the same private member more than once");
|
|
1009
1009
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1010
1010
|
};
|
|
1011
|
-
var __privateSet$
|
|
1012
|
-
__accessCheck$
|
|
1011
|
+
var __privateSet$5 = (obj, member, value, setter) => {
|
|
1012
|
+
__accessCheck$5(obj, member, "write to private field");
|
|
1013
1013
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1014
1014
|
return value;
|
|
1015
1015
|
};
|
|
@@ -1019,25 +1019,25 @@ class BackendPluginLifecycleImpl {
|
|
|
1019
1019
|
this.logger = logger;
|
|
1020
1020
|
this.rootLifecycle = rootLifecycle;
|
|
1021
1021
|
this.pluginMetadata = pluginMetadata;
|
|
1022
|
-
__privateAdd$
|
|
1023
|
-
__privateAdd$
|
|
1022
|
+
__privateAdd$5(this, _hasStarted, false);
|
|
1023
|
+
__privateAdd$5(this, _startupTasks, []);
|
|
1024
1024
|
}
|
|
1025
1025
|
addStartupHook(hook, options) {
|
|
1026
|
-
if (__privateGet$
|
|
1026
|
+
if (__privateGet$5(this, _hasStarted)) {
|
|
1027
1027
|
throw new Error("Attempted to add startup hook after startup");
|
|
1028
1028
|
}
|
|
1029
|
-
__privateGet$
|
|
1029
|
+
__privateGet$5(this, _startupTasks).push({ hook, options });
|
|
1030
1030
|
}
|
|
1031
1031
|
async startup() {
|
|
1032
|
-
if (__privateGet$
|
|
1032
|
+
if (__privateGet$5(this, _hasStarted)) {
|
|
1033
1033
|
return;
|
|
1034
1034
|
}
|
|
1035
|
-
__privateSet$
|
|
1035
|
+
__privateSet$5(this, _hasStarted, true);
|
|
1036
1036
|
this.logger.debug(
|
|
1037
|
-
`Running ${__privateGet$
|
|
1037
|
+
`Running ${__privateGet$5(this, _startupTasks).length} plugin startup tasks...`
|
|
1038
1038
|
);
|
|
1039
1039
|
await Promise.all(
|
|
1040
|
-
__privateGet$
|
|
1040
|
+
__privateGet$5(this, _startupTasks).map(async ({ hook, options }) => {
|
|
1041
1041
|
var _a;
|
|
1042
1042
|
const logger = (_a = options == null ? void 0 : options.logger) != null ? _a : this.logger;
|
|
1043
1043
|
try {
|
|
@@ -1075,6 +1075,169 @@ const lifecycleServiceFactory = backendPluginApi.createServiceFactory({
|
|
|
1075
1075
|
}
|
|
1076
1076
|
});
|
|
1077
1077
|
|
|
1078
|
+
var __accessCheck$4 = (obj, member, msg) => {
|
|
1079
|
+
if (!member.has(obj))
|
|
1080
|
+
throw TypeError("Cannot " + msg);
|
|
1081
|
+
};
|
|
1082
|
+
var __privateGet$4 = (obj, member, getter) => {
|
|
1083
|
+
__accessCheck$4(obj, member, "read from private field");
|
|
1084
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
1085
|
+
};
|
|
1086
|
+
var __privateAdd$4 = (obj, member, value) => {
|
|
1087
|
+
if (member.has(obj))
|
|
1088
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
1089
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1090
|
+
};
|
|
1091
|
+
var __privateSet$4 = (obj, member, value, setter) => {
|
|
1092
|
+
__accessCheck$4(obj, member, "write to private field");
|
|
1093
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1094
|
+
return value;
|
|
1095
|
+
};
|
|
1096
|
+
var _nodes, _allProvided;
|
|
1097
|
+
class Node {
|
|
1098
|
+
constructor(value, consumes, provides) {
|
|
1099
|
+
this.value = value;
|
|
1100
|
+
this.consumes = consumes;
|
|
1101
|
+
this.provides = provides;
|
|
1102
|
+
}
|
|
1103
|
+
static from(input) {
|
|
1104
|
+
return new Node(
|
|
1105
|
+
input.value,
|
|
1106
|
+
input.consumes ? new Set(input.consumes) : /* @__PURE__ */ new Set(),
|
|
1107
|
+
input.provides ? new Set(input.provides) : /* @__PURE__ */ new Set()
|
|
1108
|
+
);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
const _DependencyGraph = class _DependencyGraph {
|
|
1112
|
+
constructor(nodes) {
|
|
1113
|
+
__privateAdd$4(this, _nodes, void 0);
|
|
1114
|
+
__privateAdd$4(this, _allProvided, void 0);
|
|
1115
|
+
__privateSet$4(this, _nodes, nodes);
|
|
1116
|
+
__privateSet$4(this, _allProvided, /* @__PURE__ */ new Set());
|
|
1117
|
+
for (const node of __privateGet$4(this, _nodes).values()) {
|
|
1118
|
+
for (const produced of node.provides) {
|
|
1119
|
+
__privateGet$4(this, _allProvided).add(produced);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
static fromMap(nodes) {
|
|
1124
|
+
return this.fromIterable(
|
|
1125
|
+
Object.entries(nodes).map(([key, node]) => ({
|
|
1126
|
+
value: String(key),
|
|
1127
|
+
...node
|
|
1128
|
+
}))
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
static fromIterable(nodeInputs) {
|
|
1132
|
+
const nodes = new Array();
|
|
1133
|
+
for (const nodeInput of nodeInputs) {
|
|
1134
|
+
nodes.push(Node.from(nodeInput));
|
|
1135
|
+
}
|
|
1136
|
+
return new _DependencyGraph(nodes);
|
|
1137
|
+
}
|
|
1138
|
+
// Find all nodes that consume dependencies that are not provided by any other node
|
|
1139
|
+
findUnsatisfiedDeps() {
|
|
1140
|
+
const unsatisfiedDependencies = [];
|
|
1141
|
+
for (const node of __privateGet$4(this, _nodes).values()) {
|
|
1142
|
+
const unsatisfied = Array.from(node.consumes).filter(
|
|
1143
|
+
(id) => !__privateGet$4(this, _allProvided).has(id)
|
|
1144
|
+
);
|
|
1145
|
+
if (unsatisfied.length > 0) {
|
|
1146
|
+
unsatisfiedDependencies.push({ value: node.value, unsatisfied });
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
return unsatisfiedDependencies;
|
|
1150
|
+
}
|
|
1151
|
+
// Detect circular dependencies within the graph, returning the path of nodes that
|
|
1152
|
+
// form a cycle, with the same node as the first and last element of the array.
|
|
1153
|
+
detectCircularDependency() {
|
|
1154
|
+
for (const startNode of __privateGet$4(this, _nodes)) {
|
|
1155
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1156
|
+
const stack = new Array([
|
|
1157
|
+
startNode,
|
|
1158
|
+
[startNode.value]
|
|
1159
|
+
]);
|
|
1160
|
+
while (stack.length > 0) {
|
|
1161
|
+
const [node, path] = stack.pop();
|
|
1162
|
+
if (visited.has(node)) {
|
|
1163
|
+
continue;
|
|
1164
|
+
}
|
|
1165
|
+
visited.add(node);
|
|
1166
|
+
for (const produced of node.provides) {
|
|
1167
|
+
const consumerNodes = __privateGet$4(this, _nodes).filter(
|
|
1168
|
+
(other) => other.consumes.has(produced)
|
|
1169
|
+
);
|
|
1170
|
+
for (const consumer of consumerNodes) {
|
|
1171
|
+
if (consumer === startNode) {
|
|
1172
|
+
return [...path, startNode.value];
|
|
1173
|
+
}
|
|
1174
|
+
if (!visited.has(consumer)) {
|
|
1175
|
+
stack.push([consumer, [...path, consumer.value]]);
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
return void 0;
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* Traverses the dependency graph in topological order, calling the provided
|
|
1185
|
+
* function for each node and waiting for it to resolve.
|
|
1186
|
+
*
|
|
1187
|
+
* The nodes are traversed in parallel, but in such a way that no node is
|
|
1188
|
+
* visited before all of its dependencies.
|
|
1189
|
+
*
|
|
1190
|
+
* Dependencies of nodes that are not produced by any other nodes will be ignored.
|
|
1191
|
+
*/
|
|
1192
|
+
async parallelTopologicalTraversal(fn) {
|
|
1193
|
+
const allProvided = __privateGet$4(this, _allProvided);
|
|
1194
|
+
const producedSoFar = /* @__PURE__ */ new Set();
|
|
1195
|
+
const waiting = new Set(__privateGet$4(this, _nodes).values());
|
|
1196
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1197
|
+
const results = new Array();
|
|
1198
|
+
let inFlight = 0;
|
|
1199
|
+
async function processMoreNodes() {
|
|
1200
|
+
if (waiting.size === 0) {
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
const nodesToProcess = [];
|
|
1204
|
+
for (const node of waiting) {
|
|
1205
|
+
let ready = true;
|
|
1206
|
+
for (const consumed of node.consumes) {
|
|
1207
|
+
if (allProvided.has(consumed) && !producedSoFar.has(consumed)) {
|
|
1208
|
+
ready = false;
|
|
1209
|
+
continue;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
if (ready) {
|
|
1213
|
+
nodesToProcess.push(node);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
for (const node of nodesToProcess) {
|
|
1217
|
+
waiting.delete(node);
|
|
1218
|
+
}
|
|
1219
|
+
if (nodesToProcess.length === 0 && inFlight === 0) {
|
|
1220
|
+
throw new Error("Circular dependency detected");
|
|
1221
|
+
}
|
|
1222
|
+
await Promise.all(nodesToProcess.map(processNode));
|
|
1223
|
+
}
|
|
1224
|
+
async function processNode(node) {
|
|
1225
|
+
visited.add(node);
|
|
1226
|
+
inFlight += 1;
|
|
1227
|
+
const result = await fn(node.value);
|
|
1228
|
+
results.push(result);
|
|
1229
|
+
node.provides.forEach((produced) => producedSoFar.add(produced));
|
|
1230
|
+
inFlight -= 1;
|
|
1231
|
+
await processMoreNodes();
|
|
1232
|
+
}
|
|
1233
|
+
await processMoreNodes();
|
|
1234
|
+
return results;
|
|
1235
|
+
}
|
|
1236
|
+
};
|
|
1237
|
+
_nodes = new WeakMap();
|
|
1238
|
+
_allProvided = new WeakMap();
|
|
1239
|
+
let DependencyGraph = _DependencyGraph;
|
|
1240
|
+
|
|
1078
1241
|
var __accessCheck$3 = (obj, member, msg) => {
|
|
1079
1242
|
if (!member.has(obj))
|
|
1080
1243
|
throw TypeError("Cannot " + msg);
|
|
@@ -1097,29 +1260,214 @@ var __privateMethod$2 = (obj, member, method) => {
|
|
|
1097
1260
|
__accessCheck$3(obj, member, "access private method");
|
|
1098
1261
|
return method;
|
|
1099
1262
|
};
|
|
1100
|
-
var
|
|
1263
|
+
var _providedFactories, _loadedDefaultFactories, _implementations, _rootServiceImplementations, _resolveFactory, resolveFactory_fn, _checkForMissingDeps, checkForMissingDeps_fn;
|
|
1264
|
+
function toInternalServiceFactory(factory) {
|
|
1265
|
+
const f = factory;
|
|
1266
|
+
if (f.$$type !== "@backstage/BackendFeature") {
|
|
1267
|
+
throw new Error(`Invalid service factory, bad type '${f.$$type}'`);
|
|
1268
|
+
}
|
|
1269
|
+
if (f.version !== "v1") {
|
|
1270
|
+
throw new Error(`Invalid service factory, bad version '${f.version}'`);
|
|
1271
|
+
}
|
|
1272
|
+
return f;
|
|
1273
|
+
}
|
|
1274
|
+
const pluginMetadataServiceFactory = backendPluginApi.createServiceFactory(
|
|
1275
|
+
(options) => ({
|
|
1276
|
+
service: backendPluginApi.coreServices.pluginMetadata,
|
|
1277
|
+
deps: {},
|
|
1278
|
+
factory: async () => ({ getId: () => options == null ? void 0 : options.pluginId })
|
|
1279
|
+
})
|
|
1280
|
+
);
|
|
1281
|
+
class ServiceRegistry {
|
|
1282
|
+
constructor(factories) {
|
|
1283
|
+
__privateAdd$3(this, _resolveFactory);
|
|
1284
|
+
__privateAdd$3(this, _checkForMissingDeps);
|
|
1285
|
+
__privateAdd$3(this, _providedFactories, void 0);
|
|
1286
|
+
__privateAdd$3(this, _loadedDefaultFactories, void 0);
|
|
1287
|
+
__privateAdd$3(this, _implementations, void 0);
|
|
1288
|
+
__privateAdd$3(this, _rootServiceImplementations, /* @__PURE__ */ new Map());
|
|
1289
|
+
__privateSet$3(this, _providedFactories, new Map(
|
|
1290
|
+
factories.map((sf) => [sf.service.id, toInternalServiceFactory(sf)])
|
|
1291
|
+
));
|
|
1292
|
+
__privateSet$3(this, _loadedDefaultFactories, /* @__PURE__ */ new Map());
|
|
1293
|
+
__privateSet$3(this, _implementations, /* @__PURE__ */ new Map());
|
|
1294
|
+
}
|
|
1295
|
+
getServiceRefs() {
|
|
1296
|
+
return Array.from(__privateGet$3(this, _providedFactories).values()).map((f) => f.service);
|
|
1297
|
+
}
|
|
1298
|
+
get(ref, pluginId) {
|
|
1299
|
+
var _a;
|
|
1300
|
+
return (_a = __privateMethod$2(this, _resolveFactory, resolveFactory_fn).call(this, ref, pluginId)) == null ? void 0 : _a.then((factory) => {
|
|
1301
|
+
if (factory.service.scope === "root") {
|
|
1302
|
+
let existing = __privateGet$3(this, _rootServiceImplementations).get(factory);
|
|
1303
|
+
if (!existing) {
|
|
1304
|
+
__privateMethod$2(this, _checkForMissingDeps, checkForMissingDeps_fn).call(this, factory, pluginId);
|
|
1305
|
+
const rootDeps = new Array();
|
|
1306
|
+
for (const [name, serviceRef] of Object.entries(factory.deps)) {
|
|
1307
|
+
if (serviceRef.scope !== "root") {
|
|
1308
|
+
throw new Error(
|
|
1309
|
+
`Failed to instantiate 'root' scoped service '${ref.id}' because it depends on '${serviceRef.scope}' scoped service '${serviceRef.id}'.`
|
|
1310
|
+
);
|
|
1311
|
+
}
|
|
1312
|
+
const target = this.get(serviceRef, pluginId);
|
|
1313
|
+
rootDeps.push(target.then((impl) => [name, impl]));
|
|
1314
|
+
}
|
|
1315
|
+
existing = Promise.all(rootDeps).then(
|
|
1316
|
+
(entries) => factory.factory(Object.fromEntries(entries), void 0)
|
|
1317
|
+
);
|
|
1318
|
+
__privateGet$3(this, _rootServiceImplementations).set(factory, existing);
|
|
1319
|
+
}
|
|
1320
|
+
return existing;
|
|
1321
|
+
}
|
|
1322
|
+
let implementation = __privateGet$3(this, _implementations).get(factory);
|
|
1323
|
+
if (!implementation) {
|
|
1324
|
+
__privateMethod$2(this, _checkForMissingDeps, checkForMissingDeps_fn).call(this, factory, pluginId);
|
|
1325
|
+
const rootDeps = new Array();
|
|
1326
|
+
for (const [name, serviceRef] of Object.entries(factory.deps)) {
|
|
1327
|
+
if (serviceRef.scope === "root") {
|
|
1328
|
+
const target = this.get(serviceRef, pluginId);
|
|
1329
|
+
rootDeps.push(target.then((impl) => [name, impl]));
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
implementation = {
|
|
1333
|
+
context: Promise.all(rootDeps).then(
|
|
1334
|
+
(entries) => {
|
|
1335
|
+
var _a2;
|
|
1336
|
+
return (_a2 = factory.createRootContext) == null ? void 0 : _a2.call(factory, Object.fromEntries(entries));
|
|
1337
|
+
}
|
|
1338
|
+
).catch((error) => {
|
|
1339
|
+
const cause = errors.stringifyError(error);
|
|
1340
|
+
throw new Error(
|
|
1341
|
+
`Failed to instantiate service '${ref.id}' because createRootContext threw an error, ${cause}`
|
|
1342
|
+
);
|
|
1343
|
+
}),
|
|
1344
|
+
byPlugin: /* @__PURE__ */ new Map()
|
|
1345
|
+
};
|
|
1346
|
+
__privateGet$3(this, _implementations).set(factory, implementation);
|
|
1347
|
+
}
|
|
1348
|
+
let result = implementation.byPlugin.get(pluginId);
|
|
1349
|
+
if (!result) {
|
|
1350
|
+
const allDeps = new Array();
|
|
1351
|
+
for (const [name, serviceRef] of Object.entries(factory.deps)) {
|
|
1352
|
+
const target = this.get(serviceRef, pluginId);
|
|
1353
|
+
allDeps.push(target.then((impl) => [name, impl]));
|
|
1354
|
+
}
|
|
1355
|
+
result = implementation.context.then(
|
|
1356
|
+
(context) => Promise.all(allDeps).then(
|
|
1357
|
+
(entries) => factory.factory(Object.fromEntries(entries), context)
|
|
1358
|
+
)
|
|
1359
|
+
).catch((error) => {
|
|
1360
|
+
const cause = errors.stringifyError(error);
|
|
1361
|
+
throw new Error(
|
|
1362
|
+
`Failed to instantiate service '${ref.id}' for '${pluginId}' because the factory function threw an error, ${cause}`
|
|
1363
|
+
);
|
|
1364
|
+
});
|
|
1365
|
+
implementation.byPlugin.set(pluginId, result);
|
|
1366
|
+
}
|
|
1367
|
+
return result;
|
|
1368
|
+
});
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
_providedFactories = new WeakMap();
|
|
1372
|
+
_loadedDefaultFactories = new WeakMap();
|
|
1373
|
+
_implementations = new WeakMap();
|
|
1374
|
+
_rootServiceImplementations = new WeakMap();
|
|
1375
|
+
_resolveFactory = new WeakSet();
|
|
1376
|
+
resolveFactory_fn = function(ref, pluginId) {
|
|
1377
|
+
if (ref.id === backendPluginApi.coreServices.pluginMetadata.id) {
|
|
1378
|
+
return Promise.resolve(
|
|
1379
|
+
toInternalServiceFactory(pluginMetadataServiceFactory({ pluginId }))
|
|
1380
|
+
);
|
|
1381
|
+
}
|
|
1382
|
+
let resolvedFactory = __privateGet$3(this, _providedFactories).get(ref.id);
|
|
1383
|
+
const { __defaultFactory: defaultFactory } = ref;
|
|
1384
|
+
if (!resolvedFactory && !defaultFactory) {
|
|
1385
|
+
return void 0;
|
|
1386
|
+
}
|
|
1387
|
+
if (!resolvedFactory) {
|
|
1388
|
+
let loadedFactory = __privateGet$3(this, _loadedDefaultFactories).get(defaultFactory);
|
|
1389
|
+
if (!loadedFactory) {
|
|
1390
|
+
loadedFactory = Promise.resolve().then(() => defaultFactory(ref)).then(
|
|
1391
|
+
(f) => toInternalServiceFactory(typeof f === "function" ? f() : f)
|
|
1392
|
+
);
|
|
1393
|
+
__privateGet$3(this, _loadedDefaultFactories).set(defaultFactory, loadedFactory);
|
|
1394
|
+
}
|
|
1395
|
+
resolvedFactory = loadedFactory.catch((error) => {
|
|
1396
|
+
throw new Error(
|
|
1397
|
+
`Failed to instantiate service '${ref.id}' because the default factory loader threw an error, ${errors.stringifyError(
|
|
1398
|
+
error
|
|
1399
|
+
)}`
|
|
1400
|
+
);
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
return Promise.resolve(resolvedFactory);
|
|
1404
|
+
};
|
|
1405
|
+
_checkForMissingDeps = new WeakSet();
|
|
1406
|
+
checkForMissingDeps_fn = function(factory, pluginId) {
|
|
1407
|
+
const missingDeps = Object.values(factory.deps).filter((ref) => {
|
|
1408
|
+
if (ref.id === backendPluginApi.coreServices.pluginMetadata.id) {
|
|
1409
|
+
return false;
|
|
1410
|
+
}
|
|
1411
|
+
if (__privateGet$3(this, _providedFactories).get(ref.id)) {
|
|
1412
|
+
return false;
|
|
1413
|
+
}
|
|
1414
|
+
return !ref.__defaultFactory;
|
|
1415
|
+
});
|
|
1416
|
+
if (missingDeps.length) {
|
|
1417
|
+
const missing = missingDeps.map((r) => `'${r.id}'`).join(", ");
|
|
1418
|
+
throw new Error(
|
|
1419
|
+
`Failed to instantiate service '${factory.service.id}' for '${pluginId}' because the following dependent services are missing: ${missing}`
|
|
1420
|
+
);
|
|
1421
|
+
}
|
|
1422
|
+
};
|
|
1423
|
+
|
|
1424
|
+
var __accessCheck$2 = (obj, member, msg) => {
|
|
1425
|
+
if (!member.has(obj))
|
|
1426
|
+
throw TypeError("Cannot " + msg);
|
|
1427
|
+
};
|
|
1428
|
+
var __privateGet$2 = (obj, member, getter) => {
|
|
1429
|
+
__accessCheck$2(obj, member, "read from private field");
|
|
1430
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
1431
|
+
};
|
|
1432
|
+
var __privateAdd$2 = (obj, member, value) => {
|
|
1433
|
+
if (member.has(obj))
|
|
1434
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
1435
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1436
|
+
};
|
|
1437
|
+
var __privateSet$2 = (obj, member, value, setter) => {
|
|
1438
|
+
__accessCheck$2(obj, member, "write to private field");
|
|
1439
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1440
|
+
return value;
|
|
1441
|
+
};
|
|
1442
|
+
var __privateMethod$1 = (obj, member, method) => {
|
|
1443
|
+
__accessCheck$2(obj, member, "access private method");
|
|
1444
|
+
return method;
|
|
1445
|
+
};
|
|
1446
|
+
var _startPromise, _features, _extensionPoints, _serviceHolder, _providedServiceFactories, _defaultApiFactories, _getInitDeps, getInitDeps_fn, _addFeature, addFeature_fn, _doStart, doStart_fn, _getRootLifecycleImpl, getRootLifecycleImpl_fn, _getPluginLifecycleImpl, getPluginLifecycleImpl_fn;
|
|
1101
1447
|
class BackendInitializer {
|
|
1102
|
-
constructor(
|
|
1103
|
-
__privateAdd$
|
|
1104
|
-
__privateAdd$
|
|
1105
|
-
__privateAdd$
|
|
1448
|
+
constructor(defaultApiFactories) {
|
|
1449
|
+
__privateAdd$2(this, _getInitDeps);
|
|
1450
|
+
__privateAdd$2(this, _addFeature);
|
|
1451
|
+
__privateAdd$2(this, _doStart);
|
|
1106
1452
|
// Bit of a hacky way to grab the lifecycle services, potentially find a nicer way to do this
|
|
1107
|
-
__privateAdd$
|
|
1108
|
-
__privateAdd$
|
|
1109
|
-
__privateAdd$
|
|
1110
|
-
__privateAdd$
|
|
1111
|
-
__privateAdd$
|
|
1112
|
-
__privateAdd$
|
|
1113
|
-
|
|
1453
|
+
__privateAdd$2(this, _getRootLifecycleImpl);
|
|
1454
|
+
__privateAdd$2(this, _getPluginLifecycleImpl);
|
|
1455
|
+
__privateAdd$2(this, _startPromise, void 0);
|
|
1456
|
+
__privateAdd$2(this, _features, new Array());
|
|
1457
|
+
__privateAdd$2(this, _extensionPoints, /* @__PURE__ */ new Map());
|
|
1458
|
+
__privateAdd$2(this, _serviceHolder, void 0);
|
|
1459
|
+
__privateAdd$2(this, _providedServiceFactories, new Array());
|
|
1460
|
+
__privateAdd$2(this, _defaultApiFactories, void 0);
|
|
1461
|
+
__privateSet$2(this, _defaultApiFactories, defaultApiFactories);
|
|
1114
1462
|
}
|
|
1115
1463
|
add(feature) {
|
|
1116
|
-
if (__privateGet$
|
|
1464
|
+
if (__privateGet$2(this, _startPromise)) {
|
|
1117
1465
|
throw new Error("feature can not be added after the backend has started");
|
|
1118
1466
|
}
|
|
1119
|
-
__privateMethod$
|
|
1467
|
+
__privateMethod$1(this, _addFeature, addFeature_fn).call(this, feature);
|
|
1120
1468
|
}
|
|
1121
1469
|
async start() {
|
|
1122
|
-
if (__privateGet$
|
|
1470
|
+
if (__privateGet$2(this, _startPromise)) {
|
|
1123
1471
|
throw new Error("Backend has already started");
|
|
1124
1472
|
}
|
|
1125
1473
|
const exitHandler = async () => {
|
|
@@ -1137,18 +1485,18 @@ class BackendInitializer {
|
|
|
1137
1485
|
process.addListener("SIGTERM", exitHandler);
|
|
1138
1486
|
process.addListener("SIGINT", exitHandler);
|
|
1139
1487
|
process.addListener("beforeExit", exitHandler);
|
|
1140
|
-
__privateSet$
|
|
1141
|
-
await __privateGet$
|
|
1488
|
+
__privateSet$2(this, _startPromise, __privateMethod$1(this, _doStart, doStart_fn).call(this));
|
|
1489
|
+
await __privateGet$2(this, _startPromise);
|
|
1142
1490
|
}
|
|
1143
1491
|
async stop() {
|
|
1144
|
-
if (!__privateGet$
|
|
1492
|
+
if (!__privateGet$2(this, _startPromise)) {
|
|
1145
1493
|
return;
|
|
1146
1494
|
}
|
|
1147
1495
|
try {
|
|
1148
|
-
await __privateGet$
|
|
1496
|
+
await __privateGet$2(this, _startPromise);
|
|
1149
1497
|
} catch (error) {
|
|
1150
1498
|
}
|
|
1151
|
-
const lifecycleService = await __privateMethod$
|
|
1499
|
+
const lifecycleService = await __privateMethod$1(this, _getRootLifecycleImpl, getRootLifecycleImpl_fn).call(this);
|
|
1152
1500
|
await lifecycleService.shutdown();
|
|
1153
1501
|
}
|
|
1154
1502
|
}
|
|
@@ -1156,18 +1504,23 @@ _startPromise = new WeakMap();
|
|
|
1156
1504
|
_features = new WeakMap();
|
|
1157
1505
|
_extensionPoints = new WeakMap();
|
|
1158
1506
|
_serviceHolder = new WeakMap();
|
|
1507
|
+
_providedServiceFactories = new WeakMap();
|
|
1508
|
+
_defaultApiFactories = new WeakMap();
|
|
1159
1509
|
_getInitDeps = new WeakSet();
|
|
1160
1510
|
getInitDeps_fn = async function(deps, pluginId) {
|
|
1161
1511
|
const result = /* @__PURE__ */ new Map();
|
|
1162
1512
|
const missingRefs = /* @__PURE__ */ new Set();
|
|
1163
1513
|
for (const [name, ref] of Object.entries(deps)) {
|
|
1164
|
-
const
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1514
|
+
const ep = __privateGet$2(this, _extensionPoints).get(ref);
|
|
1515
|
+
if (ep) {
|
|
1516
|
+
if (ep.pluginId !== pluginId) {
|
|
1517
|
+
throw new Error(
|
|
1518
|
+
`Extension point registered for plugin '${ep.pluginId}' may not be used by module for plugin '${pluginId}'`
|
|
1519
|
+
);
|
|
1520
|
+
}
|
|
1521
|
+
result.set(name, ep.impl);
|
|
1169
1522
|
} else {
|
|
1170
|
-
const impl = await __privateGet$
|
|
1523
|
+
const impl = await __privateGet$2(this, _serviceHolder).get(
|
|
1171
1524
|
ref,
|
|
1172
1525
|
pluginId
|
|
1173
1526
|
);
|
|
@@ -1193,44 +1546,70 @@ addFeature_fn = function(feature) {
|
|
|
1193
1546
|
`Failed to add feature, invalid type '${feature.$$type}'`
|
|
1194
1547
|
);
|
|
1195
1548
|
}
|
|
1196
|
-
|
|
1197
|
-
|
|
1549
|
+
if (isServiceFactory(feature)) {
|
|
1550
|
+
if (feature.service.id === backendPluginApi.coreServices.pluginMetadata.id) {
|
|
1551
|
+
throw new Error(
|
|
1552
|
+
`The ${backendPluginApi.coreServices.pluginMetadata.id} service cannot be overridden`
|
|
1553
|
+
);
|
|
1554
|
+
}
|
|
1555
|
+
if (__privateGet$2(this, _providedServiceFactories).find(
|
|
1556
|
+
(sf) => sf.service.id === feature.service.id
|
|
1557
|
+
)) {
|
|
1558
|
+
throw new Error(
|
|
1559
|
+
`Duplicate service implementations provided for ${feature.service.id}`
|
|
1560
|
+
);
|
|
1561
|
+
}
|
|
1562
|
+
__privateGet$2(this, _providedServiceFactories).push(feature);
|
|
1563
|
+
} else if (isInternalBackendFeature(feature)) {
|
|
1564
|
+
if (feature.version !== "v1") {
|
|
1565
|
+
throw new Error(
|
|
1566
|
+
`Failed to add feature, invalid version '${feature.version}'`
|
|
1567
|
+
);
|
|
1568
|
+
}
|
|
1569
|
+
__privateGet$2(this, _features).push(feature);
|
|
1570
|
+
} else {
|
|
1198
1571
|
throw new Error(
|
|
1199
|
-
`Failed to add feature, invalid
|
|
1572
|
+
`Failed to add feature, invalid feature ${JSON.stringify(feature)}`
|
|
1200
1573
|
);
|
|
1201
1574
|
}
|
|
1202
|
-
__privateGet$3(this, _features).push(internalFeature);
|
|
1203
1575
|
};
|
|
1204
1576
|
_doStart = new WeakSet();
|
|
1205
1577
|
doStart_fn = async function() {
|
|
1206
|
-
|
|
1578
|
+
__privateSet$2(this, _serviceHolder, new ServiceRegistry([
|
|
1579
|
+
...__privateGet$2(this, _defaultApiFactories),
|
|
1580
|
+
...__privateGet$2(this, _providedServiceFactories)
|
|
1581
|
+
]));
|
|
1582
|
+
const featureDiscovery = await __privateGet$2(this, _serviceHolder).get(
|
|
1207
1583
|
alpha.featureDiscoveryServiceRef,
|
|
1208
1584
|
"root"
|
|
1209
1585
|
);
|
|
1210
1586
|
if (featureDiscovery) {
|
|
1211
1587
|
const { features } = await featureDiscovery.getBackendFeatures();
|
|
1212
1588
|
for (const feature of features) {
|
|
1213
|
-
__privateMethod$
|
|
1589
|
+
__privateMethod$1(this, _addFeature, addFeature_fn).call(this, feature);
|
|
1214
1590
|
}
|
|
1215
1591
|
}
|
|
1216
|
-
for (const ref of __privateGet$
|
|
1592
|
+
for (const ref of __privateGet$2(this, _serviceHolder).getServiceRefs()) {
|
|
1217
1593
|
if (ref.scope === "root") {
|
|
1218
|
-
await __privateGet$
|
|
1594
|
+
await __privateGet$2(this, _serviceHolder).get(ref, "root");
|
|
1219
1595
|
}
|
|
1220
1596
|
}
|
|
1221
1597
|
const pluginInits = /* @__PURE__ */ new Map();
|
|
1222
1598
|
const moduleInits = /* @__PURE__ */ new Map();
|
|
1223
|
-
for (const feature of __privateGet$
|
|
1599
|
+
for (const feature of __privateGet$2(this, _features)) {
|
|
1224
1600
|
for (const r of feature.getRegistrations()) {
|
|
1225
1601
|
const provides = /* @__PURE__ */ new Set();
|
|
1226
|
-
if (r.type === "plugin") {
|
|
1602
|
+
if (r.type === "plugin" || r.type === "module") {
|
|
1227
1603
|
for (const [extRef, extImpl] of r.extensionPoints) {
|
|
1228
|
-
if (__privateGet$
|
|
1604
|
+
if (__privateGet$2(this, _extensionPoints).has(extRef)) {
|
|
1229
1605
|
throw new Error(
|
|
1230
1606
|
`ExtensionPoint with ID '${extRef.id}' is already registered`
|
|
1231
1607
|
);
|
|
1232
1608
|
}
|
|
1233
|
-
__privateGet$
|
|
1609
|
+
__privateGet$2(this, _extensionPoints).set(extRef, {
|
|
1610
|
+
impl: extImpl,
|
|
1611
|
+
pluginId: r.pluginId
|
|
1612
|
+
});
|
|
1234
1613
|
provides.add(extRef);
|
|
1235
1614
|
}
|
|
1236
1615
|
}
|
|
@@ -1267,22 +1646,39 @@ doStart_fn = async function() {
|
|
|
1267
1646
|
];
|
|
1268
1647
|
await Promise.all(
|
|
1269
1648
|
allPluginIds.map(async (pluginId) => {
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
)
|
|
1280
|
-
})
|
|
1281
|
-
|
|
1282
|
-
|
|
1649
|
+
const modules = moduleInits.get(pluginId);
|
|
1650
|
+
if (modules) {
|
|
1651
|
+
const tree = DependencyGraph.fromIterable(
|
|
1652
|
+
Array.from(modules).map(([moduleId, moduleInit]) => ({
|
|
1653
|
+
value: { moduleId, moduleInit },
|
|
1654
|
+
// Relationships are reversed at this point since we're only interested in the extension points.
|
|
1655
|
+
// If a modules provides extension point A we want it to be initialized AFTER all modules
|
|
1656
|
+
// that depend on extension point A, so that they can provide their extensions.
|
|
1657
|
+
consumes: Array.from(moduleInit.provides).map((p) => p.id),
|
|
1658
|
+
provides: Array.from(moduleInit.consumes).map((c) => c.id)
|
|
1659
|
+
}))
|
|
1660
|
+
);
|
|
1661
|
+
const circular = tree.detectCircularDependency();
|
|
1662
|
+
if (circular) {
|
|
1663
|
+
throw new errors.ConflictError(
|
|
1664
|
+
`Circular dependency detected for modules of plugin '${pluginId}', ${circular.map(({ moduleId }) => `'${moduleId}'`).join(" -> ")}`
|
|
1665
|
+
);
|
|
1666
|
+
}
|
|
1667
|
+
await tree.parallelTopologicalTraversal(
|
|
1668
|
+
async ({ moduleId, moduleInit }) => {
|
|
1669
|
+
const moduleDeps = await __privateMethod$1(this, _getInitDeps, getInitDeps_fn).call(this, moduleInit.init.deps, pluginId);
|
|
1670
|
+
await moduleInit.init.func(moduleDeps).catch((error) => {
|
|
1671
|
+
throw new errors.ForwardedError(
|
|
1672
|
+
`Module '${moduleId}' for plugin '${pluginId}' startup failed`,
|
|
1673
|
+
error
|
|
1674
|
+
);
|
|
1675
|
+
});
|
|
1676
|
+
}
|
|
1677
|
+
);
|
|
1678
|
+
}
|
|
1283
1679
|
const pluginInit = pluginInits.get(pluginId);
|
|
1284
1680
|
if (pluginInit) {
|
|
1285
|
-
const pluginDeps = await __privateMethod$
|
|
1681
|
+
const pluginDeps = await __privateMethod$1(this, _getInitDeps, getInitDeps_fn).call(this, pluginInit.init.deps, pluginId);
|
|
1286
1682
|
await pluginInit.init.func(pluginDeps).catch((error) => {
|
|
1287
1683
|
throw new errors.ForwardedError(
|
|
1288
1684
|
`Plugin '${pluginId}' startup failed`,
|
|
@@ -1290,14 +1686,14 @@ doStart_fn = async function() {
|
|
|
1290
1686
|
);
|
|
1291
1687
|
});
|
|
1292
1688
|
}
|
|
1293
|
-
const lifecycleService2 = await __privateMethod$
|
|
1689
|
+
const lifecycleService2 = await __privateMethod$1(this, _getPluginLifecycleImpl, getPluginLifecycleImpl_fn).call(this, pluginId);
|
|
1294
1690
|
await lifecycleService2.startup();
|
|
1295
1691
|
})
|
|
1296
1692
|
);
|
|
1297
|
-
const lifecycleService = await __privateMethod$
|
|
1693
|
+
const lifecycleService = await __privateMethod$1(this, _getRootLifecycleImpl, getRootLifecycleImpl_fn).call(this);
|
|
1298
1694
|
await lifecycleService.startup();
|
|
1299
1695
|
if (process.env.NODE_ENV !== "test") {
|
|
1300
|
-
const rootLogger = await __privateGet$
|
|
1696
|
+
const rootLogger = await __privateGet$2(this, _serviceHolder).get(
|
|
1301
1697
|
backendPluginApi.coreServices.rootLogger,
|
|
1302
1698
|
"root"
|
|
1303
1699
|
);
|
|
@@ -1313,7 +1709,7 @@ doStart_fn = async function() {
|
|
|
1313
1709
|
};
|
|
1314
1710
|
_getRootLifecycleImpl = new WeakSet();
|
|
1315
1711
|
getRootLifecycleImpl_fn = async function() {
|
|
1316
|
-
const lifecycleService = await __privateGet$
|
|
1712
|
+
const lifecycleService = await __privateGet$2(this, _serviceHolder).get(
|
|
1317
1713
|
backendPluginApi.coreServices.rootLifecycle,
|
|
1318
1714
|
"root"
|
|
1319
1715
|
);
|
|
@@ -1324,7 +1720,7 @@ getRootLifecycleImpl_fn = async function() {
|
|
|
1324
1720
|
};
|
|
1325
1721
|
_getPluginLifecycleImpl = new WeakSet();
|
|
1326
1722
|
getPluginLifecycleImpl_fn = async function(pluginId) {
|
|
1327
|
-
const lifecycleService = await __privateGet$
|
|
1723
|
+
const lifecycleService = await __privateGet$2(this, _serviceHolder).get(
|
|
1328
1724
|
backendPluginApi.coreServices.lifecycle,
|
|
1329
1725
|
pluginId
|
|
1330
1726
|
);
|
|
@@ -1333,189 +1729,12 @@ getPluginLifecycleImpl_fn = async function(pluginId) {
|
|
|
1333
1729
|
}
|
|
1334
1730
|
throw new Error("Unexpected plugin lifecycle service implementation");
|
|
1335
1731
|
};
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
if (!member.has(obj))
|
|
1339
|
-
throw TypeError("Cannot " + msg);
|
|
1340
|
-
};
|
|
1341
|
-
var __privateGet$2 = (obj, member, getter) => {
|
|
1342
|
-
__accessCheck$2(obj, member, "read from private field");
|
|
1343
|
-
return getter ? getter.call(obj) : member.get(obj);
|
|
1344
|
-
};
|
|
1345
|
-
var __privateAdd$2 = (obj, member, value) => {
|
|
1346
|
-
if (member.has(obj))
|
|
1347
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
1348
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1349
|
-
};
|
|
1350
|
-
var __privateSet$2 = (obj, member, value, setter) => {
|
|
1351
|
-
__accessCheck$2(obj, member, "write to private field");
|
|
1352
|
-
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1353
|
-
return value;
|
|
1354
|
-
};
|
|
1355
|
-
var __privateMethod$1 = (obj, member, method) => {
|
|
1356
|
-
__accessCheck$2(obj, member, "access private method");
|
|
1357
|
-
return method;
|
|
1358
|
-
};
|
|
1359
|
-
var _providedFactories, _loadedDefaultFactories, _implementations, _rootServiceImplementations, _resolveFactory, resolveFactory_fn, _checkForMissingDeps, checkForMissingDeps_fn;
|
|
1360
|
-
function toInternalServiceFactory(factory) {
|
|
1361
|
-
const f = factory;
|
|
1362
|
-
if (f.$$type !== "@backstage/ServiceFactory") {
|
|
1363
|
-
throw new Error(`Invalid service factory, bad type '${f.$$type}'`);
|
|
1364
|
-
}
|
|
1365
|
-
if (f.version !== "v1") {
|
|
1366
|
-
throw new Error(`Invalid service factory, bad version '${f.version}'`);
|
|
1367
|
-
}
|
|
1368
|
-
return f;
|
|
1732
|
+
function isServiceFactory(feature) {
|
|
1733
|
+
return !!feature.service;
|
|
1369
1734
|
}
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
service: backendPluginApi.coreServices.pluginMetadata,
|
|
1373
|
-
deps: {},
|
|
1374
|
-
factory: async () => ({ getId: () => options.pluginId })
|
|
1375
|
-
})
|
|
1376
|
-
);
|
|
1377
|
-
class ServiceRegistry {
|
|
1378
|
-
constructor(factories) {
|
|
1379
|
-
__privateAdd$2(this, _resolveFactory);
|
|
1380
|
-
__privateAdd$2(this, _checkForMissingDeps);
|
|
1381
|
-
__privateAdd$2(this, _providedFactories, void 0);
|
|
1382
|
-
__privateAdd$2(this, _loadedDefaultFactories, void 0);
|
|
1383
|
-
__privateAdd$2(this, _implementations, void 0);
|
|
1384
|
-
__privateAdd$2(this, _rootServiceImplementations, /* @__PURE__ */ new Map());
|
|
1385
|
-
__privateSet$2(this, _providedFactories, new Map(
|
|
1386
|
-
factories.map((sf) => [sf.service.id, toInternalServiceFactory(sf)])
|
|
1387
|
-
));
|
|
1388
|
-
__privateSet$2(this, _loadedDefaultFactories, /* @__PURE__ */ new Map());
|
|
1389
|
-
__privateSet$2(this, _implementations, /* @__PURE__ */ new Map());
|
|
1390
|
-
}
|
|
1391
|
-
getServiceRefs() {
|
|
1392
|
-
return Array.from(__privateGet$2(this, _providedFactories).values()).map((f) => f.service);
|
|
1393
|
-
}
|
|
1394
|
-
get(ref, pluginId) {
|
|
1395
|
-
var _a;
|
|
1396
|
-
return (_a = __privateMethod$1(this, _resolveFactory, resolveFactory_fn).call(this, ref, pluginId)) == null ? void 0 : _a.then((factory) => {
|
|
1397
|
-
if (factory.service.scope === "root") {
|
|
1398
|
-
let existing = __privateGet$2(this, _rootServiceImplementations).get(factory);
|
|
1399
|
-
if (!existing) {
|
|
1400
|
-
__privateMethod$1(this, _checkForMissingDeps, checkForMissingDeps_fn).call(this, factory, pluginId);
|
|
1401
|
-
const rootDeps = new Array();
|
|
1402
|
-
for (const [name, serviceRef] of Object.entries(factory.deps)) {
|
|
1403
|
-
if (serviceRef.scope !== "root") {
|
|
1404
|
-
throw new Error(
|
|
1405
|
-
`Failed to instantiate 'root' scoped service '${ref.id}' because it depends on '${serviceRef.scope}' scoped service '${serviceRef.id}'.`
|
|
1406
|
-
);
|
|
1407
|
-
}
|
|
1408
|
-
const target = this.get(serviceRef, pluginId);
|
|
1409
|
-
rootDeps.push(target.then((impl) => [name, impl]));
|
|
1410
|
-
}
|
|
1411
|
-
existing = Promise.all(rootDeps).then(
|
|
1412
|
-
(entries) => factory.factory(Object.fromEntries(entries), void 0)
|
|
1413
|
-
);
|
|
1414
|
-
__privateGet$2(this, _rootServiceImplementations).set(factory, existing);
|
|
1415
|
-
}
|
|
1416
|
-
return existing;
|
|
1417
|
-
}
|
|
1418
|
-
let implementation = __privateGet$2(this, _implementations).get(factory);
|
|
1419
|
-
if (!implementation) {
|
|
1420
|
-
__privateMethod$1(this, _checkForMissingDeps, checkForMissingDeps_fn).call(this, factory, pluginId);
|
|
1421
|
-
const rootDeps = new Array();
|
|
1422
|
-
for (const [name, serviceRef] of Object.entries(factory.deps)) {
|
|
1423
|
-
if (serviceRef.scope === "root") {
|
|
1424
|
-
const target = this.get(serviceRef, pluginId);
|
|
1425
|
-
rootDeps.push(target.then((impl) => [name, impl]));
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
implementation = {
|
|
1429
|
-
context: Promise.all(rootDeps).then(
|
|
1430
|
-
(entries) => {
|
|
1431
|
-
var _a2;
|
|
1432
|
-
return (_a2 = factory.createRootContext) == null ? void 0 : _a2.call(factory, Object.fromEntries(entries));
|
|
1433
|
-
}
|
|
1434
|
-
).catch((error) => {
|
|
1435
|
-
const cause = errors.stringifyError(error);
|
|
1436
|
-
throw new Error(
|
|
1437
|
-
`Failed to instantiate service '${ref.id}' because createRootContext threw an error, ${cause}`
|
|
1438
|
-
);
|
|
1439
|
-
}),
|
|
1440
|
-
byPlugin: /* @__PURE__ */ new Map()
|
|
1441
|
-
};
|
|
1442
|
-
__privateGet$2(this, _implementations).set(factory, implementation);
|
|
1443
|
-
}
|
|
1444
|
-
let result = implementation.byPlugin.get(pluginId);
|
|
1445
|
-
if (!result) {
|
|
1446
|
-
const allDeps = new Array();
|
|
1447
|
-
for (const [name, serviceRef] of Object.entries(factory.deps)) {
|
|
1448
|
-
const target = this.get(serviceRef, pluginId);
|
|
1449
|
-
allDeps.push(target.then((impl) => [name, impl]));
|
|
1450
|
-
}
|
|
1451
|
-
result = implementation.context.then(
|
|
1452
|
-
(context) => Promise.all(allDeps).then(
|
|
1453
|
-
(entries) => factory.factory(Object.fromEntries(entries), context)
|
|
1454
|
-
)
|
|
1455
|
-
).catch((error) => {
|
|
1456
|
-
const cause = errors.stringifyError(error);
|
|
1457
|
-
throw new Error(
|
|
1458
|
-
`Failed to instantiate service '${ref.id}' for '${pluginId}' because the factory function threw an error, ${cause}`
|
|
1459
|
-
);
|
|
1460
|
-
});
|
|
1461
|
-
implementation.byPlugin.set(pluginId, result);
|
|
1462
|
-
}
|
|
1463
|
-
return result;
|
|
1464
|
-
});
|
|
1465
|
-
}
|
|
1735
|
+
function isInternalBackendFeature(feature) {
|
|
1736
|
+
return typeof feature.getRegistrations === "function";
|
|
1466
1737
|
}
|
|
1467
|
-
_providedFactories = new WeakMap();
|
|
1468
|
-
_loadedDefaultFactories = new WeakMap();
|
|
1469
|
-
_implementations = new WeakMap();
|
|
1470
|
-
_rootServiceImplementations = new WeakMap();
|
|
1471
|
-
_resolveFactory = new WeakSet();
|
|
1472
|
-
resolveFactory_fn = function(ref, pluginId) {
|
|
1473
|
-
if (ref.id === backendPluginApi.coreServices.pluginMetadata.id) {
|
|
1474
|
-
return Promise.resolve(
|
|
1475
|
-
toInternalServiceFactory(pluginMetadataServiceFactory({ pluginId }))
|
|
1476
|
-
);
|
|
1477
|
-
}
|
|
1478
|
-
let resolvedFactory = __privateGet$2(this, _providedFactories).get(ref.id);
|
|
1479
|
-
const { __defaultFactory: defaultFactory } = ref;
|
|
1480
|
-
if (!resolvedFactory && !defaultFactory) {
|
|
1481
|
-
return void 0;
|
|
1482
|
-
}
|
|
1483
|
-
if (!resolvedFactory) {
|
|
1484
|
-
let loadedFactory = __privateGet$2(this, _loadedDefaultFactories).get(defaultFactory);
|
|
1485
|
-
if (!loadedFactory) {
|
|
1486
|
-
loadedFactory = Promise.resolve().then(() => defaultFactory(ref)).then(
|
|
1487
|
-
(f) => toInternalServiceFactory(typeof f === "function" ? f() : f)
|
|
1488
|
-
);
|
|
1489
|
-
__privateGet$2(this, _loadedDefaultFactories).set(defaultFactory, loadedFactory);
|
|
1490
|
-
}
|
|
1491
|
-
resolvedFactory = loadedFactory.catch((error) => {
|
|
1492
|
-
throw new Error(
|
|
1493
|
-
`Failed to instantiate service '${ref.id}' because the default factory loader threw an error, ${errors.stringifyError(
|
|
1494
|
-
error
|
|
1495
|
-
)}`
|
|
1496
|
-
);
|
|
1497
|
-
});
|
|
1498
|
-
}
|
|
1499
|
-
return Promise.resolve(resolvedFactory);
|
|
1500
|
-
};
|
|
1501
|
-
_checkForMissingDeps = new WeakSet();
|
|
1502
|
-
checkForMissingDeps_fn = function(factory, pluginId) {
|
|
1503
|
-
const missingDeps = Object.values(factory.deps).filter((ref) => {
|
|
1504
|
-
if (ref.id === backendPluginApi.coreServices.pluginMetadata.id) {
|
|
1505
|
-
return false;
|
|
1506
|
-
}
|
|
1507
|
-
if (__privateGet$2(this, _providedFactories).get(ref.id)) {
|
|
1508
|
-
return false;
|
|
1509
|
-
}
|
|
1510
|
-
return !ref.__defaultFactory;
|
|
1511
|
-
});
|
|
1512
|
-
if (missingDeps.length) {
|
|
1513
|
-
const missing = missingDeps.map((r) => `'${r.id}'`).join(", ");
|
|
1514
|
-
throw new Error(
|
|
1515
|
-
`Failed to instantiate service '${factory.service.id}' for '${pluginId}' because the following dependent services are missing: ${missing}`
|
|
1516
|
-
);
|
|
1517
|
-
}
|
|
1518
|
-
};
|
|
1519
1738
|
|
|
1520
1739
|
var __accessCheck$1 = (obj, member, msg) => {
|
|
1521
1740
|
if (!member.has(obj))
|
|
@@ -1535,16 +1754,14 @@ var __privateSet$1 = (obj, member, value, setter) => {
|
|
|
1535
1754
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1536
1755
|
return value;
|
|
1537
1756
|
};
|
|
1538
|
-
var
|
|
1757
|
+
var _initializer;
|
|
1539
1758
|
class BackstageBackend {
|
|
1540
|
-
constructor(
|
|
1541
|
-
__privateAdd$1(this, _services, void 0);
|
|
1759
|
+
constructor(defaultServiceFactories) {
|
|
1542
1760
|
__privateAdd$1(this, _initializer, void 0);
|
|
1543
|
-
__privateSet$1(this,
|
|
1544
|
-
__privateSet$1(this, _initializer, new BackendInitializer(__privateGet$1(this, _services)));
|
|
1761
|
+
__privateSet$1(this, _initializer, new BackendInitializer(defaultServiceFactories));
|
|
1545
1762
|
}
|
|
1546
1763
|
add(feature) {
|
|
1547
|
-
__privateGet$1(this, _initializer).add(feature);
|
|
1764
|
+
__privateGet$1(this, _initializer).add(typeof feature === "function" ? feature() : feature);
|
|
1548
1765
|
}
|
|
1549
1766
|
async start() {
|
|
1550
1767
|
await __privateGet$1(this, _initializer).start();
|
|
@@ -1553,11 +1770,10 @@ class BackstageBackend {
|
|
|
1553
1770
|
await __privateGet$1(this, _initializer).stop();
|
|
1554
1771
|
}
|
|
1555
1772
|
}
|
|
1556
|
-
_services = new WeakMap();
|
|
1557
1773
|
_initializer = new WeakMap();
|
|
1558
1774
|
|
|
1559
1775
|
function createSpecializedBackend(options) {
|
|
1560
|
-
const services = options.
|
|
1776
|
+
const services = options.defaultServiceFactories.map(
|
|
1561
1777
|
(sf) => typeof sf === "function" ? sf() : sf
|
|
1562
1778
|
);
|
|
1563
1779
|
const exists = /* @__PURE__ */ new Set();
|