@decocms/runtime 1.0.0-alpha.14 → 1.0.0-alpha.17
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/config-schema.json +553 -0
- package/package.json +2 -2
- package/src/cors.ts +140 -0
- package/src/index.ts +30 -2
- package/src/tools.ts +2 -0
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$ref": "#/definitions/WranglerConfig",
|
|
4
|
+
"definitions": {
|
|
5
|
+
"WranglerConfig": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"name": {
|
|
9
|
+
"type": "string"
|
|
10
|
+
},
|
|
11
|
+
"main": {
|
|
12
|
+
"type": "string"
|
|
13
|
+
},
|
|
14
|
+
"scope": {
|
|
15
|
+
"type": "string"
|
|
16
|
+
},
|
|
17
|
+
"main_module": {
|
|
18
|
+
"type": "string"
|
|
19
|
+
},
|
|
20
|
+
"routes": {
|
|
21
|
+
"type": "array",
|
|
22
|
+
"items": {
|
|
23
|
+
"$ref": "#/definitions/Route"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"compatibility_date": {
|
|
27
|
+
"type": "string"
|
|
28
|
+
},
|
|
29
|
+
"compatibility_flags": {
|
|
30
|
+
"type": "array",
|
|
31
|
+
"items": {
|
|
32
|
+
"type": "string"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"vars": {
|
|
36
|
+
"type": "object",
|
|
37
|
+
"additionalProperties": {
|
|
38
|
+
"type": "string"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"kv_namespaces": {
|
|
42
|
+
"type": "array",
|
|
43
|
+
"items": {
|
|
44
|
+
"$ref": "#/definitions/KVNamespace"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"triggers": {
|
|
48
|
+
"$ref": "#/definitions/Triggers"
|
|
49
|
+
},
|
|
50
|
+
"ai": {
|
|
51
|
+
"type": "object",
|
|
52
|
+
"properties": {
|
|
53
|
+
"binding": {
|
|
54
|
+
"type": "string"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"required": [
|
|
58
|
+
"binding"
|
|
59
|
+
],
|
|
60
|
+
"additionalProperties": false
|
|
61
|
+
},
|
|
62
|
+
"browser": {
|
|
63
|
+
"type": "object",
|
|
64
|
+
"properties": {
|
|
65
|
+
"binding": {
|
|
66
|
+
"type": "string"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"required": [
|
|
70
|
+
"binding"
|
|
71
|
+
],
|
|
72
|
+
"additionalProperties": false
|
|
73
|
+
},
|
|
74
|
+
"durable_objects": {
|
|
75
|
+
"type": "object",
|
|
76
|
+
"properties": {
|
|
77
|
+
"bindings": {
|
|
78
|
+
"type": "array",
|
|
79
|
+
"items": {
|
|
80
|
+
"type": "object",
|
|
81
|
+
"properties": {
|
|
82
|
+
"name": {
|
|
83
|
+
"type": "string"
|
|
84
|
+
},
|
|
85
|
+
"class_name": {
|
|
86
|
+
"type": "string"
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"required": [
|
|
90
|
+
"name",
|
|
91
|
+
"class_name"
|
|
92
|
+
],
|
|
93
|
+
"additionalProperties": false
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"additionalProperties": false
|
|
98
|
+
},
|
|
99
|
+
"hyperdrive": {
|
|
100
|
+
"type": "array",
|
|
101
|
+
"items": {
|
|
102
|
+
"type": "object",
|
|
103
|
+
"properties": {
|
|
104
|
+
"binding": {
|
|
105
|
+
"type": "string"
|
|
106
|
+
},
|
|
107
|
+
"id": {
|
|
108
|
+
"type": "string"
|
|
109
|
+
},
|
|
110
|
+
"localConnectionString": {
|
|
111
|
+
"type": "string"
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"required": [
|
|
115
|
+
"binding",
|
|
116
|
+
"id",
|
|
117
|
+
"localConnectionString"
|
|
118
|
+
],
|
|
119
|
+
"additionalProperties": false
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"d1_databases": {
|
|
123
|
+
"type": "array",
|
|
124
|
+
"items": {
|
|
125
|
+
"type": "object",
|
|
126
|
+
"properties": {
|
|
127
|
+
"database_name": {
|
|
128
|
+
"type": "string"
|
|
129
|
+
},
|
|
130
|
+
"database_id": {
|
|
131
|
+
"type": "string"
|
|
132
|
+
},
|
|
133
|
+
"binding": {
|
|
134
|
+
"type": "string"
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"required": [
|
|
138
|
+
"database_name",
|
|
139
|
+
"binding"
|
|
140
|
+
],
|
|
141
|
+
"additionalProperties": false
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"queues": {
|
|
145
|
+
"type": "object",
|
|
146
|
+
"properties": {
|
|
147
|
+
"consumers": {
|
|
148
|
+
"type": "array",
|
|
149
|
+
"items": {
|
|
150
|
+
"type": "object",
|
|
151
|
+
"properties": {
|
|
152
|
+
"queue": {
|
|
153
|
+
"type": "string"
|
|
154
|
+
},
|
|
155
|
+
"max_batch_timeout": {
|
|
156
|
+
"type": "number"
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
"required": [
|
|
160
|
+
"queue",
|
|
161
|
+
"max_batch_timeout"
|
|
162
|
+
],
|
|
163
|
+
"additionalProperties": false
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
"producers": {
|
|
167
|
+
"type": "array",
|
|
168
|
+
"items": {
|
|
169
|
+
"type": "object",
|
|
170
|
+
"properties": {
|
|
171
|
+
"queue": {
|
|
172
|
+
"type": "string"
|
|
173
|
+
},
|
|
174
|
+
"binding": {
|
|
175
|
+
"type": "string"
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
"required": [
|
|
179
|
+
"queue",
|
|
180
|
+
"binding"
|
|
181
|
+
],
|
|
182
|
+
"additionalProperties": false
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
"additionalProperties": false
|
|
187
|
+
},
|
|
188
|
+
"workflows": {
|
|
189
|
+
"type": "array",
|
|
190
|
+
"items": {
|
|
191
|
+
"type": "object",
|
|
192
|
+
"properties": {
|
|
193
|
+
"name": {
|
|
194
|
+
"type": "string"
|
|
195
|
+
},
|
|
196
|
+
"binding": {
|
|
197
|
+
"type": "string"
|
|
198
|
+
},
|
|
199
|
+
"class_name": {
|
|
200
|
+
"type": "string"
|
|
201
|
+
},
|
|
202
|
+
"script_name": {
|
|
203
|
+
"type": "string"
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
"required": [
|
|
207
|
+
"name",
|
|
208
|
+
"binding"
|
|
209
|
+
],
|
|
210
|
+
"additionalProperties": false
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
"migrations": {
|
|
214
|
+
"type": "array",
|
|
215
|
+
"items": {
|
|
216
|
+
"$ref": "#/definitions/Migration"
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
"assets": {
|
|
220
|
+
"type": "object",
|
|
221
|
+
"properties": {
|
|
222
|
+
"directory": {
|
|
223
|
+
"type": "string"
|
|
224
|
+
},
|
|
225
|
+
"binding": {
|
|
226
|
+
"type": "string"
|
|
227
|
+
},
|
|
228
|
+
"jwt": {
|
|
229
|
+
"type": "string"
|
|
230
|
+
},
|
|
231
|
+
"not_found_handling": {
|
|
232
|
+
"type": "string",
|
|
233
|
+
"enum": [
|
|
234
|
+
"none",
|
|
235
|
+
"404-page",
|
|
236
|
+
"single-page-application"
|
|
237
|
+
]
|
|
238
|
+
},
|
|
239
|
+
"run_worker_first": {
|
|
240
|
+
"type": "boolean"
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
"additionalProperties": false
|
|
244
|
+
},
|
|
245
|
+
"keep_assets": {
|
|
246
|
+
"type": "boolean"
|
|
247
|
+
},
|
|
248
|
+
"deco": {
|
|
249
|
+
"type": "object",
|
|
250
|
+
"properties": {
|
|
251
|
+
"enable_workflows": {
|
|
252
|
+
"type": "boolean"
|
|
253
|
+
},
|
|
254
|
+
"workspace": {
|
|
255
|
+
"type": "string"
|
|
256
|
+
},
|
|
257
|
+
"local": {
|
|
258
|
+
"type": "boolean"
|
|
259
|
+
},
|
|
260
|
+
"integration": {
|
|
261
|
+
"type": "object",
|
|
262
|
+
"properties": {
|
|
263
|
+
"friendlyName": {
|
|
264
|
+
"type": "string"
|
|
265
|
+
},
|
|
266
|
+
"icon": {
|
|
267
|
+
"type": "string"
|
|
268
|
+
},
|
|
269
|
+
"description": {
|
|
270
|
+
"type": "string"
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
"additionalProperties": false
|
|
274
|
+
},
|
|
275
|
+
"bindings": {
|
|
276
|
+
"type": "array",
|
|
277
|
+
"items": {
|
|
278
|
+
"$ref": "#/definitions/Binding"
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
"additionalProperties": false
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
"required": [
|
|
286
|
+
"name"
|
|
287
|
+
],
|
|
288
|
+
"additionalProperties": false
|
|
289
|
+
},
|
|
290
|
+
"Route": {
|
|
291
|
+
"type": "object",
|
|
292
|
+
"properties": {
|
|
293
|
+
"pattern": {
|
|
294
|
+
"type": "string"
|
|
295
|
+
},
|
|
296
|
+
"custom_domain": {
|
|
297
|
+
"type": "boolean"
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
"required": [
|
|
301
|
+
"pattern"
|
|
302
|
+
],
|
|
303
|
+
"additionalProperties": false
|
|
304
|
+
},
|
|
305
|
+
"KVNamespace": {
|
|
306
|
+
"type": "object",
|
|
307
|
+
"properties": {
|
|
308
|
+
"binding": {
|
|
309
|
+
"type": "string"
|
|
310
|
+
},
|
|
311
|
+
"id": {
|
|
312
|
+
"type": "string"
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
"required": [
|
|
316
|
+
"binding",
|
|
317
|
+
"id"
|
|
318
|
+
],
|
|
319
|
+
"additionalProperties": false
|
|
320
|
+
},
|
|
321
|
+
"Triggers": {
|
|
322
|
+
"type": "object",
|
|
323
|
+
"properties": {
|
|
324
|
+
"crons": {
|
|
325
|
+
"type": "array",
|
|
326
|
+
"items": {
|
|
327
|
+
"type": "string"
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
"required": [
|
|
332
|
+
"crons"
|
|
333
|
+
],
|
|
334
|
+
"additionalProperties": false
|
|
335
|
+
},
|
|
336
|
+
"Migration": {
|
|
337
|
+
"anyOf": [
|
|
338
|
+
{
|
|
339
|
+
"$ref": "#/definitions/NewClassMigration"
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
"$ref": "#/definitions/DeletedClassMigration"
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"$ref": "#/definitions/RenamedClassMigration"
|
|
346
|
+
}
|
|
347
|
+
]
|
|
348
|
+
},
|
|
349
|
+
"NewClassMigration": {
|
|
350
|
+
"type": "object",
|
|
351
|
+
"properties": {
|
|
352
|
+
"tag": {
|
|
353
|
+
"type": "string"
|
|
354
|
+
},
|
|
355
|
+
"new_classes": {
|
|
356
|
+
"type": "array",
|
|
357
|
+
"items": {
|
|
358
|
+
"type": "string"
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
"new_sqlite_classes": {
|
|
362
|
+
"type": "array",
|
|
363
|
+
"items": {
|
|
364
|
+
"type": "string"
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
},
|
|
368
|
+
"additionalProperties": false,
|
|
369
|
+
"required": [
|
|
370
|
+
"tag"
|
|
371
|
+
]
|
|
372
|
+
},
|
|
373
|
+
"DeletedClassMigration": {
|
|
374
|
+
"type": "object",
|
|
375
|
+
"properties": {
|
|
376
|
+
"tag": {
|
|
377
|
+
"type": "string"
|
|
378
|
+
},
|
|
379
|
+
"deleted_classes": {
|
|
380
|
+
"type": "array",
|
|
381
|
+
"items": {
|
|
382
|
+
"type": "string"
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
},
|
|
386
|
+
"required": [
|
|
387
|
+
"deleted_classes",
|
|
388
|
+
"tag"
|
|
389
|
+
],
|
|
390
|
+
"additionalProperties": false
|
|
391
|
+
},
|
|
392
|
+
"RenamedClassMigration": {
|
|
393
|
+
"type": "object",
|
|
394
|
+
"properties": {
|
|
395
|
+
"tag": {
|
|
396
|
+
"type": "string"
|
|
397
|
+
},
|
|
398
|
+
"renamed_classes": {
|
|
399
|
+
"type": "array",
|
|
400
|
+
"items": {
|
|
401
|
+
"type": "object",
|
|
402
|
+
"properties": {
|
|
403
|
+
"from": {
|
|
404
|
+
"type": "string"
|
|
405
|
+
},
|
|
406
|
+
"to": {
|
|
407
|
+
"type": "string"
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
"required": [
|
|
411
|
+
"from",
|
|
412
|
+
"to"
|
|
413
|
+
],
|
|
414
|
+
"additionalProperties": false
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
},
|
|
418
|
+
"required": [
|
|
419
|
+
"renamed_classes",
|
|
420
|
+
"tag"
|
|
421
|
+
],
|
|
422
|
+
"additionalProperties": false
|
|
423
|
+
},
|
|
424
|
+
"Binding": {
|
|
425
|
+
"anyOf": [
|
|
426
|
+
{
|
|
427
|
+
"$ref": "#/definitions/MCPBinding"
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
"$ref": "#/definitions/ContractBinding"
|
|
431
|
+
}
|
|
432
|
+
]
|
|
433
|
+
},
|
|
434
|
+
"MCPBinding": {
|
|
435
|
+
"anyOf": [
|
|
436
|
+
{
|
|
437
|
+
"$ref": "#/definitions/MCPConnectionBinding"
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
"$ref": "#/definitions/MCPAppBinding"
|
|
441
|
+
}
|
|
442
|
+
]
|
|
443
|
+
},
|
|
444
|
+
"MCPConnectionBinding": {
|
|
445
|
+
"type": "object",
|
|
446
|
+
"properties": {
|
|
447
|
+
"name": {
|
|
448
|
+
"type": "string"
|
|
449
|
+
},
|
|
450
|
+
"type": {
|
|
451
|
+
"type": "string",
|
|
452
|
+
"const": "mcp"
|
|
453
|
+
},
|
|
454
|
+
"connection_id": {
|
|
455
|
+
"type": "string",
|
|
456
|
+
"description": "If not provided, will return a function that takes the integration id and return the binding implementation.."
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
"required": [
|
|
460
|
+
"connection_id",
|
|
461
|
+
"name",
|
|
462
|
+
"type"
|
|
463
|
+
],
|
|
464
|
+
"additionalProperties": false
|
|
465
|
+
},
|
|
466
|
+
"MCPAppBinding": {
|
|
467
|
+
"type": "object",
|
|
468
|
+
"properties": {
|
|
469
|
+
"name": {
|
|
470
|
+
"type": "string"
|
|
471
|
+
},
|
|
472
|
+
"type": {
|
|
473
|
+
"type": "string",
|
|
474
|
+
"const": "mcp"
|
|
475
|
+
},
|
|
476
|
+
"app_name": {
|
|
477
|
+
"type": "string",
|
|
478
|
+
"description": "The name of the integration to bind."
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
"required": [
|
|
482
|
+
"app_name",
|
|
483
|
+
"name",
|
|
484
|
+
"type"
|
|
485
|
+
],
|
|
486
|
+
"additionalProperties": false
|
|
487
|
+
},
|
|
488
|
+
"ContractBinding": {
|
|
489
|
+
"type": "object",
|
|
490
|
+
"properties": {
|
|
491
|
+
"name": {
|
|
492
|
+
"type": "string"
|
|
493
|
+
},
|
|
494
|
+
"type": {
|
|
495
|
+
"type": "string",
|
|
496
|
+
"const": "contract"
|
|
497
|
+
},
|
|
498
|
+
"contract": {
|
|
499
|
+
"$ref": "#/definitions/Contract",
|
|
500
|
+
"description": "The clauses of this contract"
|
|
501
|
+
}
|
|
502
|
+
},
|
|
503
|
+
"required": [
|
|
504
|
+
"contract",
|
|
505
|
+
"name",
|
|
506
|
+
"type"
|
|
507
|
+
],
|
|
508
|
+
"additionalProperties": false
|
|
509
|
+
},
|
|
510
|
+
"Contract": {
|
|
511
|
+
"type": "object",
|
|
512
|
+
"properties": {
|
|
513
|
+
"body": {
|
|
514
|
+
"type": "string"
|
|
515
|
+
},
|
|
516
|
+
"clauses": {
|
|
517
|
+
"type": "array",
|
|
518
|
+
"items": {
|
|
519
|
+
"$ref": "#/definitions/ContractClause"
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
},
|
|
523
|
+
"required": [
|
|
524
|
+
"body",
|
|
525
|
+
"clauses"
|
|
526
|
+
],
|
|
527
|
+
"additionalProperties": false
|
|
528
|
+
},
|
|
529
|
+
"ContractClause": {
|
|
530
|
+
"type": "object",
|
|
531
|
+
"properties": {
|
|
532
|
+
"id": {
|
|
533
|
+
"type": "string"
|
|
534
|
+
},
|
|
535
|
+
"price": {
|
|
536
|
+
"type": [
|
|
537
|
+
"string",
|
|
538
|
+
"number"
|
|
539
|
+
]
|
|
540
|
+
},
|
|
541
|
+
"description": {
|
|
542
|
+
"type": "string"
|
|
543
|
+
}
|
|
544
|
+
},
|
|
545
|
+
"required": [
|
|
546
|
+
"id",
|
|
547
|
+
"price"
|
|
548
|
+
],
|
|
549
|
+
"additionalProperties": false
|
|
550
|
+
}
|
|
551
|
+
},
|
|
552
|
+
"allowTrailingCommas": true
|
|
553
|
+
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decocms/runtime",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.17",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@cloudflare/workers-types": "^4.20250617.0",
|
|
7
7
|
"@deco/mcp": "npm:@jsr/deco__mcp@0.5.5",
|
|
8
|
-
"@decocms/bindings": "1.0.1-alpha.
|
|
8
|
+
"@decocms/bindings": "1.0.1-alpha.12",
|
|
9
9
|
"@modelcontextprotocol/sdk": "1.20.2",
|
|
10
10
|
"@ai-sdk/provider": "^2.0.0",
|
|
11
11
|
"hono": "^4.10.7",
|
package/src/cors.ts
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
export type CORSOrigin =
|
|
2
|
+
| string
|
|
3
|
+
| string[]
|
|
4
|
+
| ((origin: string, req: Request) => string | null | undefined);
|
|
5
|
+
|
|
6
|
+
export interface CORSOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The value of "Access-Control-Allow-Origin" CORS header.
|
|
9
|
+
* Can be a string, array of strings, or a function that returns the allowed origin.
|
|
10
|
+
* @default '*'
|
|
11
|
+
*/
|
|
12
|
+
origin?: CORSOrigin;
|
|
13
|
+
/**
|
|
14
|
+
* The value of "Access-Control-Allow-Methods" CORS header.
|
|
15
|
+
* @default ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH']
|
|
16
|
+
*/
|
|
17
|
+
allowMethods?: string[];
|
|
18
|
+
/**
|
|
19
|
+
* The value of "Access-Control-Allow-Headers" CORS header.
|
|
20
|
+
* @default []
|
|
21
|
+
*/
|
|
22
|
+
allowHeaders?: string[];
|
|
23
|
+
/**
|
|
24
|
+
* The value of "Access-Control-Max-Age" CORS header (in seconds).
|
|
25
|
+
*/
|
|
26
|
+
maxAge?: number;
|
|
27
|
+
/**
|
|
28
|
+
* The value of "Access-Control-Allow-Credentials" CORS header.
|
|
29
|
+
*/
|
|
30
|
+
credentials?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* The value of "Access-Control-Expose-Headers" CORS header.
|
|
33
|
+
* @default []
|
|
34
|
+
*/
|
|
35
|
+
exposeHeaders?: string[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const DEFAULT_ALLOW_METHODS = ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"];
|
|
39
|
+
|
|
40
|
+
const resolveOrigin = (
|
|
41
|
+
origin: CORSOrigin | undefined,
|
|
42
|
+
requestOrigin: string | null,
|
|
43
|
+
req: Request,
|
|
44
|
+
): string | null => {
|
|
45
|
+
if (!requestOrigin) return null;
|
|
46
|
+
|
|
47
|
+
if (origin === undefined || origin === "*") {
|
|
48
|
+
return "*";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (typeof origin === "string") {
|
|
52
|
+
return origin === requestOrigin ? origin : null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (Array.isArray(origin)) {
|
|
56
|
+
return origin.includes(requestOrigin) ? requestOrigin : null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (typeof origin === "function") {
|
|
60
|
+
return origin(requestOrigin, req) ?? null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return null;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const setCORSHeaders = (
|
|
67
|
+
headers: Headers,
|
|
68
|
+
req: Request,
|
|
69
|
+
options: CORSOptions,
|
|
70
|
+
): void => {
|
|
71
|
+
const requestOrigin = req.headers.get("Origin");
|
|
72
|
+
const allowedOrigin = resolveOrigin(options.origin, requestOrigin, req);
|
|
73
|
+
|
|
74
|
+
if (allowedOrigin) {
|
|
75
|
+
headers.set("Access-Control-Allow-Origin", allowedOrigin);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (options.credentials) {
|
|
79
|
+
headers.set("Access-Control-Allow-Credentials", "true");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (options.exposeHeaders?.length) {
|
|
83
|
+
headers.set(
|
|
84
|
+
"Access-Control-Expose-Headers",
|
|
85
|
+
options.exposeHeaders.join(", "),
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const handlePreflight = (
|
|
91
|
+
req: Request,
|
|
92
|
+
options: CORSOptions,
|
|
93
|
+
): Response => {
|
|
94
|
+
const headers = new Headers();
|
|
95
|
+
const requestOrigin = req.headers.get("Origin");
|
|
96
|
+
const allowedOrigin = resolveOrigin(options.origin, requestOrigin, req);
|
|
97
|
+
|
|
98
|
+
if (allowedOrigin) {
|
|
99
|
+
headers.set("Access-Control-Allow-Origin", allowedOrigin);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (options.credentials) {
|
|
103
|
+
headers.set("Access-Control-Allow-Credentials", "true");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const allowMethods = options.allowMethods ?? DEFAULT_ALLOW_METHODS;
|
|
107
|
+
headers.set("Access-Control-Allow-Methods", allowMethods.join(", "));
|
|
108
|
+
|
|
109
|
+
const requestHeaders = req.headers.get("Access-Control-Request-Headers");
|
|
110
|
+
if (options.allowHeaders?.length) {
|
|
111
|
+
headers.set(
|
|
112
|
+
"Access-Control-Allow-Headers",
|
|
113
|
+
options.allowHeaders.join(", "),
|
|
114
|
+
);
|
|
115
|
+
} else if (requestHeaders) {
|
|
116
|
+
// Mirror the requested headers if no explicit allowHeaders configured
|
|
117
|
+
headers.set("Access-Control-Allow-Headers", requestHeaders);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (options.maxAge !== undefined) {
|
|
121
|
+
headers.set("Access-Control-Max-Age", options.maxAge.toString());
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return new Response(null, { status: 204, headers });
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export const withCORS = (
|
|
128
|
+
response: Response,
|
|
129
|
+
req: Request,
|
|
130
|
+
options: CORSOptions,
|
|
131
|
+
): Response => {
|
|
132
|
+
const newHeaders = new Headers(response.headers);
|
|
133
|
+
setCORSHeaders(newHeaders, req, options);
|
|
134
|
+
|
|
135
|
+
return new Response(response.body, {
|
|
136
|
+
status: response.status,
|
|
137
|
+
statusText: response.statusText,
|
|
138
|
+
headers: newHeaders,
|
|
139
|
+
});
|
|
140
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -10,12 +10,14 @@ import {
|
|
|
10
10
|
MCPServer,
|
|
11
11
|
} from "./tools.ts";
|
|
12
12
|
import type { Binding, ContractBinding, MCPBinding } from "./wrangler.ts";
|
|
13
|
+
import { type CORSOptions, handlePreflight, withCORS } from "./cors.ts";
|
|
13
14
|
export { proxyConnectionForId } from "./bindings.ts";
|
|
14
15
|
export {
|
|
15
16
|
createMCPFetchStub,
|
|
16
17
|
type CreateStubAPIOptions,
|
|
17
18
|
type ToolBinder,
|
|
18
19
|
} from "./mcp.ts";
|
|
20
|
+
export { type CORSOptions, type CORSOrigin } from "./cors.ts";
|
|
19
21
|
|
|
20
22
|
export interface DefaultEnv<TSchema extends z.ZodTypeAny = any> {
|
|
21
23
|
MESH_REQUEST_CONTEXT: RequestContext<TSchema>;
|
|
@@ -56,6 +58,11 @@ export interface UserDefaultExport<
|
|
|
56
58
|
env: TEnv,
|
|
57
59
|
ctx: ExecutionContext,
|
|
58
60
|
) => Promise<Response> | Response;
|
|
61
|
+
/**
|
|
62
|
+
* CORS configuration options.
|
|
63
|
+
* Set to `false` to disable CORS handling entirely.
|
|
64
|
+
*/
|
|
65
|
+
cors?: CORSOptions | false;
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
// 1. Map binding type to its interface
|
|
@@ -155,11 +162,13 @@ export const withBindings = <TEnv>({
|
|
|
155
162
|
server,
|
|
156
163
|
tokenOrContext,
|
|
157
164
|
url,
|
|
165
|
+
bindings: inlineBindings,
|
|
158
166
|
}: {
|
|
159
167
|
env: TEnv;
|
|
160
168
|
server: MCPServer<TEnv, any>;
|
|
161
169
|
tokenOrContext?: string | RequestContext;
|
|
162
170
|
url?: string;
|
|
171
|
+
bindings?: Binding[];
|
|
163
172
|
}): TEnv => {
|
|
164
173
|
const env = _env as DefaultEnv<any>;
|
|
165
174
|
|
|
@@ -209,7 +218,7 @@ export const withBindings = <TEnv>({
|
|
|
209
218
|
}
|
|
210
219
|
|
|
211
220
|
env.MESH_REQUEST_CONTEXT = context;
|
|
212
|
-
const bindings = MCPBindings.parse(env.MESH_BINDINGS);
|
|
221
|
+
const bindings = inlineBindings ?? MCPBindings.parse(env.MESH_BINDINGS);
|
|
213
222
|
|
|
214
223
|
for (const binding of bindings) {
|
|
215
224
|
env[binding.name] = creatorByType[binding.type](binding as any, env);
|
|
@@ -228,6 +237,8 @@ export const withRuntime = <TEnv, TSchema extends z.ZodTypeAny = never>(
|
|
|
228
237
|
userFns: UserDefaultExport<TEnv, TSchema>,
|
|
229
238
|
): ExportedHandler<TEnv & DefaultEnv<TSchema>> => {
|
|
230
239
|
const server = createMCPServer<TEnv, TSchema>(userFns);
|
|
240
|
+
const corsOptions = userFns.cors;
|
|
241
|
+
|
|
231
242
|
const fetcher = async (
|
|
232
243
|
req: Request,
|
|
233
244
|
env: TEnv & DefaultEnv<TSchema>,
|
|
@@ -265,22 +276,39 @@ export const withRuntime = <TEnv, TSchema extends z.ZodTypeAny = never>(
|
|
|
265
276
|
new Response("Not found", { status: 404 })
|
|
266
277
|
);
|
|
267
278
|
};
|
|
279
|
+
|
|
268
280
|
return {
|
|
269
281
|
fetch: async (
|
|
270
282
|
req: Request,
|
|
271
283
|
env: TEnv & DefaultEnv<TSchema>,
|
|
272
284
|
ctx: ExecutionContext,
|
|
273
285
|
) => {
|
|
286
|
+
// Handle CORS preflight (OPTIONS) requests
|
|
287
|
+
if (corsOptions !== false && req.method === "OPTIONS") {
|
|
288
|
+
const options = corsOptions ?? {};
|
|
289
|
+
return handlePreflight(req, options);
|
|
290
|
+
}
|
|
291
|
+
|
|
274
292
|
const bindings = withBindings({
|
|
275
293
|
env,
|
|
276
294
|
server,
|
|
295
|
+
bindings: userFns.bindings,
|
|
277
296
|
tokenOrContext: req.headers.get("x-mesh-token") ?? undefined,
|
|
278
297
|
url: req.url,
|
|
279
298
|
});
|
|
280
|
-
|
|
299
|
+
|
|
300
|
+
const response = await State.run(
|
|
281
301
|
{ req, env: bindings, ctx },
|
|
282
302
|
async () => await fetcher(req, bindings, ctx),
|
|
283
303
|
);
|
|
304
|
+
|
|
305
|
+
// Add CORS headers to response
|
|
306
|
+
if (corsOptions !== false) {
|
|
307
|
+
const options = corsOptions ?? {};
|
|
308
|
+
return withCORS(response, req, options);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return response;
|
|
284
312
|
},
|
|
285
313
|
};
|
|
286
314
|
};
|
package/src/tools.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { z } from "zod";
|
|
|
6
6
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
7
7
|
import type { DefaultEnv } from "./index.ts";
|
|
8
8
|
import { State } from "./state.ts";
|
|
9
|
+
import { Binding } from "./wrangler.ts";
|
|
9
10
|
|
|
10
11
|
export const createRuntimeContext = (prev?: AppContext) => {
|
|
11
12
|
const store = State.getStore();
|
|
@@ -153,6 +154,7 @@ export interface CreateMCPServerOptions<
|
|
|
153
154
|
state?: TSchema;
|
|
154
155
|
scopes?: string[];
|
|
155
156
|
};
|
|
157
|
+
bindings?: Binding[];
|
|
156
158
|
tools?:
|
|
157
159
|
| Array<
|
|
158
160
|
(
|