@nsxbet/admin-sdk 0.2.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 +243 -14
- package/dist/registry/client/http.d.ts +1 -1
- package/dist/registry/client/http.js +1 -1
- package/package.json +2 -2
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
|
|
11
|
+
**Peer dependencies:**
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
|
|
15
|
-
bun add -
|
|
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
|
|
22
|
+
```
|
|
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
|
|
16
42
|
```
|
|
17
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 {
|
|
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
|
|
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": "
|
|
251
|
-
"react-dom": "
|
|
252
|
-
"react-router-dom": "
|
|
253
|
-
"i18next": "
|
|
254
|
-
"react-i18next": "
|
|
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": "
|
|
261
|
-
"postcss": "
|
|
262
|
-
"tailwindcss": "
|
|
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 |
|
|
@@ -587,6 +770,50 @@ const authClient = createInMemoryAuthClient({ users: customUsers });
|
|
|
587
770
|
| `users` | MockUser[] | **required** | Mock users available for selection |
|
|
588
771
|
| `storageKey` | string | `"@nsxbet/auth"` | localStorage key for persistence |
|
|
589
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
|
+
|
|
590
817
|
## DO NOT (Common Mistakes)
|
|
591
818
|
|
|
592
819
|
### ❌ DO NOT use MemoryRouter
|
|
@@ -690,6 +917,8 @@ import { useNavigate } from "react-router-dom"; // ✅
|
|
|
690
917
|
|
|
691
918
|
## Troubleshooting
|
|
692
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
|
+
|
|
693
922
|
### "Failed to resolve module specifier 'react'"
|
|
694
923
|
|
|
695
924
|
**Cause:** Module is bundling React instead of using shell's version.
|
|
@@ -719,7 +948,7 @@ define: {
|
|
|
719
948
|
|
|
720
949
|
### Styles not working
|
|
721
950
|
|
|
722
|
-
|
|
951
|
+
Run `npx @nsxbet/admin-cli checklist` to verify Tailwind/PostCSS configuration. Key items:
|
|
723
952
|
1. ✅ `index.css` imports `@nsxbet/admin-ui/styles.css`
|
|
724
953
|
2. ✅ `tailwind.config.js` uses `withAdminSdk` from `@nsxbet/admin-sdk/tailwind`
|
|
725
954
|
3. ✅ `postcss.config.js` exists with tailwindcss plugin
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nsxbet/admin-sdk",
|
|
3
|
-
"version": "0.2.
|
|
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": "
|
|
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",
|