@gameap/debug 0.2.17 → 0.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gameap/debug",
3
- "version": "0.2.17",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "description": "Debug harness for GameAP plugin development with mock API",
6
6
  "scripts": {
@@ -26,7 +26,7 @@
26
26
  ],
27
27
  "dependencies": {
28
28
  "@gameap/plugin-sdk": "^0.2.0",
29
- "@gameap/frontend": "4.1.0-dev8",
29
+ "@gameap/frontend": "4.1.0-dev9",
30
30
  "@originjs/vite-plugin-commonjs": "^1.0.3",
31
31
  "@tailwindcss/postcss": "^4.1.0",
32
32
  "@vitejs/plugin-vue": "^6.0.1",
package/src/main.ts CHANGED
@@ -8,7 +8,20 @@
8
8
  // Import frontend styles (bundled in vendor directory)
9
9
  import '../vendor/frontend.css'
10
10
 
11
- import { startMockServiceWorker, setPluginContent, updateDebugState } from './mocks/browser'
11
+ import {
12
+ startMockServiceWorker,
13
+ setPluginContent,
14
+ updateDebugState,
15
+ registerMockHandlers,
16
+ resetMockHandlers,
17
+ http,
18
+ HttpResponse,
19
+ delay
20
+ } from './mocks/browser'
21
+ import { mockServersList, type ServerListItem } from './mocks/servers'
22
+ import { userMocks } from './mocks/users'
23
+ import type { UserData } from '@gameap/plugin-sdk'
24
+ import type { RequestHandler } from 'msw'
12
25
 
13
26
  // Declare window globals for plugin compatibility
14
27
  declare global {
@@ -23,6 +36,21 @@ declare global {
23
36
  updateDebugState: typeof updateDebugState
24
37
  setPluginContent: typeof setPluginContent
25
38
  loadPlugin: (js: string, css?: string) => void
39
+ registerMockHandlers: (handlers: RequestHandler[]) => void
40
+ resetMockHandlers: () => void
41
+ msw: {
42
+ http: typeof http
43
+ HttpResponse: typeof HttpResponse
44
+ delay: typeof delay
45
+ }
46
+ mockData: {
47
+ addServer: (server: Partial<ServerListItem>) => ServerListItem
48
+ updateServer: (id: number, updates: Partial<ServerListItem>) => void
49
+ removeServer: (id: number) => void
50
+ getServers: () => ServerListItem[]
51
+ addUser: (key: string, user: UserData) => void
52
+ getUsers: () => Record<string, UserData>
53
+ }
26
54
  }
27
55
  }
28
56
  }
@@ -108,7 +136,69 @@ async function init() {
108
136
  setPluginContent(js, css)
109
137
  }
110
138
 
111
- // Start MSW
139
+ // Expose debug utilities globally BEFORE starting MSW
140
+ // so plugins can register handlers in onInit()
141
+ window.gameapDebug = {
142
+ updateDebugState,
143
+ setPluginContent,
144
+ loadPlugin: (newJs: string, newCss?: string) => {
145
+ setPluginContent(newJs, newCss || '')
146
+ console.log('[Debug] Plugin content updated, reload to apply')
147
+ },
148
+ registerMockHandlers,
149
+ resetMockHandlers,
150
+ msw: {
151
+ http,
152
+ HttpResponse,
153
+ delay,
154
+ },
155
+ mockData: {
156
+ addServer: (server: Partial<ServerListItem>) => {
157
+ const id = Math.max(...mockServersList.map(s => s.id), 0) + 1
158
+ const newServer: ServerListItem = {
159
+ id,
160
+ enabled: true,
161
+ installed: 1,
162
+ blocked: false,
163
+ name: `Server ${id}`,
164
+ game_id: 'minecraft',
165
+ ds_id: 1,
166
+ game_mod_id: 1,
167
+ expires: null,
168
+ server_ip: '127.0.0.1',
169
+ server_port: 25565 + id,
170
+ query_port: 25565 + id,
171
+ rcon_port: 25575 + id,
172
+ process_active: false,
173
+ last_process_check: new Date().toISOString(),
174
+ game: { code: 'minecraft', name: 'Minecraft', engine: 'Minecraft', engine_version: '1' },
175
+ online: false,
176
+ ...server,
177
+ }
178
+ mockServersList.push(newServer)
179
+ return newServer
180
+ },
181
+ updateServer: (id: number, updates: Partial<ServerListItem>) => {
182
+ const idx = mockServersList.findIndex(s => s.id === id)
183
+ if (idx !== -1) {
184
+ Object.assign(mockServersList[idx], updates)
185
+ }
186
+ },
187
+ removeServer: (id: number) => {
188
+ const idx = mockServersList.findIndex(s => s.id === id)
189
+ if (idx !== -1) {
190
+ mockServersList.splice(idx, 1)
191
+ }
192
+ },
193
+ getServers: () => [...mockServersList],
194
+ addUser: (key: string, user: UserData) => {
195
+ userMocks[key] = user
196
+ },
197
+ getUsers: () => ({ ...userMocks }),
198
+ },
199
+ }
200
+
201
+ // Start MSW (will apply any pre-registered handlers)
112
202
  console.log('[Debug] Starting Mock Service Worker...')
113
203
  await startMockServiceWorker()
114
204
  console.log('[Debug] MSW started successfully')
@@ -119,16 +209,6 @@ async function init() {
119
209
  // Load translations AFTER MSW starts (so MSW can intercept the request)
120
210
  await loadTranslations()
121
211
 
122
- // Expose debug utilities globally
123
- window.gameapDebug = {
124
- updateDebugState,
125
- setPluginContent,
126
- loadPlugin: (newJs: string, newCss?: string) => {
127
- setPluginContent(newJs, newCss || '')
128
- console.log('[Debug] Plugin content updated, reload to apply')
129
- },
130
- }
131
-
132
212
  // Now load the real GameAP frontend
133
213
  console.log('[Debug] Loading GameAP frontend...')
134
214
 
@@ -66,3 +66,91 @@ await startMockServiceWorker()
66
66
  ```
67
67
 
68
68
  The debug panel (in main.ts) provides UI controls for switching user types, adjusting network delay, and changing locale.
69
+
70
+ ## Plugin Mock API
71
+
72
+ Plugins can register custom mock handlers for their API endpoints. This is useful for:
73
+ - Adding mock endpoints for plugin-specific APIs
74
+ - Overriding default handler responses
75
+ - Testing different API scenarios
76
+
77
+ ### Registering Mock Handlers
78
+
79
+ In your plugin's `onInit()` hook:
80
+
81
+ ```typescript
82
+ export const myPlugin = {
83
+ id: 'my-plugin',
84
+ name: 'My Plugin',
85
+ version: '1.0.0',
86
+
87
+ onInit() {
88
+ if (window.gameapDebug) {
89
+ const { http, HttpResponse, delay } = window.gameapDebug.msw
90
+
91
+ window.gameapDebug.registerMockHandlers([
92
+ http.get('/api/plugins/my-plugin/data', async () => {
93
+ await delay(100)
94
+ return HttpResponse.json({
95
+ items: [{ id: 1, name: 'Item 1' }]
96
+ })
97
+ }),
98
+ ])
99
+ }
100
+ },
101
+ }
102
+ ```
103
+
104
+ ### MSW Utilities
105
+
106
+ The `window.gameapDebug.msw` object exposes:
107
+
108
+ | Utility | Description |
109
+ |---------|-------------|
110
+ | `http` | HTTP method handlers (`http.get()`, `http.post()`, etc.) |
111
+ | `HttpResponse` | Response builder for mock responses |
112
+ | `delay` | Async delay function for simulating network latency |
113
+
114
+ ### Mock Data Utilities
115
+
116
+ Manipulate mock data programmatically via `window.gameapDebug.mockData`:
117
+
118
+ ```javascript
119
+ // Add a custom server
120
+ const newServer = mockData.addServer({
121
+ name: 'My Test Server',
122
+ game_id: 'minecraft',
123
+ process_active: true
124
+ })
125
+
126
+ // Update existing server
127
+ mockData.updateServer(1, { name: 'Updated Name' })
128
+
129
+ // Remove a server
130
+ mockData.removeServer(3)
131
+
132
+ // Get all servers
133
+ const servers = mockData.getServers()
134
+
135
+ // Add a custom user type
136
+ mockData.addUser('moderator', {
137
+ id: 3,
138
+ login: 'mod',
139
+ name: 'Moderator',
140
+ roles: ['moderator'],
141
+ isAdmin: false,
142
+ isAuthenticated: true
143
+ })
144
+ ```
145
+
146
+ ### Resetting Handlers
147
+
148
+ To restore original handlers (remove all plugin handlers):
149
+
150
+ ```javascript
151
+ window.gameapDebug.resetMockHandlers()
152
+ ```
153
+
154
+ ### Handler Priority
155
+
156
+ Plugin handlers are prepended and checked **first** before default handlers, allowing overrides.
@@ -1,22 +1,57 @@
1
1
  import { setupWorker } from 'msw/browser'
2
+ import { http, HttpResponse, delay, type RequestHandler } from 'msw'
2
3
  import { handlers, debugState, setPluginContent } from './handlers'
3
4
 
5
+ // Store initial handlers for reset capability
6
+ const initialHandlers = [...handlers]
7
+
8
+ // Queue for handlers registered before MSW starts
9
+ let pendingHandlers: RequestHandler[] = []
10
+ let workerStarted = false
11
+
4
12
  export const worker = setupWorker(...handlers)
5
13
 
6
14
  // Export debug state and utilities for external control
7
15
  export { debugState, setPluginContent }
8
16
 
17
+ // Export MSW utilities for plugin use
18
+ export { http, HttpResponse, delay }
19
+
9
20
  // Helper to update debug state
10
21
  export function updateDebugState(updates: Partial<typeof debugState>) {
11
22
  Object.assign(debugState, updates)
12
23
  }
13
24
 
25
+ // Register custom mock handlers (prepends to take priority)
26
+ export function registerMockHandlers(customHandlers: RequestHandler[]) {
27
+ if (!workerStarted) {
28
+ pendingHandlers.push(...customHandlers)
29
+ } else {
30
+ worker.use(...customHandlers)
31
+ }
32
+ }
33
+
34
+ // Reset handlers to initial state (removes all plugin handlers)
35
+ export function resetMockHandlers() {
36
+ worker.resetHandlers(...initialHandlers)
37
+ }
38
+
14
39
  // Start the worker
15
40
  export async function startMockServiceWorker() {
16
- return worker.start({
17
- onUnhandledRequest: 'bypass', // Don't warn about unhandled requests
41
+ const result = await worker.start({
42
+ onUnhandledRequest: 'bypass',
18
43
  serviceWorker: {
19
44
  url: '/mockServiceWorker.js',
20
45
  },
21
46
  })
47
+
48
+ workerStarted = true
49
+
50
+ // Apply any handlers that were registered before start
51
+ if (pendingHandlers.length > 0) {
52
+ worker.use(...pendingHandlers)
53
+ pendingHandlers = []
54
+ }
55
+
56
+ return result
22
57
  }
@@ -361,6 +361,16 @@
361
361
  "disable_success_msg": "Module disabled successfully",
362
362
  "remove_success_msg": "Module removed successfully"
363
363
  },
364
+ "plugins": {
365
+ "plugins": "Plugins",
366
+ "title_list": "Plugin List",
367
+ "installed": "Installed",
368
+ "name": "Plugin name",
369
+ "install": "Install",
370
+ "update": "Update",
371
+ "install_success_msg": "Plugin installed successfully",
372
+ "remove_success_msg": "Plugin removed successfully"
373
+ },
364
374
  "navbar": {
365
375
  "main": "Home",
366
376
  "logs": "Logs",
@@ -362,6 +362,16 @@
362
362
  "disable_success_msg": "Модуль успешно выключен",
363
363
  "remove_success_msg": "Модуль успешно удалён"
364
364
  },
365
+ "plugins": {
366
+ "plugins": "Плагины",
367
+ "title_list": "Список плагинов",
368
+ "installed": "Установленные",
369
+ "name": "Имя плагина",
370
+ "install": "Установить",
371
+ "update": "Обновить",
372
+ "install_success_msg": "Плагин успешно установлен",
373
+ "remove_success_msg": "Плагин успешно удалён"
374
+ },
365
375
  "navbar": {
366
376
  "main": "Главная",
367
377
  "logs": "Логи",