@omicronenergy/oscd-shell 0.0.8 → 0.0.10

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.
Files changed (60) hide show
  1. package/dist/colors.d.ts +1 -0
  2. package/dist/colors.js +60 -0
  3. package/dist/colors.js.map +1 -0
  4. package/dist/foundation/cyrb64.js +0 -3
  5. package/dist/foundation/cyrb64.js.map +1 -1
  6. package/dist/foundation/events.d.ts +17 -0
  7. package/dist/foundation/events.js +2 -0
  8. package/dist/foundation/events.js.map +1 -0
  9. package/dist/foundation.js.map +1 -1
  10. package/dist/landing-page/landing-page.d.ts +26 -0
  11. package/dist/landing-page/landing-page.js +163 -0
  12. package/dist/landing-page/landing-page.js.map +1 -0
  13. package/dist/landing-page/landing-page.spec.d.ts +1 -0
  14. package/dist/landing-page/landing-page.spec.js +87 -0
  15. package/dist/landing-page/landing-page.spec.js.map +1 -0
  16. package/dist/locales/de.d.ts +0 -5
  17. package/dist/locales/de.js +0 -5
  18. package/dist/locales/de.js.map +1 -1
  19. package/dist/locales.js.map +1 -1
  20. package/dist/localization.d.ts +15 -0
  21. package/dist/localization.js +22 -0
  22. package/dist/localization.js.map +1 -0
  23. package/dist/menus/files-menu.d.ts +27 -0
  24. package/dist/menus/files-menu.js +102 -0
  25. package/dist/menus/files-menu.js.map +1 -0
  26. package/dist/menus/files-menu.spec.d.ts +1 -0
  27. package/dist/menus/files-menu.spec.js +33 -0
  28. package/dist/menus/files-menu.spec.js.map +1 -0
  29. package/dist/menus/plugins-menu.d.ts +32 -0
  30. package/dist/menus/plugins-menu.js +128 -0
  31. package/dist/menus/plugins-menu.js.map +1 -0
  32. package/dist/menus/plugins-menu.spec.d.ts +1 -0
  33. package/dist/menus/plugins-menu.spec.js +65 -0
  34. package/dist/menus/plugins-menu.spec.js.map +1 -0
  35. package/dist/oscd-shell.d.ts +71 -85
  36. package/dist/oscd-shell.js +382 -552
  37. package/dist/oscd-shell.js.map +1 -1
  38. package/dist/side-panel/editor-plugins-panel.d.ts +29 -0
  39. package/dist/side-panel/editor-plugins-panel.js +151 -0
  40. package/dist/side-panel/editor-plugins-panel.js.map +1 -0
  41. package/dist/side-panel/editor-plugins-panel.spec.d.ts +1 -0
  42. package/dist/side-panel/editor-plugins-panel.spec.js +87 -0
  43. package/dist/side-panel/editor-plugins-panel.spec.js.map +1 -0
  44. package/dist/theming.d.ts +1 -0
  45. package/dist/theming.js +76 -0
  46. package/dist/theming.js.map +1 -0
  47. package/dist/utils/plugin-utils.d.ts +1 -1
  48. package/dist/utils/plugin-utils.js +8 -11
  49. package/dist/utils/plugin-utils.js.map +1 -1
  50. package/dist/utils/plugin-utils.spec.js.map +1 -1
  51. package/dist/utils/testing/plugin-helpers.d.ts +24 -0
  52. package/dist/utils/testing/plugin-helpers.js +74 -0
  53. package/dist/utils/testing/plugin-helpers.js.map +1 -0
  54. package/dist/utils/testing/test-doc-helpers.d.ts +7 -0
  55. package/dist/utils/testing/test-doc-helpers.js +28 -0
  56. package/dist/utils/testing/test-doc-helpers.js.map +1 -0
  57. package/dist/utils/testing/test-plugins.d.ts +44 -0
  58. package/dist/utils/testing/test-plugins.js +56 -0
  59. package/dist/utils/testing/test-plugins.js.map +1 -0
  60. package/package.json +62 -126
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-utils.js","sourceRoot":"","sources":["../../utils/plugin-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { cyrb64 } from '../foundation/cyrb64.js';\nimport { PluginEntry, SourcedPluginEntry } from '../oscd-shell.js';\n\nconst pluginTags = new Map<string, string>();\n\n/*\n * Generates a unique tag name for a plugin based on its source URI.\n * This is used to ensure that each plugin has a unique identifier in the CustomElements registry.\n * @param uri - The source URI of the plugin.\n * @returns A unique tag name for the plugin.\n */\nfunction pluginTag(uri: string): string {\n if (!pluginTags.has(uri)) {\n pluginTags.set(uri, `oscd-p${cyrb64(uri)}`);\n }\n return pluginTags.get(uri)!;\n}\n\n/**\n * Generates a Web Component class that displays an error message when a plugin fails to load.\n * This is used to provide feedback to the Distro developer when a plugin cannot be loaded due to an error.\n * @param plugin - The plugin object that failed to load.\n * @returns A Web Component class that displays the error message.\n */\nfunction generateErrorWcClass(plugin: Partial<PluginEntry>) {\n const title = 'Error: Plugin failed to load.';\n const details = `Plugin: ${JSON.stringify(plugin)}`;\n const classString = `\n return class extends HTMLElement {\n\n connectedCallback() {\n this.innerHTML = '<h1>${title}</h1><p>${details}</p><emphasis>Check your plugins.json</emphasis>';\n }\n\n async run() {\n alert('${title}\\\\n\\\\n ${details}; \\\\n\\\\n Check your plugins.json');\n }\n }`;\n // eslint-disable-next-line no-new-func\n return new Function(classString)();\n}\n\n/**\n * Checks if the given object is a valid Plugin.\n * @param plugin - The object to check.\n * @returns true if the object is a Plugin, false otherwise.\n */\nexport function isPlugin(plugin: unknown): plugin is PluginEntry {\n return (\n typeof plugin === 'object' &&\n plugin !== null &&\n 'tagName' in plugin &&\n typeof plugin.tagName === 'string'\n );\n}\n\n/**\n * Checks if the given object is a SourcedPlugin.\n * @param plugin - The object to check.\n * @returns true if the object is a SourcedPlugin, false otherwise.\n */\nexport function isSourcedPlugin(plugin: unknown): plugin is SourcedPluginEntry {\n return (\n typeof plugin === 'object' &&\n plugin !== null &&\n 'src' in plugin &&\n typeof plugin.src === 'string'\n );\n}\n\n/**\n * Validates a Plugin object, checking for required fields and types.\n * If the plugin is invalid, it logs an error and returns undefined.\n * @param plugin - The plugin object to validate.\n * @returns The validated Plugin object or undefined if invalid.\n */\nexport function validatePlugin(plugin: unknown): PluginEntry | undefined {\n const missingFields = [];\n if (!isPlugin(plugin)) {\n missingFields.push('tagName');\n }\n\n const _plugin = plugin as PluginEntry;\n missingFields.push(\n ...(['name', 'icon'] as const).filter(\n field => !_plugin[field] || typeof _plugin[field] !== 'string',\n ),\n );\n if (\n typeof _plugin.requireDoc !== 'undefined' &&\n typeof _plugin.requireDoc !== 'boolean'\n ) {\n missingFields.push('requireDoc');\n }\n if (\n typeof _plugin.translations !== 'undefined' &&\n (typeof _plugin.translations !== 'object' ||\n Object.values(_plugin.translations).some(t => typeof t !== 'string'))\n ) {\n missingFields.push('translations');\n }\n\n if (missingFields.length > 0) {\n // eslint-disable-next-line no-console\n console.error(\n `[Invalid Plugin]\\n${JSON.stringify(plugin, null, 2)}\\nMissing/Invalid fields [${missingFields.join(',')}] - skipping.`,\n );\n return undefined;\n }\n return _plugin;\n}\n\n/**\n * Goes through all the plugins in the PluginSet and loads any sourced plugins, replacing the src field with a tagName.\n * If a plugin does not have a tagName, it will be generated based on its src.\n * All plugins returned are validated for required fields.\n * If a sourced plugin fails to load (bad src), it will be replaced with an Error Web Component.\n * @param plugins - Array of plugins to convert.\n * @returns Array of plugins with tagName included.\n */\nexport function loadSourcedPlugins(\n plugins: Partial<PluginEntry | SourcedPluginEntry>[],\n): PluginEntry[] {\n return plugins\n .map(plugin => {\n if (isPlugin(plugin)) {\n return validatePlugin(plugin);\n }\n if (!isSourcedPlugin(plugin)) {\n // eslint-disable-next-line no-console\n console.error(\n `[Invalid Plugin] Requires a tagName or src - skipping. ${JSON.stringify(plugin)}`,\n );\n return undefined;\n }\n const { src, ...rest } = plugin as SourcedPluginEntry;\n const hashedTagName = pluginTag(src);\n const validatedPlugin = validatePlugin({\n ...rest,\n tagName: hashedTagName,\n });\n\n if (!validatedPlugin) {\n return undefined;\n }\n\n if (customElements.get(hashedTagName)) {\n return validatedPlugin;\n }\n\n const url = new URL(src, window.location.href).toString();\n import(url)\n .then(mod => {\n // Because this is async, we need to check (again) if the element is already defined.\n if (!customElements?.get(hashedTagName)) {\n customElements.define(hashedTagName, mod.default);\n }\n })\n .catch(err => {\n // eslint-disable-next-line no-console\n console.error(\n `[Invalid Plugin] Failed to load plugin ${plugin.name} from ${url}`,\n err,\n );\n const ErrWc = generateErrorWcClass(plugin);\n customElements.define(hashedTagName, ErrWc);\n });\n return validatedPlugin;\n })\n .filter((plugin): plugin is PluginEntry => plugin !== undefined);\n}\n"]}
1
+ {"version":3,"file":"plugin-utils.js","sourceRoot":"","sources":["../../src/utils/plugin-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGjD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE7C;;;;;GAKG;AACH,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,UAAU,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;AAC9B,CAAC;AAED;;;;;GAKG;AACH,SAAS,oBAAoB,CAAC,MAA4B;IACxD,MAAM,KAAK,GAAG,+BAA+B,CAAC;IAC9C,MAAM,OAAO,GAAG,WAAW,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;IACpD,MAAM,WAAW,GAAG;;;;8BAIQ,KAAK,WAAW,OAAO;;;;eAItC,KAAK,UAAU,OAAO;;IAEjC,CAAC;IAEH,OAAO,IAAI,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAe;IACtC,OAAO,CACL,OAAO,MAAM,KAAK,QAAQ;QAC1B,MAAM,KAAK,IAAI;QACf,SAAS,IAAI,MAAM;QACnB,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CACnC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAe;IAC7C,OAAO,CACL,OAAO,MAAM,KAAK,QAAQ;QAC1B,MAAM,KAAK,IAAI;QACf,KAAK,IAAI,MAAM;QACf,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,CAC/B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,MAAe;IAC5C,MAAM,aAAa,GAAG,EAAE,CAAC;IACzB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED,MAAM,OAAO,GAAG,MAAqB,CAAC;IACtC,aAAa,CAAC,IAAI,CAChB,GAAI,CAAC,MAAM,EAAE,MAAM,CAAW,CAAC,MAAM,CACnC,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,QAAQ,CAC/D,CACF,CAAC;IACF,IACE,OAAO,OAAO,CAAC,UAAU,KAAK,WAAW;QACzC,OAAO,OAAO,CAAC,UAAU,KAAK,SAAS,EACvC,CAAC;QACD,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACnC,CAAC;IACD,IACE,OAAO,OAAO,CAAC,YAAY,KAAK,WAAW;QAC3C,CAAC,OAAO,OAAO,CAAC,YAAY,KAAK,QAAQ;YACvC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,EACvE,CAAC;QACD,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CACX,qBAAqB,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,6BAA6B,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,CACxH,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAoD,EACpD,QAA+B;IAE/B,OAAO,OAAO;SACX,GAAG,CAAC,MAAM,CAAC,EAAE;QACZ,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACrB,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,KAAK,CACX,0DAA0D,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CACnF,CAAC;YACF,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,MAA4B,CAAC;QACtD,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,eAAe,GAAG,cAAc,CAAC;YACrC,GAAG,IAAI;YACP,OAAO,EAAE,aAAa;SACvB,CAAC,CAAC;QAEH,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,IAAI,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;YAChC,OAAO,eAAe,CAAC;QACzB,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC1D,MAAM,CAAC,kBAAkB,CAAC,GAAG,CAAC;aAC3B,IAAI,CAAC,GAAG,CAAC,EAAE;YACV,qFAAqF;YACrF,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;gBAClC,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,CAAC,EAAE;YACX,4EAA4E;YAC5E,OAAO,CAAC,IAAI,CACV,0CAA0C,MAAM,CAAC,IAAI,KAAK,aAAa,WAAW,GAAG,EAAE,EACvF,GAAG,CACJ,CAAC;YACF,MAAM,KAAK,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;YAC3C,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QACL,OAAO,eAAe,CAAC;IACzB,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,MAAM,EAAyB,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;AACrE,CAAC","sourcesContent":["import { cyrb64 } from '../foundation/cyrb64.js';\nimport { PluginEntry, SourcedPluginEntry } from '../oscd-shell.js';\n\nconst pluginTags = new Map<string, string>();\n\n/*\n * Generates a unique tag name for a plugin based on its source URI.\n * This is used to ensure that each plugin has a unique identifier in the CustomElements registry.\n * @param uri - The source URI of the plugin.\n * @returns A unique tag name for the plugin.\n */\nfunction pluginTag(uri: string): string {\n if (!pluginTags.has(uri)) {\n pluginTags.set(uri, `oscd-p${cyrb64(uri)}`);\n }\n return pluginTags.get(uri)!;\n}\n\n/**\n * Generates a Web Component class that displays an error message when a plugin fails to load.\n * This is used to provide feedback to the Distro developer when a plugin cannot be loaded due to an error.\n * @param plugin - The plugin object that failed to load.\n * @returns A Web Component class that displays the error message.\n */\nfunction generateErrorWcClass(plugin: Partial<PluginEntry>) {\n const title = 'Error: Plugin failed to load.';\n const details = `Plugin: ${JSON.stringify(plugin)}`;\n const classString = `\n return class extends HTMLElement {\n\n connectedCallback() {\n this.innerHTML = '<h1>${title}</h1><p>${details}</p><emphasis>Check your plugins.json</emphasis>';\n }\n\n async run() {\n alert('${title}\\\\n\\\\n ${details}; \\\\n\\\\n Check your plugins.json');\n }\n }`;\n\n return new Function(classString)();\n}\n\n/**\n * Checks if the given object is a valid Plugin.\n * @param plugin - The object to check.\n * @returns true if the object is a Plugin, false otherwise.\n */\nexport function isPlugin(plugin: unknown): plugin is PluginEntry {\n return (\n typeof plugin === 'object' &&\n plugin !== null &&\n 'tagName' in plugin &&\n typeof plugin.tagName === 'string'\n );\n}\n\n/**\n * Checks if the given object is a SourcedPlugin.\n * @param plugin - The object to check.\n * @returns true if the object is a SourcedPlugin, false otherwise.\n */\nexport function isSourcedPlugin(plugin: unknown): plugin is SourcedPluginEntry {\n return (\n typeof plugin === 'object' &&\n plugin !== null &&\n 'src' in plugin &&\n typeof plugin.src === 'string'\n );\n}\n\n/**\n * Validates a Plugin object, checking for required fields and types.\n * If the plugin is invalid, it logs an error and returns undefined.\n * @param plugin - The plugin object to validate.\n * @returns The validated Plugin object or undefined if invalid.\n */\nexport function validatePlugin(plugin: unknown): PluginEntry | undefined {\n const missingFields = [];\n if (!isPlugin(plugin)) {\n missingFields.push('tagName');\n }\n\n const _plugin = plugin as PluginEntry;\n missingFields.push(\n ...(['name', 'icon'] as const).filter(\n field => !_plugin[field] || typeof _plugin[field] !== 'string',\n ),\n );\n if (\n typeof _plugin.requireDoc !== 'undefined' &&\n typeof _plugin.requireDoc !== 'boolean'\n ) {\n missingFields.push('requireDoc');\n }\n if (\n typeof _plugin.translations !== 'undefined' &&\n (typeof _plugin.translations !== 'object' ||\n Object.values(_plugin.translations).some(t => typeof t !== 'string'))\n ) {\n missingFields.push('translations');\n }\n\n if (missingFields.length > 0) {\n console.error(\n `[Invalid Plugin]\\n${JSON.stringify(plugin, null, 2)}\\nMissing/Invalid fields [${missingFields.join(',')}] - skipping.`,\n );\n return undefined;\n }\n return _plugin;\n}\n\n/**\n * Goes through all the plugins in the PluginSet and loads any sourced plugins, replacing the src field with a tagName.\n * If a plugin does not have a tagName, it will be generated based on its src.\n * All plugins returned are validated for required fields.\n * If a sourced plugin fails to load (bad src), it will be replaced with an Error Web Component.\n * @param plugins - Array of plugins to convert.\n * @returns Array of plugins with tagName included.\n */\nexport function loadSourcedPlugins(\n plugins: Partial<PluginEntry | SourcedPluginEntry>[],\n registry: CustomElementRegistry,\n): PluginEntry[] {\n return plugins\n .map(plugin => {\n if (isPlugin(plugin)) {\n return validatePlugin(plugin);\n }\n if (!isSourcedPlugin(plugin)) {\n console.error(\n `[Invalid Plugin] Requires a tagName or src - skipping. ${JSON.stringify(plugin)}`,\n );\n return undefined;\n }\n const { src, ...rest } = plugin as SourcedPluginEntry;\n const hashedTagName = pluginTag(src);\n const validatedPlugin = validatePlugin({\n ...rest,\n tagName: hashedTagName,\n });\n\n if (!validatedPlugin) {\n return undefined;\n }\n\n if (registry.get(hashedTagName)) {\n return validatedPlugin;\n }\n\n const url = new URL(src, window.location.href).toString();\n import(/* @vite-ignore */ url)\n .then(mod => {\n // Because this is async, we need to check (again) if the element is already defined.\n if (!registry?.get(hashedTagName)) {\n registry.define(hashedTagName, mod.default);\n }\n })\n .catch(err => {\n // Log this as a warning because we load an Error WC in place of the plugin.\n console.warn(\n `[Invalid Plugin] Failed to load plugin ${plugin.name} <${hashedTagName}/> from ${url}`,\n err,\n );\n const ErrWc = generateErrorWcClass(plugin);\n registry.define(hashedTagName, ErrWc);\n });\n return validatedPlugin;\n })\n .filter((plugin): plugin is PluginEntry => plugin !== undefined);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-utils.spec.js","sourceRoot":"","sources":["../../utils/plugin-utils.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { isPlugin, isSourcedPlugin, validatePlugin } from './plugin-utils.js';\n\ndescribe('Plugin Utils', () => {\n describe('isPlugin', () => {\n it('should return true for a valid Plugin object', () => {\n const plugin = {\n tagName: 'test-plugin',\n name: 'Test Plugin',\n icon: 'test-icon',\n requireDoc: false,\n };\n expect(plugin).satisfies(isPlugin);\n });\n\n it('should return false for an object without tagName', () => {\n const plugin = {\n name: 'Test Plugin',\n icon: 'test-icon',\n requireDoc: false,\n };\n expect(plugin).to.not.satisfy(isPlugin);\n });\n\n it('should return false for a SourcePlugin', () => {\n const plugin = {\n name: 'Test Plugin',\n icon: 'test-icon',\n src: 'data:text/javascript;charset=utf-8,import%20%7B%20default%20as%20TestPlugin%20%7D%20from%20\"./test-plugin.js\";',\n };\n expect(plugin).to.not.satisfy(isPlugin);\n });\n });\n\n describe('isSourcePlugin', () => {\n it('should return true for a valid SourcePlugin object', () => {\n const plugin = {\n name: 'Test Plugin',\n src: 'data:text/javascript;charset=utf-8,import%20%7B%20default%20as%20TestPlugin%20%7D%20from%20\"./test-plugin.js\";',\n icon: 'test-icon',\n };\n expect(plugin).satisfies(isSourcedPlugin);\n });\n\n it('should return false for an object without a src field', () => {\n const plugin = {\n name: 'Test Plugin',\n icon: 'test-icon',\n };\n expect(plugin).not.to.satisfy(isSourcedPlugin);\n });\n\n it('should return false for an Plugin object (has tagName, but no src)', () => {\n const plugin = {\n name: 'Test Plugin',\n icon: 'test-icon',\n tagName: 'test-plugin',\n };\n expect(plugin).not.to.satisfy(isSourcedPlugin);\n });\n });\n});\n\ndescribe('validatePlugin', () => {\n it('returns a Plugin object, for a valid plugin', async () => {\n const plugin = {\n name: 'Tagless, Sourceless, Hopeless Plugin',\n icon: 'coronavirus',\n tagName: 'test-tagless-plugin',\n };\n\n expect(plugin).satisfies(validatePlugin);\n });\n\n it('returns undefined, for a plugin definition missing its \"tagName\" field', async () => {\n const plugin = {\n icon: 'coronavirus',\n name: 'Tagless, Sourceless, Hopeless Plugin',\n };\n\n expect(plugin).not.to.satisfy(validatePlugin);\n });\n\n it('returns undefined, for a plugin definition missing its \"name\" field', async () => {\n const plugin = {\n icon: 'coronavirus',\n tagName: 'test-tagless-plugin',\n };\n\n expect(plugin).not.to.satisfy(validatePlugin);\n });\n\n it('returns undefined, for a plugin definition missing its \"icon\" field', async () => {\n const plugin = {\n name: 'Tagless, Sourceless, Hopeless Plugin',\n tagName: 'test-tagless-plugin',\n };\n\n expect(plugin).not.to.satisfy(validatePlugin);\n });\n\n it('returns undefined, for a plugin definition with invalid requireDoc field', async () => {\n const plugin = {\n name: 'Tagless, Sourceless, Hopeless Plugin',\n tagName: 'test-tagless-plugin',\n requireDoc: 'not-a-boolean',\n };\n\n expect(plugin).not.to.satisfy(validatePlugin);\n });\n\n it('returns undefined, for a plugin definition with invalid translations field', async () => {\n const plugin = {\n name: 'Tagless, Sourceless, Hopeless Plugin',\n tagName: 'test-tagless-plugin',\n translations: 'ops',\n };\n\n expect(plugin).not.to.satisfy(validatePlugin);\n });\n\n it('returns undefined, for a plugin definition with invalid translations', async () => {\n const plugin = {\n name: 'Tagless, Sourceless, Hopeless Plugin',\n tagName: 'test-tagless-plugin',\n translations: {\n en: 'Tagless, Sourceless, Hopeless Plugin',\n fr: 123, // Invalid translation (not a string)\n },\n };\n\n expect(plugin).not.to.satisfy(validatePlugin);\n });\n});\n"]}
1
+ {"version":3,"file":"plugin-utils.spec.js","sourceRoot":"","sources":["../../src/utils/plugin-utils.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { isPlugin, isSourcedPlugin, validatePlugin } from './plugin-utils.js';\n\ndescribe('Plugin Utils', () => {\n describe('isPlugin', () => {\n it('should return true for a valid Plugin object', () => {\n const plugin = {\n tagName: 'test-plugin',\n name: 'Test Plugin',\n icon: 'test-icon',\n requireDoc: false,\n };\n expect(plugin).satisfies(isPlugin);\n });\n\n it('should return false for an object without tagName', () => {\n const plugin = {\n name: 'Test Plugin',\n icon: 'test-icon',\n requireDoc: false,\n };\n expect(plugin).to.not.satisfy(isPlugin);\n });\n\n it('should return false for a SourcePlugin', () => {\n const plugin = {\n name: 'Test Plugin',\n icon: 'test-icon',\n src: 'data:text/javascript;charset=utf-8,import%20%7B%20default%20as%20TestPlugin%20%7D%20from%20\"./test-plugin.js\";',\n };\n expect(plugin).to.not.satisfy(isPlugin);\n });\n });\n\n describe('isSourcePlugin', () => {\n it('should return true for a valid SourcePlugin object', () => {\n const plugin = {\n name: 'Test Plugin',\n src: 'data:text/javascript;charset=utf-8,import%20%7B%20default%20as%20TestPlugin%20%7D%20from%20\"./test-plugin.js\";',\n icon: 'test-icon',\n };\n expect(plugin).satisfies(isSourcedPlugin);\n });\n\n it('should return false for an object without a src field', () => {\n const plugin = {\n name: 'Test Plugin',\n icon: 'test-icon',\n };\n expect(plugin).not.to.satisfy(isSourcedPlugin);\n });\n\n it('should return false for an Plugin object (has tagName, but no src)', () => {\n const plugin = {\n name: 'Test Plugin',\n icon: 'test-icon',\n tagName: 'test-plugin',\n };\n expect(plugin).not.to.satisfy(isSourcedPlugin);\n });\n });\n});\n\ndescribe('validatePlugin', () => {\n it('returns a Plugin object, for a valid plugin', async () => {\n const plugin = {\n name: 'Tagless, Sourceless, Hopeless Plugin',\n icon: 'coronavirus',\n tagName: 'test-tagless-plugin',\n };\n\n expect(plugin).satisfies(validatePlugin);\n });\n\n it('returns undefined, for a plugin definition missing its \"tagName\" field', async () => {\n const plugin = {\n icon: 'coronavirus',\n name: 'Tagless, Sourceless, Hopeless Plugin',\n };\n\n expect(plugin).not.to.satisfy(validatePlugin);\n });\n\n it('returns undefined, for a plugin definition missing its \"name\" field', async () => {\n const plugin = {\n icon: 'coronavirus',\n tagName: 'test-tagless-plugin',\n };\n\n expect(plugin).not.to.satisfy(validatePlugin);\n });\n\n it('returns undefined, for a plugin definition missing its \"icon\" field', async () => {\n const plugin = {\n name: 'Tagless, Sourceless, Hopeless Plugin',\n tagName: 'test-tagless-plugin',\n };\n\n expect(plugin).not.to.satisfy(validatePlugin);\n });\n\n it('returns undefined, for a plugin definition with invalid requireDoc field', async () => {\n const plugin = {\n name: 'Tagless, Sourceless, Hopeless Plugin',\n tagName: 'test-tagless-plugin',\n requireDoc: 'not-a-boolean',\n };\n\n expect(plugin).not.to.satisfy(validatePlugin);\n });\n\n it('returns undefined, for a plugin definition with invalid translations field', async () => {\n const plugin = {\n name: 'Tagless, Sourceless, Hopeless Plugin',\n tagName: 'test-tagless-plugin',\n translations: 'ops',\n };\n\n expect(plugin).not.to.satisfy(validatePlugin);\n });\n\n it('returns undefined, for a plugin definition with invalid translations', async () => {\n const plugin = {\n name: 'Tagless, Sourceless, Hopeless Plugin',\n tagName: 'test-tagless-plugin',\n translations: {\n en: 'Tagless, Sourceless, Hopeless Plugin',\n fr: 123, // Invalid translation (not a string)\n },\n };\n\n expect(plugin).not.to.satisfy(validatePlugin);\n });\n});\n"]}
@@ -0,0 +1,24 @@
1
+ import { OscdShell, PluginEntry } from '../../oscd-shell.js';
2
+ export declare const sampleMenuPlugins: (Omit<PluginEntry, 'tagName'> & {
3
+ tagName?: string;
4
+ src?: string;
5
+ })[];
6
+ export declare const sampleEditorPlugins: (Omit<PluginEntry, 'tagName'> & {
7
+ tagName?: string;
8
+ src?: string;
9
+ })[];
10
+ export declare const isPluginInstanciated: (pluginTagName: string, shell: OscdShell) => boolean;
11
+ export declare const waitForPluginInstanciation: (plugin: PluginEntry, shell: OscdShell) => Promise<void>;
12
+ export declare const waitForPluginsToInstantiate: (plugins: PluginEntry[], shell: OscdShell) => Promise<void[]>;
13
+ /**
14
+ * Convienience function to wait for all applicable plugins to instantiate.
15
+ * If a document is loaded, all plugins are waited for. If no document is loaded,
16
+ * only plugins that do not require a document are waited for.
17
+ * If no document is loaded, only menu and background plugins are considered, as
18
+ * the landing page does not have an editor.
19
+ *
20
+ * @param shell - The instance of the OscdShell to check for plugin instantiation.
21
+ * @returns Empty Promise that resolves when all applicable plugins have been instantiated.
22
+ */
23
+ export declare const waitForAllPluginsToInstantiate: (shell: OscdShell) => Promise<void | void[]>;
24
+ export declare const registerPlugin: (shell: OscdShell, tagName: string, pluginClass: CustomElementConstructor) => void;
@@ -0,0 +1,74 @@
1
+ /* eslint-disable import-x/no-extraneous-dependencies */
2
+ import { waitUntil } from '@open-wc/testing';
3
+ export const sampleMenuPlugins = [
4
+ {
5
+ name: 'Test Menu Plugin',
6
+ translations: { de: 'Test Menu Erweiterung' },
7
+ tagName: 'test-menu-plugin1',
8
+ icon: 'margin',
9
+ requireDoc: false,
10
+ },
11
+ {
12
+ name: 'Test Menu Plugin 2',
13
+ src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestStrMenuPlugin2%20extends%20HTMLElement%20%7B%0D%0A%20%20async%20run%28%29%20%7B%0D%0A%20%20%20%20return%20true%3B%0D%0A%20%20%7D%0D%0A%7D',
14
+ icon: 'margin',
15
+ requireDoc: false,
16
+ },
17
+ {
18
+ name: 'Test Menu Plugin 3',
19
+ src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestStrMenuPlugin3%20extends%20HTMLElement%20%7B%0D%0A%20%20async%20run%28%29%20%7B%0D%0A%20%20%20%20return%20true%3B%0D%0A%20%20%7D%0D%0A%7D',
20
+ icon: 'margin',
21
+ requireDoc: false,
22
+ },
23
+ ];
24
+ export const sampleEditorPlugins = [
25
+ {
26
+ name: 'Test Editor Plugin',
27
+ translations: { de: 'Test Editor Erweiterung' },
28
+ src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestEditorPlugin%20extends%20HTMLElement%20%7B%0D%0A%20%20constructor%20%28%29%20%7B%20super%28%29%3B%20this.innerHTML%20%3D%20%60%3Cp%3ETest%20Editor%20Plugin%3C%2Fp%3E%60%3B%20%7D%0D%0A%7D',
29
+ icon: 'coronavirus',
30
+ },
31
+ {
32
+ name: 'Test Editor Plugin 2',
33
+ src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestEditorPlugin%20extends%20HTMLElement%20%7B%0D%0A%20%20constructor%20%28%29%20%7B%20super%28%29%3B%20this.innerHTML%20%3D%20%60%3Cp%3ETest%20Editor%20Plugin%3C%2Fp%3E%60%3B%20%7D%0D%0A%7D',
34
+ icon: 'coronavirus',
35
+ },
36
+ ];
37
+ export const isPluginInstanciated = (pluginTagName, shell) => !!shell.registry?.get(pluginTagName) &&
38
+ !!shell.shadowRoot?.querySelector(pluginTagName);
39
+ export const waitForPluginInstanciation = async (plugin, shell) => waitUntil(() => isPluginInstanciated(plugin.tagName, shell), `Plugin: "${plugin.name}" <${plugin.tagName}> failed to load.
40
+ CustomElements Registered: ${shell.registry?.get(plugin.tagName) ? 'Yes' : 'No (at least not in the OscdShell registry)'},
41
+ Found in DOM: ${shell.shadowRoot?.querySelector(plugin.tagName) ? 'Yes' : 'No'},
42
+ requiresDoc?: ${plugin.requireDoc}
43
+ loadedDocName?: ${shell.docName}`);
44
+ export const waitForPluginsToInstantiate = async (plugins, shell) => await Promise.all(plugins.map(plugin => waitForPluginInstanciation(plugin, shell)));
45
+ /**
46
+ * Convienience function to wait for all applicable plugins to instantiate.
47
+ * If a document is loaded, all plugins are waited for. If no document is loaded,
48
+ * only plugins that do not require a document are waited for.
49
+ * If no document is loaded, only menu and background plugins are considered, as
50
+ * the landing page does not have an editor.
51
+ *
52
+ * @param shell - The instance of the OscdShell to check for plugin instantiation.
53
+ * @returns Empty Promise that resolves when all applicable plugins have been instantiated.
54
+ */
55
+ export const waitForAllPluginsToInstantiate = async (shell) => {
56
+ const docLoaded = !!shell.docName;
57
+ const editorPlugin = shell.plugins.editor.find(editor => editor.tagName === shell.editor);
58
+ const menuPlugins = shell.plugins.menu.filter(plugin => !plugin.requireDoc || docLoaded);
59
+ const backgroundPlugins = shell.plugins.background.filter(plugin => !plugin.requireDoc || docLoaded);
60
+ const allPlugins = [
61
+ ...menuPlugins,
62
+ ...backgroundPlugins,
63
+ ...(docLoaded && editorPlugin ? [editorPlugin] : []),
64
+ ];
65
+ return allPlugins.length > 0
66
+ ? waitForPluginsToInstantiate(allPlugins, shell)
67
+ : Promise.resolve();
68
+ };
69
+ export const registerPlugin = (shell, tagName, pluginClass) => {
70
+ if (!shell.registry?.get(tagName)) {
71
+ shell.registry?.define(tagName, pluginClass);
72
+ }
73
+ };
74
+ //# sourceMappingURL=plugin-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-helpers.js","sourceRoot":"","sources":["../../../src/utils/testing/plugin-helpers.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable import-x/no-extraneous-dependencies */\nimport { waitUntil } from '@open-wc/testing';\nimport { OscdShell, PluginEntry } from '../../oscd-shell.js';\n\nexport const sampleMenuPlugins: (Omit<PluginEntry, 'tagName'> & {\n tagName?: string;\n src?: string;\n})[] = [\n {\n name: 'Test Menu Plugin',\n translations: { de: 'Test Menu Erweiterung' },\n tagName: 'test-menu-plugin1',\n icon: 'margin',\n requireDoc: false,\n },\n {\n name: 'Test Menu Plugin 2',\n src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestStrMenuPlugin2%20extends%20HTMLElement%20%7B%0D%0A%20%20async%20run%28%29%20%7B%0D%0A%20%20%20%20return%20true%3B%0D%0A%20%20%7D%0D%0A%7D',\n icon: 'margin',\n requireDoc: false,\n },\n {\n name: 'Test Menu Plugin 3',\n src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestStrMenuPlugin3%20extends%20HTMLElement%20%7B%0D%0A%20%20async%20run%28%29%20%7B%0D%0A%20%20%20%20return%20true%3B%0D%0A%20%20%7D%0D%0A%7D',\n icon: 'margin',\n requireDoc: false,\n },\n];\n\nexport const sampleEditorPlugins: (Omit<PluginEntry, 'tagName'> & {\n tagName?: string;\n src?: string;\n})[] = [\n {\n name: 'Test Editor Plugin',\n translations: { de: 'Test Editor Erweiterung' },\n src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestEditorPlugin%20extends%20HTMLElement%20%7B%0D%0A%20%20constructor%20%28%29%20%7B%20super%28%29%3B%20this.innerHTML%20%3D%20%60%3Cp%3ETest%20Editor%20Plugin%3C%2Fp%3E%60%3B%20%7D%0D%0A%7D',\n icon: 'coronavirus',\n },\n {\n name: 'Test Editor Plugin 2',\n src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestEditorPlugin%20extends%20HTMLElement%20%7B%0D%0A%20%20constructor%20%28%29%20%7B%20super%28%29%3B%20this.innerHTML%20%3D%20%60%3Cp%3ETest%20Editor%20Plugin%3C%2Fp%3E%60%3B%20%7D%0D%0A%7D',\n icon: 'coronavirus',\n },\n];\n\nexport const isPluginInstanciated = (\n pluginTagName: string,\n shell: OscdShell,\n): boolean =>\n !!shell.registry?.get(pluginTagName) &&\n !!shell.shadowRoot?.querySelector(pluginTagName);\n\nexport const waitForPluginInstanciation = async (\n plugin: PluginEntry,\n shell: OscdShell,\n): Promise<void> =>\n waitUntil(\n () => isPluginInstanciated(plugin.tagName, shell),\n `Plugin: \"${plugin.name}\" <${plugin.tagName}> failed to load. \n CustomElements Registered: ${shell.registry?.get(plugin.tagName) ? 'Yes' : 'No (at least not in the OscdShell registry)'}, \n Found in DOM: ${shell.shadowRoot?.querySelector(plugin.tagName) ? 'Yes' : 'No'}, \n requiresDoc?: ${plugin.requireDoc}\n loadedDocName?: ${shell.docName}`,\n );\n\nexport const waitForPluginsToInstantiate = async (\n plugins: PluginEntry[],\n shell: OscdShell,\n) =>\n await Promise.all(\n plugins.map(plugin => waitForPluginInstanciation(plugin, shell)),\n );\n\n/**\n * Convienience function to wait for all applicable plugins to instantiate.\n * If a document is loaded, all plugins are waited for. If no document is loaded,\n * only plugins that do not require a document are waited for.\n * If no document is loaded, only menu and background plugins are considered, as\n * the landing page does not have an editor.\n *\n * @param shell - The instance of the OscdShell to check for plugin instantiation.\n * @returns Empty Promise that resolves when all applicable plugins have been instantiated.\n */\nexport const waitForAllPluginsToInstantiate = async (shell: OscdShell) => {\n const docLoaded = !!shell.docName;\n\n const editorPlugin = shell.plugins.editor.find(\n editor => editor.tagName === shell.editor,\n );\n\n const menuPlugins = shell.plugins.menu.filter(\n plugin => !plugin.requireDoc || docLoaded,\n );\n const backgroundPlugins = shell.plugins.background.filter(\n plugin => !plugin.requireDoc || docLoaded,\n );\n\n const allPlugins: PluginEntry[] = [\n ...menuPlugins,\n ...backgroundPlugins,\n ...(docLoaded && editorPlugin ? [editorPlugin] : []),\n ];\n\n return allPlugins.length > 0\n ? waitForPluginsToInstantiate(allPlugins, shell)\n : Promise.resolve();\n};\n\nexport const registerPlugin = (\n shell: OscdShell,\n tagName: string,\n pluginClass: CustomElementConstructor,\n) => {\n if (!shell.registry?.get(tagName)) {\n shell.registry?.define(tagName, pluginClass);\n }\n};\n"]}
@@ -0,0 +1,7 @@
1
+ import { OscdShell } from '../../oscd-shell.js';
2
+ export declare const nonSclDocString = "<testdoc></testdoc>";
3
+ export declare const sclDocString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <SCL version=\"2007\" revision=\"B\" xmlns=\"http://www.iec.ch/61850/2003/SCL\" xmlns:ens1=\"http://example.org/somePreexistingExtensionNamespace\">\n <Substation ens1:foo=\"a\" name=\"A1\" desc=\"test substation\"></Substation>\n</SCL>";
4
+ export declare const createNonSclDocument: () => Document;
5
+ export declare const createSclDocument: () => Document;
6
+ export declare const openDocOnShell: (shell: OscdShell, docName: string, doc: XMLDocument) => Promise<void>;
7
+ export declare function createTestDocs(amount: number): any;
@@ -0,0 +1,28 @@
1
+ export const nonSclDocString = `<testdoc></testdoc>`;
2
+ export const sclDocString = `<?xml version="1.0" encoding="UTF-8"?>
3
+ <SCL version="2007" revision="B" xmlns="http://www.iec.ch/61850/2003/SCL" xmlns:ens1="http://example.org/somePreexistingExtensionNamespace">
4
+ <Substation ens1:foo="a" name="A1" desc="test substation"></Substation>
5
+ </SCL>`;
6
+ export const createNonSclDocument = () => {
7
+ const parser = new DOMParser();
8
+ return parser.parseFromString(nonSclDocString, 'application/xml');
9
+ };
10
+ export const createSclDocument = () => {
11
+ const parser = new DOMParser();
12
+ return parser.parseFromString(sclDocString, 'application/xml');
13
+ };
14
+ export const openDocOnShell = async (shell, docName, doc) => {
15
+ shell.docs = { ...shell.docs, [docName]: doc };
16
+ shell.docName = docName;
17
+ await shell.updateComplete;
18
+ };
19
+ export function createTestDocs(amount) {
20
+ return Array(amount)
21
+ .fill(0)
22
+ .reduce((acc, _, index) => {
23
+ const docName = `test${index}.cid`;
24
+ acc[docName] = createSclDocument();
25
+ return acc;
26
+ }, {});
27
+ }
28
+ //# sourceMappingURL=test-doc-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-doc-helpers.js","sourceRoot":"","sources":["../../../src/utils/testing/test-doc-helpers.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAG,qBAAqB,CAAC;AAErD,MAAM,CAAC,MAAM,YAAY,GAAG;;;OAGrB,CAAC;AAER,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,EAAE;IACvC,MAAM,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;IAC/B,OAAO,MAAM,CAAC,eAAe,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;AACpE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,EAAE;IACpC,MAAM,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;IAC/B,OAAO,MAAM,CAAC,eAAe,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;AACjE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,KAAgB,EAChB,OAAe,EACf,GAAgB,EACD,EAAE;IACjB,KAAK,CAAC,IAAI,GAAG,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAC/C,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,MAAM,KAAK,CAAC,cAAc,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO,KAAK,CAAC,MAAM,CAAC;SACjB,IAAI,CAAC,CAAC,CAAC;SACP,MAAM,CACL,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE;QAChB,MAAM,OAAO,GAAG,OAAO,KAAK,MAAM,CAAC;QACnC,GAAG,CAAC,OAAO,CAAC,GAAG,iBAAiB,EAAE,CAAC;QACnC,OAAO,GAAG,CAAC;IACb,CAAC,EACD,EAAiC,CAClC,CAAC;AACN,CAAC","sourcesContent":["import { OscdShell } from '../../oscd-shell.js';\n\nexport const nonSclDocString = `<testdoc></testdoc>`;\n\nexport const sclDocString = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <SCL version=\"2007\" revision=\"B\" xmlns=\"http://www.iec.ch/61850/2003/SCL\" xmlns:ens1=\"http://example.org/somePreexistingExtensionNamespace\">\n <Substation ens1:foo=\"a\" name=\"A1\" desc=\"test substation\"></Substation>\n</SCL>`;\n\nexport const createNonSclDocument = () => {\n const parser = new DOMParser();\n return parser.parseFromString(nonSclDocString, 'application/xml');\n};\n\nexport const createSclDocument = () => {\n const parser = new DOMParser();\n return parser.parseFromString(sclDocString, 'application/xml');\n};\n\nexport const openDocOnShell = async (\n shell: OscdShell,\n docName: string,\n doc: XMLDocument,\n): Promise<void> => {\n shell.docs = { ...shell.docs, [docName]: doc };\n shell.docName = docName;\n await shell.updateComplete;\n};\n\nexport function createTestDocs(amount: number) {\n return Array(amount)\n .fill(0)\n .reduce(\n (acc, _, index) => {\n const docName = `test${index}.cid`;\n acc[docName] = createSclDocument();\n return acc;\n },\n {} as Record<string, XMLDocument>,\n );\n}\n"]}
@@ -0,0 +1,44 @@
1
+ import { LitElement } from 'lit';
2
+ export declare class TestMenuPlugin1 extends LitElement {
3
+ docVersion: number;
4
+ run(): Promise<boolean>;
5
+ }
6
+ export declare class TestBackgroundPlugin extends HTMLElement {
7
+ constructor();
8
+ }
9
+ export declare const testMenuPlugin1: {
10
+ name: string;
11
+ translations: {
12
+ de: string;
13
+ };
14
+ tagName: string;
15
+ icon: string;
16
+ requireDoc: boolean;
17
+ };
18
+ export declare const testMenuPlugin2: {
19
+ name: string;
20
+ translations: {
21
+ de: string;
22
+ };
23
+ src: string;
24
+ icon: string;
25
+ requireDoc: boolean;
26
+ };
27
+ export declare const testEditorPlugin: {
28
+ name: string;
29
+ translations: {
30
+ de: string;
31
+ };
32
+ src: string;
33
+ icon: string;
34
+ requireDoc: boolean;
35
+ };
36
+ export declare const testEditorPlugin2: {
37
+ name: string;
38
+ translations: {
39
+ de: string;
40
+ };
41
+ src: string;
42
+ icon: string;
43
+ requireDoc: boolean;
44
+ };
@@ -0,0 +1,56 @@
1
+ import { __decorate } from "tslib";
2
+ import { LitElement } from 'lit';
3
+ import { property } from 'lit/decorators.js';
4
+ export class TestMenuPlugin1 extends LitElement {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.docVersion = 0;
8
+ }
9
+ async run() {
10
+ const editor = this.getRootNode().host;
11
+ editor.undo();
12
+ return true;
13
+ }
14
+ }
15
+ __decorate([
16
+ property({})
17
+ ], TestMenuPlugin1.prototype, "docVersion", void 0);
18
+ export class TestBackgroundPlugin extends HTMLElement {
19
+ constructor() {
20
+ super();
21
+ document.addEventListener('test-tx', event => {
22
+ document.dispatchEvent(new CustomEvent('test-rx', {
23
+ detail: event.detail,
24
+ }));
25
+ });
26
+ }
27
+ }
28
+ export const testMenuPlugin1 = {
29
+ name: 'Test Undo Menu Plugin 1',
30
+ translations: { de: 'Test Rückgängig-Menü-Plugin' },
31
+ tagName: 'test-menu-plugin1',
32
+ icon: 'undo',
33
+ requireDoc: false,
34
+ };
35
+ export const testMenuPlugin2 = {
36
+ name: 'Test Undo Menu Plugin 2',
37
+ translations: { de: 'Test Rückgängig-Menü-Plugin 2' },
38
+ src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestPlugin%20extends%20HTMLElement%20%7B%0D%0A%20%20async%20run()%20%7B%0D%0A%20%20const%20editor2%20=%20(this.getRootNode()).host;%20%0D%0A%20editor2.undo();%0D%0A%20return%20true;%0D%0A%20%20%7D%0D%0A%7D',
39
+ icon: 'undo',
40
+ requireDoc: true,
41
+ };
42
+ export const testEditorPlugin = {
43
+ name: 'Test Editor Plugin',
44
+ translations: { de: 'Test Editor Erweiterung' },
45
+ src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestEditorPlugin%20extends%20HTMLElement%20%7B%0D%0A%20%20constructor%20%28%29%20%7B%20super%28%29%3B%20this.innerHTML%20%3D%20%60%3Cp%3ETest%20Editor%20Plugin%3C%2Fp%3E%60%3B%20%7D%0D%0A%7D',
46
+ icon: 'edit',
47
+ requireDoc: false,
48
+ };
49
+ export const testEditorPlugin2 = {
50
+ name: 'Test Editor Plugin 2',
51
+ translations: { de: 'Test Editor Erweiterung 2' },
52
+ src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestEditorPlugin2%20extends%20HTMLElement%20%7B%0D%0A%20%20constructor%20%28%29%20%7B%20super%28%29%3B%20this.innerHTML%20%3D%20%60%3Cp%3ETest%20Editor%20Plugin2%3C%2Fp%3E%60%3B%20%7D%0D%0A%7D',
53
+ icon: 'edit',
54
+ requireDoc: true,
55
+ };
56
+ //# sourceMappingURL=test-plugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-plugins.js","sourceRoot":"","sources":["../../../src/utils/testing/test-plugins.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7C,MAAM,OAAO,eAAgB,SAAQ,UAAU;IAA/C;;QAEE,eAAU,GAAG,CAAC,CAAC;IAOjB,CAAC;IALC,KAAK,CAAC,GAAG;QACP,MAAM,MAAM,GAAI,IAAI,CAAC,WAAW,EAAiB,CAAC,IAAiB,CAAC;QACpE,MAAM,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAPC;IADC,QAAQ,CAAC,EAAE,CAAC;mDACE;AASjB,MAAM,OAAO,oBAAqB,SAAQ,WAAW;IACnD;QACE,KAAK,EAAE,CAAC;QACR,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE;YAC3C,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAAC,SAAS,EAAE;gBACzB,MAAM,EAAG,KAAqB,CAAC,MAAM;aACtC,CAAC,CACH,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAED,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,yBAAyB;IAC/B,YAAY,EAAE,EAAE,EAAE,EAAE,6BAA6B,EAAE;IACnD,OAAO,EAAE,mBAAmB;IAC5B,IAAI,EAAE,MAAM;IACZ,UAAU,EAAE,KAAK;CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,yBAAyB;IAC/B,YAAY,EAAE,EAAE,EAAE,EAAE,+BAA+B,EAAE;IACrD,GAAG,EAAE,6QAA6Q;IAClR,IAAI,EAAE,MAAM;IACZ,UAAU,EAAE,IAAI;CACjB,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,IAAI,EAAE,oBAAoB;IAC1B,YAAY,EAAE,EAAE,EAAE,EAAE,yBAAyB,EAAE;IAC/C,GAAG,EAAE,8PAA8P;IACnQ,IAAI,EAAE,MAAM;IACZ,UAAU,EAAE,KAAK;CAClB,CAAC;AACF,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,sBAAsB;IAC5B,YAAY,EAAE,EAAE,EAAE,EAAE,2BAA2B,EAAE;IACjD,GAAG,EAAE,gQAAgQ;IACrQ,IAAI,EAAE,MAAM;IACZ,UAAU,EAAE,IAAI;CACjB,CAAC","sourcesContent":["import { LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { OscdShell } from '../../oscd-shell.js';\n\nexport class TestMenuPlugin1 extends LitElement {\n @property({})\n docVersion = 0;\n\n async run() {\n const editor = (this.getRootNode() as ShadowRoot).host as OscdShell;\n editor.undo();\n return true;\n }\n}\n\nexport class TestBackgroundPlugin extends HTMLElement {\n constructor() {\n super();\n document.addEventListener('test-tx', event => {\n document.dispatchEvent(\n new CustomEvent('test-rx', {\n detail: (event as CustomEvent).detail,\n }),\n );\n });\n }\n}\n\nexport const testMenuPlugin1 = {\n name: 'Test Undo Menu Plugin 1',\n translations: { de: 'Test Rückgängig-Menü-Plugin' },\n tagName: 'test-menu-plugin1',\n icon: 'undo',\n requireDoc: false,\n};\n\nexport const testMenuPlugin2 = {\n name: 'Test Undo Menu Plugin 2',\n translations: { de: 'Test Rückgängig-Menü-Plugin 2' },\n src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestPlugin%20extends%20HTMLElement%20%7B%0D%0A%20%20async%20run()%20%7B%0D%0A%20%20const%20editor2%20=%20(this.getRootNode()).host;%20%0D%0A%20editor2.undo();%0D%0A%20return%20true;%0D%0A%20%20%7D%0D%0A%7D',\n icon: 'undo',\n requireDoc: true,\n};\n\nexport const testEditorPlugin = {\n name: 'Test Editor Plugin',\n translations: { de: 'Test Editor Erweiterung' },\n src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestEditorPlugin%20extends%20HTMLElement%20%7B%0D%0A%20%20constructor%20%28%29%20%7B%20super%28%29%3B%20this.innerHTML%20%3D%20%60%3Cp%3ETest%20Editor%20Plugin%3C%2Fp%3E%60%3B%20%7D%0D%0A%7D',\n icon: 'edit',\n requireDoc: false,\n};\nexport const testEditorPlugin2 = {\n name: 'Test Editor Plugin 2',\n translations: { de: 'Test Editor Erweiterung 2' },\n src: 'data:text/javascript;charset=utf-8,export%20default%20class%20TestEditorPlugin2%20extends%20HTMLElement%20%7B%0D%0A%20%20constructor%20%28%29%20%7B%20super%28%29%3B%20this.innerHTML%20%3D%20%60%3Cp%3ETest%20Editor%20Plugin2%3C%2Fp%3E%60%3B%20%7D%0D%0A%7D',\n icon: 'edit',\n requireDoc: true,\n};\n"]}
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "@omicronenergy/oscd-shell",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "description": "The shell component of OpenSCD, where plugins are loaded and the application is initialized.",
5
- "displayName": "OpenSCD Shell",
6
5
  "repository": {
7
6
  "type": "git",
8
7
  "url": "git+https://github.com/OMICRONEnergyOSS/oscd-shell.git"
@@ -33,158 +32,92 @@
33
32
  "!/dist/*.test.*"
34
33
  ],
35
34
  "scripts": {
36
- "lint": "eslint --ext .ts,.html . --ignore-path .gitignore && prettier \"**/*.ts\" --check --ignore-path .gitignore",
37
- "format": "eslint --ext .ts,.html . --fix --ignore-path .gitignore && prettier \"**/*.ts\" --write --ignore-path .gitignore",
38
- "build": "rimraf dist && npm run extract && npm run localize && tsc -b",
39
- "bundle": "rimraf dist && npm run localize && rollup -c rollup.config.js",
35
+ "lint": "eslint .",
36
+ "format": "eslint . --fix",
40
37
  "extract": "lit-localize extract",
41
38
  "localize": "lit-localize build",
42
- "start": "npm run build && cp -r ./demo ./dist/ && concurrently -k -r \"tsc -b --watch --preserveWatchOutput\" \"wds\"",
43
- "start:bundle": "npm run bundle && concurrently -k -r \"rollup -c rollup.config.js --watch\" \"wds --open dist/demo/index.html --watch\"",
44
- "test": "npm run build && playwright install && wtr --coverage",
45
- "test:unit": "npm run build && playwright install && wtr --coverage --group default",
46
- "test:visual": "npm run build && playwright install && wtr --group visual",
47
- "test:watch": "npm run build && concurrently -k -r \"tsc -b --watch --preserveWatchOutput\" \"wtr --watch --coverage\"",
48
- "test:unit:watch": "npm run build && concurrently -k -r \"tsc -b --watch --preserveWatchOutput\" \"wtr --watch --coverage --group default\"",
39
+ "build": "rimraf dist && mkdir dist && npm run extract && npm run localize && npm run analyze -- --exclude dist && tsc ",
40
+ "bundle": "rimraf dist && npm run extract && npm run localize && rollup -c rollup.config.js",
41
+ "start": "npm run build && concurrently -k \"tsc --watch --preserveWatchOutput\" \"wds --open '/demo/' --node-resolve\"",
42
+ "start:bundle": "npm run bundle && concurrently -k -r \"rollup -c rollup.config.js --watch\" \"wds --root-dir dist --app-index demo/index.html --open '/demo/' --watch\"",
43
+ "test": "npm run build && wtr --coverage --group unit",
44
+ "test:watch": "npm run build && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wtr --coverage --watch --group unit\"",
45
+ "analyze": "cem analyze --litelement --exclude demo/* --exclude dist/* --exclude *.spec.ts --exclude *.test.ts --exclude coverage/*",
46
+ "doc": "npm run analyze -- --exclude dist && typedoc --out dist/doc src/oscd-shell.ts src/foundation.ts",
47
+ "test:visual": "npm run build && wtr --group visual",
49
48
  "test:update": "npm run build && wtr --group visual --update-visual-baseline",
50
- "analyze": "cem analyze --litelement",
51
- "doc": "npm run analyze -- --exclude dist && typedoc --out dist/doc oscd-shell.ts foundation.ts",
52
- "deploy": "npm run bundle && npm run doc && gh-pages --dist 'dist'",
49
+ "deploy": "npm run bundle && npm run doc && gh-pages --dist 'dist' --nojekyll",
53
50
  "prepare": "husky"
54
51
  },
55
52
  "dependencies": {
56
53
  "@lit/localize": "^0.12.2",
57
- "@omicronenergy/oscd-api": "^0.1.0",
58
54
  "@omicronenergy/oscd-background-editv1": "^0.0.6",
59
- "@omicronenergy/oscd-editor": "^1.5.0",
55
+ "@omicronenergy/oscd-editor": "^1.7.1",
56
+ "@omicronenergy/oscd-menu-commons": "^0.0.1",
60
57
  "@omicronenergy/oscd-menu-open": "^0.0.6",
61
- "@omicronenergy/oscd-menu-save": "^0.0.1",
62
- "@omicronenergy/oscd-test-utils": "^0.0.7",
63
- "@omicronenergy/oscd-ui": "^0.0.4",
64
- "@open-wc/scoped-elements": "^3.0.5",
58
+ "@omicronenergy/oscd-menu-save": "^0.0.2",
59
+ "@omicronenergy/oscd-test-utils": "^0.0.8",
60
+ "@omicronenergy/oscd-ui": "^0.0.9",
61
+ "@open-wc/scoped-elements": "^3.0.6",
62
+ "@openscd/oscd-api": "^0.1.6",
65
63
  "@webcomponents/scoped-custom-element-registry": "^0.0.10",
66
- "lit": "^3.3.0",
67
- "tslib": "^2.6.3"
64
+ "lit": "^3.3.1",
65
+ "tslib": "^2.8.1"
68
66
  },
69
67
  "devDependencies": {
70
68
  "@commitlint/cli": "^19.8.1",
71
69
  "@commitlint/config-conventional": "^19.8.1",
72
- "@custom-elements-manifest/analyzer": "^0.10.4",
70
+ "@custom-elements-manifest/analyzer": "^0.10.5",
71
+ "@eslint/eslintrc": "^3.3.1",
72
+ "@eslint/js": "^9.34.0",
73
73
  "@lit/localize-tools": "^0.8.0",
74
- "@open-wc/building-rollup": "3.0.2",
75
- "@open-wc/eslint-config": "^12.0.3",
74
+ "@open-wc/dev-server-hmr": "^0.2.0",
75
+ "@open-wc/eslint-config": "^13.0.0",
76
76
  "@open-wc/testing": "^4.0.0",
77
- "@rollup/plugin-typescript": "^12.1.2",
77
+ "@rollup/plugin-node-resolve": "^16.0.1",
78
+ "@rollup/plugin-typescript": "^12.1.4",
78
79
  "@types/mocha": "^10.0.10",
79
- "@types/node": "^22.15.18",
80
- "@typescript-eslint/eslint-plugin": "^7.16.0",
81
- "@typescript-eslint/parser": "^7.16.0",
80
+ "@typescript-eslint/eslint-plugin": "^8.41.0",
81
+ "@typescript-eslint/parser": "^8.41.0",
82
+ "@ungap/structured-clone": "^1.3.0",
82
83
  "@web/dev-server": "^0.4.6",
83
- "@web/test-runner": "^0.20.2",
84
- "@web/test-runner-playwright": "^0.11.0",
85
- "@web/test-runner-visual-regression": "^0.9.0",
86
- "concurrently": "^9.1.2",
87
- "es-dev-server": "^2.1.0",
88
- "eslint": "^8.57.0",
89
- "eslint-config-prettier": "^9.1.0",
90
- "eslint-plugin-prettier": "^5.4.1",
84
+ "@web/dev-server-polyfill": "^1.0.6",
85
+ "@web/rollup-plugin-html": "^2.3.0",
86
+ "@web/rollup-plugin-import-meta-assets": "^2.3.0",
87
+ "@web/test-runner": "0.20.2",
88
+ "@web/test-runner-commands": "^0.9.0",
89
+ "@web/test-runner-playwright": "0.11.1",
90
+ "@web/test-runner-visual-regression": "0.9.0",
91
+ "concurrently": "^9.2.1",
92
+ "eslint": "^9.34.0",
93
+ "eslint-config-prettier": "^10.1.8",
94
+ "eslint-plugin-html": "^8.1.3",
95
+ "eslint-plugin-lit": "^2.1.1",
96
+ "eslint-plugin-lit-a11y": "^5.1.1",
97
+ "eslint-plugin-no-only-tests": "^3.3.0",
98
+ "eslint-plugin-prettier": "^5.5.4",
91
99
  "eslint-plugin-tsdoc": "^0.4.0",
92
- "fast-check": "^4.1.1",
100
+ "eslint-plugin-wc": "^3.0.1",
93
101
  "gh-pages": "^6.3.0",
94
102
  "husky": "^9.1.7",
95
- "lint-staged": "^16.1.0",
96
- "prettier": "^3.3.2",
97
- "rollup": "^3.21.0",
103
+ "lint-staged": "^16.1.5",
104
+ "pixelmatch": "^7.1.0",
105
+ "pngjs": "^7.0.0",
106
+ "prettier": "^3.6.2",
107
+ "rimraf": "^6.0.1",
108
+ "rollup": "^4.49.0",
98
109
  "rollup-plugin-copy": "^3.5.0",
99
110
  "sinon": "^21.0.0",
100
111
  "tsdoc": "^0.0.4",
101
- "typedoc": "^0.28.4",
102
- "typescript": "5.5.3"
112
+ "typedoc": "^0.28.11",
113
+ "typescript": "^5.9.2"
103
114
  },
104
115
  "overrides": {
105
- "playwright": {
106
- ".": "1.50.1",
107
- "@web/test-runner-playwright": "0.11.0"
116
+ "@web/test-runner-playwright": {
117
+ "playwright": "1.54.1"
108
118
  }
109
119
  },
110
120
  "customElements": "custom-elements.json",
111
- "eslintConfig": {
112
- "parser": "@typescript-eslint/parser",
113
- "parserOptions": {
114
- "lib": [
115
- "es2018",
116
- "dom"
117
- ]
118
- },
119
- "extends": [
120
- "@open-wc",
121
- "prettier"
122
- ],
123
- "plugins": [
124
- "@typescript-eslint",
125
- "eslint-plugin-tsdoc",
126
- "prettier"
127
- ],
128
- "rules": {
129
- "no-unused-vars": "off",
130
- "class-methods-use-this": [
131
- "error",
132
- {
133
- "exceptMethods": [
134
- "locale"
135
- ]
136
- }
137
- ],
138
- "@typescript-eslint/no-explicit-any": [
139
- "error",
140
- {
141
- "ignoreRestArgs": true
142
- }
143
- ],
144
- "import/no-extraneous-dependencies": [
145
- "error",
146
- {
147
- "devDependencies": [
148
- "**/*.test.ts",
149
- "**/*.spec.ts",
150
- "./dist"
151
- ]
152
- }
153
- ],
154
- "curly": [
155
- "error",
156
- "all"
157
- ],
158
- "@typescript-eslint/no-unused-vars": [
159
- "error",
160
- {
161
- "argsIgnorePattern": "^_",
162
- "varsIgnorePattern": "^_",
163
- "destructuredArrayIgnorePattern": "^_"
164
- }
165
- ],
166
- "import/no-unresolved": "off",
167
- "import/extensions": [
168
- "error",
169
- "always",
170
- {
171
- "ignorePackages": true
172
- }
173
- ],
174
- "prettier/prettier": "error"
175
- },
176
- "overrides": [
177
- {
178
- "files": [
179
- "**/*.spec.ts",
180
- "**/*.test.ts"
181
- ],
182
- "rules": {
183
- "no-unused-expressions": "off"
184
- }
185
- }
186
- ]
187
- },
188
121
  "prettier": {
189
122
  "singleQuote": true,
190
123
  "arrowParens": "avoid"
@@ -195,6 +128,9 @@
195
128
  }
196
129
  },
197
130
  "lint-staged": {
198
- "*.ts": "npm run format"
131
+ "*.ts": [
132
+ "eslint --fix",
133
+ "eslint"
134
+ ]
199
135
  }
200
136
  }