@backstage/backend-dynamic-feature-service 0.6.2-next.2 → 0.6.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/CHANGELOG.md +29 -0
- package/dist/features/features.cjs.js +2 -0
- package/dist/features/features.cjs.js.map +1 -1
- package/dist/index.cjs.js +2 -0
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +85 -1
- package/dist/schema/openapi/generated/router.cjs.js +213 -0
- package/dist/schema/openapi/generated/router.cjs.js.map +1 -0
- package/dist/schemas/schemas.cjs.js +7 -2
- package/dist/schemas/schemas.cjs.js.map +1 -1
- package/dist/server/frontendRemotesServer.cjs.js +58 -0
- package/dist/server/frontendRemotesServer.cjs.js.map +1 -0
- package/dist/server/router.cjs.js +152 -0
- package/dist/server/router.cjs.js.map +1 -0
- package/package.json +32 -24
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @backstage/backend-dynamic-feature-service
|
|
2
2
|
|
|
3
|
+
## 0.6.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3bee3c3: The new package `frontend-dynamic-features-loader` provides a frontend feature loader that dynamically
|
|
8
|
+
loads frontend features based on the new frontend system and exposed as module federation remotes.
|
|
9
|
+
This new frontend feature loader works hand-in-hand with a new server of frontend plugin module federation
|
|
10
|
+
remotes, which is added as part of backend dynamic feature service in package `@backstage/backend-dynamic-feature-service`.
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @backstage/backend-defaults@0.9.0
|
|
13
|
+
- @backstage/plugin-catalog-backend@1.32.1
|
|
14
|
+
- @backstage/plugin-scaffolder-node@0.8.1
|
|
15
|
+
- @backstage/backend-plugin-api@1.3.0
|
|
16
|
+
- @backstage/plugin-auth-node@0.6.2
|
|
17
|
+
- @backstage/plugin-events-backend@0.5.1
|
|
18
|
+
- @backstage/plugin-permission-node@0.9.1
|
|
19
|
+
- @backstage/plugin-search-backend-node@1.3.10
|
|
20
|
+
- @backstage/backend-openapi-utils@0.5.2
|
|
21
|
+
- @backstage/cli-common@0.1.15
|
|
22
|
+
- @backstage/cli-node@0.2.13
|
|
23
|
+
- @backstage/config@1.3.2
|
|
24
|
+
- @backstage/config-loader@1.10.0
|
|
25
|
+
- @backstage/errors@1.2.7
|
|
26
|
+
- @backstage/types@1.2.1
|
|
27
|
+
- @backstage/plugin-app-node@0.1.32
|
|
28
|
+
- @backstage/plugin-events-node@0.4.10
|
|
29
|
+
- @backstage/plugin-permission-common@0.8.4
|
|
30
|
+
- @backstage/plugin-search-common@1.2.17
|
|
31
|
+
|
|
3
32
|
## 0.6.2-next.2
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
|
@@ -6,6 +6,7 @@ var pluginScanner = require('../scanner/plugin-scanner.cjs.js');
|
|
|
6
6
|
var schemas = require('../schemas/schemas.cjs.js');
|
|
7
7
|
var frontend = require('../schemas/frontend.cjs.js');
|
|
8
8
|
var rootLogger = require('../schemas/rootLogger.cjs.js');
|
|
9
|
+
var frontendRemotesServer = require('../server/frontendRemotesServer.cjs.js');
|
|
9
10
|
|
|
10
11
|
const dynamicPluginsFeatureLoaderWithOptions = (options) => backendPluginApi.createBackendFeatureLoader({
|
|
11
12
|
deps: {
|
|
@@ -25,6 +26,7 @@ const dynamicPluginsFeatureLoaderWithOptions = (options) => backendPluginApi.cre
|
|
|
25
26
|
yield* [
|
|
26
27
|
rootLogger.dynamicPluginsRootLoggerServiceFactory(rootLoggerOptions),
|
|
27
28
|
frontend.dynamicPluginsFrontendSchemas,
|
|
29
|
+
frontendRemotesServer.frontendRemotesServerService,
|
|
28
30
|
pluginManager.dynamicPluginsFeatureDiscoveryLoader
|
|
29
31
|
];
|
|
30
32
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features.cjs.js","sources":["../../src/features/features.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createBackendFeatureLoader,\n} from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport {\n DynamicPluginsFactoryOptions,\n dynamicPluginsFeatureDiscoveryLoader,\n dynamicPluginsServiceFactory,\n} from '../manager';\nimport { configKey } from '../scanner/plugin-scanner';\nimport {\n DynamicPluginsRootLoggerFactoryOptions,\n DynamicPluginsSchemasOptions,\n dynamicPluginsFrontendSchemas,\n dynamicPluginsRootLoggerServiceFactory,\n dynamicPluginsSchemasServiceFactory,\n} from '../schemas';\n\n/**\n * @public\n */\nexport type DynamicPluginsFeatureLoaderOptions = DynamicPluginsFactoryOptions &\n DynamicPluginsSchemasOptions & {\n logger?: (config?: Config) => DynamicPluginsRootLoggerFactoryOptions;\n };\n\nconst dynamicPluginsFeatureLoaderWithOptions = (\n options?: DynamicPluginsFeatureLoaderOptions,\n) =>\n createBackendFeatureLoader({\n deps: {\n config: coreServices.rootConfig,\n },\n *loader({ config }) {\n const dynamicPluginsEnabled = config.has(configKey);\n\n let rootLoggerOptions: DynamicPluginsRootLoggerFactoryOptions = {};\n if (options?.logger) {\n rootLoggerOptions = options.logger(config);\n }\n\n yield* [\n dynamicPluginsSchemasServiceFactory(options),\n dynamicPluginsServiceFactory(options),\n ];\n if (dynamicPluginsEnabled) {\n yield* [\n dynamicPluginsRootLoggerServiceFactory(rootLoggerOptions),\n dynamicPluginsFrontendSchemas,\n dynamicPluginsFeatureDiscoveryLoader,\n ];\n }\n },\n });\n\n/**\n * A backend feature loader that fully enable backend dynamic plugins.\n * More precisely it:\n * - adds the dynamic plugins root service (typically depended upon by plugins),\n * - adds additional required features to allow supporting dynamic plugins config schemas\n * in the frontend application and the backend root logger,\n * - uses the dynamic plugins service to discover and expose dynamic plugins as features.\n *\n * @public\n *\n * @example\n * Using the `dynamicPluginsFeatureLoader` loader in a backend instance:\n * ```ts\n * //...\n * import { createBackend } from '@backstage/backend-defaults';\n * import { dynamicPluginsFeatureLoader } from '@backstage/backend-dynamic-feature-service';\n *\n * const backend = createBackend();\n * backend.add(dynamicPluginsFeatureLoader);\n * //...\n * backend.start();\n * ```\n *\n * @example\n * Passing options to the `dynamicPluginsFeatureLoader` loader in a backend instance:\n * ```ts\n * //...\n * import { createBackend } from '@backstage/backend-defaults';\n * import { dynamicPluginsFeatureLoader } from '@backstage/backend-dynamic-feature-service';\n * import { myCustomModuleLoader } from './myCustomModuleLoader';\n * import { myCustomSchemaLocator } from './myCustomSchemaLocator';\n * import { myConfiguredLoggerOptions } from './myConfiguredLoggerOptions';\n *\n * const backend = createBackend();\n * backend.add(dynamicPluginsFeatureLoader({\n * moduleLoader: myCustomModuleLoader,\n * schemaLocator: myCustomSchemaLocator,\n * logger: (config) => myConfiguredLoggerOptions(config),\n * }));\n * //...\n * backend.start();\n * ```\n */\nexport const dynamicPluginsFeatureLoader = Object.assign(\n dynamicPluginsFeatureLoaderWithOptions,\n dynamicPluginsFeatureLoaderWithOptions(),\n);\n"],"names":["createBackendFeatureLoader","coreServices","configKey","dynamicPluginsSchemasServiceFactory","dynamicPluginsServiceFactory","dynamicPluginsRootLoggerServiceFactory","dynamicPluginsFrontendSchemas","dynamicPluginsFeatureDiscoveryLoader"],"mappings":"
|
|
1
|
+
{"version":3,"file":"features.cjs.js","sources":["../../src/features/features.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createBackendFeatureLoader,\n} from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport {\n DynamicPluginsFactoryOptions,\n dynamicPluginsFeatureDiscoveryLoader,\n dynamicPluginsServiceFactory,\n} from '../manager';\nimport { configKey } from '../scanner/plugin-scanner';\nimport {\n DynamicPluginsRootLoggerFactoryOptions,\n DynamicPluginsSchemasOptions,\n dynamicPluginsFrontendSchemas,\n dynamicPluginsRootLoggerServiceFactory,\n dynamicPluginsSchemasServiceFactory,\n} from '../schemas';\nimport { frontendRemotesServerService } from '../server/frontendRemotesServer';\n\n/**\n * @public\n */\nexport type DynamicPluginsFeatureLoaderOptions = DynamicPluginsFactoryOptions &\n DynamicPluginsSchemasOptions & {\n logger?: (config?: Config) => DynamicPluginsRootLoggerFactoryOptions;\n };\n\nconst dynamicPluginsFeatureLoaderWithOptions = (\n options?: DynamicPluginsFeatureLoaderOptions,\n) =>\n createBackendFeatureLoader({\n deps: {\n config: coreServices.rootConfig,\n },\n *loader({ config }) {\n const dynamicPluginsEnabled = config.has(configKey);\n\n let rootLoggerOptions: DynamicPluginsRootLoggerFactoryOptions = {};\n if (options?.logger) {\n rootLoggerOptions = options.logger(config);\n }\n\n yield* [\n dynamicPluginsSchemasServiceFactory(options),\n dynamicPluginsServiceFactory(options),\n ];\n if (dynamicPluginsEnabled) {\n yield* [\n dynamicPluginsRootLoggerServiceFactory(rootLoggerOptions),\n dynamicPluginsFrontendSchemas,\n frontendRemotesServerService,\n dynamicPluginsFeatureDiscoveryLoader,\n ];\n }\n },\n });\n\n/**\n * A backend feature loader that fully enable backend dynamic plugins.\n * More precisely it:\n * - adds the dynamic plugins root service (typically depended upon by plugins),\n * - adds additional required features to allow supporting dynamic plugins config schemas\n * in the frontend application and the backend root logger,\n * - uses the dynamic plugins service to discover and expose dynamic plugins as features.\n *\n * @public\n *\n * @example\n * Using the `dynamicPluginsFeatureLoader` loader in a backend instance:\n * ```ts\n * //...\n * import { createBackend } from '@backstage/backend-defaults';\n * import { dynamicPluginsFeatureLoader } from '@backstage/backend-dynamic-feature-service';\n *\n * const backend = createBackend();\n * backend.add(dynamicPluginsFeatureLoader);\n * //...\n * backend.start();\n * ```\n *\n * @example\n * Passing options to the `dynamicPluginsFeatureLoader` loader in a backend instance:\n * ```ts\n * //...\n * import { createBackend } from '@backstage/backend-defaults';\n * import { dynamicPluginsFeatureLoader } from '@backstage/backend-dynamic-feature-service';\n * import { myCustomModuleLoader } from './myCustomModuleLoader';\n * import { myCustomSchemaLocator } from './myCustomSchemaLocator';\n * import { myConfiguredLoggerOptions } from './myConfiguredLoggerOptions';\n *\n * const backend = createBackend();\n * backend.add(dynamicPluginsFeatureLoader({\n * moduleLoader: myCustomModuleLoader,\n * schemaLocator: myCustomSchemaLocator,\n * logger: (config) => myConfiguredLoggerOptions(config),\n * }));\n * //...\n * backend.start();\n * ```\n */\nexport const dynamicPluginsFeatureLoader = Object.assign(\n dynamicPluginsFeatureLoaderWithOptions,\n dynamicPluginsFeatureLoaderWithOptions(),\n);\n"],"names":["createBackendFeatureLoader","coreServices","configKey","dynamicPluginsSchemasServiceFactory","dynamicPluginsServiceFactory","dynamicPluginsRootLoggerServiceFactory","dynamicPluginsFrontendSchemas","frontendRemotesServerService","dynamicPluginsFeatureDiscoveryLoader"],"mappings":";;;;;;;;;;AA4CA,MAAM,sCAAA,GAAyC,CAC7C,OAAA,KAEAA,2CAA2B,CAAA;AAAA,EACzB,IAAM,EAAA;AAAA,IACJ,QAAQC,6BAAa,CAAA;AAAA,GACvB;AAAA,EACA,CAAC,MAAA,CAAO,EAAE,MAAA,EAAU,EAAA;AAClB,IAAM,MAAA,qBAAA,GAAwB,MAAO,CAAA,GAAA,CAAIC,uBAAS,CAAA;AAElD,IAAA,IAAI,oBAA4D,EAAC;AACjE,IAAA,IAAI,SAAS,MAAQ,EAAA;AACnB,MAAoB,iBAAA,GAAA,OAAA,CAAQ,OAAO,MAAM,CAAA;AAAA;AAG3C,IAAO,OAAA;AAAA,MACLC,4CAAoC,OAAO,CAAA;AAAA,MAC3CC,2CAA6B,OAAO;AAAA,KACtC;AACA,IAAA,IAAI,qBAAuB,EAAA;AACzB,MAAO,OAAA;AAAA,QACLC,kDAAuC,iBAAiB,CAAA;AAAA,QACxDC,sCAAA;AAAA,QACAC,kDAAA;AAAA,QACAC;AAAA,OACF;AAAA;AACF;AAEJ,CAAC,CAAA;AA6CI,MAAM,8BAA8B,MAAO,CAAA,MAAA;AAAA,EAChD,sCAAA;AAAA,EACA,sCAAuC;AACzC;;;;"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -7,6 +7,7 @@ var schemas = require('./schemas/schemas.cjs.js');
|
|
|
7
7
|
var frontend = require('./schemas/frontend.cjs.js');
|
|
8
8
|
var rootLogger = require('./schemas/rootLogger.cjs.js');
|
|
9
9
|
var features = require('./features/features.cjs.js');
|
|
10
|
+
var frontendRemotesServer = require('./server/frontendRemotesServer.cjs.js');
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
|
|
@@ -21,4 +22,5 @@ exports.dynamicPluginsSchemasServiceFactory = schemas.dynamicPluginsSchemasServi
|
|
|
21
22
|
exports.dynamicPluginsFrontendSchemas = frontend.dynamicPluginsFrontendSchemas;
|
|
22
23
|
exports.dynamicPluginsRootLoggerServiceFactory = rootLogger.dynamicPluginsRootLoggerServiceFactory;
|
|
23
24
|
exports.dynamicPluginsFeatureLoader = features.dynamicPluginsFeatureLoader;
|
|
25
|
+
exports.dynamicPluginsFrontendServiceRef = frontendRemotesServer.dynamicPluginsFrontendServiceRef;
|
|
24
26
|
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { IndexBuilder } from '@backstage/plugin-search-backend-node';
|
|
|
13
13
|
import { PermissionPolicy } from '@backstage/plugin-permission-node';
|
|
14
14
|
import { ConfigSchema } from '@backstage/config-loader';
|
|
15
15
|
import { WinstonLoggerOptions } from '@backstage/backend-defaults/rootLogger';
|
|
16
|
+
import { JsonObject } from '@backstage/types';
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* @public
|
|
@@ -334,4 +335,87 @@ type DynamicPluginsFeatureLoaderOptions = DynamicPluginsFactoryOptions & Dynamic
|
|
|
334
335
|
*/
|
|
335
336
|
declare const dynamicPluginsFeatureLoader: ((options?: DynamicPluginsFeatureLoaderOptions) => _backstage_backend_plugin_api.BackendFeature) & _backstage_backend_plugin_api.BackendFeature;
|
|
336
337
|
|
|
337
|
-
|
|
338
|
+
/**
|
|
339
|
+
* Definition of a frontend plugin Module Federation remote served by the backend
|
|
340
|
+
* @public
|
|
341
|
+
*/
|
|
342
|
+
interface RemoteInfo {
|
|
343
|
+
/**
|
|
344
|
+
* Name of the module federation remote
|
|
345
|
+
*/
|
|
346
|
+
name: string;
|
|
347
|
+
/**
|
|
348
|
+
* Remote entry, either the remote manifest file, or the remote entry Javascript file.
|
|
349
|
+
*/
|
|
350
|
+
entry: string;
|
|
351
|
+
entryGlobalName?: string;
|
|
352
|
+
shareScope?: string;
|
|
353
|
+
type?: RemoteInfoTypeEnum;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* @public
|
|
357
|
+
*/
|
|
358
|
+
type RemoteInfoTypeEnum = 'var' | 'module' | 'assign' | 'assign-properties' | 'this' | 'window' | 'self' | 'global' | 'commonjs' | 'commonjs2' | 'commonjs-module' | 'commonjs-static' | 'amd' | 'amd-require' | 'umd' | 'umd2' | 'jsonp' | 'system';
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
*
|
|
362
|
+
* @public
|
|
363
|
+
* */
|
|
364
|
+
type AdditionalRemoteInfo = Omit<RemoteInfo, 'name' | 'entry'>;
|
|
365
|
+
/**
|
|
366
|
+
*
|
|
367
|
+
* @public
|
|
368
|
+
* */
|
|
369
|
+
type FrontendRemoteResolver = {
|
|
370
|
+
/**
|
|
371
|
+
* Relative path to the module federation assets folder from thr root folder of the plugin package.
|
|
372
|
+
* Default value is `dist`.
|
|
373
|
+
*/
|
|
374
|
+
assetsPathFromPackage?: string;
|
|
375
|
+
/**
|
|
376
|
+
* File name of the module federation manifest inside the module federation assets folder.
|
|
377
|
+
* Default value is `mf-manifest.json`.
|
|
378
|
+
*/
|
|
379
|
+
manifestFileName?: string;
|
|
380
|
+
/**
|
|
381
|
+
* Type of the remote entry returned in the RemoteInfo for this remote.
|
|
382
|
+
* Default value is `manifest`.
|
|
383
|
+
*/
|
|
384
|
+
getRemoteEntryType?: (manifestContent: JsonObject) => 'manifest' | 'javascript';
|
|
385
|
+
/**
|
|
386
|
+
* Additional module federation fields, which might be required if the remote entry type is 'javascript'.
|
|
387
|
+
*/
|
|
388
|
+
getAdditionaRemoteInfo?: (manifestContent: JsonObject) => AdditionalRemoteInfo;
|
|
389
|
+
/**
|
|
390
|
+
* Overrides the list of exposed modules. By default the exposed modules are read from the manifest file.
|
|
391
|
+
*/
|
|
392
|
+
overrideExposedModules?: (exposedModules: string[], manifestContent: JsonObject) => string[];
|
|
393
|
+
/**
|
|
394
|
+
* Customizes the manifest before returning it as the remote entry.
|
|
395
|
+
*/
|
|
396
|
+
customizeManifest?: (content: JsonObject) => JsonObject;
|
|
397
|
+
};
|
|
398
|
+
/**
|
|
399
|
+
*
|
|
400
|
+
* @public
|
|
401
|
+
* */
|
|
402
|
+
type FrontendRemoteResolverProvider = {
|
|
403
|
+
for(pluginName: string, pluginPackagePath: string): Partial<FrontendRemoteResolver> | undefined;
|
|
404
|
+
};
|
|
405
|
+
/**
|
|
406
|
+
*
|
|
407
|
+
* @public
|
|
408
|
+
* */
|
|
409
|
+
interface DynamicPluginsFrontendRemotesService {
|
|
410
|
+
setResolverProvider(provider: FrontendRemoteResolverProvider): void;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* A service that serves the frontend module federation remotes,
|
|
414
|
+
* and allows a plugin to customize the way remotes are served,
|
|
415
|
+
* by setting a ResolverProvider.
|
|
416
|
+
*
|
|
417
|
+
* @public
|
|
418
|
+
*/
|
|
419
|
+
declare const dynamicPluginsFrontendServiceRef: _backstage_backend_plugin_api.ServiceRef<DynamicPluginsFrontendRemotesService, "root", "singleton">;
|
|
420
|
+
|
|
421
|
+
export { type AdditionalRemoteInfo, type BackendDynamicPlugin, type BackendDynamicPluginInstaller, type BackendPluginProvider, type BaseDynamicPlugin, CommonJSModuleLoader, type CommonJSModuleLoaderOptions, type DynamicPlugin, DynamicPluginManager, type DynamicPluginManagerOptions, type DynamicPluginProvider, type DynamicPluginsFactoryOptions, type DynamicPluginsFeatureLoaderOptions, type DynamicPluginsFrontendRemotesService, type DynamicPluginsRootLoggerFactoryOptions, type DynamicPluginsSchemasOptions, type DynamicPluginsSchemasService, type FrontendDynamicPlugin, type FrontendPluginProvider, type FrontendRemoteResolver, type FrontendRemoteResolverProvider, type LegacyBackendPluginInstaller, type LegacyPluginEnvironment, type ModuleLoader, type NewBackendPluginInstaller, type RemoteInfo, type RemoteInfoTypeEnum, type ScannedPluginManifest, type ScannedPluginPackage, dynamicPluginsFeatureDiscoveryLoader, dynamicPluginsFeatureLoader, dynamicPluginsFrontendSchemas, dynamicPluginsFrontendServiceRef, dynamicPluginsRootLoggerServiceFactory, dynamicPluginsSchemasServiceFactory, dynamicPluginsServiceFactory, dynamicPluginsServiceFactoryWithOptions, dynamicPluginsServiceRef, isBackendDynamicPluginInstaller };
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendOpenapiUtils = require('@backstage/backend-openapi-utils');
|
|
4
|
+
|
|
5
|
+
const spec = {
|
|
6
|
+
openapi: "3.0.3",
|
|
7
|
+
info: {
|
|
8
|
+
title: ".backstage/dynamic-features",
|
|
9
|
+
version: "1",
|
|
10
|
+
description: "The Backstage backend plugin that serves the frontend plugins module federation manifests and assets",
|
|
11
|
+
license: {
|
|
12
|
+
name: "Apache-2.0",
|
|
13
|
+
url: "http://www.apache.org/licenses/LICENSE-2.0.html"
|
|
14
|
+
},
|
|
15
|
+
contact: {}
|
|
16
|
+
},
|
|
17
|
+
servers: [
|
|
18
|
+
{
|
|
19
|
+
url: "/"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
components: {
|
|
23
|
+
examples: {},
|
|
24
|
+
headers: {},
|
|
25
|
+
parameters: {},
|
|
26
|
+
requestBodies: {},
|
|
27
|
+
responses: {
|
|
28
|
+
RemotesResponse: {
|
|
29
|
+
description: "List of Module Federation Remotes exposed by the backend",
|
|
30
|
+
content: {
|
|
31
|
+
"application/json": {
|
|
32
|
+
schema: {
|
|
33
|
+
$ref: "#/components/schemas/Remotes"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
ErrorResponse: {
|
|
39
|
+
description: "An error response from the backend.",
|
|
40
|
+
content: {
|
|
41
|
+
"application/json": {
|
|
42
|
+
schema: {
|
|
43
|
+
$ref: "#/components/schemas/Error"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
schemas: {
|
|
50
|
+
Remotes: {
|
|
51
|
+
type: "array",
|
|
52
|
+
items: {
|
|
53
|
+
$ref: "#/components/schemas/Remote"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
Remote: {
|
|
57
|
+
description: "Definition of a frontend plugin Module Federation remote served by the backend",
|
|
58
|
+
type: "object",
|
|
59
|
+
properties: {
|
|
60
|
+
packageName: {
|
|
61
|
+
description: "Name of the package exposed through this Module Federation remote",
|
|
62
|
+
type: "string"
|
|
63
|
+
},
|
|
64
|
+
remoteInfo: {
|
|
65
|
+
$ref: "#/components/schemas/RemoteInfo"
|
|
66
|
+
},
|
|
67
|
+
exposedModules: {
|
|
68
|
+
description: "Names of modules exposed by this module federation remote",
|
|
69
|
+
type: "array",
|
|
70
|
+
items: {
|
|
71
|
+
type: "string"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
required: ["packageName", "remoteInfo", "exposedModules"]
|
|
76
|
+
},
|
|
77
|
+
RemoteInfo: {
|
|
78
|
+
description: "Definition of a frontend plugin Module Federation remote served by the backend",
|
|
79
|
+
externalDocs: {
|
|
80
|
+
url: "https://module-federation.io/guide/basic/runtime.html#init"
|
|
81
|
+
},
|
|
82
|
+
type: "object",
|
|
83
|
+
properties: {
|
|
84
|
+
name: {
|
|
85
|
+
description: "Name of the module federation remote",
|
|
86
|
+
type: "string"
|
|
87
|
+
},
|
|
88
|
+
entry: {
|
|
89
|
+
description: "Remote entry, either the remote manifest file, or the remote entry Javascript file.",
|
|
90
|
+
type: "string"
|
|
91
|
+
},
|
|
92
|
+
entryGlobalName: {
|
|
93
|
+
type: "string"
|
|
94
|
+
},
|
|
95
|
+
shareScope: {
|
|
96
|
+
type: "string"
|
|
97
|
+
},
|
|
98
|
+
type: {
|
|
99
|
+
type: "string",
|
|
100
|
+
enum: [
|
|
101
|
+
"var",
|
|
102
|
+
"module",
|
|
103
|
+
"assign",
|
|
104
|
+
"assign-properties",
|
|
105
|
+
"this",
|
|
106
|
+
"window",
|
|
107
|
+
"self",
|
|
108
|
+
"global",
|
|
109
|
+
"commonjs",
|
|
110
|
+
"commonjs2",
|
|
111
|
+
"commonjs-module",
|
|
112
|
+
"commonjs-static",
|
|
113
|
+
"amd",
|
|
114
|
+
"amd-require",
|
|
115
|
+
"umd",
|
|
116
|
+
"umd2",
|
|
117
|
+
"jsonp",
|
|
118
|
+
"system"
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
required: ["name", "entry"]
|
|
123
|
+
},
|
|
124
|
+
Error: {
|
|
125
|
+
type: "object",
|
|
126
|
+
properties: {
|
|
127
|
+
error: {
|
|
128
|
+
type: "object",
|
|
129
|
+
properties: {
|
|
130
|
+
name: {
|
|
131
|
+
type: "string"
|
|
132
|
+
},
|
|
133
|
+
message: {
|
|
134
|
+
type: "string"
|
|
135
|
+
},
|
|
136
|
+
stack: {
|
|
137
|
+
type: "string"
|
|
138
|
+
},
|
|
139
|
+
code: {
|
|
140
|
+
type: "string"
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
required: ["name", "message"]
|
|
144
|
+
},
|
|
145
|
+
request: {
|
|
146
|
+
type: "object",
|
|
147
|
+
properties: {
|
|
148
|
+
method: {
|
|
149
|
+
type: "string"
|
|
150
|
+
},
|
|
151
|
+
url: {
|
|
152
|
+
type: "string"
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
required: ["method", "url"]
|
|
156
|
+
},
|
|
157
|
+
response: {
|
|
158
|
+
type: "object",
|
|
159
|
+
properties: {
|
|
160
|
+
statusCode: {
|
|
161
|
+
type: "number"
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
required: ["statusCode"]
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
required: ["error", "response"],
|
|
168
|
+
additionalProperties: {}
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
securitySchemes: {
|
|
172
|
+
JWT: {
|
|
173
|
+
type: "http",
|
|
174
|
+
scheme: "bearer",
|
|
175
|
+
bearerFormat: "JWT"
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
paths: {
|
|
180
|
+
"/remotes": {
|
|
181
|
+
get: {
|
|
182
|
+
operationId: "GetRemotes",
|
|
183
|
+
description: "Get the Module Federation remote definitions.",
|
|
184
|
+
responses: {
|
|
185
|
+
"200": {
|
|
186
|
+
$ref: "#/components/responses/RemotesResponse"
|
|
187
|
+
},
|
|
188
|
+
"400": {
|
|
189
|
+
$ref: "#/components/responses/ErrorResponse"
|
|
190
|
+
},
|
|
191
|
+
default: {
|
|
192
|
+
$ref: "#/components/responses/ErrorResponse"
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
security: [
|
|
196
|
+
{},
|
|
197
|
+
{
|
|
198
|
+
JWT: []
|
|
199
|
+
}
|
|
200
|
+
],
|
|
201
|
+
parameters: []
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
const createOpenApiRouter = async (options) => backendOpenapiUtils.createValidatedOpenApiRouterFromGeneratedEndpointMap(
|
|
207
|
+
spec,
|
|
208
|
+
options
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
exports.createOpenApiRouter = createOpenApiRouter;
|
|
212
|
+
exports.spec = spec;
|
|
213
|
+
//# sourceMappingURL=router.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.cjs.js","sources":["../../../../src/schema/openapi/generated/router.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// ******************************************************************\n// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *\n// ******************************************************************\nimport { createValidatedOpenApiRouterFromGeneratedEndpointMap } from '@backstage/backend-openapi-utils';\nimport { EndpointMap } from './';\n\nexport const spec = {\n openapi: '3.0.3',\n info: {\n title: '.backstage/dynamic-features',\n version: '1',\n description:\n 'The Backstage backend plugin that serves the frontend plugins module federation manifests and assets',\n license: {\n name: 'Apache-2.0',\n url: 'http://www.apache.org/licenses/LICENSE-2.0.html',\n },\n contact: {},\n },\n servers: [\n {\n url: '/',\n },\n ],\n components: {\n examples: {},\n headers: {},\n parameters: {},\n requestBodies: {},\n responses: {\n RemotesResponse: {\n description: 'List of Module Federation Remotes exposed by the backend',\n content: {\n 'application/json': {\n schema: {\n $ref: '#/components/schemas/Remotes',\n },\n },\n },\n },\n ErrorResponse: {\n description: 'An error response from the backend.',\n content: {\n 'application/json': {\n schema: {\n $ref: '#/components/schemas/Error',\n },\n },\n },\n },\n },\n schemas: {\n Remotes: {\n type: 'array',\n items: {\n $ref: '#/components/schemas/Remote',\n },\n },\n Remote: {\n description:\n 'Definition of a frontend plugin Module Federation remote served by the backend',\n type: 'object',\n properties: {\n packageName: {\n description:\n 'Name of the package exposed through this Module Federation remote',\n type: 'string',\n },\n remoteInfo: {\n $ref: '#/components/schemas/RemoteInfo',\n },\n exposedModules: {\n description:\n 'Names of modules exposed by this module federation remote',\n type: 'array',\n items: {\n type: 'string',\n },\n },\n },\n required: ['packageName', 'remoteInfo', 'exposedModules'],\n },\n RemoteInfo: {\n description:\n 'Definition of a frontend plugin Module Federation remote served by the backend',\n externalDocs: {\n url: 'https://module-federation.io/guide/basic/runtime.html#init',\n },\n type: 'object',\n properties: {\n name: {\n description: 'Name of the module federation remote',\n type: 'string',\n },\n entry: {\n description:\n 'Remote entry, either the remote manifest file, or the remote entry Javascript file.',\n type: 'string',\n },\n entryGlobalName: {\n type: 'string',\n },\n shareScope: {\n type: 'string',\n },\n type: {\n type: 'string',\n enum: [\n 'var',\n 'module',\n 'assign',\n 'assign-properties',\n 'this',\n 'window',\n 'self',\n 'global',\n 'commonjs',\n 'commonjs2',\n 'commonjs-module',\n 'commonjs-static',\n 'amd',\n 'amd-require',\n 'umd',\n 'umd2',\n 'jsonp',\n 'system',\n ],\n },\n },\n required: ['name', 'entry'],\n },\n Error: {\n type: 'object',\n properties: {\n error: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n },\n message: {\n type: 'string',\n },\n stack: {\n type: 'string',\n },\n code: {\n type: 'string',\n },\n },\n required: ['name', 'message'],\n },\n request: {\n type: 'object',\n properties: {\n method: {\n type: 'string',\n },\n url: {\n type: 'string',\n },\n },\n required: ['method', 'url'],\n },\n response: {\n type: 'object',\n properties: {\n statusCode: {\n type: 'number',\n },\n },\n required: ['statusCode'],\n },\n },\n required: ['error', 'response'],\n additionalProperties: {},\n },\n },\n securitySchemes: {\n JWT: {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: 'JWT',\n },\n },\n },\n paths: {\n '/remotes': {\n get: {\n operationId: 'GetRemotes',\n description: 'Get the Module Federation remote definitions.',\n responses: {\n '200': {\n $ref: '#/components/responses/RemotesResponse',\n },\n '400': {\n $ref: '#/components/responses/ErrorResponse',\n },\n default: {\n $ref: '#/components/responses/ErrorResponse',\n },\n },\n security: [\n {},\n {\n JWT: [],\n },\n ],\n parameters: [],\n },\n },\n },\n} as const;\nexport const createOpenApiRouter = async (\n options?: Parameters<\n typeof createValidatedOpenApiRouterFromGeneratedEndpointMap\n >['1'],\n) =>\n createValidatedOpenApiRouterFromGeneratedEndpointMap<EndpointMap>(\n spec,\n options,\n );\n"],"names":["createValidatedOpenApiRouterFromGeneratedEndpointMap"],"mappings":"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"}
|
|
@@ -96,7 +96,7 @@ const dynamicPluginsSchemasServiceFactory = Object.assign(
|
|
|
96
96
|
dynamicPluginsSchemasServiceFactoryWithOptions,
|
|
97
97
|
dynamicPluginsSchemasServiceFactoryWithOptions()
|
|
98
98
|
);
|
|
99
|
-
async function gatherDynamicPluginsSchemas(packages, logger, schemaLocator = () => path__namespace.join("dist", "
|
|
99
|
+
async function gatherDynamicPluginsSchemas(packages, logger, schemaLocator = () => path__namespace.join("dist", ".config-schema.json")) {
|
|
100
100
|
const allSchemas = {};
|
|
101
101
|
for (const pluginPackage of packages) {
|
|
102
102
|
let schemaLocation = schemaLocator(pluginPackage);
|
|
@@ -107,13 +107,18 @@ async function gatherDynamicPluginsSchemas(packages, logger, schemaLocator = ()
|
|
|
107
107
|
if (!await fs__default.default.pathExists(schemaLocation)) {
|
|
108
108
|
continue;
|
|
109
109
|
}
|
|
110
|
-
|
|
110
|
+
let serialized = await fs__default.default.readJson(schemaLocation);
|
|
111
111
|
if (!serialized) {
|
|
112
112
|
continue;
|
|
113
113
|
}
|
|
114
114
|
if (lodash.isEmpty(serialized)) {
|
|
115
115
|
continue;
|
|
116
116
|
}
|
|
117
|
+
if (serialized?.backstageConfigSchemaVersion === 1) {
|
|
118
|
+
serialized = configLoader.mergeConfigSchemas(
|
|
119
|
+
(serialized?.schemas).map((_) => _.value)
|
|
120
|
+
);
|
|
121
|
+
}
|
|
117
122
|
if (!serialized?.$schema || serialized?.type !== "object") {
|
|
118
123
|
logger.error(
|
|
119
124
|
`Serialized configuration schema is invalid for plugin ${pluginPackage.manifest.name}`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.cjs.js","sources":["../../src/schemas/schemas.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ScannedPluginPackage } from '../scanner/types';\nimport {\n coreServices,\n createServiceFactory,\n createServiceRef,\n} from '@backstage/backend-plugin-api';\nimport { findPaths } from '@backstage/cli-common';\n\nimport fs from 'fs-extra';\nimport * as path from 'path';\nimport * as url from 'url';\nimport { isEmpty } from 'lodash';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { JsonObject } from '@backstage/types';\nimport { PluginScanner } from '../scanner/plugin-scanner';\nimport {
|
|
1
|
+
{"version":3,"file":"schemas.cjs.js","sources":["../../src/schemas/schemas.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ScannedPluginPackage } from '../scanner/types';\nimport {\n coreServices,\n createServiceFactory,\n createServiceRef,\n} from '@backstage/backend-plugin-api';\nimport { findPaths } from '@backstage/cli-common';\n\nimport fs from 'fs-extra';\nimport * as path from 'path';\nimport * as url from 'url';\nimport { isEmpty } from 'lodash';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { JsonObject } from '@backstage/types';\nimport { PluginScanner } from '../scanner/plugin-scanner';\nimport {\n ConfigSchema,\n loadConfigSchema,\n mergeConfigSchemas,\n} from '@backstage/config-loader';\nimport { dynamicPluginsFeatureLoader } from '../features';\n\n/**\n *\n * @public\n * */\nexport interface DynamicPluginsSchemasService {\n addDynamicPluginsSchemas(configSchema: ConfigSchema): Promise<{\n schema: ConfigSchema;\n }>;\n}\n\n/**\n * A service that provides the config schemas of scanned dynamic plugins.\n *\n * @public\n */\nexport const dynamicPluginsSchemasServiceRef =\n createServiceRef<DynamicPluginsSchemasService>({\n id: 'core.dynamicplugins.schemas',\n scope: 'root',\n });\n\n/**\n * @public\n */\nexport interface DynamicPluginsSchemasOptions {\n /**\n * Function that returns the path to the Json schema file for a given scanned plugin package.\n * The path is either absolute, or relative to the plugin package root directory.\n *\n * Default behavior is to look for the `dist/configSchema.json` relative path.\n *\n * @param pluginPackage - The scanned plugin package.\n * @returns the absolute or plugin-relative path to the Json schema file.\n */\n schemaLocator?: (pluginPackage: ScannedPluginPackage) => string;\n}\n\nconst dynamicPluginsSchemasServiceFactoryWithOptions = (\n options?: DynamicPluginsSchemasOptions,\n) =>\n createServiceFactory({\n service: dynamicPluginsSchemasServiceRef,\n deps: {\n config: coreServices.rootConfig,\n },\n factory({ config }) {\n let additionalSchemas: { [context: string]: JsonObject } | undefined;\n\n return {\n async addDynamicPluginsSchemas(configSchema: ConfigSchema): Promise<{\n schema: ConfigSchema;\n }> {\n if (!additionalSchemas) {\n const logger = {\n ...console,\n child() {\n return this;\n },\n };\n\n const scanner = PluginScanner.create({\n config,\n logger,\n // eslint-disable-next-line no-restricted-syntax\n backstageRoot: findPaths(__dirname).targetRoot,\n preferAlpha: true,\n });\n\n const { packages } = await scanner.scanRoot();\n\n additionalSchemas = await gatherDynamicPluginsSchemas(\n packages,\n logger,\n options?.schemaLocator,\n );\n }\n\n const serialized = configSchema.serialize();\n if (serialized?.backstageConfigSchemaVersion !== 1) {\n throw new Error(\n 'Serialized configuration schema is invalid or has an invalid version number',\n );\n }\n const schemas = serialized.schemas as {\n value: JsonObject;\n path: string;\n }[];\n\n schemas.push(\n ...Object.keys(additionalSchemas).map(context => {\n return {\n path: context,\n value: additionalSchemas![context],\n };\n }),\n );\n serialized.schemas = schemas;\n return {\n schema: await loadConfigSchema({\n serialized,\n }),\n };\n },\n };\n },\n });\n\n/**\n * @public\n * @deprecated Use {@link dynamicPluginsFeatureLoader} instead, which gathers all services and features required for dynamic plugins.\n */\nexport const dynamicPluginsSchemasServiceFactory = Object.assign(\n dynamicPluginsSchemasServiceFactoryWithOptions,\n dynamicPluginsSchemasServiceFactoryWithOptions(),\n);\n\n/** @internal */\nasync function gatherDynamicPluginsSchemas(\n packages: ScannedPluginPackage[],\n logger: LoggerService,\n schemaLocator: (pluginPackage: ScannedPluginPackage) => string = () =>\n path.join('dist', '.config-schema.json'),\n): Promise<{ [context: string]: JsonObject }> {\n const allSchemas: { [context: string]: JsonObject } = {};\n\n for (const pluginPackage of packages) {\n let schemaLocation = schemaLocator(pluginPackage);\n\n if (!path.isAbsolute(schemaLocation)) {\n const pluginLocation = url.fileURLToPath(pluginPackage.location);\n schemaLocation = path.resolve(pluginLocation, schemaLocation);\n }\n\n if (!(await fs.pathExists(schemaLocation))) {\n continue;\n }\n\n let serialized = await fs.readJson(schemaLocation);\n if (!serialized) {\n continue;\n }\n\n if (isEmpty(serialized)) {\n continue;\n }\n\n if (serialized?.backstageConfigSchemaVersion === 1) {\n serialized = mergeConfigSchemas(\n (serialized?.schemas as JsonObject[]).map(_ => _.value as any),\n );\n }\n\n if (!serialized?.$schema || serialized?.type !== 'object') {\n logger.error(\n `Serialized configuration schema is invalid for plugin ${pluginPackage.manifest.name}`,\n );\n continue;\n }\n\n allSchemas[schemaLocation] = serialized;\n }\n\n return allSchemas;\n}\n"],"names":["createServiceRef","createServiceFactory","coreServices","PluginScanner","findPaths","loadConfigSchema","path","url","fs","isEmpty","mergeConfigSchemas"],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
|
+
var router$1 = require('./router.cjs.js');
|
|
5
|
+
var backendDynamicFeatureService = require('@backstage/backend-dynamic-feature-service');
|
|
6
|
+
var router = require('../schema/openapi/generated/router.cjs.js');
|
|
7
|
+
var sdk = require('@module-federation/sdk');
|
|
8
|
+
|
|
9
|
+
const dynamicPluginsFrontendServiceRef = backendPluginApi.createServiceRef({
|
|
10
|
+
id: "core.dynamicplugins.frontendRemotes",
|
|
11
|
+
scope: "root"
|
|
12
|
+
});
|
|
13
|
+
const frontendRemotesServerService = backendPluginApi.createServiceFactory({
|
|
14
|
+
service: dynamicPluginsFrontendServiceRef,
|
|
15
|
+
deps: {
|
|
16
|
+
logger: backendPluginApi.coreServices.rootLogger,
|
|
17
|
+
rootHttpRouter: backendPluginApi.coreServices.rootHttpRouter,
|
|
18
|
+
config: backendPluginApi.coreServices.rootConfig,
|
|
19
|
+
dynamicPlugins: backendDynamicFeatureService.dynamicPluginsServiceRef,
|
|
20
|
+
lifecycle: backendPluginApi.coreServices.rootLifecycle
|
|
21
|
+
},
|
|
22
|
+
async factory({ logger, rootHttpRouter, config, dynamicPlugins, lifecycle }) {
|
|
23
|
+
const resolvers = {
|
|
24
|
+
default: {
|
|
25
|
+
assetsPathFromPackage: "dist",
|
|
26
|
+
manifestFileName: sdk.ManifestFileName,
|
|
27
|
+
getRemoteEntryType: () => "manifest"
|
|
28
|
+
},
|
|
29
|
+
provider: void 0
|
|
30
|
+
};
|
|
31
|
+
lifecycle.addStartupHook(async () => {
|
|
32
|
+
rootHttpRouter.use(
|
|
33
|
+
`/${router.spec.info.title}`,
|
|
34
|
+
await router$1.createRouter({
|
|
35
|
+
logger,
|
|
36
|
+
config,
|
|
37
|
+
dynamicPlugins,
|
|
38
|
+
resolvers
|
|
39
|
+
})
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
return {
|
|
43
|
+
setResolverProvider(resolver) {
|
|
44
|
+
logger.info("Setting resolver provider");
|
|
45
|
+
if (resolvers.provider) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
"Attempted to install a frontend remote resolver provider twice"
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
resolvers.provider = resolver;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
exports.dynamicPluginsFrontendServiceRef = dynamicPluginsFrontendServiceRef;
|
|
57
|
+
exports.frontendRemotesServerService = frontendRemotesServerService;
|
|
58
|
+
//# sourceMappingURL=frontendRemotesServer.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontendRemotesServer.cjs.js","sources":["../../src/server/frontendRemotesServer.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n coreServices,\n createServiceFactory,\n createServiceRef,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './router';\nimport { dynamicPluginsServiceRef } from '@backstage/backend-dynamic-feature-service';\nimport { spec } from '../schema/openapi';\nimport { ManifestFileName } from '@module-federation/sdk';\nimport { RemoteInfo } from '../schema/openapi/generated/models';\nimport { JsonObject } from '@backstage/types';\n\n/**\n *\n * @public\n * */\nexport type AdditionalRemoteInfo = Omit<RemoteInfo, 'name' | 'entry'>;\n\n/**\n *\n * @public\n * */\nexport type FrontendRemoteResolver = {\n /**\n * Relative path to the module federation assets folder from thr root folder of the plugin package.\n * Default value is `dist`.\n */\n assetsPathFromPackage?: string;\n\n /**\n * File name of the module federation manifest inside the module federation assets folder.\n * Default value is `mf-manifest.json`.\n */\n manifestFileName?: string;\n\n /**\n * Type of the remote entry returned in the RemoteInfo for this remote.\n * Default value is `manifest`.\n */\n getRemoteEntryType?: (\n manifestContent: JsonObject,\n ) => 'manifest' | 'javascript';\n\n /**\n * Additional module federation fields, which might be required if the remote entry type is 'javascript'.\n */\n getAdditionaRemoteInfo?: (\n manifestContent: JsonObject,\n ) => AdditionalRemoteInfo;\n\n /**\n * Overrides the list of exposed modules. By default the exposed modules are read from the manifest file.\n */\n overrideExposedModules?: (\n exposedModules: string[],\n manifestContent: JsonObject,\n ) => string[];\n\n /**\n * Customizes the manifest before returning it as the remote entry.\n */\n customizeManifest?: (content: JsonObject) => JsonObject;\n};\n\n/**\n *\n * @public\n * */\nexport type FrontendRemoteResolverProvider = {\n for(\n pluginName: string,\n pluginPackagePath: string,\n ): Partial<FrontendRemoteResolver> | undefined;\n};\n\n/**\n *\n * @public\n * */\nexport interface DynamicPluginsFrontendRemotesService {\n setResolverProvider(provider: FrontendRemoteResolverProvider): void;\n}\n\n/**\n * A service that serves the frontend module federation remotes,\n * and allows a plugin to customize the way remotes are served,\n * by setting a ResolverProvider.\n *\n * @public\n */\nexport const dynamicPluginsFrontendServiceRef =\n createServiceRef<DynamicPluginsFrontendRemotesService>({\n id: 'core.dynamicplugins.frontendRemotes',\n scope: 'root',\n });\n\nexport type FrontendRemoteResolvers = {\n default: FrontendRemoteResolver &\n Required<\n Pick<\n FrontendRemoteResolver,\n 'assetsPathFromPackage' | 'manifestFileName' | 'getRemoteEntryType'\n >\n >;\n provider?: FrontendRemoteResolverProvider;\n};\n\nexport const frontendRemotesServerService = createServiceFactory({\n service: dynamicPluginsFrontendServiceRef,\n deps: {\n logger: coreServices.rootLogger,\n rootHttpRouter: coreServices.rootHttpRouter,\n config: coreServices.rootConfig,\n dynamicPlugins: dynamicPluginsServiceRef,\n lifecycle: coreServices.rootLifecycle,\n },\n async factory({ logger, rootHttpRouter, config, dynamicPlugins, lifecycle }) {\n const resolvers: FrontendRemoteResolvers = {\n default: {\n assetsPathFromPackage: 'dist',\n manifestFileName: ManifestFileName,\n getRemoteEntryType: () => 'manifest',\n },\n provider: undefined,\n };\n\n lifecycle.addStartupHook(async () => {\n rootHttpRouter.use(\n `/${spec.info.title}`,\n await createRouter({\n logger,\n config,\n dynamicPlugins,\n resolvers,\n }),\n );\n });\n\n return {\n setResolverProvider(resolver) {\n logger.info('Setting resolver provider');\n if (resolvers.provider) {\n throw new Error(\n 'Attempted to install a frontend remote resolver provider twice',\n );\n }\n resolvers.provider = resolver;\n },\n };\n },\n});\n"],"names":["createServiceRef","createServiceFactory","coreServices","dynamicPluginsServiceRef","ManifestFileName","spec","createRouter"],"mappings":";;;;;;;;AAyGO,MAAM,mCACXA,iCAAuD,CAAA;AAAA,EACrD,EAAI,EAAA,qCAAA;AAAA,EACJ,KAAO,EAAA;AACT,CAAC;AAaI,MAAM,+BAA+BC,qCAAqB,CAAA;AAAA,EAC/D,OAAS,EAAA,gCAAA;AAAA,EACT,IAAM,EAAA;AAAA,IACJ,QAAQC,6BAAa,CAAA,UAAA;AAAA,IACrB,gBAAgBA,6BAAa,CAAA,cAAA;AAAA,IAC7B,QAAQA,6BAAa,CAAA,UAAA;AAAA,IACrB,cAAgB,EAAAC,qDAAA;AAAA,IAChB,WAAWD,6BAAa,CAAA;AAAA,GAC1B;AAAA,EACA,MAAM,QAAQ,EAAE,MAAA,EAAQ,gBAAgB,MAAQ,EAAA,cAAA,EAAgB,WAAa,EAAA;AAC3E,IAAA,MAAM,SAAqC,GAAA;AAAA,MACzC,OAAS,EAAA;AAAA,QACP,qBAAuB,EAAA,MAAA;AAAA,QACvB,gBAAkB,EAAAE,oBAAA;AAAA,QAClB,oBAAoB,MAAM;AAAA,OAC5B;AAAA,MACA,QAAU,EAAA,KAAA;AAAA,KACZ;AAEA,IAAA,SAAA,CAAU,eAAe,YAAY;AACnC,MAAe,cAAA,CAAA,GAAA;AAAA,QACb,CAAA,CAAA,EAAIC,WAAK,CAAA,IAAA,CAAK,KAAK,CAAA,CAAA;AAAA,QACnB,MAAMC,qBAAa,CAAA;AAAA,UACjB,MAAA;AAAA,UACA,MAAA;AAAA,UACA,cAAA;AAAA,UACA;AAAA,SACD;AAAA,OACH;AAAA,KACD,CAAA;AAED,IAAO,OAAA;AAAA,MACL,oBAAoB,QAAU,EAAA;AAC5B,QAAA,MAAA,CAAO,KAAK,2BAA2B,CAAA;AACvC,QAAA,IAAI,UAAU,QAAU,EAAA;AACtB,UAAA,MAAM,IAAI,KAAA;AAAA,YACR;AAAA,WACF;AAAA;AAEF,QAAA,SAAA,CAAU,QAAW,GAAA,QAAA;AAAA;AACvB,KACF;AAAA;AAEJ,CAAC;;;;;"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var express = require('express');
|
|
4
|
+
var router = require('../schema/openapi/generated/router.cjs.js');
|
|
5
|
+
var fs = require('fs');
|
|
6
|
+
var path = require('path');
|
|
7
|
+
var url = require('url');
|
|
8
|
+
|
|
9
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
10
|
+
|
|
11
|
+
function _interopNamespaceCompat(e) {
|
|
12
|
+
if (e && typeof e === 'object' && 'default' in e) return e;
|
|
13
|
+
var n = Object.create(null);
|
|
14
|
+
if (e) {
|
|
15
|
+
Object.keys(e).forEach(function (k) {
|
|
16
|
+
if (k !== 'default') {
|
|
17
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
18
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () { return e[k]; }
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
n.default = e;
|
|
26
|
+
return Object.freeze(n);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var express__default = /*#__PURE__*/_interopDefaultCompat(express);
|
|
30
|
+
var fs__namespace = /*#__PURE__*/_interopNamespaceCompat(fs);
|
|
31
|
+
var path__namespace = /*#__PURE__*/_interopNamespaceCompat(path);
|
|
32
|
+
var url__namespace = /*#__PURE__*/_interopNamespaceCompat(url);
|
|
33
|
+
|
|
34
|
+
async function createRouter({
|
|
35
|
+
logger,
|
|
36
|
+
config,
|
|
37
|
+
dynamicPlugins,
|
|
38
|
+
resolvers
|
|
39
|
+
}) {
|
|
40
|
+
const externalBaseUrl = `${config.getString("backend.baseUrl")}/${router.spec.info.title}`;
|
|
41
|
+
const typedRouter = await router.createOpenApiRouter();
|
|
42
|
+
const frontendPluginRemotes = [];
|
|
43
|
+
const { default: defaultResolver, provider: resolverProvider } = resolvers;
|
|
44
|
+
for (const plugin of dynamicPlugins.frontendPlugins()) {
|
|
45
|
+
try {
|
|
46
|
+
const pluginScannedPackage = dynamicPlugins.getScannedPackage(plugin);
|
|
47
|
+
const pluginScannedPackagePath = path__namespace.resolve(
|
|
48
|
+
url__namespace.fileURLToPath(pluginScannedPackage.location)
|
|
49
|
+
);
|
|
50
|
+
const providedResolver = resolverProvider?.for(
|
|
51
|
+
plugin.name,
|
|
52
|
+
pluginScannedPackagePath
|
|
53
|
+
);
|
|
54
|
+
const assetsPath = path__namespace.resolve(
|
|
55
|
+
pluginScannedPackagePath,
|
|
56
|
+
providedResolver?.assetsPathFromPackage ?? defaultResolver.assetsPathFromPackage
|
|
57
|
+
);
|
|
58
|
+
const manifestFileName = providedResolver?.manifestFileName ?? defaultResolver.manifestFileName;
|
|
59
|
+
const manifestLocation = path__namespace.resolve(assetsPath, manifestFileName);
|
|
60
|
+
if (!fs__namespace.existsSync(manifestLocation)) {
|
|
61
|
+
logger.error(
|
|
62
|
+
`Could not find manifest '${manifestLocation}' for frontend plugin ${plugin.name}@${plugin.version}`
|
|
63
|
+
);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
let manifest;
|
|
67
|
+
try {
|
|
68
|
+
manifest = JSON.parse(fs__namespace.readFileSync(manifestLocation).toString());
|
|
69
|
+
} catch (error) {
|
|
70
|
+
logger.error(
|
|
71
|
+
`Dynamic frontend plugin manifest '${manifestLocation}' could not be parsed for plugin ${plugin.name}@${plugin.version}`
|
|
72
|
+
);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (!manifest.name || typeof manifest.name !== "string") {
|
|
76
|
+
logger.error(
|
|
77
|
+
`Error in manifest '${manifestLocation}' for plugin ${plugin.name}@${plugin.version}: module name not found`
|
|
78
|
+
);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (!manifest.metaData || typeof manifest.metaData !== "object" || !("remoteEntry" in manifest.metaData) || !manifest.metaData.remoteEntry || typeof manifest.metaData.remoteEntry !== "object" || !("name" in manifest.metaData.remoteEntry) || typeof manifest.metaData.remoteEntry.name !== "string") {
|
|
82
|
+
logger.error(
|
|
83
|
+
`Could not find remote entry asset in the manifest '${manifestLocation}' for plugin ${plugin.name}@${plugin.version}`
|
|
84
|
+
);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (!manifest.exposes || !Array.isArray(manifest.exposes) || !manifest.exposes.every(
|
|
88
|
+
(i) => i !== null && typeof i === "object" && "name" in i
|
|
89
|
+
)) {
|
|
90
|
+
logger.error(
|
|
91
|
+
`Could not find the exposes field in the manifest '${manifestLocation}' for plugin ${plugin.name}@${plugin.version}`
|
|
92
|
+
);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const getAdditionalRemoteInfo = providedResolver?.getAdditionaRemoteInfo ?? defaultResolver.getAdditionaRemoteInfo;
|
|
96
|
+
const getRemoteEntryType = providedResolver?.getRemoteEntryType ?? defaultResolver.getRemoteEntryType;
|
|
97
|
+
const remoteEntryType = getRemoteEntryType(manifest);
|
|
98
|
+
let remoteEntryAsset = manifestFileName;
|
|
99
|
+
if (remoteEntryType === "javascript") {
|
|
100
|
+
remoteEntryAsset = manifest.metaData.remoteEntry.name;
|
|
101
|
+
}
|
|
102
|
+
const remoteEntryAssetLocation = path__namespace.resolve(
|
|
103
|
+
assetsPath,
|
|
104
|
+
remoteEntryAsset
|
|
105
|
+
);
|
|
106
|
+
if (!fs__namespace.existsSync(remoteEntryAssetLocation)) {
|
|
107
|
+
logger.error(
|
|
108
|
+
`Could not find remote entry asset '${remoteEntryAssetLocation}' for frontend plugin ${plugin.name}@${plugin.version}`
|
|
109
|
+
);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
const remoteAssetsPrefix = `/remotes/${plugin.name}`;
|
|
113
|
+
const remoteEntryPath = `${remoteAssetsPrefix}/${remoteEntryAsset}`;
|
|
114
|
+
const overrideExposedModules = providedResolver?.overrideExposedModules ?? defaultResolver.overrideExposedModules;
|
|
115
|
+
const exposedModules = manifest.exposes.map((e) => e.name);
|
|
116
|
+
frontendPluginRemotes.push({
|
|
117
|
+
packageName: plugin.name,
|
|
118
|
+
remoteInfo: {
|
|
119
|
+
name: manifest.name,
|
|
120
|
+
entry: `${externalBaseUrl}${remoteEntryPath}`,
|
|
121
|
+
...getAdditionalRemoteInfo?.(manifest)
|
|
122
|
+
},
|
|
123
|
+
exposedModules: overrideExposedModules?.(exposedModules, manifest) ?? exposedModules
|
|
124
|
+
});
|
|
125
|
+
const customizeManifest = providedResolver?.customizeManifest ?? defaultResolver.customizeManifest;
|
|
126
|
+
if (remoteEntryType === "manifest" && customizeManifest) {
|
|
127
|
+
const customizedContent = customizeManifest(manifest);
|
|
128
|
+
typedRouter.use(`${remoteEntryPath}`, (_, res) => {
|
|
129
|
+
res.json(customizedContent);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
typedRouter.use(remoteAssetsPrefix, express__default.default.static(assetsPath));
|
|
133
|
+
logger.info(
|
|
134
|
+
`Exposed dynamic frontend plugin '${plugin.name}' from '${assetsPath}' `
|
|
135
|
+
);
|
|
136
|
+
} catch (error) {
|
|
137
|
+
logger.error(
|
|
138
|
+
`Unexpected error when exposing dynamic frontend plugin '${plugin.name}@${plugin.version}'`,
|
|
139
|
+
error
|
|
140
|
+
);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
logger.info(`/remotes => ${JSON.stringify(frontendPluginRemotes)}`);
|
|
145
|
+
typedRouter.get("/remotes", (_, res) => {
|
|
146
|
+
res.status(200).json(frontendPluginRemotes);
|
|
147
|
+
});
|
|
148
|
+
return typedRouter;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
exports.createRouter = createRouter;
|
|
152
|
+
//# sourceMappingURL=router.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.cjs.js","sources":["../../src/server/router.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n LoggerService,\n RootConfigService,\n} from '@backstage/backend-plugin-api';\nimport express from 'express';\nimport { createOpenApiRouter, spec } from '../schema/openapi';\nimport { DynamicPluginProvider } from '@backstage/backend-dynamic-feature-service';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as url from 'url';\nimport { FrontendRemoteResolvers } from './frontendRemotesServer';\nimport { Remote } from '../schema/openapi/generated/models';\nimport { JsonObject } from '@backstage/types';\n\nexport async function createRouter({\n logger,\n config,\n dynamicPlugins,\n resolvers,\n}: {\n logger: LoggerService;\n config: RootConfigService;\n dynamicPlugins: DynamicPluginProvider;\n resolvers: FrontendRemoteResolvers;\n}): Promise<express.Router> {\n const externalBaseUrl = `${config.getString('backend.baseUrl')}/${\n spec.info.title\n }`;\n\n const typedRouter = await createOpenApiRouter();\n\n const frontendPluginRemotes: Remote[] = [];\n\n const { default: defaultResolver, provider: resolverProvider } = resolvers;\n for (const plugin of dynamicPlugins.frontendPlugins()) {\n try {\n const pluginScannedPackage = dynamicPlugins.getScannedPackage(plugin);\n const pluginScannedPackagePath = path.resolve(\n url.fileURLToPath(pluginScannedPackage.location),\n );\n const providedResolver = resolverProvider?.for(\n plugin.name,\n pluginScannedPackagePath,\n );\n\n const assetsPath = path.resolve(\n pluginScannedPackagePath,\n providedResolver?.assetsPathFromPackage ??\n defaultResolver.assetsPathFromPackage,\n );\n\n const manifestFileName =\n providedResolver?.manifestFileName ?? defaultResolver.manifestFileName;\n const manifestLocation = path.resolve(assetsPath, manifestFileName);\n if (!fs.existsSync(manifestLocation)) {\n logger.error(\n `Could not find manifest '${manifestLocation}' for frontend plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n let manifest: JsonObject;\n try {\n manifest = JSON.parse(fs.readFileSync(manifestLocation).toString());\n } catch (error) {\n logger.error(\n `Dynamic frontend plugin manifest '${manifestLocation}' could not be parsed for plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n if (!manifest.name || typeof manifest.name !== 'string') {\n logger.error(\n `Error in manifest '${manifestLocation}' for plugin ${plugin.name}@${plugin.version}: module name not found`,\n );\n continue;\n }\n if (\n !manifest.metaData ||\n typeof manifest.metaData !== 'object' ||\n !('remoteEntry' in manifest.metaData) ||\n !manifest.metaData.remoteEntry ||\n typeof manifest.metaData.remoteEntry !== 'object' ||\n !('name' in manifest.metaData.remoteEntry) ||\n typeof manifest.metaData.remoteEntry.name !== 'string'\n ) {\n logger.error(\n `Could not find remote entry asset in the manifest '${manifestLocation}' for plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n if (\n !manifest.exposes ||\n !Array.isArray(manifest.exposes) ||\n !manifest.exposes.every<{ name: string }>(\n (i): i is { name: string } =>\n i !== null && typeof i === 'object' && 'name' in i,\n )\n ) {\n logger.error(\n `Could not find the exposes field in the manifest '${manifestLocation}' for plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n const getAdditionalRemoteInfo =\n providedResolver?.getAdditionaRemoteInfo ??\n defaultResolver.getAdditionaRemoteInfo;\n const getRemoteEntryType =\n providedResolver?.getRemoteEntryType ??\n defaultResolver.getRemoteEntryType;\n const remoteEntryType = getRemoteEntryType(manifest);\n\n let remoteEntryAsset = manifestFileName;\n if (remoteEntryType === 'javascript') {\n remoteEntryAsset = manifest.metaData.remoteEntry.name;\n }\n\n const remoteEntryAssetLocation = path.resolve(\n assetsPath,\n remoteEntryAsset,\n );\n if (!fs.existsSync(remoteEntryAssetLocation)) {\n logger.error(\n `Could not find remote entry asset '${remoteEntryAssetLocation}' for frontend plugin ${plugin.name}@${plugin.version}`,\n );\n continue;\n }\n\n const remoteAssetsPrefix = `/remotes/${plugin.name}`;\n const remoteEntryPath = `${remoteAssetsPrefix}/${remoteEntryAsset}`;\n\n const overrideExposedModules =\n providedResolver?.overrideExposedModules ??\n defaultResolver.overrideExposedModules;\n\n const exposedModules = manifest.exposes.map(e => e.name);\n\n frontendPluginRemotes.push({\n packageName: plugin.name,\n remoteInfo: {\n name: manifest.name,\n entry: `${externalBaseUrl}${remoteEntryPath}`,\n ...getAdditionalRemoteInfo?.(manifest),\n },\n exposedModules:\n overrideExposedModules?.(exposedModules, manifest) ?? exposedModules,\n });\n\n const customizeManifest =\n providedResolver?.customizeManifest ??\n defaultResolver.customizeManifest;\n if (remoteEntryType === 'manifest' && customizeManifest) {\n const customizedContent = customizeManifest(manifest);\n typedRouter.use(`${remoteEntryPath}`, (_, res) => {\n res.json(customizedContent);\n });\n }\n typedRouter.use(remoteAssetsPrefix, express.static(assetsPath));\n logger.info(\n `Exposed dynamic frontend plugin '${plugin.name}' from '${assetsPath}' `,\n );\n } catch (error) {\n logger.error(\n `Unexpected error when exposing dynamic frontend plugin '${plugin.name}@${plugin.version}'`,\n error,\n );\n continue;\n }\n }\n\n logger.info(`/remotes => ${JSON.stringify(frontendPluginRemotes)}`);\n typedRouter.get('/remotes', (_, res) => {\n res.status(200).json(frontendPluginRemotes);\n });\n\n return typedRouter;\n}\n"],"names":["spec","createOpenApiRouter","path","url","fs","express"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/backend-dynamic-feature-service",
|
|
3
|
-
"version": "0.6.2
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Backstage dynamic feature service",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "node-library"
|
|
@@ -42,6 +42,9 @@
|
|
|
42
42
|
"scripts": {
|
|
43
43
|
"build": "backstage-cli package build",
|
|
44
44
|
"clean": "backstage-cli package clean",
|
|
45
|
+
"diff": "backstage-repo-tools package schema openapi diff",
|
|
46
|
+
"fuzz": "backstage-repo-tools package schema openapi fuzz --exclude-checks response_schema_conformance",
|
|
47
|
+
"generate": "backstage-repo-tools package schema openapi generate --server --client-package packages/frontend-dynamic-feature-loader",
|
|
45
48
|
"lint": "backstage-cli package lint",
|
|
46
49
|
"prepack": "backstage-cli package prepack",
|
|
47
50
|
"postpack": "backstage-cli package postpack",
|
|
@@ -49,38 +52,43 @@
|
|
|
49
52
|
"test": "backstage-cli package test"
|
|
50
53
|
},
|
|
51
54
|
"dependencies": {
|
|
52
|
-
"@backstage/backend-defaults": "0.9.0
|
|
53
|
-
"@backstage/backend-
|
|
54
|
-
"@backstage/
|
|
55
|
-
"@backstage/cli-
|
|
56
|
-
"@backstage/
|
|
57
|
-
"@backstage/config
|
|
58
|
-
"@backstage/
|
|
59
|
-
"@backstage/
|
|
60
|
-
"@backstage/plugin-
|
|
61
|
-
"@backstage/plugin-
|
|
62
|
-
"@backstage/plugin-
|
|
63
|
-
"@backstage/plugin-events-
|
|
64
|
-
"@backstage/plugin-
|
|
65
|
-
"@backstage/plugin-permission-
|
|
66
|
-
"@backstage/plugin-
|
|
67
|
-
"@backstage/plugin-
|
|
68
|
-
"@backstage/plugin-search-
|
|
69
|
-
"@backstage/
|
|
55
|
+
"@backstage/backend-defaults": "^0.9.0",
|
|
56
|
+
"@backstage/backend-openapi-utils": "^0.5.2",
|
|
57
|
+
"@backstage/backend-plugin-api": "^1.3.0",
|
|
58
|
+
"@backstage/cli-common": "^0.1.15",
|
|
59
|
+
"@backstage/cli-node": "^0.2.13",
|
|
60
|
+
"@backstage/config": "^1.3.2",
|
|
61
|
+
"@backstage/config-loader": "^1.10.0",
|
|
62
|
+
"@backstage/errors": "^1.2.7",
|
|
63
|
+
"@backstage/plugin-app-node": "^0.1.32",
|
|
64
|
+
"@backstage/plugin-auth-node": "^0.6.2",
|
|
65
|
+
"@backstage/plugin-catalog-backend": "^1.32.1",
|
|
66
|
+
"@backstage/plugin-events-backend": "^0.5.1",
|
|
67
|
+
"@backstage/plugin-events-node": "^0.4.10",
|
|
68
|
+
"@backstage/plugin-permission-common": "^0.8.4",
|
|
69
|
+
"@backstage/plugin-permission-node": "^0.9.1",
|
|
70
|
+
"@backstage/plugin-scaffolder-node": "^0.8.1",
|
|
71
|
+
"@backstage/plugin-search-backend-node": "^1.3.10",
|
|
72
|
+
"@backstage/plugin-search-common": "^1.2.17",
|
|
73
|
+
"@backstage/types": "^1.2.1",
|
|
70
74
|
"@manypkg/get-packages": "^1.1.3",
|
|
75
|
+
"@module-federation/sdk": "^0.9.0",
|
|
71
76
|
"@types/express": "^4.17.6",
|
|
72
77
|
"chokidar": "^3.5.3",
|
|
73
78
|
"express": "^4.17.1",
|
|
79
|
+
"express-promise-router": "^4.1.0",
|
|
74
80
|
"fs-extra": "^11.2.0",
|
|
75
81
|
"lodash": "^4.17.21",
|
|
76
82
|
"winston": "^3.2.1"
|
|
77
83
|
},
|
|
78
84
|
"devDependencies": {
|
|
79
|
-
"@backstage/backend-app-api": "1.2.
|
|
80
|
-
"@backstage/backend-test-utils": "1.
|
|
81
|
-
"@backstage/cli": "0.32.0
|
|
82
|
-
"@backstage/plugin-app-backend": "0.5.
|
|
85
|
+
"@backstage/backend-app-api": "^1.2.2",
|
|
86
|
+
"@backstage/backend-test-utils": "^1.4.0",
|
|
87
|
+
"@backstage/cli": "^0.32.0",
|
|
88
|
+
"@backstage/plugin-app-backend": "^0.5.1",
|
|
89
|
+
"@backstage/repo-tools": "^0.13.2",
|
|
83
90
|
"triple-beam": "^1.4.1",
|
|
84
91
|
"wait-for-expect": "^3.0.2"
|
|
85
|
-
}
|
|
92
|
+
},
|
|
93
|
+
"configSchema": "config.d.ts"
|
|
86
94
|
}
|