@kosdev-code/kos-ui-plugin 2.1.17 → 2.1.19
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/documentation-generator-CAlVz5vA.cjs +266 -0
- package/documentation-generator-CAlVz5vA.cjs.map +1 -0
- package/documentation-generator-Di4c9D9P.js +2337 -0
- package/documentation-generator-Di4c9D9P.js.map +1 -0
- package/index.cjs +69 -69
- package/index.cjs.map +1 -1
- package/index.d.ts +1 -0
- package/index.d.ts.map +1 -1
- package/index.js +817 -753
- package/index.js.map +1 -1
- package/lib/components/dynamic-component/dynamic-component.d.ts +69 -0
- package/lib/components/dynamic-component/dynamic-component.d.ts.map +1 -1
- package/lib/contexts/index.d.ts +1 -0
- package/lib/contexts/index.d.ts.map +1 -1
- package/lib/contexts/plugins-provider/plugins-provider.d.ts.map +1 -1
- package/lib/contexts/reactive-extension-registry-context.d.ts +10 -0
- package/lib/contexts/reactive-extension-registry-context.d.ts.map +1 -0
- package/lib/hooks/index.d.ts +4 -2
- package/lib/hooks/index.d.ts.map +1 -1
- package/lib/hooks/use-dynamic-component.d.ts +12 -1
- package/lib/hooks/use-dynamic-component.d.ts.map +1 -1
- package/lib/hooks/use-extension-point.d.ts +95 -0
- package/lib/hooks/use-extension-point.d.ts.map +1 -0
- package/lib/hooks/use-reactive-extension-registry.d.ts +20 -0
- package/lib/hooks/use-reactive-extension-registry.d.ts.map +1 -0
- package/lib/hooks/use-typed-extensions.d.ts.map +1 -1
- package/lib/utils/contribution-registry.d.ts +170 -0
- package/lib/utils/contribution-registry.d.ts.map +1 -0
- package/lib/utils/extension-points/extension-point-registry.d.ts.map +1 -1
- package/lib/utils/extension-points/extension-point-schemas.d.ts +4 -4
- package/lib/utils/index.d.ts +3 -0
- package/lib/utils/index.d.ts.map +1 -1
- package/lib/utils/plugin-system/plugin-extension-manager.d.ts.map +1 -1
- package/lib/utils/processors/initialize-plugins.d.ts.map +1 -1
- package/lib/utils/reactive-extension-registry.d.ts +140 -0
- package/lib/utils/reactive-extension-registry.d.ts.map +1 -0
- package/lib/webpack/index.d.ts +2 -0
- package/lib/webpack/index.d.ts.map +1 -1
- package/lib/webpack/with-plugin-dev-aggregator.d.ts +94 -0
- package/lib/webpack/with-plugin-dev-aggregator.d.ts.map +1 -0
- package/lib/webpack/with-plugin-dev-server.d.ts +113 -0
- package/lib/webpack/with-plugin-dev-server.d.ts.map +1 -0
- package/package.json +2 -2
- package/types/contribution-enablement.d.ts +293 -0
- package/types/contribution-enablement.d.ts.map +1 -0
- package/types/plugins.d.ts +8 -0
- package/utils.cjs +1 -1
- package/utils.cjs.map +1 -1
- package/utils.js +29 -291
- package/utils.js.map +1 -1
- package/webpack.cjs +3 -12
- package/webpack.cjs.map +1 -1
- package/webpack.js +455 -727
- package/webpack.js.map +1 -1
- package/documentation-generator-DFaIDo0E.cjs +0 -266
- package/documentation-generator-DFaIDo0E.cjs.map +0 -1
- package/documentation-generator-auruIa_o.js +0 -1560
- package/documentation-generator-auruIa_o.js.map +0 -1
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { PluginExtension, PluginExtensionsType } from '../../types/plugins';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Event emitted when extension point changes
|
|
5
|
+
*/
|
|
6
|
+
export interface ExtensionPointChangeEvent {
|
|
7
|
+
extensionPoint: string;
|
|
8
|
+
changeType: "contribution-enabled" | "contribution-disabled" | "best-changed";
|
|
9
|
+
affectedContribution: string;
|
|
10
|
+
newBest?: string;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Reactive extension registry that monitors contribution state
|
|
15
|
+
*
|
|
16
|
+
* Bridges the gap between ContributionRegistry (state management) and
|
|
17
|
+
* React components by providing filtered extension lists and change notifications.
|
|
18
|
+
*
|
|
19
|
+
* This registry:
|
|
20
|
+
* - Filters extensions based on enabled state
|
|
21
|
+
* - Subscribes to ContributionRegistry for state changes
|
|
22
|
+
* - Emits ExtensionPointChangeEvent when contributions change
|
|
23
|
+
* - Manages extension point-scoped subscriptions
|
|
24
|
+
* - Handles cleanup to prevent memory leaks
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const registry = new ReactiveExtensionRegistry(extensions);
|
|
29
|
+
*
|
|
30
|
+
* // Get only enabled extensions
|
|
31
|
+
* const enabledExtensions = registry.getExtensions('ddk.settings.view');
|
|
32
|
+
*
|
|
33
|
+
* // Subscribe to changes
|
|
34
|
+
* const unsubscribe = registry.subscribe('ddk.settings.view', (event) => {
|
|
35
|
+
* console.log('Extension point changed:', event);
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* // Cleanup when done
|
|
39
|
+
* registry.destroy();
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare class ReactiveExtensionRegistry {
|
|
43
|
+
/**
|
|
44
|
+
* Reference to all plugin extensions (unfiltered)
|
|
45
|
+
*/
|
|
46
|
+
private extensions;
|
|
47
|
+
/**
|
|
48
|
+
* Map of extension point to listeners
|
|
49
|
+
* Each extension point can have multiple components listening for changes
|
|
50
|
+
*/
|
|
51
|
+
private listeners;
|
|
52
|
+
/**
|
|
53
|
+
* Unsubscribe function for ContributionRegistry subscription
|
|
54
|
+
* Used during cleanup to remove listener
|
|
55
|
+
*/
|
|
56
|
+
private contributionUnsubscribe;
|
|
57
|
+
constructor(extensions: PluginExtensionsType);
|
|
58
|
+
/**
|
|
59
|
+
* Get extensions for an extension point (filtered by enabled state)
|
|
60
|
+
*
|
|
61
|
+
* By default, only returns enabled contributions. Use `includeDisabled: true`
|
|
62
|
+
* to get all contributions regardless of state.
|
|
63
|
+
*
|
|
64
|
+
* @param extensionPoint - Extension point identifier
|
|
65
|
+
* @param includeDisabled - If true, include disabled contributions (default: false)
|
|
66
|
+
* @returns Record of extension ID to extension object
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* // Get only enabled settings extensions
|
|
71
|
+
* const enabled = registry.getExtensions('ddk.settings.view');
|
|
72
|
+
*
|
|
73
|
+
* // Get all settings extensions (including disabled)
|
|
74
|
+
* const all = registry.getExtensions('ddk.settings.view', true);
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
getExtensions(extensionPoint: string, includeDisabled?: boolean): Record<string, PluginExtension>;
|
|
78
|
+
/**
|
|
79
|
+
* Subscribe to changes for a specific extension point
|
|
80
|
+
*
|
|
81
|
+
* Registers a listener that will be called whenever contributions for
|
|
82
|
+
* the specified extension point change state (enabled/disabled) or when
|
|
83
|
+
* the best contribution for that point changes.
|
|
84
|
+
*
|
|
85
|
+
* @param extensionPoint - Extension point identifier to monitor
|
|
86
|
+
* @param listener - Callback function to handle change events
|
|
87
|
+
* @returns Unsubscribe function to stop receiving events
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* const unsubscribe = registry.subscribe('ddk.settings.view', (event) => {
|
|
92
|
+
* if (event.changeType === 'best-changed') {
|
|
93
|
+
* console.log('New best contribution:', event.newBest);
|
|
94
|
+
* }
|
|
95
|
+
* });
|
|
96
|
+
*
|
|
97
|
+
* // Later...
|
|
98
|
+
* unsubscribe();
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
subscribe(extensionPoint: string, listener: (event: ExtensionPointChangeEvent) => void): () => void;
|
|
102
|
+
/**
|
|
103
|
+
* Internal: Subscribe to contribution state changes
|
|
104
|
+
*
|
|
105
|
+
* Sets up subscription to ContributionRegistry to receive notifications
|
|
106
|
+
* when any contribution's enabled state changes. Routes these events to
|
|
107
|
+
* extension point-specific listeners.
|
|
108
|
+
*
|
|
109
|
+
* @private
|
|
110
|
+
*/
|
|
111
|
+
private subscribeToContributionChanges;
|
|
112
|
+
/**
|
|
113
|
+
* Internal: Handle contribution state change
|
|
114
|
+
*
|
|
115
|
+
* Called when ContributionRegistry emits a state change event.
|
|
116
|
+
* Determines if the "best" contribution has changed and emits
|
|
117
|
+
* ExtensionPointChangeEvent to all listeners for that extension point.
|
|
118
|
+
*
|
|
119
|
+
* @param event - Contribution state change event from ContributionRegistry
|
|
120
|
+
* @private
|
|
121
|
+
*/
|
|
122
|
+
private handleContributionChange;
|
|
123
|
+
/**
|
|
124
|
+
* Cleanup subscriptions and listeners
|
|
125
|
+
*
|
|
126
|
+
* Call this when the registry is no longer needed to prevent memory leaks.
|
|
127
|
+
* Typically called when the PluginsProvider is unmounted.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* useEffect(() => {
|
|
132
|
+
* const registry = new ReactiveExtensionRegistry(extensions);
|
|
133
|
+
* // Use registry...
|
|
134
|
+
* return () => registry.destroy();
|
|
135
|
+
* }, []);
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
destroy(): void;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=reactive-extension-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactive-extension-registry.d.ts","sourceRoot":"","sources":["../../../../../../packages/sdk/kos-ui-plugin/src/lib/utils/reactive-extension-registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EACrB,MAAM,qBAAqB,CAAC;AAI7B;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,sBAAsB,GAAG,uBAAuB,GAAG,cAAc,CAAC;IAC9E,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,yBAAyB;IACpC;;OAEG;IACH,OAAO,CAAC,UAAU,CAAuB;IAEzC;;;OAGG;IACH,OAAO,CAAC,SAAS,CAGf;IAEF;;;OAGG;IACH,OAAO,CAAC,uBAAuB,CAA6B;gBAEhD,UAAU,EAAE,oBAAoB;IAM5C;;;;;;;;;;;;;;;;;;OAkBG;IACH,aAAa,CACX,cAAc,EAAE,MAAM,EACtB,eAAe,UAAQ,GACtB,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC;IAgBlC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,SAAS,CACP,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,IAAI,GACnD,MAAM,IAAI;IAuBb;;;;;;;;OAQG;IACH,OAAO,CAAC,8BAA8B;IAMtC;;;;;;;;;OASG;IACH,OAAO,CAAC,wBAAwB;IA6ChC;;;;;;;;;;;;;;OAcG;IACH,OAAO,IAAI,IAAI;CAQhB"}
|
package/lib/webpack/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Plugin Development Mode Aggregation Middleware
|
|
3
|
+
*
|
|
4
|
+
* This webpack composable aggregates metadata from multiple plugin dev servers
|
|
5
|
+
* running on different ports, combining them into a single response at the
|
|
6
|
+
* `/api/kos/ui/plugins/contexts` endpoint.
|
|
7
|
+
*
|
|
8
|
+
* This allows a host app to load multiple plugins simultaneously during development.
|
|
9
|
+
*/
|
|
10
|
+
export interface PluginDevAggregatorOptions {
|
|
11
|
+
/**
|
|
12
|
+
* List of plugin dev server URLs to aggregate.
|
|
13
|
+
* Example: ['http://localhost:4201', 'http://localhost:4202']
|
|
14
|
+
*/
|
|
15
|
+
pluginServers: string[];
|
|
16
|
+
/**
|
|
17
|
+
* Include the host app's own .kos.json plugin definitions.
|
|
18
|
+
* Default: true
|
|
19
|
+
*/
|
|
20
|
+
includeHostPlugins?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Path to the host app's .kos.json file.
|
|
23
|
+
* Default: './.kos.json'
|
|
24
|
+
*/
|
|
25
|
+
kosJsonPath?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Merge backend plugins with local dev plugins.
|
|
28
|
+
* When true, fetches plugins from backend and overlays local dev plugins on top.
|
|
29
|
+
* Local dev plugins get overrides pointing to dev servers.
|
|
30
|
+
* Backend plugins use their original URLs (no overrides).
|
|
31
|
+
*
|
|
32
|
+
* This is useful for third-party developers who want to:
|
|
33
|
+
* - Run against a production DDK backend
|
|
34
|
+
* - Load DDK base plugins from the backend
|
|
35
|
+
* - Develop their own custom plugins locally
|
|
36
|
+
*
|
|
37
|
+
* Default: false (local-only mode)
|
|
38
|
+
*/
|
|
39
|
+
mergeWithBackend?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Fallback to backend if no local plugin servers are available.
|
|
42
|
+
* Default: true
|
|
43
|
+
*/
|
|
44
|
+
fallbackToBackend?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Backend URL to fallback to when no plugin servers available.
|
|
47
|
+
* Default: 'http://localhost:8081'
|
|
48
|
+
*/
|
|
49
|
+
backendUrl?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Enable verbose logging for debugging.
|
|
52
|
+
* Default: false
|
|
53
|
+
*/
|
|
54
|
+
verbose?: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Webpack plugin composable that aggregates multiple plugin dev servers.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* // Host app webpack.config.ts
|
|
62
|
+
* import { withPluginDevAggregator } from '@kosdev-code/kos-ui-plugin/webpack';
|
|
63
|
+
*
|
|
64
|
+
* export default composePlugins(
|
|
65
|
+
* withNx(),
|
|
66
|
+
* withReact({}),
|
|
67
|
+
* withPluginDevAggregator({
|
|
68
|
+
* pluginServers: [
|
|
69
|
+
* 'http://localhost:4201', // beverage-pour
|
|
70
|
+
* 'http://localhost:4202' // kos-ddk-standard-plugin
|
|
71
|
+
* ]
|
|
72
|
+
* })
|
|
73
|
+
* );
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @example With environment variables
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const pluginServers = [
|
|
79
|
+
* process.env.PLUGIN_A_DEV === 'true' && 'http://localhost:4201',
|
|
80
|
+
* process.env.PLUGIN_B_DEV === 'true' && 'http://localhost:4202',
|
|
81
|
+
* ].filter(Boolean);
|
|
82
|
+
*
|
|
83
|
+
* export default composePlugins(
|
|
84
|
+
* withNx(),
|
|
85
|
+
* withReact({}),
|
|
86
|
+
* withPluginDevAggregator({
|
|
87
|
+
* pluginServers,
|
|
88
|
+
* fallbackToBackend: pluginServers.length === 0
|
|
89
|
+
* })
|
|
90
|
+
* );
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export declare const withPluginDevAggregator: (options: PluginDevAggregatorOptions) => (config: any, context: any) => any;
|
|
94
|
+
//# sourceMappingURL=with-plugin-dev-aggregator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with-plugin-dev-aggregator.d.ts","sourceRoot":"","sources":["../../../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-plugin-dev-aggregator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,aAAa,EAAE,MAAM,EAAE,CAAC;IAExB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,uBAAuB,YACzB,0BAA0B,cAYnB,GAAG,WAAW,GAAG,QA8VlC,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration options for plugin development server middleware
|
|
3
|
+
*/
|
|
4
|
+
export interface PluginDevServerOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Path to .kos.json file, relative to project root.
|
|
7
|
+
* Default: '.kos.json'
|
|
8
|
+
*/
|
|
9
|
+
kosJsonPath?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Project root directory. Used to resolve kosJsonPath.
|
|
12
|
+
* Default: process.cwd()
|
|
13
|
+
*/
|
|
14
|
+
projectRoot?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Default plugin context if not specified in .kos.json test section.
|
|
17
|
+
* Default: 'kosdev.ddk'
|
|
18
|
+
*/
|
|
19
|
+
defaultContext?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Enable verbose logging for debugging.
|
|
22
|
+
* Default: false
|
|
23
|
+
*/
|
|
24
|
+
verbose?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Webpack plugin composable that adds plugin development server middleware.
|
|
28
|
+
*
|
|
29
|
+
* This middleware serves the `/api/kos/ui/plugins/contexts` endpoint, mimicking
|
|
30
|
+
* the backend KOS plugin API response format. It enables local plugin development
|
|
31
|
+
* without requiring backend deployment.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* // webpack.config.ts
|
|
36
|
+
* import { withKosConfig, withPluginDevServer } from '@kosdev-code/kos-ui-plugin/webpack';
|
|
37
|
+
* import { composePlugins, withNx } from '@nx/webpack';
|
|
38
|
+
*
|
|
39
|
+
* export default composePlugins(
|
|
40
|
+
* withNx(),
|
|
41
|
+
* withReact({}),
|
|
42
|
+
* withKosConfig(webpack),
|
|
43
|
+
* withPluginDevServer() // ← Add plugin dev server
|
|
44
|
+
* );
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example With options
|
|
48
|
+
* ```typescript
|
|
49
|
+
* export default composePlugins(
|
|
50
|
+
* withNx(),
|
|
51
|
+
* withReact({}),
|
|
52
|
+
* withKosConfig(webpack),
|
|
53
|
+
* withPluginDevServer({
|
|
54
|
+
* kosJsonPath: '.kos.json',
|
|
55
|
+
* defaultContext: 'kosdev.ddk',
|
|
56
|
+
* verbose: true
|
|
57
|
+
* })
|
|
58
|
+
* );
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* ## .kos.json Structure
|
|
62
|
+
*
|
|
63
|
+
* The middleware reads two sections from .kos.json:
|
|
64
|
+
*
|
|
65
|
+
* ```json
|
|
66
|
+
* {
|
|
67
|
+
* "kos": {
|
|
68
|
+
* "ui": {
|
|
69
|
+
* "plugin": {
|
|
70
|
+
* "id": "MyPlugin",
|
|
71
|
+
* "extensions": [...],
|
|
72
|
+
* "contributes": {...}
|
|
73
|
+
* }
|
|
74
|
+
* }
|
|
75
|
+
* },
|
|
76
|
+
* "test": {
|
|
77
|
+
* "plugin": {
|
|
78
|
+
* "context": "kosdev.ddk"
|
|
79
|
+
* }
|
|
80
|
+
* }
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* - `kos.ui.plugin`: Production plugin descriptor (becomes API `descriptor`)
|
|
85
|
+
* - `test.plugin.context`: Development plugin context/group name
|
|
86
|
+
*
|
|
87
|
+
* ## Response Format
|
|
88
|
+
*
|
|
89
|
+
* The middleware returns the same format as the backend `/api/kos/ui/plugins/contexts`:
|
|
90
|
+
*
|
|
91
|
+
* ```json
|
|
92
|
+
* {
|
|
93
|
+
* "status": 200,
|
|
94
|
+
* "version": {"major": 1, "minor": 0},
|
|
95
|
+
* "data": [
|
|
96
|
+
* {
|
|
97
|
+
* "name": "kosdev.ddk",
|
|
98
|
+
* "plugins": [
|
|
99
|
+
* {
|
|
100
|
+
* "descriptor": { ... },
|
|
101
|
+
* "id": "uuid-v4",
|
|
102
|
+
* "path": "/"
|
|
103
|
+
* }
|
|
104
|
+
* ]
|
|
105
|
+
* }
|
|
106
|
+
* ]
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @param options - Configuration options
|
|
111
|
+
*/
|
|
112
|
+
export declare const withPluginDevServer: (options?: PluginDevServerOptions) => (config: any, context: any) => any;
|
|
113
|
+
//# sourceMappingURL=with-plugin-dev-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with-plugin-dev-server.d.ts","sourceRoot":"","sources":["../../../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-plugin-dev-server.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AACH,eAAO,MAAM,mBAAmB,aAAa,sBAAsB,cAQjD,GAAG,WAAW,GAAG,QAuJlC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kosdev-code/kos-ui-plugin",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.19",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"kos": {
|
|
23
23
|
"build": {
|
|
24
|
-
"gitHash": "
|
|
24
|
+
"gitHash": "6a8e249e4d22e16b7c678edf286c58258f65b6db"
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
"publishConfig": {
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { BaseContribution, PluginExtensionsType, ProcessedContributions } from './plugins';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Enhanced contribution interface with runtime enablement state
|
|
5
|
+
*
|
|
6
|
+
* Extends BaseContribution with fields that enable dynamic runtime control
|
|
7
|
+
* over contribution visibility and availability. This allows plugins to
|
|
8
|
+
* respond to events (feature flags, device state, etc.) and update which
|
|
9
|
+
* contributions are visible to the plugin system.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const contribution: DynamicContribution = {
|
|
14
|
+
* id: 'advanced-settings',
|
|
15
|
+
* remote: 'settingsPlugin',
|
|
16
|
+
* sectionId: 'settings',
|
|
17
|
+
* enabled: true,
|
|
18
|
+
* enabledCondition: (context) => {
|
|
19
|
+
* return context.context?.userRole === 'admin';
|
|
20
|
+
* }
|
|
21
|
+
* };
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export interface DynamicContribution extends BaseContribution {
|
|
25
|
+
/**
|
|
26
|
+
* Whether this contribution is currently enabled
|
|
27
|
+
*
|
|
28
|
+
* When false, the contribution will be filtered out by resolveBestExtension
|
|
29
|
+
* and will not be visible to DynamicComponent or other plugin consumers.
|
|
30
|
+
*
|
|
31
|
+
* @default true
|
|
32
|
+
*/
|
|
33
|
+
enabled: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Optional reason for disabled state
|
|
36
|
+
*
|
|
37
|
+
* Useful for debugging, logging, and displaying to users why a contribution
|
|
38
|
+
* is unavailable. Should be a human-readable string.
|
|
39
|
+
*
|
|
40
|
+
* @example "Feature flag 'advanced-mode' is disabled"
|
|
41
|
+
* @example "User lacks premium license"
|
|
42
|
+
* @example "Device mode: basic"
|
|
43
|
+
*/
|
|
44
|
+
disabledReason?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Optional timestamp when enabled state last changed
|
|
47
|
+
*
|
|
48
|
+
* Unix timestamp (milliseconds) of the last state transition.
|
|
49
|
+
* Useful for debugging, auditing, and temporal queries.
|
|
50
|
+
*
|
|
51
|
+
* @example Date.now() // 1705780800000
|
|
52
|
+
*/
|
|
53
|
+
lastStateChange?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Optional conditional enablement function
|
|
56
|
+
*
|
|
57
|
+
* Evaluated when contribution is accessed via isEnabled().
|
|
58
|
+
* Allows for dynamic enablement based on runtime context.
|
|
59
|
+
*
|
|
60
|
+
* If provided, this function is called in addition to checking the
|
|
61
|
+
* `enabled` boolean field. Both must be true for the contribution
|
|
62
|
+
* to be considered enabled.
|
|
63
|
+
*
|
|
64
|
+
* @param context - Current runtime context including extensions, contributions, and custom data
|
|
65
|
+
* @returns true if contribution should be enabled, false otherwise
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* enabledCondition: (context) => {
|
|
70
|
+
* const licenseModel = context.context?.licenseModel;
|
|
71
|
+
* return licenseModel?.hasPremiumLicense === true;
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
enabledCondition?: (context: EnablementContext) => boolean;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Context provided to enablement condition functions
|
|
79
|
+
*
|
|
80
|
+
* Provides runtime information that enablement conditions can use to
|
|
81
|
+
* determine whether a contribution should be enabled. This includes
|
|
82
|
+
* the current plugin system state and custom application data.
|
|
83
|
+
*/
|
|
84
|
+
export interface EnablementContext {
|
|
85
|
+
/**
|
|
86
|
+
* Current extensions state
|
|
87
|
+
*
|
|
88
|
+
* The full PluginExtensionsType object representing all registered
|
|
89
|
+
* extension points and their contributions.
|
|
90
|
+
*/
|
|
91
|
+
extensions: PluginExtensionsType;
|
|
92
|
+
/**
|
|
93
|
+
* Current contributions state
|
|
94
|
+
*
|
|
95
|
+
* Processed contributions including experiences and other contribution types.
|
|
96
|
+
*/
|
|
97
|
+
contributions: ProcessedContributions;
|
|
98
|
+
/**
|
|
99
|
+
* Custom context data
|
|
100
|
+
*
|
|
101
|
+
* Application-specific context that can be used in enablement conditions.
|
|
102
|
+
* For example, user model, license model, device state, etc.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* {
|
|
107
|
+
* userModel: { role: 'admin', id: '123' },
|
|
108
|
+
* licenseModel: { hasPremiumLicense: true },
|
|
109
|
+
* deviceState: { mode: 'advanced' }
|
|
110
|
+
* }
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
context?: Record<string, any>;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Event emitted when a contribution's enabled state changes
|
|
117
|
+
*
|
|
118
|
+
* This event is emitted by ContributionRegistry whenever setEnabled()
|
|
119
|
+
* or batchUpdate() changes a contribution's state. Listeners can subscribe
|
|
120
|
+
* to these events to react to enablement changes.
|
|
121
|
+
*/
|
|
122
|
+
export interface ContributionStateChangeEvent {
|
|
123
|
+
/**
|
|
124
|
+
* Unique identifier of the contribution that changed
|
|
125
|
+
*/
|
|
126
|
+
contributionId: string;
|
|
127
|
+
/**
|
|
128
|
+
* Extension point this contribution belongs to
|
|
129
|
+
*
|
|
130
|
+
* @example "ddk.features"
|
|
131
|
+
* @example "ddk.settings.view"
|
|
132
|
+
*/
|
|
133
|
+
extensionPoint: string;
|
|
134
|
+
/**
|
|
135
|
+
* New enabled state (true = enabled, false = disabled)
|
|
136
|
+
*/
|
|
137
|
+
enabled: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Previous enabled state before this change
|
|
140
|
+
*/
|
|
141
|
+
previousState: boolean;
|
|
142
|
+
/**
|
|
143
|
+
* Optional reason for the state change
|
|
144
|
+
*
|
|
145
|
+
* @example "Feature flag 'advanced-mode' changed to enabled"
|
|
146
|
+
* @example "App unloaded"
|
|
147
|
+
*/
|
|
148
|
+
reason?: string;
|
|
149
|
+
/**
|
|
150
|
+
* Unix timestamp (milliseconds) when this change occurred
|
|
151
|
+
*/
|
|
152
|
+
timestamp: number;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Centralized contribution enablement registry interface
|
|
156
|
+
*
|
|
157
|
+
* The ContributionRegistry manages the enabled/disabled state of all
|
|
158
|
+
* contributions in the plugin system. It provides methods to:
|
|
159
|
+
* - Update contribution state
|
|
160
|
+
* - Query contribution state
|
|
161
|
+
* - Subscribe to state changes
|
|
162
|
+
* - Perform batch atomic updates
|
|
163
|
+
*
|
|
164
|
+
* This is the primary API for implementing dynamic contribution enablement.
|
|
165
|
+
*/
|
|
166
|
+
export interface IContributionRegistry {
|
|
167
|
+
/**
|
|
168
|
+
* Set enabled state for a contribution
|
|
169
|
+
*
|
|
170
|
+
* Updates the contribution's enabled state and emits a
|
|
171
|
+
* ContributionStateChangeEvent to all subscribers.
|
|
172
|
+
*
|
|
173
|
+
* @param contributionId - Unique identifier of the contribution
|
|
174
|
+
* @param enabled - New enabled state (true = enabled, false = disabled)
|
|
175
|
+
* @param reason - Optional human-readable reason for the change
|
|
176
|
+
*
|
|
177
|
+
* @throws Error if contribution does not exist
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* ContributionRegistry.setEnabled(
|
|
182
|
+
* 'advanced-settings',
|
|
183
|
+
* false,
|
|
184
|
+
* 'Device mode changed to basic'
|
|
185
|
+
* );
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
setEnabled(contributionId: string, enabled: boolean, reason?: string): void;
|
|
189
|
+
/**
|
|
190
|
+
* Get enabled state for a contribution
|
|
191
|
+
*
|
|
192
|
+
* Checks both the enabled boolean field and evaluates any
|
|
193
|
+
* enabledCondition function if present. Returns true only if
|
|
194
|
+
* both checks pass.
|
|
195
|
+
*
|
|
196
|
+
* @param contributionId - Unique identifier of the contribution
|
|
197
|
+
* @returns true if contribution is enabled, false otherwise
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* if (ContributionRegistry.isEnabled('advanced-settings')) {
|
|
202
|
+
* // Show advanced settings UI
|
|
203
|
+
* }
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
isEnabled(contributionId: string): boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Subscribe to all contribution state changes
|
|
209
|
+
*
|
|
210
|
+
* Registers a listener that will be called whenever any contribution's
|
|
211
|
+
* enabled state changes. The listener receives a ContributionStateChangeEvent.
|
|
212
|
+
*
|
|
213
|
+
* @param listener - Callback function to handle state change events
|
|
214
|
+
* @returns Unsubscribe function to stop receiving events
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```typescript
|
|
218
|
+
* const unsubscribe = ContributionRegistry.subscribe((event) => {
|
|
219
|
+
* console.log(`${event.contributionId} ${event.enabled ? 'enabled' : 'disabled'}`);
|
|
220
|
+
* });
|
|
221
|
+
*
|
|
222
|
+
* // Later: stop listening
|
|
223
|
+
* unsubscribe();
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
subscribe(listener: (event: ContributionStateChangeEvent) => void): () => void;
|
|
227
|
+
/**
|
|
228
|
+
* Subscribe to changes for a specific extension point
|
|
229
|
+
*
|
|
230
|
+
* Like subscribe(), but only emits events for contributions
|
|
231
|
+
* belonging to the specified extension point.
|
|
232
|
+
*
|
|
233
|
+
* @param extensionPoint - Extension point identifier to monitor
|
|
234
|
+
* @param listener - Callback function to handle state change events
|
|
235
|
+
* @returns Unsubscribe function to stop receiving events
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* const unsubscribe = ContributionRegistry.subscribeToExtensionPoint(
|
|
240
|
+
* 'ddk.settings.view',
|
|
241
|
+
* (event) => {
|
|
242
|
+
* console.log(`Settings contribution changed: ${event.contributionId}`);
|
|
243
|
+
* }
|
|
244
|
+
* );
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
subscribeToExtensionPoint(extensionPoint: string, listener: (event: ContributionStateChangeEvent) => void): () => void;
|
|
248
|
+
/**
|
|
249
|
+
* Batch update multiple contributions atomically
|
|
250
|
+
*
|
|
251
|
+
* Updates multiple contribution states in a single atomic operation.
|
|
252
|
+
* All updates succeed or all fail together. Emits one event per
|
|
253
|
+
* contribution that changed state.
|
|
254
|
+
*
|
|
255
|
+
* @param updates - Array of contribution updates to apply
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* ```typescript
|
|
259
|
+
* // Disable all advanced features at once
|
|
260
|
+
* ContributionRegistry.batchUpdate([
|
|
261
|
+
* { contributionId: 'advanced-settings', enabled: false, reason: 'Basic mode' },
|
|
262
|
+
* { contributionId: 'diagnostics', enabled: false, reason: 'Basic mode' },
|
|
263
|
+
* { contributionId: 'dev-tools', enabled: false, reason: 'Basic mode' }
|
|
264
|
+
* ]);
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
batchUpdate(updates: Array<{
|
|
268
|
+
contributionId: string;
|
|
269
|
+
enabled: boolean;
|
|
270
|
+
reason?: string;
|
|
271
|
+
}>): void;
|
|
272
|
+
/**
|
|
273
|
+
* Get all contributions for an extension point
|
|
274
|
+
*
|
|
275
|
+
* Returns an array of DynamicContribution objects for the specified
|
|
276
|
+
* extension point. By default, only returns enabled contributions.
|
|
277
|
+
*
|
|
278
|
+
* @param extensionPoint - Extension point identifier
|
|
279
|
+
* @param includeDisabled - If true, include disabled contributions in results
|
|
280
|
+
* @returns Array of contributions for the extension point
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```typescript
|
|
284
|
+
* // Get only enabled settings contributions
|
|
285
|
+
* const enabledSettings = ContributionRegistry.getContributions('ddk.settings.view');
|
|
286
|
+
*
|
|
287
|
+
* // Get all settings contributions (including disabled)
|
|
288
|
+
* const allSettings = ContributionRegistry.getContributions('ddk.settings.view', true);
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
getContributions(extensionPoint: string, includeDisabled?: boolean): DynamicContribution[];
|
|
292
|
+
}
|
|
293
|
+
//# sourceMappingURL=contribution-enablement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contribution-enablement.d.ts","sourceRoot":"","sources":["../../../../../packages/sdk/kos-ui-plugin/src/types/contribution-enablement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,WAAW,CAAC;AAEnB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC3D;;;;;;;OAOG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;;;;;;;;OASG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC;CAC5D;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,UAAU,EAAE,oBAAoB,CAAC;IAEjC;;;;OAIG;IACH,aAAa,EAAE,sBAAsB,CAAC;IAEtC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,UAAU,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5E;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;IAE3C;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAS,CACP,QAAQ,EAAE,CAAC,KAAK,EAAE,4BAA4B,KAAK,IAAI,GACtD,MAAM,IAAI,CAAC;IAEd;;;;;;;;;;;;;;;;;;;OAmBG;IACH,yBAAyB,CACvB,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,4BAA4B,KAAK,IAAI,GACtD,MAAM,IAAI,CAAC;IAEd;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CACT,OAAO,EAAE,KAAK,CAAC;QACb,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,GACD,IAAI,CAAC;IAER;;;;;;;;;;;;;;;;;;OAkBG;IACH,gBAAgB,CACd,cAAc,EAAE,MAAM,EACtB,eAAe,CAAC,EAAE,OAAO,GACxB,mBAAmB,EAAE,CAAC;CAC1B"}
|