@iobroker/json-config 9.0.4 → 9.0.6

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/README.md CHANGED
@@ -1822,7 +1822,7 @@ The schema is used here: https://github.com/SchemaStore/schemastore/blob/6da29cd
1822
1822
  ### **WORK IN PROGRESS**
1823
1823
  -->
1824
1824
  ## Changelog
1825
- ### 9.0.4 (2026-07-26)
1825
+ ### 9.0.6 (2026-07-26)
1826
1826
  - (@GermanBluefox) Breaking: React 19 + MUI 9 + TS 6
1827
1827
  - (@GermanBluefox) Added loading of the new custom components
1828
1828
 
@@ -1,29 +1,25 @@
1
1
  import React from 'react';
2
2
  import { LinearProgress } from '@mui/material';
3
3
  import { registerRemotes, loadRemote, init } from '@module-federation/runtime';
4
- import * as IconsMaterial from '@mui/icons-material';
5
- import * as AdapterReact from '@iobroker/gui-components';
6
4
  import { I18n, InfoBox } from '@iobroker/gui-components';
7
5
  import ConfigGeneric from './ConfigGeneric';
8
6
  import ConfigCustomErrorBoundary from './ConfigCustomErrorBoundary';
9
7
  import { checkGuiApiCompatibility, GUI_API_GENERATION } from './guiApiGate';
10
- import * as JsonConfig from '../';
8
+ // Only create the federation instance so that `registerRemotes`/`loadRemote` below have one.
9
+ //
10
+ // Do NOT declare shared modules here. The host already registers them from its own federation
11
+ // config, with the real version and `singleton: true`. Re-registering a subset under the pseudo
12
+ // version '*' and without `singleton` put a SECOND entry for the same package into the share scope
13
+ // (observable as `['*', '10.0.3']` for '@iobroker/gui-components'), which let a custom component
14
+ // resolve to its own bundled fallback copy instead of the host's module. For `I18n` - whose
15
+ // dictionary lives in static class fields - that meant `ConfigCustom` filled one instance while the
16
+ // component read from another, so custom components rendered raw keys like `custom_easy_Instance`.
17
+ //
18
+ // That the host's registration is the operative one is evident from `react`, `react-dom` and
19
+ // `@mui/material`: they were never registered here and resolve correctly.
11
20
  init({
12
21
  name: 'iobroker_admin',
13
- shared: {
14
- '@iobroker/gui-components': {
15
- lib: () => AdapterReact,
16
- version: '*',
17
- },
18
- '@mui/icons-material': {
19
- lib: () => IconsMaterial,
20
- version: '*',
21
- },
22
- '@iobroker/json-config': {
23
- lib: () => JsonConfig,
24
- version: '*',
25
- },
26
- },
22
+ shared: {},
27
23
  remotes: [],
28
24
  });
29
25
  export default class ConfigCustom extends ConfigGeneric {
@@ -1 +1 @@
1
- {"version":3,"file":"ConfigCustom.js","sourceRoot":"src/","sources":["JsonConfigComponent/ConfigCustom.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { type JSX } from 'react';\nimport { LinearProgress } from '@mui/material';\nimport { registerRemotes, loadRemote, init } from '@module-federation/runtime';\n\nimport * as IconsMaterial from '@mui/icons-material';\n\nimport * as AdapterReact from '@iobroker/gui-components';\nimport { I18n, InfoBox } from '@iobroker/gui-components';\n\nimport ConfigGeneric, { type ConfigGenericProps, type ConfigGenericState } from './ConfigGeneric';\nimport ConfigCustomErrorBoundary from './ConfigCustomErrorBoundary';\nimport { checkGuiApiCompatibility, GUI_API_GENERATION, type GuiApiVerdict } from './guiApiGate';\nimport * as JsonConfig from '../';\nimport type { ConfigItemCustom } from '../types';\n\ninterface ConfigCustomProps extends ConfigGenericProps {\n schema: ConfigItemCustom;\n}\n\ninterface ConfigCustomState extends ConfigGenericState {\n Component: React.FC<ConfigGenericProps> | null;\n error: string;\n /** Set when the component was refused by the GUI API gate, so it was never loaded */\n incompatible: GuiApiVerdict | null;\n}\n\ninit({\n name: 'iobroker_admin',\n shared: {\n '@iobroker/gui-components': {\n lib: () => AdapterReact,\n version: '*',\n },\n '@mui/icons-material': {\n lib: () => IconsMaterial,\n version: '*',\n },\n '@iobroker/json-config': {\n lib: () => JsonConfig,\n version: '*',\n },\n },\n remotes: [],\n});\n\nexport default class ConfigCustom extends ConfigGeneric<ConfigCustomProps, ConfigCustomState> {\n static runningLoads: Record<string, Promise<{ default: Record<string, React.FC<ConfigGenericProps>> } | null>> = {};\n\n constructor(props: ConfigCustomProps) {\n super(props);\n // schema.url - location of Widget\n // schema.name - Component name\n // schema.i18n - i18n\n\n Object.assign(this.state, {\n Component: null,\n error: '',\n incompatible: null,\n });\n }\n\n // load component dynamically\n async componentDidMount(): Promise<void> {\n if (!this.props.schema.url) {\n console.error('URL is empty. Cannot load custom component!');\n this.setState({ error: 'URL is empty. Cannot load custom component!' });\n return;\n }\n\n let url;\n if (this.props.schema.url.startsWith('http:') || this.props.schema.url.startsWith('https:')) {\n url = this.props.schema.url;\n } else if (this.props.schema.url.startsWith('./')) {\n url = `${window.location.protocol}//${window.location.host}${this.props.schema.url.replace(/^\\./, '')}`;\n } else {\n url = `${window.location.protocol}//${window.location.host}/adapter/${this.props.oContext.adapterName}/${this.props.schema.url}`;\n }\n const [uniqueName, fileToLoad, ...componentNameParts] = this.props.schema.name.split('/');\n const componentName = componentNameParts.join('/');\n if (!url) {\n console.error(\n 'Cannot find URL for custom component! Please define \"url\" as \"custom/customComponents.js\" in the schema',\n );\n return;\n }\n if (!uniqueName || !fileToLoad || !componentName) {\n console.error(\n 'Invalid format of \"name\"! Please define \"name\" as \"ConfigCustomBackItUpSet/Components/AdapterExist\" in the schema',\n );\n return;\n }\n\n // Refuse an incompatible component before it is registered: it shares this admin's React and\n // MUI singletons, so one built against another generation would break while rendering.\n const verdict = await checkGuiApiCompatibility(url, this.props.schema.guiApi);\n if (!verdict.compatible) {\n console.warn(\n `Custom component \"${this.props.schema.name}\" from \"${url}\" was not started: it targets ` +\n `GUI API generation ${verdict.declared}, but this admin provides generation ${GUI_API_GENERATION}.`,\n );\n this.setState({ incompatible: verdict });\n return;\n }\n\n let setPromise: Promise<{ default: Record<string, React.FC<ConfigGenericProps>> } | null> | undefined =\n ConfigCustom.runningLoads[`${url}!${fileToLoad}`];\n\n if (!(setPromise instanceof Promise)) {\n let i18nPromise: Promise<void> | undefined;\n if (this.props.schema.i18n === true) {\n // load i18n from files\n const pos = url.lastIndexOf('/');\n let i18nURL: string;\n if (pos !== -1) {\n i18nURL = url.substring(0, pos);\n } else {\n i18nURL = url;\n }\n const lang = I18n.getLanguage();\n const file = `${i18nURL}/i18n/${lang}.json`;\n\n i18nPromise = fetch(file)\n .then(data => data.json())\n .then(json => I18n.extendTranslations(json, lang))\n .catch(error => {\n if (lang !== 'en') {\n // try to load English\n fetch(`${i18nURL}/i18n/en.json`)\n .then(data => data.json())\n .then(json => I18n.extendTranslations(json, lang))\n .catch(err => console.log(`Cannot load i18n \"${file}\": ${err}`));\n return;\n }\n console.log(`Cannot load i18n \"${file}\": ${error}`);\n });\n } else if (this.props.schema.i18n && typeof this.props.schema.i18n === 'object') {\n try {\n I18n.extendTranslations(this.props.schema.i18n);\n } catch (error) {\n console.error(`Cannot import i18n: ${error}`);\n }\n }\n try {\n console.log(url, uniqueName, fileToLoad, componentName);\n\n registerRemotes(\n [\n {\n name: uniqueName,\n entry: url,\n // Components of the current GUI API generation are always built as ES\n // modules, so the former `bundlerType` schema attribute is obsolete.\n type: 'module',\n },\n ],\n // force: true // may be needed to side-load remotes after the fact.\n );\n setPromise = loadRemote(`${uniqueName}/${fileToLoad}`);\n if (i18nPromise instanceof Promise) {\n setPromise = Promise.all([setPromise, i18nPromise]).then(result => result[0]);\n }\n // remember promise\n ConfigCustom.runningLoads[`${url}!${fileToLoad}`] = setPromise;\n } catch (error) {\n console.error(error);\n this.setState({ error: `Cannot import from ${this.props.schema.url}: ${error}` });\n }\n }\n try {\n const component: Record<string, React.FC<ConfigGenericProps>> | undefined = (await setPromise)?.default;\n\n if (!component?.[componentName]) {\n const keys = Object.keys(component || {});\n console.error('URL is empty. Cannot load custom component!');\n this.setState({\n error: `Component ${this.props.schema.name} not found in ${this.props.schema.url}. Found: ${keys.join(', ')}`,\n });\n } else {\n this.setState({ Component: component[componentName] });\n }\n } catch (error) {\n console.error(error);\n this.setState({ error: `Cannot import from ${this.props.schema.url}: ${error}` });\n }\n }\n\n /** Explain why a component was not started, and what the user can do about it */\n renderIncompatible(verdict: GuiApiVerdict): JSX.Element {\n return (\n <InfoBox\n type=\"warning\"\n iconPosition=\"top\"\n >\n <div>\n <div style={{ fontWeight: 'bold' }}>\n {I18n.t('jc_Custom component \"%s\" was not started', this.props.schema.name)}\n </div>\n <div>\n {verdict.tooNew\n ? I18n.t(\n 'jc_It requires GUI API generation %s, but this admin provides generation %s. Please update the admin.',\n verdict.declared,\n GUI_API_GENERATION,\n )\n : I18n.t(\n 'jc_It was built for GUI API generation %s, but this admin provides generation %s. Please update the adapter.',\n verdict.declared,\n GUI_API_GENERATION,\n )}\n </div>\n </div>\n </InfoBox>\n );\n }\n\n render(): JSX.Element {\n const CustomComponent: React.FC<ConfigGenericProps> | null = this.state.Component;\n const schema = this.props.schema || ({} as ConfigItemCustom);\n\n const item = CustomComponent ? (\n // The custom component is third-party code, so a render error must not take down the\n // whole configuration page with it.\n <ConfigCustomErrorBoundary\n name={schema.name}\n url={schema.url}\n >\n <CustomComponent\n {...this.props}\n // @ts-expect-error BF (2024-12-18) Remove after the 7.4 will be mainstream. All following lines\n socket={this.props.oContext.socket}\n theme={this.props.oContext.theme}\n themeType={this.props.oContext.themeType}\n instance={this.props.oContext.instance}\n adapterName={this.props.oContext.adapterName}\n systemConfig={this.props.oContext.systemConfig}\n forceUpdate={this.props.oContext.forceUpdate}\n />\n </ConfigCustomErrorBoundary>\n ) : this.state.incompatible ? (\n this.renderIncompatible(this.state.incompatible)\n ) : this.state.error ? (\n <div>{this.state.error}</div>\n ) : (\n <LinearProgress />\n );\n\n if (schema.newLine) {\n return (\n <>\n <div style={{ flexBasis: '100%', height: 0 }} />\n {item}\n </>\n );\n }\n\n return item;\n }\n}\n"]}
1
+ {"version":3,"file":"ConfigCustom.js","sourceRoot":"src/","sources":["JsonConfigComponent/ConfigCustom.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { type JSX } from 'react';\nimport { LinearProgress } from '@mui/material';\nimport { registerRemotes, loadRemote, init } from '@module-federation/runtime';\n\nimport { I18n, InfoBox } from '@iobroker/gui-components';\n\nimport ConfigGeneric, { type ConfigGenericProps, type ConfigGenericState } from './ConfigGeneric';\nimport ConfigCustomErrorBoundary from './ConfigCustomErrorBoundary';\nimport { checkGuiApiCompatibility, GUI_API_GENERATION, type GuiApiVerdict } from './guiApiGate';\nimport type { ConfigItemCustom } from '../types';\n\ninterface ConfigCustomProps extends ConfigGenericProps {\n schema: ConfigItemCustom;\n}\n\ninterface ConfigCustomState extends ConfigGenericState {\n Component: React.FC<ConfigGenericProps> | null;\n error: string;\n /** Set when the component was refused by the GUI API gate, so it was never loaded */\n incompatible: GuiApiVerdict | null;\n}\n\n// Only create the federation instance so that `registerRemotes`/`loadRemote` below have one.\n//\n// Do NOT declare shared modules here. The host already registers them from its own federation\n// config, with the real version and `singleton: true`. Re-registering a subset under the pseudo\n// version '*' and without `singleton` put a SECOND entry for the same package into the share scope\n// (observable as `['*', '10.0.3']` for '@iobroker/gui-components'), which let a custom component\n// resolve to its own bundled fallback copy instead of the host's module. For `I18n` - whose\n// dictionary lives in static class fields - that meant `ConfigCustom` filled one instance while the\n// component read from another, so custom components rendered raw keys like `custom_easy_Instance`.\n//\n// That the host's registration is the operative one is evident from `react`, `react-dom` and\n// `@mui/material`: they were never registered here and resolve correctly.\ninit({\n name: 'iobroker_admin',\n shared: {},\n remotes: [],\n});\n\nexport default class ConfigCustom extends ConfigGeneric<ConfigCustomProps, ConfigCustomState> {\n static runningLoads: Record<string, Promise<{ default: Record<string, React.FC<ConfigGenericProps>> } | null>> = {};\n\n constructor(props: ConfigCustomProps) {\n super(props);\n // schema.url - location of Widget\n // schema.name - Component name\n // schema.i18n - i18n\n\n Object.assign(this.state, {\n Component: null,\n error: '',\n incompatible: null,\n });\n }\n\n // load component dynamically\n async componentDidMount(): Promise<void> {\n if (!this.props.schema.url) {\n console.error('URL is empty. Cannot load custom component!');\n this.setState({ error: 'URL is empty. Cannot load custom component!' });\n return;\n }\n\n let url;\n if (this.props.schema.url.startsWith('http:') || this.props.schema.url.startsWith('https:')) {\n url = this.props.schema.url;\n } else if (this.props.schema.url.startsWith('./')) {\n url = `${window.location.protocol}//${window.location.host}${this.props.schema.url.replace(/^\\./, '')}`;\n } else {\n url = `${window.location.protocol}//${window.location.host}/adapter/${this.props.oContext.adapterName}/${this.props.schema.url}`;\n }\n const [uniqueName, fileToLoad, ...componentNameParts] = this.props.schema.name.split('/');\n const componentName = componentNameParts.join('/');\n if (!url) {\n console.error(\n 'Cannot find URL for custom component! Please define \"url\" as \"custom/customComponents.js\" in the schema',\n );\n return;\n }\n if (!uniqueName || !fileToLoad || !componentName) {\n console.error(\n 'Invalid format of \"name\"! Please define \"name\" as \"ConfigCustomBackItUpSet/Components/AdapterExist\" in the schema',\n );\n return;\n }\n\n // Refuse an incompatible component before it is registered: it shares this admin's React and\n // MUI singletons, so one built against another generation would break while rendering.\n const verdict = await checkGuiApiCompatibility(url, this.props.schema.guiApi);\n if (!verdict.compatible) {\n console.warn(\n `Custom component \"${this.props.schema.name}\" from \"${url}\" was not started: it targets ` +\n `GUI API generation ${verdict.declared}, but this admin provides generation ${GUI_API_GENERATION}.`,\n );\n this.setState({ incompatible: verdict });\n return;\n }\n\n let setPromise: Promise<{ default: Record<string, React.FC<ConfigGenericProps>> } | null> | undefined =\n ConfigCustom.runningLoads[`${url}!${fileToLoad}`];\n\n if (!(setPromise instanceof Promise)) {\n let i18nPromise: Promise<void> | undefined;\n if (this.props.schema.i18n === true) {\n // load i18n from files\n const pos = url.lastIndexOf('/');\n let i18nURL: string;\n if (pos !== -1) {\n i18nURL = url.substring(0, pos);\n } else {\n i18nURL = url;\n }\n const lang = I18n.getLanguage();\n const file = `${i18nURL}/i18n/${lang}.json`;\n\n i18nPromise = fetch(file)\n .then(data => data.json())\n .then(json => I18n.extendTranslations(json, lang))\n .catch(error => {\n if (lang !== 'en') {\n // try to load English\n fetch(`${i18nURL}/i18n/en.json`)\n .then(data => data.json())\n .then(json => I18n.extendTranslations(json, lang))\n .catch(err => console.log(`Cannot load i18n \"${file}\": ${err}`));\n return;\n }\n console.log(`Cannot load i18n \"${file}\": ${error}`);\n });\n } else if (this.props.schema.i18n && typeof this.props.schema.i18n === 'object') {\n try {\n I18n.extendTranslations(this.props.schema.i18n);\n } catch (error) {\n console.error(`Cannot import i18n: ${error}`);\n }\n }\n try {\n console.log(url, uniqueName, fileToLoad, componentName);\n\n registerRemotes(\n [\n {\n name: uniqueName,\n entry: url,\n // Components of the current GUI API generation are always built as ES\n // modules, so the former `bundlerType` schema attribute is obsolete.\n type: 'module',\n },\n ],\n // force: true // may be needed to side-load remotes after the fact.\n );\n setPromise = loadRemote(`${uniqueName}/${fileToLoad}`);\n if (i18nPromise instanceof Promise) {\n setPromise = Promise.all([setPromise, i18nPromise]).then(result => result[0]);\n }\n // remember promise\n ConfigCustom.runningLoads[`${url}!${fileToLoad}`] = setPromise;\n } catch (error) {\n console.error(error);\n this.setState({ error: `Cannot import from ${this.props.schema.url}: ${error}` });\n }\n }\n try {\n const component: Record<string, React.FC<ConfigGenericProps>> | undefined = (await setPromise)?.default;\n\n if (!component?.[componentName]) {\n const keys = Object.keys(component || {});\n console.error('URL is empty. Cannot load custom component!');\n this.setState({\n error: `Component ${this.props.schema.name} not found in ${this.props.schema.url}. Found: ${keys.join(', ')}`,\n });\n } else {\n this.setState({ Component: component[componentName] });\n }\n } catch (error) {\n console.error(error);\n this.setState({ error: `Cannot import from ${this.props.schema.url}: ${error}` });\n }\n }\n\n /** Explain why a component was not started, and what the user can do about it */\n renderIncompatible(verdict: GuiApiVerdict): JSX.Element {\n return (\n <InfoBox\n type=\"warning\"\n iconPosition=\"top\"\n >\n <div>\n <div style={{ fontWeight: 'bold' }}>\n {I18n.t('jc_Custom component \"%s\" was not started', this.props.schema.name)}\n </div>\n <div>\n {verdict.tooNew\n ? I18n.t(\n 'jc_It requires GUI API generation %s, but this admin provides generation %s. Please update the admin.',\n verdict.declared,\n GUI_API_GENERATION,\n )\n : I18n.t(\n 'jc_It was built for GUI API generation %s, but this admin provides generation %s. Please update the adapter.',\n verdict.declared,\n GUI_API_GENERATION,\n )}\n </div>\n </div>\n </InfoBox>\n );\n }\n\n render(): JSX.Element {\n const CustomComponent: React.FC<ConfigGenericProps> | null = this.state.Component;\n const schema = this.props.schema || ({} as ConfigItemCustom);\n\n const item = CustomComponent ? (\n // The custom component is third-party code, so a render error must not take down the\n // whole configuration page with it.\n <ConfigCustomErrorBoundary\n name={schema.name}\n url={schema.url}\n >\n <CustomComponent\n {...this.props}\n // @ts-expect-error BF (2024-12-18) Remove after the 7.4 will be mainstream. All following lines\n socket={this.props.oContext.socket}\n theme={this.props.oContext.theme}\n themeType={this.props.oContext.themeType}\n instance={this.props.oContext.instance}\n adapterName={this.props.oContext.adapterName}\n systemConfig={this.props.oContext.systemConfig}\n forceUpdate={this.props.oContext.forceUpdate}\n />\n </ConfigCustomErrorBoundary>\n ) : this.state.incompatible ? (\n this.renderIncompatible(this.state.incompatible)\n ) : this.state.error ? (\n <div>{this.state.error}</div>\n ) : (\n <LinearProgress />\n );\n\n if (schema.newLine) {\n return (\n <>\n <div style={{ flexBasis: '100%', height: 0 }} />\n {item}\n </>\n );\n }\n\n return item;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@iobroker/json-config",
3
3
  "description": "This package contains the ioBroker JSON config UI components",
4
- "version": "9.0.4",
4
+ "version": "9.0.6",
5
5
  "author": {
6
6
  "name": "bluefox",
7
7
  "email": "dogafox@gmail.com"
@@ -37,7 +37,7 @@
37
37
  "dependencies": {
38
38
  "@emotion/react": "^11.14.0",
39
39
  "@emotion/styled": "^11.14.1",
40
- "@iobroker/gui-components": "^10.0.3",
40
+ "@iobroker/gui-components": "^10.0.4",
41
41
  "@module-federation/runtime": "^2.8.0",
42
42
  "@mui/icons-material": "^9.2.0",
43
43
  "@mui/material": "^9.2.0",