@nsxbet/admin-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +680 -0
- package/dist/auth/client/in-memory.d.ts +27 -0
- package/dist/auth/client/in-memory.d.ts.map +1 -0
- package/dist/auth/client/in-memory.js +242 -0
- package/dist/auth/client/index.d.ts +7 -0
- package/dist/auth/client/index.d.ts.map +1 -0
- package/dist/auth/client/index.js +7 -0
- package/dist/auth/client/interface.d.ts +115 -0
- package/dist/auth/client/interface.d.ts.map +1 -0
- package/dist/auth/client/interface.js +7 -0
- package/dist/auth/client/keycloak.d.ts +19 -0
- package/dist/auth/client/keycloak.d.ts.map +1 -0
- package/dist/auth/client/keycloak.js +126 -0
- package/dist/auth/components/UserSelector.d.ts +19 -0
- package/dist/auth/components/UserSelector.d.ts.map +1 -0
- package/dist/auth/components/UserSelector.js +100 -0
- package/dist/auth/components/index.d.ts +5 -0
- package/dist/auth/components/index.d.ts.map +1 -0
- package/dist/auth/components/index.js +4 -0
- package/dist/auth/index.d.ts +7 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +7 -0
- package/dist/components/AuthProvider.d.ts +48 -0
- package/dist/components/AuthProvider.d.ts.map +1 -0
- package/dist/components/AuthProvider.js +117 -0
- package/dist/hooks/useAuth.d.ts +21 -0
- package/dist/hooks/useAuth.d.ts.map +1 -0
- package/dist/hooks/useAuth.js +34 -0
- package/dist/hooks/useFetch.d.ts +8 -0
- package/dist/hooks/useFetch.d.ts.map +1 -0
- package/dist/hooks/useFetch.js +31 -0
- package/dist/hooks/useI18n.d.ts +46 -0
- package/dist/hooks/useI18n.d.ts.map +1 -0
- package/dist/hooks/useI18n.js +95 -0
- package/dist/hooks/usePlatformAPI.d.ts +12 -0
- package/dist/hooks/usePlatformAPI.d.ts.map +1 -0
- package/dist/hooks/usePlatformAPI.js +10 -0
- package/dist/hooks/useTelemetry.d.ts +17 -0
- package/dist/hooks/useTelemetry.d.ts.map +1 -0
- package/dist/hooks/useTelemetry.js +36 -0
- package/dist/i18n/config.d.ts +26 -0
- package/dist/i18n/config.d.ts.map +1 -0
- package/dist/i18n/config.js +92 -0
- package/dist/i18n/index.d.ts +6 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +4 -0
- package/dist/i18n/locales/en-US.json +144 -0
- package/dist/i18n/locales/es.json +144 -0
- package/dist/i18n/locales/pt-BR.json +144 -0
- package/dist/i18n/locales/ro.json +144 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/registry/AdminShellRegistry.d.ts +140 -0
- package/dist/registry/AdminShellRegistry.d.ts.map +1 -0
- package/dist/registry/AdminShellRegistry.js +237 -0
- package/dist/registry/client/http.d.ts +21 -0
- package/dist/registry/client/http.d.ts.map +1 -0
- package/dist/registry/client/http.js +107 -0
- package/dist/registry/client/in-memory.d.ts +36 -0
- package/dist/registry/client/in-memory.d.ts.map +1 -0
- package/dist/registry/client/in-memory.js +242 -0
- package/dist/registry/client/index.d.ts +7 -0
- package/dist/registry/client/index.d.ts.map +1 -0
- package/dist/registry/client/index.js +5 -0
- package/dist/registry/client/interface.d.ts +96 -0
- package/dist/registry/client/interface.d.ts.map +1 -0
- package/dist/registry/client/interface.js +7 -0
- package/dist/registry/index.d.ts +12 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +8 -0
- package/dist/registry/types/index.d.ts +9 -0
- package/dist/registry/types/index.d.ts.map +1 -0
- package/dist/registry/types/index.js +6 -0
- package/dist/registry/types/manifest.d.ts +98 -0
- package/dist/registry/types/manifest.d.ts.map +1 -0
- package/dist/registry/types/manifest.js +81 -0
- package/dist/registry/types/module.d.ts +115 -0
- package/dist/registry/types/module.d.ts.map +1 -0
- package/dist/registry/types/module.js +6 -0
- package/dist/router/DynamicModule.d.ts +50 -0
- package/dist/router/DynamicModule.d.ts.map +1 -0
- package/dist/router/DynamicModule.js +141 -0
- package/dist/router/index.d.ts +2 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +1 -0
- package/dist/shell/AdminShell.d.ts +38 -0
- package/dist/shell/AdminShell.d.ts.map +1 -0
- package/dist/shell/AdminShell.js +299 -0
- package/dist/shell/BackofficeShell.d.ts +38 -0
- package/dist/shell/BackofficeShell.d.ts.map +1 -0
- package/dist/shell/BackofficeShell.js +299 -0
- package/dist/shell/components/CommandPalette.d.ts +8 -0
- package/dist/shell/components/CommandPalette.d.ts.map +1 -0
- package/dist/shell/components/CommandPalette.js +197 -0
- package/dist/shell/components/HomePage.d.ts +2 -0
- package/dist/shell/components/HomePage.d.ts.map +1 -0
- package/dist/shell/components/HomePage.js +32 -0
- package/dist/shell/components/LeftNav.d.ts +7 -0
- package/dist/shell/components/LeftNav.d.ts.map +1 -0
- package/dist/shell/components/LeftNav.js +247 -0
- package/dist/shell/components/MainContent.d.ts +9 -0
- package/dist/shell/components/MainContent.d.ts.map +1 -0
- package/dist/shell/components/MainContent.js +88 -0
- package/dist/shell/components/ModuleOverview.d.ts +7 -0
- package/dist/shell/components/ModuleOverview.d.ts.map +1 -0
- package/dist/shell/components/ModuleOverview.js +40 -0
- package/dist/shell/components/ProfilePage.d.ts +2 -0
- package/dist/shell/components/ProfilePage.d.ts.map +1 -0
- package/dist/shell/components/ProfilePage.js +30 -0
- package/dist/shell/components/RegistryPage.d.ts +8 -0
- package/dist/shell/components/RegistryPage.d.ts.map +1 -0
- package/dist/shell/components/RegistryPage.js +129 -0
- package/dist/shell/components/SettingsPage.d.ts +2 -0
- package/dist/shell/components/SettingsPage.d.ts.map +1 -0
- package/dist/shell/components/SettingsPage.js +60 -0
- package/dist/shell/components/TopBar.d.ts +8 -0
- package/dist/shell/components/TopBar.d.ts.map +1 -0
- package/dist/shell/components/TopBar.js +61 -0
- package/dist/shell/components/index.d.ts +10 -0
- package/dist/shell/components/index.d.ts.map +1 -0
- package/dist/shell/components/index.js +7 -0
- package/dist/shell/components/theme-provider.d.ts +15 -0
- package/dist/shell/components/theme-provider.d.ts.map +1 -0
- package/dist/shell/components/theme-provider.js +39 -0
- package/dist/shell/index.d.ts +9 -0
- package/dist/shell/index.d.ts.map +1 -0
- package/dist/shell/index.js +8 -0
- package/dist/shell/search/fuzzy.d.ts +18 -0
- package/dist/shell/search/fuzzy.d.ts.map +1 -0
- package/dist/shell/search/fuzzy.js +121 -0
- package/dist/shell/search/index.d.ts +3 -0
- package/dist/shell/search/index.d.ts.map +1 -0
- package/dist/shell/search/index.js +1 -0
- package/dist/shell/telemetry.d.ts +7 -0
- package/dist/shell/telemetry.d.ts.map +1 -0
- package/dist/shell/telemetry.js +25 -0
- package/dist/shell/types.d.ts +110 -0
- package/dist/shell/types.d.ts.map +1 -0
- package/dist/shell/types.js +4 -0
- package/dist/tailwind/index.d.ts +20 -0
- package/dist/tailwind/index.d.ts.map +1 -0
- package/dist/tailwind/index.js +42 -0
- package/dist/types/keycloak.d.ts +26 -0
- package/dist/types/keycloak.d.ts.map +1 -0
- package/dist/types/keycloak.js +1 -0
- package/dist/types/platform.d.ts +83 -0
- package/dist/types/platform.d.ts.map +1 -0
- package/dist/types/platform.js +5 -0
- package/dist/vite/config.d.ts +71 -0
- package/dist/vite/config.d.ts.map +1 -0
- package/dist/vite/config.js +87 -0
- package/dist/vite/index.d.ts +18 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +17 -0
- package/dist/vite/plugins.d.ts +44 -0
- package/dist/vite/plugins.d.ts.map +1 -0
- package/dist/vite/plugins.js +74 -0
- package/package.json +86 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registered Module Types
|
|
3
|
+
*
|
|
4
|
+
* Types for modules that have been registered in the registry.
|
|
5
|
+
*/
|
|
6
|
+
import type { AdminModuleManifest } from './manifest';
|
|
7
|
+
/**
|
|
8
|
+
* A module that has been registered in the registry
|
|
9
|
+
*/
|
|
10
|
+
export interface RegisteredModule {
|
|
11
|
+
/** Auto-increment ID */
|
|
12
|
+
id: number;
|
|
13
|
+
/** Module identifier from manifest (e.g., "@admin/tasks") */
|
|
14
|
+
moduleId: string;
|
|
15
|
+
/** Base URL where the module is hosted */
|
|
16
|
+
baseUrl: string;
|
|
17
|
+
/** Full parsed module.manifest.json (without entry - fetched at runtime) */
|
|
18
|
+
manifest: AdminModuleManifest;
|
|
19
|
+
/** Admin-controlled navigation order */
|
|
20
|
+
navOrder: number;
|
|
21
|
+
/** Whether the module is enabled */
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
/** ISO timestamp when registered */
|
|
24
|
+
registeredAt: string;
|
|
25
|
+
/** ISO timestamp when last updated */
|
|
26
|
+
updatedAt: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* DTO for updating a registered module
|
|
30
|
+
* Only admin-controlled fields can be updated
|
|
31
|
+
*/
|
|
32
|
+
export interface UpdateModuleDto {
|
|
33
|
+
/** Update navigation order */
|
|
34
|
+
navOrder?: number;
|
|
35
|
+
/** Enable or disable the module */
|
|
36
|
+
enabled?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* DTO for reordering modules
|
|
40
|
+
*/
|
|
41
|
+
export interface ReorderModuleDto {
|
|
42
|
+
/** Module ID */
|
|
43
|
+
id: number;
|
|
44
|
+
/** New navigation order */
|
|
45
|
+
navOrder: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Filters for listing modules
|
|
49
|
+
*/
|
|
50
|
+
export interface ModuleFilters {
|
|
51
|
+
/** Filter by enabled status */
|
|
52
|
+
enabled?: boolean;
|
|
53
|
+
/** Filter by category */
|
|
54
|
+
category?: string;
|
|
55
|
+
/** Filter by status */
|
|
56
|
+
status?: 'active' | 'deprecated' | 'disabled';
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Catalog structure for shell consumption (denormalized)
|
|
60
|
+
*/
|
|
61
|
+
export interface Catalog {
|
|
62
|
+
/** Version identifier */
|
|
63
|
+
version: string;
|
|
64
|
+
/** Timestamp when generated */
|
|
65
|
+
generatedAt: string;
|
|
66
|
+
/** Array of modules in catalog format */
|
|
67
|
+
modules: CatalogModule[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Module in catalog format (denormalized for shell)
|
|
71
|
+
* Note: entry is not included - DynamicModule fetches module.manifest.json at runtime
|
|
72
|
+
*/
|
|
73
|
+
export interface CatalogModule {
|
|
74
|
+
id: string;
|
|
75
|
+
title: string;
|
|
76
|
+
/** i18n key for the title (for translation) */
|
|
77
|
+
titleKey?: string;
|
|
78
|
+
description: string;
|
|
79
|
+
/** i18n key for the description (for translation) */
|
|
80
|
+
descriptionKey?: string;
|
|
81
|
+
category: string;
|
|
82
|
+
routeBase: string;
|
|
83
|
+
/** Base URL where the module is hosted */
|
|
84
|
+
baseUrl: string;
|
|
85
|
+
keywords: string[];
|
|
86
|
+
permissions: {
|
|
87
|
+
view: string[];
|
|
88
|
+
dangerous?: string[];
|
|
89
|
+
};
|
|
90
|
+
owners: {
|
|
91
|
+
team: string;
|
|
92
|
+
supportChannel: string;
|
|
93
|
+
};
|
|
94
|
+
status: 'active' | 'deprecated' | 'disabled';
|
|
95
|
+
navOrder?: number;
|
|
96
|
+
icon?: string;
|
|
97
|
+
commands?: Array<{
|
|
98
|
+
id: string;
|
|
99
|
+
title: string;
|
|
100
|
+
/** i18n key for the title (for translation) */
|
|
101
|
+
titleKey?: string;
|
|
102
|
+
keywords?: string[];
|
|
103
|
+
route: string;
|
|
104
|
+
icon?: string;
|
|
105
|
+
}>;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Import map structure for dynamic module loading
|
|
109
|
+
*/
|
|
110
|
+
export interface ImportMap {
|
|
111
|
+
imports: {
|
|
112
|
+
[moduleName: string]: string;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../src/registry/types/module.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,+BAA+B;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,MAAM,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,UAAU,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC;IACF,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,MAAM,EAAE,QAAQ,GAAG,YAAY,GAAG,UAAU,CAAC;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC;QACf,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,+CAA+C;QAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE;QACP,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;KAC9B,CAAC;CACH"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Component, type ReactNode } from "react";
|
|
2
|
+
interface DynamicModuleProps {
|
|
3
|
+
/** Base URL where the module is hosted (e.g., "http://localhost:5001") */
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
/** Module global name (e.g., "TasksAdminModule") - if not provided, uses ES import */
|
|
6
|
+
globalName?: string;
|
|
7
|
+
/** Custom loading fallback */
|
|
8
|
+
fallback?: ReactNode;
|
|
9
|
+
/** Custom error fallback */
|
|
10
|
+
errorFallback?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Loading spinner shown while module is being fetched
|
|
14
|
+
*/
|
|
15
|
+
declare function ModuleLoading(): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
/**
|
|
17
|
+
* Error boundary for catching module load errors
|
|
18
|
+
*/
|
|
19
|
+
interface ErrorBoundaryProps {
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
fallback?: ReactNode;
|
|
22
|
+
onRetry?: () => void;
|
|
23
|
+
}
|
|
24
|
+
interface ErrorBoundaryState {
|
|
25
|
+
hasError: boolean;
|
|
26
|
+
error?: Error;
|
|
27
|
+
}
|
|
28
|
+
declare class ModuleErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
29
|
+
constructor(props: ErrorBoundaryProps);
|
|
30
|
+
static getDerivedStateFromError(error: Error): ErrorBoundaryState;
|
|
31
|
+
componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;
|
|
32
|
+
handleRetry: () => void;
|
|
33
|
+
render(): string | number | boolean | Iterable<ReactNode> | import("react/jsx-runtime").JSX.Element | null | undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* DynamicModule - Loads a module from a URL using React.lazy
|
|
37
|
+
*
|
|
38
|
+
* This component:
|
|
39
|
+
* 1. Fetches module.manifest.json from baseUrl to get the hashed entry path
|
|
40
|
+
* 2. Loads the module JS file using React.lazy
|
|
41
|
+
* 3. Keeps the module in the shell's React tree for shared Router context
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```tsx
|
|
45
|
+
* <DynamicModule baseUrl="http://localhost:5001" />
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function DynamicModule({ baseUrl, globalName, fallback, errorFallback, }: DynamicModuleProps): import("react/jsx-runtime").JSX.Element;
|
|
49
|
+
export { ModuleLoading, ModuleErrorBoundary };
|
|
50
|
+
//# sourceMappingURL=DynamicModule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DynamicModule.d.ts","sourceRoot":"","sources":["../../src/router/DynamicModule.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA2B,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG3E,UAAU,kBAAkB;IAC1B,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,4BAA4B;IAC5B,aAAa,CAAC,EAAE,SAAS,CAAC;CAC3B;AAUD;;GAEG;AACH,iBAAS,aAAa,4CAerB;AAED;;GAEG;AACH,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,cAAM,mBAAoB,SAAQ,SAAS,CACzC,kBAAkB,EAClB,kBAAkB,CACnB;gBACa,KAAK,EAAE,kBAAkB;IAKrC,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,kBAAkB;IAIjE,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS;IAI1D,WAAW,aAGT;IAEF,MAAM;CAkEP;AA0DD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,UAAU,EACV,QAAQ,EACR,aAAa,GACd,EAAE,kBAAkB,2CAsDpB;AAED,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Suspense, lazy, useMemo, Component } from "react";
|
|
3
|
+
import { Icon, Card, CardContent, Button } from "@nsxbet/admin-ui";
|
|
4
|
+
/**
|
|
5
|
+
* Loading spinner shown while module is being fetched
|
|
6
|
+
*/
|
|
7
|
+
function ModuleLoading() {
|
|
8
|
+
return (_jsxs("div", { "data-testid": "module-loading", className: "flex flex-col items-center justify-center h-full min-h-[300px] gap-4", children: [_jsx("div", { className: "inline-flex p-4 rounded-full bg-primary/10", children: _jsx(Icon, { name: "loader-2", className: "h-8 w-8 text-primary animate-spin" }) }), _jsxs("div", { className: "text-center", children: [_jsx("p", { className: "text-lg font-medium", children: "Loading module..." }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Please wait while the module is being loaded" })] })] }));
|
|
9
|
+
}
|
|
10
|
+
class ModuleErrorBoundary extends Component {
|
|
11
|
+
constructor(props) {
|
|
12
|
+
super(props);
|
|
13
|
+
Object.defineProperty(this, "handleRetry", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: () => {
|
|
18
|
+
this.setState({ hasError: false, error: undefined });
|
|
19
|
+
this.props.onRetry?.();
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
this.state = { hasError: false };
|
|
23
|
+
}
|
|
24
|
+
static getDerivedStateFromError(error) {
|
|
25
|
+
return { hasError: true, error };
|
|
26
|
+
}
|
|
27
|
+
componentDidCatch(error, errorInfo) {
|
|
28
|
+
console.error("[DynamicModule] Failed to load module:", error, errorInfo);
|
|
29
|
+
}
|
|
30
|
+
render() {
|
|
31
|
+
if (this.state.hasError) {
|
|
32
|
+
if (this.props.fallback) {
|
|
33
|
+
return this.props.fallback;
|
|
34
|
+
}
|
|
35
|
+
const errorMessage = this.state.error?.message || "An unexpected error occurred";
|
|
36
|
+
const isNetworkError = errorMessage.includes("Failed to fetch") ||
|
|
37
|
+
errorMessage.includes("NetworkError") ||
|
|
38
|
+
errorMessage.includes("Failed to load script");
|
|
39
|
+
return (_jsx("div", { "data-testid": "module-error", className: "flex items-center justify-center h-full min-h-[300px] p-6", children: _jsx(Card, { className: "max-w-md w-full", children: _jsx(CardContent, { className: "pt-6", children: _jsxs("div", { className: "flex flex-col items-center text-center gap-4", children: [_jsx("div", { className: "inline-flex p-4 rounded-full bg-destructive/10", children: _jsx(Icon, { name: isNetworkError ? "wifi-off" : "alert-triangle", className: "h-8 w-8 text-destructive" }) }), _jsxs("div", { children: [_jsx("h3", { className: "text-lg font-semibold mb-1", children: isNetworkError ? "Module Unavailable" : "Failed to Load Module" }), _jsx("p", { className: "text-sm text-muted-foreground mb-2", children: isNetworkError
|
|
40
|
+
? "The module server is not responding. Please ensure the module is running."
|
|
41
|
+
: "An error occurred while loading the module." }), _jsx("p", { className: "text-xs font-mono text-muted-foreground bg-muted p-2 rounded break-all", children: errorMessage })] }), _jsx("div", { className: "flex gap-2", children: _jsxs(Button, { "data-testid": "module-retry-button", onClick: this.handleRetry, variant: "default", children: [_jsx(Icon, { name: "refresh-cw", className: "h-4 w-4 mr-2" }), "Try Again"] }) }), isNetworkError && (_jsx("p", { className: "text-xs text-muted-foreground", children: "Tip: Run the module dev server or check your network connection." }))] }) }) }) }));
|
|
42
|
+
}
|
|
43
|
+
return this.props.children;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Load a script and return the global it exposes
|
|
48
|
+
*/
|
|
49
|
+
function loadScript(url, globalName) {
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
52
|
+
const win = window;
|
|
53
|
+
// Check if already loaded
|
|
54
|
+
if (win[globalName]) {
|
|
55
|
+
resolve(win[globalName]);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const script = document.createElement("script");
|
|
59
|
+
script.src = url;
|
|
60
|
+
script.async = true;
|
|
61
|
+
script.onload = () => {
|
|
62
|
+
const moduleExport = win[globalName];
|
|
63
|
+
if (moduleExport) {
|
|
64
|
+
resolve(moduleExport);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
reject(new Error(`Global "${globalName}" not found after loading ${url}`));
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
script.onerror = () => {
|
|
71
|
+
reject(new Error(`Failed to load script: ${url}`));
|
|
72
|
+
};
|
|
73
|
+
document.head.appendChild(script);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Fetch module manifest to get the entry path
|
|
78
|
+
*/
|
|
79
|
+
async function fetchModuleEntry(baseUrl) {
|
|
80
|
+
const manifestUrl = `${baseUrl}/module.manifest.json`;
|
|
81
|
+
console.log(`[DynamicModule] Fetching manifest from ${manifestUrl}`);
|
|
82
|
+
const response = await fetch(manifestUrl);
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
throw new Error(`Failed to fetch manifest from ${manifestUrl}: ${response.status}`);
|
|
85
|
+
}
|
|
86
|
+
const manifest = await response.json();
|
|
87
|
+
if (!manifest.entry) {
|
|
88
|
+
throw new Error(`Manifest at ${manifestUrl} is missing required 'entry' field`);
|
|
89
|
+
}
|
|
90
|
+
return manifest.entry;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* DynamicModule - Loads a module from a URL using React.lazy
|
|
94
|
+
*
|
|
95
|
+
* This component:
|
|
96
|
+
* 1. Fetches module.manifest.json from baseUrl to get the hashed entry path
|
|
97
|
+
* 2. Loads the module JS file using React.lazy
|
|
98
|
+
* 3. Keeps the module in the shell's React tree for shared Router context
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```tsx
|
|
102
|
+
* <DynamicModule baseUrl="http://localhost:5001" />
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export function DynamicModule({ baseUrl, globalName, fallback, errorFallback, }) {
|
|
106
|
+
// Normalize baseUrl (remove trailing slash)
|
|
107
|
+
const normalizedUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
108
|
+
// Create lazy component - memoized to avoid re-creating on every render
|
|
109
|
+
const ModuleComponent = useMemo(() => lazy(async () => {
|
|
110
|
+
try {
|
|
111
|
+
// Step 1: Fetch manifest to get entry path
|
|
112
|
+
const entry = await fetchModuleEntry(normalizedUrl);
|
|
113
|
+
// Step 2: Load the module
|
|
114
|
+
const moduleUrl = `${normalizedUrl}/${entry}`;
|
|
115
|
+
console.log(`[DynamicModule] Loading module from ${moduleUrl}`);
|
|
116
|
+
let moduleExport;
|
|
117
|
+
if (globalName) {
|
|
118
|
+
// IIFE format: load script and get global
|
|
119
|
+
moduleExport = await loadScript(moduleUrl, globalName);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
// ES module format: use dynamic import
|
|
123
|
+
moduleExport = await import(/* @vite-ignore */ moduleUrl);
|
|
124
|
+
}
|
|
125
|
+
console.log(`[DynamicModule] Module loaded successfully`);
|
|
126
|
+
// Handle both default export and direct component
|
|
127
|
+
const mod = moduleExport;
|
|
128
|
+
const Component = (mod.default || mod.App || mod);
|
|
129
|
+
if (typeof Component !== "function") {
|
|
130
|
+
throw new Error("Module must export a default component or named App export");
|
|
131
|
+
}
|
|
132
|
+
return { default: Component };
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
console.error(`[DynamicModule] Failed to load module:`, error);
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
}), [normalizedUrl, globalName]);
|
|
139
|
+
return (_jsx(ModuleErrorBoundary, { fallback: errorFallback, children: _jsx(Suspense, { fallback: fallback ?? _jsx(ModuleLoading, {}), children: _jsx(ModuleComponent, {}) }) }));
|
|
140
|
+
}
|
|
141
|
+
export { ModuleLoading, ModuleErrorBoundary };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/router/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DynamicModule, ModuleLoading, ModuleErrorBoundary } from "./DynamicModule";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { AuthClient } from "../auth/client/interface";
|
|
2
|
+
import type { AdminModuleManifest, RegistryClient } from "../registry";
|
|
3
|
+
export interface AdminShellProps {
|
|
4
|
+
/**
|
|
5
|
+
* Module manifests to load (used for standalone mode when no registryClient)
|
|
6
|
+
* In standalone mode, modules are rendered via children prop
|
|
7
|
+
*/
|
|
8
|
+
modules?: AdminModuleManifest[];
|
|
9
|
+
/**
|
|
10
|
+
* Content to render for standalone module development.
|
|
11
|
+
* Only used in standalone mode (when modules prop is provided)
|
|
12
|
+
*/
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* Keycloak configuration
|
|
16
|
+
* If not provided, uses in-memory (mock) authentication
|
|
17
|
+
*/
|
|
18
|
+
keycloak?: {
|
|
19
|
+
url: string;
|
|
20
|
+
realm: string;
|
|
21
|
+
clientId: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Auth client to use for authentication.
|
|
25
|
+
* If not provided, creates one based on keycloak prop or environment.
|
|
26
|
+
*/
|
|
27
|
+
authClient?: AuthClient;
|
|
28
|
+
/** Registry client for fetching modules from API */
|
|
29
|
+
registryClient?: RegistryClient;
|
|
30
|
+
/** API URL for registry management (e.g., "http://localhost:4000/api") */
|
|
31
|
+
apiUrl?: string;
|
|
32
|
+
/** Use in-memory registry (default: true, ignored if registryClient is provided) */
|
|
33
|
+
inMemoryRegistry?: boolean;
|
|
34
|
+
/** Environment (default: "local") */
|
|
35
|
+
environment?: string;
|
|
36
|
+
}
|
|
37
|
+
export declare function AdminShell({ modules: manifests, children, keycloak, authClient: providedAuthClient, registryClient, apiUrl, inMemoryRegistry, environment, }: AdminShellProps): import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
//# sourceMappingURL=AdminShell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminShell.d.ts","sourceRoot":"","sources":["../../src/shell/AdminShell.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAiB,MAAM,aAAa,CAAC;AAMtF,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE;QACT,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF;;;OAGG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,oDAAoD;IACpD,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oFAAoF;IACpF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA8RD,wBAAgB,UAAU,CAAC,EACzB,OAAO,EAAE,SAAc,EACvB,QAAQ,EACR,QAAQ,EACR,UAAU,EAAE,kBAAkB,EAC9B,cAAc,EACd,MAAM,EACN,gBAAuB,EACvB,WAAqB,GACtB,EAAE,eAAe,2CAsLjB"}
|