@linagora/linid-im-front-corelib 0.0.1

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 (43) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.yml +83 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.yml +90 -0
  3. package/.github/ISSUE_TEMPLATE/question.yml +31 -0
  4. package/.github/ISSUE_TEMPLATE/security.yml +69 -0
  5. package/.github/actions/setup-node-pnpm/action.yml +29 -0
  6. package/.github/workflows/pull-request.yml +122 -0
  7. package/.github/workflows/release.yml +85 -0
  8. package/.prettierignore +7 -0
  9. package/.prettierrc.json +5 -0
  10. package/.vscode/extensions.json +3 -0
  11. package/.vscode/settings.json +9 -0
  12. package/CONTRIBUTING.md +264 -0
  13. package/COPYRIGHT +23 -0
  14. package/LICENSE.md +482 -0
  15. package/README.md +107 -0
  16. package/dist/core-lib.es.js +3045 -0
  17. package/dist/core-lib.umd.js +12 -0
  18. package/dist/package.json +74 -0
  19. package/dist/types/src/components/LinidZoneRenderer.vue.d.ts +19 -0
  20. package/dist/types/src/index.d.ts +7 -0
  21. package/dist/types/src/lifecycle/skeleton.d.ts +100 -0
  22. package/dist/types/src/services/federationService.d.ts +11 -0
  23. package/dist/types/src/stores/linidZoneStore.d.ts +23 -0
  24. package/dist/types/src/types/linidZone.d.ts +21 -0
  25. package/dist/types/src/types/module.d.ts +63 -0
  26. package/dist/types/src/types/moduleLifecycle.d.ts +121 -0
  27. package/dist/types/vite.config.d.ts +2 -0
  28. package/docs/components-plugin-zones.md +168 -0
  29. package/docs/helpers.md +188 -0
  30. package/docs/module-lifecycle.md +874 -0
  31. package/docs/types-and-interfaces.md +92 -0
  32. package/eslint.config.js +135 -0
  33. package/package.json +73 -0
  34. package/src/components/LinidZoneRenderer.vue +77 -0
  35. package/src/index.ts +51 -0
  36. package/src/lifecycle/skeleton.ts +154 -0
  37. package/src/services/federationService.ts +44 -0
  38. package/src/stores/linidZoneStore.ts +62 -0
  39. package/src/types/linidZone.ts +48 -0
  40. package/src/types/module.ts +96 -0
  41. package/src/types/moduleLifecycle.ts +163 -0
  42. package/tsconfig.json +30 -0
  43. package/vite.config.ts +42 -0
@@ -0,0 +1,92 @@
1
+ # TypeScript Types & Interfaces đź§©
2
+
3
+ This document explains the **types and interfaces** used in `linid-im-front-corelib`.
4
+
5
+ ---
6
+
7
+ ## 🔌 LinidZoneEntry
8
+
9
+ Represents a plugin entry that can be rendered inside a zone.
10
+
11
+ ```ts
12
+ export interface LinidZoneEntry {
13
+ /** Path or identifier of the plugin module */
14
+ plugin: string;
15
+
16
+ /** Props forwarded to the plugin component */
17
+ props?: Record<string, unknown>;
18
+ }
19
+ ```
20
+
21
+ **Usage:**
22
+ All plugins registered to the `Linid Zone Store` must implement this interface.
23
+
24
+ ---
25
+
26
+ ## đź§± LinidZoneState
27
+
28
+ Represents the state of the Pinia store that manages all plugin zones.
29
+
30
+ ```ts
31
+ interface LinidZoneState {
32
+ /** Map of zone names to their registered plugin entries */
33
+ zones: Record<string, LinidZoneEntry[]>;
34
+ }
35
+ ```
36
+
37
+ * `zones` is a reactive object.
38
+ * Each key corresponds to a zone, each value is an array of plugins for that zone.
39
+
40
+ ---
41
+
42
+ ## 📦 RemoteComponentModule
43
+
44
+ Defines the structure of a Vue component module loaded via Module Federation.
45
+
46
+ ```ts
47
+ export interface RemoteComponentModule {
48
+ /** The default exported Vue component */
49
+ default: Component;
50
+ }
51
+ ```
52
+
53
+ **Usage:**
54
+
55
+ Used internally by [`loadAsyncComponent`](./helpers.md#loadasynccomponent) to ensure type safety when loading federated components.
56
+
57
+ **Remote modules must export a default component:**
58
+
59
+ ```vue
60
+ <!-- âś… Correct - .vue file -->
61
+ <template>
62
+ <div>My Component</div>
63
+ </template>
64
+
65
+ <script setup lang="ts">
66
+ // Default export is automatic
67
+ </script>
68
+ ```
69
+
70
+ ```typescript
71
+ // ❌ Wrong - named export only
72
+ export const MyComponent = defineComponent({ /* ... */ });
73
+
74
+ // âś… Correct - default export
75
+ export default defineComponent({ /* ... */ });
76
+ ```
77
+
78
+ ---
79
+
80
+ ## đź§° Summary
81
+
82
+ | Type / Interface | Purpose |
83
+ | ----------------------- | ----------------------------------------------------- |
84
+ | `LinidZoneEntry` | Defines the contract for a plugin component |
85
+ | `LinidZoneState` | Defines the structure of the zone store |
86
+ | `RemoteComponentModule` | Defines the structure of a federated component module |
87
+
88
+ These types enforce **consistency and type safety** across all front-end modules and plugins.
89
+
90
+ ---
91
+
92
+ > Additional types and interfaces will be added as new features are implemented in the library.
@@ -0,0 +1,135 @@
1
+ import js from '@eslint/js';
2
+ import prettierSkipFormatting from '@vue/eslint-config-prettier/skip-formatting';
3
+ import {
4
+ defineConfigWithVueTs,
5
+ vueTsConfigs,
6
+ } from '@vue/eslint-config-typescript';
7
+ import jsdoc from 'eslint-plugin-jsdoc';
8
+ import vue from 'eslint-plugin-vue';
9
+ import headers from 'eslint-plugin-headers';
10
+
11
+ export default defineConfigWithVueTs(
12
+ {
13
+ ignores: [
14
+ 'dist/',
15
+ 'coverage/',
16
+ '**/vite.config.*.timestamp*',
17
+ '**/vitest.config.*.timestamp*',
18
+ ],
19
+ },
20
+ js.configs.recommended,
21
+ vueTsConfigs.recommended,
22
+ vue.configs['flat/recommended'],
23
+ jsdoc.configs['flat/recommended-typescript'],
24
+ prettierSkipFormatting,
25
+ {
26
+ files: ['**/*.{js,mjs,cjs}'],
27
+ languageOptions: {
28
+ globals: {
29
+ process: 'readonly',
30
+ },
31
+ },
32
+ },
33
+ {
34
+ files: ['**/*.{js,mjs,cjs,ts,vue}'],
35
+ rules: {
36
+ // Vue rules
37
+ 'vue/multi-word-component-names': 'off',
38
+ 'vue/require-default-prop': 'error',
39
+ 'vue/require-prop-types': 'error',
40
+ 'vue/component-api-style': ['error', ['script-setup']],
41
+ 'vue/max-attributes-per-line': 'error',
42
+
43
+ // TypeScript rules
44
+ '@typescript-eslint/no-explicit-any': 'warn',
45
+ '@typescript-eslint/no-unused-vars': [
46
+ 'error',
47
+ {
48
+ argsIgnorePattern: '^_',
49
+ varsIgnorePattern: '^_',
50
+ },
51
+ ],
52
+ '@typescript-eslint/consistent-type-imports': 'error',
53
+
54
+ // JSDoc rules
55
+ 'jsdoc/require-jsdoc': [
56
+ 'error',
57
+ {
58
+ require: {
59
+ ArrowFunctionExpression: false,
60
+ ClassDeclaration: true,
61
+ ClassExpression: true,
62
+ FunctionExpression: true,
63
+ MethodDefinition: true,
64
+ },
65
+ contexts: [
66
+ 'TSInterfaceDeclaration',
67
+ 'TSTypeAliasDeclaration',
68
+ 'TSEnumDeclaration',
69
+ 'TSPropertySignature',
70
+ 'TSModuleDeclaration VariableDeclaration',
71
+ 'VariableDeclaration > VariableDeclarator > ArrowFunctionExpression',
72
+ ],
73
+ },
74
+ ],
75
+ 'jsdoc/check-tag-names': 'error',
76
+ 'jsdoc/check-types': 'error',
77
+ 'jsdoc/check-param-names': 'error',
78
+ 'jsdoc/require-description': 'warn',
79
+ 'jsdoc/require-description-complete-sentence': 'error',
80
+
81
+ // General rules
82
+ 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
83
+ 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
84
+ curly: 'error',
85
+ 'arrow-body-style': ['error', 'as-needed'],
86
+ },
87
+ },
88
+ {
89
+ files: ['src/**/*.vue'],
90
+ plugins: {
91
+ headers,
92
+ },
93
+ rules: {
94
+ 'headers/header-format': [
95
+ 'error',
96
+ {
97
+ source: 'file',
98
+ path: 'COPYRIGHT',
99
+ trailingNewlines: 2,
100
+ enableVueSupport: true,
101
+ },
102
+ ],
103
+ },
104
+ },
105
+ {
106
+ files: ['src/**/*.{ts,js}'],
107
+ plugins: {
108
+ headers,
109
+ },
110
+ rules: {
111
+ 'headers/header-format': [
112
+ 'error',
113
+ {
114
+ source: 'file',
115
+ path: 'COPYRIGHT',
116
+ blockPrefix: '\n',
117
+ trailingNewlines: 2,
118
+ },
119
+ ],
120
+ },
121
+ },
122
+ {
123
+ files: [
124
+ '**/*.test.ts',
125
+ '**/*.spec.ts',
126
+ '**/__tests__/**',
127
+ '**/*.config.*',
128
+ '**/*.config.*',
129
+ ],
130
+ rules: {
131
+ 'jsdoc/require-jsdoc': 'off',
132
+ 'headers/header-format': 'off',
133
+ },
134
+ }
135
+ );
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@linagora/linid-im-front-corelib",
3
+ "version": "0.0.1",
4
+ "description": "Core library of the LinID Identity Manager project. Provides shared types, services, components, and utilities for front-end and plugin, enabling consistent integration across the LinID ecosystem.",
5
+ "type": "module",
6
+ "main": "dist/core-lib.umd.js",
7
+ "module": "dist/core-lib.es.js",
8
+ "types": "dist/types/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./src/index.ts",
12
+ "types": "./src/index.ts"
13
+ }
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/linagora/linid-im-front-corelib.git"
18
+ },
19
+ "contributors": [
20
+ {
21
+ "name": "Vincent Moittie",
22
+ "email": "moittie.vincent@gmail.com",
23
+ "url": "https://github.com/Zorin95670"
24
+ },
25
+ {
26
+ "name": "Jordy Cabannes",
27
+ "email": "jcabannes@linagora.com",
28
+ "url": "https://github.com/jcabannes"
29
+ },
30
+ {
31
+ "name": "Christophe Chevalier",
32
+ "email": "cchevalier@linagora.com",
33
+ "url": "https://github.com/christophechevalier"
34
+ }
35
+ ],
36
+ "license": "AGPL-3.0-only",
37
+ "bugs": {
38
+ "url": "https://github.com/linagora/linid-im-front-corelib/issues"
39
+ },
40
+ "homepage": "https://github.com/linagora/linid-im-front-corelib#readme",
41
+ "peerDependencies": {
42
+ "@module-federation/enhanced": "0.21.4",
43
+ "pinia": "3.0.4",
44
+ "vue": "3.5.24"
45
+ },
46
+ "devDependencies": {
47
+ "@eslint/js": "9.39.1",
48
+ "@types/node": "20.19.9",
49
+ "@vitejs/plugin-vue": "6.0.1",
50
+ "@vue/eslint-config-prettier": "10.2.0",
51
+ "@vue/eslint-config-typescript": "14.6.0",
52
+ "eslint": "9.39.1",
53
+ "eslint-plugin-headers": "1.3.3",
54
+ "eslint-plugin-jsdoc": "61.2.1",
55
+ "eslint-plugin-vue": "10.5.1",
56
+ "prettier": "3.6.2",
57
+ "typescript": "5.9.3",
58
+ "vite": "7.2.2",
59
+ "vitest": "4.0.8",
60
+ "vue-tsc": "3.1.3"
61
+ },
62
+ "scripts": {
63
+ "build": "vite build && vue-tsc --declaration --emitDeclarationOnly",
64
+ "test": "vitest",
65
+ "dev": "vite",
66
+ "lint": "eslint . --max-warnings 0",
67
+ "lint:fix": "eslint . --fix",
68
+ "format": "prettier --write \"src/**/*.{js,ts,vue,json,css,scss,md}\"",
69
+ "format:check": "prettier --check \"src/**/*.{js,ts,vue,json,css,scss,md}\"",
70
+ "type-check": "vue-tsc --noEmit",
71
+ "validate": "pnpm type-check && pnpm lint && pnpm format:check"
72
+ }
73
+ }
@@ -0,0 +1,77 @@
1
+ <!--
2
+ Copyright (C) 2025 Linagora
3
+
4
+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
5
+ Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option)
6
+ any later version, provided you comply with the Additional Terms applicable for LinID Identity Manager software by
7
+ LINAGORA pursuant to Section 7 of the GNU Affero General Public License, subsections (b), (c), and (e), pursuant to
8
+ which these Appropriate Legal Notices must notably (i) retain the display of the "LinID™" trademark/logo at the top
9
+ of the interface window, the display of the “You are using the Open Source and free version of LinID™, powered by
10
+ Linagora © 2009–2013. Contribute to LinID R&D by subscribing to an Enterprise offer!” infobox and in the e-mails
11
+ sent with the Program, notice appended to any type of outbound messages (e.g. e-mail and meeting requests) as well
12
+ as in the LinID Identity Manager user interface, (ii) retain all hypertext links between LinID Identity Manager
13
+ and https://linid.org/, as well as between LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA
14
+ intellectual property rights over its trademarks and commercial brands. Other Additional Terms apply, see
15
+ <http://www.linagora.com/licenses/> for more details.
16
+
17
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
18
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
19
+ details.
20
+
21
+ You should have received a copy of the GNU Affero General Public License and its applicable Additional Terms for
22
+ LinID Identity Manager along with this program. If not, see <http://www.gnu.org/licenses/> for the GNU Affero
23
+ General Public License version 3 and <http://www.linagora.com/licenses/> for the Additional Terms applicable to the
24
+ LinID Identity Manager software.
25
+ -->
26
+
27
+ <template>
28
+ <component
29
+ :is="entry.component"
30
+ v-for="(entry, index) in components"
31
+ :key="entry.plugin + index"
32
+ v-bind="entry.props"
33
+ />
34
+ <slot v-if="isLoadingComplete && components.length === 0">
35
+ <div>No components to render in this zone.</div>
36
+ </slot>
37
+ </template>
38
+
39
+ <script setup lang="ts">
40
+ import { ref, watchEffect } from 'vue';
41
+ import { loadAsyncComponent } from '../services/federationService';
42
+ import { useLinidZoneStore } from '../stores/linidZoneStore';
43
+ import type { LinidZoneEntry } from '../types/linidZone';
44
+
45
+ const props = defineProps<{
46
+ /**
47
+ * The zone identifier where to render components.
48
+ */
49
+ zone: string;
50
+ }>();
51
+ const linidZoneStore = useLinidZoneStore();
52
+
53
+ const components = ref<
54
+ ({
55
+ /**
56
+ * The component to render.
57
+ */
58
+ component: unknown;
59
+ } & LinidZoneEntry)[]
60
+ >([]);
61
+
62
+ const isLoadingComplete = ref(false);
63
+
64
+ watchEffect(() => {
65
+ isLoadingComplete.value = false;
66
+
67
+ const entries = linidZoneStore.zones[props.zone] || [];
68
+ components.value = entries.map((entry) => ({
69
+ ...entry,
70
+ component: loadAsyncComponent(entry.plugin),
71
+ }));
72
+
73
+ Promise.resolve().then(() => {
74
+ isLoadingComplete.value = true;
75
+ });
76
+ });
77
+ </script>
package/src/index.ts ADDED
@@ -0,0 +1,51 @@
1
+ /*
2
+ * Copyright (C) 2025 Linagora
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
5
+ * Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option)
6
+ * any later version, provided you comply with the Additional Terms applicable for LinID Identity Manager software by
7
+ * LINAGORA pursuant to Section 7 of the GNU Affero General Public License, subsections (b), (c), and (e), pursuant to
8
+ * which these Appropriate Legal Notices must notably (i) retain the display of the "LinID™" trademark/logo at the top
9
+ * of the interface window, the display of the “You are using the Open Source and free version of LinID™, powered by
10
+ * Linagora © 2009–2013. Contribute to LinID R&D by subscribing to an Enterprise offer!” infobox and in the e-mails
11
+ * sent with the Program, notice appended to any type of outbound messages (e.g. e-mail and meeting requests) as well
12
+ * as in the LinID Identity Manager user interface, (ii) retain all hypertext links between LinID Identity Manager
13
+ * and https://linid.org/, as well as between LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA
14
+ * intellectual property rights over its trademarks and commercial brands. Other Additional Terms apply, see
15
+ * <http://www.linagora.com/licenses/> for more details.
16
+ *
17
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
18
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
19
+ * details.
20
+ *
21
+ * You should have received a copy of the GNU Affero General Public License and its applicable Additional Terms for
22
+ * LinID Identity Manager along with this program. If not, see <http://www.gnu.org/licenses/> for the GNU Affero
23
+ * General Public License version 3 and <http://www.linagora.com/licenses/> for the Additional Terms applicable to the
24
+ * LinID Identity Manager software.
25
+ */
26
+
27
+ // Components
28
+ export { default as LinidZoneRenderer } from './components/LinidZoneRenderer.vue';
29
+
30
+ // Stores
31
+ export { useLinidZoneStore } from './stores/linidZoneStore';
32
+
33
+ // Types - Zones
34
+ export type { LinidZoneEntry } from './types/linidZone';
35
+
36
+ export type {
37
+ ModuleHostConfig,
38
+ RemoteComponentModule,
39
+ RemoteModule,
40
+ } from './types/module';
41
+
42
+ // Types - Module Lifecycle
43
+ export type {
44
+ ModuleLifecycleHooks,
45
+ ModuleLifecycleResult,
46
+ } from './types/moduleLifecycle';
47
+
48
+ export { ModuleLifecyclePhase } from './types/moduleLifecycle';
49
+
50
+ // Lifecycle Base Class
51
+ export { BasicRemoteModule } from './lifecycle/skeleton';
@@ -0,0 +1,154 @@
1
+ /*
2
+ * Copyright (C) 2025 Linagora
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
5
+ * Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option)
6
+ * any later version, provided you comply with the Additional Terms applicable for LinID Identity Manager software by
7
+ * LINAGORA pursuant to Section 7 of the GNU Affero General Public License, subsections (b), (c), and (e), pursuant to
8
+ * which these Appropriate Legal Notices must notably (i) retain the display of the "LinID™" trademark/logo at the top
9
+ * of the interface window, the display of the “You are using the Open Source and free version of LinID™, powered by
10
+ * Linagora © 2009–2013. Contribute to LinID R&D by subscribing to an Enterprise offer!” infobox and in the e-mails
11
+ * sent with the Program, notice appended to any type of outbound messages (e.g. e-mail and meeting requests) as well
12
+ * as in the LinID Identity Manager user interface, (ii) retain all hypertext links between LinID Identity Manager
13
+ * and https://linid.org/, as well as between LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA
14
+ * intellectual property rights over its trademarks and commercial brands. Other Additional Terms apply, see
15
+ * <http://www.linagora.com/licenses/> for more details.
16
+ *
17
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
18
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
19
+ * details.
20
+ *
21
+ * You should have received a copy of the GNU Affero General Public License and its applicable Additional Terms for
22
+ * LinID Identity Manager along with this program. If not, see <http://www.gnu.org/licenses/> for the GNU Affero
23
+ * General Public License version 3 and <http://www.linagora.com/licenses/> for the Additional Terms applicable to the
24
+ * LinID Identity Manager software.
25
+ */
26
+
27
+ import type { App } from 'vue';
28
+ import type { ModuleHostConfig, RemoteModule } from '../types/module';
29
+ import type { ModuleLifecycleResult } from '../types/moduleLifecycle';
30
+
31
+ /**
32
+ * Basic implementation of a remote module lifecycle.
33
+ *
34
+ * This class provides default implementations for all lifecycle hooks,
35
+ * allowing business modules to extend it and override only the hooks they need.
36
+ *
37
+ * All lifecycle hooks are optional and return success by default.
38
+ */
39
+ export class BasicRemoteModule implements RemoteModule {
40
+ /**
41
+ * Unique identifier for the module.
42
+ *
43
+ * Must match the ID in the host configuration.
44
+ */
45
+ public readonly id: string;
46
+
47
+ /**
48
+ * Human-readable name of the module.
49
+ */
50
+ public readonly name: string;
51
+
52
+ /**
53
+ * Version of the module (semantic versioning).
54
+ */
55
+ public readonly version: string;
56
+
57
+ /**
58
+ * Optional description of what the module does.
59
+ */
60
+ public readonly description?: string;
61
+
62
+ /**
63
+ * Creates a new remote module instance.
64
+ * @param id - Unique module identifier (kebab-case).
65
+ * @param name - Human-readable module name.
66
+ * @param version - Module version (semver).
67
+ * @param description - Optional module description.
68
+ */
69
+ constructor(id: string, name: string, version: string, description?: string) {
70
+ this.id = id;
71
+ this.name = name;
72
+ this.version = version;
73
+ this.description = description;
74
+ }
75
+
76
+ /**
77
+ * Setup phase - validate dependencies and prepare the module.
78
+ *
79
+ * This is called first, before any other lifecycle phase.
80
+ * Use it to check if all required dependencies are available.
81
+ *
82
+ * Default implementation returns success.
83
+ * Override this method to add custom setup logic.
84
+ * @param _app - The Vue application instance.
85
+ * @returns Promise resolving to the lifecycle result.
86
+ */
87
+ async onSetup(_app: App): Promise<ModuleLifecycleResult> {
88
+ return { success: true };
89
+ }
90
+
91
+ /**
92
+ * Configure phase - receive and validate host configuration.
93
+ *
94
+ * This is called after setup, before initialization.
95
+ * Use it to receive and validate the configuration from the host.
96
+ *
97
+ * Default implementation returns success.
98
+ * Override this method to add custom configuration logic.
99
+ * @param _app - The Vue application instance.
100
+ * @param _config - Module-specific configuration from host.
101
+ * @returns Promise resolving to the lifecycle result.
102
+ */
103
+ async onConfigure(
104
+ _app: App,
105
+ _config: ModuleHostConfig
106
+ ): Promise<ModuleLifecycleResult> {
107
+ return { success: true };
108
+ }
109
+
110
+ /**
111
+ * Initialize phase - register stores and initialize resources.
112
+ *
113
+ * This is called after configuration.
114
+ * Use it to register Pinia stores and initialize module resources.
115
+ *
116
+ * Default implementation returns success.
117
+ * Override this method to add custom initialization logic.
118
+ * @param _app - The Vue application instance.
119
+ * @returns Promise resolving to the lifecycle result.
120
+ */
121
+ async onInitialize(_app: App): Promise<ModuleLifecycleResult> {
122
+ return { success: true };
123
+ }
124
+
125
+ /**
126
+ * Ready phase - signal that the module is ready for use.
127
+ *
128
+ * This is called after all modules are initialized.
129
+ * Use it to perform final checks and emit ready state.
130
+ *
131
+ * Default implementation returns success.
132
+ * Override this method to add custom ready logic.
133
+ * @param _app - The Vue application instance.
134
+ * @returns Promise resolving to the lifecycle result.
135
+ */
136
+ async onReady(_app: App): Promise<ModuleLifecycleResult> {
137
+ return { success: true };
138
+ }
139
+
140
+ /**
141
+ * Post-initialization phase - cross-module integrations.
142
+ *
143
+ * This is called after all modules are ready.
144
+ * Use it for cross-module integrations and final setup.
145
+ *
146
+ * Default implementation returns success.
147
+ * Override this method to add custom post-init logic.
148
+ * @param _app - The Vue application instance.
149
+ * @returns Promise resolving to the lifecycle result.
150
+ */
151
+ async onPostInit(_app: App): Promise<ModuleLifecycleResult> {
152
+ return { success: true };
153
+ }
154
+ }
@@ -0,0 +1,44 @@
1
+ /*
2
+ * Copyright (C) 2025 Linagora
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
5
+ * Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option)
6
+ * any later version, provided you comply with the Additional Terms applicable for LinID Identity Manager software by
7
+ * LINAGORA pursuant to Section 7 of the GNU Affero General Public License, subsections (b), (c), and (e), pursuant to
8
+ * which these Appropriate Legal Notices must notably (i) retain the display of the "LinID™" trademark/logo at the top
9
+ * of the interface window, the display of the “You are using the Open Source and free version of LinID™, powered by
10
+ * Linagora © 2009–2013. Contribute to LinID R&D by subscribing to an Enterprise offer!” infobox and in the e-mails
11
+ * sent with the Program, notice appended to any type of outbound messages (e.g. e-mail and meeting requests) as well
12
+ * as in the LinID Identity Manager user interface, (ii) retain all hypertext links between LinID Identity Manager
13
+ * and https://linid.org/, as well as between LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA
14
+ * intellectual property rights over its trademarks and commercial brands. Other Additional Terms apply, see
15
+ * <http://www.linagora.com/licenses/> for more details.
16
+ *
17
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
18
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
19
+ * details.
20
+ *
21
+ * You should have received a copy of the GNU Affero General Public License and its applicable Additional Terms for
22
+ * LinID Identity Manager along with this program. If not, see <http://www.gnu.org/licenses/> for the GNU Affero
23
+ * General Public License version 3 and <http://www.linagora.com/licenses/> for the Additional Terms applicable to the
24
+ * LinID Identity Manager software.
25
+ */
26
+
27
+ import { loadRemote } from '@module-federation/enhanced/runtime';
28
+ import { defineAsyncComponent } from 'vue';
29
+ import type { RemoteComponentModule } from '../types/module';
30
+
31
+ /**
32
+ * Loads a remote component using the module federation enhanced runtime.
33
+ * @param plugin - The name of the remote plugin component to load.
34
+ * @returns A Vue async component.
35
+ */
36
+ export const loadAsyncComponent = (plugin: string) =>
37
+ defineAsyncComponent(() =>
38
+ loadRemote<RemoteComponentModule>(plugin).then((module) => {
39
+ if (!module?.default) {
40
+ throw new Error(`Failed to load component from ${plugin}`);
41
+ }
42
+ return module.default;
43
+ })
44
+ );