@tangle-network/agent-integrations 0.53.32 → 0.53.33
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/data/activepieces-catalog.json +5 -5
- package/dist/catalog.js +5 -5
- package/dist/{chunk-7GS2RYBA.js → chunk-3NQFKQTR.js} +4 -3
- package/dist/chunk-3NQFKQTR.js.map +1 -0
- package/dist/{chunk-M3CRVHGW.js → chunk-AG4ORH2A.js} +5 -4
- package/dist/chunk-AG4ORH2A.js.map +1 -0
- package/dist/{chunk-UUXEF2QZ.js → chunk-EC675ZAS.js} +111 -3
- package/dist/chunk-EC675ZAS.js.map +1 -0
- package/dist/{chunk-5MHN5LWD.js → chunk-QOY5LZXH.js} +2 -2
- package/dist/{chunk-FOIC32DF.js → chunk-R5GQB3SQ.js} +1651 -1120
- package/dist/{chunk-FOIC32DF.js.map → chunk-R5GQB3SQ.js.map} +1 -1
- package/dist/connectors/adapters/index.d.ts +78 -23
- package/dist/connectors/adapters/index.js +11 -1
- package/dist/connectors/index.d.ts +3 -1
- package/dist/connectors/index.js +12 -2
- package/dist/coverage-catalog.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +15 -5
- package/dist/mcp.js +5 -5
- package/dist/registry.js +5 -5
- package/dist/runtime.js +5 -5
- package/dist/specs.js +4 -4
- package/docs/integration-execution-audit.md +22 -20
- package/docs/integration-execution-matrix.json +39 -55
- package/package.json +13 -12
- package/dist/chunk-7GS2RYBA.js.map +0 -1
- package/dist/chunk-M3CRVHGW.js.map +0 -1
- package/dist/chunk-UUXEF2QZ.js.map +0 -1
- /package/dist/{chunk-5MHN5LWD.js.map → chunk-QOY5LZXH.js.map} +0 -0
|
@@ -182,9 +182,12 @@ __export(adapters_exports, {
|
|
|
182
182
|
copyAiConnector: () => copyAiConnector,
|
|
183
183
|
couchbaseConnector: () => couchbaseConnector,
|
|
184
184
|
createKafkaConnector: () => createKafkaConnector,
|
|
185
|
+
createMongoDbConnector: () => createMongoDbConnector,
|
|
185
186
|
createMySqlConnector: () => createMySqlConnector,
|
|
187
|
+
createPostgresConnector: () => createPostgresConnector,
|
|
186
188
|
createRabbitMqConnector: () => createRabbitMqConnector,
|
|
187
189
|
createRedisConnector: () => createRedisConnector,
|
|
190
|
+
createRedshiftConnector: () => createRedshiftConnector,
|
|
188
191
|
createSftpConnector: () => createSftpConnector,
|
|
189
192
|
createTangleIdentityClient: () => createTangleIdentityClient,
|
|
190
193
|
crispConnector: () => crispConnector,
|
|
@@ -446,6 +449,7 @@ __export(adapters_exports, {
|
|
|
446
449
|
n8nConnector: () => n8nConnector,
|
|
447
450
|
netlifyConnector: () => netlifyConnector,
|
|
448
451
|
netsuiteConnector: () => netsuiteConnector,
|
|
452
|
+
neverbounceConnector: () => neverbounceConnector,
|
|
449
453
|
niftyConnector: () => niftyConnector,
|
|
450
454
|
ninjapipeConnector: () => ninjapipeConnector,
|
|
451
455
|
nocodbConnector: () => nocodbConnector,
|
|
@@ -522,6 +526,7 @@ __export(adapters_exports, {
|
|
|
522
526
|
recurlyConnector: () => recurlyConnector,
|
|
523
527
|
redditConnector: () => redditConnector,
|
|
524
528
|
redisConnector: () => redisConnector,
|
|
529
|
+
redshiftConnector: () => redshiftConnector,
|
|
525
530
|
reoonVerifierConnector: () => reoonVerifierConnector,
|
|
526
531
|
replyIoConnector: () => replyIoConnector,
|
|
527
532
|
resolveConnectorAdapterFactoryOptions: () => resolveConnectorAdapterFactoryOptions,
|
|
@@ -39205,6 +39210,628 @@ var mollieConnector = declarativeRestConnector({
|
|
|
39205
39210
|
]
|
|
39206
39211
|
});
|
|
39207
39212
|
|
|
39213
|
+
// src/connectors/adapters/miro.ts
|
|
39214
|
+
var miroConnector = declarativeRestConnector({
|
|
39215
|
+
kind: "miro",
|
|
39216
|
+
displayName: "Miro",
|
|
39217
|
+
description: "Read and edit Miro boards: list and search boards, read board items (sticky notes, shapes, text, cards, images, frames, connectors), create and update items, and post board content back into the source of truth.",
|
|
39218
|
+
auth: {
|
|
39219
|
+
kind: "oauth2",
|
|
39220
|
+
authorizationUrl: "https://miro.com/oauth/authorize",
|
|
39221
|
+
tokenUrl: "https://api.miro.com/v1/oauth/token",
|
|
39222
|
+
scopes: [
|
|
39223
|
+
"boards:read",
|
|
39224
|
+
"boards:write",
|
|
39225
|
+
"identity:read"
|
|
39226
|
+
],
|
|
39227
|
+
clientIdEnv: "MIRO_OAUTH_CLIENT_ID",
|
|
39228
|
+
clientSecretEnv: "MIRO_OAUTH_CLIENT_SECRET"
|
|
39229
|
+
},
|
|
39230
|
+
category: "doc",
|
|
39231
|
+
defaultConsistencyModel: "authoritative",
|
|
39232
|
+
baseUrl: "https://api.miro.com",
|
|
39233
|
+
defaultHeaders: { accept: "application/json" },
|
|
39234
|
+
// GET /v2/me returns the authenticated user — Miro's documented health probe.
|
|
39235
|
+
test: { method: "GET", path: "/v2/me" },
|
|
39236
|
+
capabilities: [
|
|
39237
|
+
{
|
|
39238
|
+
name: "me.get",
|
|
39239
|
+
class: "read",
|
|
39240
|
+
description: "Return the authenticated Miro user.",
|
|
39241
|
+
parameters: { type: "object", properties: {} },
|
|
39242
|
+
request: { method: "GET", path: "/v2/me" },
|
|
39243
|
+
requiredScopes: ["identity:read"]
|
|
39244
|
+
},
|
|
39245
|
+
{
|
|
39246
|
+
name: "boards.list",
|
|
39247
|
+
class: "read",
|
|
39248
|
+
description: "List boards accessible to the authenticated user. Supports cursor pagination via `cursor` and team / sort filters.",
|
|
39249
|
+
parameters: {
|
|
39250
|
+
type: "object",
|
|
39251
|
+
properties: {
|
|
39252
|
+
team_id: { type: "string", description: "Filter to a single team id." },
|
|
39253
|
+
query: { type: "string", description: "Free-text board name filter." },
|
|
39254
|
+
owner: { type: "string", description: "Filter by owner user id." },
|
|
39255
|
+
limit: { type: "integer", minimum: 1, maximum: 50 },
|
|
39256
|
+
offset: { type: "integer", minimum: 0 },
|
|
39257
|
+
sort: {
|
|
39258
|
+
type: "string",
|
|
39259
|
+
enum: ["default", "last_modified", "last_opened", "last_created", "alphabetically"]
|
|
39260
|
+
}
|
|
39261
|
+
}
|
|
39262
|
+
},
|
|
39263
|
+
request: {
|
|
39264
|
+
method: "GET",
|
|
39265
|
+
path: "/v2/boards",
|
|
39266
|
+
query: {
|
|
39267
|
+
team_id: "{team_id}",
|
|
39268
|
+
query: "{query}",
|
|
39269
|
+
owner: "{owner}",
|
|
39270
|
+
limit: "{limit}",
|
|
39271
|
+
offset: "{offset}",
|
|
39272
|
+
sort: "{sort}"
|
|
39273
|
+
}
|
|
39274
|
+
},
|
|
39275
|
+
requiredScopes: ["boards:read"]
|
|
39276
|
+
},
|
|
39277
|
+
{
|
|
39278
|
+
name: "boards.get",
|
|
39279
|
+
class: "read",
|
|
39280
|
+
description: "Fetch a single Miro board by id.",
|
|
39281
|
+
parameters: {
|
|
39282
|
+
type: "object",
|
|
39283
|
+
properties: { board_id: { type: "string" } },
|
|
39284
|
+
required: ["board_id"]
|
|
39285
|
+
},
|
|
39286
|
+
request: { method: "GET", path: "/v2/boards/{board_id}" },
|
|
39287
|
+
requiredScopes: ["boards:read"]
|
|
39288
|
+
},
|
|
39289
|
+
{
|
|
39290
|
+
name: "boards.members.list",
|
|
39291
|
+
class: "read",
|
|
39292
|
+
description: "List members (collaborators) of a Miro board.",
|
|
39293
|
+
parameters: {
|
|
39294
|
+
type: "object",
|
|
39295
|
+
properties: {
|
|
39296
|
+
board_id: { type: "string" },
|
|
39297
|
+
limit: { type: "integer", minimum: 1, maximum: 50 },
|
|
39298
|
+
offset: { type: "integer", minimum: 0 }
|
|
39299
|
+
},
|
|
39300
|
+
required: ["board_id"]
|
|
39301
|
+
},
|
|
39302
|
+
request: {
|
|
39303
|
+
method: "GET",
|
|
39304
|
+
path: "/v2/boards/{board_id}/members",
|
|
39305
|
+
query: { limit: "{limit}", offset: "{offset}" }
|
|
39306
|
+
},
|
|
39307
|
+
requiredScopes: ["boards:read"]
|
|
39308
|
+
},
|
|
39309
|
+
{
|
|
39310
|
+
name: "items.list",
|
|
39311
|
+
class: "read",
|
|
39312
|
+
description: "List all items on a board, optionally filtered by item type (sticky_note, text, shape, card, image, frame, connector, embed, app_card, document).",
|
|
39313
|
+
parameters: {
|
|
39314
|
+
type: "object",
|
|
39315
|
+
properties: {
|
|
39316
|
+
board_id: { type: "string" },
|
|
39317
|
+
type: {
|
|
39318
|
+
type: "string",
|
|
39319
|
+
enum: [
|
|
39320
|
+
"sticky_note",
|
|
39321
|
+
"text",
|
|
39322
|
+
"shape",
|
|
39323
|
+
"card",
|
|
39324
|
+
"image",
|
|
39325
|
+
"frame",
|
|
39326
|
+
"connector",
|
|
39327
|
+
"embed",
|
|
39328
|
+
"app_card",
|
|
39329
|
+
"document",
|
|
39330
|
+
"preview"
|
|
39331
|
+
]
|
|
39332
|
+
},
|
|
39333
|
+
limit: { type: "integer", minimum: 1, maximum: 50 },
|
|
39334
|
+
cursor: { type: "string" }
|
|
39335
|
+
},
|
|
39336
|
+
required: ["board_id"]
|
|
39337
|
+
},
|
|
39338
|
+
request: {
|
|
39339
|
+
method: "GET",
|
|
39340
|
+
path: "/v2/boards/{board_id}/items",
|
|
39341
|
+
query: { type: "{type}", limit: "{limit}", cursor: "{cursor}" }
|
|
39342
|
+
},
|
|
39343
|
+
requiredScopes: ["boards:read"]
|
|
39344
|
+
},
|
|
39345
|
+
{
|
|
39346
|
+
name: "items.get",
|
|
39347
|
+
class: "read",
|
|
39348
|
+
description: "Fetch a single board item by id.",
|
|
39349
|
+
parameters: {
|
|
39350
|
+
type: "object",
|
|
39351
|
+
properties: {
|
|
39352
|
+
board_id: { type: "string" },
|
|
39353
|
+
item_id: { type: "string" }
|
|
39354
|
+
},
|
|
39355
|
+
required: ["board_id", "item_id"]
|
|
39356
|
+
},
|
|
39357
|
+
request: { method: "GET", path: "/v2/boards/{board_id}/items/{item_id}" },
|
|
39358
|
+
requiredScopes: ["boards:read"]
|
|
39359
|
+
},
|
|
39360
|
+
{
|
|
39361
|
+
name: "connectors.list",
|
|
39362
|
+
class: "read",
|
|
39363
|
+
description: "List connector lines on a board (arrows / lines between items).",
|
|
39364
|
+
parameters: {
|
|
39365
|
+
type: "object",
|
|
39366
|
+
properties: {
|
|
39367
|
+
board_id: { type: "string" },
|
|
39368
|
+
limit: { type: "integer", minimum: 1, maximum: 50 },
|
|
39369
|
+
cursor: { type: "string" }
|
|
39370
|
+
},
|
|
39371
|
+
required: ["board_id"]
|
|
39372
|
+
},
|
|
39373
|
+
request: {
|
|
39374
|
+
method: "GET",
|
|
39375
|
+
path: "/v2/boards/{board_id}/connectors",
|
|
39376
|
+
query: { limit: "{limit}", cursor: "{cursor}" }
|
|
39377
|
+
},
|
|
39378
|
+
requiredScopes: ["boards:read"]
|
|
39379
|
+
},
|
|
39380
|
+
{
|
|
39381
|
+
name: "tags.list",
|
|
39382
|
+
class: "read",
|
|
39383
|
+
description: "List tags defined on a board.",
|
|
39384
|
+
parameters: {
|
|
39385
|
+
type: "object",
|
|
39386
|
+
properties: {
|
|
39387
|
+
board_id: { type: "string" },
|
|
39388
|
+
limit: { type: "integer", minimum: 1, maximum: 50 },
|
|
39389
|
+
offset: { type: "integer", minimum: 0 }
|
|
39390
|
+
},
|
|
39391
|
+
required: ["board_id"]
|
|
39392
|
+
},
|
|
39393
|
+
request: {
|
|
39394
|
+
method: "GET",
|
|
39395
|
+
path: "/v2/boards/{board_id}/tags",
|
|
39396
|
+
query: { limit: "{limit}", offset: "{offset}" }
|
|
39397
|
+
},
|
|
39398
|
+
requiredScopes: ["boards:read"]
|
|
39399
|
+
},
|
|
39400
|
+
{
|
|
39401
|
+
name: "boards.create",
|
|
39402
|
+
class: "mutation",
|
|
39403
|
+
description: "Create a new Miro board. Accepts an optional name, description, team_id, and sharing policy. Returns the new board id used by every items.* endpoint.",
|
|
39404
|
+
parameters: {
|
|
39405
|
+
type: "object",
|
|
39406
|
+
properties: {
|
|
39407
|
+
name: { type: "string", maxLength: 60 },
|
|
39408
|
+
description: { type: "string", maxLength: 300 },
|
|
39409
|
+
team_id: { type: "string" },
|
|
39410
|
+
policy: {
|
|
39411
|
+
type: "object",
|
|
39412
|
+
description: "Permissions + sharing policy. See https://developers.miro.com/reference/create-board for the full PolicyChange shape."
|
|
39413
|
+
}
|
|
39414
|
+
},
|
|
39415
|
+
required: ["name"]
|
|
39416
|
+
},
|
|
39417
|
+
request: {
|
|
39418
|
+
method: "POST",
|
|
39419
|
+
path: "/v2/boards",
|
|
39420
|
+
body: {
|
|
39421
|
+
name: "{name}",
|
|
39422
|
+
description: "{description}",
|
|
39423
|
+
teamId: "{team_id}",
|
|
39424
|
+
policy: "{policy}"
|
|
39425
|
+
}
|
|
39426
|
+
},
|
|
39427
|
+
cas: "native-idempotency",
|
|
39428
|
+
requiredScopes: ["boards:write"]
|
|
39429
|
+
},
|
|
39430
|
+
{
|
|
39431
|
+
name: "boards.update",
|
|
39432
|
+
class: "mutation",
|
|
39433
|
+
description: "Update a Miro board (name, description, team, or sharing policy).",
|
|
39434
|
+
parameters: {
|
|
39435
|
+
type: "object",
|
|
39436
|
+
properties: {
|
|
39437
|
+
board_id: { type: "string" },
|
|
39438
|
+
name: { type: "string", maxLength: 60 },
|
|
39439
|
+
description: { type: "string", maxLength: 300 },
|
|
39440
|
+
team_id: { type: "string" },
|
|
39441
|
+
policy: { type: "object" }
|
|
39442
|
+
},
|
|
39443
|
+
required: ["board_id"]
|
|
39444
|
+
},
|
|
39445
|
+
request: {
|
|
39446
|
+
method: "PATCH",
|
|
39447
|
+
path: "/v2/boards/{board_id}",
|
|
39448
|
+
body: {
|
|
39449
|
+
name: "{name}",
|
|
39450
|
+
description: "{description}",
|
|
39451
|
+
teamId: "{team_id}",
|
|
39452
|
+
policy: "{policy}"
|
|
39453
|
+
}
|
|
39454
|
+
},
|
|
39455
|
+
cas: "native-idempotency",
|
|
39456
|
+
requiredScopes: ["boards:write"]
|
|
39457
|
+
},
|
|
39458
|
+
{
|
|
39459
|
+
name: "boards.delete",
|
|
39460
|
+
class: "mutation",
|
|
39461
|
+
description: "Delete a Miro board (irreversible).",
|
|
39462
|
+
parameters: {
|
|
39463
|
+
type: "object",
|
|
39464
|
+
properties: { board_id: { type: "string" } },
|
|
39465
|
+
required: ["board_id"]
|
|
39466
|
+
},
|
|
39467
|
+
request: { method: "DELETE", path: "/v2/boards/{board_id}" },
|
|
39468
|
+
cas: "native-idempotency",
|
|
39469
|
+
requiredScopes: ["boards:write"]
|
|
39470
|
+
},
|
|
39471
|
+
{
|
|
39472
|
+
name: "sticky_notes.create",
|
|
39473
|
+
class: "mutation",
|
|
39474
|
+
description: "Create a sticky note on a board. `data.content` accepts plain text; `style.fillColor` is a Miro sticky-note color keyword (e.g. yellow, light_yellow, pink).",
|
|
39475
|
+
parameters: {
|
|
39476
|
+
type: "object",
|
|
39477
|
+
properties: {
|
|
39478
|
+
board_id: { type: "string" },
|
|
39479
|
+
data: {
|
|
39480
|
+
type: "object",
|
|
39481
|
+
properties: {
|
|
39482
|
+
content: { type: "string" },
|
|
39483
|
+
shape: { type: "string", enum: ["square", "rectangle"] }
|
|
39484
|
+
},
|
|
39485
|
+
required: ["content"]
|
|
39486
|
+
},
|
|
39487
|
+
style: {
|
|
39488
|
+
type: "object",
|
|
39489
|
+
properties: {
|
|
39490
|
+
fillColor: { type: "string" },
|
|
39491
|
+
textAlign: { type: "string", enum: ["left", "center", "right"] },
|
|
39492
|
+
textAlignVertical: { type: "string", enum: ["top", "middle", "bottom"] }
|
|
39493
|
+
}
|
|
39494
|
+
},
|
|
39495
|
+
position: {
|
|
39496
|
+
type: "object",
|
|
39497
|
+
properties: {
|
|
39498
|
+
x: { type: "number" },
|
|
39499
|
+
y: { type: "number" },
|
|
39500
|
+
origin: { type: "string", enum: ["center"] }
|
|
39501
|
+
}
|
|
39502
|
+
},
|
|
39503
|
+
geometry: {
|
|
39504
|
+
type: "object",
|
|
39505
|
+
properties: {
|
|
39506
|
+
width: { type: "number" },
|
|
39507
|
+
height: { type: "number" }
|
|
39508
|
+
}
|
|
39509
|
+
},
|
|
39510
|
+
parent: {
|
|
39511
|
+
type: "object",
|
|
39512
|
+
description: "Attach the sticky note to a frame: { id: <frame_item_id> }.",
|
|
39513
|
+
properties: { id: { type: "string" } }
|
|
39514
|
+
}
|
|
39515
|
+
},
|
|
39516
|
+
required: ["board_id", "data"]
|
|
39517
|
+
},
|
|
39518
|
+
request: {
|
|
39519
|
+
method: "POST",
|
|
39520
|
+
path: "/v2/boards/{board_id}/sticky_notes",
|
|
39521
|
+
body: {
|
|
39522
|
+
data: "{data}",
|
|
39523
|
+
style: "{style}",
|
|
39524
|
+
position: "{position}",
|
|
39525
|
+
geometry: "{geometry}",
|
|
39526
|
+
parent: "{parent}"
|
|
39527
|
+
}
|
|
39528
|
+
},
|
|
39529
|
+
cas: "native-idempotency",
|
|
39530
|
+
requiredScopes: ["boards:write"]
|
|
39531
|
+
},
|
|
39532
|
+
{
|
|
39533
|
+
name: "sticky_notes.update",
|
|
39534
|
+
class: "mutation",
|
|
39535
|
+
description: "Update a sticky note (content, style, position, geometry, or parent frame).",
|
|
39536
|
+
parameters: {
|
|
39537
|
+
type: "object",
|
|
39538
|
+
properties: {
|
|
39539
|
+
board_id: { type: "string" },
|
|
39540
|
+
item_id: { type: "string" },
|
|
39541
|
+
data: { type: "object" },
|
|
39542
|
+
style: { type: "object" },
|
|
39543
|
+
position: { type: "object" },
|
|
39544
|
+
geometry: { type: "object" },
|
|
39545
|
+
parent: { type: "object" }
|
|
39546
|
+
},
|
|
39547
|
+
required: ["board_id", "item_id"]
|
|
39548
|
+
},
|
|
39549
|
+
request: {
|
|
39550
|
+
method: "PATCH",
|
|
39551
|
+
path: "/v2/boards/{board_id}/sticky_notes/{item_id}",
|
|
39552
|
+
body: {
|
|
39553
|
+
data: "{data}",
|
|
39554
|
+
style: "{style}",
|
|
39555
|
+
position: "{position}",
|
|
39556
|
+
geometry: "{geometry}",
|
|
39557
|
+
parent: "{parent}"
|
|
39558
|
+
}
|
|
39559
|
+
},
|
|
39560
|
+
cas: "native-idempotency",
|
|
39561
|
+
requiredScopes: ["boards:write"]
|
|
39562
|
+
},
|
|
39563
|
+
{
|
|
39564
|
+
name: "text.create",
|
|
39565
|
+
class: "mutation",
|
|
39566
|
+
description: "Create a text item on a board.",
|
|
39567
|
+
parameters: {
|
|
39568
|
+
type: "object",
|
|
39569
|
+
properties: {
|
|
39570
|
+
board_id: { type: "string" },
|
|
39571
|
+
data: {
|
|
39572
|
+
type: "object",
|
|
39573
|
+
properties: { content: { type: "string" } },
|
|
39574
|
+
required: ["content"]
|
|
39575
|
+
},
|
|
39576
|
+
style: { type: "object" },
|
|
39577
|
+
position: { type: "object" },
|
|
39578
|
+
geometry: { type: "object" },
|
|
39579
|
+
parent: { type: "object" }
|
|
39580
|
+
},
|
|
39581
|
+
required: ["board_id", "data"]
|
|
39582
|
+
},
|
|
39583
|
+
request: {
|
|
39584
|
+
method: "POST",
|
|
39585
|
+
path: "/v2/boards/{board_id}/texts",
|
|
39586
|
+
body: {
|
|
39587
|
+
data: "{data}",
|
|
39588
|
+
style: "{style}",
|
|
39589
|
+
position: "{position}",
|
|
39590
|
+
geometry: "{geometry}",
|
|
39591
|
+
parent: "{parent}"
|
|
39592
|
+
}
|
|
39593
|
+
},
|
|
39594
|
+
cas: "native-idempotency",
|
|
39595
|
+
requiredScopes: ["boards:write"]
|
|
39596
|
+
},
|
|
39597
|
+
{
|
|
39598
|
+
name: "shapes.create",
|
|
39599
|
+
class: "mutation",
|
|
39600
|
+
description: "Create a shape item on a board. `data.shape` selects the geometric primitive (rectangle, round_rectangle, circle, triangle, rhombus, etc.).",
|
|
39601
|
+
parameters: {
|
|
39602
|
+
type: "object",
|
|
39603
|
+
properties: {
|
|
39604
|
+
board_id: { type: "string" },
|
|
39605
|
+
data: {
|
|
39606
|
+
type: "object",
|
|
39607
|
+
properties: {
|
|
39608
|
+
shape: {
|
|
39609
|
+
type: "string",
|
|
39610
|
+
description: "Miro shape kind; full enum at https://developers.miro.com/reference/create-shape-item."
|
|
39611
|
+
},
|
|
39612
|
+
content: { type: "string" }
|
|
39613
|
+
},
|
|
39614
|
+
required: ["shape"]
|
|
39615
|
+
},
|
|
39616
|
+
style: { type: "object" },
|
|
39617
|
+
position: { type: "object" },
|
|
39618
|
+
geometry: { type: "object" },
|
|
39619
|
+
parent: { type: "object" }
|
|
39620
|
+
},
|
|
39621
|
+
required: ["board_id", "data"]
|
|
39622
|
+
},
|
|
39623
|
+
request: {
|
|
39624
|
+
method: "POST",
|
|
39625
|
+
path: "/v2/boards/{board_id}/shapes",
|
|
39626
|
+
body: {
|
|
39627
|
+
data: "{data}",
|
|
39628
|
+
style: "{style}",
|
|
39629
|
+
position: "{position}",
|
|
39630
|
+
geometry: "{geometry}",
|
|
39631
|
+
parent: "{parent}"
|
|
39632
|
+
}
|
|
39633
|
+
},
|
|
39634
|
+
cas: "native-idempotency",
|
|
39635
|
+
requiredScopes: ["boards:write"]
|
|
39636
|
+
},
|
|
39637
|
+
{
|
|
39638
|
+
name: "cards.create",
|
|
39639
|
+
class: "mutation",
|
|
39640
|
+
description: "Create a card item (title + description + assignee + due-date) on a board.",
|
|
39641
|
+
parameters: {
|
|
39642
|
+
type: "object",
|
|
39643
|
+
properties: {
|
|
39644
|
+
board_id: { type: "string" },
|
|
39645
|
+
data: {
|
|
39646
|
+
type: "object",
|
|
39647
|
+
properties: {
|
|
39648
|
+
title: { type: "string" },
|
|
39649
|
+
description: { type: "string" },
|
|
39650
|
+
dueDate: { type: "string", format: "date-time" },
|
|
39651
|
+
assigneeId: { type: "string" }
|
|
39652
|
+
},
|
|
39653
|
+
required: ["title"]
|
|
39654
|
+
},
|
|
39655
|
+
style: { type: "object" },
|
|
39656
|
+
position: { type: "object" },
|
|
39657
|
+
geometry: { type: "object" },
|
|
39658
|
+
parent: { type: "object" }
|
|
39659
|
+
},
|
|
39660
|
+
required: ["board_id", "data"]
|
|
39661
|
+
},
|
|
39662
|
+
request: {
|
|
39663
|
+
method: "POST",
|
|
39664
|
+
path: "/v2/boards/{board_id}/cards",
|
|
39665
|
+
body: {
|
|
39666
|
+
data: "{data}",
|
|
39667
|
+
style: "{style}",
|
|
39668
|
+
position: "{position}",
|
|
39669
|
+
geometry: "{geometry}",
|
|
39670
|
+
parent: "{parent}"
|
|
39671
|
+
}
|
|
39672
|
+
},
|
|
39673
|
+
cas: "native-idempotency",
|
|
39674
|
+
requiredScopes: ["boards:write"]
|
|
39675
|
+
},
|
|
39676
|
+
{
|
|
39677
|
+
name: "frames.create",
|
|
39678
|
+
class: "mutation",
|
|
39679
|
+
description: "Create a frame on a board. Frames group items; child items can be attached via `parent.id` on item creation.",
|
|
39680
|
+
parameters: {
|
|
39681
|
+
type: "object",
|
|
39682
|
+
properties: {
|
|
39683
|
+
board_id: { type: "string" },
|
|
39684
|
+
data: {
|
|
39685
|
+
type: "object",
|
|
39686
|
+
properties: {
|
|
39687
|
+
title: { type: "string" },
|
|
39688
|
+
format: { type: "string", enum: ["custom"] },
|
|
39689
|
+
type: { type: "string", enum: ["freeform"] }
|
|
39690
|
+
}
|
|
39691
|
+
},
|
|
39692
|
+
style: { type: "object" },
|
|
39693
|
+
position: { type: "object" },
|
|
39694
|
+
geometry: { type: "object" }
|
|
39695
|
+
},
|
|
39696
|
+
required: ["board_id"]
|
|
39697
|
+
},
|
|
39698
|
+
request: {
|
|
39699
|
+
method: "POST",
|
|
39700
|
+
path: "/v2/boards/{board_id}/frames",
|
|
39701
|
+
body: {
|
|
39702
|
+
data: "{data}",
|
|
39703
|
+
style: "{style}",
|
|
39704
|
+
position: "{position}",
|
|
39705
|
+
geometry: "{geometry}"
|
|
39706
|
+
}
|
|
39707
|
+
},
|
|
39708
|
+
cas: "native-idempotency",
|
|
39709
|
+
requiredScopes: ["boards:write"]
|
|
39710
|
+
},
|
|
39711
|
+
{
|
|
39712
|
+
name: "images.create.by_url",
|
|
39713
|
+
class: "mutation",
|
|
39714
|
+
description: "Create an image item from a public URL (Miro fetches the image server-side).",
|
|
39715
|
+
parameters: {
|
|
39716
|
+
type: "object",
|
|
39717
|
+
properties: {
|
|
39718
|
+
board_id: { type: "string" },
|
|
39719
|
+
data: {
|
|
39720
|
+
type: "object",
|
|
39721
|
+
properties: {
|
|
39722
|
+
url: { type: "string", format: "uri" },
|
|
39723
|
+
title: { type: "string" }
|
|
39724
|
+
},
|
|
39725
|
+
required: ["url"]
|
|
39726
|
+
},
|
|
39727
|
+
position: { type: "object" },
|
|
39728
|
+
geometry: { type: "object" },
|
|
39729
|
+
parent: { type: "object" }
|
|
39730
|
+
},
|
|
39731
|
+
required: ["board_id", "data"]
|
|
39732
|
+
},
|
|
39733
|
+
request: {
|
|
39734
|
+
method: "POST",
|
|
39735
|
+
path: "/v2/boards/{board_id}/images",
|
|
39736
|
+
body: {
|
|
39737
|
+
data: "{data}",
|
|
39738
|
+
position: "{position}",
|
|
39739
|
+
geometry: "{geometry}",
|
|
39740
|
+
parent: "{parent}"
|
|
39741
|
+
}
|
|
39742
|
+
},
|
|
39743
|
+
cas: "native-idempotency",
|
|
39744
|
+
requiredScopes: ["boards:write"]
|
|
39745
|
+
},
|
|
39746
|
+
{
|
|
39747
|
+
name: "connectors.create",
|
|
39748
|
+
class: "mutation",
|
|
39749
|
+
description: "Create a connector line between two items on the board. `startItem.id` and `endItem.id` reference existing item ids.",
|
|
39750
|
+
parameters: {
|
|
39751
|
+
type: "object",
|
|
39752
|
+
properties: {
|
|
39753
|
+
board_id: { type: "string" },
|
|
39754
|
+
startItem: {
|
|
39755
|
+
type: "object",
|
|
39756
|
+
properties: { id: { type: "string" } },
|
|
39757
|
+
required: ["id"]
|
|
39758
|
+
},
|
|
39759
|
+
endItem: {
|
|
39760
|
+
type: "object",
|
|
39761
|
+
properties: { id: { type: "string" } },
|
|
39762
|
+
required: ["id"]
|
|
39763
|
+
},
|
|
39764
|
+
captions: {
|
|
39765
|
+
type: "array",
|
|
39766
|
+
items: { type: "object", properties: { content: { type: "string" } } }
|
|
39767
|
+
},
|
|
39768
|
+
style: { type: "object" },
|
|
39769
|
+
shape: { type: "string", enum: ["straight", "elbowed", "curved"] }
|
|
39770
|
+
},
|
|
39771
|
+
required: ["board_id", "startItem", "endItem"]
|
|
39772
|
+
},
|
|
39773
|
+
request: {
|
|
39774
|
+
method: "POST",
|
|
39775
|
+
path: "/v2/boards/{board_id}/connectors",
|
|
39776
|
+
body: {
|
|
39777
|
+
startItem: "{startItem}",
|
|
39778
|
+
endItem: "{endItem}",
|
|
39779
|
+
captions: "{captions}",
|
|
39780
|
+
style: "{style}",
|
|
39781
|
+
shape: "{shape}"
|
|
39782
|
+
}
|
|
39783
|
+
},
|
|
39784
|
+
cas: "native-idempotency",
|
|
39785
|
+
requiredScopes: ["boards:write"]
|
|
39786
|
+
},
|
|
39787
|
+
{
|
|
39788
|
+
name: "items.delete",
|
|
39789
|
+
class: "mutation",
|
|
39790
|
+
description: "Delete an item from a board (works across all item types).",
|
|
39791
|
+
parameters: {
|
|
39792
|
+
type: "object",
|
|
39793
|
+
properties: {
|
|
39794
|
+
board_id: { type: "string" },
|
|
39795
|
+
item_id: { type: "string" }
|
|
39796
|
+
},
|
|
39797
|
+
required: ["board_id", "item_id"]
|
|
39798
|
+
},
|
|
39799
|
+
request: { method: "DELETE", path: "/v2/boards/{board_id}/items/{item_id}" },
|
|
39800
|
+
cas: "native-idempotency",
|
|
39801
|
+
requiredScopes: ["boards:write"]
|
|
39802
|
+
},
|
|
39803
|
+
{
|
|
39804
|
+
name: "boards.share",
|
|
39805
|
+
class: "mutation",
|
|
39806
|
+
description: "Invite users to a Miro board by email. Roles: viewer, commenter, editor, coowner.",
|
|
39807
|
+
parameters: {
|
|
39808
|
+
type: "object",
|
|
39809
|
+
properties: {
|
|
39810
|
+
board_id: { type: "string" },
|
|
39811
|
+
emails: { type: "array", items: { type: "string", format: "email" } },
|
|
39812
|
+
role: {
|
|
39813
|
+
type: "string",
|
|
39814
|
+
enum: ["viewer", "commenter", "editor", "coowner"]
|
|
39815
|
+
},
|
|
39816
|
+
message: { type: "string" }
|
|
39817
|
+
},
|
|
39818
|
+
required: ["board_id", "emails", "role"]
|
|
39819
|
+
},
|
|
39820
|
+
request: {
|
|
39821
|
+
method: "POST",
|
|
39822
|
+
path: "/v2/boards/{board_id}/members",
|
|
39823
|
+
body: {
|
|
39824
|
+
emails: "{emails}",
|
|
39825
|
+
role: "{role}",
|
|
39826
|
+
message: "{message}"
|
|
39827
|
+
}
|
|
39828
|
+
},
|
|
39829
|
+
cas: "native-idempotency",
|
|
39830
|
+
requiredScopes: ["boards:write"]
|
|
39831
|
+
}
|
|
39832
|
+
]
|
|
39833
|
+
});
|
|
39834
|
+
|
|
39208
39835
|
// src/connectors/adapters/monday.ts
|
|
39209
39836
|
var BOARD_FRAGMENT = `
|
|
39210
39837
|
id
|
|
@@ -39329,7 +39956,7 @@ var mondayConnector = declarativeRestConnector({
|
|
|
39329
39956
|
auth: {
|
|
39330
39957
|
kind: "oauth2",
|
|
39331
39958
|
authorizationUrl: "https://auth.monday.com/oauth2/authorize",
|
|
39332
|
-
tokenUrl: "https://auth.monday.com/
|
|
39959
|
+
tokenUrl: "https://auth.monday.com/oauth_ms/oauth/token",
|
|
39333
39960
|
scopes: [
|
|
39334
39961
|
"me:read",
|
|
39335
39962
|
"boards:read",
|
|
@@ -39719,6 +40346,475 @@ var mondayConnector = declarativeRestConnector({
|
|
|
39719
40346
|
]
|
|
39720
40347
|
});
|
|
39721
40348
|
|
|
40349
|
+
// src/connectors/adapters/mongodb.ts
|
|
40350
|
+
import { isIP as isIP3 } from "net";
|
|
40351
|
+
import { createSecureContext } from "tls";
|
|
40352
|
+
import {
|
|
40353
|
+
BSON,
|
|
40354
|
+
MongoClient
|
|
40355
|
+
} from "mongodb";
|
|
40356
|
+
var MAX_NAME_BYTES = 120;
|
|
40357
|
+
var MAX_FIELD_BYTES = 256;
|
|
40358
|
+
var MAX_FILTERS = 20;
|
|
40359
|
+
var MAX_PROJECTION_FIELDS = 64;
|
|
40360
|
+
var MAX_SORT_FIELDS = 8;
|
|
40361
|
+
var MAX_COLLECTIONS = 1e3;
|
|
40362
|
+
var MAX_INDEXES = 200;
|
|
40363
|
+
var MAX_DOCUMENTS = 1e3;
|
|
40364
|
+
var MAX_RESULT_BYTES2 = 10 * 1024 * 1024;
|
|
40365
|
+
var MAX_FILTER_BYTES = 1024 * 1024;
|
|
40366
|
+
var MAX_SCALAR_STRING_BYTES = 64 * 1024;
|
|
40367
|
+
var MAX_TLS_CA_BYTES = 256 * 1024;
|
|
40368
|
+
function createMongoDbConnector(options = {}) {
|
|
40369
|
+
const createClient = options.createClient ?? defaultCreateClient;
|
|
40370
|
+
const resolveHost = options.resolveHost ?? resolvePublicHostAddresses;
|
|
40371
|
+
return {
|
|
40372
|
+
manifest: {
|
|
40373
|
+
kind: "mongodb",
|
|
40374
|
+
displayName: "MongoDB",
|
|
40375
|
+
description: "Inspect MongoDB collections and indexes and run bounded structured document reads over a verified TLS connection.",
|
|
40376
|
+
auth: {
|
|
40377
|
+
kind: "api-key",
|
|
40378
|
+
hint: "JSON with a public MongoDB host, database, user, password, optional port/auth source, and optional TLS CA. Verified TLS is mandatory."
|
|
40379
|
+
},
|
|
40380
|
+
category: "database",
|
|
40381
|
+
defaultConsistencyModel: "authoritative",
|
|
40382
|
+
rateLimit: { requests: 120, windowMs: 6e4, scope: "data-source" },
|
|
40383
|
+
capabilities: [
|
|
40384
|
+
readCapability6("mongodb.collections.list", "List collections visible in the configured database.", {
|
|
40385
|
+
type: "object",
|
|
40386
|
+
properties: {},
|
|
40387
|
+
additionalProperties: false
|
|
40388
|
+
}),
|
|
40389
|
+
readCapability6("mongodb.collections.describe", "Read options and metadata for one collection.", collectionSchema()),
|
|
40390
|
+
readCapability6("mongodb.indexes.list", "List bounded index metadata for one collection.", collectionSchema()),
|
|
40391
|
+
readCapability6("mongodb.documents.find", "Read bounded documents using fixed scalar predicates, projection, and sort fields.", {
|
|
40392
|
+
type: "object",
|
|
40393
|
+
properties: {
|
|
40394
|
+
collection: nameParameter("Collection name."),
|
|
40395
|
+
filters: filterArraySchema(),
|
|
40396
|
+
fields: {
|
|
40397
|
+
type: "array",
|
|
40398
|
+
minItems: 1,
|
|
40399
|
+
maxItems: MAX_PROJECTION_FIELDS,
|
|
40400
|
+
uniqueItems: true,
|
|
40401
|
+
items: fieldParameter()
|
|
40402
|
+
},
|
|
40403
|
+
includeId: { type: "boolean", default: true },
|
|
40404
|
+
sort: {
|
|
40405
|
+
type: "array",
|
|
40406
|
+
maxItems: MAX_SORT_FIELDS,
|
|
40407
|
+
items: {
|
|
40408
|
+
type: "object",
|
|
40409
|
+
properties: {
|
|
40410
|
+
field: fieldParameter(),
|
|
40411
|
+
direction: { type: "string", enum: ["asc", "desc"], default: "asc" }
|
|
40412
|
+
},
|
|
40413
|
+
required: ["field"],
|
|
40414
|
+
additionalProperties: false
|
|
40415
|
+
}
|
|
40416
|
+
},
|
|
40417
|
+
limit: { type: "integer", minimum: 1, maximum: MAX_DOCUMENTS, default: 100 },
|
|
40418
|
+
skip: { type: "integer", minimum: 0, maximum: 1e6, default: 0 }
|
|
40419
|
+
},
|
|
40420
|
+
required: ["collection"],
|
|
40421
|
+
additionalProperties: false
|
|
40422
|
+
}),
|
|
40423
|
+
readCapability6("mongodb.documents.count", "Count documents matching fixed scalar predicates within a bounded server execution time.", {
|
|
40424
|
+
type: "object",
|
|
40425
|
+
properties: {
|
|
40426
|
+
collection: nameParameter("Collection name."),
|
|
40427
|
+
filters: filterArraySchema()
|
|
40428
|
+
},
|
|
40429
|
+
required: ["collection"],
|
|
40430
|
+
additionalProperties: false
|
|
40431
|
+
})
|
|
40432
|
+
]
|
|
40433
|
+
},
|
|
40434
|
+
async test(source) {
|
|
40435
|
+
try {
|
|
40436
|
+
await withClient(source, createClient, resolveHost, async (client, credentials) => {
|
|
40437
|
+
const response = await client.db(credentials.database).command(
|
|
40438
|
+
{ ping: 1 },
|
|
40439
|
+
{ maxTimeMS: credentials.commandTimeoutMs }
|
|
40440
|
+
);
|
|
40441
|
+
if (response.ok !== 1) throw new Error("MongoDB ping returned an unexpected response");
|
|
40442
|
+
});
|
|
40443
|
+
return { ok: true };
|
|
40444
|
+
} catch (error) {
|
|
40445
|
+
return { ok: false, reason: safeErrorMessage(error, credentialSecrets(source)) };
|
|
40446
|
+
}
|
|
40447
|
+
},
|
|
40448
|
+
async executeRead(invocation) {
|
|
40449
|
+
const request4 = prepareRead(invocation);
|
|
40450
|
+
const data4 = await withClient(invocation.source, createClient, resolveHost, async (client, credentials) => {
|
|
40451
|
+
return executeRead(request4, client.db(credentials.database), credentials.commandTimeoutMs);
|
|
40452
|
+
});
|
|
40453
|
+
return { data: data4, fetchedAt: Date.now() };
|
|
40454
|
+
}
|
|
40455
|
+
};
|
|
40456
|
+
}
|
|
40457
|
+
var mongodbConnector = createMongoDbConnector();
|
|
40458
|
+
function defaultCreateClient(uri, options) {
|
|
40459
|
+
return new MongoClient(uri, options);
|
|
40460
|
+
}
|
|
40461
|
+
async function withClient(source, createClient, resolveHost, run) {
|
|
40462
|
+
const credentials = readCredentials2(source);
|
|
40463
|
+
const addresses = await resolveHost(credentials.host);
|
|
40464
|
+
if (addresses.length === 0) throw new Error("MongoDB host did not resolve");
|
|
40465
|
+
const uriHost = isIP3(credentials.host) === 6 ? `[${credentials.host}]` : credentials.host;
|
|
40466
|
+
const client = createClient(`mongodb://${uriHost}:${credentials.port}/`, {
|
|
40467
|
+
appName: "tangle-integration-hub",
|
|
40468
|
+
auth: { username: credentials.user, password: credentials.password },
|
|
40469
|
+
authSource: credentials.authSource,
|
|
40470
|
+
connectTimeoutMS: credentials.connectTimeoutMs,
|
|
40471
|
+
directConnection: true,
|
|
40472
|
+
lookup: pinnedLookup(addresses[0]),
|
|
40473
|
+
maxIdleTimeMS: 5e3,
|
|
40474
|
+
maxPoolSize: 1,
|
|
40475
|
+
minPoolSize: 0,
|
|
40476
|
+
rejectUnauthorized: true,
|
|
40477
|
+
retryReads: true,
|
|
40478
|
+
retryWrites: false,
|
|
40479
|
+
serverSelectionTimeoutMS: credentials.connectTimeoutMs,
|
|
40480
|
+
servername: isIP3(credentials.host) === 0 ? credentials.host : void 0,
|
|
40481
|
+
secureContext: createSecureContext({ ca: credentials.tlsCa, minVersion: "TLSv1.2" }),
|
|
40482
|
+
socketTimeoutMS: credentials.commandTimeoutMs,
|
|
40483
|
+
tls: true
|
|
40484
|
+
});
|
|
40485
|
+
try {
|
|
40486
|
+
await client.connect();
|
|
40487
|
+
return await run(client, credentials);
|
|
40488
|
+
} catch (error) {
|
|
40489
|
+
throw new Error(safeErrorMessage(error, credentials.secrets));
|
|
40490
|
+
} finally {
|
|
40491
|
+
await client.close().catch(() => void 0);
|
|
40492
|
+
}
|
|
40493
|
+
}
|
|
40494
|
+
async function executeRead(request4, database, commandTimeoutMs) {
|
|
40495
|
+
if (request4.kind === "collections.list") {
|
|
40496
|
+
const collections = await readCursor(
|
|
40497
|
+
database.listCollections({}, { nameOnly: true, maxTimeMS: commandTimeoutMs }),
|
|
40498
|
+
MAX_COLLECTIONS,
|
|
40499
|
+
"MongoDB collection list"
|
|
40500
|
+
);
|
|
40501
|
+
return boundedResult({ collections }, "MongoDB collection list");
|
|
40502
|
+
}
|
|
40503
|
+
if (request4.kind === "collections.describe") {
|
|
40504
|
+
const matches = await readCursor(
|
|
40505
|
+
database.listCollections({ name: request4.collection }, { nameOnly: false, maxTimeMS: commandTimeoutMs }),
|
|
40506
|
+
1,
|
|
40507
|
+
"MongoDB collection description"
|
|
40508
|
+
);
|
|
40509
|
+
return boundedResult({ collection: matches[0] ?? null }, "MongoDB collection description");
|
|
40510
|
+
}
|
|
40511
|
+
if (request4.kind === "indexes.list") {
|
|
40512
|
+
const indexes = await readCursor(
|
|
40513
|
+
database.collection(request4.collection).listIndexes({ maxTimeMS: commandTimeoutMs }),
|
|
40514
|
+
MAX_INDEXES,
|
|
40515
|
+
"MongoDB index list"
|
|
40516
|
+
);
|
|
40517
|
+
return boundedResult({ collection: request4.collection, indexes }, "MongoDB index list");
|
|
40518
|
+
}
|
|
40519
|
+
if (request4.kind === "documents.find") {
|
|
40520
|
+
const cursor = database.collection(request4.collection).find(request4.filter, {
|
|
40521
|
+
...request4.projection ? { projection: request4.projection } : {},
|
|
40522
|
+
maxTimeMS: commandTimeoutMs
|
|
40523
|
+
});
|
|
40524
|
+
if (Object.keys(request4.sort).length > 0) cursor.sort(request4.sort);
|
|
40525
|
+
cursor.skip(request4.skip).limit(request4.limit);
|
|
40526
|
+
const documents = await readCursor(cursor, request4.limit, "MongoDB document result");
|
|
40527
|
+
return boundedResult({ collection: request4.collection, documents }, "MongoDB document result");
|
|
40528
|
+
}
|
|
40529
|
+
if (request4.kind === "documents.count") {
|
|
40530
|
+
const count = await database.collection(request4.collection).countDocuments(request4.filter, { maxTimeMS: commandTimeoutMs });
|
|
40531
|
+
if (!Number.isSafeInteger(count) || count < 0) throw new Error("MongoDB returned a malformed document count");
|
|
40532
|
+
return { collection: request4.collection, count };
|
|
40533
|
+
}
|
|
40534
|
+
}
|
|
40535
|
+
function prepareRead(invocation) {
|
|
40536
|
+
if (invocation.capabilityName === "mongodb.collections.list") return { kind: "collections.list" };
|
|
40537
|
+
if (invocation.capabilityName === "mongodb.collections.describe") {
|
|
40538
|
+
return { kind: "collections.describe", collection: readCollectionName(invocation.args.collection) };
|
|
40539
|
+
}
|
|
40540
|
+
if (invocation.capabilityName === "mongodb.indexes.list") {
|
|
40541
|
+
return { kind: "indexes.list", collection: readCollectionName(invocation.args.collection) };
|
|
40542
|
+
}
|
|
40543
|
+
if (invocation.capabilityName === "mongodb.documents.find") {
|
|
40544
|
+
return {
|
|
40545
|
+
kind: "documents.find",
|
|
40546
|
+
collection: readCollectionName(invocation.args.collection),
|
|
40547
|
+
filter: readFilters(invocation.args.filters),
|
|
40548
|
+
projection: readProjection(invocation.args.fields, invocation.args.includeId),
|
|
40549
|
+
sort: readSort(invocation.args.sort),
|
|
40550
|
+
limit: readBoundedInteger(invocation.args.limit, 100, 1, MAX_DOCUMENTS, "limit"),
|
|
40551
|
+
skip: readBoundedInteger(invocation.args.skip, 0, 0, 1e6, "skip")
|
|
40552
|
+
};
|
|
40553
|
+
}
|
|
40554
|
+
if (invocation.capabilityName === "mongodb.documents.count") {
|
|
40555
|
+
return {
|
|
40556
|
+
kind: "documents.count",
|
|
40557
|
+
collection: readCollectionName(invocation.args.collection),
|
|
40558
|
+
filter: readFilters(invocation.args.filters)
|
|
40559
|
+
};
|
|
40560
|
+
}
|
|
40561
|
+
throw new Error(`Unknown MongoDB read capability: ${invocation.capabilityName}`);
|
|
40562
|
+
}
|
|
40563
|
+
async function readCursor(cursor, maximum, label) {
|
|
40564
|
+
const entries = [];
|
|
40565
|
+
let serializedBytes = 2;
|
|
40566
|
+
try {
|
|
40567
|
+
while (entries.length < maximum) {
|
|
40568
|
+
const entry = await cursor.next();
|
|
40569
|
+
if (entry === null) return entries;
|
|
40570
|
+
serializedBytes += Buffer.byteLength(
|
|
40571
|
+
JSON.stringify(BSON.EJSON.serialize(entry, { relaxed: true })),
|
|
40572
|
+
"utf8"
|
|
40573
|
+
) + 1;
|
|
40574
|
+
if (serializedBytes > MAX_RESULT_BYTES2) {
|
|
40575
|
+
throw new Error(`${label} exceeds the ${MAX_RESULT_BYTES2}-byte limit`);
|
|
40576
|
+
}
|
|
40577
|
+
entries.push(entry);
|
|
40578
|
+
}
|
|
40579
|
+
if (await cursor.next() !== null) throw new Error(`${label} exceeds ${maximum} entries`);
|
|
40580
|
+
return entries;
|
|
40581
|
+
} finally {
|
|
40582
|
+
await cursor.close().catch(() => void 0);
|
|
40583
|
+
}
|
|
40584
|
+
}
|
|
40585
|
+
function readCredentials2(source) {
|
|
40586
|
+
let raw;
|
|
40587
|
+
if (source.credentials.kind === "custom") raw = source.credentials.values;
|
|
40588
|
+
else if (source.credentials.kind === "api-key") {
|
|
40589
|
+
try {
|
|
40590
|
+
raw = JSON.parse(source.credentials.apiKey);
|
|
40591
|
+
} catch {
|
|
40592
|
+
throw new Error("MongoDB credential must be valid JSON");
|
|
40593
|
+
}
|
|
40594
|
+
} else {
|
|
40595
|
+
throw new Error("MongoDB requires a structured credential bundle");
|
|
40596
|
+
}
|
|
40597
|
+
if (!isPlainRecord(raw)) throw new Error("MongoDB credential must be a JSON object");
|
|
40598
|
+
const host = readHost(raw.host);
|
|
40599
|
+
const database = readDatabaseName(raw.database, "database");
|
|
40600
|
+
const user = readCredentialString(raw.user ?? raw.username, "user", 128);
|
|
40601
|
+
const password = readCredentialString(raw.password, "password", 4096);
|
|
40602
|
+
const authSource = raw.authSource === void 0 ? "admin" : readDatabaseName(raw.authSource, "authSource");
|
|
40603
|
+
const tlsCa = readOptionalString(raw.tlsCa, "tlsCa");
|
|
40604
|
+
if (tlsCa && Buffer.byteLength(tlsCa, "utf8") > MAX_TLS_CA_BYTES) {
|
|
40605
|
+
throw new Error(`MongoDB tlsCa exceeds the ${MAX_TLS_CA_BYTES}-byte limit`);
|
|
40606
|
+
}
|
|
40607
|
+
return {
|
|
40608
|
+
host,
|
|
40609
|
+
port: readBoundedInteger(raw.port, 27017, 1, 65535, "port"),
|
|
40610
|
+
database,
|
|
40611
|
+
user,
|
|
40612
|
+
password,
|
|
40613
|
+
authSource,
|
|
40614
|
+
tlsCa,
|
|
40615
|
+
connectTimeoutMs: readBoundedInteger(raw.connectTimeoutMs, 1e4, 1e3, 3e4, "connectTimeoutMs"),
|
|
40616
|
+
commandTimeoutMs: readBoundedInteger(raw.commandTimeoutMs, 3e4, 1e3, 6e4, "commandTimeoutMs"),
|
|
40617
|
+
secrets: [password]
|
|
40618
|
+
};
|
|
40619
|
+
}
|
|
40620
|
+
function readFilters(value) {
|
|
40621
|
+
if (value === void 0 || value === null) return {};
|
|
40622
|
+
if (!Array.isArray(value) || value.length > MAX_FILTERS) {
|
|
40623
|
+
throw new Error(`filters must contain at most ${MAX_FILTERS} entries`);
|
|
40624
|
+
}
|
|
40625
|
+
const predicates = value.map((entry, index) => {
|
|
40626
|
+
if (!isPlainRecord(entry)) throw new Error(`filters[${index}] must be an object`);
|
|
40627
|
+
const field = readField(entry.field, `filters[${index}].field`);
|
|
40628
|
+
const operator = entry.operator;
|
|
40629
|
+
if (!["eq", "ne", "lt", "lte", "gt", "gte"].includes(String(operator))) {
|
|
40630
|
+
throw new Error(`filters[${index}].operator is unsupported`);
|
|
40631
|
+
}
|
|
40632
|
+
const scalar = readScalar(entry.value, `filters[${index}].value`);
|
|
40633
|
+
return { [field]: { [mongoOperator(String(operator))]: scalar } };
|
|
40634
|
+
});
|
|
40635
|
+
const filter = predicates.length === 0 ? {} : { $and: predicates };
|
|
40636
|
+
if (Buffer.byteLength(JSON.stringify(filter), "utf8") > MAX_FILTER_BYTES) {
|
|
40637
|
+
throw new Error(`MongoDB filters exceed the ${MAX_FILTER_BYTES}-byte limit`);
|
|
40638
|
+
}
|
|
40639
|
+
return filter;
|
|
40640
|
+
}
|
|
40641
|
+
function readProjection(fieldsValue, includeIdValue) {
|
|
40642
|
+
const includeId = includeIdValue === void 0 || includeIdValue === null ? true : readBoolean2(includeIdValue, "includeId");
|
|
40643
|
+
if (fieldsValue === void 0 || fieldsValue === null) return includeId ? void 0 : { _id: 0 };
|
|
40644
|
+
const fields = readFieldArray(fieldsValue, "fields", MAX_PROJECTION_FIELDS, true);
|
|
40645
|
+
return Object.fromEntries([
|
|
40646
|
+
...fields.map((field) => [field, 1]),
|
|
40647
|
+
...!includeId && !fields.includes("_id") ? [["_id", 0]] : []
|
|
40648
|
+
]);
|
|
40649
|
+
}
|
|
40650
|
+
function readSort(value) {
|
|
40651
|
+
if (value === void 0 || value === null) return {};
|
|
40652
|
+
if (!Array.isArray(value) || value.length > MAX_SORT_FIELDS) {
|
|
40653
|
+
throw new Error(`sort must contain at most ${MAX_SORT_FIELDS} entries`);
|
|
40654
|
+
}
|
|
40655
|
+
const entries = value.map((entry, index) => {
|
|
40656
|
+
if (!isPlainRecord(entry)) throw new Error(`sort[${index}] must be an object`);
|
|
40657
|
+
const field = readField(entry.field, `sort[${index}].field`);
|
|
40658
|
+
const direction = entry.direction ?? "asc";
|
|
40659
|
+
if (direction !== "asc" && direction !== "desc") {
|
|
40660
|
+
throw new Error(`sort[${index}].direction must be asc or desc`);
|
|
40661
|
+
}
|
|
40662
|
+
return [field, direction === "asc" ? 1 : -1];
|
|
40663
|
+
});
|
|
40664
|
+
if (new Set(entries.map(([field]) => field)).size !== entries.length) {
|
|
40665
|
+
throw new Error("sort must not contain duplicate fields");
|
|
40666
|
+
}
|
|
40667
|
+
return Object.fromEntries(entries);
|
|
40668
|
+
}
|
|
40669
|
+
function readFieldArray(value, label, maximum, required) {
|
|
40670
|
+
if (!Array.isArray(value) || required && value.length === 0 || value.length > maximum) {
|
|
40671
|
+
throw new Error(`${label} must contain ${required ? "1-" : "0-"}${maximum} fields`);
|
|
40672
|
+
}
|
|
40673
|
+
const fields = value.map((entry, index) => readField(entry, `${label}[${index}]`));
|
|
40674
|
+
if (new Set(fields).size !== fields.length) throw new Error(`${label} must not contain duplicates`);
|
|
40675
|
+
return fields;
|
|
40676
|
+
}
|
|
40677
|
+
function readScalar(value, label) {
|
|
40678
|
+
if (value === null || typeof value === "boolean") return value;
|
|
40679
|
+
if (typeof value === "number") {
|
|
40680
|
+
if (!Number.isFinite(value)) throw new Error(`${label} must be finite`);
|
|
40681
|
+
return value;
|
|
40682
|
+
}
|
|
40683
|
+
if (typeof value === "string") {
|
|
40684
|
+
if (Buffer.byteLength(value, "utf8") > MAX_SCALAR_STRING_BYTES) {
|
|
40685
|
+
throw new Error(`${label} exceeds the ${MAX_SCALAR_STRING_BYTES}-byte limit`);
|
|
40686
|
+
}
|
|
40687
|
+
return value;
|
|
40688
|
+
}
|
|
40689
|
+
throw new Error(`${label} must be a JSON scalar or null`);
|
|
40690
|
+
}
|
|
40691
|
+
function mongoOperator(value) {
|
|
40692
|
+
return { eq: "$eq", ne: "$ne", lt: "$lt", lte: "$lte", gt: "$gt", gte: "$gte" }[value];
|
|
40693
|
+
}
|
|
40694
|
+
function boundedResult(value, label) {
|
|
40695
|
+
const serialized = BSON.EJSON.serialize(value, { relaxed: true });
|
|
40696
|
+
if (Buffer.byteLength(JSON.stringify(serialized), "utf8") > MAX_RESULT_BYTES2) {
|
|
40697
|
+
throw new Error(`${label} exceeds the ${MAX_RESULT_BYTES2}-byte limit`);
|
|
40698
|
+
}
|
|
40699
|
+
return serialized;
|
|
40700
|
+
}
|
|
40701
|
+
function readHost(value) {
|
|
40702
|
+
const host = readCredentialString(value, "host", 253);
|
|
40703
|
+
const ipVersion = isIP3(host);
|
|
40704
|
+
if (ipVersion !== 0) {
|
|
40705
|
+
if (!isPublicNetworkAddress(host)) throw new Error("MongoDB host is not a public network target");
|
|
40706
|
+
return host;
|
|
40707
|
+
}
|
|
40708
|
+
const normalized = host.toLowerCase();
|
|
40709
|
+
if (normalized === "localhost" || normalized.endsWith(".localhost") || normalized.endsWith(".local") || /[\s/@:\[\]]/.test(host)) {
|
|
40710
|
+
throw new Error("MongoDB host must be a public hostname or IP address without a scheme or port");
|
|
40711
|
+
}
|
|
40712
|
+
return host;
|
|
40713
|
+
}
|
|
40714
|
+
function readName(value, label) {
|
|
40715
|
+
if (typeof value !== "string" || value.length === 0 || Buffer.byteLength(value, "utf8") > MAX_NAME_BYTES || /[\u0000-\u001f\u007f/\\]/.test(value)) {
|
|
40716
|
+
throw new Error(`${label} must be a non-empty MongoDB name under ${MAX_NAME_BYTES} bytes`);
|
|
40717
|
+
}
|
|
40718
|
+
return value;
|
|
40719
|
+
}
|
|
40720
|
+
function readCollectionName(value) {
|
|
40721
|
+
const collection = readName(value, "collection");
|
|
40722
|
+
if (collection.startsWith("system.") || collection.includes("$")) {
|
|
40723
|
+
throw new Error("collection must not target MongoDB system or command namespaces");
|
|
40724
|
+
}
|
|
40725
|
+
return collection;
|
|
40726
|
+
}
|
|
40727
|
+
function readDatabaseName(value, label) {
|
|
40728
|
+
const database = readName(value, label);
|
|
40729
|
+
if (Buffer.byteLength(database, "utf8") > 63 || !/^[A-Za-z0-9_-]+$/.test(database)) {
|
|
40730
|
+
throw new Error(`${label} must use only letters, numbers, underscores, or hyphens and stay under 63 bytes`);
|
|
40731
|
+
}
|
|
40732
|
+
return database;
|
|
40733
|
+
}
|
|
40734
|
+
function readField(value, label) {
|
|
40735
|
+
if (typeof value !== "string" || value.length === 0 || Buffer.byteLength(value, "utf8") > MAX_FIELD_BYTES || !/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(value)) {
|
|
40736
|
+
throw new Error(`${label} must be a dotted MongoDB field path under ${MAX_FIELD_BYTES} bytes`);
|
|
40737
|
+
}
|
|
40738
|
+
return value;
|
|
40739
|
+
}
|
|
40740
|
+
function readCredentialString(value, label, maximum) {
|
|
40741
|
+
if (typeof value !== "string" || value.length === 0 || value.length > maximum || label !== "password" && /[\u0000-\u001f\u007f]/.test(value)) {
|
|
40742
|
+
throw new Error(`MongoDB credential ${label} must be a non-empty string under ${maximum} characters`);
|
|
40743
|
+
}
|
|
40744
|
+
return value;
|
|
40745
|
+
}
|
|
40746
|
+
function readBoolean2(value, label) {
|
|
40747
|
+
if (typeof value !== "boolean") throw new Error(`${label} must be a boolean`);
|
|
40748
|
+
return value;
|
|
40749
|
+
}
|
|
40750
|
+
function pinnedLookup(address) {
|
|
40751
|
+
const family = isIP3(address);
|
|
40752
|
+
return (_hostname, options, callback) => {
|
|
40753
|
+
const normalizedOptions = typeof options === "number" ? { family: options } : options;
|
|
40754
|
+
if (normalizedOptions?.family && normalizedOptions.family !== family) {
|
|
40755
|
+
callback(new Error("MongoDB pinned address does not match the requested network family"), "", 0);
|
|
40756
|
+
return;
|
|
40757
|
+
}
|
|
40758
|
+
if (normalizedOptions?.all) {
|
|
40759
|
+
callback(null, [{ address, family }], void 0);
|
|
40760
|
+
return;
|
|
40761
|
+
}
|
|
40762
|
+
callback(null, address, family);
|
|
40763
|
+
};
|
|
40764
|
+
}
|
|
40765
|
+
function safeErrorMessage(error, secrets) {
|
|
40766
|
+
let message = error instanceof Error ? error.message : String(error);
|
|
40767
|
+
for (const secret of secrets) {
|
|
40768
|
+
if (secret.length >= 4) message = message.replaceAll(secret, "[REDACTED]");
|
|
40769
|
+
}
|
|
40770
|
+
return message;
|
|
40771
|
+
}
|
|
40772
|
+
function credentialSecrets(source) {
|
|
40773
|
+
try {
|
|
40774
|
+
return readCredentials2(source).secrets;
|
|
40775
|
+
} catch {
|
|
40776
|
+
return [];
|
|
40777
|
+
}
|
|
40778
|
+
}
|
|
40779
|
+
function collectionSchema() {
|
|
40780
|
+
return {
|
|
40781
|
+
type: "object",
|
|
40782
|
+
properties: { collection: nameParameter("Collection name.") },
|
|
40783
|
+
required: ["collection"],
|
|
40784
|
+
additionalProperties: false
|
|
40785
|
+
};
|
|
40786
|
+
}
|
|
40787
|
+
function filterArraySchema() {
|
|
40788
|
+
return {
|
|
40789
|
+
type: "array",
|
|
40790
|
+
maxItems: MAX_FILTERS,
|
|
40791
|
+
items: {
|
|
40792
|
+
type: "object",
|
|
40793
|
+
properties: {
|
|
40794
|
+
field: fieldParameter(),
|
|
40795
|
+
operator: { type: "string", enum: ["eq", "ne", "lt", "lte", "gt", "gte"] },
|
|
40796
|
+
value: { type: ["string", "number", "boolean", "null"] }
|
|
40797
|
+
},
|
|
40798
|
+
required: ["field", "operator", "value"],
|
|
40799
|
+
additionalProperties: false
|
|
40800
|
+
}
|
|
40801
|
+
};
|
|
40802
|
+
}
|
|
40803
|
+
function nameParameter(description) {
|
|
40804
|
+
return { type: "string", minLength: 1, maxLength: MAX_NAME_BYTES, description };
|
|
40805
|
+
}
|
|
40806
|
+
function fieldParameter() {
|
|
40807
|
+
return {
|
|
40808
|
+
type: "string",
|
|
40809
|
+
minLength: 1,
|
|
40810
|
+
maxLength: MAX_FIELD_BYTES,
|
|
40811
|
+
pattern: "^[A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*)*$"
|
|
40812
|
+
};
|
|
40813
|
+
}
|
|
40814
|
+
function readCapability6(name, description, parameters) {
|
|
40815
|
+
return { name, class: "read", description, parameters };
|
|
40816
|
+
}
|
|
40817
|
+
|
|
39722
40818
|
// src/connectors/adapters/mycase.ts
|
|
39723
40819
|
var pageProperties = {
|
|
39724
40820
|
page: { type: "integer", minimum: 1 },
|
|
@@ -44747,12 +45843,12 @@ var quickbooksConnector = declarativeRestConnector({
|
|
|
44747
45843
|
|
|
44748
45844
|
// src/connectors/adapters/rabbitmq.ts
|
|
44749
45845
|
import { createHash as createHash7 } from "crypto";
|
|
44750
|
-
import { isIP as
|
|
45846
|
+
import { isIP as isIP4 } from "net";
|
|
44751
45847
|
import {
|
|
44752
45848
|
connect as amqpConnect
|
|
44753
45849
|
} from "amqplib";
|
|
44754
45850
|
var MAX_MESSAGE_BYTES3 = 1024 * 1024;
|
|
44755
|
-
var
|
|
45851
|
+
var MAX_NAME_BYTES2 = 255;
|
|
44756
45852
|
var MAX_PEM_BYTES = 64 * 1024;
|
|
44757
45853
|
var MAX_CA_CERTIFICATES = 16;
|
|
44758
45854
|
var MAX_CA_BYTES = 256 * 1024;
|
|
@@ -44772,13 +45868,13 @@ function createRabbitMqConnector(options = {}) {
|
|
|
44772
45868
|
category: "webhook",
|
|
44773
45869
|
rateLimit: { requests: 120, windowMs: 6e4, scope: "data-source" },
|
|
44774
45870
|
capabilities: [
|
|
44775
|
-
|
|
45871
|
+
readCapability7("rabbitmq.queues.inspect", "Check a queue and return its current message and consumer counts.", {
|
|
44776
45872
|
type: "object",
|
|
44777
45873
|
properties: { queue: nameSchema("queue") },
|
|
44778
45874
|
required: ["queue"],
|
|
44779
45875
|
additionalProperties: false
|
|
44780
45876
|
}),
|
|
44781
|
-
|
|
45877
|
+
readCapability7("rabbitmq.exchanges.inspect", "Check whether a named exchange exists and is visible to the connection.", {
|
|
44782
45878
|
type: "object",
|
|
44783
45879
|
properties: { exchange: nameSchema("exchange") },
|
|
44784
45880
|
required: ["exchange"],
|
|
@@ -44800,7 +45896,7 @@ function createRabbitMqConnector(options = {}) {
|
|
|
44800
45896
|
type: "object",
|
|
44801
45897
|
properties: {
|
|
44802
45898
|
exchange: nameSchema("exchange"),
|
|
44803
|
-
routingKey: { type: "string", maxLength:
|
|
45899
|
+
routingKey: { type: "string", maxLength: MAX_NAME_BYTES2, default: "" },
|
|
44804
45900
|
data: {},
|
|
44805
45901
|
persistent: { type: "boolean", default: true },
|
|
44806
45902
|
expirationMs: { type: "integer", minimum: 1, maximum: 6048e5 },
|
|
@@ -44813,7 +45909,7 @@ function createRabbitMqConnector(options = {}) {
|
|
|
44813
45909
|
},
|
|
44814
45910
|
async executeRead({ source, capabilityName, args }) {
|
|
44815
45911
|
if (capabilityName === "rabbitmq.queues.inspect") {
|
|
44816
|
-
const queue =
|
|
45912
|
+
const queue = readName2(args.queue, "queue");
|
|
44817
45913
|
const data4 = await withChannel(source, connect, resolveHost, async (channel) => {
|
|
44818
45914
|
const details = await channel.checkQueue(queue);
|
|
44819
45915
|
return { queue: details.queue, messageCount: details.messageCount, consumerCount: details.consumerCount };
|
|
@@ -44821,7 +45917,7 @@ function createRabbitMqConnector(options = {}) {
|
|
|
44821
45917
|
return { data: data4, fetchedAt: Date.now() };
|
|
44822
45918
|
}
|
|
44823
45919
|
if (capabilityName === "rabbitmq.exchanges.inspect") {
|
|
44824
|
-
const exchange =
|
|
45920
|
+
const exchange = readName2(args.exchange, "exchange");
|
|
44825
45921
|
const data4 = await withChannel(source, connect, resolveHost, async (channel) => {
|
|
44826
45922
|
await channel.checkExchange(exchange);
|
|
44827
45923
|
return { exchange, exists: true };
|
|
@@ -44833,7 +45929,7 @@ function createRabbitMqConnector(options = {}) {
|
|
|
44833
45929
|
async executeMutation({ source, capabilityName, args, idempotencyKey }) {
|
|
44834
45930
|
let data4;
|
|
44835
45931
|
if (capabilityName === "send.message.to.queue") {
|
|
44836
|
-
const queue =
|
|
45932
|
+
const queue = readName2(args.queue, "queue");
|
|
44837
45933
|
const body = readJsonMessage(args.data);
|
|
44838
45934
|
const publishOptions = readPublishOptions(args, idempotencyKey);
|
|
44839
45935
|
data4 = await withConfirmChannel(source, connect, resolveHost, async (channel) => {
|
|
@@ -44842,7 +45938,7 @@ function createRabbitMqConnector(options = {}) {
|
|
|
44842
45938
|
return { queue, confirmed: true, messageId: publishOptions.messageId, byteLength: body.byteLength };
|
|
44843
45939
|
});
|
|
44844
45940
|
} else if (capabilityName === "send.message.to.exchange") {
|
|
44845
|
-
const exchange =
|
|
45941
|
+
const exchange = readName2(args.exchange, "exchange");
|
|
44846
45942
|
const routingKey = readRoutingKey(args.routingKey);
|
|
44847
45943
|
const body = readJsonMessage(args.data);
|
|
44848
45944
|
const publishOptions = readPublishOptions(args, idempotencyKey);
|
|
@@ -44858,20 +45954,20 @@ function createRabbitMqConnector(options = {}) {
|
|
|
44858
45954
|
},
|
|
44859
45955
|
async test(source) {
|
|
44860
45956
|
try {
|
|
44861
|
-
const credentials =
|
|
45957
|
+
const credentials = readCredentials3(source);
|
|
44862
45958
|
await resolveHost(credentials.host);
|
|
44863
45959
|
const model2 = await connect(credentials.connectOptions, credentials.socketOptions);
|
|
44864
45960
|
await model2.close();
|
|
44865
45961
|
return { ok: true };
|
|
44866
45962
|
} catch (error) {
|
|
44867
|
-
return { ok: false, reason:
|
|
45963
|
+
return { ok: false, reason: safeErrorMessage2(error, credentialSecrets2(source)) };
|
|
44868
45964
|
}
|
|
44869
45965
|
}
|
|
44870
45966
|
};
|
|
44871
45967
|
}
|
|
44872
45968
|
var rabbitMqConnector = createRabbitMqConnector();
|
|
44873
45969
|
async function withChannel(source, connect, resolveHost, run) {
|
|
44874
|
-
const credentials =
|
|
45970
|
+
const credentials = readCredentials3(source);
|
|
44875
45971
|
await resolveHost(credentials.host);
|
|
44876
45972
|
let model2;
|
|
44877
45973
|
let channel;
|
|
@@ -44880,14 +45976,14 @@ async function withChannel(source, connect, resolveHost, run) {
|
|
|
44880
45976
|
channel = await model2.createChannel();
|
|
44881
45977
|
return await run(channel);
|
|
44882
45978
|
} catch (error) {
|
|
44883
|
-
throw new Error(
|
|
45979
|
+
throw new Error(safeErrorMessage2(error, credentials.secrets));
|
|
44884
45980
|
} finally {
|
|
44885
45981
|
await channel?.close().catch(() => void 0);
|
|
44886
45982
|
await model2?.close().catch(() => void 0);
|
|
44887
45983
|
}
|
|
44888
45984
|
}
|
|
44889
45985
|
async function withConfirmChannel(source, connect, resolveHost, run) {
|
|
44890
|
-
const credentials =
|
|
45986
|
+
const credentials = readCredentials3(source);
|
|
44891
45987
|
await resolveHost(credentials.host);
|
|
44892
45988
|
let model2;
|
|
44893
45989
|
let channel;
|
|
@@ -44896,7 +45992,7 @@ async function withConfirmChannel(source, connect, resolveHost, run) {
|
|
|
44896
45992
|
channel = await model2.createConfirmChannel();
|
|
44897
45993
|
return await run(channel);
|
|
44898
45994
|
} catch (error) {
|
|
44899
|
-
throw new Error(
|
|
45995
|
+
throw new Error(safeErrorMessage2(error, credentials.secrets));
|
|
44900
45996
|
} finally {
|
|
44901
45997
|
await channel?.close().catch(() => void 0);
|
|
44902
45998
|
await model2?.close().catch(() => void 0);
|
|
@@ -44916,7 +46012,7 @@ async function publishConfirmed(channel, publishOptions, publish) {
|
|
|
44916
46012
|
channel.removeListener("return", onReturn);
|
|
44917
46013
|
}
|
|
44918
46014
|
}
|
|
44919
|
-
function
|
|
46015
|
+
function readCredentials3(source) {
|
|
44920
46016
|
let raw;
|
|
44921
46017
|
if (source.credentials.kind === "custom") raw = source.credentials.values;
|
|
44922
46018
|
else if (source.credentials.kind === "api-key") {
|
|
@@ -44929,13 +46025,13 @@ function readCredentials2(source) {
|
|
|
44929
46025
|
throw new Error("RabbitMQ requires a structured credential bundle");
|
|
44930
46026
|
}
|
|
44931
46027
|
if (!isPlainRecord(raw)) throw new Error("RabbitMQ credential must be a JSON object");
|
|
44932
|
-
const host =
|
|
46028
|
+
const host = readHost2(raw.host);
|
|
44933
46029
|
const port = readBoundedInteger(raw.port, 5671, 1, 65535, "port");
|
|
44934
46030
|
const username = readRequiredString(raw.username, "username", 1024);
|
|
44935
46031
|
const password = readRequiredString(raw.password, "password", 4096);
|
|
44936
46032
|
const vhost = readOptionalString(raw.vhost, "vhost") ?? "/";
|
|
44937
|
-
if (Buffer.byteLength(vhost, "utf8") >
|
|
44938
|
-
throw new Error(`vhost must be at most ${
|
|
46033
|
+
if (Buffer.byteLength(vhost, "utf8") > MAX_NAME_BYTES2 || /[\u0000-\u001f\u007f]/.test(vhost)) {
|
|
46034
|
+
throw new Error(`vhost must be at most ${MAX_NAME_BYTES2} bytes without control characters`);
|
|
44939
46035
|
}
|
|
44940
46036
|
const ca = readPem(raw.tlsCa, "tlsCa", true);
|
|
44941
46037
|
const cert = readPem(raw.tlsCert, "tlsCert", false);
|
|
@@ -44957,7 +46053,7 @@ function readCredentials2(source) {
|
|
|
44957
46053
|
socketOptions: {
|
|
44958
46054
|
minVersion: "TLSv1.2",
|
|
44959
46055
|
rejectUnauthorized: true,
|
|
44960
|
-
servername:
|
|
46056
|
+
servername: isIP4(host) === 0 ? host : void 0,
|
|
44961
46057
|
lookup: publicDnsLookup,
|
|
44962
46058
|
timeout: readBoundedInteger(raw.connectionTimeoutMs, 1e4, 1e3, 3e4, "connectionTimeoutMs"),
|
|
44963
46059
|
noDelay: true,
|
|
@@ -44971,9 +46067,9 @@ function readCredentials2(source) {
|
|
|
44971
46067
|
secrets: [password, ...cert ? [cert] : [], ...key ? [key] : [], ...passphrase ? [passphrase] : []]
|
|
44972
46068
|
};
|
|
44973
46069
|
}
|
|
44974
|
-
function
|
|
46070
|
+
function readHost2(value) {
|
|
44975
46071
|
const host = readRequiredString(value, "host", 253);
|
|
44976
|
-
const ipVersion =
|
|
46072
|
+
const ipVersion = isIP4(host);
|
|
44977
46073
|
if (ipVersion !== 0) {
|
|
44978
46074
|
if (!isPublicNetworkAddress(host)) throw new Error("RabbitMQ host is not a public network target");
|
|
44979
46075
|
return host;
|
|
@@ -45012,16 +46108,16 @@ function readJsonMessage(value) {
|
|
|
45012
46108
|
if (body.byteLength > MAX_MESSAGE_BYTES3) throw new Error(`data exceeds the ${MAX_MESSAGE_BYTES3}-byte limit`);
|
|
45013
46109
|
return body;
|
|
45014
46110
|
}
|
|
45015
|
-
function
|
|
45016
|
-
const name = readRequiredString(value, label,
|
|
45017
|
-
if (Buffer.byteLength(name, "utf8") >
|
|
45018
|
-
throw new Error(`${label} must be at most ${
|
|
46111
|
+
function readName2(value, label) {
|
|
46112
|
+
const name = readRequiredString(value, label, MAX_NAME_BYTES2);
|
|
46113
|
+
if (Buffer.byteLength(name, "utf8") > MAX_NAME_BYTES2 || /[\u0000-\u001f\u007f]/.test(name)) {
|
|
46114
|
+
throw new Error(`${label} must be at most ${MAX_NAME_BYTES2} bytes without control characters`);
|
|
45019
46115
|
}
|
|
45020
46116
|
return name;
|
|
45021
46117
|
}
|
|
45022
46118
|
function readRoutingKey(value) {
|
|
45023
46119
|
if (value === void 0 || value === null || value === "") return "";
|
|
45024
|
-
return
|
|
46120
|
+
return readName2(value, "routingKey");
|
|
45025
46121
|
}
|
|
45026
46122
|
function readRequiredString(value, label, maxLength) {
|
|
45027
46123
|
if (typeof value !== "string" || value.length === 0 || value.length > maxLength) {
|
|
@@ -45039,32 +46135,32 @@ function readPem(value, label, allowArray) {
|
|
|
45039
46135
|
}
|
|
45040
46136
|
return allowArray ? values : values[0];
|
|
45041
46137
|
}
|
|
45042
|
-
function
|
|
46138
|
+
function credentialSecrets2(source) {
|
|
45043
46139
|
try {
|
|
45044
|
-
return
|
|
46140
|
+
return readCredentials3(source).secrets;
|
|
45045
46141
|
} catch {
|
|
45046
46142
|
return [];
|
|
45047
46143
|
}
|
|
45048
46144
|
}
|
|
45049
|
-
function
|
|
46145
|
+
function safeErrorMessage2(error, secrets) {
|
|
45050
46146
|
let message = error instanceof Error ? error.message : String(error);
|
|
45051
46147
|
for (const secret of secrets) {
|
|
45052
46148
|
if (secret.length >= 4) message = message.replaceAll(secret, "[REDACTED]");
|
|
45053
46149
|
}
|
|
45054
46150
|
return message;
|
|
45055
46151
|
}
|
|
45056
|
-
function
|
|
46152
|
+
function readCapability7(name, description, parameters) {
|
|
45057
46153
|
return { name, class: "read", description, parameters };
|
|
45058
46154
|
}
|
|
45059
46155
|
function mutationCapability6(name, description, parameters) {
|
|
45060
46156
|
return { name, class: "mutation", description, parameters, cas: "none", externalEffect: true };
|
|
45061
46157
|
}
|
|
45062
46158
|
function nameSchema(label) {
|
|
45063
|
-
return { type: "string", minLength: 1, maxLength:
|
|
46159
|
+
return { type: "string", minLength: 1, maxLength: MAX_NAME_BYTES2, description: `Existing RabbitMQ ${label} name.` };
|
|
45064
46160
|
}
|
|
45065
46161
|
|
|
45066
46162
|
// src/connectors/adapters/redis.ts
|
|
45067
|
-
import { isIP as
|
|
46163
|
+
import { isIP as isIP5 } from "net";
|
|
45068
46164
|
import {
|
|
45069
46165
|
createClient as createRedisClient
|
|
45070
46166
|
} from "redis";
|
|
@@ -45073,7 +46169,7 @@ var MAX_PATTERN_BYTES = 4096;
|
|
|
45073
46169
|
var MAX_VALUE_BYTES = 1024 * 1024;
|
|
45074
46170
|
var MAX_SCAN_KEYS = 1e3;
|
|
45075
46171
|
var MAX_SCAN_BYTES = 1024 * 1024;
|
|
45076
|
-
var
|
|
46172
|
+
var MAX_TLS_CA_BYTES2 = 256 * 1024;
|
|
45077
46173
|
var MAX_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
45078
46174
|
var SCAN_SCRIPT = `
|
|
45079
46175
|
local page
|
|
@@ -45123,7 +46219,7 @@ if redis.call('GET', KEYS[1]) ~= ARGV[1] then return 0 end
|
|
|
45123
46219
|
return redis.call('DEL', KEYS[1])
|
|
45124
46220
|
`;
|
|
45125
46221
|
function createRedisConnector(options = {}) {
|
|
45126
|
-
const createClient = options.createClient ??
|
|
46222
|
+
const createClient = options.createClient ?? defaultCreateClient2;
|
|
45127
46223
|
const resolveHost = options.resolveHost ?? resolvePublicHostAddresses;
|
|
45128
46224
|
return {
|
|
45129
46225
|
manifest: {
|
|
@@ -45138,7 +46234,7 @@ function createRedisConnector(options = {}) {
|
|
|
45138
46234
|
category: "database",
|
|
45139
46235
|
rateLimit: { requests: 120, windowMs: 6e4, scope: "data-source" },
|
|
45140
46236
|
capabilities: [
|
|
45141
|
-
|
|
46237
|
+
readCapability8("redis.keys.scan", "Read one bounded SCAN page without blocking the server with KEYS.", {
|
|
45142
46238
|
type: "object",
|
|
45143
46239
|
properties: {
|
|
45144
46240
|
cursor: { type: "string", pattern: "^[0-9]+$", default: "0" },
|
|
@@ -45148,8 +46244,8 @@ function createRedisConnector(options = {}) {
|
|
|
45148
46244
|
},
|
|
45149
46245
|
additionalProperties: false
|
|
45150
46246
|
}),
|
|
45151
|
-
|
|
45152
|
-
|
|
46247
|
+
readCapability8("redis.key.inspect", "Read a key type and remaining expiry atomically.", keySchema()),
|
|
46248
|
+
readCapability8("redis.string.get", "Read one bounded string value, type, and remaining expiry atomically.", keySchema()),
|
|
45153
46249
|
mutationCapability7("redis.string.set", "Set a bounded string only when the key is absent, present, or matches an expected value.", {
|
|
45154
46250
|
type: "object",
|
|
45155
46251
|
properties: {
|
|
@@ -45176,22 +46272,22 @@ function createRedisConnector(options = {}) {
|
|
|
45176
46272
|
},
|
|
45177
46273
|
async test(source) {
|
|
45178
46274
|
try {
|
|
45179
|
-
await
|
|
46275
|
+
await withClient2(source, createClient, resolveHost, async (client) => {
|
|
45180
46276
|
const response = await client.ping();
|
|
45181
46277
|
if (response !== "PONG") throw new Error("Redis PING returned an unexpected response");
|
|
45182
46278
|
});
|
|
45183
46279
|
return { ok: true };
|
|
45184
46280
|
} catch (error) {
|
|
45185
|
-
return { ok: false, reason:
|
|
46281
|
+
return { ok: false, reason: safeErrorMessage3(error, credentialSecrets3(source)) };
|
|
45186
46282
|
}
|
|
45187
46283
|
},
|
|
45188
46284
|
async executeRead({ source, capabilityName, args }) {
|
|
45189
46285
|
if (capabilityName === "redis.keys.scan") {
|
|
45190
|
-
const cursor =
|
|
46286
|
+
const cursor = readCursor2(args.cursor);
|
|
45191
46287
|
const match = readPattern(args.match);
|
|
45192
46288
|
const count = readBoundedInteger(args.count, 100, 1, MAX_SCAN_KEYS, "count");
|
|
45193
46289
|
const type = readScanType(args.type);
|
|
45194
|
-
const data4 = await
|
|
46290
|
+
const data4 = await withClient2(source, createClient, resolveHost, async (client) => {
|
|
45195
46291
|
const reply = readArrayReply(await client.eval(SCAN_SCRIPT, {
|
|
45196
46292
|
keys: [],
|
|
45197
46293
|
arguments: [
|
|
@@ -45206,13 +46302,13 @@ function createRedisConnector(options = {}) {
|
|
|
45206
46302
|
}), "scan");
|
|
45207
46303
|
const keys = readStringArray(reply[1], "scan keys");
|
|
45208
46304
|
assertScanPage(keys);
|
|
45209
|
-
return { cursor:
|
|
46305
|
+
return { cursor: readCursor2(readReplyString(reply[0], "cursor")), keys };
|
|
45210
46306
|
});
|
|
45211
46307
|
return { data: data4, fetchedAt: Date.now() };
|
|
45212
46308
|
}
|
|
45213
46309
|
if (capabilityName === "redis.key.inspect") {
|
|
45214
46310
|
const key = readKey(args.key);
|
|
45215
|
-
const data4 = await
|
|
46311
|
+
const data4 = await withClient2(source, createClient, resolveHost, async (client) => {
|
|
45216
46312
|
const reply = readArrayReply(await client.eval(INSPECT_SCRIPT, { keys: [key], arguments: [] }), "inspect");
|
|
45217
46313
|
const type = readReplyString(reply[0], "type");
|
|
45218
46314
|
return { key, exists: type !== "none", type, ttlMs: normalizeTtl(reply[1]) };
|
|
@@ -45221,7 +46317,7 @@ function createRedisConnector(options = {}) {
|
|
|
45221
46317
|
}
|
|
45222
46318
|
if (capabilityName === "redis.string.get") {
|
|
45223
46319
|
const key = readKey(args.key);
|
|
45224
|
-
const data4 = await
|
|
46320
|
+
const data4 = await withClient2(source, createClient, resolveHost, async (client) => {
|
|
45225
46321
|
const reply = readArrayReply(await client.eval(READ_STRING_SCRIPT, {
|
|
45226
46322
|
keys: [key],
|
|
45227
46323
|
arguments: [String(MAX_VALUE_BYTES)]
|
|
@@ -45248,7 +46344,7 @@ function createRedisConnector(options = {}) {
|
|
|
45248
46344
|
async executeMutation({ source, capabilityName, args }) {
|
|
45249
46345
|
if (capabilityName === "redis.string.set") {
|
|
45250
46346
|
const input = readSetInput(args);
|
|
45251
|
-
return
|
|
46347
|
+
return withClient2(source, createClient, resolveHost, async (client) => {
|
|
45252
46348
|
let committed;
|
|
45253
46349
|
if (input.condition === "matches") {
|
|
45254
46350
|
committed = readReplyInteger(await client.eval(COMPARE_SET_SCRIPT, {
|
|
@@ -45269,7 +46365,7 @@ function createRedisConnector(options = {}) {
|
|
|
45269
46365
|
if (capabilityName === "redis.string.delete") {
|
|
45270
46366
|
const key = readKey(args.key);
|
|
45271
46367
|
const expectedValue = readValue(args.expectedValue, "expectedValue");
|
|
45272
|
-
return
|
|
46368
|
+
return withClient2(source, createClient, resolveHost, async (client) => {
|
|
45273
46369
|
const deleted = readReplyInteger(await client.eval(COMPARE_DELETE_SCRIPT, {
|
|
45274
46370
|
keys: [key],
|
|
45275
46371
|
arguments: [expectedValue]
|
|
@@ -45283,11 +46379,11 @@ function createRedisConnector(options = {}) {
|
|
|
45283
46379
|
};
|
|
45284
46380
|
}
|
|
45285
46381
|
var redisConnector = createRedisConnector();
|
|
45286
|
-
function
|
|
46382
|
+
function defaultCreateClient2(options) {
|
|
45287
46383
|
return createRedisClient(options);
|
|
45288
46384
|
}
|
|
45289
|
-
async function
|
|
45290
|
-
const credentials =
|
|
46385
|
+
async function withClient2(source, createClient, resolveHost, run) {
|
|
46386
|
+
const credentials = readCredentials4(source);
|
|
45291
46387
|
const addresses = await resolveHost(credentials.host);
|
|
45292
46388
|
if (addresses.length === 0) throw new Error("Redis host did not resolve");
|
|
45293
46389
|
let client;
|
|
@@ -45305,7 +46401,7 @@ async function withClient(source, createClient, resolveHost, run) {
|
|
|
45305
46401
|
host: addresses[0],
|
|
45306
46402
|
port: credentials.port,
|
|
45307
46403
|
tls: true,
|
|
45308
|
-
servername:
|
|
46404
|
+
servername: isIP5(credentials.host) === 0 ? credentials.host : void 0,
|
|
45309
46405
|
minVersion: "TLSv1.2",
|
|
45310
46406
|
rejectUnauthorized: true,
|
|
45311
46407
|
ca: credentials.tlsCa,
|
|
@@ -45318,13 +46414,13 @@ async function withClient(source, createClient, resolveHost, run) {
|
|
|
45318
46414
|
await client.connect();
|
|
45319
46415
|
return await run(client);
|
|
45320
46416
|
} catch (error) {
|
|
45321
|
-
throw new Error(
|
|
46417
|
+
throw new Error(safeErrorMessage3(error, credentials.secrets));
|
|
45322
46418
|
} finally {
|
|
45323
46419
|
if (client?.isOpen) await client.close().catch(() => client?.destroy());
|
|
45324
46420
|
else client?.destroy();
|
|
45325
46421
|
}
|
|
45326
46422
|
}
|
|
45327
|
-
function
|
|
46423
|
+
function readCredentials4(source) {
|
|
45328
46424
|
let raw;
|
|
45329
46425
|
if (source.credentials.kind === "custom") raw = source.credentials.values;
|
|
45330
46426
|
else if (source.credentials.kind === "api-key") {
|
|
@@ -45337,15 +46433,15 @@ function readCredentials3(source) {
|
|
|
45337
46433
|
throw new Error("Redis requires a structured credential bundle");
|
|
45338
46434
|
}
|
|
45339
46435
|
if (!isPlainRecord(raw)) throw new Error("Redis credential must be a JSON object");
|
|
45340
|
-
const host =
|
|
46436
|
+
const host = readHost3(raw.host);
|
|
45341
46437
|
const username = readOptionalString(raw.username, "username");
|
|
45342
46438
|
if (username && (username.length > 128 || /[\u0000-\u001f\u007f]/.test(username))) {
|
|
45343
46439
|
throw new Error("Redis username must be at most 128 characters without control characters");
|
|
45344
46440
|
}
|
|
45345
46441
|
const password = readRequiredString2(raw.password, "password", 4096);
|
|
45346
46442
|
const tlsCa = readOptionalString(raw.tlsCa, "tlsCa");
|
|
45347
|
-
if (tlsCa && Buffer.byteLength(tlsCa, "utf8") >
|
|
45348
|
-
throw new Error(`Redis tlsCa exceeds the ${
|
|
46443
|
+
if (tlsCa && Buffer.byteLength(tlsCa, "utf8") > MAX_TLS_CA_BYTES2) {
|
|
46444
|
+
throw new Error(`Redis tlsCa exceeds the ${MAX_TLS_CA_BYTES2}-byte limit`);
|
|
45349
46445
|
}
|
|
45350
46446
|
return {
|
|
45351
46447
|
host,
|
|
@@ -45359,9 +46455,9 @@ function readCredentials3(source) {
|
|
|
45359
46455
|
secrets: [password]
|
|
45360
46456
|
};
|
|
45361
46457
|
}
|
|
45362
|
-
function
|
|
46458
|
+
function readHost3(value) {
|
|
45363
46459
|
const host = readRequiredString2(value, "host", 253);
|
|
45364
|
-
const ipVersion =
|
|
46460
|
+
const ipVersion = isIP5(host);
|
|
45365
46461
|
if (ipVersion !== 0) {
|
|
45366
46462
|
if (!isPublicNetworkAddress(host)) throw new Error("Redis host is not a public network target");
|
|
45367
46463
|
return host;
|
|
@@ -45387,7 +46483,7 @@ function readSetInput(args) {
|
|
|
45387
46483
|
if (ttlMs !== void 0 && keepTtl) throw new Error("ttlMs and keepTtl cannot be used together");
|
|
45388
46484
|
return { key, value, condition, expectedValue, ttlMs, keepTtl };
|
|
45389
46485
|
}
|
|
45390
|
-
function
|
|
46486
|
+
function readCursor2(value) {
|
|
45391
46487
|
if (value === void 0 || value === null || value === "") return "0";
|
|
45392
46488
|
if (typeof value !== "string" || !/^[0-9]+$/.test(value) || value.length > 32) {
|
|
45393
46489
|
throw new Error("cursor must be a Redis numeric cursor string");
|
|
@@ -45460,16 +46556,16 @@ function normalizeTtl(value) {
|
|
|
45460
46556
|
const ttl = readReplyInteger(value, "ttlMs");
|
|
45461
46557
|
return ttl >= 0 ? ttl : null;
|
|
45462
46558
|
}
|
|
45463
|
-
function
|
|
46559
|
+
function safeErrorMessage3(error, secrets) {
|
|
45464
46560
|
let message = error instanceof Error ? error.message : String(error);
|
|
45465
46561
|
for (const secret of secrets) {
|
|
45466
46562
|
if (secret.length >= 4) message = message.replaceAll(secret, "[REDACTED]");
|
|
45467
46563
|
}
|
|
45468
46564
|
return message;
|
|
45469
46565
|
}
|
|
45470
|
-
function
|
|
46566
|
+
function credentialSecrets3(source) {
|
|
45471
46567
|
try {
|
|
45472
|
-
return
|
|
46568
|
+
return readCredentials4(source).secrets;
|
|
45473
46569
|
} catch {
|
|
45474
46570
|
return [];
|
|
45475
46571
|
}
|
|
@@ -45480,7 +46576,7 @@ function committedResult(data4) {
|
|
|
45480
46576
|
function conflict(message) {
|
|
45481
46577
|
return { status: "conflict", alternatives: [], currentState: null, message };
|
|
45482
46578
|
}
|
|
45483
|
-
function
|
|
46579
|
+
function readCapability8(name, description, parameters) {
|
|
45484
46580
|
return { name, class: "read", description, parameters };
|
|
45485
46581
|
}
|
|
45486
46582
|
function mutationCapability7(name, description, parameters) {
|
|
@@ -45498,6 +46594,390 @@ function keySchema() {
|
|
|
45498
46594
|
};
|
|
45499
46595
|
}
|
|
45500
46596
|
|
|
46597
|
+
// src/connectors/adapters/redshift.ts
|
|
46598
|
+
import { isIP as isIP6 } from "net";
|
|
46599
|
+
import {
|
|
46600
|
+
Client as PgClient
|
|
46601
|
+
} from "pg";
|
|
46602
|
+
var MAX_IDENTIFIER_BYTES = 127;
|
|
46603
|
+
var MAX_COLUMNS5 = 64;
|
|
46604
|
+
var MAX_FILTERS2 = 20;
|
|
46605
|
+
var MAX_ORDER_COLUMNS = 8;
|
|
46606
|
+
var MAX_PARAMETERS_BYTES = 10 * 1024 * 1024;
|
|
46607
|
+
var MAX_RESULT_ROWS = 1e4;
|
|
46608
|
+
var MAX_RESULT_BYTES3 = 10 * 1024 * 1024;
|
|
46609
|
+
var MAX_TLS_CA_BYTES3 = 256 * 1024;
|
|
46610
|
+
var REDSHIFT_PROVIDER = {
|
|
46611
|
+
kind: "redshift",
|
|
46612
|
+
displayName: "Amazon Redshift",
|
|
46613
|
+
description: "Inspect Redshift schemas and tables and run bounded structured row reads over the verified PostgreSQL wire protocol.",
|
|
46614
|
+
authHint: "JSON with a public Redshift host, database, user, password, optional port, and optional TLS CA. Verified TLS is mandatory.",
|
|
46615
|
+
defaultPort: 5439
|
|
46616
|
+
};
|
|
46617
|
+
function createRedshiftConnector(options = {}) {
|
|
46618
|
+
return createPostgresWireReadConnector(REDSHIFT_PROVIDER, options);
|
|
46619
|
+
}
|
|
46620
|
+
function createPostgresWireReadConnector(provider2, options = {}) {
|
|
46621
|
+
const createClient = options.createClient ?? defaultCreateClient3;
|
|
46622
|
+
const resolveHost = options.resolveHost ?? resolvePublicHostAddresses;
|
|
46623
|
+
return {
|
|
46624
|
+
manifest: {
|
|
46625
|
+
kind: provider2.kind,
|
|
46626
|
+
displayName: provider2.displayName,
|
|
46627
|
+
description: provider2.description,
|
|
46628
|
+
auth: {
|
|
46629
|
+
kind: "api-key",
|
|
46630
|
+
hint: provider2.authHint
|
|
46631
|
+
},
|
|
46632
|
+
defaultConsistencyModel: "authoritative",
|
|
46633
|
+
category: "database",
|
|
46634
|
+
rateLimit: { requests: 120, windowMs: 6e4, scope: "data-source" },
|
|
46635
|
+
capabilities: [
|
|
46636
|
+
readCapability9(`${provider2.kind}.schemas.list`, `List schemas visible to the connected ${provider2.displayName} user.`, emptySchema2()),
|
|
46637
|
+
readCapability9(`${provider2.kind}.tables.list`, "List tables and views in one schema.", {
|
|
46638
|
+
type: "object",
|
|
46639
|
+
properties: { schema: identifierSchema("Schema name; defaults to public.") },
|
|
46640
|
+
additionalProperties: false
|
|
46641
|
+
}),
|
|
46642
|
+
readCapability9(`${provider2.kind}.tables.describe`, "Read ordered column metadata for one table or view.", {
|
|
46643
|
+
type: "object",
|
|
46644
|
+
properties: {
|
|
46645
|
+
schema: identifierSchema("Schema name; defaults to public."),
|
|
46646
|
+
table: identifierSchema("Table or view name.")
|
|
46647
|
+
},
|
|
46648
|
+
required: ["table"],
|
|
46649
|
+
additionalProperties: false
|
|
46650
|
+
}),
|
|
46651
|
+
readCapability9(`${provider2.kind}.rows.select`, "Read bounded rows using an identifier-safe query builder with scalar predicates.", {
|
|
46652
|
+
type: "object",
|
|
46653
|
+
properties: {
|
|
46654
|
+
schema: identifierSchema("Schema name; defaults to public."),
|
|
46655
|
+
table: identifierSchema("Table or view name."),
|
|
46656
|
+
columns: {
|
|
46657
|
+
type: "array",
|
|
46658
|
+
minItems: 1,
|
|
46659
|
+
maxItems: MAX_COLUMNS5,
|
|
46660
|
+
uniqueItems: true,
|
|
46661
|
+
items: identifierSchema("Column name.")
|
|
46662
|
+
},
|
|
46663
|
+
filters: {
|
|
46664
|
+
type: "array",
|
|
46665
|
+
maxItems: MAX_FILTERS2,
|
|
46666
|
+
items: {
|
|
46667
|
+
type: "object",
|
|
46668
|
+
properties: {
|
|
46669
|
+
column: identifierSchema("Column name."),
|
|
46670
|
+
operator: { type: "string", enum: ["eq", "ne", "lt", "lte", "gt", "gte", "like", "is-null", "not-null"] },
|
|
46671
|
+
value: { type: ["string", "number", "boolean", "null"] }
|
|
46672
|
+
},
|
|
46673
|
+
required: ["column", "operator"],
|
|
46674
|
+
additionalProperties: false
|
|
46675
|
+
}
|
|
46676
|
+
},
|
|
46677
|
+
orderBy: {
|
|
46678
|
+
type: "array",
|
|
46679
|
+
maxItems: MAX_ORDER_COLUMNS,
|
|
46680
|
+
items: {
|
|
46681
|
+
type: "object",
|
|
46682
|
+
properties: {
|
|
46683
|
+
column: identifierSchema("Column name."),
|
|
46684
|
+
direction: { type: "string", enum: ["asc", "desc"], default: "asc" }
|
|
46685
|
+
},
|
|
46686
|
+
required: ["column"],
|
|
46687
|
+
additionalProperties: false
|
|
46688
|
+
}
|
|
46689
|
+
},
|
|
46690
|
+
limit: { type: "integer", minimum: 1, maximum: MAX_RESULT_ROWS, default: 100 },
|
|
46691
|
+
offset: { type: "integer", minimum: 0, maximum: 1e6, default: 0 }
|
|
46692
|
+
},
|
|
46693
|
+
required: ["table", "columns"],
|
|
46694
|
+
additionalProperties: false
|
|
46695
|
+
})
|
|
46696
|
+
]
|
|
46697
|
+
},
|
|
46698
|
+
async test(source) {
|
|
46699
|
+
try {
|
|
46700
|
+
await withClient3(source, provider2, createClient, resolveHost, async (client) => {
|
|
46701
|
+
await client.query({ text: "SELECT current_database() AS database_name, current_user AS user_name", values: [] });
|
|
46702
|
+
});
|
|
46703
|
+
return { ok: true };
|
|
46704
|
+
} catch (error) {
|
|
46705
|
+
return { ok: false, reason: safeErrorMessage4(error, credentialSecrets4(source, provider2)) };
|
|
46706
|
+
}
|
|
46707
|
+
},
|
|
46708
|
+
async executeRead(inv) {
|
|
46709
|
+
const query2 = buildQuery(inv, provider2);
|
|
46710
|
+
const data4 = await withClient3(inv.source, provider2, createClient, resolveHost, async (client) => {
|
|
46711
|
+
await client.query({ text: "BEGIN READ ONLY", values: [] });
|
|
46712
|
+
try {
|
|
46713
|
+
const result = await client.query(query2);
|
|
46714
|
+
return boundedResult2(result, provider2.displayName);
|
|
46715
|
+
} finally {
|
|
46716
|
+
await client.query({ text: "ROLLBACK", values: [] }).catch(() => void 0);
|
|
46717
|
+
}
|
|
46718
|
+
});
|
|
46719
|
+
return { data: data4, fetchedAt: Date.now() };
|
|
46720
|
+
}
|
|
46721
|
+
};
|
|
46722
|
+
}
|
|
46723
|
+
var redshiftConnector = createRedshiftConnector();
|
|
46724
|
+
function defaultCreateClient3(config) {
|
|
46725
|
+
return new PgClient(config);
|
|
46726
|
+
}
|
|
46727
|
+
async function withClient3(source, provider2, createClient, resolveHost, run) {
|
|
46728
|
+
const credentials = readCredentials5(source, provider2);
|
|
46729
|
+
const addresses = await resolveHost(credentials.host);
|
|
46730
|
+
if (addresses.length === 0) throw new Error(`${provider2.displayName} host did not resolve`);
|
|
46731
|
+
let client;
|
|
46732
|
+
try {
|
|
46733
|
+
client = createClient({
|
|
46734
|
+
host: addresses[0],
|
|
46735
|
+
port: credentials.port,
|
|
46736
|
+
user: credentials.user,
|
|
46737
|
+
password: credentials.password,
|
|
46738
|
+
database: credentials.database,
|
|
46739
|
+
application_name: "tangle-integration-hub",
|
|
46740
|
+
connectionTimeoutMillis: credentials.connectTimeoutMs,
|
|
46741
|
+
query_timeout: credentials.queryTimeoutMs,
|
|
46742
|
+
statement_timeout: credentials.queryTimeoutMs,
|
|
46743
|
+
lock_timeout: credentials.queryTimeoutMs,
|
|
46744
|
+
keepAlive: true,
|
|
46745
|
+
keepAliveInitialDelayMillis: 6e4,
|
|
46746
|
+
ssl: {
|
|
46747
|
+
servername: isIP6(credentials.host) === 0 ? credentials.host : void 0,
|
|
46748
|
+
minVersion: "TLSv1.2",
|
|
46749
|
+
rejectUnauthorized: true,
|
|
46750
|
+
ca: credentials.tlsCa
|
|
46751
|
+
}
|
|
46752
|
+
});
|
|
46753
|
+
client.on("error", () => void 0);
|
|
46754
|
+
await client.connect();
|
|
46755
|
+
return await run(client);
|
|
46756
|
+
} catch (error) {
|
|
46757
|
+
throw new Error(safeErrorMessage4(error, credentials.secrets));
|
|
46758
|
+
} finally {
|
|
46759
|
+
await client?.end().catch(() => void 0);
|
|
46760
|
+
}
|
|
46761
|
+
}
|
|
46762
|
+
function readCredentials5(source, provider2) {
|
|
46763
|
+
let raw;
|
|
46764
|
+
if (source.credentials.kind === "custom") raw = source.credentials.values;
|
|
46765
|
+
else if (source.credentials.kind === "api-key") {
|
|
46766
|
+
try {
|
|
46767
|
+
raw = JSON.parse(source.credentials.apiKey);
|
|
46768
|
+
} catch {
|
|
46769
|
+
throw new Error(`${provider2.displayName} credential must be valid JSON`);
|
|
46770
|
+
}
|
|
46771
|
+
} else {
|
|
46772
|
+
throw new Error(`${provider2.displayName} requires a structured credential bundle`);
|
|
46773
|
+
}
|
|
46774
|
+
if (!isPlainRecord(raw)) throw new Error(`${provider2.displayName} credential must be a JSON object`);
|
|
46775
|
+
const host = readHost4(raw.host, provider2.displayName);
|
|
46776
|
+
const user = readCredentialString2(raw.user ?? raw.username, "user", 128, provider2.displayName);
|
|
46777
|
+
const password = readCredentialString2(raw.password, "password", 4096, provider2.displayName);
|
|
46778
|
+
const database = readCredentialString2(raw.database, "database", MAX_IDENTIFIER_BYTES, provider2.displayName);
|
|
46779
|
+
const tlsCa = readOptionalString(raw.tlsCa, "tlsCa");
|
|
46780
|
+
if (tlsCa && Buffer.byteLength(tlsCa, "utf8") > MAX_TLS_CA_BYTES3) {
|
|
46781
|
+
throw new Error(`${provider2.displayName} tlsCa exceeds the ${MAX_TLS_CA_BYTES3}-byte limit`);
|
|
46782
|
+
}
|
|
46783
|
+
return {
|
|
46784
|
+
host,
|
|
46785
|
+
port: readBoundedInteger(raw.port, provider2.defaultPort, 1, 65535, "port"),
|
|
46786
|
+
user,
|
|
46787
|
+
password,
|
|
46788
|
+
database,
|
|
46789
|
+
tlsCa,
|
|
46790
|
+
connectTimeoutMs: readBoundedInteger(raw.connectTimeoutMs, 1e4, 1e3, 3e4, "connectTimeoutMs"),
|
|
46791
|
+
queryTimeoutMs: readBoundedInteger(raw.queryTimeoutMs, 3e4, 1e3, 6e4, "queryTimeoutMs"),
|
|
46792
|
+
secrets: [password]
|
|
46793
|
+
};
|
|
46794
|
+
}
|
|
46795
|
+
function buildQuery(inv, provider2) {
|
|
46796
|
+
if (inv.capabilityName === `${provider2.kind}.schemas.list`) {
|
|
46797
|
+
return {
|
|
46798
|
+
text: `SELECT schema_name AS "schemaName", schema_owner AS "schemaOwner" FROM information_schema.schemata WHERE schema_name NOT LIKE 'pg_%' AND schema_name <> 'information_schema' ORDER BY schema_name LIMIT ${MAX_RESULT_ROWS + 1}`,
|
|
46799
|
+
values: []
|
|
46800
|
+
};
|
|
46801
|
+
}
|
|
46802
|
+
if (inv.capabilityName === `${provider2.kind}.tables.list`) {
|
|
46803
|
+
return {
|
|
46804
|
+
text: `SELECT table_schema AS "schemaName", table_name AS "tableName", table_type AS "tableType" FROM information_schema.tables WHERE table_schema = $1 ORDER BY table_name LIMIT ${MAX_RESULT_ROWS + 1}`,
|
|
46805
|
+
values: [readSchema(inv.args.schema)]
|
|
46806
|
+
};
|
|
46807
|
+
}
|
|
46808
|
+
if (inv.capabilityName === `${provider2.kind}.tables.describe`) {
|
|
46809
|
+
return {
|
|
46810
|
+
text: `SELECT table_schema AS "schemaName", table_name AS "tableName", column_name AS "columnName", ordinal_position AS "ordinalPosition", column_default AS "columnDefault", is_nullable AS "isNullable", data_type AS "dataType", character_maximum_length AS "characterMaximumLength", numeric_precision AS "numericPrecision", numeric_scale AS "numericScale" FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 ORDER BY ordinal_position LIMIT ${MAX_RESULT_ROWS + 1}`,
|
|
46811
|
+
values: [readSchema(inv.args.schema), readIdentifier(inv.args.table, "table")]
|
|
46812
|
+
};
|
|
46813
|
+
}
|
|
46814
|
+
if (inv.capabilityName === `${provider2.kind}.rows.select`) return buildRowSelect(inv.args, provider2.displayName);
|
|
46815
|
+
throw new Error(`Unknown ${provider2.displayName} read capability: ${inv.capabilityName}`);
|
|
46816
|
+
}
|
|
46817
|
+
function buildRowSelect(args, providerLabel) {
|
|
46818
|
+
const schema = readSchema(args.schema);
|
|
46819
|
+
const table = readIdentifier(args.table, "table");
|
|
46820
|
+
const columns = readIdentifierArray(args.columns, "columns", MAX_COLUMNS5, true);
|
|
46821
|
+
const filters = readFilters2(args.filters);
|
|
46822
|
+
const orderBy = readOrderBy(args.orderBy);
|
|
46823
|
+
const limit = readBoundedInteger(args.limit, 100, 1, MAX_RESULT_ROWS, "limit");
|
|
46824
|
+
const offset = readBoundedInteger(args.offset, 0, 0, 1e6, "offset");
|
|
46825
|
+
const values = [];
|
|
46826
|
+
const predicates = filters.map((filter) => {
|
|
46827
|
+
const column = quoteIdentifier2(filter.column);
|
|
46828
|
+
if (filter.operator === "is-null") return `${column} IS NULL`;
|
|
46829
|
+
if (filter.operator === "not-null") return `${column} IS NOT NULL`;
|
|
46830
|
+
values.push(filter.value);
|
|
46831
|
+
return `${column} ${sqlOperator(filter.operator)} $${values.length}`;
|
|
46832
|
+
});
|
|
46833
|
+
assertParameterBytes(values, providerLabel);
|
|
46834
|
+
const where = predicates.length > 0 ? ` WHERE ${predicates.join(" AND ")}` : "";
|
|
46835
|
+
const order = orderBy.length > 0 ? ` ORDER BY ${orderBy.map((entry) => `${quoteIdentifier2(entry.column)} ${entry.direction.toUpperCase()}`).join(", ")}` : "";
|
|
46836
|
+
return {
|
|
46837
|
+
text: `SELECT ${columns.map(quoteIdentifier2).join(", ")} FROM ${quoteIdentifier2(schema)}.${quoteIdentifier2(table)}${where}${order} LIMIT ${limit} OFFSET ${offset}`,
|
|
46838
|
+
values
|
|
46839
|
+
};
|
|
46840
|
+
}
|
|
46841
|
+
function readFilters2(value) {
|
|
46842
|
+
if (value === void 0 || value === null) return [];
|
|
46843
|
+
if (!Array.isArray(value) || value.length > MAX_FILTERS2) throw new Error(`filters must contain at most ${MAX_FILTERS2} entries`);
|
|
46844
|
+
return value.map((entry, index) => {
|
|
46845
|
+
if (!isPlainRecord(entry)) throw new Error(`filters[${index}] must be an object`);
|
|
46846
|
+
const column = readIdentifier(entry.column, `filters[${index}].column`);
|
|
46847
|
+
const operator = entry.operator;
|
|
46848
|
+
if (!["eq", "ne", "lt", "lte", "gt", "gte", "like", "is-null", "not-null"].includes(String(operator))) {
|
|
46849
|
+
throw new Error(`filters[${index}].operator is unsupported`);
|
|
46850
|
+
}
|
|
46851
|
+
const valueRequired = !["is-null", "not-null"].includes(String(operator));
|
|
46852
|
+
if (valueRequired) assertScalar(entry.value, `filters[${index}].value`);
|
|
46853
|
+
else if (entry.value !== void 0) throw new Error(`filters[${index}].value is not valid for ${operator}`);
|
|
46854
|
+
if (valueRequired && entry.value === null) throw new Error(`filters[${index}] must use is-null or not-null for null values`);
|
|
46855
|
+
if (operator === "like" && typeof entry.value !== "string") throw new Error(`filters[${index}].value must be a string for like`);
|
|
46856
|
+
return { column, operator: String(operator), value: entry.value };
|
|
46857
|
+
});
|
|
46858
|
+
}
|
|
46859
|
+
function readOrderBy(value) {
|
|
46860
|
+
if (value === void 0 || value === null) return [];
|
|
46861
|
+
if (!Array.isArray(value) || value.length > MAX_ORDER_COLUMNS) throw new Error(`orderBy must contain at most ${MAX_ORDER_COLUMNS} entries`);
|
|
46862
|
+
return value.map((entry, index) => {
|
|
46863
|
+
if (!isPlainRecord(entry)) throw new Error(`orderBy[${index}] must be an object`);
|
|
46864
|
+
const column = readIdentifier(entry.column, `orderBy[${index}].column`);
|
|
46865
|
+
const direction = entry.direction ?? "asc";
|
|
46866
|
+
if (direction !== "asc" && direction !== "desc") throw new Error(`orderBy[${index}].direction must be asc or desc`);
|
|
46867
|
+
return { column, direction };
|
|
46868
|
+
});
|
|
46869
|
+
}
|
|
46870
|
+
function readIdentifierArray(value, label, max, required) {
|
|
46871
|
+
if (!Array.isArray(value) || required && value.length === 0 || value.length > max) {
|
|
46872
|
+
throw new Error(`${label} must contain ${required ? "1-" : "0-"}${max} identifiers`);
|
|
46873
|
+
}
|
|
46874
|
+
const identifiers = value.map((entry, index) => readIdentifier(entry, `${label}[${index}]`));
|
|
46875
|
+
if (new Set(identifiers).size !== identifiers.length) throw new Error(`${label} must not contain duplicates`);
|
|
46876
|
+
return identifiers;
|
|
46877
|
+
}
|
|
46878
|
+
function boundedResult2(result, providerLabel) {
|
|
46879
|
+
if (!Array.isArray(result.rows) || result.rows.length > MAX_RESULT_ROWS) {
|
|
46880
|
+
throw new Error(`${providerLabel} result exceeds ${MAX_RESULT_ROWS} rows`);
|
|
46881
|
+
}
|
|
46882
|
+
if (result.rowCount !== null && (!Number.isSafeInteger(result.rowCount) || result.rowCount < 0 || result.rowCount > MAX_RESULT_ROWS)) {
|
|
46883
|
+
throw new Error(`${providerLabel} result returned a malformed row count`);
|
|
46884
|
+
}
|
|
46885
|
+
const data4 = {
|
|
46886
|
+
rows: jsonSafe(result.rows),
|
|
46887
|
+
columns: result.fields.map((field) => ({
|
|
46888
|
+
name: field.name,
|
|
46889
|
+
tableId: field.tableID,
|
|
46890
|
+
columnId: field.columnID,
|
|
46891
|
+
dataTypeId: field.dataTypeID
|
|
46892
|
+
})),
|
|
46893
|
+
rowCount: result.rowCount ?? result.rows.length
|
|
46894
|
+
};
|
|
46895
|
+
const serialized = JSON.stringify(data4);
|
|
46896
|
+
if (Buffer.byteLength(serialized, "utf8") > MAX_RESULT_BYTES3) {
|
|
46897
|
+
throw new Error(`${providerLabel} result exceeds the ${MAX_RESULT_BYTES3}-byte limit`);
|
|
46898
|
+
}
|
|
46899
|
+
return data4;
|
|
46900
|
+
}
|
|
46901
|
+
function assertParameterBytes(values, providerLabel) {
|
|
46902
|
+
if (Buffer.byteLength(JSON.stringify(values), "utf8") > MAX_PARAMETERS_BYTES) {
|
|
46903
|
+
throw new Error(`${providerLabel} filter values exceed the ${MAX_PARAMETERS_BYTES}-byte limit`);
|
|
46904
|
+
}
|
|
46905
|
+
}
|
|
46906
|
+
function assertScalar(value, label) {
|
|
46907
|
+
if (value !== null && !["string", "number", "boolean"].includes(typeof value)) throw new Error(`${label} must be a JSON scalar or null`);
|
|
46908
|
+
if (typeof value === "number" && !Number.isFinite(value)) throw new Error(`${label} must be finite`);
|
|
46909
|
+
}
|
|
46910
|
+
function sqlOperator(value) {
|
|
46911
|
+
return { eq: "=", ne: "<>", lt: "<", lte: "<=", gt: ">", gte: ">=", like: "LIKE" }[value];
|
|
46912
|
+
}
|
|
46913
|
+
function readSchema(value) {
|
|
46914
|
+
return value === void 0 || value === null ? "public" : readIdentifier(value, "schema");
|
|
46915
|
+
}
|
|
46916
|
+
function readIdentifier(value, label) {
|
|
46917
|
+
if (typeof value !== "string" || value.length === 0 || Buffer.byteLength(value, "utf8") > MAX_IDENTIFIER_BYTES || !/^[A-Za-z_][A-Za-z0-9_$]*$/.test(value)) {
|
|
46918
|
+
throw new Error(`${label} must be a SQL identifier under ${MAX_IDENTIFIER_BYTES} bytes`);
|
|
46919
|
+
}
|
|
46920
|
+
return value;
|
|
46921
|
+
}
|
|
46922
|
+
function quoteIdentifier2(value) {
|
|
46923
|
+
return `"${value.replaceAll('"', '""')}"`;
|
|
46924
|
+
}
|
|
46925
|
+
function readHost4(value, providerLabel) {
|
|
46926
|
+
const host = readCredentialString2(value, "host", 253, providerLabel);
|
|
46927
|
+
const ipVersion = isIP6(host);
|
|
46928
|
+
if (ipVersion !== 0) {
|
|
46929
|
+
if (!isPublicNetworkAddress(host)) throw new Error(`${providerLabel} host is not a public network target`);
|
|
46930
|
+
return host;
|
|
46931
|
+
}
|
|
46932
|
+
const normalized = host.toLowerCase();
|
|
46933
|
+
if (normalized === "localhost" || normalized.endsWith(".localhost") || normalized.endsWith(".local") || /[\s/@:\[\]]/.test(host)) {
|
|
46934
|
+
throw new Error(`${providerLabel} host must be a public hostname or IP address without a scheme or port`);
|
|
46935
|
+
}
|
|
46936
|
+
return host;
|
|
46937
|
+
}
|
|
46938
|
+
function readCredentialString2(value, label, maxLength, providerLabel) {
|
|
46939
|
+
if (typeof value !== "string" || value.length === 0 || value.length > maxLength || label !== "password" && /[\u0000-\u001f\u007f]/.test(value)) {
|
|
46940
|
+
throw new Error(`${providerLabel} credential ${label} must be a non-empty string under ${maxLength} characters`);
|
|
46941
|
+
}
|
|
46942
|
+
return value;
|
|
46943
|
+
}
|
|
46944
|
+
function safeErrorMessage4(error, secrets) {
|
|
46945
|
+
let message = error instanceof Error ? error.message : String(error);
|
|
46946
|
+
for (const secret of secrets) {
|
|
46947
|
+
if (secret.length >= 4) message = message.replaceAll(secret, "[REDACTED]");
|
|
46948
|
+
}
|
|
46949
|
+
return message;
|
|
46950
|
+
}
|
|
46951
|
+
function credentialSecrets4(source, provider2) {
|
|
46952
|
+
try {
|
|
46953
|
+
return readCredentials5(source, provider2).secrets;
|
|
46954
|
+
} catch {
|
|
46955
|
+
return [];
|
|
46956
|
+
}
|
|
46957
|
+
}
|
|
46958
|
+
function emptySchema2() {
|
|
46959
|
+
return { type: "object", properties: {}, additionalProperties: false };
|
|
46960
|
+
}
|
|
46961
|
+
function identifierSchema(description) {
|
|
46962
|
+
return { type: "string", minLength: 1, maxLength: MAX_IDENTIFIER_BYTES, pattern: "^[A-Za-z_][A-Za-z0-9_$]*$", description };
|
|
46963
|
+
}
|
|
46964
|
+
function readCapability9(name, description, parameters) {
|
|
46965
|
+
return { name, class: "read", description, parameters };
|
|
46966
|
+
}
|
|
46967
|
+
|
|
46968
|
+
// src/connectors/adapters/postgres.ts
|
|
46969
|
+
var POSTGRES_PROVIDER = {
|
|
46970
|
+
kind: "postgres",
|
|
46971
|
+
displayName: "PostgreSQL",
|
|
46972
|
+
description: "Inspect PostgreSQL schemas and tables and run bounded structured row reads over a verified TLS connection.",
|
|
46973
|
+
authHint: "JSON with a public PostgreSQL host, database, user, password, optional port, and optional TLS CA. Verified TLS is mandatory.",
|
|
46974
|
+
defaultPort: 5432
|
|
46975
|
+
};
|
|
46976
|
+
function createPostgresConnector(options = {}) {
|
|
46977
|
+
return createPostgresWireReadConnector(POSTGRES_PROVIDER, options);
|
|
46978
|
+
}
|
|
46979
|
+
var postgresConnector = createPostgresConnector();
|
|
46980
|
+
|
|
45501
46981
|
// src/connectors/adapters/recall-ai.ts
|
|
45502
46982
|
var recallAiRegions = [
|
|
45503
46983
|
"https://us-east-1.recall.ai",
|
|
@@ -46434,7 +47914,7 @@ function createSftpConnector(options = {}) {
|
|
|
46434
47914
|
]
|
|
46435
47915
|
},
|
|
46436
47916
|
async executeRead({ source, capabilityName, args }) {
|
|
46437
|
-
const credentials =
|
|
47917
|
+
const credentials = readCredentials6(source);
|
|
46438
47918
|
if (capabilityName === "sftp.list") {
|
|
46439
47919
|
const path = resolveRemotePath(credentials.rootPath, args.path ?? "/");
|
|
46440
47920
|
const limit = readBoundedInteger(args.limit, MAX_LIST_ENTRIES, 1, MAX_LIST_ENTRIES, "limit");
|
|
@@ -46467,7 +47947,7 @@ function createSftpConnector(options = {}) {
|
|
|
46467
47947
|
throw new Error(`Unknown SFTP read capability: ${capabilityName}`);
|
|
46468
47948
|
},
|
|
46469
47949
|
async executeMutation({ source, capabilityName, args }) {
|
|
46470
|
-
const credentials =
|
|
47950
|
+
const credentials = readCredentials6(source);
|
|
46471
47951
|
const prepared = prepareMutation(capabilityName, args, credentials.rootPath);
|
|
46472
47952
|
return withSftp(credentials, createClient, lookupHost, async (client) => {
|
|
46473
47953
|
let data4;
|
|
@@ -46501,7 +47981,7 @@ function createSftpConnector(options = {}) {
|
|
|
46501
47981
|
},
|
|
46502
47982
|
async test(source) {
|
|
46503
47983
|
try {
|
|
46504
|
-
const credentials =
|
|
47984
|
+
const credentials = readCredentials6(source);
|
|
46505
47985
|
await withSftp(credentials, createClient, lookupHost, (client) => client.cwd());
|
|
46506
47986
|
return { ok: true };
|
|
46507
47987
|
} catch (error) {
|
|
@@ -46569,7 +48049,7 @@ async function withSftp(credentials, createClient, lookupHost, run) {
|
|
|
46569
48049
|
await client.end().catch(() => false);
|
|
46570
48050
|
}
|
|
46571
48051
|
}
|
|
46572
|
-
function
|
|
48052
|
+
function readCredentials6(source) {
|
|
46573
48053
|
let raw;
|
|
46574
48054
|
if (source.credentials.kind === "custom") raw = source.credentials.values;
|
|
46575
48055
|
else if (source.credentials.kind === "api-key") {
|
|
@@ -49918,7 +51398,15 @@ var squareConnector = declarativeRestConnector({
|
|
|
49918
51398
|
kind: "oauth2",
|
|
49919
51399
|
authorizationUrl: "https://connect.squareup.com/oauth2/authorize",
|
|
49920
51400
|
tokenUrl: "https://connect.squareup.com/oauth2/token",
|
|
49921
|
-
scopes: [
|
|
51401
|
+
scopes: [
|
|
51402
|
+
"CUSTOMERS_READ",
|
|
51403
|
+
"CUSTOMERS_WRITE",
|
|
51404
|
+
"PAYMENTS_READ",
|
|
51405
|
+
"PAYMENTS_WRITE",
|
|
51406
|
+
"INVOICES_READ",
|
|
51407
|
+
"INVOICES_WRITE",
|
|
51408
|
+
"ITEMS_WRITE"
|
|
51409
|
+
],
|
|
49922
51410
|
clientIdEnv: "SQUARE_OAUTH_CLIENT_ID",
|
|
49923
51411
|
clientSecretEnv: "SQUARE_OAUTH_CLIENT_SECRET"
|
|
49924
51412
|
},
|
|
@@ -56272,17 +57760,17 @@ var zohoBookingsConnector = {
|
|
|
56272
57760
|
category: "calendar",
|
|
56273
57761
|
defaultConsistencyModel: "authoritative",
|
|
56274
57762
|
capabilities: [
|
|
56275
|
-
|
|
56276
|
-
|
|
57763
|
+
readCapability10("workspaces.list", "List Zoho Bookings workspaces.", {}),
|
|
57764
|
+
readCapability10("services.list", "List services, optionally within one workspace.", {
|
|
56277
57765
|
workspace_id: { type: "string" }
|
|
56278
57766
|
}),
|
|
56279
|
-
|
|
57767
|
+
readCapability10("resources.list", "List bookable resources, optionally for one service.", {
|
|
56280
57768
|
service_id: { type: "string" }
|
|
56281
57769
|
}),
|
|
56282
|
-
|
|
57770
|
+
readCapability10("staff.list", "List staff, optionally for one service.", {
|
|
56283
57771
|
service_id: { type: "string" }
|
|
56284
57772
|
}),
|
|
56285
|
-
|
|
57773
|
+
readCapability10("appointments.list", "List appointments from a required start time.", {
|
|
56286
57774
|
from_time: {
|
|
56287
57775
|
type: "string",
|
|
56288
57776
|
description: "Zoho timestamp in dd-MMM-yyyy HH:mm:ss format."
|
|
@@ -56292,10 +57780,10 @@ var zohoBookingsConnector = {
|
|
|
56292
57780
|
staff_id: { type: "string" },
|
|
56293
57781
|
status: { type: "string" }
|
|
56294
57782
|
}, ["from_time"]),
|
|
56295
|
-
|
|
57783
|
+
readCapability10("appointments.get", "Read one appointment by booking id.", {
|
|
56296
57784
|
booking_id: { type: "string" }
|
|
56297
57785
|
}, ["booking_id"]),
|
|
56298
|
-
|
|
57786
|
+
readCapability10("availability.fetch", "Fetch open time slots for a service and date.", {
|
|
56299
57787
|
service_id: { type: "string" },
|
|
56300
57788
|
selected_date: { type: "string", description: "Date in YYYY-MM-DD format." },
|
|
56301
57789
|
staff_id: { type: "string" },
|
|
@@ -56441,7 +57929,7 @@ var zohoBookingsConnector = {
|
|
|
56441
57929
|
}
|
|
56442
57930
|
}
|
|
56443
57931
|
};
|
|
56444
|
-
function
|
|
57932
|
+
function readCapability10(name, description, properties, required = []) {
|
|
56445
57933
|
return {
|
|
56446
57934
|
name,
|
|
56447
57935
|
class: "read",
|
|
@@ -63795,14 +65283,14 @@ var metabaseConnector = declarativeRestConnector({
|
|
|
63795
65283
|
});
|
|
63796
65284
|
|
|
63797
65285
|
// src/connectors/adapters/mysql.ts
|
|
63798
|
-
import { connect as createSocket, isIP as
|
|
65286
|
+
import { connect as createSocket, isIP as isIP7 } from "net";
|
|
63799
65287
|
import {
|
|
63800
65288
|
createConnection as createMysqlConnection
|
|
63801
65289
|
} from "mysql2/promise";
|
|
63802
65290
|
var MAX_PARAMETERS = 1e3;
|
|
63803
65291
|
var MAX_PARAMETER_BYTES = 10 * 1024 * 1024;
|
|
63804
|
-
var
|
|
63805
|
-
var
|
|
65292
|
+
var MAX_RESULT_ROWS2 = 1e4;
|
|
65293
|
+
var MAX_RESULT_BYTES4 = 10 * 1024 * 1024;
|
|
63806
65294
|
var DEFAULT_QUERY_TIMEOUT_MS = 3e4;
|
|
63807
65295
|
function createMySqlConnector(options = {}) {
|
|
63808
65296
|
const createConnection = options.createConnection ?? defaultCreateConnection;
|
|
@@ -63824,7 +65312,7 @@ function createMySqlConnector(options = {}) {
|
|
|
63824
65312
|
name: "mysql.databases.list",
|
|
63825
65313
|
class: "read",
|
|
63826
65314
|
description: "List databases visible to the connected MySQL user.",
|
|
63827
|
-
parameters:
|
|
65315
|
+
parameters: emptySchema3()
|
|
63828
65316
|
},
|
|
63829
65317
|
{
|
|
63830
65318
|
name: "mysql.tables.list",
|
|
@@ -63832,7 +65320,7 @@ function createMySqlConnector(options = {}) {
|
|
|
63832
65320
|
description: "List base tables and views in one database.",
|
|
63833
65321
|
parameters: {
|
|
63834
65322
|
type: "object",
|
|
63835
|
-
properties: { database:
|
|
65323
|
+
properties: { database: identifierSchema2("Database name; defaults to the connection database.") },
|
|
63836
65324
|
additionalProperties: false
|
|
63837
65325
|
}
|
|
63838
65326
|
},
|
|
@@ -63843,8 +65331,8 @@ function createMySqlConnector(options = {}) {
|
|
|
63843
65331
|
parameters: {
|
|
63844
65332
|
type: "object",
|
|
63845
65333
|
properties: {
|
|
63846
|
-
database:
|
|
63847
|
-
table:
|
|
65334
|
+
database: identifierSchema2("Database name; defaults to the connection database."),
|
|
65335
|
+
table: identifierSchema2("Table name.")
|
|
63848
65336
|
},
|
|
63849
65337
|
required: ["table"],
|
|
63850
65338
|
additionalProperties: false
|
|
@@ -63873,7 +65361,7 @@ function createMySqlConnector(options = {}) {
|
|
|
63873
65361
|
});
|
|
63874
65362
|
return { ok: true };
|
|
63875
65363
|
} catch (error) {
|
|
63876
|
-
return { ok: false, reason:
|
|
65364
|
+
return { ok: false, reason: safeErrorMessage5(error) };
|
|
63877
65365
|
}
|
|
63878
65366
|
},
|
|
63879
65367
|
async executeRead(inv) {
|
|
@@ -63887,7 +65375,7 @@ function createMySqlConnector(options = {}) {
|
|
|
63887
65375
|
try {
|
|
63888
65376
|
const [rows, fields] = await executeStatement(connection, query2, queryTimeout(inv.source));
|
|
63889
65377
|
if (!Array.isArray(rows)) throw new Error("MySQL read returned a non-row result");
|
|
63890
|
-
return
|
|
65378
|
+
return boundedResult3(rows, fields);
|
|
63891
65379
|
} finally {
|
|
63892
65380
|
await connection.rollback().catch(() => void 0);
|
|
63893
65381
|
}
|
|
@@ -63904,7 +65392,7 @@ function createMySqlConnector(options = {}) {
|
|
|
63904
65392
|
inv.args.expectedAffectedRows,
|
|
63905
65393
|
-1,
|
|
63906
65394
|
0,
|
|
63907
|
-
|
|
65395
|
+
MAX_RESULT_ROWS2,
|
|
63908
65396
|
"expectedAffectedRows"
|
|
63909
65397
|
);
|
|
63910
65398
|
if (expectedAffectedRows < 0) throw new Error("expectedAffectedRows is required");
|
|
@@ -63937,7 +65425,7 @@ async function defaultCreateConnection(config) {
|
|
|
63937
65425
|
return createMysqlConnection(config);
|
|
63938
65426
|
}
|
|
63939
65427
|
async function withConnection(source, createConnection, resolveHost, run) {
|
|
63940
|
-
const credentials =
|
|
65428
|
+
const credentials = readCredentials7(source);
|
|
63941
65429
|
const addresses = await resolveHost(credentials.host);
|
|
63942
65430
|
if (addresses.length === 0) throw new Error("MySQL host did not resolve");
|
|
63943
65431
|
const address = addresses[0];
|
|
@@ -63973,7 +65461,7 @@ async function withConnection(source, createConnection, resolveHost, run) {
|
|
|
63973
65461
|
if (connection) await connection.end().catch(() => void 0);
|
|
63974
65462
|
}
|
|
63975
65463
|
}
|
|
63976
|
-
function
|
|
65464
|
+
function readCredentials7(source) {
|
|
63977
65465
|
let raw;
|
|
63978
65466
|
if (source.credentials.kind === "custom") raw = source.credentials.values;
|
|
63979
65467
|
else if (source.credentials.kind === "api-key") {
|
|
@@ -64023,7 +65511,7 @@ function readQuery2(inv) {
|
|
|
64023
65511
|
}
|
|
64024
65512
|
if (inv.capabilityName === "mysql.tables.describe") {
|
|
64025
65513
|
const database = readDatabase(inv.args.database, inv.source);
|
|
64026
|
-
const table =
|
|
65514
|
+
const table = readIdentifier2(inv.args.table, "table");
|
|
64027
65515
|
return {
|
|
64028
65516
|
statement: "SELECT COLUMN_NAME AS columnName, ORDINAL_POSITION AS ordinalPosition, COLUMN_DEFAULT AS columnDefault, IS_NULLABLE AS isNullable, DATA_TYPE AS dataType, COLUMN_TYPE AS columnType, COLUMN_KEY AS columnKey, EXTRA AS extra FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION",
|
|
64029
65517
|
parameters: [database, table]
|
|
@@ -64074,8 +65562,8 @@ function leadingKeyword(statement) {
|
|
|
64074
65562
|
async function executeStatement(connection, query2, timeout) {
|
|
64075
65563
|
return connection.execute({ sql: query2.statement, values: query2.parameters, timeout });
|
|
64076
65564
|
}
|
|
64077
|
-
function
|
|
64078
|
-
if (rows.length >
|
|
65565
|
+
function boundedResult3(rows, fields) {
|
|
65566
|
+
if (rows.length > MAX_RESULT_ROWS2) throw new Error(`MySQL result exceeds ${MAX_RESULT_ROWS2} rows`);
|
|
64079
65567
|
const data4 = {
|
|
64080
65568
|
rows: jsonSafe(rows),
|
|
64081
65569
|
columns: fields.map((field) => ({
|
|
@@ -64087,8 +65575,8 @@ function boundedResult(rows, fields) {
|
|
|
64087
65575
|
rowCount: rows.length
|
|
64088
65576
|
};
|
|
64089
65577
|
const serialized = JSON.stringify(data4);
|
|
64090
|
-
if (Buffer.byteLength(serialized, "utf8") >
|
|
64091
|
-
throw new Error(`MySQL result exceeds the ${
|
|
65578
|
+
if (Buffer.byteLength(serialized, "utf8") > MAX_RESULT_BYTES4) {
|
|
65579
|
+
throw new Error(`MySQL result exceeds the ${MAX_RESULT_BYTES4}-byte limit`);
|
|
64092
65580
|
}
|
|
64093
65581
|
return data4;
|
|
64094
65582
|
}
|
|
@@ -64115,14 +65603,14 @@ function committedMutation(result, affectedRows) {
|
|
|
64115
65603
|
};
|
|
64116
65604
|
}
|
|
64117
65605
|
function readDatabase(value, source) {
|
|
64118
|
-
const explicit = value === void 0 ? void 0 :
|
|
65606
|
+
const explicit = value === void 0 ? void 0 : readIdentifier2(value, "database");
|
|
64119
65607
|
if (explicit) return explicit;
|
|
64120
|
-
const credentials =
|
|
65608
|
+
const credentials = readCredentials7(source);
|
|
64121
65609
|
if (!credentials.database) throw new Error("database is required when the connection has no default database");
|
|
64122
65610
|
return credentials.database;
|
|
64123
65611
|
}
|
|
64124
65612
|
function queryTimeout(source) {
|
|
64125
|
-
return
|
|
65613
|
+
return readCredentials7(source).queryTimeoutMs;
|
|
64126
65614
|
}
|
|
64127
65615
|
function requiredString7(value, label) {
|
|
64128
65616
|
const parsed = readOptionalString(value, label);
|
|
@@ -64135,21 +65623,21 @@ function requiredCredentialString3(value, label, maxLength) {
|
|
|
64135
65623
|
if (parsed.length > maxLength) throw new Error(`MySQL credential ${label} exceeds ${maxLength} characters`);
|
|
64136
65624
|
return parsed;
|
|
64137
65625
|
}
|
|
64138
|
-
function
|
|
65626
|
+
function readIdentifier2(value, label) {
|
|
64139
65627
|
const parsed = requiredString7(value, label);
|
|
64140
65628
|
if (parsed.length > 64) throw new Error(`${label} exceeds 64 characters`);
|
|
64141
65629
|
return parsed;
|
|
64142
65630
|
}
|
|
64143
65631
|
function validateHost(host) {
|
|
64144
65632
|
const normalized = host.toLowerCase();
|
|
64145
|
-
if (host.length > 253 || host.includes("://") || /[\s/@]/.test(host) || normalized === "localhost" || normalized.endsWith(".localhost") || normalized.endsWith(".local") ||
|
|
65633
|
+
if (host.length > 253 || host.includes("://") || /[\s/@]/.test(host) || normalized === "localhost" || normalized.endsWith(".localhost") || normalized.endsWith(".local") || isIP7(host) === 0 && !/^[A-Za-z0-9.-]+$/.test(host) || host.split(".").some((label) => !label || label.startsWith("-") || label.endsWith("-"))) {
|
|
64146
65634
|
throw new Error("MySQL host must be a public hostname or IP address without a scheme");
|
|
64147
65635
|
}
|
|
64148
65636
|
}
|
|
64149
|
-
function
|
|
65637
|
+
function emptySchema3() {
|
|
64150
65638
|
return { type: "object", properties: {}, additionalProperties: false };
|
|
64151
65639
|
}
|
|
64152
|
-
function
|
|
65640
|
+
function identifierSchema2(description) {
|
|
64153
65641
|
return { type: "string", minLength: 1, maxLength: 64, description };
|
|
64154
65642
|
}
|
|
64155
65643
|
function statementSchema(mutation) {
|
|
@@ -64166,7 +65654,7 @@ function statementSchema(mutation) {
|
|
|
64166
65654
|
properties.expectedAffectedRows = {
|
|
64167
65655
|
type: "integer",
|
|
64168
65656
|
minimum: 0,
|
|
64169
|
-
maximum:
|
|
65657
|
+
maximum: MAX_RESULT_ROWS2,
|
|
64170
65658
|
description: "Commit only when MySQL reports exactly this many affected rows."
|
|
64171
65659
|
};
|
|
64172
65660
|
}
|
|
@@ -64177,7 +65665,7 @@ function statementSchema(mutation) {
|
|
|
64177
65665
|
additionalProperties: false
|
|
64178
65666
|
};
|
|
64179
65667
|
}
|
|
64180
|
-
function
|
|
65668
|
+
function safeErrorMessage5(error) {
|
|
64181
65669
|
return error instanceof Error && error.message ? error.message : "MySQL connection failed";
|
|
64182
65670
|
}
|
|
64183
65671
|
|
|
@@ -65325,6 +66813,49 @@ var hunterConnector = declarativeRestConnector({
|
|
|
65325
66813
|
]
|
|
65326
66814
|
});
|
|
65327
66815
|
|
|
66816
|
+
// src/connectors/adapters/neverbounce.ts
|
|
66817
|
+
var neverbounceConnector = declarativeRestConnector({
|
|
66818
|
+
kind: "neverbounce",
|
|
66819
|
+
displayName: "NeverBounce",
|
|
66820
|
+
description: "Verify email deliverability with the NeverBounce API.",
|
|
66821
|
+
auth: {
|
|
66822
|
+
kind: "api-key",
|
|
66823
|
+
hint: "NeverBounce API key from Apps > API in the NeverBounce dashboard."
|
|
66824
|
+
},
|
|
66825
|
+
category: "crm",
|
|
66826
|
+
defaultConsistencyModel: "authoritative",
|
|
66827
|
+
baseUrl: "https://api.neverbounce.com/v4.2",
|
|
66828
|
+
credentialPlacement: { kind: "query", parameter: "key" },
|
|
66829
|
+
test: {
|
|
66830
|
+
method: "GET",
|
|
66831
|
+
path: "/account/info"
|
|
66832
|
+
},
|
|
66833
|
+
capabilities: [
|
|
66834
|
+
{
|
|
66835
|
+
name: "verify.email.address",
|
|
66836
|
+
class: "mutation",
|
|
66837
|
+
description: "Verify one email address and return deliverability status such as valid, invalid, disposable, catch-all, or unknown.",
|
|
66838
|
+
parameters: {
|
|
66839
|
+
type: "object",
|
|
66840
|
+
properties: {
|
|
66841
|
+
email: {
|
|
66842
|
+
type: "string",
|
|
66843
|
+
description: "Email address to verify."
|
|
66844
|
+
}
|
|
66845
|
+
},
|
|
66846
|
+
required: ["email"]
|
|
66847
|
+
},
|
|
66848
|
+
request: {
|
|
66849
|
+
method: "GET",
|
|
66850
|
+
path: "/single/check",
|
|
66851
|
+
query: { email: "{email}" }
|
|
66852
|
+
},
|
|
66853
|
+
cas: "native-idempotency",
|
|
66854
|
+
externalEffect: true
|
|
66855
|
+
}
|
|
66856
|
+
]
|
|
66857
|
+
});
|
|
66858
|
+
|
|
65328
66859
|
// src/connectors/adapters/theirstack.ts
|
|
65329
66860
|
var theirstackConnector = declarativeRestConnector({
|
|
65330
66861
|
kind: "theirstack",
|
|
@@ -65738,6 +67269,9 @@ var CONNECTOR_ADAPTER_FACTORIES = [
|
|
|
65738
67269
|
defineFactoryAdapter(() => duckdbConnector, {}),
|
|
65739
67270
|
defineFactoryAdapter(() => rabbitMqConnector, {}),
|
|
65740
67271
|
defineFactoryAdapter(() => redisConnector, {}),
|
|
67272
|
+
defineFactoryAdapter(() => redshiftConnector, {}),
|
|
67273
|
+
defineFactoryAdapter(() => postgresConnector, {}),
|
|
67274
|
+
defineFactoryAdapter(() => mongodbConnector, {}),
|
|
65741
67275
|
defineFactoryAdapter(() => csvFilesConnector, {}),
|
|
65742
67276
|
defineFactoryAdapter(() => excelFilesConnector, {}),
|
|
65743
67277
|
defineFactoryAdapter(() => parquetFilesConnector, {}),
|
|
@@ -65806,6 +67340,10 @@ var CONNECTOR_ADAPTER_FACTORIES = [
|
|
|
65806
67340
|
clientId: "LINEAR_OAUTH_CLIENT_ID",
|
|
65807
67341
|
clientSecret: "LINEAR_OAUTH_CLIENT_SECRET"
|
|
65808
67342
|
}),
|
|
67343
|
+
defineFactoryAdapter(() => miroConnector, {
|
|
67344
|
+
clientId: "MIRO_OAUTH_CLIENT_ID",
|
|
67345
|
+
clientSecret: "MIRO_OAUTH_CLIENT_SECRET"
|
|
67346
|
+
}),
|
|
65809
67347
|
defineFactoryAdapter(() => mondayConnector, {
|
|
65810
67348
|
clientId: "MONDAY_OAUTH_CLIENT_ID",
|
|
65811
67349
|
clientSecret: "MONDAY_OAUTH_CLIENT_SECRET"
|
|
@@ -66032,6 +67570,7 @@ var CONNECTOR_ADAPTER_FACTORIES = [
|
|
|
66032
67570
|
defineFactoryAdapter(() => builtwithConnector, {}),
|
|
66033
67571
|
defineFactoryAdapter(() => fullenrichConnector, {}),
|
|
66034
67572
|
defineFactoryAdapter(() => hunterConnector, {}),
|
|
67573
|
+
defineFactoryAdapter(() => neverbounceConnector, {}),
|
|
66035
67574
|
defineFactoryAdapter(() => theirstackConnector, {}),
|
|
66036
67575
|
defineFactoryAdapter(() => zerobounceConnector, {})
|
|
66037
67576
|
];
|
|
@@ -72417,677 +73956,6 @@ var figjamConnector = declarativeRestConnector({
|
|
|
72417
73956
|
]
|
|
72418
73957
|
});
|
|
72419
73958
|
|
|
72420
|
-
// src/connectors/adapters/miro.ts
|
|
72421
|
-
var miroConnector = declarativeRestConnector({
|
|
72422
|
-
kind: "miro",
|
|
72423
|
-
displayName: "Miro",
|
|
72424
|
-
description: "Read and edit Miro boards: list and search boards, read board items (sticky notes, shapes, text, cards, images, frames, connectors), create and update items, and post board content back into the source of truth.",
|
|
72425
|
-
auth: {
|
|
72426
|
-
kind: "oauth2",
|
|
72427
|
-
authorizationUrl: "https://miro.com/oauth/authorize",
|
|
72428
|
-
tokenUrl: "https://api.miro.com/v1/oauth/token",
|
|
72429
|
-
scopes: [
|
|
72430
|
-
"boards:read",
|
|
72431
|
-
"boards:write",
|
|
72432
|
-
"identity:read",
|
|
72433
|
-
"team:read",
|
|
72434
|
-
"organizations:read"
|
|
72435
|
-
],
|
|
72436
|
-
clientIdEnv: "MIRO_OAUTH_CLIENT_ID",
|
|
72437
|
-
clientSecretEnv: "MIRO_OAUTH_CLIENT_SECRET"
|
|
72438
|
-
},
|
|
72439
|
-
category: "doc",
|
|
72440
|
-
defaultConsistencyModel: "authoritative",
|
|
72441
|
-
baseUrl: "https://api.miro.com",
|
|
72442
|
-
defaultHeaders: { accept: "application/json" },
|
|
72443
|
-
// GET /v2/me returns the authenticated user — Miro's documented health probe.
|
|
72444
|
-
test: { method: "GET", path: "/v2/me" },
|
|
72445
|
-
capabilities: [
|
|
72446
|
-
{
|
|
72447
|
-
name: "me.get",
|
|
72448
|
-
class: "read",
|
|
72449
|
-
description: "Return the authenticated Miro user.",
|
|
72450
|
-
parameters: { type: "object", properties: {} },
|
|
72451
|
-
request: { method: "GET", path: "/v2/me" },
|
|
72452
|
-
requiredScopes: ["identity:read"]
|
|
72453
|
-
},
|
|
72454
|
-
{
|
|
72455
|
-
name: "boards.list",
|
|
72456
|
-
class: "read",
|
|
72457
|
-
description: "List boards accessible to the authenticated user. Supports cursor pagination via `cursor` and team / sort filters.",
|
|
72458
|
-
parameters: {
|
|
72459
|
-
type: "object",
|
|
72460
|
-
properties: {
|
|
72461
|
-
team_id: { type: "string", description: "Filter to a single team id." },
|
|
72462
|
-
query: { type: "string", description: "Free-text board name filter." },
|
|
72463
|
-
owner: { type: "string", description: "Filter by owner user id." },
|
|
72464
|
-
limit: { type: "integer", minimum: 1, maximum: 50 },
|
|
72465
|
-
offset: { type: "integer", minimum: 0 },
|
|
72466
|
-
sort: {
|
|
72467
|
-
type: "string",
|
|
72468
|
-
enum: ["default", "last_modified", "last_opened", "last_created", "alphabetically"]
|
|
72469
|
-
}
|
|
72470
|
-
}
|
|
72471
|
-
},
|
|
72472
|
-
request: {
|
|
72473
|
-
method: "GET",
|
|
72474
|
-
path: "/v2/boards",
|
|
72475
|
-
query: {
|
|
72476
|
-
team_id: "{team_id}",
|
|
72477
|
-
query: "{query}",
|
|
72478
|
-
owner: "{owner}",
|
|
72479
|
-
limit: "{limit}",
|
|
72480
|
-
offset: "{offset}",
|
|
72481
|
-
sort: "{sort}"
|
|
72482
|
-
}
|
|
72483
|
-
},
|
|
72484
|
-
requiredScopes: ["boards:read"]
|
|
72485
|
-
},
|
|
72486
|
-
{
|
|
72487
|
-
name: "boards.get",
|
|
72488
|
-
class: "read",
|
|
72489
|
-
description: "Fetch a single Miro board by id.",
|
|
72490
|
-
parameters: {
|
|
72491
|
-
type: "object",
|
|
72492
|
-
properties: { board_id: { type: "string" } },
|
|
72493
|
-
required: ["board_id"]
|
|
72494
|
-
},
|
|
72495
|
-
request: { method: "GET", path: "/v2/boards/{board_id}" },
|
|
72496
|
-
requiredScopes: ["boards:read"]
|
|
72497
|
-
},
|
|
72498
|
-
{
|
|
72499
|
-
name: "boards.members.list",
|
|
72500
|
-
class: "read",
|
|
72501
|
-
description: "List members (collaborators) of a Miro board.",
|
|
72502
|
-
parameters: {
|
|
72503
|
-
type: "object",
|
|
72504
|
-
properties: {
|
|
72505
|
-
board_id: { type: "string" },
|
|
72506
|
-
limit: { type: "integer", minimum: 1, maximum: 50 },
|
|
72507
|
-
offset: { type: "integer", minimum: 0 }
|
|
72508
|
-
},
|
|
72509
|
-
required: ["board_id"]
|
|
72510
|
-
},
|
|
72511
|
-
request: {
|
|
72512
|
-
method: "GET",
|
|
72513
|
-
path: "/v2/boards/{board_id}/members",
|
|
72514
|
-
query: { limit: "{limit}", offset: "{offset}" }
|
|
72515
|
-
},
|
|
72516
|
-
requiredScopes: ["boards:read"]
|
|
72517
|
-
},
|
|
72518
|
-
{
|
|
72519
|
-
name: "items.list",
|
|
72520
|
-
class: "read",
|
|
72521
|
-
description: "List all items on a board, optionally filtered by item type (sticky_note, text, shape, card, image, frame, connector, embed, app_card, document).",
|
|
72522
|
-
parameters: {
|
|
72523
|
-
type: "object",
|
|
72524
|
-
properties: {
|
|
72525
|
-
board_id: { type: "string" },
|
|
72526
|
-
type: {
|
|
72527
|
-
type: "string",
|
|
72528
|
-
enum: [
|
|
72529
|
-
"sticky_note",
|
|
72530
|
-
"text",
|
|
72531
|
-
"shape",
|
|
72532
|
-
"card",
|
|
72533
|
-
"image",
|
|
72534
|
-
"frame",
|
|
72535
|
-
"connector",
|
|
72536
|
-
"embed",
|
|
72537
|
-
"app_card",
|
|
72538
|
-
"document",
|
|
72539
|
-
"preview"
|
|
72540
|
-
]
|
|
72541
|
-
},
|
|
72542
|
-
limit: { type: "integer", minimum: 1, maximum: 50 },
|
|
72543
|
-
cursor: { type: "string" }
|
|
72544
|
-
},
|
|
72545
|
-
required: ["board_id"]
|
|
72546
|
-
},
|
|
72547
|
-
request: {
|
|
72548
|
-
method: "GET",
|
|
72549
|
-
path: "/v2/boards/{board_id}/items",
|
|
72550
|
-
query: { type: "{type}", limit: "{limit}", cursor: "{cursor}" }
|
|
72551
|
-
},
|
|
72552
|
-
requiredScopes: ["boards:read"]
|
|
72553
|
-
},
|
|
72554
|
-
{
|
|
72555
|
-
name: "items.get",
|
|
72556
|
-
class: "read",
|
|
72557
|
-
description: "Fetch a single board item by id.",
|
|
72558
|
-
parameters: {
|
|
72559
|
-
type: "object",
|
|
72560
|
-
properties: {
|
|
72561
|
-
board_id: { type: "string" },
|
|
72562
|
-
item_id: { type: "string" }
|
|
72563
|
-
},
|
|
72564
|
-
required: ["board_id", "item_id"]
|
|
72565
|
-
},
|
|
72566
|
-
request: { method: "GET", path: "/v2/boards/{board_id}/items/{item_id}" },
|
|
72567
|
-
requiredScopes: ["boards:read"]
|
|
72568
|
-
},
|
|
72569
|
-
{
|
|
72570
|
-
name: "connectors.list",
|
|
72571
|
-
class: "read",
|
|
72572
|
-
description: "List connector lines on a board (arrows / lines between items).",
|
|
72573
|
-
parameters: {
|
|
72574
|
-
type: "object",
|
|
72575
|
-
properties: {
|
|
72576
|
-
board_id: { type: "string" },
|
|
72577
|
-
limit: { type: "integer", minimum: 1, maximum: 50 },
|
|
72578
|
-
cursor: { type: "string" }
|
|
72579
|
-
},
|
|
72580
|
-
required: ["board_id"]
|
|
72581
|
-
},
|
|
72582
|
-
request: {
|
|
72583
|
-
method: "GET",
|
|
72584
|
-
path: "/v2/boards/{board_id}/connectors",
|
|
72585
|
-
query: { limit: "{limit}", cursor: "{cursor}" }
|
|
72586
|
-
},
|
|
72587
|
-
requiredScopes: ["boards:read"]
|
|
72588
|
-
},
|
|
72589
|
-
{
|
|
72590
|
-
name: "tags.list",
|
|
72591
|
-
class: "read",
|
|
72592
|
-
description: "List tags defined on a board.",
|
|
72593
|
-
parameters: {
|
|
72594
|
-
type: "object",
|
|
72595
|
-
properties: {
|
|
72596
|
-
board_id: { type: "string" },
|
|
72597
|
-
limit: { type: "integer", minimum: 1, maximum: 50 },
|
|
72598
|
-
offset: { type: "integer", minimum: 0 }
|
|
72599
|
-
},
|
|
72600
|
-
required: ["board_id"]
|
|
72601
|
-
},
|
|
72602
|
-
request: {
|
|
72603
|
-
method: "GET",
|
|
72604
|
-
path: "/v2/boards/{board_id}/tags",
|
|
72605
|
-
query: { limit: "{limit}", offset: "{offset}" }
|
|
72606
|
-
},
|
|
72607
|
-
requiredScopes: ["boards:read"]
|
|
72608
|
-
},
|
|
72609
|
-
{
|
|
72610
|
-
name: "organizations.get",
|
|
72611
|
-
class: "read",
|
|
72612
|
-
description: "Read an organization (Enterprise plan).",
|
|
72613
|
-
parameters: {
|
|
72614
|
-
type: "object",
|
|
72615
|
-
properties: { org_id: { type: "string" } },
|
|
72616
|
-
required: ["org_id"]
|
|
72617
|
-
},
|
|
72618
|
-
request: { method: "GET", path: "/v2/orgs/{org_id}" },
|
|
72619
|
-
requiredScopes: ["organizations:read"]
|
|
72620
|
-
},
|
|
72621
|
-
{
|
|
72622
|
-
name: "organizations.teams.list",
|
|
72623
|
-
class: "read",
|
|
72624
|
-
description: "List teams in an organization (Enterprise plan).",
|
|
72625
|
-
parameters: {
|
|
72626
|
-
type: "object",
|
|
72627
|
-
properties: {
|
|
72628
|
-
org_id: { type: "string" },
|
|
72629
|
-
limit: { type: "integer", minimum: 1, maximum: 100 },
|
|
72630
|
-
cursor: { type: "string" }
|
|
72631
|
-
},
|
|
72632
|
-
required: ["org_id"]
|
|
72633
|
-
},
|
|
72634
|
-
request: {
|
|
72635
|
-
method: "GET",
|
|
72636
|
-
path: "/v2/orgs/{org_id}/teams",
|
|
72637
|
-
query: { limit: "{limit}", cursor: "{cursor}" }
|
|
72638
|
-
},
|
|
72639
|
-
requiredScopes: ["organizations:read"]
|
|
72640
|
-
},
|
|
72641
|
-
{
|
|
72642
|
-
name: "teams.get",
|
|
72643
|
-
class: "read",
|
|
72644
|
-
description: "Fetch a single team by id.",
|
|
72645
|
-
parameters: {
|
|
72646
|
-
type: "object",
|
|
72647
|
-
properties: {
|
|
72648
|
-
org_id: { type: "string" },
|
|
72649
|
-
team_id: { type: "string" }
|
|
72650
|
-
},
|
|
72651
|
-
required: ["org_id", "team_id"]
|
|
72652
|
-
},
|
|
72653
|
-
request: { method: "GET", path: "/v2/orgs/{org_id}/teams/{team_id}" },
|
|
72654
|
-
requiredScopes: ["team:read"]
|
|
72655
|
-
},
|
|
72656
|
-
{
|
|
72657
|
-
name: "boards.create",
|
|
72658
|
-
class: "mutation",
|
|
72659
|
-
description: "Create a new Miro board. Accepts an optional name, description, team_id, and sharing policy. Returns the new board id used by every items.* endpoint.",
|
|
72660
|
-
parameters: {
|
|
72661
|
-
type: "object",
|
|
72662
|
-
properties: {
|
|
72663
|
-
name: { type: "string", maxLength: 60 },
|
|
72664
|
-
description: { type: "string", maxLength: 300 },
|
|
72665
|
-
team_id: { type: "string" },
|
|
72666
|
-
policy: {
|
|
72667
|
-
type: "object",
|
|
72668
|
-
description: "Permissions + sharing policy. See https://developers.miro.com/reference/create-board for the full PolicyChange shape."
|
|
72669
|
-
}
|
|
72670
|
-
},
|
|
72671
|
-
required: ["name"]
|
|
72672
|
-
},
|
|
72673
|
-
request: {
|
|
72674
|
-
method: "POST",
|
|
72675
|
-
path: "/v2/boards",
|
|
72676
|
-
body: {
|
|
72677
|
-
name: "{name}",
|
|
72678
|
-
description: "{description}",
|
|
72679
|
-
teamId: "{team_id}",
|
|
72680
|
-
policy: "{policy}"
|
|
72681
|
-
}
|
|
72682
|
-
},
|
|
72683
|
-
cas: "native-idempotency",
|
|
72684
|
-
requiredScopes: ["boards:write"]
|
|
72685
|
-
},
|
|
72686
|
-
{
|
|
72687
|
-
name: "boards.update",
|
|
72688
|
-
class: "mutation",
|
|
72689
|
-
description: "Update a Miro board (name, description, team, or sharing policy).",
|
|
72690
|
-
parameters: {
|
|
72691
|
-
type: "object",
|
|
72692
|
-
properties: {
|
|
72693
|
-
board_id: { type: "string" },
|
|
72694
|
-
name: { type: "string", maxLength: 60 },
|
|
72695
|
-
description: { type: "string", maxLength: 300 },
|
|
72696
|
-
team_id: { type: "string" },
|
|
72697
|
-
policy: { type: "object" }
|
|
72698
|
-
},
|
|
72699
|
-
required: ["board_id"]
|
|
72700
|
-
},
|
|
72701
|
-
request: {
|
|
72702
|
-
method: "PATCH",
|
|
72703
|
-
path: "/v2/boards/{board_id}",
|
|
72704
|
-
body: {
|
|
72705
|
-
name: "{name}",
|
|
72706
|
-
description: "{description}",
|
|
72707
|
-
teamId: "{team_id}",
|
|
72708
|
-
policy: "{policy}"
|
|
72709
|
-
}
|
|
72710
|
-
},
|
|
72711
|
-
cas: "native-idempotency",
|
|
72712
|
-
requiredScopes: ["boards:write"]
|
|
72713
|
-
},
|
|
72714
|
-
{
|
|
72715
|
-
name: "boards.delete",
|
|
72716
|
-
class: "mutation",
|
|
72717
|
-
description: "Delete a Miro board (irreversible).",
|
|
72718
|
-
parameters: {
|
|
72719
|
-
type: "object",
|
|
72720
|
-
properties: { board_id: { type: "string" } },
|
|
72721
|
-
required: ["board_id"]
|
|
72722
|
-
},
|
|
72723
|
-
request: { method: "DELETE", path: "/v2/boards/{board_id}" },
|
|
72724
|
-
cas: "native-idempotency",
|
|
72725
|
-
requiredScopes: ["boards:write"]
|
|
72726
|
-
},
|
|
72727
|
-
{
|
|
72728
|
-
name: "sticky_notes.create",
|
|
72729
|
-
class: "mutation",
|
|
72730
|
-
description: "Create a sticky note on a board. `data.content` accepts plain text; `style.fillColor` is a Miro sticky-note color keyword (e.g. yellow, light_yellow, pink).",
|
|
72731
|
-
parameters: {
|
|
72732
|
-
type: "object",
|
|
72733
|
-
properties: {
|
|
72734
|
-
board_id: { type: "string" },
|
|
72735
|
-
data: {
|
|
72736
|
-
type: "object",
|
|
72737
|
-
properties: {
|
|
72738
|
-
content: { type: "string" },
|
|
72739
|
-
shape: { type: "string", enum: ["square", "rectangle"] }
|
|
72740
|
-
},
|
|
72741
|
-
required: ["content"]
|
|
72742
|
-
},
|
|
72743
|
-
style: {
|
|
72744
|
-
type: "object",
|
|
72745
|
-
properties: {
|
|
72746
|
-
fillColor: { type: "string" },
|
|
72747
|
-
textAlign: { type: "string", enum: ["left", "center", "right"] },
|
|
72748
|
-
textAlignVertical: { type: "string", enum: ["top", "middle", "bottom"] }
|
|
72749
|
-
}
|
|
72750
|
-
},
|
|
72751
|
-
position: {
|
|
72752
|
-
type: "object",
|
|
72753
|
-
properties: {
|
|
72754
|
-
x: { type: "number" },
|
|
72755
|
-
y: { type: "number" },
|
|
72756
|
-
origin: { type: "string", enum: ["center"] }
|
|
72757
|
-
}
|
|
72758
|
-
},
|
|
72759
|
-
geometry: {
|
|
72760
|
-
type: "object",
|
|
72761
|
-
properties: {
|
|
72762
|
-
width: { type: "number" },
|
|
72763
|
-
height: { type: "number" }
|
|
72764
|
-
}
|
|
72765
|
-
},
|
|
72766
|
-
parent: {
|
|
72767
|
-
type: "object",
|
|
72768
|
-
description: "Attach the sticky note to a frame: { id: <frame_item_id> }.",
|
|
72769
|
-
properties: { id: { type: "string" } }
|
|
72770
|
-
}
|
|
72771
|
-
},
|
|
72772
|
-
required: ["board_id", "data"]
|
|
72773
|
-
},
|
|
72774
|
-
request: {
|
|
72775
|
-
method: "POST",
|
|
72776
|
-
path: "/v2/boards/{board_id}/sticky_notes",
|
|
72777
|
-
body: {
|
|
72778
|
-
data: "{data}",
|
|
72779
|
-
style: "{style}",
|
|
72780
|
-
position: "{position}",
|
|
72781
|
-
geometry: "{geometry}",
|
|
72782
|
-
parent: "{parent}"
|
|
72783
|
-
}
|
|
72784
|
-
},
|
|
72785
|
-
cas: "native-idempotency",
|
|
72786
|
-
requiredScopes: ["boards:write"]
|
|
72787
|
-
},
|
|
72788
|
-
{
|
|
72789
|
-
name: "sticky_notes.update",
|
|
72790
|
-
class: "mutation",
|
|
72791
|
-
description: "Update a sticky note (content, style, position, geometry, or parent frame).",
|
|
72792
|
-
parameters: {
|
|
72793
|
-
type: "object",
|
|
72794
|
-
properties: {
|
|
72795
|
-
board_id: { type: "string" },
|
|
72796
|
-
item_id: { type: "string" },
|
|
72797
|
-
data: { type: "object" },
|
|
72798
|
-
style: { type: "object" },
|
|
72799
|
-
position: { type: "object" },
|
|
72800
|
-
geometry: { type: "object" },
|
|
72801
|
-
parent: { type: "object" }
|
|
72802
|
-
},
|
|
72803
|
-
required: ["board_id", "item_id"]
|
|
72804
|
-
},
|
|
72805
|
-
request: {
|
|
72806
|
-
method: "PATCH",
|
|
72807
|
-
path: "/v2/boards/{board_id}/sticky_notes/{item_id}",
|
|
72808
|
-
body: {
|
|
72809
|
-
data: "{data}",
|
|
72810
|
-
style: "{style}",
|
|
72811
|
-
position: "{position}",
|
|
72812
|
-
geometry: "{geometry}",
|
|
72813
|
-
parent: "{parent}"
|
|
72814
|
-
}
|
|
72815
|
-
},
|
|
72816
|
-
cas: "native-idempotency",
|
|
72817
|
-
requiredScopes: ["boards:write"]
|
|
72818
|
-
},
|
|
72819
|
-
{
|
|
72820
|
-
name: "text.create",
|
|
72821
|
-
class: "mutation",
|
|
72822
|
-
description: "Create a text item on a board.",
|
|
72823
|
-
parameters: {
|
|
72824
|
-
type: "object",
|
|
72825
|
-
properties: {
|
|
72826
|
-
board_id: { type: "string" },
|
|
72827
|
-
data: {
|
|
72828
|
-
type: "object",
|
|
72829
|
-
properties: { content: { type: "string" } },
|
|
72830
|
-
required: ["content"]
|
|
72831
|
-
},
|
|
72832
|
-
style: { type: "object" },
|
|
72833
|
-
position: { type: "object" },
|
|
72834
|
-
geometry: { type: "object" },
|
|
72835
|
-
parent: { type: "object" }
|
|
72836
|
-
},
|
|
72837
|
-
required: ["board_id", "data"]
|
|
72838
|
-
},
|
|
72839
|
-
request: {
|
|
72840
|
-
method: "POST",
|
|
72841
|
-
path: "/v2/boards/{board_id}/texts",
|
|
72842
|
-
body: {
|
|
72843
|
-
data: "{data}",
|
|
72844
|
-
style: "{style}",
|
|
72845
|
-
position: "{position}",
|
|
72846
|
-
geometry: "{geometry}",
|
|
72847
|
-
parent: "{parent}"
|
|
72848
|
-
}
|
|
72849
|
-
},
|
|
72850
|
-
cas: "native-idempotency",
|
|
72851
|
-
requiredScopes: ["boards:write"]
|
|
72852
|
-
},
|
|
72853
|
-
{
|
|
72854
|
-
name: "shapes.create",
|
|
72855
|
-
class: "mutation",
|
|
72856
|
-
description: "Create a shape item on a board. `data.shape` selects the geometric primitive (rectangle, round_rectangle, circle, triangle, rhombus, etc.).",
|
|
72857
|
-
parameters: {
|
|
72858
|
-
type: "object",
|
|
72859
|
-
properties: {
|
|
72860
|
-
board_id: { type: "string" },
|
|
72861
|
-
data: {
|
|
72862
|
-
type: "object",
|
|
72863
|
-
properties: {
|
|
72864
|
-
shape: {
|
|
72865
|
-
type: "string",
|
|
72866
|
-
description: "Miro shape kind; full enum at https://developers.miro.com/reference/create-shape-item."
|
|
72867
|
-
},
|
|
72868
|
-
content: { type: "string" }
|
|
72869
|
-
},
|
|
72870
|
-
required: ["shape"]
|
|
72871
|
-
},
|
|
72872
|
-
style: { type: "object" },
|
|
72873
|
-
position: { type: "object" },
|
|
72874
|
-
geometry: { type: "object" },
|
|
72875
|
-
parent: { type: "object" }
|
|
72876
|
-
},
|
|
72877
|
-
required: ["board_id", "data"]
|
|
72878
|
-
},
|
|
72879
|
-
request: {
|
|
72880
|
-
method: "POST",
|
|
72881
|
-
path: "/v2/boards/{board_id}/shapes",
|
|
72882
|
-
body: {
|
|
72883
|
-
data: "{data}",
|
|
72884
|
-
style: "{style}",
|
|
72885
|
-
position: "{position}",
|
|
72886
|
-
geometry: "{geometry}",
|
|
72887
|
-
parent: "{parent}"
|
|
72888
|
-
}
|
|
72889
|
-
},
|
|
72890
|
-
cas: "native-idempotency",
|
|
72891
|
-
requiredScopes: ["boards:write"]
|
|
72892
|
-
},
|
|
72893
|
-
{
|
|
72894
|
-
name: "cards.create",
|
|
72895
|
-
class: "mutation",
|
|
72896
|
-
description: "Create a card item (title + description + assignee + due-date) on a board.",
|
|
72897
|
-
parameters: {
|
|
72898
|
-
type: "object",
|
|
72899
|
-
properties: {
|
|
72900
|
-
board_id: { type: "string" },
|
|
72901
|
-
data: {
|
|
72902
|
-
type: "object",
|
|
72903
|
-
properties: {
|
|
72904
|
-
title: { type: "string" },
|
|
72905
|
-
description: { type: "string" },
|
|
72906
|
-
dueDate: { type: "string", format: "date-time" },
|
|
72907
|
-
assigneeId: { type: "string" }
|
|
72908
|
-
},
|
|
72909
|
-
required: ["title"]
|
|
72910
|
-
},
|
|
72911
|
-
style: { type: "object" },
|
|
72912
|
-
position: { type: "object" },
|
|
72913
|
-
geometry: { type: "object" },
|
|
72914
|
-
parent: { type: "object" }
|
|
72915
|
-
},
|
|
72916
|
-
required: ["board_id", "data"]
|
|
72917
|
-
},
|
|
72918
|
-
request: {
|
|
72919
|
-
method: "POST",
|
|
72920
|
-
path: "/v2/boards/{board_id}/cards",
|
|
72921
|
-
body: {
|
|
72922
|
-
data: "{data}",
|
|
72923
|
-
style: "{style}",
|
|
72924
|
-
position: "{position}",
|
|
72925
|
-
geometry: "{geometry}",
|
|
72926
|
-
parent: "{parent}"
|
|
72927
|
-
}
|
|
72928
|
-
},
|
|
72929
|
-
cas: "native-idempotency",
|
|
72930
|
-
requiredScopes: ["boards:write"]
|
|
72931
|
-
},
|
|
72932
|
-
{
|
|
72933
|
-
name: "frames.create",
|
|
72934
|
-
class: "mutation",
|
|
72935
|
-
description: "Create a frame on a board. Frames group items; child items can be attached via `parent.id` on item creation.",
|
|
72936
|
-
parameters: {
|
|
72937
|
-
type: "object",
|
|
72938
|
-
properties: {
|
|
72939
|
-
board_id: { type: "string" },
|
|
72940
|
-
data: {
|
|
72941
|
-
type: "object",
|
|
72942
|
-
properties: {
|
|
72943
|
-
title: { type: "string" },
|
|
72944
|
-
format: { type: "string", enum: ["custom"] },
|
|
72945
|
-
type: { type: "string", enum: ["freeform"] }
|
|
72946
|
-
}
|
|
72947
|
-
},
|
|
72948
|
-
style: { type: "object" },
|
|
72949
|
-
position: { type: "object" },
|
|
72950
|
-
geometry: { type: "object" }
|
|
72951
|
-
},
|
|
72952
|
-
required: ["board_id"]
|
|
72953
|
-
},
|
|
72954
|
-
request: {
|
|
72955
|
-
method: "POST",
|
|
72956
|
-
path: "/v2/boards/{board_id}/frames",
|
|
72957
|
-
body: {
|
|
72958
|
-
data: "{data}",
|
|
72959
|
-
style: "{style}",
|
|
72960
|
-
position: "{position}",
|
|
72961
|
-
geometry: "{geometry}"
|
|
72962
|
-
}
|
|
72963
|
-
},
|
|
72964
|
-
cas: "native-idempotency",
|
|
72965
|
-
requiredScopes: ["boards:write"]
|
|
72966
|
-
},
|
|
72967
|
-
{
|
|
72968
|
-
name: "images.create.by_url",
|
|
72969
|
-
class: "mutation",
|
|
72970
|
-
description: "Create an image item from a public URL (Miro fetches the image server-side).",
|
|
72971
|
-
parameters: {
|
|
72972
|
-
type: "object",
|
|
72973
|
-
properties: {
|
|
72974
|
-
board_id: { type: "string" },
|
|
72975
|
-
data: {
|
|
72976
|
-
type: "object",
|
|
72977
|
-
properties: {
|
|
72978
|
-
url: { type: "string", format: "uri" },
|
|
72979
|
-
title: { type: "string" }
|
|
72980
|
-
},
|
|
72981
|
-
required: ["url"]
|
|
72982
|
-
},
|
|
72983
|
-
position: { type: "object" },
|
|
72984
|
-
geometry: { type: "object" },
|
|
72985
|
-
parent: { type: "object" }
|
|
72986
|
-
},
|
|
72987
|
-
required: ["board_id", "data"]
|
|
72988
|
-
},
|
|
72989
|
-
request: {
|
|
72990
|
-
method: "POST",
|
|
72991
|
-
path: "/v2/boards/{board_id}/images",
|
|
72992
|
-
body: {
|
|
72993
|
-
data: "{data}",
|
|
72994
|
-
position: "{position}",
|
|
72995
|
-
geometry: "{geometry}",
|
|
72996
|
-
parent: "{parent}"
|
|
72997
|
-
}
|
|
72998
|
-
},
|
|
72999
|
-
cas: "native-idempotency",
|
|
73000
|
-
requiredScopes: ["boards:write"]
|
|
73001
|
-
},
|
|
73002
|
-
{
|
|
73003
|
-
name: "connectors.create",
|
|
73004
|
-
class: "mutation",
|
|
73005
|
-
description: "Create a connector line between two items on the board. `startItem.id` and `endItem.id` reference existing item ids.",
|
|
73006
|
-
parameters: {
|
|
73007
|
-
type: "object",
|
|
73008
|
-
properties: {
|
|
73009
|
-
board_id: { type: "string" },
|
|
73010
|
-
startItem: {
|
|
73011
|
-
type: "object",
|
|
73012
|
-
properties: { id: { type: "string" } },
|
|
73013
|
-
required: ["id"]
|
|
73014
|
-
},
|
|
73015
|
-
endItem: {
|
|
73016
|
-
type: "object",
|
|
73017
|
-
properties: { id: { type: "string" } },
|
|
73018
|
-
required: ["id"]
|
|
73019
|
-
},
|
|
73020
|
-
captions: {
|
|
73021
|
-
type: "array",
|
|
73022
|
-
items: { type: "object", properties: { content: { type: "string" } } }
|
|
73023
|
-
},
|
|
73024
|
-
style: { type: "object" },
|
|
73025
|
-
shape: { type: "string", enum: ["straight", "elbowed", "curved"] }
|
|
73026
|
-
},
|
|
73027
|
-
required: ["board_id", "startItem", "endItem"]
|
|
73028
|
-
},
|
|
73029
|
-
request: {
|
|
73030
|
-
method: "POST",
|
|
73031
|
-
path: "/v2/boards/{board_id}/connectors",
|
|
73032
|
-
body: {
|
|
73033
|
-
startItem: "{startItem}",
|
|
73034
|
-
endItem: "{endItem}",
|
|
73035
|
-
captions: "{captions}",
|
|
73036
|
-
style: "{style}",
|
|
73037
|
-
shape: "{shape}"
|
|
73038
|
-
}
|
|
73039
|
-
},
|
|
73040
|
-
cas: "native-idempotency",
|
|
73041
|
-
requiredScopes: ["boards:write"]
|
|
73042
|
-
},
|
|
73043
|
-
{
|
|
73044
|
-
name: "items.delete",
|
|
73045
|
-
class: "mutation",
|
|
73046
|
-
description: "Delete an item from a board (works across all item types).",
|
|
73047
|
-
parameters: {
|
|
73048
|
-
type: "object",
|
|
73049
|
-
properties: {
|
|
73050
|
-
board_id: { type: "string" },
|
|
73051
|
-
item_id: { type: "string" }
|
|
73052
|
-
},
|
|
73053
|
-
required: ["board_id", "item_id"]
|
|
73054
|
-
},
|
|
73055
|
-
request: { method: "DELETE", path: "/v2/boards/{board_id}/items/{item_id}" },
|
|
73056
|
-
cas: "native-idempotency",
|
|
73057
|
-
requiredScopes: ["boards:write"]
|
|
73058
|
-
},
|
|
73059
|
-
{
|
|
73060
|
-
name: "boards.share",
|
|
73061
|
-
class: "mutation",
|
|
73062
|
-
description: "Invite users to a Miro board by email. Roles: viewer, commenter, editor, coowner.",
|
|
73063
|
-
parameters: {
|
|
73064
|
-
type: "object",
|
|
73065
|
-
properties: {
|
|
73066
|
-
board_id: { type: "string" },
|
|
73067
|
-
emails: { type: "array", items: { type: "string", format: "email" } },
|
|
73068
|
-
role: {
|
|
73069
|
-
type: "string",
|
|
73070
|
-
enum: ["viewer", "commenter", "editor", "coowner"]
|
|
73071
|
-
},
|
|
73072
|
-
message: { type: "string" }
|
|
73073
|
-
},
|
|
73074
|
-
required: ["board_id", "emails", "role"]
|
|
73075
|
-
},
|
|
73076
|
-
request: {
|
|
73077
|
-
method: "POST",
|
|
73078
|
-
path: "/v2/boards/{board_id}/members",
|
|
73079
|
-
body: {
|
|
73080
|
-
emails: "{emails}",
|
|
73081
|
-
role: "{role}",
|
|
73082
|
-
message: "{message}"
|
|
73083
|
-
}
|
|
73084
|
-
},
|
|
73085
|
-
cas: "native-idempotency",
|
|
73086
|
-
requiredScopes: ["boards:write"]
|
|
73087
|
-
}
|
|
73088
|
-
]
|
|
73089
|
-
});
|
|
73090
|
-
|
|
73091
73959
|
// src/connectors/adapters/canva.ts
|
|
73092
73960
|
var canvaConnector = declarativeRestConnector({
|
|
73093
73961
|
kind: "canva",
|
|
@@ -120704,309 +121572,6 @@ var mindStudioConnector = declarativeRestConnector({
|
|
|
120704
121572
|
]
|
|
120705
121573
|
});
|
|
120706
121574
|
|
|
120707
|
-
// src/connectors/adapters/mongodb.ts
|
|
120708
|
-
var mongodbConnector = declarativeRestConnector({
|
|
120709
|
-
kind: "mongodb",
|
|
120710
|
-
displayName: "MongoDB",
|
|
120711
|
-
description: "Query, insert, update, and delete MongoDB documents via the Data API.",
|
|
120712
|
-
auth: { kind: "api-key", hint: "MongoDB Data API key." },
|
|
120713
|
-
category: "database",
|
|
120714
|
-
defaultConsistencyModel: "authoritative",
|
|
120715
|
-
baseUrl: "https://data.mongodb-api.com/app",
|
|
120716
|
-
test: { method: "POST", path: "/{appId}/endpoint/data/v1/action/findOne" },
|
|
120717
|
-
capabilities: [
|
|
120718
|
-
{
|
|
120719
|
-
name: "documents.find",
|
|
120720
|
-
class: "read",
|
|
120721
|
-
description: "Query documents in a collection.",
|
|
120722
|
-
parameters: {
|
|
120723
|
-
type: "object",
|
|
120724
|
-
properties: {
|
|
120725
|
-
appId: { type: "string", description: "MongoDB Data API application ID." },
|
|
120726
|
-
dataSourceName: { type: "string", description: 'Data source name (e.g., "Cluster0").' },
|
|
120727
|
-
databaseName: { type: "string", description: "Database name." },
|
|
120728
|
-
collectionName: { type: "string", description: "Collection name." },
|
|
120729
|
-
filter: { type: "object", description: 'Query filter (e.g., { "status": "active" }).' },
|
|
120730
|
-
projection: { type: "object", description: "Fields to include/exclude." },
|
|
120731
|
-
sort: { type: "object", description: "Sort criteria." },
|
|
120732
|
-
limit: { type: "integer", description: "Maximum documents to return." },
|
|
120733
|
-
skip: { type: "integer", description: "Documents to skip." }
|
|
120734
|
-
},
|
|
120735
|
-
required: ["appId", "dataSourceName", "databaseName", "collectionName"]
|
|
120736
|
-
},
|
|
120737
|
-
request: {
|
|
120738
|
-
method: "POST",
|
|
120739
|
-
path: "/{appId}/endpoint/data/v1/action/find",
|
|
120740
|
-
body: {
|
|
120741
|
-
dataSource: "{dataSourceName}",
|
|
120742
|
-
database: "{databaseName}",
|
|
120743
|
-
collection: "{collectionName}",
|
|
120744
|
-
filter: "{filter}",
|
|
120745
|
-
projection: "{projection}",
|
|
120746
|
-
sort: "{sort}",
|
|
120747
|
-
limit: "{limit}",
|
|
120748
|
-
skip: "{skip}"
|
|
120749
|
-
}
|
|
120750
|
-
}
|
|
120751
|
-
},
|
|
120752
|
-
{
|
|
120753
|
-
name: "documents.findOne",
|
|
120754
|
-
class: "read",
|
|
120755
|
-
description: "Find a single document matching a filter.",
|
|
120756
|
-
parameters: {
|
|
120757
|
-
type: "object",
|
|
120758
|
-
properties: {
|
|
120759
|
-
appId: { type: "string", description: "MongoDB Data API application ID." },
|
|
120760
|
-
dataSourceName: { type: "string", description: "Data source name." },
|
|
120761
|
-
databaseName: { type: "string", description: "Database name." },
|
|
120762
|
-
collectionName: { type: "string", description: "Collection name." },
|
|
120763
|
-
filter: { type: "object", description: "Query filter." },
|
|
120764
|
-
projection: { type: "object", description: "Fields to include/exclude." }
|
|
120765
|
-
},
|
|
120766
|
-
required: ["appId", "dataSourceName", "databaseName", "collectionName"]
|
|
120767
|
-
},
|
|
120768
|
-
request: {
|
|
120769
|
-
method: "POST",
|
|
120770
|
-
path: "/{appId}/endpoint/data/v1/action/findOne",
|
|
120771
|
-
body: {
|
|
120772
|
-
dataSource: "{dataSourceName}",
|
|
120773
|
-
database: "{databaseName}",
|
|
120774
|
-
collection: "{collectionName}",
|
|
120775
|
-
filter: "{filter}",
|
|
120776
|
-
projection: "{projection}"
|
|
120777
|
-
}
|
|
120778
|
-
}
|
|
120779
|
-
},
|
|
120780
|
-
{
|
|
120781
|
-
name: "documents.insertOne",
|
|
120782
|
-
class: "mutation",
|
|
120783
|
-
description: "Insert a single document into a collection.",
|
|
120784
|
-
parameters: {
|
|
120785
|
-
type: "object",
|
|
120786
|
-
properties: {
|
|
120787
|
-
appId: { type: "string", description: "MongoDB Data API application ID." },
|
|
120788
|
-
dataSourceName: { type: "string", description: "Data source name." },
|
|
120789
|
-
databaseName: { type: "string", description: "Database name." },
|
|
120790
|
-
collectionName: { type: "string", description: "Collection name." },
|
|
120791
|
-
document: { type: "object", description: "Document to insert." }
|
|
120792
|
-
},
|
|
120793
|
-
required: ["appId", "dataSourceName", "databaseName", "collectionName", "document"]
|
|
120794
|
-
},
|
|
120795
|
-
request: {
|
|
120796
|
-
method: "POST",
|
|
120797
|
-
path: "/{appId}/endpoint/data/v1/action/insertOne",
|
|
120798
|
-
body: {
|
|
120799
|
-
dataSource: "{dataSourceName}",
|
|
120800
|
-
database: "{databaseName}",
|
|
120801
|
-
collection: "{collectionName}",
|
|
120802
|
-
document: "{document}"
|
|
120803
|
-
}
|
|
120804
|
-
},
|
|
120805
|
-
cas: "native-idempotency"
|
|
120806
|
-
},
|
|
120807
|
-
{
|
|
120808
|
-
name: "documents.insertMany",
|
|
120809
|
-
class: "mutation",
|
|
120810
|
-
description: "Insert multiple documents into a collection.",
|
|
120811
|
-
parameters: {
|
|
120812
|
-
type: "object",
|
|
120813
|
-
properties: {
|
|
120814
|
-
appId: { type: "string", description: "MongoDB Data API application ID." },
|
|
120815
|
-
dataSourceName: { type: "string", description: "Data source name." },
|
|
120816
|
-
databaseName: { type: "string", description: "Database name." },
|
|
120817
|
-
collectionName: { type: "string", description: "Collection name." },
|
|
120818
|
-
documents: { type: "array", items: { type: "object" }, description: "Array of documents to insert." }
|
|
120819
|
-
},
|
|
120820
|
-
required: ["appId", "dataSourceName", "databaseName", "collectionName", "documents"]
|
|
120821
|
-
},
|
|
120822
|
-
request: {
|
|
120823
|
-
method: "POST",
|
|
120824
|
-
path: "/{appId}/endpoint/data/v1/action/insertMany",
|
|
120825
|
-
body: {
|
|
120826
|
-
dataSource: "{dataSourceName}",
|
|
120827
|
-
database: "{databaseName}",
|
|
120828
|
-
collection: "{collectionName}",
|
|
120829
|
-
documents: "{documents}"
|
|
120830
|
-
}
|
|
120831
|
-
},
|
|
120832
|
-
cas: "native-idempotency"
|
|
120833
|
-
},
|
|
120834
|
-
{
|
|
120835
|
-
name: "documents.updateOne",
|
|
120836
|
-
class: "mutation",
|
|
120837
|
-
description: "Update a single document matching a filter.",
|
|
120838
|
-
parameters: {
|
|
120839
|
-
type: "object",
|
|
120840
|
-
properties: {
|
|
120841
|
-
appId: { type: "string", description: "MongoDB Data API application ID." },
|
|
120842
|
-
dataSourceName: { type: "string", description: "Data source name." },
|
|
120843
|
-
databaseName: { type: "string", description: "Database name." },
|
|
120844
|
-
collectionName: { type: "string", description: "Collection name." },
|
|
120845
|
-
filter: { type: "object", description: "Query filter." },
|
|
120846
|
-
update: { type: "object", description: 'Update operations (e.g., { "$set": { "status": "inactive" } }).' },
|
|
120847
|
-
upsert: { type: "boolean", description: "Insert if no match found." }
|
|
120848
|
-
},
|
|
120849
|
-
required: ["appId", "dataSourceName", "databaseName", "collectionName", "filter", "update"]
|
|
120850
|
-
},
|
|
120851
|
-
request: {
|
|
120852
|
-
method: "POST",
|
|
120853
|
-
path: "/{appId}/endpoint/data/v1/action/updateOne",
|
|
120854
|
-
body: {
|
|
120855
|
-
dataSource: "{dataSourceName}",
|
|
120856
|
-
database: "{databaseName}",
|
|
120857
|
-
collection: "{collectionName}",
|
|
120858
|
-
filter: "{filter}",
|
|
120859
|
-
update: "{update}",
|
|
120860
|
-
upsert: "{upsert}"
|
|
120861
|
-
}
|
|
120862
|
-
},
|
|
120863
|
-
cas: "optimistic-read-verify"
|
|
120864
|
-
},
|
|
120865
|
-
{
|
|
120866
|
-
name: "documents.updateMany",
|
|
120867
|
-
class: "mutation",
|
|
120868
|
-
description: "Update multiple documents matching a filter.",
|
|
120869
|
-
parameters: {
|
|
120870
|
-
type: "object",
|
|
120871
|
-
properties: {
|
|
120872
|
-
appId: { type: "string", description: "MongoDB Data API application ID." },
|
|
120873
|
-
dataSourceName: { type: "string", description: "Data source name." },
|
|
120874
|
-
databaseName: { type: "string", description: "Database name." },
|
|
120875
|
-
collectionName: { type: "string", description: "Collection name." },
|
|
120876
|
-
filter: { type: "object", description: "Query filter." },
|
|
120877
|
-
update: { type: "object", description: "Update operations." },
|
|
120878
|
-
upsert: { type: "boolean", description: "Insert if no match found." }
|
|
120879
|
-
},
|
|
120880
|
-
required: ["appId", "dataSourceName", "databaseName", "collectionName", "filter", "update"]
|
|
120881
|
-
},
|
|
120882
|
-
request: {
|
|
120883
|
-
method: "POST",
|
|
120884
|
-
path: "/{appId}/endpoint/data/v1/action/updateMany",
|
|
120885
|
-
body: {
|
|
120886
|
-
dataSource: "{dataSourceName}",
|
|
120887
|
-
database: "{databaseName}",
|
|
120888
|
-
collection: "{collectionName}",
|
|
120889
|
-
filter: "{filter}",
|
|
120890
|
-
update: "{update}",
|
|
120891
|
-
upsert: "{upsert}"
|
|
120892
|
-
}
|
|
120893
|
-
},
|
|
120894
|
-
cas: "optimistic-read-verify"
|
|
120895
|
-
},
|
|
120896
|
-
{
|
|
120897
|
-
name: "documents.replaceOne",
|
|
120898
|
-
class: "mutation",
|
|
120899
|
-
description: "Replace a single document entirely.",
|
|
120900
|
-
parameters: {
|
|
120901
|
-
type: "object",
|
|
120902
|
-
properties: {
|
|
120903
|
-
appId: { type: "string", description: "MongoDB Data API application ID." },
|
|
120904
|
-
dataSourceName: { type: "string", description: "Data source name." },
|
|
120905
|
-
databaseName: { type: "string", description: "Database name." },
|
|
120906
|
-
collectionName: { type: "string", description: "Collection name." },
|
|
120907
|
-
filter: { type: "object", description: "Query filter." },
|
|
120908
|
-
replacement: { type: "object", description: "Replacement document." },
|
|
120909
|
-
upsert: { type: "boolean", description: "Insert if no match found." }
|
|
120910
|
-
},
|
|
120911
|
-
required: ["appId", "dataSourceName", "databaseName", "collectionName", "filter", "replacement"]
|
|
120912
|
-
},
|
|
120913
|
-
request: {
|
|
120914
|
-
method: "POST",
|
|
120915
|
-
path: "/{appId}/endpoint/data/v1/action/replaceOne",
|
|
120916
|
-
body: {
|
|
120917
|
-
dataSource: "{dataSourceName}",
|
|
120918
|
-
database: "{databaseName}",
|
|
120919
|
-
collection: "{collectionName}",
|
|
120920
|
-
filter: "{filter}",
|
|
120921
|
-
replacement: "{replacement}",
|
|
120922
|
-
upsert: "{upsert}"
|
|
120923
|
-
}
|
|
120924
|
-
},
|
|
120925
|
-
cas: "etag-if-match"
|
|
120926
|
-
},
|
|
120927
|
-
{
|
|
120928
|
-
name: "documents.deleteOne",
|
|
120929
|
-
class: "mutation",
|
|
120930
|
-
description: "Delete a single document matching a filter.",
|
|
120931
|
-
parameters: {
|
|
120932
|
-
type: "object",
|
|
120933
|
-
properties: {
|
|
120934
|
-
appId: { type: "string", description: "MongoDB Data API application ID." },
|
|
120935
|
-
dataSourceName: { type: "string", description: "Data source name." },
|
|
120936
|
-
databaseName: { type: "string", description: "Database name." },
|
|
120937
|
-
collectionName: { type: "string", description: "Collection name." },
|
|
120938
|
-
filter: { type: "object", description: "Query filter." }
|
|
120939
|
-
},
|
|
120940
|
-
required: ["appId", "dataSourceName", "databaseName", "collectionName", "filter"]
|
|
120941
|
-
},
|
|
120942
|
-
request: {
|
|
120943
|
-
method: "POST",
|
|
120944
|
-
path: "/{appId}/endpoint/data/v1/action/deleteOne",
|
|
120945
|
-
body: {
|
|
120946
|
-
dataSource: "{dataSourceName}",
|
|
120947
|
-
database: "{databaseName}",
|
|
120948
|
-
collection: "{collectionName}",
|
|
120949
|
-
filter: "{filter}"
|
|
120950
|
-
}
|
|
120951
|
-
},
|
|
120952
|
-
cas: "native-idempotency"
|
|
120953
|
-
},
|
|
120954
|
-
{
|
|
120955
|
-
name: "documents.deleteMany",
|
|
120956
|
-
class: "mutation",
|
|
120957
|
-
description: "Delete multiple documents matching a filter.",
|
|
120958
|
-
parameters: {
|
|
120959
|
-
type: "object",
|
|
120960
|
-
properties: {
|
|
120961
|
-
appId: { type: "string", description: "MongoDB Data API application ID." },
|
|
120962
|
-
dataSourceName: { type: "string", description: "Data source name." },
|
|
120963
|
-
databaseName: { type: "string", description: "Database name." },
|
|
120964
|
-
collectionName: { type: "string", description: "Collection name." },
|
|
120965
|
-
filter: { type: "object", description: "Query filter." }
|
|
120966
|
-
},
|
|
120967
|
-
required: ["appId", "dataSourceName", "databaseName", "collectionName", "filter"]
|
|
120968
|
-
},
|
|
120969
|
-
request: {
|
|
120970
|
-
method: "POST",
|
|
120971
|
-
path: "/{appId}/endpoint/data/v1/action/deleteMany",
|
|
120972
|
-
body: {
|
|
120973
|
-
dataSource: "{dataSourceName}",
|
|
120974
|
-
database: "{databaseName}",
|
|
120975
|
-
collection: "{collectionName}",
|
|
120976
|
-
filter: "{filter}"
|
|
120977
|
-
}
|
|
120978
|
-
},
|
|
120979
|
-
cas: "native-idempotency"
|
|
120980
|
-
},
|
|
120981
|
-
{
|
|
120982
|
-
name: "documents.aggregate",
|
|
120983
|
-
class: "read",
|
|
120984
|
-
description: "Run an aggregation pipeline over a collection.",
|
|
120985
|
-
parameters: {
|
|
120986
|
-
type: "object",
|
|
120987
|
-
properties: {
|
|
120988
|
-
appId: { type: "string", description: "MongoDB Data API application ID." },
|
|
120989
|
-
dataSourceName: { type: "string", description: "Data source name." },
|
|
120990
|
-
databaseName: { type: "string", description: "Database name." },
|
|
120991
|
-
collectionName: { type: "string", description: "Collection name." },
|
|
120992
|
-
pipeline: { type: "array", items: { type: "object" }, description: "Aggregation stages." }
|
|
120993
|
-
},
|
|
120994
|
-
required: ["appId", "dataSourceName", "databaseName", "collectionName", "pipeline"]
|
|
120995
|
-
},
|
|
120996
|
-
request: {
|
|
120997
|
-
method: "POST",
|
|
120998
|
-
path: "/{appId}/endpoint/data/v1/action/aggregate",
|
|
120999
|
-
body: {
|
|
121000
|
-
dataSource: "{dataSourceName}",
|
|
121001
|
-
database: "{databaseName}",
|
|
121002
|
-
collection: "{collectionName}",
|
|
121003
|
-
pipeline: "{pipeline}"
|
|
121004
|
-
}
|
|
121005
|
-
}
|
|
121006
|
-
}
|
|
121007
|
-
]
|
|
121008
|
-
});
|
|
121009
|
-
|
|
121010
121575
|
// src/connectors/adapters/nifty.ts
|
|
121011
121576
|
var niftyConnector = declarativeRestConnector({
|
|
121012
121577
|
kind: "nifty",
|
|
@@ -125588,45 +126153,6 @@ var pollybotAiConnector = declarativeRestConnector({
|
|
|
125588
126153
|
]
|
|
125589
126154
|
});
|
|
125590
126155
|
|
|
125591
|
-
// src/connectors/adapters/postgres.ts
|
|
125592
|
-
var postgresConnector = declarativeRestConnector({
|
|
125593
|
-
kind: "postgres",
|
|
125594
|
-
displayName: "PostgreSQL",
|
|
125595
|
-
description: "Execute queries and monitor PostgreSQL databases.",
|
|
125596
|
-
auth: { kind: "api-key", hint: "PostgreSQL connection credentials." },
|
|
125597
|
-
category: "database",
|
|
125598
|
-
defaultConsistencyModel: "authoritative",
|
|
125599
|
-
baseUrl: "postgresql://",
|
|
125600
|
-
test: { method: "GET", path: "/" },
|
|
125601
|
-
capabilities: [
|
|
125602
|
-
{
|
|
125603
|
-
name: "query.execute",
|
|
125604
|
-
class: "read",
|
|
125605
|
-
description: "Execute a SQL query against the database.",
|
|
125606
|
-
parameters: {
|
|
125607
|
-
type: "object",
|
|
125608
|
-
properties: {
|
|
125609
|
-
host: { type: "string", description: "PostgreSQL server hostname" },
|
|
125610
|
-
port: { type: "integer", description: "PostgreSQL server port" },
|
|
125611
|
-
user: { type: "string", description: "Database user" },
|
|
125612
|
-
password: { type: "string", description: "Database password" },
|
|
125613
|
-
database: { type: "string", description: "Database name" },
|
|
125614
|
-
query: { type: "string", description: "SQL query to execute" },
|
|
125615
|
-
args: { type: "array", description: "Query arguments for parameterized queries" },
|
|
125616
|
-
query_timeout: { type: "integer", description: "Query timeout in milliseconds" },
|
|
125617
|
-
connection_timeout_ms: { type: "integer", description: "Connection timeout in milliseconds" },
|
|
125618
|
-
application_name: { type: "string", description: "Application name for the connection" },
|
|
125619
|
-
enable_ssl: { type: "boolean", description: "Enable SSL connection" },
|
|
125620
|
-
reject_unauthorized: { type: "boolean", description: "Verify server certificate" },
|
|
125621
|
-
certificate: { type: "string", description: "CA certificate for SSL verification" }
|
|
125622
|
-
},
|
|
125623
|
-
required: ["host", "port", "user", "password", "database", "query"]
|
|
125624
|
-
},
|
|
125625
|
-
request: { method: "POST", path: "/query", body: "{query}" }
|
|
125626
|
-
}
|
|
125627
|
-
]
|
|
125628
|
-
});
|
|
125629
|
-
|
|
125630
126156
|
// src/connectors/adapters/postiz.ts
|
|
125631
126157
|
var postizConnector = declarativeRestConnector({
|
|
125632
126158
|
kind: "postiz",
|
|
@@ -145721,7 +146247,10 @@ export {
|
|
|
145721
146247
|
mastodonConnector,
|
|
145722
146248
|
meetgeekAiConnector,
|
|
145723
146249
|
mollieConnector,
|
|
146250
|
+
miroConnector,
|
|
145724
146251
|
mondayConnector,
|
|
146252
|
+
createMongoDbConnector,
|
|
146253
|
+
mongodbConnector,
|
|
145725
146254
|
mycaseConnector,
|
|
145726
146255
|
notionConnector,
|
|
145727
146256
|
notion,
|
|
@@ -145743,6 +146272,10 @@ export {
|
|
|
145743
146272
|
rabbitMqConnector,
|
|
145744
146273
|
createRedisConnector,
|
|
145745
146274
|
redisConnector,
|
|
146275
|
+
createRedshiftConnector,
|
|
146276
|
+
redshiftConnector,
|
|
146277
|
+
createPostgresConnector,
|
|
146278
|
+
postgresConnector,
|
|
145746
146279
|
recallAiConnector,
|
|
145747
146280
|
rampConnector,
|
|
145748
146281
|
ringcentralConnector,
|
|
@@ -145817,6 +146350,7 @@ export {
|
|
|
145817
146350
|
builtwithConnector,
|
|
145818
146351
|
fullenrichConnector,
|
|
145819
146352
|
hunterConnector,
|
|
146353
|
+
neverbounceConnector,
|
|
145820
146354
|
theirstackConnector,
|
|
145821
146355
|
zerobounceConnector,
|
|
145822
146356
|
CONNECTOR_ADAPTER_FACTORIES,
|
|
@@ -145842,7 +146376,6 @@ export {
|
|
|
145842
146376
|
sanityConnector,
|
|
145843
146377
|
figmaConnector,
|
|
145844
146378
|
figjamConnector,
|
|
145845
|
-
miroConnector,
|
|
145846
146379
|
canvaConnector,
|
|
145847
146380
|
adobeCreativeCloudConnector,
|
|
145848
146381
|
clioConnector,
|
|
@@ -146062,7 +146595,6 @@ export {
|
|
|
146062
146595
|
mailchainConnector,
|
|
146063
146596
|
medullarConnector,
|
|
146064
146597
|
mindStudioConnector,
|
|
146065
|
-
mongodbConnector,
|
|
146066
146598
|
niftyConnector,
|
|
146067
146599
|
nocodbConnector,
|
|
146068
146600
|
ntfyConnector,
|
|
@@ -146088,7 +146620,6 @@ export {
|
|
|
146088
146620
|
plausibleConnector,
|
|
146089
146621
|
pocketbaseConnector,
|
|
146090
146622
|
pollybotAiConnector,
|
|
146091
|
-
postgresConnector,
|
|
146092
146623
|
postizConnector,
|
|
146093
146624
|
posthogConnector,
|
|
146094
146625
|
predictLeadsConnector,
|
|
@@ -146203,4 +146734,4 @@ export {
|
|
|
146203
146734
|
demandbaseConnector,
|
|
146204
146735
|
adapters_exports
|
|
146205
146736
|
};
|
|
146206
|
-
//# sourceMappingURL=chunk-
|
|
146737
|
+
//# sourceMappingURL=chunk-R5GQB3SQ.js.map
|