@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/dist/index.cjs.js CHANGED
@@ -585,31 +585,31 @@ function createCorsOriginMatcher(allowedOriginPatterns) {
585
585
  };
586
586
  }
587
587
 
588
- var __accessCheck$7 = (obj, member, msg) => {
588
+ var __accessCheck$8 = (obj, member, msg) => {
589
589
  if (!member.has(obj))
590
590
  throw TypeError("Cannot " + msg);
591
591
  };
592
- var __privateGet$7 = (obj, member, getter) => {
593
- __accessCheck$7(obj, member, "read from private field");
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$7 = (obj, member, value) => {
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$7 = (obj, member, value, setter) => {
602
- __accessCheck$7(obj, member, "write to private field");
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$7(this, _config, void 0);
610
- __privateAdd$7(this, _logger, void 0);
611
- __privateSet$7(this, _config, options.config);
612
- __privateSet$7(this, _logger, options.logger);
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$7(this, _logger).child({
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$7(this, _config).getOptionalConfig("backend")));
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$7(this, _config).getOptionalConfig("backend")));
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$7(this, _logger).child({
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$6 = (obj, member, msg) => {
780
+ var __accessCheck$7 = (obj, member, msg) => {
781
781
  if (!member.has(obj))
782
782
  throw TypeError("Cannot " + msg);
783
783
  };
784
- var __privateGet$6 = (obj, member, getter) => {
785
- __accessCheck$6(obj, member, "read from private field");
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$6 = (obj, member, value) => {
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$6 = (obj, member, value, setter) => {
794
- __accessCheck$6(obj, member, "write to private field");
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$6(this, _winston, void 0);
802
- __privateAdd$6(this, _addRedactions, void 0);
803
- __privateSet$6(this, _winston, winston);
804
- __privateSet$6(this, _addRedactions, addRedactions);
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$6(this, _winston).error(message, meta);
881
+ __privateGet$7(this, _winston).error(message, meta);
882
882
  }
883
883
  warn(message, meta) {
884
- __privateGet$6(this, _winston).warn(message, meta);
884
+ __privateGet$7(this, _winston).warn(message, meta);
885
885
  }
886
886
  info(message, meta) {
887
- __privateGet$6(this, _winston).info(message, meta);
887
+ __privateGet$7(this, _winston).info(message, meta);
888
888
  }
889
889
  debug(message, meta) {
890
- __privateGet$6(this, _winston).debug(message, meta);
890
+ __privateGet$7(this, _winston).debug(message, meta);
891
891
  }
892
892
  child(meta) {
893
- return new _WinstonLogger(__privateGet$6(this, _winston).child(meta));
893
+ return new _WinstonLogger(__privateGet$7(this, _winston).child(meta));
894
894
  }
895
895
  addRedactions(redactions) {
896
896
  var _a;
897
- (_a = __privateGet$6(this, _addRedactions)) == null ? void 0 : _a.call(this, redactions);
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$5 = (obj, member, msg) => {
904
+ var __accessCheck$6 = (obj, member, msg) => {
905
905
  if (!member.has(obj))
906
906
  throw TypeError("Cannot " + msg);
907
907
  };
908
- var __privateGet$5 = (obj, member, getter) => {
909
- __accessCheck$5(obj, member, "read from private field");
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$5 = (obj, member, value) => {
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$5 = (obj, member, value, setter) => {
918
- __accessCheck$5(obj, member, "write to private field");
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$5(this, _hasStarted$1, false);
927
- __privateAdd$5(this, _startupTasks$1, []);
928
- __privateAdd$5(this, _hasShutdown, false);
929
- __privateAdd$5(this, _shutdownTasks, []);
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$5(this, _hasStarted$1)) {
932
+ if (__privateGet$6(this, _hasStarted$1)) {
933
933
  throw new Error("Attempted to add startup hook after startup");
934
934
  }
935
- __privateGet$5(this, _startupTasks$1).push({ hook, options });
935
+ __privateGet$6(this, _startupTasks$1).push({ hook, options });
936
936
  }
937
937
  async startup() {
938
- if (__privateGet$5(this, _hasStarted$1)) {
938
+ if (__privateGet$6(this, _hasStarted$1)) {
939
939
  return;
940
940
  }
941
- __privateSet$5(this, _hasStarted$1, true);
942
- this.logger.debug(`Running ${__privateGet$5(this, _startupTasks$1).length} startup tasks...`);
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$5(this, _startupTasks$1).map(async ({ hook, options }) => {
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$5(this, _hasShutdown)) {
957
+ if (__privateGet$6(this, _hasShutdown)) {
958
958
  throw new Error("Attempted to add shutdown hook after shutdown");
959
959
  }
960
- __privateGet$5(this, _shutdownTasks).push({ hook, options });
960
+ __privateGet$6(this, _shutdownTasks).push({ hook, options });
961
961
  }
962
962
  async shutdown() {
963
- if (__privateGet$5(this, _hasShutdown)) {
963
+ if (__privateGet$6(this, _hasShutdown)) {
964
964
  return;
965
965
  }
966
- __privateSet$5(this, _hasShutdown, true);
966
+ __privateSet$6(this, _hasShutdown, true);
967
967
  this.logger.debug(
968
- `Running ${__privateGet$5(this, _shutdownTasks).length} shutdown tasks...`
968
+ `Running ${__privateGet$6(this, _shutdownTasks).length} shutdown tasks...`
969
969
  );
970
970
  await Promise.all(
971
- __privateGet$5(this, _shutdownTasks).map(async ({ hook, options }) => {
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$4 = (obj, member, msg) => {
998
+ var __accessCheck$5 = (obj, member, msg) => {
999
999
  if (!member.has(obj))
1000
1000
  throw TypeError("Cannot " + msg);
1001
1001
  };
1002
- var __privateGet$4 = (obj, member, getter) => {
1003
- __accessCheck$4(obj, member, "read from private field");
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$4 = (obj, member, value) => {
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$4 = (obj, member, value, setter) => {
1012
- __accessCheck$4(obj, member, "write to private field");
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$4(this, _hasStarted, false);
1023
- __privateAdd$4(this, _startupTasks, []);
1022
+ __privateAdd$5(this, _hasStarted, false);
1023
+ __privateAdd$5(this, _startupTasks, []);
1024
1024
  }
1025
1025
  addStartupHook(hook, options) {
1026
- if (__privateGet$4(this, _hasStarted)) {
1026
+ if (__privateGet$5(this, _hasStarted)) {
1027
1027
  throw new Error("Attempted to add startup hook after startup");
1028
1028
  }
1029
- __privateGet$4(this, _startupTasks).push({ hook, options });
1029
+ __privateGet$5(this, _startupTasks).push({ hook, options });
1030
1030
  }
1031
1031
  async startup() {
1032
- if (__privateGet$4(this, _hasStarted)) {
1032
+ if (__privateGet$5(this, _hasStarted)) {
1033
1033
  return;
1034
1034
  }
1035
- __privateSet$4(this, _hasStarted, true);
1035
+ __privateSet$5(this, _hasStarted, true);
1036
1036
  this.logger.debug(
1037
- `Running ${__privateGet$4(this, _startupTasks).length} plugin startup tasks...`
1037
+ `Running ${__privateGet$5(this, _startupTasks).length} plugin startup tasks...`
1038
1038
  );
1039
1039
  await Promise.all(
1040
- __privateGet$4(this, _startupTasks).map(async ({ hook, options }) => {
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 _startPromise, _features, _extensionPoints, _serviceHolder, _getInitDeps, getInitDeps_fn, _addFeature, addFeature_fn, _doStart, doStart_fn, _getRootLifecycleImpl, getRootLifecycleImpl_fn, _getPluginLifecycleImpl, getPluginLifecycleImpl_fn;
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(serviceHolder) {
1103
- __privateAdd$3(this, _getInitDeps);
1104
- __privateAdd$3(this, _addFeature);
1105
- __privateAdd$3(this, _doStart);
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$3(this, _getRootLifecycleImpl);
1108
- __privateAdd$3(this, _getPluginLifecycleImpl);
1109
- __privateAdd$3(this, _startPromise, void 0);
1110
- __privateAdd$3(this, _features, new Array());
1111
- __privateAdd$3(this, _extensionPoints, /* @__PURE__ */ new Map());
1112
- __privateAdd$3(this, _serviceHolder, void 0);
1113
- __privateSet$3(this, _serviceHolder, serviceHolder);
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$3(this, _startPromise)) {
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$2(this, _addFeature, addFeature_fn).call(this, feature);
1467
+ __privateMethod$1(this, _addFeature, addFeature_fn).call(this, feature);
1120
1468
  }
1121
1469
  async start() {
1122
- if (__privateGet$3(this, _startPromise)) {
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$3(this, _startPromise, __privateMethod$2(this, _doStart, doStart_fn).call(this));
1141
- await __privateGet$3(this, _startPromise);
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$3(this, _startPromise)) {
1492
+ if (!__privateGet$2(this, _startPromise)) {
1145
1493
  return;
1146
1494
  }
1147
1495
  try {
1148
- await __privateGet$3(this, _startPromise);
1496
+ await __privateGet$2(this, _startPromise);
1149
1497
  } catch (error) {
1150
1498
  }
1151
- const lifecycleService = await __privateMethod$2(this, _getRootLifecycleImpl, getRootLifecycleImpl_fn).call(this);
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 extensionPoint = __privateGet$3(this, _extensionPoints).get(
1165
- ref
1166
- );
1167
- if (extensionPoint) {
1168
- result.set(name, extensionPoint);
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$3(this, _serviceHolder).get(
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
- const internalFeature = feature;
1197
- if (internalFeature.version !== "v1") {
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 version '${internalFeature.version}'`
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
- const featureDiscovery = await __privateGet$3(this, _serviceHolder).get(
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$2(this, _addFeature, addFeature_fn).call(this, feature);
1589
+ __privateMethod$1(this, _addFeature, addFeature_fn).call(this, feature);
1214
1590
  }
1215
1591
  }
1216
- for (const ref of __privateGet$3(this, _serviceHolder).getServiceRefs()) {
1592
+ for (const ref of __privateGet$2(this, _serviceHolder).getServiceRefs()) {
1217
1593
  if (ref.scope === "root") {
1218
- await __privateGet$3(this, _serviceHolder).get(ref, "root");
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$3(this, _features)) {
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$3(this, _extensionPoints).has(extRef)) {
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$3(this, _extensionPoints).set(extRef, extImpl);
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
- var _a;
1271
- const modules = (_a = moduleInits.get(pluginId)) != null ? _a : [];
1272
- await Promise.all(
1273
- Array.from(modules).map(async ([moduleId, moduleInit]) => {
1274
- const moduleDeps = await __privateMethod$2(this, _getInitDeps, getInitDeps_fn).call(this, moduleInit.init.deps, pluginId);
1275
- await moduleInit.init.func(moduleDeps).catch((error) => {
1276
- throw new errors.ForwardedError(
1277
- `Module '${moduleId}' for plugin '${pluginId}' startup failed`,
1278
- error
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$2(this, _getInitDeps, getInitDeps_fn).call(this, pluginInit.init.deps, pluginId);
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$2(this, _getPluginLifecycleImpl, getPluginLifecycleImpl_fn).call(this, pluginId);
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$2(this, _getRootLifecycleImpl, getRootLifecycleImpl_fn).call(this);
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$3(this, _serviceHolder).get(
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$3(this, _serviceHolder).get(
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$3(this, _serviceHolder).get(
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
- var __accessCheck$2 = (obj, member, msg) => {
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
- const pluginMetadataServiceFactory = backendPluginApi.createServiceFactory(
1371
- (options) => ({
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 _services, _initializer;
1757
+ var _initializer;
1539
1758
  class BackstageBackend {
1540
- constructor(apiFactories) {
1541
- __privateAdd$1(this, _services, void 0);
1759
+ constructor(defaultServiceFactories) {
1542
1760
  __privateAdd$1(this, _initializer, void 0);
1543
- __privateSet$1(this, _services, new ServiceRegistry(apiFactories));
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.services.map(
1776
+ const services = options.defaultServiceFactories.map(
1561
1777
  (sf) => typeof sf === "function" ? sf() : sf
1562
1778
  );
1563
1779
  const exists = /* @__PURE__ */ new Set();