@nsxbet/admin-sdk 0.2.0 → 0.4.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/CHECKLIST.md +212 -0
- package/README.md +260 -16
- package/dist/registry/client/http.d.ts +1 -1
- package/dist/registry/client/http.js +1 -1
- package/dist/vite/config.d.ts +2 -1
- package/dist/vite/config.d.ts.map +1 -1
- package/dist/vite/config.js +1 -1
- package/package.json +6 -3
- package/scripts/postinstall.js +1 -0
package/CHECKLIST.md
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Admin Module Setup Checklist
|
|
2
|
+
|
|
3
|
+
> Verify each item to ensure your module is correctly configured.
|
|
4
|
+
> For module-specific values, run `npx adminx checklist` (requires `@nsxbet/admin-cli`).
|
|
5
|
+
|
|
6
|
+
**Usage for LLMs:** Work through each section, check off items as you verify them. Compare your files against the expected content blocks.
|
|
7
|
+
|
|
8
|
+
## Required Files
|
|
9
|
+
|
|
10
|
+
- [ ] `admin.module.json` — Module manifest
|
|
11
|
+
- [ ] `package.json` — Package configuration
|
|
12
|
+
- [ ] `vite.config.ts` — Vite build config
|
|
13
|
+
- [ ] `index.html` — HTML entry point
|
|
14
|
+
- [ ] `src/spa.tsx` — Shell entry (default export)
|
|
15
|
+
- [ ] `src/standalone.tsx` — Dev entry (AdminShell wrapper)
|
|
16
|
+
- [ ] `src/App.tsx` — Main app component (Routes)
|
|
17
|
+
- [ ] `src/index.css` — Styles with Tailwind directives
|
|
18
|
+
- [ ] `tailwind.config.js` — Tailwind config
|
|
19
|
+
- [ ] `postcss.config.js` — PostCSS config
|
|
20
|
+
- [ ] `tsconfig.json` — TypeScript config
|
|
21
|
+
- [ ] `tsconfig.node.json` — Node TypeScript config
|
|
22
|
+
- [ ] `src/globals.d.ts` — Global type declarations
|
|
23
|
+
|
|
24
|
+
## Module Manifest (`admin.module.json`)
|
|
25
|
+
|
|
26
|
+
- [ ] Has `id` field (format: `@admin/<name>`)
|
|
27
|
+
- [ ] Has `title` field
|
|
28
|
+
- [ ] Has `routeBase` field (starts with `/`)
|
|
29
|
+
- [ ] Has `description` field (recommended)
|
|
30
|
+
- [ ] Has `version` field (recommended)
|
|
31
|
+
- [ ] Has `category` field (recommended)
|
|
32
|
+
- [ ] Has `permissions` object (recommended, values are string arrays)
|
|
33
|
+
- [ ] Has `commands` array (recommended, each with `id`, `title`, `route`)
|
|
34
|
+
- [ ] All command `route` values start with the module's `routeBase`
|
|
35
|
+
|
|
36
|
+
Expected structure:
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"id": "@admin/my-module",
|
|
41
|
+
"title": "My Module",
|
|
42
|
+
"routeBase": "/my-module",
|
|
43
|
+
"description": "My Module admin module",
|
|
44
|
+
"version": "1.0.0",
|
|
45
|
+
"category": "Tools",
|
|
46
|
+
"commands": [{ "id": "home", "title": "Home", "route": "/my-module/home" }],
|
|
47
|
+
"permissions": {
|
|
48
|
+
"view": ["admin.my-module.view"],
|
|
49
|
+
"edit": ["admin.my-module.edit"],
|
|
50
|
+
"delete": ["admin.my-module.delete"]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Dependencies (`package.json`)
|
|
56
|
+
|
|
57
|
+
- [ ] `"type": "module"` is set
|
|
58
|
+
- [ ] Build script is `"tsc && vite build"`
|
|
59
|
+
|
|
60
|
+
### Runtime Dependencies
|
|
61
|
+
|
|
62
|
+
- [ ] `@nsxbet/admin-sdk` — `workspace:*` or git tag version
|
|
63
|
+
- [ ] `@nsxbet/admin-ui` — `workspace:*` or git tag version
|
|
64
|
+
- [ ] `react` — `^18.2.0`
|
|
65
|
+
- [ ] `react-dom` — `^18.2.0`
|
|
66
|
+
- [ ] `react-router-dom` — `^6.20.1`
|
|
67
|
+
|
|
68
|
+
### Dev Dependencies
|
|
69
|
+
|
|
70
|
+
- [ ] `@vitejs/plugin-react` — `^4.2.1`
|
|
71
|
+
- [ ] `vite` — `^5.0.8`
|
|
72
|
+
- [ ] `typescript` — `^5.2.2`
|
|
73
|
+
- [ ] `tailwindcss` — `^3.4.0`
|
|
74
|
+
- [ ] `postcss` — `^8.4.32`
|
|
75
|
+
- [ ] `autoprefixer` — `^10.4.16`
|
|
76
|
+
- [ ] `@nsxbet/eslint-plugin-admin` — (same version as SDK)
|
|
77
|
+
|
|
78
|
+
## Vite Configuration
|
|
79
|
+
|
|
80
|
+
- [ ] Imports `defineModuleConfig` from `@nsxbet/admin-sdk/vite`
|
|
81
|
+
- [ ] Imports and uses `react()` from `@vitejs/plugin-react`
|
|
82
|
+
|
|
83
|
+
Expected:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import { defineModuleConfig } from "@nsxbet/admin-sdk/vite";
|
|
87
|
+
import react from "@vitejs/plugin-react";
|
|
88
|
+
|
|
89
|
+
export default defineModuleConfig({
|
|
90
|
+
port: 3003, // Choose a unique port for your module
|
|
91
|
+
plugins: [react()],
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Tailwind Configuration
|
|
96
|
+
|
|
97
|
+
- [ ] Imports `withAdminSdk` from `@nsxbet/admin-sdk/tailwind`
|
|
98
|
+
|
|
99
|
+
Expected:
|
|
100
|
+
|
|
101
|
+
```javascript
|
|
102
|
+
import { withAdminSdk } from "@nsxbet/admin-sdk/tailwind";
|
|
103
|
+
|
|
104
|
+
export default withAdminSdk({
|
|
105
|
+
content: ["./index.html", "./src/**/*.{ts,tsx}"],
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## PostCSS Configuration
|
|
110
|
+
|
|
111
|
+
- [ ] Has `tailwindcss` and `autoprefixer` plugins
|
|
112
|
+
|
|
113
|
+
Expected:
|
|
114
|
+
|
|
115
|
+
```javascript
|
|
116
|
+
export default {
|
|
117
|
+
plugins: {
|
|
118
|
+
tailwindcss: {},
|
|
119
|
+
autoprefixer: {},
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## CSS Setup (`src/index.css`)
|
|
125
|
+
|
|
126
|
+
- [ ] Imports `@nsxbet/admin-ui/styles.css`
|
|
127
|
+
- [ ] Has `@tailwind base`, `@tailwind components`, `@tailwind utilities`
|
|
128
|
+
|
|
129
|
+
Expected:
|
|
130
|
+
|
|
131
|
+
```css
|
|
132
|
+
@import "@nsxbet/admin-ui/styles.css";
|
|
133
|
+
|
|
134
|
+
@tailwind base;
|
|
135
|
+
@tailwind components;
|
|
136
|
+
@tailwind utilities;
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Entry Points
|
|
140
|
+
|
|
141
|
+
### `src/spa.tsx`
|
|
142
|
+
|
|
143
|
+
- [ ] Has `export default` (the App component)
|
|
144
|
+
|
|
145
|
+
Expected:
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
import { App } from "./App";
|
|
149
|
+
|
|
150
|
+
export default App;
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### `src/standalone.tsx`
|
|
154
|
+
|
|
155
|
+
- [ ] Uses `AdminShell` from `@nsxbet/admin-sdk`
|
|
156
|
+
- [ ] Imports manifest and passes to `modules` prop
|
|
157
|
+
- [ ] Permissions use namespace `admin.<module-name>.*`
|
|
158
|
+
|
|
159
|
+
Expected (simplified):
|
|
160
|
+
|
|
161
|
+
```tsx
|
|
162
|
+
import { AdminShell } from "@nsxbet/admin-sdk";
|
|
163
|
+
import manifest from "../admin.module.json";
|
|
164
|
+
import { App } from "./App";
|
|
165
|
+
|
|
166
|
+
<AdminShell modules={[manifest]} keycloak={config}>
|
|
167
|
+
<App />
|
|
168
|
+
</AdminShell>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### `src/App.tsx`
|
|
172
|
+
|
|
173
|
+
- [ ] Uses `<Routes>` from `react-router-dom`
|
|
174
|
+
|
|
175
|
+
Expected:
|
|
176
|
+
|
|
177
|
+
```tsx
|
|
178
|
+
import { Routes, Route, Navigate } from "react-router-dom";
|
|
179
|
+
|
|
180
|
+
export function App() {
|
|
181
|
+
return (
|
|
182
|
+
<Routes>
|
|
183
|
+
<Route path="/" element={<Navigate to="home" replace />} />
|
|
184
|
+
<Route path="home" element={<HomePage />} />
|
|
185
|
+
</Routes>
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## SDK Hook Usage
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import { useAuth, useFetch, useTelemetry } from "@nsxbet/admin-sdk";
|
|
194
|
+
import { useNavigate } from "react-router-dom";
|
|
195
|
+
|
|
196
|
+
function MyComponent() {
|
|
197
|
+
const { hasPermission, getUser } = useAuth();
|
|
198
|
+
const fetch = useFetch(); // Use this instead of raw fetch()
|
|
199
|
+
const { track } = useTelemetry();
|
|
200
|
+
const navigate = useNavigate(); // From react-router-dom, NOT from SDK
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Anti-Patterns (MUST NOT be present)
|
|
205
|
+
|
|
206
|
+
- [ ] No `@supabase/supabase-js` or `supabase` imports in `src/**`
|
|
207
|
+
- [ ] No `firebase` imports in `src/**`
|
|
208
|
+
- [ ] No `BrowserRouter` or `MemoryRouter` in `src/**` (except `standalone.tsx`)
|
|
209
|
+
- [ ] No `useNavigate` imported from `@nsxbet/admin-sdk` (use `react-router-dom`)
|
|
210
|
+
- [ ] No `@supabase/supabase-js` or `firebase` in `package.json` dependencies
|
|
211
|
+
- [ ] No raw `fetch()` or `window.fetch()` calls — use `useFetch()` from the SDK
|
|
212
|
+
- [ ] Do NOT scaffold shadcn/ui components locally — use `@nsxbet/admin-ui` which ships them pre-configured
|
package/README.md
CHANGED
|
@@ -8,13 +8,45 @@ 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
|
|
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
|
+
|
|
48
|
+
> **Static checklist:** A ready-to-use `CHECKLIST.md` is also shipped inside the SDK package at `node_modules/@nsxbet/admin-sdk/CHECKLIST.md`. You can use it directly without installing the CLI.
|
|
49
|
+
|
|
18
50
|
## Quick Start
|
|
19
51
|
|
|
20
52
|
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 +147,13 @@ export default App;
|
|
|
115
147
|
```tsx
|
|
116
148
|
import React from "react";
|
|
117
149
|
import ReactDOM from "react-dom/client";
|
|
118
|
-
import {
|
|
150
|
+
import {
|
|
151
|
+
AdminShell,
|
|
152
|
+
initI18n,
|
|
153
|
+
i18n,
|
|
154
|
+
createInMemoryAuthClient,
|
|
155
|
+
createMockUsersFromRoles,
|
|
156
|
+
} from "@nsxbet/admin-sdk";
|
|
119
157
|
import type { AdminModuleManifest } from "@nsxbet/admin-sdk";
|
|
120
158
|
import { App } from "./App";
|
|
121
159
|
import manifest from "../admin.module.json";
|
|
@@ -134,9 +172,40 @@ const NAMESPACE = "mymodule";
|
|
|
134
172
|
i18n.addResourceBundle("en-US", NAMESPACE, enUS, true, true);
|
|
135
173
|
i18n.addResourceBundle("pt-BR", NAMESPACE, ptBR, true, true);
|
|
136
174
|
|
|
175
|
+
// Type assertion for JSON import
|
|
176
|
+
const moduleManifest = manifest as AdminModuleManifest;
|
|
177
|
+
|
|
178
|
+
// Check environment variable to toggle between mock auth and Keycloak
|
|
179
|
+
const useKeycloak = import.meta.env.VITE_MOCK_AUTH === "false";
|
|
180
|
+
|
|
181
|
+
// Create mock users with module-specific permissions
|
|
182
|
+
const mockUsers = createMockUsersFromRoles({
|
|
183
|
+
admin: ["admin.mymodule.view", "admin.mymodule.edit", "admin.mymodule.delete"],
|
|
184
|
+
editor: ["admin.mymodule.view", "admin.mymodule.edit"],
|
|
185
|
+
viewer: ["admin.mymodule.view"],
|
|
186
|
+
noAccess: [],
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Use in-memory auth by default (shows user selector), or Keycloak if configured
|
|
190
|
+
const authClient = useKeycloak
|
|
191
|
+
? undefined
|
|
192
|
+
: createInMemoryAuthClient({ users: mockUsers });
|
|
193
|
+
|
|
137
194
|
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
138
195
|
<React.StrictMode>
|
|
139
|
-
<AdminShell
|
|
196
|
+
<AdminShell
|
|
197
|
+
modules={[moduleManifest]}
|
|
198
|
+
authClient={authClient}
|
|
199
|
+
keycloak={
|
|
200
|
+
useKeycloak
|
|
201
|
+
? {
|
|
202
|
+
url: "http://localhost:8080",
|
|
203
|
+
realm: "admin",
|
|
204
|
+
clientId: "admin-shell",
|
|
205
|
+
}
|
|
206
|
+
: undefined
|
|
207
|
+
}
|
|
208
|
+
>
|
|
140
209
|
<App />
|
|
141
210
|
</AdminShell>
|
|
142
211
|
</React.StrictMode>
|
|
@@ -219,6 +288,52 @@ export function ItemList() {
|
|
|
219
288
|
@tailwind utilities;
|
|
220
289
|
```
|
|
221
290
|
|
|
291
|
+
### Directory: `src/i18n/` (optional - for translations)
|
|
292
|
+
|
|
293
|
+
Structure:
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
src/i18n/
|
|
297
|
+
locales/
|
|
298
|
+
en-US.json # English (required)
|
|
299
|
+
pt-BR.json # Portuguese
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Example `src/i18n/locales/en-US.json`:
|
|
303
|
+
|
|
304
|
+
```json
|
|
305
|
+
{
|
|
306
|
+
"module": {
|
|
307
|
+
"title": "My Module",
|
|
308
|
+
"description": "Description of my module"
|
|
309
|
+
},
|
|
310
|
+
"list": {
|
|
311
|
+
"title": "All Items",
|
|
312
|
+
"noItems": "No items found.",
|
|
313
|
+
"create": "Create Item"
|
|
314
|
+
},
|
|
315
|
+
"form": {
|
|
316
|
+
"titleLabel": "Title",
|
|
317
|
+
"titlePlaceholder": "Enter title",
|
|
318
|
+
"cancel": "Cancel",
|
|
319
|
+
"submit": "Submit"
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Use translations in components:
|
|
325
|
+
|
|
326
|
+
```tsx
|
|
327
|
+
import { useI18n } from "@nsxbet/admin-sdk";
|
|
328
|
+
|
|
329
|
+
function MyComponent() {
|
|
330
|
+
const { t } = useI18n();
|
|
331
|
+
|
|
332
|
+
// Use with namespace prefix (set in standalone.tsx)
|
|
333
|
+
return <h1>{t("mymodule:list.title")}</h1>;
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
222
337
|
### File: `tailwind.config.js`
|
|
223
338
|
|
|
224
339
|
Use `withAdminSdk` which automatically includes the UI preset and SDK/UI content paths:
|
|
@@ -241,31 +356,36 @@ export default withAdminSdk({
|
|
|
241
356
|
"type": "module",
|
|
242
357
|
"scripts": {
|
|
243
358
|
"dev": "vite",
|
|
244
|
-
"build": "tsc && vite build
|
|
359
|
+
"build": "tsc && vite build",
|
|
245
360
|
"preview": "vite preview"
|
|
246
361
|
},
|
|
247
362
|
"dependencies": {
|
|
248
363
|
"@nsxbet/admin-sdk": "latest",
|
|
249
364
|
"@nsxbet/admin-ui": "latest",
|
|
250
|
-
"react": "
|
|
251
|
-
"react-dom": "
|
|
252
|
-
"react-router-dom": "
|
|
253
|
-
"i18next": "
|
|
254
|
-
"react-i18next": "
|
|
365
|
+
"react": "18.2.0",
|
|
366
|
+
"react-dom": "18.2.0",
|
|
367
|
+
"react-router-dom": "6.20.1",
|
|
368
|
+
"i18next": "25.0.0",
|
|
369
|
+
"react-i18next": "16.0.0"
|
|
255
370
|
},
|
|
256
371
|
"devDependencies": {
|
|
257
372
|
"@types/react": "^18.2.0",
|
|
258
373
|
"@types/react-dom": "^18.2.0",
|
|
259
374
|
"@vitejs/plugin-react": "^4.2.0",
|
|
260
|
-
"autoprefixer": "
|
|
261
|
-
"postcss": "
|
|
262
|
-
"tailwindcss": "
|
|
375
|
+
"autoprefixer": "10.4.16",
|
|
376
|
+
"postcss": "8.4.32",
|
|
377
|
+
"tailwindcss": "3.4.0",
|
|
378
|
+
"tailwindcss-animate": "1.0.7",
|
|
263
379
|
"typescript": "^5.2.0",
|
|
264
380
|
"vite": "^5.0.0"
|
|
265
381
|
}
|
|
266
382
|
}
|
|
267
383
|
```
|
|
268
384
|
|
|
385
|
+
> **Note:** Exact versions for runtime deps (react, i18next) avoid conflicts with the shell. Exact versions for styling (tailwindcss, postcss) ensure design system consistency.
|
|
386
|
+
|
|
387
|
+
> **Note:** `module.manifest.json` is generated automatically by `defineModuleConfig` at build time. No manual copy step is needed.
|
|
388
|
+
|
|
269
389
|
### File: `tsconfig.json`
|
|
270
390
|
|
|
271
391
|
```json
|
|
@@ -319,6 +439,66 @@ export default {
|
|
|
319
439
|
};
|
|
320
440
|
```
|
|
321
441
|
|
|
442
|
+
### File: `src/globals.d.ts`
|
|
443
|
+
|
|
444
|
+
TypeScript declarations for environment variables and platform API:
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
/// <reference types="vite/client" />
|
|
448
|
+
|
|
449
|
+
declare global {
|
|
450
|
+
interface ImportMetaEnv {
|
|
451
|
+
readonly VITE_MOCK_AUTH?: string;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
interface ImportMeta {
|
|
455
|
+
readonly env: ImportMetaEnv;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
interface Window {
|
|
459
|
+
__ADMIN_PLATFORM_API__?: import("@nsxbet/admin-sdk").PlatformAPI;
|
|
460
|
+
__ENV__?: {
|
|
461
|
+
ENVIRONMENT: string;
|
|
462
|
+
KEYCLOAK_URL: string;
|
|
463
|
+
KEYCLOAK_REALM: string;
|
|
464
|
+
KEYCLOAK_CLIENT_ID: string;
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
export {};
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### File: `tsconfig.node.json`
|
|
473
|
+
|
|
474
|
+
Separate TypeScript config for Vite configuration file:
|
|
475
|
+
|
|
476
|
+
```json
|
|
477
|
+
{
|
|
478
|
+
"compilerOptions": {
|
|
479
|
+
"composite": true,
|
|
480
|
+
"skipLibCheck": true,
|
|
481
|
+
"module": "ESNext",
|
|
482
|
+
"moduleResolution": "bundler",
|
|
483
|
+
"allowSyntheticDefaultImports": true,
|
|
484
|
+
"strict": true
|
|
485
|
+
},
|
|
486
|
+
"include": ["vite.config.ts"]
|
|
487
|
+
}
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### File: `.env.local` (optional)
|
|
491
|
+
|
|
492
|
+
Environment configuration for development:
|
|
493
|
+
|
|
494
|
+
```bash
|
|
495
|
+
# Use mock authentication with user selector (default: true)
|
|
496
|
+
VITE_MOCK_AUTH=true
|
|
497
|
+
|
|
498
|
+
# Set to "false" to use Keycloak authentication
|
|
499
|
+
# VITE_MOCK_AUTH=false
|
|
500
|
+
```
|
|
501
|
+
|
|
322
502
|
## Manifest Schema (`admin.module.json`)
|
|
323
503
|
|
|
324
504
|
| Field | Type | Required | Description |
|
|
@@ -371,11 +551,16 @@ export default defineModuleConfig({
|
|
|
371
551
|
});
|
|
372
552
|
```
|
|
373
553
|
|
|
554
|
+
> **Important:** Each module must use a unique port. The default is `8080` (matching Lovable's default). Modules running alongside Keycloak (which also uses port 8080) should specify an explicit port. Standard assignments:
|
|
555
|
+
> - Shell: 3000
|
|
556
|
+
> - API: 4000
|
|
557
|
+
> - Modules: 3002, 3003, 3004, etc.
|
|
558
|
+
|
|
374
559
|
### Options
|
|
375
560
|
|
|
376
561
|
| Option | Type | Default | Description |
|
|
377
562
|
|--------|------|---------|-------------|
|
|
378
|
-
| `port` | number |
|
|
563
|
+
| `port` | number | `8080` | Dev server port |
|
|
379
564
|
| `entry` | string | `"./src/spa.tsx"` | Entry file path |
|
|
380
565
|
| `outDir` | string | `"dist"` | Output directory |
|
|
381
566
|
| `plugins` | Plugin[] | `[]` | Additional Vite plugins |
|
|
@@ -390,6 +575,19 @@ These dependencies are provided by the shell (do not bundle them):
|
|
|
390
575
|
["react", "react-dom", "react-router-dom", "i18next", "react-i18next"]
|
|
391
576
|
```
|
|
392
577
|
|
|
578
|
+
## ESLint Plugin
|
|
579
|
+
|
|
580
|
+
Install `@nsxbet/eslint-plugin-admin` (requires ESLint 9+) to catch common mistakes at development time:
|
|
581
|
+
|
|
582
|
+
```javascript
|
|
583
|
+
// eslint.config.js
|
|
584
|
+
import adminPlugin from "@nsxbet/eslint-plugin-admin";
|
|
585
|
+
|
|
586
|
+
export default [adminPlugin.configs.recommended];
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
This enables all recommended rules including `@nsxbet/no-raw-fetch` which flags direct `fetch()`/`window.fetch()` calls that bypass authentication. Use `useFetch()` from the SDK instead.
|
|
590
|
+
|
|
393
591
|
## SDK Hooks
|
|
394
592
|
|
|
395
593
|
### `useAuth()`
|
|
@@ -587,6 +785,50 @@ const authClient = createInMemoryAuthClient({ users: customUsers });
|
|
|
587
785
|
| `users` | MockUser[] | **required** | Mock users available for selection |
|
|
588
786
|
| `storageKey` | string | `"@nsxbet/auth"` | localStorage key for persistence |
|
|
589
787
|
|
|
788
|
+
## Keycloak Configuration (Production Auth)
|
|
789
|
+
|
|
790
|
+
For production or when testing with real authentication, configure Keycloak:
|
|
791
|
+
|
|
792
|
+
### Prerequisites
|
|
793
|
+
|
|
794
|
+
1. Keycloak server running (default: `http://localhost:8080`)
|
|
795
|
+
2. Realm named `admin` created
|
|
796
|
+
3. Client named `admin-shell` configured with:
|
|
797
|
+
- Client Protocol: `openid-connect`
|
|
798
|
+
- Access Type: `public`
|
|
799
|
+
- Valid Redirect URIs: `http://localhost:3003/*`
|
|
800
|
+
|
|
801
|
+
### Enable Keycloak in Development
|
|
802
|
+
|
|
803
|
+
Set the environment variable in `.env.local`:
|
|
804
|
+
|
|
805
|
+
```bash
|
|
806
|
+
VITE_MOCK_AUTH=false
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
Or pass the `keycloak` prop directly without `authClient`:
|
|
810
|
+
|
|
811
|
+
```tsx
|
|
812
|
+
<AdminShell
|
|
813
|
+
modules={[manifest]}
|
|
814
|
+
keycloak={{
|
|
815
|
+
url: "http://localhost:8080",
|
|
816
|
+
realm: "admin",
|
|
817
|
+
clientId: "admin-shell",
|
|
818
|
+
}}
|
|
819
|
+
>
|
|
820
|
+
<App />
|
|
821
|
+
</AdminShell>
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
### Keycloak Configuration Options
|
|
825
|
+
|
|
826
|
+
| Option | Type | Description |
|
|
827
|
+
|--------|------|-------------|
|
|
828
|
+
| `url` | string | Keycloak server URL |
|
|
829
|
+
| `realm` | string | Realm name |
|
|
830
|
+
| `clientId` | string | Client ID |
|
|
831
|
+
|
|
590
832
|
## DO NOT (Common Mistakes)
|
|
591
833
|
|
|
592
834
|
### ❌ DO NOT use MemoryRouter
|
|
@@ -690,6 +932,8 @@ import { useNavigate } from "react-router-dom"; // ✅
|
|
|
690
932
|
|
|
691
933
|
## Troubleshooting
|
|
692
934
|
|
|
935
|
+
**First step:** Run `npx @nsxbet/admin-cli checklist` and verify all items. The checklist covers every setup requirement and often identifies misconfigurations quickly.
|
|
936
|
+
|
|
693
937
|
### "Failed to resolve module specifier 'react'"
|
|
694
938
|
|
|
695
939
|
**Cause:** Module is bundling React instead of using shell's version.
|
|
@@ -719,7 +963,7 @@ define: {
|
|
|
719
963
|
|
|
720
964
|
### Styles not working
|
|
721
965
|
|
|
722
|
-
|
|
966
|
+
Run `npx @nsxbet/admin-cli checklist` to verify Tailwind/PostCSS configuration. Key items:
|
|
723
967
|
1. ✅ `index.css` imports `@nsxbet/admin-ui/styles.css`
|
|
724
968
|
2. ✅ `tailwind.config.js` uses `withAdminSdk` from `@nsxbet/admin-sdk/tailwind`
|
|
725
969
|
3. ✅ `postcss.config.js` exists with tailwindcss plugin
|
package/dist/vite/config.d.ts
CHANGED
|
@@ -6,8 +6,9 @@ export declare const SHARED_EXTERNALS: readonly ["react", "react-dom", "react-ro
|
|
|
6
6
|
export interface ModuleConfigOptions {
|
|
7
7
|
/**
|
|
8
8
|
* Development server port
|
|
9
|
+
* @default 8080
|
|
9
10
|
*/
|
|
10
|
-
port
|
|
11
|
+
port?: number;
|
|
11
12
|
/**
|
|
12
13
|
* Entry file for the module SPA
|
|
13
14
|
* @default "./src/spa.tsx"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/vite/config.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,gBAAgB,iFAMnB,CAAC;AAEX,MAAM,WAAW,mBAAmB;IAClC
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/vite/config.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,gBAAgB,iFAMnB,CAAC;AAEX,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B;;OAEG;IAEH,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAEhB;;OAEG;IAEH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,GAAG,CA8CpE"}
|
package/dist/vite/config.js
CHANGED
|
@@ -48,7 +48,7 @@ export const SHARED_EXTERNALS = [
|
|
|
48
48
|
*/
|
|
49
49
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
50
50
|
export function defineModuleConfig(options) {
|
|
51
|
-
const { port, entry = "./src/spa.tsx", outDir = "dist", additionalExternals = [], plugins = [], overrides = {}, } = options;
|
|
51
|
+
const { port = 8080, entry = "./src/spa.tsx", outDir = "dist", additionalExternals = [], plugins = [], overrides = {}, } = options;
|
|
52
52
|
const externals = [...SHARED_EXTERNALS, ...additionalExternals];
|
|
53
53
|
return {
|
|
54
54
|
plugins: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nsxbet/admin-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "SDK for building NSX Admin modules with integrated shell",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,16 +25,19 @@
|
|
|
25
25
|
"./package.json": "./package.json"
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
|
-
"dist"
|
|
28
|
+
"dist",
|
|
29
|
+
"CHECKLIST.md",
|
|
30
|
+
"scripts"
|
|
29
31
|
],
|
|
30
32
|
"scripts": {
|
|
33
|
+
"postinstall": "node scripts/postinstall.js",
|
|
31
34
|
"build": "tsc",
|
|
32
35
|
"dev": "tsc --watch --preserveWatchOutput",
|
|
33
36
|
"type-check": "tsc --noEmit",
|
|
34
37
|
"test": "vitest run --passWithNoTests"
|
|
35
38
|
},
|
|
36
39
|
"peerDependencies": {
|
|
37
|
-
"@nsxbet/admin-ui": "
|
|
40
|
+
"@nsxbet/admin-ui": "^0.2.0",
|
|
38
41
|
"@vitejs/plugin-react": "^4.0.0",
|
|
39
42
|
"i18next": "^23.0.0 || ^24.0.0 || ^25.0.0",
|
|
40
43
|
"react": "^18.2.0",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log("@nsxbet/admin-sdk: Module setup checklist available at node_modules/@nsxbet/admin-sdk/CHECKLIST.md");
|