@backstage/backend-dynamic-feature-service 0.4.2-next.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -1,698 +1,23 @@
1
1
  'use strict';
2
2
 
3
- var fs$1 = require('fs/promises');
4
- var fs = require('fs');
5
- var chokidar = require('chokidar');
6
- var path = require('path');
7
- var url = require('url');
8
- var debounce = require('lodash/debounce');
9
- var cliNode = require('@backstage/cli-node');
10
- var backendPluginApi = require('@backstage/backend-plugin-api');
11
- var cliCommon = require('@backstage/cli-common');
12
- var alpha = require('@backstage/backend-plugin-api/alpha');
13
- var fs$2 = require('fs-extra');
14
- var lodash = require('lodash');
15
- var configLoader = require('@backstage/config-loader');
16
- var pluginAppNode = require('@backstage/plugin-app-node');
17
- var rootLogger = require('@backstage/backend-defaults/rootLogger');
18
- var winston = require('winston');
19
- var backendCommon = require('@backstage/backend-common');
20
- var getPackages = require('@manypkg/get-packages');
21
-
22
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
23
-
24
- function _interopNamespaceCompat(e) {
25
- if (e && typeof e === 'object' && 'default' in e) return e;
26
- var n = Object.create(null);
27
- if (e) {
28
- Object.keys(e).forEach(function (k) {
29
- if (k !== 'default') {
30
- var d = Object.getOwnPropertyDescriptor(e, k);
31
- Object.defineProperty(n, k, d.get ? d : {
32
- enumerable: true,
33
- get: function () { return e[k]; }
34
- });
35
- }
36
- });
37
- }
38
- n.default = e;
39
- return Object.freeze(n);
40
- }
41
-
42
- var fs__namespace = /*#__PURE__*/_interopNamespaceCompat(fs$1);
43
- var fs__namespace$1 = /*#__PURE__*/_interopNamespaceCompat(fs);
44
- var chokidar__namespace = /*#__PURE__*/_interopNamespaceCompat(chokidar);
45
- var path__namespace = /*#__PURE__*/_interopNamespaceCompat(path);
46
- var url__namespace = /*#__PURE__*/_interopNamespaceCompat(url);
47
- var debounce__default = /*#__PURE__*/_interopDefaultCompat(debounce);
48
- var fs__default = /*#__PURE__*/_interopDefaultCompat(fs$2);
49
-
50
- function isBackendDynamicPluginInstaller(obj) {
51
- return obj !== void 0 && "kind" in obj && (obj.kind === "new" || obj.kind === "legacy");
52
- }
53
-
54
- class PluginScanner {
55
- constructor(config, logger, backstageRoot, preferAlpha) {
56
- this.config = config;
57
- this.logger = logger;
58
- this.backstageRoot = backstageRoot;
59
- this.preferAlpha = preferAlpha;
60
- }
61
- _rootDirectory;
62
- configUnsubscribe;
63
- rootDirectoryWatcher;
64
- subscribers = [];
65
- static create(options) {
66
- const scanner = new PluginScanner(
67
- options.config,
68
- options.logger,
69
- options.backstageRoot,
70
- options.preferAlpha || false
71
- );
72
- scanner.applyConfig();
73
- return scanner;
74
- }
75
- subscribeToRootDirectoryChange(subscriber) {
76
- this.subscribers.push(subscriber);
77
- }
78
- get rootDirectory() {
79
- return this._rootDirectory;
80
- }
81
- applyConfig() {
82
- const dynamicPlugins = this.config.getOptional("dynamicPlugins");
83
- if (!dynamicPlugins) {
84
- this.logger.info("'dynamicPlugins' config entry not found.");
85
- this._rootDirectory = void 0;
86
- return;
87
- }
88
- if (typeof dynamicPlugins !== "object") {
89
- this.logger.warn("'dynamicPlugins' config entry should be an object.");
90
- this._rootDirectory = void 0;
91
- return;
92
- }
93
- if (!("rootDirectory" in dynamicPlugins)) {
94
- this.logger.warn(
95
- "'dynamicPlugins' config entry does not contain the 'rootDirectory' field."
96
- );
97
- this._rootDirectory = void 0;
98
- return;
99
- }
100
- if (typeof dynamicPlugins.rootDirectory !== "string") {
101
- this.logger.warn(
102
- "'dynamicPlugins.rootDirectory' config entry should be a string."
103
- );
104
- this._rootDirectory = void 0;
105
- return;
106
- }
107
- const dynamicPluginsRootPath = path__namespace.isAbsolute(dynamicPlugins.rootDirectory) ? path__namespace.resolve(dynamicPlugins.rootDirectory) : path__namespace.resolve(this.backstageRoot, dynamicPlugins.rootDirectory);
108
- if (!path__namespace.dirname(dynamicPluginsRootPath).startsWith(path__namespace.resolve(this.backstageRoot))) {
109
- const nodePath = process.env.NODE_PATH;
110
- const backstageNodeModules = path__namespace.resolve(
111
- this.backstageRoot,
112
- "node_modules"
113
- );
114
- if (!nodePath || !nodePath.split(path__namespace.delimiter).includes(backstageNodeModules)) {
115
- throw new Error(
116
- `Dynamic plugins under '${dynamicPluginsRootPath}' cannot access backstage modules in '${backstageNodeModules}'.
117
- Please add '${backstageNodeModules}' to the 'NODE_PATH' when running the backstage backend.`
118
- );
119
- }
120
- }
121
- if (!fs.lstatSync(dynamicPluginsRootPath).isDirectory()) {
122
- throw new Error("Not a directory");
123
- }
124
- this._rootDirectory = dynamicPluginsRootPath;
125
- }
126
- async scanRoot() {
127
- if (!this._rootDirectory) {
128
- return { packages: [] };
129
- }
130
- const dynamicPluginsLocation = this._rootDirectory;
131
- const scannedPlugins = [];
132
- for (const dirEnt of await fs__namespace.readdir(dynamicPluginsLocation, {
133
- withFileTypes: true
134
- })) {
135
- const pluginDir = dirEnt;
136
- if (pluginDir.name === "lost+found") {
137
- this.logger.debug(`skipping '${pluginDir.name}' system directory`);
138
- continue;
139
- }
140
- const pluginHome = path__namespace.normalize(
141
- path__namespace.resolve(dynamicPluginsLocation, pluginDir.name)
142
- );
143
- if (dirEnt.isSymbolicLink()) {
144
- if (!(await fs__namespace.lstat(await fs__namespace.readlink(pluginHome))).isDirectory()) {
145
- this.logger.info(
146
- `skipping '${pluginHome}' since it is not a directory`
147
- );
148
- continue;
149
- }
150
- } else if (!dirEnt.isDirectory()) {
151
- this.logger.info(
152
- `skipping '${pluginHome}' since it is not a directory`
153
- );
154
- continue;
155
- }
156
- let scannedPlugin;
157
- let platform;
158
- try {
159
- scannedPlugin = await this.scanDir(pluginHome);
160
- if (!scannedPlugin.manifest.main) {
161
- throw new Error("field 'main' not found in 'package.json'");
162
- }
163
- if (scannedPlugin.manifest.backstage?.role) {
164
- platform = cliNode.PackageRoles.getRoleInfo(
165
- scannedPlugin.manifest.backstage.role
166
- ).platform;
167
- } else {
168
- throw new Error("field 'backstage.role' not found in 'package.json'");
169
- }
170
- } catch (e) {
171
- this.logger.error(
172
- `failed to load dynamic plugin manifest from '${pluginHome}'`,
173
- e
174
- );
175
- continue;
176
- }
177
- if (platform === "node") {
178
- if (this.preferAlpha) {
179
- const pluginHomeAlpha = path__namespace.resolve(pluginHome, "alpha");
180
- if (fs.existsSync(pluginHomeAlpha)) {
181
- if ((await fs__namespace.lstat(pluginHomeAlpha)).isDirectory()) {
182
- const backstage = scannedPlugin.manifest.backstage;
183
- try {
184
- scannedPlugin = await this.scanDir(pluginHomeAlpha);
185
- } catch (e) {
186
- this.logger.error(
187
- `failed to load dynamic plugin manifest from '${pluginHomeAlpha}'`,
188
- e
189
- );
190
- continue;
191
- }
192
- scannedPlugin.manifest.backstage = backstage;
193
- } else {
194
- this.logger.warn(
195
- `skipping '${pluginHomeAlpha}' since it is not a directory`
196
- );
197
- }
198
- }
199
- }
200
- }
201
- scannedPlugins.push(scannedPlugin);
202
- }
203
- return { packages: scannedPlugins };
204
- }
205
- async scanDir(pluginHome) {
206
- const manifestFile = path__namespace.resolve(pluginHome, "package.json");
207
- const content = await fs__namespace.readFile(manifestFile);
208
- const manifest = JSON.parse(content.toString());
209
- return {
210
- location: url__namespace.pathToFileURL(pluginHome),
211
- manifest
212
- };
213
- }
214
- async trackChanges() {
215
- const setupRootDirectoryWatcher = async () => {
216
- return new Promise((resolve, reject) => {
217
- if (!this._rootDirectory) {
218
- resolve();
219
- return;
220
- }
221
- const callSubscribers = debounce__default.default(() => {
222
- this.subscribers.forEach((s) => s());
223
- }, 500);
224
- let ready = false;
225
- this.rootDirectoryWatcher = chokidar__namespace.watch(this._rootDirectory, {
226
- ignoreInitial: true,
227
- followSymlinks: true,
228
- depth: 1,
229
- disableGlobbing: true
230
- }).on(
231
- "all",
232
- (event, eventPath, _) => {
233
- if (["addDir", "unlinkDir"].includes(event) && path__namespace.dirname(eventPath) === this._rootDirectory || ["add", "unlink", "change"].includes(event) && path__namespace.dirname(path__namespace.dirname(eventPath)) === this._rootDirectory && path__namespace.basename(eventPath) === "package.json") {
234
- this.logger.info(
235
- `rootDirectory changed (${event} - ${eventPath}): scanning plugins again`
236
- );
237
- callSubscribers();
238
- } else {
239
- this.logger.debug(
240
- `rootDirectory changed (${event} - ${eventPath}): no need to scan plugins again`
241
- );
242
- }
243
- }
244
- ).on("error", (error) => {
245
- this.logger.error(
246
- `error while watching '${this.rootDirectory}'`,
247
- error
248
- );
249
- if (!ready) {
250
- reject(error);
251
- }
252
- }).on("ready", () => {
253
- ready = true;
254
- resolve();
255
- });
256
- });
257
- };
258
- await setupRootDirectoryWatcher();
259
- if (this.config.subscribe) {
260
- const { unsubscribe } = this.config.subscribe(async () => {
261
- const oldRootDirectory = this._rootDirectory;
262
- try {
263
- this.applyConfig();
264
- } catch (e) {
265
- this.logger.error(
266
- "failed to apply new config for dynamic plugins",
267
- e
268
- );
269
- }
270
- if (oldRootDirectory !== this._rootDirectory) {
271
- this.logger.info(
272
- `rootDirectory changed in Config from '${oldRootDirectory}' to '${this._rootDirectory}'`
273
- );
274
- this.subscribers.forEach((s) => s());
275
- if (this.rootDirectoryWatcher) {
276
- await this.rootDirectoryWatcher.close();
277
- }
278
- await setupRootDirectoryWatcher();
279
- }
280
- });
281
- this.configUnsubscribe = unsubscribe;
282
- }
283
- }
284
- async untrackChanges() {
285
- if (this.rootDirectoryWatcher) {
286
- this.rootDirectoryWatcher.close();
287
- }
288
- if (this.configUnsubscribe) {
289
- this.configUnsubscribe();
290
- }
291
- }
292
- destructor() {
293
- this.untrackChanges();
294
- }
295
- }
296
-
297
- class CommonJSModuleLoader {
298
- constructor(logger) {
299
- this.logger = logger;
300
- }
301
- async bootstrap(backstageRoot, dynamicPluginsPaths) {
302
- const backstageRootNodeModulesPath = `${backstageRoot}/node_modules`;
303
- const dynamicNodeModulesPaths = [
304
- ...dynamicPluginsPaths.map((p) => path__namespace.default.resolve(p, "node_modules"))
305
- ];
306
- const Module = require("module");
307
- const oldNodeModulePaths = Module._nodeModulePaths;
308
- Module._nodeModulePaths = (from) => {
309
- const result = oldNodeModulePaths(from);
310
- if (!dynamicPluginsPaths.some((p) => from.startsWith(p))) {
311
- return result;
312
- }
313
- const filtered = result.filter((nodeModulePath) => {
314
- return nodeModulePath === backstageRootNodeModulesPath || dynamicNodeModulesPaths.some((p) => nodeModulePath.startsWith(p));
315
- });
316
- this.logger.debug(
317
- `Overriding node_modules search path for dynamic plugin ${from} to: ${filtered}`
318
- );
319
- return filtered;
320
- };
321
- }
322
- async load(packagePath) {
323
- return await require(
324
- /* webpackIgnore: true */
325
- packagePath
326
- );
327
- }
328
- }
329
-
330
- class DynamicPluginManager {
331
- constructor(logger, packages, moduleLoader) {
332
- this.logger = logger;
333
- this.packages = packages;
334
- this.moduleLoader = moduleLoader;
335
- this._plugins = [];
336
- this._availablePackages = packages;
337
- }
338
- static async create(options) {
339
- const backstageRoot = cliCommon.findPaths(__dirname).targetRoot;
340
- const scanner = PluginScanner.create({
341
- config: options.config,
342
- logger: options.logger,
343
- backstageRoot,
344
- preferAlpha: options.preferAlpha
345
- });
346
- const scannedPlugins = (await scanner.scanRoot()).packages;
347
- scanner.trackChanges();
348
- const moduleLoader = options.moduleLoader || new CommonJSModuleLoader(options.logger);
349
- const manager = new DynamicPluginManager(
350
- options.logger,
351
- scannedPlugins,
352
- moduleLoader
353
- );
354
- const dynamicPluginsPaths = scannedPlugins.map(
355
- (p) => fs__namespace$1.realpathSync(
356
- path__namespace.default.dirname(
357
- path__namespace.default.dirname(
358
- path__namespace.default.resolve(url__namespace.fileURLToPath(p.location), p.manifest.main)
359
- )
360
- )
361
- )
362
- );
363
- moduleLoader.bootstrap(backstageRoot, dynamicPluginsPaths);
364
- scanner.subscribeToRootDirectoryChange(async () => {
365
- manager._availablePackages = (await scanner.scanRoot()).packages;
366
- });
367
- manager._plugins.push(...await manager.loadPlugins());
368
- return manager;
369
- }
370
- _plugins;
371
- _availablePackages;
372
- get availablePackages() {
373
- return this._availablePackages;
374
- }
375
- addBackendPlugin(plugin) {
376
- this._plugins.push(plugin);
377
- }
378
- async loadPlugins() {
379
- const loadedPlugins = [];
380
- for (const scannedPlugin of this.packages) {
381
- const platform = cliNode.PackageRoles.getRoleInfo(
382
- scannedPlugin.manifest.backstage.role
383
- ).platform;
384
- if (platform === "node" && scannedPlugin.manifest.backstage.role.includes("-plugin")) {
385
- const plugin = await this.loadBackendPlugin(scannedPlugin);
386
- if (plugin !== void 0) {
387
- loadedPlugins.push(plugin);
388
- }
389
- } else {
390
- loadedPlugins.push({
391
- name: scannedPlugin.manifest.name,
392
- version: scannedPlugin.manifest.version,
393
- role: scannedPlugin.manifest.backstage.role,
394
- platform: "web"
395
- // TODO(davidfestal): add required front-end plugin information here.
396
- });
397
- }
398
- }
399
- return loadedPlugins;
400
- }
401
- async loadBackendPlugin(plugin) {
402
- const packagePath = url__namespace.fileURLToPath(
403
- `${plugin.location}/${plugin.manifest.main}`
404
- );
405
- try {
406
- const pluginModule = await this.moduleLoader.load(packagePath);
407
- let dynamicPluginInstaller;
408
- if (isBackendFeature(pluginModule.default)) {
409
- dynamicPluginInstaller = {
410
- kind: "new",
411
- install: () => pluginModule.default
412
- };
413
- } else if (isBackendFeatureFactory(pluginModule.default)) {
414
- dynamicPluginInstaller = {
415
- kind: "new",
416
- install: pluginModule.default
417
- };
418
- } else {
419
- dynamicPluginInstaller = pluginModule.dynamicPluginInstaller;
420
- }
421
- if (!isBackendDynamicPluginInstaller(dynamicPluginInstaller)) {
422
- this.logger.error(
423
- `dynamic backend plugin '${plugin.manifest.name}' could not be loaded from '${plugin.location}': the module should either export a 'BackendFeature' or 'BackendFeatureFactory' as default export, or export a 'const dynamicPluginInstaller: BackendDynamicPluginInstaller' field as dynamic loading entrypoint.`
424
- );
425
- return void 0;
426
- }
427
- this.logger.info(
428
- `loaded dynamic backend plugin '${plugin.manifest.name}' from '${plugin.location}'`
429
- );
430
- return {
431
- name: plugin.manifest.name,
432
- version: plugin.manifest.version,
433
- platform: "node",
434
- role: plugin.manifest.backstage.role,
435
- installer: dynamicPluginInstaller
436
- };
437
- } catch (error) {
438
- this.logger.error(
439
- `an error occurred while loading dynamic backend plugin '${plugin.manifest.name}' from '${plugin.location}'`,
440
- error
441
- );
442
- return void 0;
443
- }
444
- }
445
- backendPlugins() {
446
- return this._plugins.filter(
447
- (p) => p.platform === "node"
448
- );
449
- }
450
- frontendPlugins() {
451
- return this._plugins.filter(
452
- (p) => p.platform === "web"
453
- );
454
- }
455
- plugins() {
456
- return this._plugins;
457
- }
458
- }
459
- const dynamicPluginsServiceRef = backendPluginApi.createServiceRef(
460
- {
461
- id: "core.dynamicplugins",
462
- scope: "root"
463
- }
464
- );
465
- const dynamicPluginsServiceFactoryWithOptions = (options) => backendPluginApi.createServiceFactory({
466
- service: dynamicPluginsServiceRef,
467
- deps: {
468
- config: backendPluginApi.coreServices.rootConfig,
469
- logger: backendPluginApi.coreServices.rootLogger
470
- },
471
- async factory({ config, logger }) {
472
- return await DynamicPluginManager.create({
473
- config,
474
- logger,
475
- preferAlpha: true,
476
- moduleLoader: options?.moduleLoader?.(logger)
477
- });
478
- }
479
- });
480
- const dynamicPluginsServiceFactory = dynamicPluginsServiceFactoryWithOptions();
481
- class DynamicPluginsEnabledFeatureDiscoveryService {
482
- constructor(dynamicPlugins, featureDiscoveryService) {
483
- this.dynamicPlugins = dynamicPlugins;
484
- this.featureDiscoveryService = featureDiscoveryService;
485
- }
486
- async getBackendFeatures() {
487
- const staticFeatures = (await this.featureDiscoveryService?.getBackendFeatures())?.features ?? [];
488
- return {
489
- features: [
490
- ...this.dynamicPlugins.backendPlugins().flatMap((plugin) => {
491
- if (plugin.installer.kind === "new") {
492
- const installed = plugin.installer.install();
493
- if (Array.isArray(installed)) {
494
- return installed;
495
- }
496
- return [installed];
497
- }
498
- return [];
499
- }),
500
- ...staticFeatures
501
- ]
502
- };
503
- }
504
- }
505
- const dynamicPluginsFeatureDiscoveryServiceFactory = backendPluginApi.createServiceFactory({
506
- service: alpha.featureDiscoveryServiceRef,
507
- deps: {
508
- config: backendPluginApi.coreServices.rootConfig,
509
- dynamicPlugins: dynamicPluginsServiceRef
510
- },
511
- factory({ dynamicPlugins }) {
512
- return new DynamicPluginsEnabledFeatureDiscoveryService(dynamicPlugins);
513
- }
514
- });
515
- const dynamicPluginsFeatureDiscoveryLoaderWithOptions = (options) => backendPluginApi.createBackendFeatureLoader({
516
- deps: {
517
- config: backendPluginApi.coreServices.rootConfig,
518
- logger: backendPluginApi.coreServices.rootLogger
519
- },
520
- async loader({ config, logger }) {
521
- const manager = await DynamicPluginManager.create({
522
- config,
523
- logger,
524
- preferAlpha: true,
525
- moduleLoader: options?.moduleLoader?.(logger)
526
- });
527
- const service = new DynamicPluginsEnabledFeatureDiscoveryService(manager);
528
- const { features } = await service.getBackendFeatures();
529
- return features;
530
- }
531
- });
532
- const dynamicPluginsFeatureDiscoveryLoader = Object.assign(
533
- dynamicPluginsFeatureDiscoveryLoaderWithOptions,
534
- dynamicPluginsFeatureDiscoveryLoaderWithOptions()
535
- );
536
- function isBackendFeature(value) {
537
- return !!value && (typeof value === "object" || typeof value === "function") && value.$$type === "@backstage/BackendFeature";
538
- }
539
- function isBackendFeatureFactory(value) {
540
- return !!value && typeof value === "function" && value.$$type === "@backstage/BackendFeatureFactory";
541
- }
542
-
543
- const dynamicPluginsSchemasServiceRef = backendPluginApi.createServiceRef({
544
- id: "core.dynamicplugins.schemas",
545
- scope: "root"
546
- });
547
- const dynamicPluginsSchemasServiceFactoryWithOptions = (options) => backendPluginApi.createServiceFactory({
548
- service: dynamicPluginsSchemasServiceRef,
549
- deps: {
550
- config: backendPluginApi.coreServices.rootConfig
551
- },
552
- factory({ config }) {
553
- let additionalSchemas;
554
- return {
555
- async addDynamicPluginsSchemas(configSchema) {
556
- if (!additionalSchemas) {
557
- const logger = {
558
- ...console,
559
- child() {
560
- return this;
561
- }
562
- };
563
- const scanner = PluginScanner.create({
564
- config,
565
- logger,
566
- // eslint-disable-next-line no-restricted-syntax
567
- backstageRoot: cliCommon.findPaths(__dirname).targetRoot,
568
- preferAlpha: true
569
- });
570
- const { packages } = await scanner.scanRoot();
571
- additionalSchemas = await gatherDynamicPluginsSchemas(
572
- packages,
573
- logger,
574
- options?.schemaLocator
575
- );
576
- }
577
- const serialized = configSchema.serialize();
578
- if (serialized?.backstageConfigSchemaVersion !== 1) {
579
- throw new Error(
580
- "Serialized configuration schema is invalid or has an invalid version number"
581
- );
582
- }
583
- const schemas = serialized.schemas;
584
- schemas.push(
585
- ...Object.keys(additionalSchemas).map((context) => {
586
- return {
587
- path: context,
588
- value: additionalSchemas[context]
589
- };
590
- })
591
- );
592
- serialized.schemas = schemas;
593
- return {
594
- schema: await configLoader.loadConfigSchema({
595
- serialized
596
- })
597
- };
598
- }
599
- };
600
- }
601
- });
602
- const dynamicPluginsSchemasServiceFactory = dynamicPluginsSchemasServiceFactoryWithOptions();
603
- async function gatherDynamicPluginsSchemas(packages, logger, schemaLocator = () => path__namespace.join("dist", "configSchema.json")) {
604
- const allSchemas = {};
605
- for (const pluginPackage of packages) {
606
- let schemaLocation = schemaLocator(pluginPackage);
607
- if (!path__namespace.isAbsolute(schemaLocation)) {
608
- let pluginLocation = url__namespace.fileURLToPath(pluginPackage.location);
609
- if (path__namespace.basename(pluginLocation) === "alpha") {
610
- pluginLocation = path__namespace.dirname(pluginLocation);
611
- }
612
- schemaLocation = path__namespace.resolve(pluginLocation, schemaLocation);
613
- }
614
- if (!await fs__default.default.pathExists(schemaLocation)) {
615
- continue;
616
- }
617
- const serialized = await fs__default.default.readJson(schemaLocation);
618
- if (!serialized) {
619
- continue;
620
- }
621
- if (lodash.isEmpty(serialized)) {
622
- continue;
623
- }
624
- if (!serialized?.$schema || serialized?.type !== "object") {
625
- logger.error(
626
- `Serialized configuration schema is invalid for plugin ${pluginPackage.manifest.name}`
627
- );
628
- continue;
629
- }
630
- allSchemas[schemaLocation] = serialized;
631
- }
632
- return allSchemas;
633
- }
634
-
635
- const dynamicPluginsFrontendSchemas = backendPluginApi.createBackendModule({
636
- pluginId: "app",
637
- moduleId: "core.dynamicplugins.frontendSchemas",
638
- register(reg) {
639
- reg.registerInit({
640
- deps: {
641
- config: backendPluginApi.coreServices.rootConfig,
642
- schemas: dynamicPluginsSchemasServiceRef,
643
- configSchemaExtension: pluginAppNode.configSchemaExtensionPoint
644
- },
645
- async init({ config, schemas, configSchemaExtension }) {
646
- const appPackageName = config.getOptionalString("app.packageName") ?? "app";
647
- const appDistDir = backendPluginApi.resolvePackagePath(appPackageName, "dist");
648
- const compiledConfigSchema = await pluginAppNode.loadCompiledConfigSchema(appDistDir);
649
- if (compiledConfigSchema) {
650
- configSchemaExtension.setConfigSchema(
651
- (await schemas.addDynamicPluginsSchemas(compiledConfigSchema)).schema
652
- );
653
- }
654
- }
655
- });
656
- }
657
- });
658
-
659
- const dynamicPluginsRootLoggerServiceFactory = backendPluginApi.createServiceFactory({
660
- service: backendPluginApi.coreServices.rootLogger,
661
- deps: {
662
- config: backendPluginApi.coreServices.rootConfig,
663
- schemas: dynamicPluginsSchemasServiceRef
664
- },
665
- async factory({ config, schemas }) {
666
- const logger = rootLogger.WinstonLogger.create({
667
- meta: {
668
- service: "backstage"
669
- },
670
- level: process.env.LOG_LEVEL || "info",
671
- format: process.env.NODE_ENV === "production" ? winston.format.json() : rootLogger.WinstonLogger.colorFormat(),
672
- transports: [new winston.transports.Console()]
673
- });
674
- const configSchema = await configLoader.loadConfigSchema({
675
- dependencies: (await getPackages.getPackages(process.cwd())).packages.map((p) => p.packageJson.name)
676
- });
677
- const secretEnumerator = await backendCommon.createConfigSecretEnumerator({
678
- logger,
679
- schema: (await schemas.addDynamicPluginsSchemas(configSchema)).schema
680
- });
681
- logger.addRedactions(secretEnumerator(config));
682
- config.subscribe?.(() => logger.addRedactions(secretEnumerator(config)));
683
- return logger;
684
- }
685
- });
686
-
687
- exports.DynamicPluginManager = DynamicPluginManager;
688
- exports.dynamicPluginsFeatureDiscoveryLoader = dynamicPluginsFeatureDiscoveryLoader;
689
- exports.dynamicPluginsFeatureDiscoveryServiceFactory = dynamicPluginsFeatureDiscoveryServiceFactory;
690
- exports.dynamicPluginsFrontendSchemas = dynamicPluginsFrontendSchemas;
691
- exports.dynamicPluginsRootLoggerServiceFactory = dynamicPluginsRootLoggerServiceFactory;
692
- exports.dynamicPluginsSchemasServiceFactory = dynamicPluginsSchemasServiceFactory;
693
- exports.dynamicPluginsSchemasServiceFactoryWithOptions = dynamicPluginsSchemasServiceFactoryWithOptions;
694
- exports.dynamicPluginsServiceFactory = dynamicPluginsServiceFactory;
695
- exports.dynamicPluginsServiceFactoryWithOptions = dynamicPluginsServiceFactoryWithOptions;
696
- exports.dynamicPluginsServiceRef = dynamicPluginsServiceRef;
697
- exports.isBackendDynamicPluginInstaller = isBackendDynamicPluginInstaller;
3
+ var types = require('./manager/types.cjs.js');
4
+ var pluginManager = require('./manager/plugin-manager.cjs.js');
5
+ var schemas = require('./schemas/schemas.cjs.js');
6
+ var frontend = require('./schemas/frontend.cjs.js');
7
+ var rootLogger = require('./schemas/rootLogger.cjs.js');
8
+ var features = require('./features/features.cjs.js');
9
+
10
+
11
+
12
+ exports.isBackendDynamicPluginInstaller = types.isBackendDynamicPluginInstaller;
13
+ exports.DynamicPluginManager = pluginManager.DynamicPluginManager;
14
+ exports.dynamicPluginsFeatureDiscoveryLoader = pluginManager.dynamicPluginsFeatureDiscoveryLoader;
15
+ exports.dynamicPluginsFeatureDiscoveryServiceFactory = pluginManager.dynamicPluginsFeatureDiscoveryServiceFactory;
16
+ exports.dynamicPluginsServiceFactory = pluginManager.dynamicPluginsServiceFactory;
17
+ exports.dynamicPluginsServiceFactoryWithOptions = pluginManager.dynamicPluginsServiceFactoryWithOptions;
18
+ exports.dynamicPluginsServiceRef = pluginManager.dynamicPluginsServiceRef;
19
+ exports.dynamicPluginsSchemasServiceFactory = schemas.dynamicPluginsSchemasServiceFactory;
20
+ exports.dynamicPluginsFrontendSchemas = frontend.dynamicPluginsFrontendSchemas;
21
+ exports.dynamicPluginsRootLoggerServiceFactory = rootLogger.dynamicPluginsRootLoggerServiceFactory;
22
+ exports.dynamicPluginsFeatureLoader = features.dynamicPluginsFeatureLoader;
698
23
  //# sourceMappingURL=index.cjs.js.map