@nsxbet/admin-sdk 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -8,13 +8,43 @@ SDK for building admin modules for the NSX Admin platform.
8
8
  bun add @nsxbet/admin-sdk @nsxbet/admin-ui
9
9
  ```
10
10
 
11
- **Peer dependencies** (install these too):
11
+ **Peer dependencies:**
12
12
 
13
13
  ```bash
14
- bun add react react-dom react-router-dom i18next react-i18next
15
- bun add -D @vitejs/plugin-react vite tailwindcss postcss autoprefixer typescript
14
+ # Shared with shell - use exact versions to avoid conflicts
15
+ bun add react@18.2.0 react-dom@18.2.0 react-router-dom@6.20.1 i18next@25.0.0 react-i18next@16.0.0
16
+
17
+ # Styling - use exact versions for design system consistency
18
+ bun add -D tailwindcss@3.4.0 postcss@8.4.32 autoprefixer@10.4.16 tailwindcss-animate@1.0.7
19
+
20
+ # Build tools - flexible versions are fine
21
+ bun add -D @vitejs/plugin-react vite typescript
16
22
  ```
17
23
 
24
+ > **Why exact versions?** React, React Router, and i18next are shared at runtime - mismatches cause conflicts. Tailwind/PostCSS versions ensure consistent styling with the design system.
25
+
26
+ ## Quick Start (CLI)
27
+
28
+ The fastest way to create a new module is using the CLI:
29
+
30
+ ```bash
31
+ # Scaffold a new module
32
+ npx @nsxbet/admin-cli init --id "@admin/my-module" --title "My Module" --route "/my-module" --port 3010
33
+
34
+ # Generate a setup verification checklist
35
+ npx @nsxbet/admin-cli checklist --output CHECKLIST.md
36
+
37
+ # Validate an existing module
38
+ npx @nsxbet/admin-cli check
39
+
40
+ # Auto-fix common issues
41
+ npx @nsxbet/admin-cli check --fix
42
+ ```
43
+
44
+ The CLI scaffolds all 13 required files with correct configuration, dependency versions, and SDK integration. It also validates existing modules against the canonical reference.
45
+
46
+ > **Required for LLMs:** After creating or modifying a module, run `npx @nsxbet/admin-cli checklist --output CHECKLIST.md` and verify every item in the generated file before considering the setup complete. The checklist is a self-contained verification guide—no CLI installation needed to consume it.
47
+
18
48
  ## Quick Start
19
49
 
20
50
  This SDK enables you to build admin modules that integrate with the NSX Admin shell. Modules are loaded dynamically via React.lazy and share the shell's Router context.
@@ -115,7 +145,13 @@ export default App;
115
145
  ```tsx
116
146
  import React from "react";
117
147
  import ReactDOM from "react-dom/client";
118
- import { AdminShell, initI18n, i18n } from "@nsxbet/admin-sdk";
148
+ import {
149
+ AdminShell,
150
+ initI18n,
151
+ i18n,
152
+ createInMemoryAuthClient,
153
+ createMockUsersFromRoles,
154
+ } from "@nsxbet/admin-sdk";
119
155
  import type { AdminModuleManifest } from "@nsxbet/admin-sdk";
120
156
  import { App } from "./App";
121
157
  import manifest from "../admin.module.json";
@@ -134,9 +170,40 @@ const NAMESPACE = "mymodule";
134
170
  i18n.addResourceBundle("en-US", NAMESPACE, enUS, true, true);
135
171
  i18n.addResourceBundle("pt-BR", NAMESPACE, ptBR, true, true);
136
172
 
173
+ // Type assertion for JSON import
174
+ const moduleManifest = manifest as AdminModuleManifest;
175
+
176
+ // Check environment variable to toggle between mock auth and Keycloak
177
+ const useKeycloak = import.meta.env.VITE_MOCK_AUTH === "false";
178
+
179
+ // Create mock users with module-specific permissions
180
+ const mockUsers = createMockUsersFromRoles({
181
+ admin: ["admin.mymodule.view", "admin.mymodule.edit", "admin.mymodule.delete"],
182
+ editor: ["admin.mymodule.view", "admin.mymodule.edit"],
183
+ viewer: ["admin.mymodule.view"],
184
+ noAccess: [],
185
+ });
186
+
187
+ // Use in-memory auth by default (shows user selector), or Keycloak if configured
188
+ const authClient = useKeycloak
189
+ ? undefined
190
+ : createInMemoryAuthClient({ users: mockUsers });
191
+
137
192
  ReactDOM.createRoot(document.getElementById("root")!).render(
138
193
  <React.StrictMode>
139
- <AdminShell modules={[manifest as AdminModuleManifest]}>
194
+ <AdminShell
195
+ modules={[moduleManifest]}
196
+ authClient={authClient}
197
+ keycloak={
198
+ useKeycloak
199
+ ? {
200
+ url: "http://localhost:8080",
201
+ realm: "admin",
202
+ clientId: "admin-shell",
203
+ }
204
+ : undefined
205
+ }
206
+ >
140
207
  <App />
141
208
  </AdminShell>
142
209
  </React.StrictMode>
@@ -219,6 +286,52 @@ export function ItemList() {
219
286
  @tailwind utilities;
220
287
  ```
221
288
 
289
+ ### Directory: `src/i18n/` (optional - for translations)
290
+
291
+ Structure:
292
+
293
+ ```
294
+ src/i18n/
295
+ locales/
296
+ en-US.json # English (required)
297
+ pt-BR.json # Portuguese
298
+ ```
299
+
300
+ Example `src/i18n/locales/en-US.json`:
301
+
302
+ ```json
303
+ {
304
+ "module": {
305
+ "title": "My Module",
306
+ "description": "Description of my module"
307
+ },
308
+ "list": {
309
+ "title": "All Items",
310
+ "noItems": "No items found.",
311
+ "create": "Create Item"
312
+ },
313
+ "form": {
314
+ "titleLabel": "Title",
315
+ "titlePlaceholder": "Enter title",
316
+ "cancel": "Cancel",
317
+ "submit": "Submit"
318
+ }
319
+ }
320
+ ```
321
+
322
+ Use translations in components:
323
+
324
+ ```tsx
325
+ import { useI18n } from "@nsxbet/admin-sdk";
326
+
327
+ function MyComponent() {
328
+ const { t } = useI18n();
329
+
330
+ // Use with namespace prefix (set in standalone.tsx)
331
+ return <h1>{t("mymodule:list.title")}</h1>;
332
+ }
333
+ ```
334
+
222
335
  ### File: `tailwind.config.js`
223
336
 
224
337
  Use `withAdminSdk` which automatically includes the UI preset and SDK/UI content paths:
@@ -247,25 +360,30 @@ export default withAdminSdk({
247
360
  "dependencies": {
248
361
  "@nsxbet/admin-sdk": "latest",
249
362
  "@nsxbet/admin-ui": "latest",
250
- "react": "^18.2.0",
251
- "react-dom": "^18.2.0",
252
- "react-router-dom": "^6.20.0",
253
- "i18next": "^25.0.0",
254
- "react-i18next": "^16.0.0"
363
+ "react": "18.2.0",
364
+ "react-dom": "18.2.0",
365
+ "react-router-dom": "6.20.1",
366
+ "i18next": "25.0.0",
367
+ "react-i18next": "16.0.0"
255
368
  },
256
369
  "devDependencies": {
257
370
  "@types/react": "^18.2.0",
258
371
  "@types/react-dom": "^18.2.0",
259
372
  "@vitejs/plugin-react": "^4.2.0",
260
- "autoprefixer": "^10.4.16",
261
- "postcss": "^8.4.32",
262
- "tailwindcss": "^3.4.0",
373
+ "autoprefixer": "10.4.16",
374
+ "postcss": "8.4.32",
375
+ "tailwindcss": "3.4.0",
376
+ "tailwindcss-animate": "1.0.7",
263
377
  "typescript": "^5.2.0",
264
378
  "vite": "^5.0.0"
265
379
  }
266
380
  }
267
381
  ```
268
382
 
383
+ > **Note:** Exact versions for runtime deps (react, i18next) avoid conflicts with the shell. Exact versions for styling (tailwindcss, postcss) ensure design system consistency.
384
+
385
+ > **Note:** The build script copies `admin.module.json` to `dist/` because the shell needs the manifest to register your module.
386
+
269
387
  ### File: `tsconfig.json`
270
388
 
271
389
  ```json
@@ -319,6 +437,66 @@ export default {
319
437
  };
320
438
  ```
321
439
 
440
+ ### File: `src/globals.d.ts`
441
+
442
+ TypeScript declarations for environment variables and platform API:
443
+
444
+ ```typescript
445
+ /// <reference types="vite/client" />
446
+
447
+ declare global {
448
+ interface ImportMetaEnv {
449
+ readonly VITE_MOCK_AUTH?: string;
450
+ }
451
+
452
+ interface ImportMeta {
453
+ readonly env: ImportMetaEnv;
454
+ }
455
+
456
+ interface Window {
457
+ __ADMIN_PLATFORM_API__?: import("@nsxbet/admin-sdk").PlatformAPI;
458
+ __ENV__?: {
459
+ ENVIRONMENT: string;
460
+ KEYCLOAK_URL: string;
461
+ KEYCLOAK_REALM: string;
462
+ KEYCLOAK_CLIENT_ID: string;
463
+ };
464
+ }
465
+ }
466
+
467
+ export {};
468
+ ```
469
+
470
+ ### File: `tsconfig.node.json`
471
+
472
+ Separate TypeScript config for Vite configuration file:
473
+
474
+ ```json
475
+ {
476
+ "compilerOptions": {
477
+ "composite": true,
478
+ "skipLibCheck": true,
479
+ "module": "ESNext",
480
+ "moduleResolution": "bundler",
481
+ "allowSyntheticDefaultImports": true,
482
+ "strict": true
483
+ },
484
+ "include": ["vite.config.ts"]
485
+ }
486
+ ```
487
+
488
+ ### File: `.env.local` (optional)
489
+
490
+ Environment configuration for development:
491
+
492
+ ```bash
493
+ # Use mock authentication with user selector (default: true)
494
+ VITE_MOCK_AUTH=true
495
+
496
+ # Set to "false" to use Keycloak authentication
497
+ # VITE_MOCK_AUTH=false
498
+ ```
499
+
322
500
  ## Manifest Schema (`admin.module.json`)
323
501
 
324
502
  | Field | Type | Required | Description |
@@ -371,6 +549,11 @@ export default defineModuleConfig({
371
549
  });
372
550
  ```
373
551
 
552
+ > **Important:** Each module must use a unique port. Standard assignments:
553
+ > - Shell: 3000
554
+ > - API: 4000
555
+ > - Modules: 3002, 3003, 3004, etc.
556
+
374
557
  ### Options
375
558
 
376
559
  | Option | Type | Default | Description |
@@ -511,6 +694,126 @@ function MyComponent() {
511
694
  }
512
695
  ```
513
696
 
697
+ ## Custom Mock Users for Development
698
+
699
+ During standalone development, the SDK uses an in-memory auth client with default mock users. You can customize these users to match your module's specific permission requirements.
700
+
701
+ ### Using `createMockUsersFromRoles()`
702
+
703
+ The simplest way to create custom mock users is with the `createMockUsersFromRoles()` factory:
704
+
705
+ ```typescript
706
+ import {
707
+ AdminShell,
708
+ createInMemoryAuthClient,
709
+ createMockUsersFromRoles,
710
+ } from "@nsxbet/admin-sdk";
711
+
712
+ // Define roles for your module
713
+ const mockUsers = createMockUsersFromRoles({
714
+ admin: [
715
+ "admin.payments.view",
716
+ "admin.payments.edit",
717
+ "admin.payments.delete",
718
+ ],
719
+ editor: ["admin.payments.view", "admin.payments.edit"],
720
+ viewer: ["admin.payments.view"],
721
+ noAccess: [],
722
+ });
723
+
724
+ // Create auth client with custom users
725
+ const authClient = createInMemoryAuthClient({ users: mockUsers });
726
+
727
+ // Use in standalone.tsx
728
+ ReactDOM.createRoot(document.getElementById("root")!).render(
729
+ <AdminShell authClient={authClient} modules={[manifest]}>
730
+ <App />
731
+ </AdminShell>
732
+ );
733
+ ```
734
+
735
+ This creates 4 standard user types with your custom roles:
736
+ - **Admin User** - Full access (all roles in `admin` array)
737
+ - **Editor User** - View/edit access (roles in `editor` array)
738
+ - **Viewer User** - View-only access (roles in `viewer` array)
739
+ - **No Access User** - No permissions (roles in `noAccess` array)
740
+
741
+ ### Using Custom Users Directly
742
+
743
+ For more control, pass custom `MockUser` objects directly:
744
+
745
+ ```typescript
746
+ import { createInMemoryAuthClient, type MockUser } from "@nsxbet/admin-sdk";
747
+
748
+ const customUsers: MockUser[] = [
749
+ {
750
+ id: "super-admin",
751
+ email: "superadmin@example.com",
752
+ displayName: "Super Admin",
753
+ roles: ["*"], // Wildcard: all permissions
754
+ },
755
+ {
756
+ id: "payments-admin",
757
+ email: "payments@example.com",
758
+ displayName: "Payments Admin",
759
+ roles: ["admin.payments.view", "admin.payments.edit"],
760
+ },
761
+ ];
762
+
763
+ const authClient = createInMemoryAuthClient({ users: customUsers });
764
+ ```
765
+
766
+ ### Options
767
+
768
+ | Option | Type | Default | Description |
769
+ |--------|------|---------|-------------|
770
+ | `users` | MockUser[] | **required** | Mock users available for selection |
771
+ | `storageKey` | string | `"@nsxbet/auth"` | localStorage key for persistence |
772
+
773
+ ## Keycloak Configuration (Production Auth)
774
+
775
+ For production or when testing with real authentication, configure Keycloak:
776
+
777
+ ### Prerequisites
778
+
779
+ 1. Keycloak server running (default: `http://localhost:8080`)
780
+ 2. Realm named `admin` created
781
+ 3. Client named `admin-shell` configured with:
782
+ - Client Protocol: `openid-connect`
783
+ - Access Type: `public`
784
+ - Valid Redirect URIs: `http://localhost:3003/*`
785
+
786
+ ### Enable Keycloak in Development
787
+
788
+ Set the environment variable in `.env.local`:
789
+
790
+ ```bash
791
+ VITE_MOCK_AUTH=false
792
+ ```
793
+
794
+ Or pass the `keycloak` prop directly without `authClient`:
795
+
796
+ ```tsx
797
+ <AdminShell
798
+ modules={[manifest]}
799
+ keycloak={{
800
+ url: "http://localhost:8080",
801
+ realm: "admin",
802
+ clientId: "admin-shell",
803
+ }}
804
+ >
805
+ <App />
806
+ </AdminShell>
807
+ ```
808
+
809
+ ### Keycloak Configuration Options
810
+
811
+ | Option | Type | Description |
812
+ |--------|------|-------------|
813
+ | `url` | string | Keycloak server URL |
814
+ | `realm` | string | Realm name |
815
+ | `clientId` | string | Client ID |
816
+
514
817
  ## DO NOT (Common Mistakes)
515
818
 
516
819
  ### ❌ DO NOT use MemoryRouter
@@ -614,6 +917,8 @@ import { useNavigate } from "react-router-dom"; // ✅
614
917
 
615
918
  ## Troubleshooting
616
919
 
920
+ **First step:** Run `npx @nsxbet/admin-cli checklist` and verify all items. The checklist covers every setup requirement and often identifies misconfigurations quickly.
921
+
617
922
  ### "Failed to resolve module specifier 'react'"
618
923
 
619
924
  **Cause:** Module is bundling React instead of using shell's version.
@@ -643,7 +948,7 @@ define: {
643
948
 
644
949
  ### Styles not working
645
950
 
646
- **Checklist:**
951
+ Run `npx @nsxbet/admin-cli checklist` to verify Tailwind/PostCSS configuration. Key items:
647
952
  1. ✅ `index.css` imports `@nsxbet/admin-ui/styles.css`
648
953
  2. ✅ `tailwind.config.js` uses `withAdminSdk` from `@nsxbet/admin-sdk/tailwind`
649
954
  3. ✅ `postcss.config.js` exists with tailwindcss plugin
@@ -5,21 +5,63 @@
5
5
  * Users can be selected from a predefined list or created custom.
6
6
  */
7
7
  import type { MockUser, InMemoryAuthClient } from './interface';
8
+ /**
9
+ * Role configuration for creating mock users
10
+ */
11
+ export interface MockUserRoles {
12
+ /** Roles for the admin user (full access) */
13
+ admin: string[];
14
+ /** Roles for the editor user (view/edit, no delete) */
15
+ editor: string[];
16
+ /** Roles for the viewer user (view only) */
17
+ viewer: string[];
18
+ /** Roles for the no-access user (typically empty) */
19
+ noAccess: string[];
20
+ }
21
+ /**
22
+ * Create mock users from a role configuration
23
+ *
24
+ * Generates the standard 4 user types (admin, editor, viewer, no-access)
25
+ * with custom roles. Use with `createInMemoryAuthClient({ users: ... })`.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const mockUsers = createMockUsersFromRoles({
30
+ * admin: ['admin.payments.view', 'admin.payments.edit', 'admin.payments.delete'],
31
+ * editor: ['admin.payments.view', 'admin.payments.edit'],
32
+ * viewer: ['admin.payments.view'],
33
+ * noAccess: [],
34
+ * });
35
+ *
36
+ * const authClient = createInMemoryAuthClient({ users: mockUsers });
37
+ * ```
38
+ */
39
+ export declare function createMockUsersFromRoles(roles: MockUserRoles): MockUser[];
8
40
  /**
9
41
  * Options for creating an in-memory auth client
10
42
  */
11
43
  export interface InMemoryAuthClientOptions {
12
- /** Custom mock users (merged with defaults) */
13
- users?: MockUser[];
14
- /** Replace default users instead of merging */
15
- replaceDefaults?: boolean;
44
+ /** Mock users available for selection (required) */
45
+ users: MockUser[];
16
46
  /** localStorage key prefix (defaults to '@nsxbet/auth') */
17
47
  storageKey?: string;
18
48
  }
19
49
  /**
20
50
  * Create an in-memory auth client for development/testing
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const mockUsers = createMockUsersFromRoles({
55
+ * admin: ['admin.tasks.view', 'admin.tasks.edit', 'admin.tasks.delete'],
56
+ * editor: ['admin.tasks.view', 'admin.tasks.edit'],
57
+ * viewer: ['admin.tasks.view'],
58
+ * noAccess: [],
59
+ * });
60
+ *
61
+ * const authClient = createInMemoryAuthClient({ users: mockUsers });
62
+ * ```
21
63
  */
22
- export declare function createInMemoryAuthClient(options?: InMemoryAuthClientOptions): InMemoryAuthClient;
64
+ export declare function createInMemoryAuthClient(options: InMemoryAuthClientOptions): InMemoryAuthClient;
23
65
  /**
24
66
  * Clear in-memory auth storage (useful for tests)
25
67
  */
@@ -1 +1 @@
1
- {"version":3,"file":"in-memory.d.ts","sourceRoot":"","sources":["../../../src/auth/client/in-memory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAgC,MAAM,aAAa,CAAC;AAoD9F;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,+CAA+C;IAC/C,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAYD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,yBAA8B,GAAG,kBAAkB,CAiNpG;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,SAAsB,GAAG,IAAI,CAExE"}
1
+ {"version":3,"file":"in-memory.d.ts","sourceRoot":"","sources":["../../../src/auth/client/in-memory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAgC,MAAM,aAAa,CAAC;AAE9F;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,uDAAuD;IACvD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,aAAa,GAAG,QAAQ,EAAE,CA2BzE;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,oDAAoD;IACpD,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAYD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,kBAAkB,CA6M/F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,SAAsB,GAAG,IAAI,CAExE"}
@@ -5,62 +5,71 @@
5
5
  * Users can be selected from a predefined list or created custom.
6
6
  */
7
7
  /**
8
- * Default mock users
8
+ * Create mock users from a role configuration
9
+ *
10
+ * Generates the standard 4 user types (admin, editor, viewer, no-access)
11
+ * with custom roles. Use with `createInMemoryAuthClient({ users: ... })`.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const mockUsers = createMockUsersFromRoles({
16
+ * admin: ['admin.payments.view', 'admin.payments.edit', 'admin.payments.delete'],
17
+ * editor: ['admin.payments.view', 'admin.payments.edit'],
18
+ * viewer: ['admin.payments.view'],
19
+ * noAccess: [],
20
+ * });
21
+ *
22
+ * const authClient = createInMemoryAuthClient({ users: mockUsers });
23
+ * ```
9
24
  */
10
- const DEFAULT_MOCK_USERS = [
11
- {
12
- id: 'admin-user',
13
- email: 'admin@example.com',
14
- displayName: 'Admin User',
15
- roles: [
16
- 'admin',
17
- // Tasks - full access
18
- 'admin.tasks.view',
19
- 'admin.tasks.edit',
20
- 'admin.tasks.delete',
21
- // Users - full access
22
- 'admin.users.view',
23
- 'admin.users.edit',
24
- 'admin.users.delete',
25
- ],
26
- },
27
- {
28
- id: 'editor-user',
29
- email: 'editor@example.com',
30
- displayName: 'Editor User',
31
- roles: [
32
- // Tasks - can create/edit, no delete
33
- 'admin.tasks.view',
34
- 'admin.tasks.edit',
35
- // Users - view only
36
- 'admin.users.view',
37
- ],
38
- },
39
- {
40
- id: 'viewer-user',
41
- email: 'viewer@example.com',
42
- displayName: 'Viewer User',
43
- roles: [
44
- // View only - no edit or delete
45
- 'admin.tasks.view',
46
- 'admin.users.view',
47
- ],
48
- },
49
- {
50
- id: 'no-access-user',
51
- email: 'noaccess@example.com',
52
- displayName: 'No Access User',
53
- roles: [],
54
- },
55
- ];
25
+ export function createMockUsersFromRoles(roles) {
26
+ return [
27
+ {
28
+ id: 'admin-user',
29
+ email: 'admin@example.com',
30
+ displayName: 'Admin User',
31
+ roles: roles.admin,
32
+ },
33
+ {
34
+ id: 'editor-user',
35
+ email: 'editor@example.com',
36
+ displayName: 'Editor User',
37
+ roles: roles.editor,
38
+ },
39
+ {
40
+ id: 'viewer-user',
41
+ email: 'viewer@example.com',
42
+ displayName: 'Viewer User',
43
+ roles: roles.viewer,
44
+ },
45
+ {
46
+ id: 'no-access-user',
47
+ email: 'noaccess@example.com',
48
+ displayName: 'No Access User',
49
+ roles: roles.noAccess,
50
+ },
51
+ ];
52
+ }
56
53
  const DEFAULT_STORAGE_KEY = '@nsxbet/auth';
57
54
  /**
58
55
  * Create an in-memory auth client for development/testing
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const mockUsers = createMockUsersFromRoles({
60
+ * admin: ['admin.tasks.view', 'admin.tasks.edit', 'admin.tasks.delete'],
61
+ * editor: ['admin.tasks.view', 'admin.tasks.edit'],
62
+ * viewer: ['admin.tasks.view'],
63
+ * noAccess: [],
64
+ * });
65
+ *
66
+ * const authClient = createInMemoryAuthClient({ users: mockUsers });
67
+ * ```
59
68
  */
60
- export function createInMemoryAuthClient(options = {}) {
61
- const { users: customUsers = [], replaceDefaults = false, storageKey = DEFAULT_STORAGE_KEY, } = options;
62
- // Merge users
63
- const predefinedUsers = replaceDefaults ? customUsers : [...DEFAULT_MOCK_USERS, ...customUsers];
69
+ export function createInMemoryAuthClient(options) {
70
+ const { users, storageKey = DEFAULT_STORAGE_KEY } = options;
71
+ // Use provided users
72
+ const predefinedUsers = users;
64
73
  // State
65
74
  let selectedUser = null;
66
75
  const subscribers = new Set();
@@ -2,6 +2,6 @@
2
2
  * Auth Client exports
3
3
  */
4
4
  export type { AuthClient, InMemoryAuthClient, MockUser, AuthState, AuthStateCallback, } from './interface';
5
- export { createInMemoryAuthClient, clearInMemoryAuth, type InMemoryAuthClientOptions, } from './in-memory';
5
+ export { createInMemoryAuthClient, clearInMemoryAuth, createMockUsersFromRoles, type InMemoryAuthClientOptions, type MockUserRoles, } from './in-memory';
6
6
  export { createKeycloakAuthClient, type KeycloakAuthClientOptions, } from './keycloak';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/client/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,KAAK,yBAAyB,GAC/B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,wBAAwB,EACxB,KAAK,yBAAyB,GAC/B,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/client/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,wBAAwB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,wBAAwB,EACxB,KAAK,yBAAyB,GAC/B,MAAM,YAAY,CAAC"}
@@ -2,6 +2,6 @@
2
2
  * Auth Client exports
3
3
  */
4
4
  // In-memory client
5
- export { createInMemoryAuthClient, clearInMemoryAuth, } from './in-memory';
5
+ export { createInMemoryAuthClient, clearInMemoryAuth, createMockUsersFromRoles, } from './in-memory';
6
6
  // Keycloak client
7
7
  export { createKeycloakAuthClient, } from './keycloak';
@@ -1 +1 @@
1
- {"version":3,"file":"UserSelector.d.ts","sourceRoot":"","sources":["../../../src/auth/components/UserSelector.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAY,MAAM,qBAAqB,CAAC;AAExE,UAAU,iBAAiB;IACzB,gCAAgC;IAChC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,qCAAqC;IACrC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AA2ND;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,UAAU,EAAE,cAAc,EAAE,EAAE,iBAAiB,2CAqF7E"}
1
+ {"version":3,"file":"UserSelector.d.ts","sourceRoot":"","sources":["../../../src/auth/components/UserSelector.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAY,MAAM,qBAAqB,CAAC;AAExE,UAAU,iBAAiB;IACzB,gCAAgC;IAChC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,qCAAqC;IACrC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AA4OD;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,UAAU,EAAE,cAAc,EAAE,EAAE,iBAAiB,2CAqF7E"}
@@ -12,13 +12,24 @@ import { Crown, Ban, Eye, User, Users, Sparkles, Wrench, Trash2, Plus, ChevronRi
12
12
  */
13
13
  function getUserIcon(roles) {
14
14
  const iconClass = "h-7 w-7";
15
- if (roles.includes('admin') || roles.includes('*')) {
16
- return _jsx(Crown, { className: `${iconClass} text-amber-500` });
17
- }
15
+ // No roles = no access
18
16
  if (roles.length === 0) {
19
17
  return _jsx(Ban, { className: `${iconClass} text-destructive` });
20
18
  }
21
- if (roles.some((r) => r.includes('view') && !r.includes('edit'))) {
19
+ // Wildcard or 'admin' role = full admin
20
+ if (roles.includes('*') || roles.includes('admin')) {
21
+ return _jsx(Crown, { className: `${iconClass} text-amber-500` });
22
+ }
23
+ // Has delete permission = admin level
24
+ if (roles.some((r) => r.includes('.delete'))) {
25
+ return _jsx(Crown, { className: `${iconClass} text-amber-500` });
26
+ }
27
+ // Has edit permission = editor level
28
+ if (roles.some((r) => r.includes('.edit'))) {
29
+ return _jsx(User, { className: `${iconClass} text-success` });
30
+ }
31
+ // View only
32
+ if (roles.some((r) => r.includes('.view'))) {
22
33
  return _jsx(Eye, { className: `${iconClass} text-info` });
23
34
  }
24
35
  return _jsx(User, { className: `${iconClass} text-muted-foreground` });
@@ -2,6 +2,6 @@
2
2
  * Authentication module exports
3
3
  */
4
4
  export type { AuthClient, InMemoryAuthClient, MockUser, AuthState, AuthStateCallback, } from './client';
5
- export { createInMemoryAuthClient, clearInMemoryAuth, createKeycloakAuthClient, type InMemoryAuthClientOptions, type KeycloakAuthClientOptions, } from './client';
5
+ export { createInMemoryAuthClient, clearInMemoryAuth, createMockUsersFromRoles, createKeycloakAuthClient, type InMemoryAuthClientOptions, type MockUserRoles, type KeycloakAuthClientOptions, } from './client';
6
6
  export { UserSelector } from './components';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,wBAAwB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,GAC/B,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,wBAAwB,EACxB,wBAAwB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,aAAa,EAClB,KAAK,yBAAyB,GAC/B,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
@@ -2,6 +2,6 @@
2
2
  * Authentication module exports
3
3
  */
4
4
  // Auth client factories
5
- export { createInMemoryAuthClient, clearInMemoryAuth, createKeycloakAuthClient, } from './client';
5
+ export { createInMemoryAuthClient, clearInMemoryAuth, createMockUsersFromRoles, createKeycloakAuthClient, } from './client';
6
6
  // Auth components
7
7
  export { UserSelector } from './components';
package/dist/index.d.ts CHANGED
@@ -10,8 +10,8 @@ export { usePlatformAPI } from './hooks/usePlatformAPI';
10
10
  export { useFetch } from './hooks/useFetch';
11
11
  export { useTelemetry } from './hooks/useTelemetry';
12
12
  export { useI18n } from './hooks/useI18n';
13
- export { createInMemoryAuthClient, clearInMemoryAuth, createKeycloakAuthClient, UserSelector, } from './auth';
14
- export type { AuthClient, InMemoryAuthClient, MockUser, AuthState, AuthStateCallback, InMemoryAuthClientOptions, KeycloakAuthClientOptions, } from './auth';
13
+ export { createInMemoryAuthClient, clearInMemoryAuth, createMockUsersFromRoles, createKeycloakAuthClient, UserSelector, } from './auth';
14
+ export type { AuthClient, InMemoryAuthClient, MockUser, MockUserRoles, AuthState, AuthStateCallback, InMemoryAuthClientOptions, KeycloakAuthClientOptions, } from './auth';
15
15
  export type { PlatformAPI, Breadcrumb, User } from './types/platform';
16
16
  export type { KeycloakConfig } from './types/keycloak';
17
17
  export type { UseAuthResult } from './hooks/useAuth';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGjG,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG1C,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,wBAAwB,EACxB,YAAY,GACb,MAAM,QAAQ,CAAC;AAEhB,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,QAAQ,CAAC;AAGhB,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACtE,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGrD,OAAO,EACL,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,IAAI,EACJ,iBAAiB,EACjB,YAAY,EACZ,YAAY,GACb,MAAM,QAAQ,CAAC;AAEhB,YAAY,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAEL,4BAA4B,EAC5B,qBAAqB,EACrB,wBAAwB,EAExB,gBAAgB,EAChB,aAAa,EAEb,kBAAkB,EAClB,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,YAAY,EAEV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EAEnB,mBAAmB,EACnB,aAAa,IAAI,qBAAqB,EACtC,iBAAiB,EACjB,YAAY,EACZ,YAAY,IAAI,oBAAoB,EAEpC,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,OAAO,IAAI,eAAe,EAC1B,aAAa,EACb,SAAS,IAAI,iBAAiB,EAE9B,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,UAAU,EACV,MAAM,EACN,OAAO,EACP,WAAW,EACX,cAAc,EACd,aAAa,EACb,QAAQ,EACR,aAAa,EACb,KAAK,EACL,UAAU,EACV,WAAW,GACZ,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,aAAa,EACb,aAAa,EACb,mBAAmB,GACpB,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,MAAM,EACN,aAAa,EACb,YAAY,EACZ,OAAO,EACP,SAAS,EACT,cAAc,EACd,YAAY,EACZ,aAAa,GACd,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGjG,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG1C,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,wBAAwB,EACxB,wBAAwB,EACxB,YAAY,GACb,MAAM,QAAQ,CAAC;AAEhB,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,aAAa,EACb,SAAS,EACT,iBAAiB,EACjB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,QAAQ,CAAC;AAGhB,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACtE,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGrD,OAAO,EACL,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,IAAI,EACJ,iBAAiB,EACjB,YAAY,EACZ,YAAY,GACb,MAAM,QAAQ,CAAC;AAEhB,YAAY,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAEL,4BAA4B,EAC5B,qBAAqB,EACrB,wBAAwB,EAExB,gBAAgB,EAChB,aAAa,EAEb,kBAAkB,EAClB,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,YAAY,EAEV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EAEnB,mBAAmB,EACnB,aAAa,IAAI,qBAAqB,EACtC,iBAAiB,EACjB,YAAY,EACZ,YAAY,IAAI,oBAAoB,EAEpC,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,OAAO,IAAI,eAAe,EAC1B,aAAa,EACb,SAAS,IAAI,iBAAiB,EAE9B,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,UAAU,EACV,MAAM,EACN,OAAO,EACP,WAAW,EACX,cAAc,EACd,aAAa,EACb,QAAQ,EACR,aAAa,EACb,KAAK,EACL,UAAU,EACV,WAAW,GACZ,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,aAAa,EACb,aAAa,EACb,mBAAmB,GACpB,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,MAAM,EACN,aAAa,EACb,YAAY,EACZ,OAAO,EACP,SAAS,EACT,cAAc,EACd,YAAY,EACZ,aAAa,GACd,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ export { useFetch } from './hooks/useFetch';
13
13
  export { useTelemetry } from './hooks/useTelemetry';
14
14
  export { useI18n } from './hooks/useI18n';
15
15
  // Auth Client
16
- export { createInMemoryAuthClient, clearInMemoryAuth, createKeycloakAuthClient, UserSelector, } from './auth';
16
+ export { createInMemoryAuthClient, clearInMemoryAuth, createMockUsersFromRoles, createKeycloakAuthClient, UserSelector, } from './auth';
17
17
  // i18n
18
18
  export { initI18n, saveLocale, isSupportedLocale, i18n, SUPPORTED_LOCALES, LOCALE_FLAGS, LOCALE_NAMES, } from './i18n';
19
19
  // Registry
@@ -2,7 +2,7 @@
2
2
  * HTTP Registry Client
3
3
  *
4
4
  * Implementation of RegistryClient that communicates with the admin-api.
5
- * Used when running with PostgreSQL backend.
5
+ * Used when running with MySQL backend.
6
6
  */
7
7
  import type { RegistryClient } from './interface';
8
8
  /**
@@ -2,7 +2,7 @@
2
2
  * HTTP Registry Client
3
3
  *
4
4
  * Implementation of RegistryClient that communicates with the admin-api.
5
- * Used when running with PostgreSQL backend.
5
+ * Used when running with MySQL backend.
6
6
  */
7
7
  /**
8
8
  * Create an HTTP registry client
@@ -1 +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"}
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,2CA4LjB"}
@@ -204,7 +204,13 @@ export function AdminShell({ modules: manifests = [], children, keycloak, authCl
204
204
  const useMockAuth = typeof window !== 'undefined' &&
205
205
  (import.meta.env.VITE_MOCK_AUTH === 'true' || !keycloak);
206
206
  if (useMockAuth) {
207
- return createInMemoryAuthClient();
207
+ // Create default mock users with wildcard permissions for shell development
208
+ return createInMemoryAuthClient({
209
+ users: [
210
+ { id: 'admin-user', email: 'admin@example.com', displayName: 'Admin User', roles: ['*'] },
211
+ { id: 'viewer-user', email: 'viewer@example.com', displayName: 'Viewer User', roles: [] },
212
+ ],
213
+ });
208
214
  }
209
215
  // Use Keycloak
210
216
  return createKeycloakAuthClient({
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeShell.d.ts","sourceRoot":"","sources":["../../src/shell/BackofficeShell.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"}
1
+ {"version":3,"file":"BackofficeShell.d.ts","sourceRoot":"","sources":["../../src/shell/BackofficeShell.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,2CA4LjB"}
@@ -204,7 +204,13 @@ export function AdminShell({ modules: manifests = [], children, keycloak, authCl
204
204
  const useMockAuth = typeof window !== 'undefined' &&
205
205
  (import.meta.env.VITE_MOCK_AUTH === 'true' || !keycloak);
206
206
  if (useMockAuth) {
207
- return createInMemoryAuthClient();
207
+ // Create default mock users with wildcard permissions for shell development
208
+ return createInMemoryAuthClient({
209
+ users: [
210
+ { id: 'admin-user', email: 'admin@example.com', displayName: 'Admin User', roles: ['*'] },
211
+ { id: 'viewer-user', email: 'viewer@example.com', displayName: 'Viewer User', roles: [] },
212
+ ],
213
+ });
208
214
  }
209
215
  // Use Keycloak
210
216
  return createKeycloakAuthClient({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nsxbet/admin-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "SDK for building NSX Admin modules with integrated shell",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -34,7 +34,7 @@
34
34
  "test": "vitest run --passWithNoTests"
35
35
  },
36
36
  "peerDependencies": {
37
- "@nsxbet/admin-ui": ">=0.1.0",
37
+ "@nsxbet/admin-ui": "^0.2.0",
38
38
  "@vitejs/plugin-react": "^4.0.0",
39
39
  "i18next": "^23.0.0 || ^24.0.0 || ^25.0.0",
40
40
  "react": "^18.2.0",