@backstage/frontend-dynamic-feature-loader 0.1.3 → 0.1.4

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # @backstage/frontend-dynamic-feature-loader
2
2
 
3
+ ## 0.1.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/frontend-plugin-api@0.11.0
9
+
10
+ ## 0.1.4-next.0
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies
15
+ - @backstage/frontend-plugin-api@0.11.0-next.0
16
+ - @backstage/config@1.3.3
17
+
3
18
  ## 0.1.3
4
19
 
5
20
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"loader.esm.js","sources":["../src/loader.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 FederationRuntimePlugin,\n init,\n loadRemote,\n} from '@module-federation/enhanced/runtime';\nimport { Module } from '@module-federation/sdk';\nimport { DefaultApiClient, Remote } from './schema/openapi';\nimport {\n FrontendFeature,\n FrontendFeatureLoader,\n createFrontendFeatureLoader,\n} from '@backstage/frontend-plugin-api';\nimport { ShareStrategy, UserOptions } from '@module-federation/runtime/types';\n\n/**\n *\n * @public\n */\nexport type DynamicFrontendFeaturesLoaderOptions = {\n /**\n * Additional module federation arguments for the Module Federation runtime initialization.\n */\n moduleFederation: {\n shared?: UserOptions['shared'];\n shareStrategy?: ShareStrategy;\n plugins?: Array<FederationRuntimePlugin>;\n };\n};\n\n/**\n * A function providing a loader of frontend features exposed as module federation remotes\n * from the backend dynamic features service.\n *\n * @public\n */\nexport function dynamicFrontendFeaturesLoader(\n options?: DynamicFrontendFeaturesLoaderOptions,\n): FrontendFeatureLoader {\n return createFrontendFeatureLoader({\n async loader({ config }) {\n const dynamicPLuginsConfig = config.getOptionalConfig('dynamicPlugins');\n if (!dynamicPLuginsConfig) {\n return [];\n }\n\n function error(message: string, err: unknown) {\n // eslint-disable-next-line no-console\n console.error(\n `${message}: ${\n err instanceof Error ? err.toString() : JSON.stringify(err)\n }`,\n );\n }\n\n const backendBaseUrl = config.getString('backend.baseUrl');\n\n const appPackageName =\n config.getOptionalString('app.packageName') ?? 'app';\n let frontendPluginRemotes: Array<Remote>;\n try {\n const apiClient = new DefaultApiClient({\n discoveryApi: {\n getBaseUrl: async rootPath => `${backendBaseUrl}/${rootPath}`,\n },\n fetchApi: {\n fetch(input) {\n return global.fetch(input);\n },\n },\n });\n\n const response = await apiClient.getRemotes({});\n if (!response.ok) {\n throw new Error(`${response.status} - ${response.statusText}`);\n }\n frontendPluginRemotes = await response.json();\n } catch (err) {\n error(\n `Failed fetching module federation configuration of dynamic frontend plugins`,\n err,\n );\n return [];\n }\n\n try {\n init({\n ...options?.moduleFederation,\n name: appPackageName\n .replaceAll('@', '')\n .replaceAll('/', '__')\n .replaceAll('-', '_'),\n remotes: frontendPluginRemotes.map(remote => ({\n alias: remote.packageName,\n ...remote.remoteInfo,\n })),\n });\n } catch (err) {\n error(`Failed initializing module federation`, err);\n return [];\n }\n\n const features = (\n await Promise.all(\n frontendPluginRemotes.map(async remote => {\n // eslint-disable-next-line no-console\n console.debug(\n `Loading dynamic plugin '${remote.packageName}' from '${remote.remoteInfo.entry}'`,\n );\n\n const moduleFeatures = await Promise.all(\n remote.exposedModules.map(async exposedModuleName => {\n const remoteModuleName =\n exposedModuleName === '.'\n ? remote.remoteInfo.name\n : `${remote.remoteInfo.name}/${exposedModuleName}`;\n let module: Module;\n try {\n module = await loadRemote<Module>(remoteModuleName);\n } catch (err) {\n error(\n `Failed loading remote module '${remoteModuleName}' of dynamic plugin '${remote.packageName}'`,\n err,\n );\n return undefined;\n }\n if (!module) {\n // eslint-disable-next-line no-console\n console.warn(\n `Skipping empty dynamic plugin remote module '${remoteModuleName}'.`,\n );\n return undefined;\n }\n // eslint-disable-next-line no-console\n console.info(\n `Remote module '${remoteModuleName}' of dynamic plugin '${remote.packageName}' loaded from ${remote.remoteInfo.entry}`,\n );\n const defaultEntry = module.default;\n if (!isLoadable(defaultEntry)) {\n // eslint-disable-next-line no-console\n console.debug(\n `Skipping dynamic plugin remote module '${remote}' since it doesn't export a new 'FrontendFeature' as default export.`,\n );\n return undefined;\n }\n return defaultEntry;\n }),\n );\n return moduleFeatures;\n }),\n )\n )\n .flat()\n .filter((feature): feature is FrontendFeature => feature !== undefined);\n\n return [...features];\n },\n });\n}\n\nfunction isLoadable(obj: unknown): obj is FrontendFeature {\n if (obj !== null && typeof obj === 'object' && '$$type' in obj) {\n return (\n obj.$$type === '@backstage/FrontendPlugin' ||\n obj.$$type === '@backstage/FrontendModule'\n );\n }\n return false;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.esm.js","sources":["../src/loader.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 FederationRuntimePlugin,\n init,\n loadRemote,\n} from '@module-federation/enhanced/runtime';\nimport { Module } from '@module-federation/sdk';\nimport { DefaultApiClient, Remote } from './schema/openapi';\nimport {\n FrontendFeature,\n FrontendFeatureLoader,\n createFrontendFeatureLoader,\n} from '@backstage/frontend-plugin-api';\nimport { ShareStrategy, UserOptions } from '@module-federation/runtime/types';\n\n/**\n *\n * @public\n */\nexport type DynamicFrontendFeaturesLoaderOptions = {\n /**\n * Additional module federation arguments for the Module Federation runtime initialization.\n */\n moduleFederation: {\n shared?: UserOptions['shared'];\n shareStrategy?: ShareStrategy;\n plugins?: Array<FederationRuntimePlugin>;\n };\n};\n\n/**\n * A function providing a loader of frontend features exposed as module federation remotes\n * from the backend dynamic features service.\n *\n * @public\n */\nexport function dynamicFrontendFeaturesLoader(\n options?: DynamicFrontendFeaturesLoaderOptions,\n): FrontendFeatureLoader {\n return createFrontendFeatureLoader({\n async loader({ config }) {\n const dynamicPLuginsConfig = config.getOptionalConfig('dynamicPlugins');\n if (!dynamicPLuginsConfig) {\n return [];\n }\n\n function error(message: string, err: unknown) {\n // eslint-disable-next-line no-console\n console.error(\n `${message}: ${\n err instanceof Error ? err.toString() : JSON.stringify(err)\n }`,\n );\n }\n\n const backendBaseUrl = config.getString('backend.baseUrl');\n\n const appPackageName =\n config.getOptionalString('app.packageName') ?? 'app';\n let frontendPluginRemotes: Array<Remote>;\n try {\n const apiClient = new DefaultApiClient({\n discoveryApi: {\n getBaseUrl: async rootPath => `${backendBaseUrl}/${rootPath}`,\n },\n fetchApi: {\n fetch(input) {\n return global.fetch(input);\n },\n },\n });\n\n const response = await apiClient.getRemotes({});\n if (!response.ok) {\n throw new Error(`${response.status} - ${response.statusText}`);\n }\n frontendPluginRemotes = await response.json();\n } catch (err) {\n error(\n `Failed fetching module federation configuration of dynamic frontend plugins`,\n err,\n );\n return [];\n }\n\n try {\n init({\n ...options?.moduleFederation,\n name: appPackageName\n .replaceAll('@', '')\n .replaceAll('/', '__')\n .replaceAll('-', '_'),\n remotes: frontendPluginRemotes.map(remote => ({\n alias: remote.packageName,\n ...remote.remoteInfo,\n })),\n });\n } catch (err) {\n error(`Failed initializing module federation`, err);\n return [];\n }\n\n const features = (\n await Promise.all(\n frontendPluginRemotes.map(async remote => {\n // eslint-disable-next-line no-console\n console.debug(\n `Loading dynamic plugin '${remote.packageName}' from '${remote.remoteInfo.entry}'`,\n );\n\n const moduleFeatures = await Promise.all(\n remote.exposedModules.map(async exposedModuleName => {\n const remoteModuleName =\n exposedModuleName === '.'\n ? remote.remoteInfo.name\n : `${remote.remoteInfo.name}/${exposedModuleName}`;\n let module: Module;\n try {\n module = await loadRemote<Module>(remoteModuleName);\n } catch (err) {\n error(\n `Failed loading remote module '${remoteModuleName}' of dynamic plugin '${remote.packageName}'`,\n err,\n );\n return undefined;\n }\n if (!module) {\n // eslint-disable-next-line no-console\n console.warn(\n `Skipping empty dynamic plugin remote module '${remoteModuleName}'.`,\n );\n return undefined;\n }\n // eslint-disable-next-line no-console\n console.info(\n `Remote module '${remoteModuleName}' of dynamic plugin '${remote.packageName}' loaded from ${remote.remoteInfo.entry}`,\n );\n const defaultEntry = module.default;\n if (!isLoadable(defaultEntry)) {\n // eslint-disable-next-line no-console\n console.debug(\n `Skipping dynamic plugin remote module '${remote}' since it doesn't export a new 'FrontendFeature' as default export.`,\n );\n return undefined;\n }\n return defaultEntry;\n }),\n );\n return moduleFeatures;\n }),\n )\n )\n .flat()\n .filter((feature): feature is FrontendFeature => feature !== undefined);\n\n return [...features];\n },\n });\n}\n\nfunction isLoadable(obj: unknown): obj is FrontendFeature {\n if (obj !== null && typeof obj === 'object' && '$$type' in obj) {\n return (\n obj.$$type === '@backstage/FrontendPlugin' ||\n obj.$$type === '@backstage/FrontendModule'\n );\n }\n return false;\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Api.client.esm.js","sources":["../../../../../src/schema/openapi/generated/apis/Api.client.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 { DiscoveryApi } from '../types/discovery';\nimport { FetchApi } from '../types/fetch';\nimport crossFetch from 'cross-fetch';\nimport { pluginId } from '../pluginId';\nimport * as parser from 'uri-template';\nimport { Remote } from '../models/Remote.model';\n\n/**\n * Wraps the Response type to convey a type on the json call.\n *\n * @public\n */\nexport type TypedResponse<T> = Omit<Response, 'json'> & {\n json: () => Promise<T>;\n};\n\n/**\n * Options you can pass into a request for additional information.\n *\n * @public\n */\nexport interface RequestOptions {\n token?: string;\n}\n/**\n * @public\n */\nexport type GetRemotes = {};\n\n/**\n * @public\n */\nexport class DefaultApiClient {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi?: { fetch: typeof fetch };\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi || { fetch: crossFetch };\n }\n\n /**\n * Get the Module Federation remote definitions.\n */\n public async getRemotes(\n // @ts-ignore\n request: GetRemotes,\n options?: RequestOptions,\n ): Promise<TypedResponse<Array<Remote>>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/remotes`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n}\n"],"names":[],"mappings":";;;;AAmDO,MAAM,gBAAiB,CAAA;AAAA,EACX,YAAA;AAAA,EACA,QAAA;AAAA,EAEjB,YAAY,OAGT,EAAA;AACD,IAAA,IAAA,CAAK,eAAe,OAAQ,CAAA,YAAA;AAC5B,IAAA,IAAA,CAAK,QAAW,GAAA,OAAA,CAAQ,QAAY,IAAA,EAAE,OAAO,UAAW,EAAA;AAAA;AAC1D;AAAA;AAAA;AAAA,EAKA,MAAa,UAEX,CAAA,OAAA,EACA,OACuC,EAAA;AACvC,IAAA,MAAM,OAAU,GAAA,MAAM,IAAK,CAAA,YAAA,CAAa,WAAW,QAAQ,CAAA;AAE3D,IAAA,MAAM,WAAc,GAAA,CAAA,QAAA,CAAA;AAEpB,IAAA,MAAM,MAAM,MAAO,CAAA,KAAA,CAAM,WAAW,CAAE,CAAA,MAAA,CAAO,EAAE,CAAA;AAE/C,IAAO,OAAA,MAAM,KAAK,QAAS,CAAA,KAAA,CAAM,GAAG,OAAO,CAAA,EAAG,GAAG,CAAI,CAAA,EAAA;AAAA,MACnD,OAAS,EAAA;AAAA,QACP,cAAgB,EAAA,kBAAA;AAAA,QAChB,GAAI,SAAS,KAAS,IAAA,EAAE,eAAe,CAAU,OAAA,EAAA,OAAA,EAAS,KAAK,CAAG,CAAA;AAAA,OACpE;AAAA,MACA,MAAQ,EAAA;AAAA,KACT,CAAA;AAAA;AAEL;;;;"}
1
+ {"version":3,"file":"Api.client.esm.js","sources":["../../../../../src/schema/openapi/generated/apis/Api.client.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 { DiscoveryApi } from '../types/discovery';\nimport { FetchApi } from '../types/fetch';\nimport crossFetch from 'cross-fetch';\nimport { pluginId } from '../pluginId';\nimport * as parser from 'uri-template';\nimport { Remote } from '../models/Remote.model';\n\n/**\n * Wraps the Response type to convey a type on the json call.\n *\n * @public\n */\nexport type TypedResponse<T> = Omit<Response, 'json'> & {\n json: () => Promise<T>;\n};\n\n/**\n * Options you can pass into a request for additional information.\n *\n * @public\n */\nexport interface RequestOptions {\n token?: string;\n}\n/**\n * @public\n */\nexport type GetRemotes = {};\n\n/**\n * @public\n */\nexport class DefaultApiClient {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi?: { fetch: typeof fetch };\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi || { fetch: crossFetch };\n }\n\n /**\n * Get the Module Federation remote definitions.\n */\n public async getRemotes(\n // @ts-ignore\n request: GetRemotes,\n options?: RequestOptions,\n ): Promise<TypedResponse<Array<Remote>>> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n\n const uriTemplate = `/remotes`;\n\n const uri = parser.parse(uriTemplate).expand({});\n\n return await this.fetchApi.fetch(`${baseUrl}${uri}`, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'GET',\n });\n }\n}\n"],"names":[],"mappings":";;;;AAmDO,MAAM,gBAAA,CAAiB;AAAA,EACX,YAAA;AAAA,EACA,QAAA;AAAA,EAEjB,YAAY,OAAA,EAGT;AACD,IAAA,IAAA,CAAK,eAAe,OAAA,CAAQ,YAAA;AAC5B,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA,CAAQ,QAAA,IAAY,EAAE,OAAO,UAAA,EAAW;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,UAAA,CAEX,OAAA,EACA,OAAA,EACuC;AACvC,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,YAAA,CAAa,WAAW,QAAQ,CAAA;AAE3D,IAAA,MAAM,WAAA,GAAc,CAAA,QAAA,CAAA;AAEpB,IAAA,MAAM,MAAM,MAAA,CAAO,KAAA,CAAM,WAAW,CAAA,CAAE,MAAA,CAAO,EAAE,CAAA;AAE/C,IAAA,OAAO,MAAM,KAAK,QAAA,CAAS,KAAA,CAAM,GAAG,OAAO,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI;AAAA,MACnD,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,GAAI,SAAS,KAAA,IAAS,EAAE,eAAe,CAAA,OAAA,EAAU,OAAA,EAAS,KAAK,CAAA,CAAA;AAAG,OACpE;AAAA,MACA,MAAA,EAAQ;AAAA,KACT,CAAA;AAAA,EACH;AACF;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"pluginId.esm.js","sources":["../../../../src/schema/openapi/generated/pluginId.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\nexport const pluginId = '.backstage/dynamic-features';\n"],"names":[],"mappings":"AAgBO,MAAM,QAAW,GAAA;;;;"}
1
+ {"version":3,"file":"pluginId.esm.js","sources":["../../../../src/schema/openapi/generated/pluginId.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\nexport const pluginId = '.backstage/dynamic-features';\n"],"names":[],"mappings":"AAgBO,MAAM,QAAA,GAAW;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/frontend-dynamic-feature-loader",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "backstage": {
5
5
  "role": "web-library"
6
6
  },
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@backstage/config": "^1.3.3",
36
- "@backstage/frontend-plugin-api": "^0.10.4",
36
+ "@backstage/frontend-plugin-api": "^0.11.0",
37
37
  "@module-federation/enhanced": "^0.9.0",
38
38
  "@module-federation/runtime": "^0.9.0",
39
39
  "@module-federation/sdk": "^0.9.0",
@@ -41,8 +41,8 @@
41
41
  "uri-template": "^2.0.0"
42
42
  },
43
43
  "devDependencies": {
44
- "@backstage/cli": "^0.33.1",
45
- "@backstage/test-utils": "^1.7.10",
44
+ "@backstage/cli": "^0.34.0",
45
+ "@backstage/test-utils": "^1.7.11",
46
46
  "@testing-library/jest-dom": "^6.0.0",
47
47
  "@testing-library/react": "^16.0.0",
48
48
  "@types/react": "^18.0.0",