@wp-playground/mcp 3.1.5
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/.eslintrc.json +24 -0
- package/README.md +96 -0
- package/e2e/mcp-tools.spec.ts +679 -0
- package/package.json +46 -0
- package/playwright.config.ts +35 -0
- package/project.json +64 -0
- package/src/bridge-client.ts +196 -0
- package/src/bridge-server.spec.ts +228 -0
- package/src/bridge-server.ts +485 -0
- package/src/client.ts +3 -0
- package/src/index.ts +28 -0
- package/src/mcp-server.ts +34 -0
- package/src/tools/register-mcp-server-tools.ts +347 -0
- package/src/tools/tool-definitions.ts +527 -0
- package/src/tools/tool-executors.ts +205 -0
- package/tsconfig.json +15 -0
- package/tsconfig.lib.json +10 -0
- package/vite.config.ts +49 -0
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool metadata and schema helpers for WordPress Playground.
|
|
3
|
+
*
|
|
4
|
+
* Pure data — no execution logic. Both the MCP server and
|
|
5
|
+
* WebMCP import these for consistent descriptions, annotations,
|
|
6
|
+
* and schema conversion.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export interface ToolAnnotations {
|
|
10
|
+
readOnlyHint?: boolean;
|
|
11
|
+
destructiveHint?: boolean;
|
|
12
|
+
idempotentHint?: boolean;
|
|
13
|
+
openWorldHint?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type ToolParamType = 'string' | 'boolean' | 'object';
|
|
17
|
+
|
|
18
|
+
export interface ToolParam {
|
|
19
|
+
name: string;
|
|
20
|
+
type: ToolParamType;
|
|
21
|
+
description: string;
|
|
22
|
+
required: boolean;
|
|
23
|
+
additionalProperties?: boolean;
|
|
24
|
+
default?: unknown;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ToolDefinition {
|
|
28
|
+
title: string;
|
|
29
|
+
description: string;
|
|
30
|
+
errorPrefix: string;
|
|
31
|
+
annotations: ToolAnnotations;
|
|
32
|
+
params: ToolParam[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const PLAYGROUND_BASE_URL = 'https://playground.wordpress.net/';
|
|
36
|
+
|
|
37
|
+
export function playgroundUrl(port: number): string {
|
|
38
|
+
return `${PLAYGROUND_BASE_URL}?mcp=yes&mcp-port=${port}`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// -- Per-site tool definitions --
|
|
42
|
+
|
|
43
|
+
export const toolDefinitions: Record<string, ToolDefinition> = {
|
|
44
|
+
playground_execute_php: {
|
|
45
|
+
title: 'Execute PHP Code',
|
|
46
|
+
errorPrefix: 'Error executing PHP',
|
|
47
|
+
description: `Run arbitrary PHP code in WordPress Playground
|
|
48
|
+
and return the output.
|
|
49
|
+
|
|
50
|
+
WordPress is NOT bootstrapped automatically. To use
|
|
51
|
+
WordPress functions, start your code with:
|
|
52
|
+
require("/wordpress/wp-load.php");
|
|
53
|
+
Always include the opening <?php tag.
|
|
54
|
+
|
|
55
|
+
The response JSON contains three fields:
|
|
56
|
+
- "text": stdout output
|
|
57
|
+
- "errors": PHP warnings, notices, and fatal error
|
|
58
|
+
messages from stderr
|
|
59
|
+
- "exitCode": 0 on success, non-zero on fatal error
|
|
60
|
+
Check both "errors" and "exitCode" to determine
|
|
61
|
+
whether the call succeeded.
|
|
62
|
+
|
|
63
|
+
WARNING: output is returned in full with no
|
|
64
|
+
truncation — avoid queries that produce unbounded
|
|
65
|
+
output (e.g. SELECT * without LIMIT). Keep output
|
|
66
|
+
under 50 KB to avoid filling the context window.`,
|
|
67
|
+
annotations: {
|
|
68
|
+
readOnlyHint: false,
|
|
69
|
+
destructiveHint: true,
|
|
70
|
+
idempotentHint: false,
|
|
71
|
+
openWorldHint: true,
|
|
72
|
+
},
|
|
73
|
+
params: [
|
|
74
|
+
{
|
|
75
|
+
name: 'code',
|
|
76
|
+
type: 'string',
|
|
77
|
+
description: `PHP code to execute. Example:
|
|
78
|
+
"<?php echo get_bloginfo('name');"`,
|
|
79
|
+
required: true,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
playground_request: {
|
|
84
|
+
title: 'HTTP Request',
|
|
85
|
+
errorPrefix: 'Error making request',
|
|
86
|
+
description: `Make an HTTP request to the WordPress site
|
|
87
|
+
running in Playground. Requests are authenticated
|
|
88
|
+
automatically via the browser session's cookie
|
|
89
|
+
store.
|
|
90
|
+
|
|
91
|
+
Prefer playground_execute_php for reading WordPress
|
|
92
|
+
data (posts, options, plugin state) — it is faster
|
|
93
|
+
and returns only what you echo. Use this tool only
|
|
94
|
+
when the HTTP layer itself is what you are testing,
|
|
95
|
+
for example: verifying that a URL returns a 301
|
|
96
|
+
redirect, that a form submission sets a cookie, or
|
|
97
|
+
that a REST endpoint returns the correct status
|
|
98
|
+
code.
|
|
99
|
+
|
|
100
|
+
Note: full HTML responses can be very large and may
|
|
101
|
+
fill the context window. To change the URL the user
|
|
102
|
+
sees in their tab, use playground_navigate instead.`,
|
|
103
|
+
annotations: {
|
|
104
|
+
readOnlyHint: false,
|
|
105
|
+
destructiveHint: false,
|
|
106
|
+
idempotentHint: false,
|
|
107
|
+
openWorldHint: true,
|
|
108
|
+
},
|
|
109
|
+
params: [
|
|
110
|
+
{
|
|
111
|
+
name: 'url',
|
|
112
|
+
type: 'string',
|
|
113
|
+
description: `Request URL path, e.g.
|
|
114
|
+
"/wp-json/wp/v2/posts" or
|
|
115
|
+
"/wp-admin/plugins.php"`,
|
|
116
|
+
required: true,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'method',
|
|
120
|
+
type: 'string',
|
|
121
|
+
description: `HTTP method (GET, POST, PUT,
|
|
122
|
+
DELETE, etc.). Defaults to GET.`,
|
|
123
|
+
required: false,
|
|
124
|
+
default: 'GET',
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'headers',
|
|
128
|
+
type: 'object',
|
|
129
|
+
description: 'Request headers as key-value pairs',
|
|
130
|
+
required: false,
|
|
131
|
+
additionalProperties: true,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: 'body',
|
|
135
|
+
type: 'string',
|
|
136
|
+
description: 'Request body (for POST/PUT requests)',
|
|
137
|
+
required: false,
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
},
|
|
141
|
+
playground_navigate: {
|
|
142
|
+
title: 'Navigate to URL',
|
|
143
|
+
errorPrefix: 'Error navigating',
|
|
144
|
+
description: `Navigate to a URL path in WordPress
|
|
145
|
+
Playground and return the final URL after any
|
|
146
|
+
redirects. Examples: "/wp-admin/",
|
|
147
|
+
"/wp-login.php", "/".
|
|
148
|
+
|
|
149
|
+
On 404 or error pages, navigation still succeeds
|
|
150
|
+
from the tool's perspective — check the returned
|
|
151
|
+
URL or use playground_request to verify the HTTP
|
|
152
|
+
status code if needed.`,
|
|
153
|
+
annotations: {
|
|
154
|
+
readOnlyHint: false,
|
|
155
|
+
destructiveHint: false,
|
|
156
|
+
idempotentHint: false,
|
|
157
|
+
openWorldHint: true,
|
|
158
|
+
},
|
|
159
|
+
params: [
|
|
160
|
+
{
|
|
161
|
+
name: 'path',
|
|
162
|
+
type: 'string',
|
|
163
|
+
description: `The URL path to navigate to,
|
|
164
|
+
e.g. "/wp-admin/" or
|
|
165
|
+
"/wp-login.php"`,
|
|
166
|
+
required: true,
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
playground_get_current_url: {
|
|
171
|
+
title: 'Get Current URL',
|
|
172
|
+
errorPrefix: 'Error getting current URL',
|
|
173
|
+
description: `Get the current URL path of the WordPress
|
|
174
|
+
site displayed in Playground. For additional
|
|
175
|
+
metadata (WordPress version, PHP version, document
|
|
176
|
+
root), use playground_get_site_info instead.`,
|
|
177
|
+
annotations: {
|
|
178
|
+
readOnlyHint: true,
|
|
179
|
+
destructiveHint: false,
|
|
180
|
+
openWorldHint: true,
|
|
181
|
+
},
|
|
182
|
+
params: [],
|
|
183
|
+
},
|
|
184
|
+
playground_get_site_info: {
|
|
185
|
+
title: 'Get Site Info',
|
|
186
|
+
errorPrefix: 'Error getting site info',
|
|
187
|
+
description: `Get metadata about the running WordPress
|
|
188
|
+
instance: current URL, document root, site URL,
|
|
189
|
+
WordPress version, and PHP version. Use this when
|
|
190
|
+
you need version information or the document root
|
|
191
|
+
path. For just the current URL, prefer
|
|
192
|
+
playground_get_current_url.`,
|
|
193
|
+
annotations: {
|
|
194
|
+
readOnlyHint: true,
|
|
195
|
+
destructiveHint: false,
|
|
196
|
+
openWorldHint: true,
|
|
197
|
+
},
|
|
198
|
+
params: [],
|
|
199
|
+
},
|
|
200
|
+
playground_read_file: {
|
|
201
|
+
title: 'Read File',
|
|
202
|
+
errorPrefix: 'Error reading file',
|
|
203
|
+
description: `Read a file from the WordPress virtual
|
|
204
|
+
filesystem. Returns the file contents as text.`,
|
|
205
|
+
annotations: {
|
|
206
|
+
readOnlyHint: true,
|
|
207
|
+
destructiveHint: false,
|
|
208
|
+
openWorldHint: true,
|
|
209
|
+
},
|
|
210
|
+
params: [
|
|
211
|
+
{
|
|
212
|
+
name: 'path',
|
|
213
|
+
type: 'string',
|
|
214
|
+
description: `Absolute path to the file, e.g.
|
|
215
|
+
"/wordpress/wp-config.php"`,
|
|
216
|
+
required: true,
|
|
217
|
+
},
|
|
218
|
+
],
|
|
219
|
+
},
|
|
220
|
+
playground_write_file: {
|
|
221
|
+
title: 'Write File',
|
|
222
|
+
errorPrefix: 'Error writing file',
|
|
223
|
+
description: `Write content to a file in the WordPress
|
|
224
|
+
virtual filesystem.
|
|
225
|
+
|
|
226
|
+
WARNING: Overwrites the entire file — existing
|
|
227
|
+
content is permanently lost. Read the file first
|
|
228
|
+
with playground_read_file if you need to preserve
|
|
229
|
+
any content.
|
|
230
|
+
|
|
231
|
+
Creates the file if it does not exist. Parent
|
|
232
|
+
directories are NOT created automatically — call
|
|
233
|
+
playground_mkdir first if needed, otherwise the
|
|
234
|
+
write will fail with a "no such file or directory"
|
|
235
|
+
error.`,
|
|
236
|
+
annotations: {
|
|
237
|
+
readOnlyHint: false,
|
|
238
|
+
destructiveHint: true,
|
|
239
|
+
idempotentHint: false,
|
|
240
|
+
openWorldHint: true,
|
|
241
|
+
},
|
|
242
|
+
params: [
|
|
243
|
+
{
|
|
244
|
+
name: 'path',
|
|
245
|
+
type: 'string',
|
|
246
|
+
description: `Absolute path to write to, e.g.
|
|
247
|
+
"/wordpress/wp-content/test.txt"`,
|
|
248
|
+
required: true,
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
name: 'contents',
|
|
252
|
+
type: 'string',
|
|
253
|
+
description: 'File contents to write',
|
|
254
|
+
required: true,
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
|
+
},
|
|
258
|
+
playground_list_files: {
|
|
259
|
+
title: 'List Files',
|
|
260
|
+
errorPrefix: 'Error listing files',
|
|
261
|
+
description: `List files and directories at a given path
|
|
262
|
+
in the WordPress virtual filesystem. Returns a
|
|
263
|
+
flat, non-recursive listing of the immediate
|
|
264
|
+
contents. To explore subdirectories, call this tool
|
|
265
|
+
again with the subdirectory path.`,
|
|
266
|
+
annotations: {
|
|
267
|
+
readOnlyHint: true,
|
|
268
|
+
destructiveHint: false,
|
|
269
|
+
openWorldHint: true,
|
|
270
|
+
},
|
|
271
|
+
params: [
|
|
272
|
+
{
|
|
273
|
+
name: 'path',
|
|
274
|
+
type: 'string',
|
|
275
|
+
description: `Absolute path to list, e.g.
|
|
276
|
+
"/wordpress/wp-content/plugins"`,
|
|
277
|
+
required: true,
|
|
278
|
+
},
|
|
279
|
+
],
|
|
280
|
+
},
|
|
281
|
+
playground_mkdir: {
|
|
282
|
+
title: 'Create Directory',
|
|
283
|
+
errorPrefix: 'Error creating directory',
|
|
284
|
+
description: `Create a directory (and all required parent
|
|
285
|
+
directories) in the WordPress virtual filesystem.
|
|
286
|
+
Call this before playground_write_file when writing
|
|
287
|
+
to a path whose parent directories do not yet
|
|
288
|
+
exist.`,
|
|
289
|
+
annotations: {
|
|
290
|
+
readOnlyHint: false,
|
|
291
|
+
destructiveHint: false,
|
|
292
|
+
idempotentHint: true,
|
|
293
|
+
openWorldHint: true,
|
|
294
|
+
},
|
|
295
|
+
params: [
|
|
296
|
+
{
|
|
297
|
+
name: 'path',
|
|
298
|
+
type: 'string',
|
|
299
|
+
description: `Absolute path of directory to
|
|
300
|
+
create, e.g.
|
|
301
|
+
"/wordpress/wp-content/my-plugin"`,
|
|
302
|
+
required: true,
|
|
303
|
+
},
|
|
304
|
+
],
|
|
305
|
+
},
|
|
306
|
+
playground_delete_file: {
|
|
307
|
+
title: 'Delete File',
|
|
308
|
+
errorPrefix: 'Error deleting file',
|
|
309
|
+
description: `Delete a file from the WordPress virtual
|
|
310
|
+
filesystem.
|
|
311
|
+
|
|
312
|
+
WARNING: Deletion is permanent and cannot be
|
|
313
|
+
undone. Returns an error if the file does not
|
|
314
|
+
exist — use playground_file_exists first if
|
|
315
|
+
deletion is conditional.`,
|
|
316
|
+
annotations: {
|
|
317
|
+
readOnlyHint: false,
|
|
318
|
+
destructiveHint: true,
|
|
319
|
+
idempotentHint: false,
|
|
320
|
+
openWorldHint: true,
|
|
321
|
+
},
|
|
322
|
+
params: [
|
|
323
|
+
{
|
|
324
|
+
name: 'path',
|
|
325
|
+
type: 'string',
|
|
326
|
+
description: 'Absolute path of file to delete',
|
|
327
|
+
required: true,
|
|
328
|
+
},
|
|
329
|
+
],
|
|
330
|
+
},
|
|
331
|
+
playground_delete_directory: {
|
|
332
|
+
title: 'Delete Directory',
|
|
333
|
+
errorPrefix: 'Error deleting directory',
|
|
334
|
+
description: `Delete a directory from the WordPress
|
|
335
|
+
virtual filesystem.
|
|
336
|
+
|
|
337
|
+
WARNING: Deletion is permanent and cannot be
|
|
338
|
+
undone. By default (recursive=false), the directory
|
|
339
|
+
must be empty or the call will fail. Set
|
|
340
|
+
recursive=true to delete a directory and all its
|
|
341
|
+
contents — use with care.`,
|
|
342
|
+
annotations: {
|
|
343
|
+
readOnlyHint: false,
|
|
344
|
+
destructiveHint: true,
|
|
345
|
+
idempotentHint: false,
|
|
346
|
+
openWorldHint: true,
|
|
347
|
+
},
|
|
348
|
+
params: [
|
|
349
|
+
{
|
|
350
|
+
name: 'path',
|
|
351
|
+
type: 'string',
|
|
352
|
+
description: 'Absolute path of directory to delete',
|
|
353
|
+
required: true,
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
name: 'recursive',
|
|
357
|
+
type: 'boolean',
|
|
358
|
+
description: `If true, delete directory and
|
|
359
|
+
all contents. If false (default), fails
|
|
360
|
+
on non-empty directories.`,
|
|
361
|
+
required: false,
|
|
362
|
+
default: false,
|
|
363
|
+
},
|
|
364
|
+
],
|
|
365
|
+
},
|
|
366
|
+
playground_file_exists: {
|
|
367
|
+
title: 'File Exists',
|
|
368
|
+
errorPrefix: 'Error checking file existence',
|
|
369
|
+
description: `Check whether a file or directory exists
|
|
370
|
+
in the WordPress virtual filesystem.`,
|
|
371
|
+
annotations: {
|
|
372
|
+
readOnlyHint: true,
|
|
373
|
+
destructiveHint: false,
|
|
374
|
+
openWorldHint: true,
|
|
375
|
+
},
|
|
376
|
+
params: [
|
|
377
|
+
{
|
|
378
|
+
name: 'path',
|
|
379
|
+
type: 'string',
|
|
380
|
+
description: 'Absolute path to check',
|
|
381
|
+
required: true,
|
|
382
|
+
},
|
|
383
|
+
],
|
|
384
|
+
},
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
// -- Site management tool definitions --
|
|
388
|
+
|
|
389
|
+
export function getSiteToolDefinitions(
|
|
390
|
+
port: number
|
|
391
|
+
): Record<string, ToolDefinition> {
|
|
392
|
+
const url = playgroundUrl(port);
|
|
393
|
+
return {
|
|
394
|
+
playground_list_sites: {
|
|
395
|
+
title: 'List Available Sites',
|
|
396
|
+
errorPrefix: 'Error listing sites',
|
|
397
|
+
description: `List all WordPress Playground sites
|
|
398
|
+
available. Call this before any other playground
|
|
399
|
+
tool — it returns the siteId required by every
|
|
400
|
+
other operation.
|
|
401
|
+
|
|
402
|
+
If this returns no sites, the user may need to
|
|
403
|
+
open Playground at ${url} .
|
|
404
|
+
|
|
405
|
+
Returns site names and storage type. "temporary"
|
|
406
|
+
sites are lost on page reload, "opfs" sites persist
|
|
407
|
+
across reloads. Call playground_save_site to persist
|
|
408
|
+
a temporary site.`,
|
|
409
|
+
annotations: {
|
|
410
|
+
readOnlyHint: true,
|
|
411
|
+
destructiveHint: false,
|
|
412
|
+
},
|
|
413
|
+
params: [],
|
|
414
|
+
},
|
|
415
|
+
playground_open_site: {
|
|
416
|
+
title: 'Open Site in Browser',
|
|
417
|
+
errorPrefix: 'Error opening site',
|
|
418
|
+
description: `Open a WordPress Playground site in a new
|
|
419
|
+
browser tab. The site must appear in
|
|
420
|
+
playground_list_sites.
|
|
421
|
+
|
|
422
|
+
Check playground_get_current_url first — if the
|
|
423
|
+
site is already open in a tab, calling this tool
|
|
424
|
+
will open a second tab rather than switching to
|
|
425
|
+
the existing one.`,
|
|
426
|
+
annotations: {
|
|
427
|
+
readOnlyHint: false,
|
|
428
|
+
destructiveHint: false,
|
|
429
|
+
},
|
|
430
|
+
params: [],
|
|
431
|
+
},
|
|
432
|
+
playground_rename_site: {
|
|
433
|
+
title: 'Rename Site',
|
|
434
|
+
errorPrefix: 'Error renaming site',
|
|
435
|
+
description: `Rename a WordPress Playground site. Updates
|
|
436
|
+
the display name shown in the browser UI.`,
|
|
437
|
+
annotations: {
|
|
438
|
+
readOnlyHint: false,
|
|
439
|
+
destructiveHint: false,
|
|
440
|
+
},
|
|
441
|
+
params: [
|
|
442
|
+
{
|
|
443
|
+
name: 'newName',
|
|
444
|
+
type: 'string',
|
|
445
|
+
description: 'The new display name for the site',
|
|
446
|
+
required: true,
|
|
447
|
+
},
|
|
448
|
+
],
|
|
449
|
+
},
|
|
450
|
+
playground_save_site: {
|
|
451
|
+
title: 'Save Site',
|
|
452
|
+
errorPrefix: 'Error saving site',
|
|
453
|
+
description: `Save a temporary WordPress Playground site
|
|
454
|
+
to browser storage so it survives page reloads.
|
|
455
|
+
Safe to call even if the site is already saved
|
|
456
|
+
(no-op).
|
|
457
|
+
|
|
458
|
+
Sites start as temporary by default and are lost
|
|
459
|
+
when the browser tab is closed or the page is
|
|
460
|
+
reloaded. Call this early in any multi-step
|
|
461
|
+
workflow where losing progress would be costly.`,
|
|
462
|
+
annotations: {
|
|
463
|
+
readOnlyHint: false,
|
|
464
|
+
destructiveHint: false,
|
|
465
|
+
},
|
|
466
|
+
params: [],
|
|
467
|
+
},
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
export function stringifyError(error: unknown): string {
|
|
472
|
+
if (error instanceof Error) {
|
|
473
|
+
return error.message;
|
|
474
|
+
}
|
|
475
|
+
if (typeof error === 'string') {
|
|
476
|
+
return error;
|
|
477
|
+
}
|
|
478
|
+
try {
|
|
479
|
+
return JSON.stringify(error);
|
|
480
|
+
} catch {
|
|
481
|
+
return String(error);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Translate internal Playground storage types to user-facing names.
|
|
487
|
+
*/
|
|
488
|
+
export function presentStorage(raw: string): string {
|
|
489
|
+
return raw === 'none' ? 'temporary' : raw;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Convert ToolParam[] to a plain JSON Schema object.
|
|
494
|
+
* Used by WebMCP which expects raw JSON Schema (not Zod).
|
|
495
|
+
*/
|
|
496
|
+
export function paramsToJsonSchema(
|
|
497
|
+
params: ToolParam[]
|
|
498
|
+
): Record<string, unknown> {
|
|
499
|
+
const properties: Record<string, Record<string, unknown>> = {};
|
|
500
|
+
const required: string[] = [];
|
|
501
|
+
|
|
502
|
+
for (const param of params) {
|
|
503
|
+
const prop: Record<string, unknown> = {
|
|
504
|
+
type: param.type,
|
|
505
|
+
description: param.description,
|
|
506
|
+
};
|
|
507
|
+
if (param.additionalProperties !== undefined) {
|
|
508
|
+
prop['additionalProperties'] = param.additionalProperties;
|
|
509
|
+
}
|
|
510
|
+
if (param.default !== undefined) {
|
|
511
|
+
prop['default'] = param.default;
|
|
512
|
+
}
|
|
513
|
+
properties[param.name] = prop;
|
|
514
|
+
if (param.required) {
|
|
515
|
+
required.push(param.name);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
const schema: Record<string, unknown> = {
|
|
520
|
+
type: 'object',
|
|
521
|
+
properties,
|
|
522
|
+
};
|
|
523
|
+
if (required.length > 0) {
|
|
524
|
+
schema['required'] = required;
|
|
525
|
+
}
|
|
526
|
+
return schema;
|
|
527
|
+
}
|